idea-analogist
想法群聊室 — 类比者角色。被 idea-team 主编排器调用,或用户单独说"类比一下"、"别的行业有没有"、"yes-and 扩展"、"X…
Guides clean architecture design with strict 200-line file limits. Use when starting new features, refactoring large files, or planning module structure. Enforces modular design and real testing.
$ npx -y skills add majiayu000/spellbook --skill elegant-architecture --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/elegant-architectureContext preview
The summary Claude sees to decide when to auto-load this skill.
Guides clean architecture design with strict 200-line file limits. Use when starting new features, refactoring large files, or planning module structure. Enforces modular design and real testing.
name: elegant-architecture description: Guides clean architecture design with strict 200-line file limits. Use when starting new features, refactoring large files, or planning module structure. Enforces modular design and real testing.
Before writing any code: - List all features/functionalities needed - Estimate code volume for each module - Identify shared components - Map dependencies between modules
When estimated lines > 200: - Convert file to folder with index - Split by sub-functionality - Extract shared utilities Example transformation:
# Before (user.ts - 400+ lines) user.ts # After (user/ folder) user/ ├── index.ts # Public exports ├── types.ts # Interfaces, types ├── validation.ts # Input validation ├── repository.ts # Data access └── service.ts # Business logic
// Define contracts before implementation
interface UserService {
create(input: CreateUserInput): Promise<User>;
findById(id: string): Promise<User | null>;
update(id: string, input: UpdateUserInput): Promise<User>;
delete(id: string): Promise<void>;
}
interface UserRepository {
save(user: User): Promise<User>;
findById(id: string): Promise<User | null>;
findByEmail(email: string): Promise<User | null>;
delete(id: string): Promise<void>;
}For each module: 1. Create type definitions 2. Implement core logic 3. Add error handling 4. Write tests 5. Verify line count < 200
// ❌ Avoid: Mock everything
const mockRepo = jest.fn();
const service = new UserService(mockRepo);
// ✅ Prefer: Real implementations
const testDb = createTestDatabase();
const repo = new UserRepository(testDb);
const service = new UserService(repo);
// Test actual behavior
const user = await service.create({ email: 'test@example.com' });
const found = await service.findById(user.id);
expect(found).toEqual(user);src/ ├── modules/ │ ├── auth/ │ │ ├── index.ts │ │ ├── types.ts │ │ ├── service.ts │ │ └── middleware.ts │ ├── user/ │ │ ├── index.ts │ │ ├── types.ts │ │ ├── service.ts │ │ └── repository.ts │ └── order/ │ ├── index.ts │ ├── types.ts │ ├── service.ts │ └── repository.ts ├── shared/ │ ├── database/ │ ├── errors/ │ └── utils/ └── index.ts
// Decouple components via constructor injection
class OrderService {
constructor(
private readonly orderRepo: OrderRepository,
private readonly userService: UserService,
private readonly paymentGateway: PaymentGateway
) {}
async createOrder(userId: string, items: OrderItem[]): Promise<Order> {
const user = await this.userService.findById(userId);
if (!user) throw new NotFoundError('User', userId);
const order = Order.create(user, items);
await this.paymentGateway.charge(user, order.total);
return this.orderRepo.save(order);
}
}
// Wire up in composition root
const orderService = new OrderService(
new PostgresOrderRepository(db),
new UserService(userRepo),
new StripePaymentGateway(stripeClient)
);// Complex object creation
class NotificationFactory {
create(type: NotificationType, data: NotificationData): Notification {
switch (type) {
case 'email':
return new EmailNotification(data, this.emailClient);
case 'sms':
return new SmsNotification(data, this.smsClient);
case 'push':
return new PushNotification(data, this.pushClient);
default:
throw new Error(`Unknown notification type: ${type}`);
}
}
}// Replaceable algorithms
interface PricingStrategy {
calculate(order: Order): Money;
}
class StandardPricing implements PricingStrategy {
calculate(order: Order): Money {
return order.items.reduce((sum, item) => sum.add(item.price), Money.zero());
}
}
class DiscountPricing implements PricingStrategy {
constructor(private readonly discount: Percentage) {}
calculate(order: Order): Money {
const standard = new StandardPricing().calculate(order);
return standard.subtract(standard.multiply(this.discount));
}
}
class OrderProcessor {
constructor(private pricing: PricingStrategy) {}
setPricing(strategy: PricingStrategy) {
this.pricing = strategy;
}
process(order: Order): ProcessedOrder {
const total = this.pricing.calculate(order);
return { ...order, total };
}
}| Indicator | Action | |-----------|--------| | File > 200 lines | Split immediately | | File > 150 lines | Plan split | | 3+ distinct responsibilities | Split by responsibility | | Shared types growing | Extract to types.ts | | Utility functions accumulating | Extract to utils.ts |
1. Identify logical boundaries 2. Create folder with same name as file 3. Move related code to separate files 4. Create index.ts for public exports 5. Update imports in dependent files
module/ ├── index.ts # Public API exports ├── types.ts # Interfaces, types, enums ├── constants.ts # Configuration, magic values ├── utils.ts # Helper functions ├── service.ts # Business logic ├── repository.ts # Data access ├── validation.ts # Input validation └── errors.ts #
Cross-runtime skills for Claude Code, Codex, and multi-agent workflows.
Repo: majiayu000/claude-arsenal
想法群聊室 — 类比者角色。被 idea-team 主编排器调用,或用户单独说"类比一下"、"别的行业有没有"、"yes-and 扩展"、"X…
想法群聊室 — 反方角色。被 idea-team 主编排器调用,或用户单独说"反方意见"、"挑这个想法的刺"、"为什么会失败"、"找漏洞 / 反例"、"devil's…
想法群聊室 — 调研员角色。被 idea-team 主编排器调用,或用户单独说"调研一下 X"、"X 的现状/竞品/数据"、"找 2026 数据"、"事实底"时触发。**用…
端到端产品教练 — 把一句话想法走到 PRD + 可点击 HTML 原型。会顶嘴、强制砍功能、用 Nielsen + Norman 做友好性硬检。Use when user…
Mobile app UI design expert for iOS and Android. Use when designing app interfaces, creating…