interface"
+
+ mediator:
+ difficulty: 3
+ use_frequency: medium
+ detection_confidence: 0.65
+ typical_files: ["*Mediator.ts", "*Controller.ts"]
+ primary_signals: ["centralized communication", "colleagues reference mediator", "loose coupling"]
+ anti_patterns: ["god mediator", "tight coupling to mediator"]
+ related: [facade, observer]
+ stack_native:
+ react: "Context API"
+ angular: "Services with dependency injection"
+
+ memento:
+ difficulty: 3
+ use_frequency: low
+ detection_confidence: 0.60
+ typical_files: ["*Memento.ts", "*Snapshot.ts", "*Caretaker.ts"]
+ primary_signals: ["save state", "restore state", "encapsulated snapshot", "caretaker manages history"]
+ anti_patterns: ["large state snapshots", "exposing internals"]
+ related: [command]
+ common_use_cases: ["undo/redo", "transaction rollback", "state history"]
+
+ observer:
+ difficulty: 2
+ use_frequency: very-high
+ detection_confidence: 0.85
+ typical_files: ["*Observer.ts", "*Subject.ts", "*Publisher.ts", "*Subscriber.ts"]
+ primary_signals: ["subscribe/unsubscribe", "notify/emit", "observers list", "one-to-many dependency"]
+ anti_patterns: ["memory leaks", "notification storms", "observer order dependency"]
+ related: [mediator, singleton]
+ stack_native:
+ javascript: "EventEmitter, EventTarget"
+ react: "useState, useEffect, Context"
+ angular: "RxJS Observables"
+ rxjs: "Subject, BehaviorSubject, ReplaySubject"
+ vue: "ref(), reactive(), watch()"
+
+ state:
+ difficulty: 2
+ use_frequency: medium
+ detection_confidence: 0.70
+ typical_files: ["*State.ts", "*Context.ts"]
+ primary_signals: ["state interface", "context holds state", "state transitions", "behavior varies by state"]
+ anti_patterns: ["state explosion", "complex transitions"]
+ related: [strategy, flyweight]
+ stack_native:
+ react: "useState, useReducer"
+ redux: "Reducers"
+ xstate: "State machines"
+
+ strategy:
+ difficulty: 1
+ use_frequency: high
+ detection_confidence: 0.80
+ typical_files: ["*Strategy.ts", "*Policy.ts"]
+ primary_signals: ["strategy interface", "context has strategy reference", "interchangeable algorithms"]
+ anti_patterns: ["strategy explosion", "client awareness of strategies"]
+ related: [state, bridge, template-method]
+ stack_native:
+ react: "Custom hooks"
+ vue: "Composables"
+
+ template-method:
+ difficulty: 2
+ use_frequency: medium
+ detection_confidence: 0.75
+ typical_files: ["*Template.ts", "*Abstract*.ts"]
+ primary_signals: ["abstract class", "template method", "primitive operations", "hook methods"]
+ anti_patterns: ["too many hooks", "subclass override complexity"]
+ related: [strategy, factory-method]
+
+ visitor:
+ difficulty: 4
+ use_frequency: low
+ detection_confidence: 0.60
+ typical_files: ["*Visitor.ts"]
+ primary_signals: ["visit* methods", "double dispatch", "element accepts visitor", "operations on object structure"]
+ anti_patterns: ["adding new element types", "circular dependencies"]
+ related: [composite, iterator]
+
+ interpreter:
+ difficulty: 4
+ use_frequency: very-low
+ detection_confidence: 0.55
+ typical_files: ["*Interpreter.ts", "*Expression.ts"]
+ primary_signals: ["grammar rules", "interpret() method", "abstract syntax tree", "terminal/non-terminal expressions"]
+ anti_patterns: ["complex grammars", "performance issues"]
+ related: [composite, visitor]
+ common_use_cases: ["DSLs", "query languages", "expression evaluators"]
+
+# Detection difficulty levels
+difficulty_levels:
+ 1: "Easy - Clear structural markers and naming conventions"
+ 2: "Medium - Requires pattern knowledge to distinguish from similar patterns"
+ 3: "Hard - Subtle structural differences, context-dependent"
+ 4: "Very Hard - Requires deep analysis of intent and relationships"
+
+# Usage frequency in modern codebases
+frequency_levels:
+ very-high: "Ubiquitous in modern frameworks"
+ high: "Common in most projects"
+ medium: "Occasional use, specific scenarios"
+ low: "Rare, specialized use cases"
+ very-low: "Academic or niche applications"
+
+# Confidence score interpretation
+confidence_interpretation:
+ 0.85-1.0: "High confidence - Multiple strong signals, unlikely false positive"
+ 0.70-0.84: "Medium-high - Clear signals, some ambiguity possible"
+ 0.55-0.69: "Medium - Requires manual validation"
+ 0.40-0.54: "Low - Weak signals, high false positive risk"
+ 0.0-0.39: "Very low - Naming convention only, not reliable"
diff --git a/examples/skills/design-patterns/reference/structural.md b/examples/skills/design-patterns/reference/structural.md
new file mode 100644
index 0000000..905c2bf
--- /dev/null
+++ b/examples/skills/design-patterns/reference/structural.md
@@ -0,0 +1,873 @@
+# Structural Design Patterns
+
+Patterns that deal with object composition and relationships between entities, providing ways to assemble objects and classes into larger structures.
+
+## Adapter
+
+### Definition
+Converts the interface of a class into another interface clients expect, allowing incompatible interfaces to work together.
+
+### When to Use
+- [x] Want to use an existing class with an incompatible interface
+- [x] Need to integrate third-party libraries with different interfaces
+- [x] Want to create a reusable class that cooperates with unrelated classes
+- [x] Legacy code must work with new systems
+
+### TypeScript Signature
+```typescript
+// Target interface (what client expects)
+interface Target {
+ request(): string;
+}
+
+// Adaptee (existing incompatible class)
+class Adaptee {
+ specificRequest(): string {
+ return '.eetpadA eht fo roivaheb laicepS';
+ }
+}
+
+// Adapter (makes Adaptee compatible with Target)
+class Adapter implements Target {
+ private adaptee: Adaptee;
+
+ constructor(adaptee: Adaptee) {
+ this.adaptee = adaptee;
+ }
+
+ public request(): string {
+ const result = this.adaptee.specificRequest().split('').reverse().join('');
+ return `Adapter: ${result}`;
+ }
+}
+
+// Client code
+function clientCode(target: Target) {
+ console.log(target.request());
+}
+
+// Usage
+const adaptee = new Adaptee();
+const adapter = new Adapter(adaptee);
+clientCode(adapter);
+```
+
+### Real-World Example: Third-Party Library Integration
+```typescript
+// Third-party library (can't modify)
+class XMLDataProvider {
+ getXMLData(): string {
+ return '- 1
';
+ }
+}
+
+// Your application expects JSON
+interface JSONDataProvider {
+ getJSONData(): object;
+}
+
+// Adapter
+class XMLToJSONAdapter implements JSONDataProvider {
+ constructor(private xmlProvider: XMLDataProvider) {}
+
+ getJSONData(): object {
+ const xml = this.xmlProvider.getXMLData();
+ // Convert XML to JSON (simplified)
+ return { data: { item: '1' } };
+ }
+}
+
+// Usage
+const xmlProvider = new XMLDataProvider();
+const adapter = new XMLToJSONAdapter(xmlProvider);
+const data = adapter.getJSONData();
+```
+
+### Detection Markers
+- Class implements target interface
+- Holds reference to adaptee
+- Delegates to adaptee with interface conversion
+- Names like `*Adapter`, `*Wrapper`
+
+### Code Smells It Fixes
+- **Incompatible interfaces**: Makes legacy or third-party code compatible
+- **Interface proliferation**: Single adapter vs modifying multiple client calls
+
+### Common Mistakes
+- **Two-way adapters**: Bidirectional conversion is complex; create two adapters
+- **Adapter chains**: Multiple adapters in sequence indicate design issues
+- **Overusing for new code**: Design compatible interfaces from the start
+
+---
+
+## Bridge
+
+### Definition
+Decouples an abstraction from its implementation so the two can vary independently.
+
+### When to Use
+- [x] Want to avoid permanent binding between abstraction and implementation
+- [x] Both abstractions and implementations should be extensible by subclassing
+- [x] Changes in implementation shouldn't affect clients
+- [x] Want to share implementation among multiple objects (Flyweight-like)
+
+### TypeScript Signature
+```typescript
+// Implementation interface
+interface Implementation {
+ operationImpl(): string;
+}
+
+// Concrete implementations
+class ConcreteImplementationA implements Implementation {
+ operationImpl(): string {
+ return 'ConcreteImplementationA';
+ }
+}
+
+class ConcreteImplementationB implements Implementation {
+ operationImpl(): string {
+ return 'ConcreteImplementationB';
+ }
+}
+
+// Abstraction
+class Abstraction {
+ constructor(protected implementation: Implementation) {}
+
+ public operation(): string {
+ return `Abstraction: ${this.implementation.operationImpl()}`;
+ }
+}
+
+// Refined abstraction
+class ExtendedAbstraction extends Abstraction {
+ public operation(): string {
+ return `ExtendedAbstraction: ${this.implementation.operationImpl()}`;
+ }
+}
+
+// Usage
+const implA = new ConcreteImplementationA();
+const abstraction1 = new Abstraction(implA);
+console.log(abstraction1.operation());
+
+const implB = new ConcreteImplementationB();
+const abstraction2 = new ExtendedAbstraction(implB);
+console.log(abstraction2.operation());
+```
+
+### Real-World Example: UI Components with Multiple Renderers
+```typescript
+// Implementation: Renderers
+interface Renderer {
+ renderCircle(radius: number): string;
+ renderSquare(side: number): string;
+}
+
+class VectorRenderer implements Renderer {
+ renderCircle(radius: number): string {
+ return `Drawing circle (vector) with radius ${radius}`;
+ }
+ renderSquare(side: number): string {
+ return `Drawing square (vector) with side ${side}`;
+ }
+}
+
+class RasterRenderer implements Renderer {
+ renderCircle(radius: number): string {
+ return `Drawing circle (pixels) with radius ${radius}`;
+ }
+ renderSquare(side: number): string {
+ return `Drawing square (pixels) with side ${side}`;
+ }
+}
+
+// Abstraction: Shapes
+abstract class Shape {
+ constructor(protected renderer: Renderer) {}
+ abstract draw(): string;
+}
+
+class Circle extends Shape {
+ constructor(renderer: Renderer, private radius: number) {
+ super(renderer);
+ }
+ draw(): string {
+ return this.renderer.renderCircle(this.radius);
+ }
+}
+
+class Square extends Shape {
+ constructor(renderer: Renderer, private side: number) {
+ super(renderer);
+ }
+ draw(): string {
+ return this.renderer.renderSquare(this.side);
+ }
+}
+
+// Usage: Can mix any shape with any renderer
+const vectorCircle = new Circle(new VectorRenderer(), 5);
+const rasterSquare = new Square(new RasterRenderer(), 10);
+```
+
+### Detection Markers
+- Abstraction holds reference to implementation interface
+- Constructor injects implementation
+- Two parallel hierarchies (abstraction and implementation)
+
+### Common Mistakes
+- **Confusion with Adapter**: Bridge is design-time; Adapter is runtime fix
+- **Over-engineering simple scenarios**: Use only when both hierarchies need to vary
+
+---
+
+## Composite
+
+### Definition
+Composes objects into tree structures to represent part-whole hierarchies, letting clients treat individual objects and compositions uniformly.
+
+### When to Use
+- [x] Want to represent part-whole hierarchies of objects
+- [x] Want clients to ignore difference between compositions and individual objects
+- [x] Tree structures are natural for the domain (file systems, UI components, org charts)
+
+### TypeScript Signature
+```typescript
+// Component interface
+interface Component {
+ operation(): string;
+ add?(component: Component): void;
+ remove?(component: Component): void;
+ getChild?(index: number): Component;
+}
+
+// Leaf (no children)
+class Leaf implements Component {
+ constructor(private name: string) {}
+
+ operation(): string {
+ return this.name;
+ }
+}
+
+// Composite (has children)
+class Composite implements Component {
+ private children: Component[] = [];
+
+ constructor(private name: string) {}
+
+ add(component: Component): void {
+ this.children.push(component);
+ }
+
+ remove(component: Component): void {
+ const index = this.children.indexOf(component);
+ if (index !== -1) {
+ this.children.splice(index, 1);
+ }
+ }
+
+ getChild(index: number): Component {
+ return this.children[index];
+ }
+
+ operation(): string {
+ const results = this.children.map(child => child.operation());
+ return `${this.name}(${results.join(', ')})`;
+ }
+}
+
+// Usage
+const tree = new Composite('root');
+const branch1 = new Composite('branch1');
+branch1.add(new Leaf('leaf1'));
+branch1.add(new Leaf('leaf2'));
+
+const branch2 = new Composite('branch2');
+branch2.add(new Leaf('leaf3'));
+
+tree.add(branch1);
+tree.add(branch2);
+tree.add(new Leaf('leaf4'));
+
+console.log(tree.operation());
+// Output: root(branch1(leaf1, leaf2), branch2(leaf3), leaf4)
+```
+
+### Real-World Example: File System
+```typescript
+interface FileSystemComponent {
+ getName(): string;
+ getSize(): number;
+ print(indent: string): void;
+}
+
+class File implements FileSystemComponent {
+ constructor(private name: string, private size: number) {}
+
+ getName(): string {
+ return this.name;
+ }
+
+ getSize(): number {
+ return this.size;
+ }
+
+ print(indent: string): void {
+ console.log(`${indent}📄 ${this.name} (${this.size} bytes)`);
+ }
+}
+
+class Directory implements FileSystemComponent {
+ private children: FileSystemComponent[] = [];
+
+ constructor(private name: string) {}
+
+ add(component: FileSystemComponent): void {
+ this.children.push(component);
+ }
+
+ getName(): string {
+ return this.name;
+ }
+
+ getSize(): number {
+ return this.children.reduce((sum, child) => sum + child.getSize(), 0);
+ }
+
+ print(indent: string): void {
+ console.log(`${indent}📁 ${this.name} (${this.getSize()} bytes)`);
+ this.children.forEach(child => child.print(indent + ' '));
+ }
+}
+
+// Usage
+const root = new Directory('root');
+const home = new Directory('home');
+home.add(new File('photo.jpg', 2048));
+home.add(new File('document.pdf', 4096));
+
+const work = new Directory('work');
+work.add(new File('report.docx', 8192));
+
+root.add(home);
+root.add(work);
+root.print('');
+```
+
+### Detection Markers
+- Tree structure with uniform interface
+- Collection of children components
+- `add()`, `remove()`, `getChild()` methods
+- Recursive operation calls
+
+### Code Smells It Fixes
+- **Type checking for composition vs leaf**: Uniform interface eliminates `instanceof` checks
+- **Different handling for parts vs wholes**: Clients treat both uniformly
+
+### Common Mistakes
+- **Violating uniformity**: Leaf and Composite should have same interface
+- **Incorrect child management**: Not handling removal properly
+- **Deep recursion**: Can cause stack overflow on very deep trees
+
+---
+
+## Decorator
+
+### Definition
+Attaches additional responsibilities to an object dynamically, providing a flexible alternative to subclassing for extending functionality.
+
+### When to Use
+- [x] Need to add responsibilities to objects dynamically and transparently
+- [x] Responsibilities can be withdrawn
+- [x] Extension by subclassing is impractical (many possible combinations)
+- [x] Want to add features incrementally
+
+### TypeScript Signature
+```typescript
+// Component interface
+interface Component {
+ operation(): string;
+}
+
+// Concrete component
+class ConcreteComponent implements Component {
+ operation(): string {
+ return 'ConcreteComponent';
+ }
+}
+
+// Base decorator
+abstract class Decorator implements Component {
+ constructor(protected component: Component) {}
+
+ operation(): string {
+ return this.component.operation();
+ }
+}
+
+// Concrete decorators
+class DecoratorA extends Decorator {
+ operation(): string {
+ return `DecoratorA(${super.operation()})`;
+ }
+}
+
+class DecoratorB extends Decorator {
+ operation(): string {
+ return `DecoratorB(${super.operation()})`;
+ }
+}
+
+// Usage: Stack decorators
+const simple = new ConcreteComponent();
+const decorated1 = new DecoratorA(simple);
+const decorated2 = new DecoratorB(decorated1);
+console.log(decorated2.operation());
+// Output: DecoratorB(DecoratorA(ConcreteComponent))
+```
+
+### Stack-Native Alternatives
+
+**React - Higher-Order Components**:
+```typescript
+// HOC decorator
+function withAuth(
+ Component: React.ComponentType
+): React.ComponentType
{
+ return (props: P) => {
+ const { user } = useAuth();
+ if (!user) return ;
+ return ;
+ };
+}
+
+// Usage: Stack decorators
+const AuthenticatedProfile = withAuth(Profile);
+const AuthenticatedAdminProfile = withLogging(withAuth(Profile));
+```
+
+**NestJS - Interceptors**:
+```typescript
+@Injectable()
+export class LoggingInterceptor implements NestInterceptor {
+ intercept(context: ExecutionContext, next: CallHandler): Observable {
+ console.log('Before...');
+ return next.handle().pipe(
+ tap(() => console.log('After...'))
+ );
+ }
+}
+
+// Apply decorator
+@UseInterceptors(LoggingInterceptor)
+@Controller('users')
+export class UsersController {}
+```
+
+### Detection Markers
+- Implements same interface as wrapped object
+- Holds reference to wrapped object
+- Delegates to wrapped, adding behavior
+- Can be stacked
+
+### Code Smells It Fixes
+- **Class explosion**: Avoid creating subclass for every feature combination
+- **Rigid feature addition**: Add/remove features dynamically
+
+### Common Mistakes
+- **Order dependency**: DecoratorA(DecoratorB(x)) ≠ DecoratorB(DecoratorA(x))
+- **Decorator explosion**: Too many small decorators can be hard to manage
+- **Breaking interface**: Decorator must maintain interface contract
+
+---
+
+## Facade
+
+### Definition
+Provides a unified interface to a set of interfaces in a subsystem, making the subsystem easier to use.
+
+### When to Use
+- [x] Want to provide a simple interface to a complex subsystem
+- [x] Many dependencies exist between clients and implementation classes
+- [x] Want to layer subsystems
+- [x] Need to decouple subsystem from clients
+
+### TypeScript Signature
+```typescript
+// Complex subsystem classes
+class SubsystemA {
+ operationA(): string {
+ return 'SubsystemA';
+ }
+}
+
+class SubsystemB {
+ operationB(): string {
+ return 'SubsystemB';
+ }
+}
+
+class SubsystemC {
+ operationC(): string {
+ return 'SubsystemC';
+ }
+}
+
+// Facade
+class Facade {
+ private subsystemA: SubsystemA;
+ private subsystemB: SubsystemB;
+ private subsystemC: SubsystemC;
+
+ constructor() {
+ this.subsystemA = new SubsystemA();
+ this.subsystemB = new SubsystemB();
+ this.subsystemC = new SubsystemC();
+ }
+
+ // Simplified interface
+ public simpleOperation(): string {
+ const resultA = this.subsystemA.operationA();
+ const resultB = this.subsystemB.operationB();
+ const resultC = this.subsystemC.operationC();
+ return `Facade coordinates: ${resultA}, ${resultB}, ${resultC}`;
+ }
+}
+
+// Client code
+const facade = new Facade();
+console.log(facade.simpleOperation());
+// Instead of:
+// const a = new SubsystemA(); const b = new SubsystemB(); const c = new SubsystemC();
+// a.operationA(); b.operationB(); c.operationC();
+```
+
+### Real-World Example: Payment Processing
+```typescript
+// Complex subsystems
+class PaymentValidator {
+ validate(amount: number, card: string): boolean {
+ // Complex validation logic
+ return amount > 0 && card.length === 16;
+ }
+}
+
+class PaymentGateway {
+ charge(amount: number, card: string): string {
+ return `Charged $${amount} to ${card}`;
+ }
+}
+
+class NotificationService {
+ sendReceipt(email: string, transactionId: string): void {
+ console.log(`Receipt sent to ${email}: ${transactionId}`);
+ }
+}
+
+class TransactionLogger {
+ log(transaction: string): void {
+ console.log(`Logged: ${transaction}`);
+ }
+}
+
+// Facade
+class PaymentFacade {
+ private validator = new PaymentValidator();
+ private gateway = new PaymentGateway();
+ private notifications = new NotificationService();
+ private logger = new TransactionLogger();
+
+ processPayment(amount: number, card: string, email: string): boolean {
+ // Simplified interface for complex process
+ if (!this.validator.validate(amount, card)) {
+ return false;
+ }
+
+ const result = this.gateway.charge(amount, card);
+ this.logger.log(result);
+ this.notifications.sendReceipt(email, result);
+ return true;
+ }
+}
+
+// Client code (simple!)
+const payment = new PaymentFacade();
+payment.processPayment(100, '1234567890123456', 'user@example.com');
+```
+
+### Detection Markers
+- Class with multiple subsystem dependencies
+- Simple public methods coordinating subsystems
+- Named `*Facade`, `*API`, `*Service`
+
+### Code Smells It Fixes
+- **Complex subsystem usage**: Clients don't need to know subsystem details
+- **Tight coupling**: Clients depend on facade, not many classes
+
+### Common Mistakes
+- **God Facade**: Facade does too much; should coordinate, not contain logic
+- **Leaky abstraction**: Exposing subsystem details defeats the purpose
+
+---
+
+## Flyweight
+
+### Definition
+Uses sharing to support large numbers of fine-grained objects efficiently by storing shared state externally.
+
+### When to Use
+- [x] Application uses large number of objects
+- [x] Storage cost is high due to object quantity
+- [x] Most object state can be made extrinsic (externalized)
+- [x] Many groups of objects may be replaced by relatively few shared objects
+
+### TypeScript Signature
+```typescript
+// Flyweight
+class Flyweight {
+ constructor(private sharedState: string) {}
+
+ operation(uniqueState: string): void {
+ console.log(`Flyweight: Shared (${this.sharedState}) and unique (${uniqueState}) state.`);
+ }
+}
+
+// Flyweight factory
+class FlyweightFactory {
+ private flyweights: Map = new Map();
+
+ constructor(initialFlyweights: string[][]) {
+ for (const state of initialFlyweights) {
+ this.flyweights.set(this.getKey(state), new Flyweight(state.join('_')));
+ }
+ }
+
+ private getKey(state: string[]): string {
+ return state.join('_');
+ }
+
+ getFlyweight(sharedState: string[]): Flyweight {
+ const key = this.getKey(sharedState);
+
+ if (!this.flyweights.has(key)) {
+ console.log('Creating new flyweight');
+ this.flyweights.set(key, new Flyweight(key));
+ } else {
+ console.log('Reusing existing flyweight');
+ }
+
+ return this.flyweights.get(key)!;
+ }
+
+ listFlyweights(): void {
+ console.log(`FlyweightFactory: ${this.flyweights.size} flyweights:`);
+ for (const key of this.flyweights.keys()) {
+ console.log(key);
+ }
+ }
+}
+
+// Usage
+const factory = new FlyweightFactory([
+ ['Chevrolet', 'Camaro2018', 'pink'],
+ ['Mercedes Benz', 'C300', 'black'],
+]);
+
+const flyweight1 = factory.getFlyweight(['Chevrolet', 'Camaro2018', 'pink']);
+flyweight1.operation('license-123');
+
+const flyweight2 = factory.getFlyweight(['Chevrolet', 'Camaro2018', 'pink']);
+flyweight2.operation('license-456'); // Reuses same flyweight
+```
+
+### Real-World Example: Text Editor Characters
+```typescript
+// Flyweight: Character formatting (shared)
+class CharacterFormat {
+ constructor(
+ public font: string,
+ public size: number,
+ public color: string
+ ) {}
+}
+
+// Flyweight factory
+class FormatFactory {
+ private formats = new Map();
+
+ getFormat(font: string, size: number, color: string): CharacterFormat {
+ const key = `${font}_${size}_${color}`;
+ if (!this.formats.has(key)) {
+ this.formats.set(key, new CharacterFormat(font, size, color));
+ }
+ return this.formats.get(key)!;
+ }
+}
+
+// Character with extrinsic state
+class Character {
+ constructor(
+ private char: string,
+ private format: CharacterFormat // Shared flyweight
+ ) {}
+
+ render(position: number): string {
+ return `'${this.char}' at ${position} (${this.format.font}, ${this.format.size}px, ${this.format.color})`;
+ }
+}
+
+// Document
+const formatFactory = new FormatFactory();
+const arial12Black = formatFactory.getFormat('Arial', 12, 'black');
+const arial12Red = formatFactory.getFormat('Arial', 12, 'red');
+
+// 10,000 characters, but only 2 format objects
+const characters: Character[] = [];
+for (let i = 0; i < 10000; i++) {
+ const format = i % 2 === 0 ? arial12Black : arial12Red;
+ characters.push(new Character('A', format));
+}
+```
+
+### Detection Markers
+- Factory managing pool of shared objects
+- Intrinsic (shared) vs extrinsic (unique) state separation
+- Map/cache of flyweights
+
+### Common Mistakes
+- **Premature optimization**: Only use if memory is actually a problem
+- **Incorrect state separation**: Mixing intrinsic and extrinsic state
+
+---
+
+## Proxy
+
+### Definition
+Provides a surrogate or placeholder for another object to control access to it.
+
+### When to Use
+- [x] Lazy initialization (virtual proxy): Create expensive object only when needed
+- [x] Access control (protection proxy): Control access to original object
+- [x] Local representative of remote object (remote proxy)
+- [x] Logging, caching, or monitoring access
+
+### TypeScript Signature
+```typescript
+// Subject interface
+interface Subject {
+ request(): void;
+}
+
+// Real subject
+class RealSubject implements Subject {
+ request(): void {
+ console.log('RealSubject: Handling request');
+ }
+}
+
+// Proxy
+class Proxy implements Subject {
+ private realSubject: RealSubject | null = null;
+
+ request(): void {
+ // Access control
+ if (this.checkAccess()) {
+ // Lazy initialization
+ if (!this.realSubject) {
+ this.realSubject = new RealSubject();
+ }
+
+ // Logging
+ this.logAccess();
+
+ // Delegate to real subject
+ this.realSubject.request();
+ }
+ }
+
+ private checkAccess(): boolean {
+ console.log('Proxy: Checking access');
+ return true;
+ }
+
+ private logAccess(): void {
+ console.log('Proxy: Logging access time');
+ }
+}
+
+// Usage
+const proxy = new Proxy();
+proxy.request();
+// Output:
+// Proxy: Checking access
+// Proxy: Logging access time
+// RealSubject: Handling request
+```
+
+### Modern JavaScript Proxy
+```typescript
+const target = {
+ message: 'Hello',
+ getValue() {
+ return this.message;
+ }
+};
+
+const handler = {
+ get(target: any, prop: string) {
+ console.log(`Accessing property: ${prop}`);
+ return target[prop];
+ },
+ set(target: any, prop: string, value: any) {
+ console.log(`Setting property: ${prop} = ${value}`);
+ target[prop] = value;
+ return true;
+ }
+};
+
+const proxy = new Proxy(target, handler);
+console.log(proxy.message); // Logs: Accessing property: message
+proxy.message = 'World'; // Logs: Setting property: message = World
+```
+
+### Detection Markers
+- Implements same interface as real subject
+- Holds reference to real subject
+- Controls access (checks, logging, caching)
+- Lazy initialization of real subject
+
+### Common Mistakes
+- **Proxy chains**: Multiple proxies wrapping each other
+- **Performance overhead**: Every access goes through proxy
+- **Confusion with Decorator**: Proxy controls access; Decorator adds behavior
+
+---
+
+## Summary Table
+
+| Pattern | Complexity | Use Frequency | Main Benefit |
+|---------|------------|---------------|--------------|
+| Adapter | Low | High | Interface compatibility |
+| Bridge | High | Low | Decouple abstraction from implementation |
+| Composite | Medium | High | Uniform tree structure handling |
+| Decorator | Medium | High | Dynamic responsibility addition |
+| Facade | Low | Very High | Simplified subsystem interface |
+| Flyweight | High | Low | Memory optimization |
+| Proxy | Medium | Medium | Controlled access |
+
+## Best Practices
+
+1. **Adapter vs Bridge**: Adapter fixes incompatibility; Bridge designs flexibility
+2. **Decorator vs Proxy**: Decorator adds features; Proxy controls access
+3. **Facade simplicity**: Should coordinate, not contain business logic
+4. **Composite uniformity**: Leaf and Composite must share interface
+5. **Use native Proxy**: JavaScript `Proxy` object for dynamic property access
+
+## References
+
+- *Design Patterns: Elements of Reusable Object-Oriented Software* (Gang of Four)
+- [MDN: Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
+- [Refactoring Guru: Structural Patterns](https://refactoring.guru/design-patterns/structural-patterns)
diff --git a/examples/skills/design-patterns/signatures/code-smells.yaml b/examples/skills/design-patterns/signatures/code-smells.yaml
new file mode 100644
index 0000000..e5543a1
--- /dev/null
+++ b/examples/skills/design-patterns/signatures/code-smells.yaml
@@ -0,0 +1,478 @@
+version: "1.0.0"
+description: Mapping from code smells to applicable design patterns with detection rules and rationale
+
+# Code Smell Categories
+categories:
+ - bloaters # Code that has grown too large
+ - oo_abusers # Misuse of object-oriented principles
+ - change_preventers # Changes require modifications in many places
+ - dispensables # Pointless code that should be removed
+ - couplers # Excessive coupling between classes
+
+# Code Smells with Pattern Suggestions
+code_smells:
+ switch_on_type:
+ category: oo_abusers
+ description: "Switch statement (or if-else chain) discriminating on object type or kind"
+ severity: medium
+
+ detection:
+ patterns:
+ - "switch\\s*\\([^)]*\\.type\\)"
+ - "switch\\s*\\([^)]*\\.kind\\)"
+ - "if\\s*\\([^)]*instanceof\\s+\\w+\\).*else\\s+if\\s*\\([^)]*instanceof"
+ context: "Function or method with >3 cases"
+
+ suggested_patterns:
+ - pattern: strategy
+ priority: high
+ rationale: "Replace conditional logic with strategy objects"
+ example: |
+ // Before (smell)
+ switch (paymentType) {
+ case 'credit': return processCreditCard();
+ case 'paypal': return processPaypal();
+ case 'crypto': return processCrypto();
+ }
+
+ // After (Strategy)
+ const strategy = strategies[paymentType];
+ return strategy.process();
+
+ - pattern: factory-method
+ priority: medium
+ rationale: "If creating objects based on type"
+ example: |
+ // Before (smell)
+ switch (type) {
+ case 'A': return new ProductA();
+ case 'B': return new ProductB();
+ }
+
+ // After (Factory)
+ return ProductFactory.create(type);
+
+ long_parameter_list:
+ category: bloaters
+ description: "Function/constructor with more than 4 parameters"
+ severity: medium
+
+ detection:
+ patterns:
+ - "function\\s+\\w+\\s*\\([^)]{100,}\\)" # Heuristic: >100 chars
+ - "constructor\\s*\\([^)]{80,}\\)"
+ context: "Count commas in parameter list"
+
+ suggested_patterns:
+ - pattern: builder
+ priority: high
+ rationale: "Fluent interface for step-by-step construction"
+ example: |
+ // Before (smell)
+ new House(walls, doors, windows, roof, garage, pool, garden);
+
+ // After (Builder)
+ new HouseBuilder()
+ .setWalls(walls)
+ .setDoors(doors)
+ .build();
+
+ - pattern: parameter-object
+ priority: medium
+ rationale: "Group related parameters into object"
+ example: |
+ // Before (smell)
+ function createUser(name, email, age, address, phone, role) { }
+
+ // After (Parameter Object)
+ function createUser(userData: UserData) { }
+
+ global_state_access:
+ category: couplers
+ description: "Scattered access to global variables or singletons"
+ severity: high
+
+ detection:
+ patterns:
+ - "window\\.[A-Z]\\w+"
+ - "global\\.[A-Z]\\w+"
+ - "\\w+\\.getInstance\\(\\)"
+ context: "Outside of configuration/initialization files"
+
+ suggested_patterns:
+ - pattern: dependency-injection
+ priority: high
+ rationale: "Inject dependencies instead of global access"
+ example: |
+ // Before (smell)
+ const config = Config.getInstance();
+
+ // After (DI)
+ class Service {
+ constructor(private config: Config) {}
+ }
+
+ - pattern: singleton
+ priority: low
+ rationale: "If truly global state is needed (use sparingly)"
+ note: "Consider framework-native alternatives (React Context, Angular Services)"
+
+ duplicated_conditionals_on_state:
+ category: change_preventers
+ description: "Same state checks scattered across methods"
+ severity: medium
+
+ detection:
+ patterns:
+ - "if\\s*\\([^)]*\\.state\\s*===\\s*['\"]\\w+['\"]\\).*if\\s*\\([^)]*\\.state\\s*===\\s*['\"]\\w+['\"]\\)"
+ - "switch\\s*\\([^)]*\\.status\\)"
+ context: "Multiple methods with identical state checks"
+
+ suggested_patterns:
+ - pattern: state
+ priority: high
+ rationale: "Encapsulate state-dependent behavior in state classes"
+ example: |
+ // Before (smell)
+ if (order.status === 'draft') { /* ... */ }
+ else if (order.status === 'submitted') { /* ... */ }
+
+ // After (State pattern)
+ order.state.process(); // Behavior varies by state object
+
+ scattered_notification_logic:
+ category: change_preventers
+ description: "Manual notification loops in multiple places"
+ severity: medium
+
+ detection:
+ patterns:
+ - "listeners\\.forEach\\(\\s*\\w+\\s*=>\\s*\\w+\\.\\w+\\(\\)"
+ - "for\\s*\\([^)]*observers[^)]*\\).*\\.update\\("
+ context: "Multiple locations with similar notification code"
+
+ suggested_patterns:
+ - pattern: observer
+ priority: high
+ rationale: "Centralize subscription and notification mechanism"
+ example: |
+ // Before (smell)
+ for (const listener of this.listeners) {
+ listener.notify(data);
+ }
+
+ // After (Observer)
+ this.subject.notify(data); // Handles all observers
+
+ - pattern: event-emitter
+ priority: medium
+ rationale: "Use built-in EventEmitter (Node.js) or EventTarget"
+ stack_native:
+ javascript: "EventTarget, EventEmitter"
+ rxjs: "Subject, BehaviorSubject"
+
+ complex_object_creation:
+ category: bloaters
+ description: "Object construction requires many steps or conditional logic"
+ severity: medium
+
+ detection:
+ patterns:
+ - "new\\s+\\w+\\([^)]{80,}\\)" # Long constructor call
+ - "const\\s+\\w+\\s*=\\s*new\\s+\\w+\\(\\);[^}]{50,}\\w+\\.set\\w+"
+ context: "Construction spans multiple lines with setters"
+
+ suggested_patterns:
+ - pattern: builder
+ priority: high
+ rationale: "Step-by-step construction with fluent interface"
+
+ - pattern: factory-method
+ priority: medium
+ rationale: "Encapsulate creation logic"
+
+ - pattern: abstract-factory
+ priority: low
+ rationale: "If creating families of related objects"
+
+ tight_coupling_to_concrete_classes:
+ category: couplers
+ description: "Direct instantiation of concrete classes throughout codebase"
+ severity: medium
+
+ detection:
+ patterns:
+ - "new\\s+Concrete\\w+\\("
+ - "new\\s+\\w+Impl\\("
+ context: "Multiple files instantiating same concrete classes"
+
+ suggested_patterns:
+ - pattern: factory-method
+ priority: high
+ rationale: "Depend on interfaces, not concrete classes"
+
+ - pattern: dependency-injection
+ priority: high
+ rationale: "Inject dependencies instead of creating them"
+
+ - pattern: adapter
+ priority: medium
+ rationale: "If integrating incompatible third-party code"
+
+ repetitive_interface_conversions:
+ category: dispensables
+ description: "Manual conversion between incompatible interfaces"
+ severity: low
+
+ detection:
+ patterns:
+ - "\\{\\s*\\w+:\\s*\\w+\\.\\w+,.*\\w+:\\s*\\w+\\.\\w+" # Object mapping
+ context: "Same mapping logic repeated in multiple places"
+
+ suggested_patterns:
+ - pattern: adapter
+ priority: high
+ rationale: "Single adapter class for interface conversion"
+
+ deep_nesting_for_feature_addition:
+ category: change_preventers
+ description: "Adding features requires modifying deeply nested code"
+ severity: medium
+
+ detection:
+ patterns:
+ - "class\\s+\\w+\\s+extends\\s+\\w+\\s+extends\\s+\\w+" # Multi-level inheritance
+ context: "Inheritance hierarchy >3 levels deep"
+
+ suggested_patterns:
+ - pattern: decorator
+ priority: high
+ rationale: "Compose behavior dynamically instead of deep inheritance"
+
+ - pattern: strategy
+ priority: medium
+ rationale: "If behavior variants are swapped at runtime"
+
+ large_class_many_responsibilities:
+ category: bloaters
+ description: "Class has too many responsibilities (God Object)"
+ severity: high
+
+ detection:
+ patterns:
+ - "class\\s+\\w+\\s*\\{"
+ context: "Class >300 lines or >20 methods"
+
+ suggested_patterns:
+ - pattern: facade
+ priority: high
+ rationale: "If class coordinates multiple subsystems"
+
+ - pattern: strategy
+ priority: medium
+ rationale: "Extract varying behavior into strategies"
+
+ - pattern: extract-class
+ priority: high
+ rationale: "Split into multiple focused classes"
+
+ complex_conditional_logic:
+ category: bloaters
+ description: "Deeply nested conditionals or complex boolean expressions"
+ severity: medium
+
+ detection:
+ patterns:
+ - "if\\s*\\([^)]*&&[^)]*&&[^)]*\\)" # Multiple conditions
+ - "if\\s*\\(.*if\\s*\\(.*if\\s*\\(" # Nested ifs
+ context: "Cyclomatic complexity >10"
+
+ suggested_patterns:
+ - pattern: strategy
+ priority: high
+ rationale: "Replace conditional with strategy object"
+
+ - pattern: state
+ priority: medium
+ rationale: "If conditionals check object state"
+
+ - pattern: chain-of-responsibility
+ priority: low
+ rationale: "If processing steps can be chained"
+
+ data_clumps:
+ category: bloaters
+ description: "Same group of parameters appears together frequently"
+ severity: low
+
+ detection:
+ patterns:
+ - "function\\s+\\w+\\([^)]*userId[^)]*userName[^)]*userEmail[^)]*\\)"
+ context: "Same 3+ parameters in multiple functions"
+
+ suggested_patterns:
+ - pattern: parameter-object
+ priority: high
+ rationale: "Group related parameters into object"
+
+ - pattern: builder
+ priority: medium
+ rationale: "If object construction is complex"
+
+ manual_resource_management:
+ category: change_preventers
+ description: "Manual open/close, connect/disconnect, etc."
+ severity: medium
+
+ detection:
+ patterns:
+ - "open\\([^)]*\\);.*close\\("
+ - "connect\\([^)]*\\);.*disconnect\\("
+ context: "Scattered resource management logic"
+
+ suggested_patterns:
+ - pattern: template-method
+ priority: high
+ rationale: "Template ensures proper initialization/cleanup"
+
+ - pattern: proxy
+ priority: medium
+ rationale: "Proxy manages resource lifecycle"
+
+ feature_envy:
+ category: couplers
+ description: "Method uses more features of another class than its own"
+ severity: medium
+
+ detection:
+ patterns:
+ - "this\\.(\\w+\\.){3,}" # Multiple chained accesses
+ context: "Method heavily accesses another object's data"
+
+ suggested_patterns:
+ - pattern: extract-method
+ priority: high
+ rationale: "Move method to the class it envies"
+
+ - pattern: visitor
+ priority: low
+ rationale: "If operation needs to be external"
+
+ shotgun_surgery:
+ category: change_preventers
+ description: "Single change requires modifying many classes"
+ severity: high
+
+ detection:
+ manual: true
+ context: "Feature addition requires >5 file changes"
+
+ suggested_patterns:
+ - pattern: facade
+ priority: high
+ rationale: "Centralize interface to subsystem"
+
+ - pattern: mediator
+ priority: medium
+ rationale: "Centralize communication between objects"
+
+ - pattern: observer
+ priority: medium
+ rationale: "Decouple event sources from handlers"
+
+ parallel_inheritance_hierarchies:
+ category: change_preventers
+ description: "Adding subclass to one hierarchy requires adding to another"
+ severity: medium
+
+ detection:
+ manual: true
+ context: "Two inheritance trees grow together"
+
+ suggested_patterns:
+ - pattern: bridge
+ priority: high
+ rationale: "Separate abstraction from implementation"
+
+ refused_bequest:
+ category: oo_abusers
+ description: "Subclass doesn't use inherited methods"
+ severity: low
+
+ detection:
+ manual: true
+ context: "Subclass throws errors or leaves methods empty"
+
+ suggested_patterns:
+ - pattern: composition-over-inheritance
+ priority: high
+ rationale: "Use composition instead of inheritance"
+
+ - pattern: strategy
+ priority: medium
+ rationale: "Delegate to strategy object"
+
+# Detection Priority Rules
+detection_rules:
+ priority_high:
+ - "Affects >5 files"
+ - "Security implications"
+ - "Performance bottleneck"
+ - "Blocks new features"
+
+ priority_medium:
+ - "Affects 2-5 files"
+ - "Moderate complexity increase"
+ - "Makes testing harder"
+
+ priority_low:
+ - "Affects 1 file"
+ - "Minor code quality issue"
+ - "Cosmetic improvement"
+
+# Refactoring Impact Assessment
+impact_assessment:
+ effort:
+ low: "< 2 hours, single file"
+ medium: "2-8 hours, multiple files"
+ high: "> 8 hours, architectural change"
+
+ risk:
+ low: "Localized change, comprehensive tests exist"
+ medium: "Multiple components affected, partial test coverage"
+ high: "Core functionality, limited tests"
+
+ benefit:
+ low: "Minor code quality improvement"
+ medium: "Improved maintainability, easier testing"
+ high: "Significant complexity reduction, enables new features"
+
+# Stack-Specific Smell Detection
+stack_specific_smells:
+ react:
+ - smell: "Class components with complex lifecycle methods"
+ pattern: hooks
+ note: "Migrate to functional components with hooks"
+
+ - smell: "Props drilling >3 levels"
+ pattern: context
+ note: "Use Context API for shared state"
+
+ angular:
+ - smell: "Manual subscription management"
+ pattern: async-pipe
+ note: "Use async pipe in templates"
+
+ - smell: "Services with getInstance()"
+ pattern: dependency-injection
+ note: "Use Angular DI with @Injectable()"
+
+ nestjs:
+ - smell: "Manual middleware chaining"
+ pattern: guards-interceptors
+ note: "Use NestJS Guards/Interceptors"
+
+ express:
+ - smell: "Nested callback chains"
+ pattern: async-await
+ note: "Use async/await or Promises"
diff --git a/examples/skills/design-patterns/signatures/detection-rules.yaml b/examples/skills/design-patterns/signatures/detection-rules.yaml
new file mode 100644
index 0000000..cfd78a6
--- /dev/null
+++ b/examples/skills/design-patterns/signatures/detection-rules.yaml
@@ -0,0 +1,769 @@
+version: "1.0.0"
+description: Detection rules and heuristics for identifying design patterns in TypeScript/JavaScript code
+
+# Detection Strategy:
+# 1. Glob Phase: Find candidate files by naming convention
+# 2. Grep Phase: Search for primary and secondary signals
+# 3. Read Phase: Validate structure and relationships
+# 4. Confidence Scoring: Aggregate signal strengths
+
+# Creational Patterns
+creational:
+ singleton:
+ naming_conventions:
+ - "*Singleton*.ts"
+ - "*Manager.ts"
+ - "*Service.ts"
+ - "*Client.ts"
+ - "*Config.ts"
+ - "*Instance.ts"
+
+ primary_signals:
+ - pattern: "private\\s+constructor"
+ weight: 0.4
+ description: "Private constructor prevents direct instantiation"
+
+ - pattern: "static\\s+getInstance\\s*\\("
+ weight: 0.35
+ description: "Static getInstance method is canonical singleton signature"
+
+ - pattern: "private\\s+static\\s+\\w+:\\s*\\w+"
+ weight: 0.25
+ description: "Private static instance field"
+
+ secondary_signals:
+ - pattern: "if\\s*\\(!\\w+\\.instance\\)"
+ weight: 0.15
+ description: "Lazy initialization check"
+
+ - pattern: "return\\s+\\w+\\.instance"
+ weight: 0.10
+ description: "Returns singleton instance"
+
+ typescript_specific:
+ - pattern: "private\\s+static\\s+instance\\?:\\s*\\w+"
+ description: "TypeScript optional instance field"
+
+ - pattern: "public\\s+static\\s+getInstance\\(\\):\\s*\\w+"
+ description: "Explicit return type annotation"
+
+ anti_patterns:
+ - pattern: "new\\s+\\w+\\(\\).*getInstance"
+ description: "Creating new instance inside getInstance (wrong)"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ factory-method:
+ naming_conventions:
+ - "*Factory.ts"
+ - "*Creator.ts"
+ - "*Provider.ts"
+ - "*Builder.ts"
+
+ primary_signals:
+ - pattern: "create\\w+\\s*\\([^)]*\\):\\s*\\w+"
+ weight: 0.35
+ description: "create* method returning interface/type"
+
+ - pattern: "abstract\\s+create\\w+"
+ weight: 0.30
+ description: "Abstract factory method"
+
+ - pattern: "interface\\s+\\w+Factory"
+ weight: 0.20
+ description: "Factory interface definition"
+
+ secondary_signals:
+ - pattern: "class\\s+\\w+\\s+extends\\s+\\w+Factory"
+ weight: 0.15
+ description: "Concrete factory inheriting from abstract"
+
+ - pattern: "return\\s+new\\s+\\w+\\("
+ weight: 0.10
+ description: "Factory returns new instance"
+
+ - pattern: "switch\\s*\\([^)]*type[^)]*\\)"
+ weight: 0.15
+ description: "Type-based creation logic"
+
+ typescript_specific:
+ - pattern: "create\\w+]*>"
+ description: "Generic factory method"
+
+ confidence_threshold: 0.65
+ minimum_signals: 2
+
+ abstract-factory:
+ naming_conventions:
+ - "*AbstractFactory.ts"
+ - "*Factory.ts"
+ - "*FactoryInterface.ts"
+
+ primary_signals:
+ - pattern: "abstract\\s+class\\s+\\w+Factory"
+ weight: 0.30
+ description: "Abstract factory class"
+
+ - pattern: "interface\\s+\\w+Factory\\s*\\{[^}]*create\\w+[^}]*create\\w+"
+ weight: 0.35
+ description: "Factory interface with multiple create methods"
+
+ - pattern: "create\\w+\\s*\\([^)]*\\):\\s*\\w+.*create\\w+\\s*\\([^)]*\\):\\s*\\w+"
+ weight: 0.25
+ description: "Multiple factory methods"
+
+ secondary_signals:
+ - pattern: "class\\s+\\w+\\s+implements\\s+\\w+Factory"
+ weight: 0.15
+ description: "Concrete factory implementing interface"
+
+ - pattern: "family|related|product"
+ weight: 0.10
+ description: "Domain language suggesting related objects"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ builder:
+ naming_conventions:
+ - "*Builder.ts"
+ - "*ConfigBuilder.ts"
+ - "*QueryBuilder.ts"
+
+ primary_signals:
+ - pattern: "\\w+\\s*\\([^)]*\\):\\s*(this|\\w+Builder)"
+ weight: 0.30
+ description: "Fluent interface returning this or builder type"
+
+ - pattern: "build\\s*\\(\\):\\s*\\w+"
+ weight: 0.35
+ description: "Build method returning final product"
+
+ - pattern: "with\\w+\\s*\\([^)]*\\):\\s*this"
+ weight: 0.25
+ description: "with* methods for setting properties"
+
+ secondary_signals:
+ - pattern: "set\\w+\\s*\\([^)]*\\):\\s*this"
+ weight: 0.15
+ description: "set* methods returning this"
+
+ - pattern: "private\\s+\\w+\\?:\\s*\\w+"
+ weight: 0.10
+ description: "Optional private fields being built up"
+
+ typescript_specific:
+ - pattern: "class\\s+\\w+Builder"
+ description: "Typed array of components"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ decorator:
+ naming_conventions:
+ - "*Decorator.ts"
+ - "*Wrapper.ts"
+
+ primary_signals:
+ - pattern: "class\\s+\\w+Decorator\\s+implements\\s+\\w+"
+ weight: 0.30
+ description: "Decorator implements same interface"
+
+ - pattern: "protected\\s+wrapped:\\s*\\w+"
+ weight: 0.30
+ description: "Holds reference to wrapped object"
+
+ - pattern: "constructor\\([^)]*wrapped[^)]*\\)"
+ weight: 0.25
+ description: "Wrapped object injected"
+
+ secondary_signals:
+ - pattern: "this\\.wrapped\\.\\w+\\("
+ weight: 0.20
+ description: "Delegates to wrapped object"
+
+ - pattern: "super\\(wrapped\\)"
+ weight: 0.15
+ description: "Passes wrapped to base decorator"
+
+ typescript_specific:
+ - pattern: "@\\w+"
+ description: "TypeScript decorator syntax (different usage)"
+
+ confidence_threshold: 0.65
+ minimum_signals: 2
+
+ facade:
+ naming_conventions:
+ - "*Facade.ts"
+ - "*API.ts"
+ - "*Interface.ts"
+ - "*Service.ts"
+
+ primary_signals:
+ - pattern: "private\\s+\\w+Service:\\s*\\w+;[^}]*private\\s+\\w+Service:\\s*\\w+"
+ weight: 0.35
+ description: "Multiple subsystem dependencies"
+
+ - pattern: "constructor\\([^)]*,\\s*[^)]*,\\s*[^)]*\\)"
+ weight: 0.25
+ description: "Multiple injected dependencies"
+
+ secondary_signals:
+ - pattern: "this\\.\\w+Service\\.\\w+\\([^)]*\\);[^}]*this\\.\\w+Service\\.\\w+\\("
+ weight: 0.20
+ description: "Coordinates multiple subsystems"
+
+ - pattern: "public\\s+async\\s+\\w+\\([^)]*\\)"
+ weight: 0.10
+ description: "Simplified public interface"
+
+ confidence_threshold: 0.60
+ minimum_signals: 2
+
+ flyweight:
+ naming_conventions:
+ - "*Flyweight.ts"
+ - "*Pool.ts"
+ - "*Cache.ts"
+
+ primary_signals:
+ - pattern: "private\\s+static\\s+pool:\\s*Map"
+ weight: 0.35
+ description: "Shared pool of flyweights"
+
+ - pattern: "getFlyweight\\s*\\([^)]*\\):\\s*\\w+"
+ weight: 0.30
+ description: "Factory method for shared objects"
+
+ - pattern: "if\\s*\\(!pool\\.has\\([^)]*\\)\\)"
+ weight: 0.25
+ description: "Check if flyweight exists before creating"
+
+ secondary_signals:
+ - pattern: "intrinsic|extrinsic"
+ weight: 0.15
+ description: "Domain language for shared/unique state"
+
+ confidence_threshold: 0.65
+ minimum_signals: 2
+
+ proxy:
+ naming_conventions:
+ - "*Proxy.ts"
+
+ primary_signals:
+ - pattern: "class\\s+\\w+Proxy\\s+implements\\s+\\w+"
+ weight: 0.30
+ description: "Proxy implements same interface as real subject"
+
+ - pattern: "private\\s+realSubject:\\s*\\w+"
+ weight: 0.30
+ description: "Holds reference to real subject"
+
+ - pattern: "lazy|cache|access|log"
+ weight: 0.20
+ description: "Proxy purpose keywords"
+
+ secondary_signals:
+ - pattern: "if\\s*\\(!this\\.realSubject\\)"
+ weight: 0.15
+ description: "Lazy initialization"
+
+ - pattern: "this\\.realSubject\\.\\w+\\("
+ weight: 0.15
+ description: "Delegates to real subject"
+
+ typescript_specific:
+ - pattern: "new\\s+Proxy\\("
+ description: "JavaScript Proxy object"
+
+ confidence_threshold: 0.65
+ minimum_signals: 2
+
+# Behavioral Patterns
+behavioral:
+ chain-of-responsibility:
+ naming_conventions:
+ - "*Handler.ts"
+ - "*Middleware.ts"
+ - "*Chain.ts"
+
+ primary_signals:
+ - pattern: "protected\\s+next:\\s*\\w+Handler"
+ weight: 0.35
+ description: "Reference to next handler"
+
+ - pattern: "setNext\\s*\\([^)]*\\):\\s*\\w+Handler"
+ weight: 0.30
+ description: "Method to set next handler"
+
+ - pattern: "handle\\s*\\([^)]*\\):"
+ weight: 0.25
+ description: "Handle method"
+
+ secondary_signals:
+ - pattern: "if\\s*\\(this\\.next\\)"
+ weight: 0.15
+ description: "Checks if next handler exists"
+
+ - pattern: "this\\.next\\.handle\\("
+ weight: 0.15
+ description: "Passes request to next"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ command:
+ naming_conventions:
+ - "*Command.ts"
+ - "*Action.ts"
+
+ primary_signals:
+ - pattern: "interface\\s+\\w+Command\\s*\\{[^}]*execute"
+ weight: 0.35
+ description: "Command interface with execute"
+
+ - pattern: "execute\\s*\\(\\):"
+ weight: 0.30
+ description: "Execute method"
+
+ - pattern: "undo\\s*\\(\\):"
+ weight: 0.25
+ description: "Undo method for reversibility"
+
+ secondary_signals:
+ - pattern: "private\\s+receiver:\\s*\\w+"
+ weight: 0.15
+ description: "Holds receiver reference"
+
+ - pattern: "history|stack"
+ weight: 0.10
+ description: "Command history tracking"
+
+ confidence_threshold: 0.65
+ minimum_signals: 2
+
+ iterator:
+ naming_conventions:
+ - "*Iterator.ts"
+
+ primary_signals:
+ - pattern: "\\[Symbol\\.iterator\\]\\(\\)"
+ weight: 0.40
+ description: "JavaScript iterator protocol"
+
+ - pattern: "next\\s*\\(\\):\\s*\\{\\s*value[^}]*done"
+ weight: 0.35
+ description: "Iterator next method"
+
+ - pattern: "function\\*|\\*\\w+\\s*\\("
+ weight: 0.25
+ description: "Generator function"
+
+ secondary_signals:
+ - pattern: "yield"
+ weight: 0.15
+ description: "Generator yield"
+
+ - pattern: "implements\\s+Iterator<"
+ weight: 0.15
+ description: "Implements Iterator interface"
+
+ confidence_threshold: 0.65
+ minimum_signals: 1
+
+ mediator:
+ naming_conventions:
+ - "*Mediator.ts"
+ - "*Controller.ts"
+ - "*Coordinator.ts"
+
+ primary_signals:
+ - pattern: "class\\s+\\w+Mediator"
+ weight: 0.30
+ description: "Mediator class"
+
+ - pattern: "private\\s+colleagues:\\s*\\w+\\[\\]"
+ weight: 0.30
+ description: "Collection of colleagues"
+
+ - pattern: "notify\\s*\\([^)]*sender[^)]*\\)"
+ weight: 0.30
+ description: "Notify method with sender"
+
+ secondary_signals:
+ - pattern: "register\\w+\\(|add\\w+\\("
+ weight: 0.15
+ description: "Register colleagues"
+
+ confidence_threshold: 0.65
+ minimum_signals: 2
+
+ memento:
+ naming_conventions:
+ - "*Memento.ts"
+ - "*Snapshot.ts"
+ - "*Caretaker.ts"
+
+ primary_signals:
+ - pattern: "save\\s*\\(\\):\\s*\\w+Memento"
+ weight: 0.35
+ description: "Save state to memento"
+
+ - pattern: "restore\\s*\\([^)]*memento[^)]*\\)"
+ weight: 0.35
+ description: "Restore from memento"
+
+ - pattern: "class\\s+\\w+Memento"
+ weight: 0.20
+ description: "Memento class"
+
+ secondary_signals:
+ - pattern: "private\\s+state:"
+ weight: 0.15
+ description: "Encapsulated state"
+
+ - pattern: "history:\\s*\\w+\\[\\]"
+ weight: 0.10
+ description: "History of mementos"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ observer:
+ naming_conventions:
+ - "*Observer.ts"
+ - "*Subject.ts"
+ - "*Publisher.ts"
+ - "*Subscriber.ts"
+ - "*Event*.ts"
+
+ primary_signals:
+ - pattern: "subscribe\\s*\\([^)]*\\):|attach\\s*\\([^)]*\\):"
+ weight: 0.30
+ description: "Subscribe method"
+
+ - pattern: "unsubscribe\\s*\\([^)]*\\):|detach\\s*\\([^)]*\\):"
+ weight: 0.25
+ description: "Unsubscribe method"
+
+ - pattern: "notify\\s*\\(\\):|emit\\s*\\("
+ weight: 0.30
+ description: "Notify/emit method"
+
+ secondary_signals:
+ - pattern: "private\\s+observers:\\s*\\w+\\[\\]"
+ weight: 0.20
+ description: "Collection of observers"
+
+ - pattern: "observers\\.forEach\\("
+ weight: 0.15
+ description: "Iterates over observers to notify"
+
+ typescript_specific:
+ - pattern: "Subject<"
+ description: "RxJS Subject (common in Angular/React)"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ state:
+ naming_conventions:
+ - "*State.ts"
+ - "*Context.ts"
+
+ primary_signals:
+ - pattern: "interface\\s+\\w+State"
+ weight: 0.30
+ description: "State interface"
+
+ - pattern: "private\\s+state:\\s*\\w+State"
+ weight: 0.30
+ description: "Context holds current state"
+
+ - pattern: "setState\\s*\\([^)]*\\):|changeState\\s*\\([^)]*\\):"
+ weight: 0.30
+ description: "Method to change state"
+
+ secondary_signals:
+ - pattern: "this\\.state\\.handle\\("
+ weight: 0.15
+ description: "Delegates to state"
+
+ - pattern: "class\\s+\\w+State\\s+implements\\s+\\w+State"
+ weight: 0.15
+ description: "Concrete state classes"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ strategy:
+ naming_conventions:
+ - "*Strategy.ts"
+ - "*Policy.ts"
+ - "*Algorithm.ts"
+
+ primary_signals:
+ - pattern: "interface\\s+\\w+Strategy"
+ weight: 0.35
+ description: "Strategy interface"
+
+ - pattern: "private\\s+strategy:\\s*\\w+Strategy"
+ weight: 0.30
+ description: "Context holds strategy"
+
+ - pattern: "setStrategy\\s*\\([^)]*\\):"
+ weight: 0.25
+ description: "Method to set strategy"
+
+ secondary_signals:
+ - pattern: "this\\.strategy\\.execute\\("
+ weight: 0.15
+ description: "Delegates to strategy"
+
+ - pattern: "class\\s+\\w+Strategy\\s+implements\\s+\\w+Strategy"
+ weight: 0.15
+ description: "Concrete strategies"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ template-method:
+ naming_conventions:
+ - "*Template.ts"
+ - "*Abstract*.ts"
+
+ primary_signals:
+ - pattern: "abstract\\s+class"
+ weight: 0.30
+ description: "Abstract class with template"
+
+ - pattern: "abstract\\s+\\w+\\s*\\(\\):"
+ weight: 0.30
+ description: "Abstract primitive operations"
+
+ - pattern: "protected\\s+\\w+\\s*\\(\\):"
+ weight: 0.20
+ description: "Hook methods"
+
+ secondary_signals:
+ - pattern: "this\\.\\w+\\(\\);[^}]*this\\.\\w+\\(\\);"
+ weight: 0.15
+ description: "Template calls primitive operations"
+
+ - pattern: "final\\s+|\\btemplate\\b"
+ weight: 0.10
+ description: "Template method should be final (not overridden)"
+
+ confidence_threshold: 0.65
+ minimum_signals: 2
+
+ visitor:
+ naming_conventions:
+ - "*Visitor.ts"
+
+ primary_signals:
+ - pattern: "interface\\s+\\w+Visitor\\s*\\{[^}]*visit\\w+"
+ weight: 0.35
+ description: "Visitor interface with visit methods"
+
+ - pattern: "visit\\w+\\s*\\([^)]*:\\s*\\w+\\)"
+ weight: 0.30
+ description: "Visit methods for each element type"
+
+ - pattern: "accept\\s*\\([^)]*visitor[^)]*\\)"
+ weight: 0.30
+ description: "Elements accept visitor"
+
+ secondary_signals:
+ - pattern: "visitor\\.visit\\w+\\(this\\)"
+ weight: 0.15
+ description: "Double dispatch pattern"
+
+ confidence_threshold: 0.70
+ minimum_signals: 2
+
+ interpreter:
+ naming_conventions:
+ - "*Interpreter.ts"
+ - "*Expression.ts"
+ - "*Parser.ts"
+
+ primary_signals:
+ - pattern: "interface\\s+\\w+Expression"
+ weight: 0.30
+ description: "Expression interface"
+
+ - pattern: "interpret\\s*\\([^)]*context[^)]*\\)"
+ weight: 0.35
+ description: "Interpret method with context"
+
+ - pattern: "abstract\\s+class\\s+\\w+Expression"
+ weight: 0.25
+ description: "Abstract expression"
+
+ secondary_signals:
+ - pattern: "class\\s+Terminal\\w+|class\\s+NonTerminal\\w+"
+ weight: 0.15
+ description: "Terminal and non-terminal expressions"
+
+ - pattern: "parse\\s*\\("
+ weight: 0.10
+ description: "Parser for grammar"
+
+ confidence_threshold: 0.60
+ minimum_signals: 2
+
+# Confidence Calculation
+confidence_calculation:
+ formula: "sum(matched_signal_weights) / sum(all_possible_weights)"
+ adjustments:
+ - "If pattern name matches naming convention: +0.15"
+ - "If stack has native equivalent and not used: -0.20"
+ - "If anti-pattern detected: -0.30"
+ - "If typescript-specific signals present: +0.10"
+
+# Output Format for Detection Results
+detection_output:
+ file: "path/to/file.ts"
+ pattern: "singleton"
+ lines: "5-28"
+ confidence: 0.85
+ matched_signals:
+ - signal: "private constructor"
+ weight: 0.4
+ - signal: "static getInstance"
+ weight: 0.35
+ stack_context:
+ native_alternative: "Context API"
+ recommendation: "Consider using React Context for better testability"
diff --git a/examples/skills/design-patterns/signatures/stack-patterns.yaml b/examples/skills/design-patterns/signatures/stack-patterns.yaml
new file mode 100644
index 0000000..33755a5
--- /dev/null
+++ b/examples/skills/design-patterns/signatures/stack-patterns.yaml
@@ -0,0 +1,582 @@
+version: "1.0.0"
+description: Stack detection rules and pattern adaptations for framework-native idioms
+
+# Stack Detection Rules
+stack_detection:
+ sources:
+ - file: "package.json"
+ check: "dependencies + devDependencies"
+ priority: 1
+ - file: "tsconfig.json"
+ check: "compilerOptions, paths, lib"
+ priority: 2
+ - files: ["angular.json", "next.config.*", "nest-cli.json", "vite.config.*", "nuxt.config.*"]
+ check: "presence"
+ priority: 1
+ - pattern: "*.jsx, *.tsx, *.vue, *.svelte"
+ check: "file extensions"
+ priority: 3
+
+ confidence_scoring:
+ high: "Primary framework found in package.json + config file present"
+ medium: "Framework in package.json OR config file present"
+ low: "Only file extensions or indirect evidence"
+
+# Supported Stacks
+stacks:
+ react:
+ detection:
+ package_json:
+ required: ["react"]
+ optional: ["react-dom", "next", "@types/react"]
+ files:
+ optional: ["next.config.js", "next.config.ts", "vite.config.ts"]
+ extensions: [".jsx", ".tsx"]
+
+ version_detection:
+ hooks_era: ">=16.8.0" # useState, useEffect introduced
+ concurrent: ">=18.0.0" # Concurrent features
+
+ native_patterns:
+ singleton:
+ replacement: "Context API + Provider"
+ example: |
+ // Instead of Singleton
+ const MyContext = createContext(defaultValue);
+ export const MyProvider = ({ children }) => (
+ {children}
+ );
+ rationale: "Context provides dependency injection without global state"
+ confidence: 0.95
+
+ observer:
+ replacement: "useState + useEffect"
+ example: |
+ const [value, setValue] = useState(initial);
+ useEffect(() => {
+ // React auto-notifies subscribers
+ }, [value]);
+ rationale: "React's reactivity system is built-in observer pattern"
+ confidence: 0.98
+
+ strategy:
+ replacement: "Custom hooks"
+ example: |
+ const usePaymentStrategy = (type: PaymentType) => {
+ const strategies = {
+ credit: useCreditPayment(),
+ paypal: usePaypalPayment(),
+ };
+ return strategies[type];
+ };
+ rationale: "Hooks encapsulate behavior and are composable"
+ confidence: 0.90
+
+ decorator:
+ replacement: "Higher-Order Components (HOC)"
+ example: |
+ const withAuth = (Component: React.ComponentType
) => {
+ return (props: P) => {
+ const { user } = useAuth();
+ if (!user) return ;
+ return ;
+ };
+ };
+ rationale: "HOCs wrap components to add behavior"
+ confidence: 0.85
+
+ mediator:
+ replacement: "Context API"
+ example: |
+ // Centralized state management
+ const AppContext = createContext(initialState);
+ // Components communicate through context
+ rationale: "Context mediates communication between components"
+ confidence: 0.80
+
+ recommendations:
+ - "Prefer hooks over class-based patterns"
+ - "Use Context for shared state, not Singleton"
+ - "Leverage built-in reactivity instead of manual observer"
+ - "Consider React Query/SWR for data fetching patterns"
+
+ angular:
+ detection:
+ package_json:
+ required: ["@angular/core"]
+ optional: ["@angular/common", "@angular/platform-browser"]
+ files:
+ required: ["angular.json"]
+ extensions: [".ts"]
+
+ version_detection:
+ standalone: ">=14.0.0" # Standalone components
+ signals: ">=16.0.0" # Signals API
+
+ native_patterns:
+ singleton:
+ replacement: "@Injectable() services"
+ example: |
+ @Injectable({ providedIn: 'root' })
+ export class ConfigService {
+ // Automatically singleton via DI
+ }
+ rationale: "Angular's DI container manages singleton lifecycle"
+ confidence: 0.98
+
+ observer:
+ replacement: "RxJS Observables"
+ example: |
+ import { BehaviorSubject } from 'rxjs';
+ private data$ = new BehaviorSubject(initial);
+ getData() { return this.data$.asObservable(); }
+ rationale: "RxJS is Angular's standard reactive programming library"
+ confidence: 0.98
+
+ decorator:
+ replacement: "Directives and Pipes"
+ example: |
+ @Directive({ selector: '[appHighlight]' })
+ export class HighlightDirective {
+ // Adds behavior to DOM elements
+ }
+ rationale: "Angular decorators are first-class pattern"
+ confidence: 0.95
+
+ facade:
+ replacement: "Service with injected dependencies"
+ example: |
+ @Injectable()
+ export class UserFacade {
+ constructor(
+ private userService: UserService,
+ private authService: AuthService,
+ private profileService: ProfileService
+ ) {}
+ }
+ rationale: "Services naturally encapsulate subsystems"
+ confidence: 0.90
+
+ recommendations:
+ - "Use DI instead of manual singleton patterns"
+ - "Leverage RxJS for all reactive patterns"
+ - "Use Angular decorators (@Component, @Directive, @Pipe)"
+ - "Services should be injected, not manually instantiated"
+
+ nestjs:
+ detection:
+ package_json:
+ required: ["@nestjs/core"]
+ optional: ["@nestjs/common", "@nestjs/platform-express"]
+ files:
+ required: ["nest-cli.json"]
+ extensions: [".ts"]
+
+ native_patterns:
+ singleton:
+ replacement: "@Injectable() with default scope"
+ example: |
+ @Injectable() // Default scope is SINGLETON
+ export class AppService {}
+ rationale: "NestJS DI uses singleton scope by default"
+ confidence: 0.98
+
+ chain-of-responsibility:
+ replacement: "Guards, Interceptors, Pipes, Middleware"
+ example: |
+ @Injectable()
+ export class AuthGuard implements CanActivate {
+ canActivate(context: ExecutionContext): boolean {
+ // Guard chain
+ }
+ }
+ rationale: "NestJS request pipeline is built-in chain pattern"
+ confidence: 0.95
+
+ decorator:
+ replacement: "Interceptors"
+ example: |
+ @Injectable()
+ export class LoggingInterceptor implements NestInterceptor {
+ intercept(context: ExecutionContext, next: CallHandler) {
+ // Wraps request handling
+ }
+ }
+ rationale: "Interceptors add behavior to route handlers"
+ confidence: 0.95
+
+ facade:
+ replacement: "Modules"
+ example: |
+ @Module({
+ providers: [ServiceA, ServiceB],
+ exports: [FacadeService]
+ })
+ export class FeatureModule {}
+ rationale: "Modules encapsulate and export simplified interfaces"
+ confidence: 0.85
+
+ factory:
+ replacement: "useFactory provider"
+ example: |
+ {
+ provide: 'CONFIG',
+ useFactory: (env: EnvService) => createConfig(env),
+ inject: [EnvService]
+ }
+ rationale: "DI supports factory pattern natively"
+ confidence: 0.90
+
+ recommendations:
+ - "Use built-in DI, never manual singleton"
+ - "Leverage Guards/Interceptors/Pipes for cross-cutting concerns"
+ - "Modules should export facades to subsystems"
+ - "Use dynamic modules for configurable features"
+
+ vue:
+ detection:
+ package_json:
+ required: ["vue"]
+ version: ">=3.0.0"
+ files:
+ optional: ["vite.config.ts", "nuxt.config.ts"]
+ extensions: [".vue"]
+
+ version_detection:
+ composition_api: ">=3.0.0" # Composition API default
+ script_setup: ">=3.2.0" #