@itz4blitz/agentful 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -301,6 +301,38 @@ For hierarchical structure examples, check:
301
301
 
302
302
  **No**: The system auto-detects ONE format. Choose the format that best fits your project size and complexity.
303
303
 
304
+ ## Product Analysis File
305
+
306
+ After running `/agentful-product`, a `product-analysis.json` file is generated:
307
+
308
+ ```bash
309
+ .claude/product/
310
+ ├── index.md # Your product spec (template)
311
+ └── product-analysis.json # Generated analysis (created by /agentful-product)
312
+ ```
313
+
314
+ **Key points:**
315
+ - **Not in templates**: This file doesn't exist in the agentful package itself
316
+ - **Generated on demand**: Created when you run `/agentful-product` in your project
317
+ - **Purpose**: Analyzes your product spec for completeness, clarity, feasibility, testability, and consistency
318
+ - **Scores readiness**: 0-100% score with blocking issues and recommendations
319
+ - **Version controlled**: Commit to git to track spec quality improvements over time
320
+
321
+ **Example content:**
322
+ ```json
323
+ {
324
+ "version": "1.0",
325
+ "timestamp": "2026-01-20T00:00:00Z",
326
+ "readiness_score": 75,
327
+ "dimensions": {
328
+ "completeness": { "score": 85 },
329
+ "clarity": { "score": 90 }
330
+ },
331
+ "blocking_issues": [],
332
+ "can_start_development": true
333
+ }
334
+ ```
335
+
304
336
  ## Summary
305
337
 
306
338
  | Format | Best For | Tracking | File Structure |
package/bin/cli.js CHANGED
@@ -11,6 +11,7 @@ import { fileURLToPath } from 'url';
11
11
  import { analyzeProject, exportToArchitectureJson } from '../lib/project-analyzer.js';
12
12
  import AgentGenerator from '../lib/agent-generator.js';
13
13
  import DomainStructureGenerator from '../lib/domain-structure-generator.js';
14
+ import { detectTechStack } from '../lib/tech-stack-detector.js';
14
15
 
15
16
  const __filename = fileURLToPath(import.meta.url);
16
17
  const __dirname = path.dirname(__filename);
@@ -582,87 +583,13 @@ function showStatus() {
582
583
  console.log('');
583
584
  }
584
585
 
585
- function detectTechStack() {
586
- const targetDir = process.cwd();
587
- const detected = {
588
- language: null,
589
- framework: null,
590
- dependencies: [],
591
- devDependencies: []
592
- };
593
-
594
- // Check for package.json (Node.js/JavaScript/TypeScript)
595
- const packageJsonPath = path.join(targetDir, 'package.json');
596
- if (fs.existsSync(packageJsonPath)) {
597
- try {
598
- const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
599
- detected.dependencies = Object.keys(pkg.dependencies || {});
600
- detected.devDependencies = Object.keys(pkg.devDependencies || {});
601
- detected.language = pkg.type === 'module' ? 'TypeScript/ESM' : 'JavaScript/TypeScript';
602
-
603
- // Detect framework
604
- if (detected.dependencies.includes('next')) {
605
- detected.framework = 'Next.js';
606
- } else if (detected.dependencies.includes('react')) {
607
- detected.framework = 'React';
608
- } else if (detected.dependencies.includes('vue')) {
609
- detected.framework = 'Vue';
610
- } else if (detected.dependencies.includes('express')) {
611
- detected.framework = 'Express';
612
- } else if (detected.dependencies.includes('nestjs')) {
613
- detected.framework = 'NestJS';
614
- }
615
- } catch (err) {
616
- log(colors.yellow, '⚠️ Could not parse package.json');
617
- }
618
- }
619
-
620
- // Check for requirements.txt or pyproject.toml (Python)
621
- const requirementsPath = path.join(targetDir, 'requirements.txt');
622
- const pyprojectPath = path.join(targetDir, 'pyproject.toml');
623
- if (fs.existsSync(requirementsPath) || fs.existsSync(pyprojectPath)) {
624
- detected.language = 'Python';
625
- const requirements = fs.existsSync(requirementsPath)
626
- ? fs.readFileSync(requirementsPath, 'utf-8')
627
- : '';
628
- if (requirements.includes('django')) detected.framework = 'Django';
629
- else if (requirements.includes('flask')) detected.framework = 'Flask';
630
- else if (requirements.includes('fastapi')) detected.framework = 'FastAPI';
631
- }
632
-
633
- // Check for go.mod (Go)
634
- if (fs.existsSync(path.join(targetDir, 'go.mod'))) {
635
- detected.language = 'Go';
636
- detected.framework = 'Standard Library';
637
- }
638
-
639
- // Check for Cargo.toml (Rust)
640
- if (fs.existsSync(path.join(targetDir, 'Cargo.toml'))) {
641
- detected.language = 'Rust';
642
- }
643
-
644
- // Check for .csproj or .fsproj (C#/.NET)
645
- const csprojFiles = fs.readdirSync(targetDir).filter(f => f.endsWith('.csproj'));
646
- if (csprojFiles.length > 0) {
647
- detected.language = 'C#';
648
- detected.framework = 'ASP.NET';
649
- }
650
-
651
- // Check for pom.xml (Java)
652
- if (fs.existsSync(path.join(targetDir, 'pom.xml'))) {
653
- detected.language = 'Java';
654
- detected.framework = 'Maven';
655
- }
656
-
657
- return detected;
658
- }
659
-
660
586
  function generateAgentPrompt(stack) {
661
587
  let prompt = `# Tech Stack Analysis\n\n`;
662
588
  prompt += `**Language**: ${stack.language || 'Unknown'}\n`;
663
- prompt += `**Framework**: ${stack.framework || 'None'}\n\n`;
589
+ const primaryFramework = stack.frameworks && stack.frameworks.length > 0 ? stack.frameworks[0] : null;
590
+ prompt += `**Framework**: ${primaryFramework || 'None'}\n\n`;
664
591
 
665
- if (stack.dependencies.length > 0) {
592
+ if (stack.dependencies && stack.dependencies.length > 0) {
666
593
  prompt += `**Key Dependencies**:\n`;
667
594
  stack.dependencies.slice(0, 10).forEach(dep => {
668
595
  prompt += `- ${dep}\n`;
@@ -724,11 +651,11 @@ async function generateAgents() {
724
651
  process.exit(1);
725
652
  }
726
653
 
727
- // Detect tech stack
654
+ // Detect tech stack using library function
728
655
  log(colors.dim, 'Analyzing tech stack...');
729
- const stack = detectTechStack();
656
+ const stack = await detectTechStack(process.cwd());
730
657
 
731
- if (!stack.language) {
658
+ if (!stack.language || stack.language === 'unknown') {
732
659
  log(colors.yellow, '⚠️ Could not detect language/framework');
733
660
  log(colors.dim, 'Supported: Node.js, Python, Go, Rust, C#, Java');
734
661
  console.log('');
@@ -739,7 +666,8 @@ async function generateAgents() {
739
666
  return;
740
667
  }
741
668
 
742
- log(colors.green, `✓ Detected: ${stack.language} ${stack.framework ? `(${stack.framework})` : ''}`);
669
+ const primaryFramework = stack.frameworks.length > 0 ? stack.frameworks[0] : null;
670
+ log(colors.green, `✓ Detected: ${stack.language} ${primaryFramework ? `(${primaryFramework})` : ''}`);
743
671
  log(colors.dim, ` Dependencies: ${stack.dependencies.length} packages`);
744
672
 
745
673
  // Update architecture.json
@@ -762,7 +690,7 @@ async function generateAgents() {
762
690
 
763
691
  log(colors.bright, 'Detected Stack:');
764
692
  if (stack.language) log(colors.cyan, ` Language: ${stack.language}`);
765
- if (stack.framework) log(colors.cyan, ` Framework: ${stack.framework}`);
693
+ if (primaryFramework) log(colors.cyan, ` Framework: ${primaryFramework}`);
766
694
  if (stack.dependencies.length > 0) {
767
695
  log(colors.cyan, ` Dependencies: ${stack.dependencies.length} packages`);
768
696
  }
@@ -13,12 +13,124 @@ import TemplateEngine from './template-engine.js';
13
13
  const __filename = fileURLToPath(import.meta.url);
14
14
  const __dirname = path.dirname(__filename);
15
15
 
16
+ /**
17
+ * Default core agent types registry
18
+ * Users can extend this by passing custom agent types to the constructor
19
+ */
20
+ const DEFAULT_CORE_AGENT_TYPES = ['backend', 'frontend', 'tester', 'reviewer', 'fixer'];
21
+
22
+ /**
23
+ * Default agent patterns configuration
24
+ * Defines how each agent type should extract patterns from the codebase
25
+ */
26
+ const DEFAULT_AGENT_PATTERNS = {
27
+ backend: {
28
+ directories: ['src/repositories', 'src/services', 'src/controllers', 'src/routes', 'api'],
29
+ keywords: ['repository', 'service', 'controller', 'route', 'handler'],
30
+ },
31
+ frontend: {
32
+ directories: ['src/components', 'src/pages', 'src/app', 'components', 'pages'],
33
+ keywords: ['component', 'hook', 'page', 'view'],
34
+ },
35
+ tester: {
36
+ directories: ['tests', 'test', '__tests__', '__tests__', 'spec'],
37
+ keywords: ['describe', 'test', 'it', 'expect', 'mock'],
38
+ },
39
+ reviewer: {
40
+ directories: ['src'],
41
+ keywords: ['export', 'function', 'class', 'interface'],
42
+ },
43
+ fixer: {
44
+ directories: ['src'],
45
+ keywords: ['error', 'bug', 'fix', 'throw'],
46
+ },
47
+ };
48
+
16
49
  class AgentGenerator {
17
- constructor(projectPath, analysis) {
50
+ /**
51
+ * @param {string} projectPath - Path to the project
52
+ * @param {object} analysis - Project analysis results
53
+ * @param {object} options - Configuration options
54
+ * @param {string[]} options.customAgentTypes - Additional core agent types to generate
55
+ * @param {object} options.customAgentPatterns - Pattern configurations for custom agent types
56
+ */
57
+ constructor(projectPath, analysis, options = {}) {
18
58
  this.projectPath = projectPath;
19
59
  this.analysis = analysis;
20
60
  this.templatesDir = path.join(__dirname, '../templates/agents');
21
61
  this.agentsDir = path.join(projectPath, '.claude/agents/auto-generated');
62
+
63
+ // Extensible agent type registry
64
+ this.coreAgentTypes = [...DEFAULT_CORE_AGENT_TYPES];
65
+ this.agentPatterns = { ...DEFAULT_AGENT_PATTERNS };
66
+
67
+ // Apply custom agent types if provided
68
+ if (options.customAgentTypes && Array.isArray(options.customAgentTypes)) {
69
+ this.coreAgentTypes.push(...options.customAgentTypes);
70
+ }
71
+
72
+ // Apply custom agent patterns if provided
73
+ if (options.customAgentPatterns && typeof options.customAgentPatterns === 'object') {
74
+ Object.assign(this.agentPatterns, options.customAgentPatterns);
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Register a custom agent type at runtime
80
+ * @param {string} type - Agent type name
81
+ * @param {object} pattern - Pattern configuration for the agent type
82
+ * @param {string[]} pattern.directories - Directories to scan for this agent type
83
+ * @param {string[]} pattern.keywords - Keywords to look for in code
84
+ */
85
+ registerAgentType(type, pattern) {
86
+ if (!this.coreAgentTypes.includes(type)) {
87
+ this.coreAgentTypes.push(type);
88
+ }
89
+
90
+ if (pattern) {
91
+ this.agentPatterns[type] = pattern;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Get all registered core agent types
97
+ * @returns {string[]} List of core agent types
98
+ */
99
+ getCoreAgentTypes() {
100
+ return [...this.coreAgentTypes];
101
+ }
102
+
103
+ /**
104
+ * Get pattern configuration for a specific agent type
105
+ * @param {string} type - Agent type name
106
+ * @returns {object|null} Pattern configuration or null if not found
107
+ */
108
+ getAgentPattern(type) {
109
+ return this.agentPatterns[type] || null;
110
+ }
111
+
112
+ /**
113
+ * Load custom agent types from a configuration file
114
+ * @param {string} configPath - Path to the configuration file (JSON)
115
+ * @returns {Promise<void>}
116
+ */
117
+ async loadCustomAgentTypesFromConfig(configPath) {
118
+ try {
119
+ const content = await fs.readFile(configPath, 'utf-8');
120
+ const config = JSON.parse(content);
121
+
122
+ if (config.customAgentTypes && Array.isArray(config.customAgentTypes)) {
123
+ for (const agentConfig of config.customAgentTypes) {
124
+ if (agentConfig.type && agentConfig.pattern) {
125
+ this.registerAgentType(agentConfig.type, agentConfig.pattern);
126
+ }
127
+ }
128
+ }
129
+
130
+ console.log(`✅ Loaded custom agent types from ${configPath}`);
131
+ } catch (error) {
132
+ console.warn(`⚠️ Could not load custom agent types from ${configPath}: ${error.message}`);
133
+ }
22
134
  }
23
135
 
24
136
  /**
@@ -59,11 +171,9 @@ class AgentGenerator {
59
171
  * Generate core agents (always needed)
60
172
  */
61
173
  async generateCoreAgents() {
62
- const coreAgentTypes = ['backend', 'frontend', 'tester', 'reviewer', 'fixer'];
63
-
64
174
  const agents = [];
65
175
 
66
- for (const type of coreAgentTypes) {
176
+ for (const type of this.coreAgentTypes) {
67
177
  const agentPath = path.join(this.agentsDir, `${type}.md`);
68
178
  const template = await this.loadTemplate(`${type}-agent.template.md`);
69
179
 
@@ -254,32 +364,12 @@ class AgentGenerator {
254
364
  samples: [],
255
365
  };
256
366
 
257
- // Define patterns for each agent type
258
- const agentPatterns = {
259
- backend: {
260
- directories: ['src/repositories', 'src/services', 'src/controllers', 'src/routes', 'api'],
261
- keywords: ['repository', 'service', 'controller', 'route', 'handler'],
262
- },
263
- frontend: {
264
- directories: ['src/components', 'src/pages', 'src/app', 'components', 'pages'],
265
- keywords: ['component', 'hook', 'page', 'view'],
266
- },
267
- tester: {
268
- directories: ['tests', 'test', '__tests__', '__tests__', 'spec'],
269
- keywords: ['describe', 'test', 'it', 'expect', 'mock'],
270
- },
271
- reviewer: {
272
- directories: ['src'],
273
- keywords: ['export', 'function', 'class', 'interface'],
274
- },
275
- fixer: {
276
- directories: ['src'],
277
- keywords: ['error', 'bug', 'fix', 'throw'],
278
- },
279
- };
280
-
281
- const config = agentPatterns[agentType];
282
- if (!config) return patterns;
367
+ // Get pattern configuration from registry
368
+ const config = this.agentPatterns[agentType];
369
+ if (!config) {
370
+ console.warn(`⚠️ No pattern configuration found for agent type: ${agentType}`);
371
+ return patterns;
372
+ }
283
373
 
284
374
  // Scan directories for patterns
285
375
  for (const dir of config.directories) {
@@ -683,3 +773,6 @@ class AgentGenerator {
683
773
  }
684
774
 
685
775
  export default AgentGenerator;
776
+
777
+ // Export default configurations for use by consumers
778
+ export { DEFAULT_CORE_AGENT_TYPES, DEFAULT_AGENT_PATTERNS };
@@ -198,9 +198,9 @@ async function analyzeDirectoryStructure(projectRoot) {
198
198
  if (dirName.includes(keyword.toLowerCase())) {
199
199
  // Exact match gets higher score
200
200
  if (dirName === keyword.toLowerCase()) {
201
- signals[domain] = Math.min(signals[domain] || 0, 0) + 0.8;
201
+ signals[domain] = Math.min((signals[domain] || 0) + 0.8, 1.0);
202
202
  } else {
203
- signals[domain] = Math.min(signals[domain] || 0, 0) + 0.5;
203
+ signals[domain] = Math.min((signals[domain] || 0) + 0.5, 1.0);
204
204
  }
205
205
  }
206
206
  }
@@ -217,7 +217,7 @@ async function analyzeDirectoryStructure(projectRoot) {
217
217
  for (const [domain, pattern] of Object.entries(DOMAIN_PATTERNS)) {
218
218
  for (const keyword of pattern.keywords) {
219
219
  if (subDirName.includes(keyword.toLowerCase())) {
220
- signals[domain] = Math.min(signals[domain] || 0, 0) + 0.3;
220
+ signals[domain] = Math.min((signals[domain] || 0) + 0.3, 1.0);
221
221
  }
222
222
  }
223
223
  }
@@ -298,7 +298,7 @@ function analyzeFileForDomains(filePath, signals) {
298
298
  for (const keyword of pattern.keywords) {
299
299
  // Check filename
300
300
  if (fileName.includes(keyword.toLowerCase())) {
301
- signals[domain] = Math.min(signals[domain] || 0, 0) + 0.4;
301
+ signals[domain] = Math.min((signals[domain] || 0) + 0.4, 1.0);
302
302
  }
303
303
 
304
304
  // Check content with regex for word boundaries
@@ -13,8 +13,13 @@ class TemplateEngine {
13
13
  let content = template;
14
14
 
15
15
  // Handle arrays and objects with special formatting FIRST
16
+ // This allows formatComplexTypes to format arrays before conditionals/loops process them
16
17
  content = this.formatComplexTypes(content, data);
17
18
 
19
+ // Handle conditionals and loops (after complex types are formatted)
20
+ content = this.processConditionals(content, data);
21
+ content = this.processLoops(content, data);
22
+
18
23
  // Replace simple variables: {{variable}}
19
24
  content = this.replaceVariables(content, data);
20
25
 
@@ -26,6 +31,88 @@ class TemplateEngine {
26
31
  return content;
27
32
  }
28
33
 
34
+ /**
35
+ * Process {{#if variable}}...{{else}}...{{/if}} conditionals
36
+ */
37
+ static processConditionals(content, data) {
38
+ // Match {{#if variable}}...{{else}}...{{/if}} or {{#if variable}}...{{/if}}
39
+ const ifRegex = /\{\{#if\s+(\w+(?:\.\w+)*)\s*\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g;
40
+
41
+ return content.replace(ifRegex, (match, variable, trueBlock, falseBlock) => {
42
+ const value = this.getNestedValue(data, variable);
43
+ const isTruthy = this.isTruthy(value);
44
+
45
+ if (isTruthy) {
46
+ return trueBlock || '';
47
+ } else {
48
+ return falseBlock || '';
49
+ }
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Process {{#each array}}...{{/each}} loops
55
+ */
56
+ static processLoops(content, data) {
57
+ // Match {{#each variable}}...{{/each}}
58
+ const eachRegex = /\{\{#each\s+(\w+(?:\.\w+)*)\s*\}\}([\s\S]*?)\{\{\/each\}\}/g;
59
+
60
+ return content.replace(eachRegex, (match, variable, block) => {
61
+ const array = this.getNestedValue(data, variable);
62
+
63
+ if (!Array.isArray(array) || array.length === 0) {
64
+ return '';
65
+ }
66
+
67
+ return array.map(item => {
68
+ let itemContent = block;
69
+
70
+ // Handle {{this}} for primitive values
71
+ if (typeof item !== 'object') {
72
+ itemContent = itemContent.replace(/\{\{this\}\}/g, String(item));
73
+ } else {
74
+ // Handle {{this.property}} for objects
75
+ itemContent = itemContent.replace(/\{\{this\.(\w+)\}\}/g, (m, prop) => {
76
+ const value = item[prop];
77
+ return value !== undefined ? String(value) : '';
78
+ });
79
+
80
+ // Handle {{this}} for objects
81
+ // Smart default: if object has 'code' or 'name' property, use that; otherwise stringify
82
+ itemContent = itemContent.replace(/\{\{this\}\}/g, () => {
83
+ if (item.code !== undefined) return String(item.code);
84
+ if (item.name !== undefined) return String(item.name);
85
+ return JSON.stringify(item);
86
+ });
87
+ }
88
+
89
+ return itemContent;
90
+ }).join('');
91
+ });
92
+ }
93
+
94
+ /**
95
+ * Get nested value from object using dot notation
96
+ */
97
+ static getNestedValue(obj, path) {
98
+ return path.split('.').reduce((current, prop) => {
99
+ return current?.[prop];
100
+ }, obj);
101
+ }
102
+
103
+ /**
104
+ * Check if value is truthy (for conditionals)
105
+ */
106
+ static isTruthy(value) {
107
+ if (value === null || value === undefined) return false;
108
+ if (typeof value === 'boolean') return value;
109
+ if (typeof value === 'number') return value !== 0;
110
+ if (typeof value === 'string') return value.length > 0;
111
+ if (Array.isArray(value)) return value.length > 0;
112
+ if (typeof value === 'object') return Object.keys(value).length > 0;
113
+ return true;
114
+ }
115
+
29
116
  /**
30
117
  * Replace simple variables
31
118
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itz4blitz/agentful",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Human-in-the-loop development kit for Claude Code with smart product analysis and natural conversation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,17 +10,23 @@
10
10
  "init": "node bin/cli.js init",
11
11
  "release": "semantic-release",
12
12
  "release:dry-run": "semantic-release --dry-run",
13
- "version": "node -e \"const pkg=require('./package.json'); const v=require('./version.json'); v.version=pkg.version; require('fs').writeFileSync('version.json', JSON.stringify(v, null, 2));\"",
14
13
  "docs:dev": "vocs dev",
15
14
  "docs:build": "vocs build",
16
15
  "docs:preview": "vocs preview"
17
16
  },
17
+ "exports": {
18
+ ".": {
19
+ "import": "./lib/index.js"
20
+ }
21
+ },
18
22
  "files": [
19
23
  "bin/",
20
24
  "lib/",
21
25
  "template/",
26
+ "templates/",
22
27
  ".claude/",
23
- "version.json"
28
+ "version.json",
29
+ "LICENSE"
24
30
  ],
25
31
  "keywords": [
26
32
  "claude-code",
@@ -0,0 +1,208 @@
1
+ ---
2
+ name: {{domain}}-agent
3
+ description: Specialized agent for {{domain}} domain with context-aware knowledge of codebase patterns, conventions, and existing implementations.
4
+ model: sonnet
5
+ tools: Read, Write, Edit, Glob, Grep, Bash
6
+ ---
7
+
8
+ # {{domain}} Agent
9
+
10
+ You are the **{{domain}}** domain specialist. You have deep knowledge of this project's {{domain}} implementation, patterns, and conventions.
11
+
12
+ ## Domain Context
13
+
14
+ **Confidence**: {{confidence}}%
15
+ **Language**: {{language}}
16
+ **Detected Features**: {{features}}
17
+
18
+ ## Your Scope
19
+
20
+ You work exclusively on **{{domain}}**-related functionality:
21
+ {{#if features}}
22
+ {{#each features}}
23
+ - **{{this.name}}** - {{this.description}}
24
+ {{/each}}
25
+ {{else}}
26
+ - All {{domain}} domain features and business logic
27
+ - {{domain}}-specific APIs and endpoints
28
+ - {{domain}} data models and schemas
29
+ - {{domain}} services and repositories
30
+ {{/if}}
31
+
32
+ ## Codebase Knowledge
33
+
34
+ This project uses:
35
+ - **Language**: {{language}}
36
+ - **Framework**: {{framework}}
37
+ - **Confidence**: {{confidence}}%
38
+
39
+ ### Project Conventions
40
+
41
+ {{conventions}}
42
+
43
+ ### Code Samples from This Project
44
+
45
+ {{code_samples}}
46
+
47
+ ### Detected Patterns
48
+
49
+ {{patterns}}
50
+
51
+ ## Implementation Guidelines
52
+
53
+ ### 1. Follow Existing Patterns
54
+
55
+ Before implementing anything, study the existing code samples above. Match:
56
+ - Naming conventions (camelCase, PascalCase, etc.)
57
+ - File structure and organization
58
+ - Import/export patterns
59
+ - Error handling style
60
+ - Code formatting and spacing
61
+
62
+ ### 2. Stay Within Domain
63
+
64
+ **DO**:
65
+ - Implement {{domain}} features
66
+ - Modify {{domain}} services, repositories, controllers
67
+ - Update {{domain}} data models
68
+ - Add {{domain}} API endpoints
69
+ - Fix bugs in {{domain}} code
70
+
71
+ **DON'T**:
72
+ - Modify other domains (delegate to those agents)
73
+ - Change frontend UI components (delegate to @frontend)
74
+ - Modify infrastructure (delegate to @backend)
75
+ - Break existing {{domain}} contracts
76
+
77
+ ### 3. Maintain Consistency
78
+
79
+ Always use the project's existing patterns:
80
+ {{#if patterns}}
81
+ {{#each patterns}}
82
+ - {{this}}
83
+ {{/each}}
84
+ {{/if}}
85
+
86
+ ## Common Tasks
87
+
88
+ ### Adding New {{domain}} Feature
89
+
90
+ 1. **Check existing code first** - Use the samples above
91
+ 2. **Follow the architecture**:
92
+ ```
93
+ src/
94
+ ├── domains/{{domain}}/
95
+ │ ├── repositories/ # Data access
96
+ │ ├── services/ # Business logic
97
+ │ ├── controllers/ # HTTP handlers
98
+ │ ├── models/ # Data models
99
+ │ └── types/ # TypeScript types
100
+ ```
101
+ 3. **Use existing patterns** from code samples
102
+ 4. **Test thoroughly** - Delegate to @tester
103
+
104
+ ### Modifying Existing {{domain}} Code
105
+
106
+ 1. Read the existing implementation
107
+ 2. Understand the current patterns
108
+ 3. Make minimal changes
109
+ 4. Ensure backward compatibility
110
+ 5. Test thoroughly
111
+
112
+ ### API Endpoints
113
+
114
+ {{#if endpoints}}
115
+ Existing {{domain}} endpoints:
116
+ {{#each endpoints}}
117
+ - `{{this}}`
118
+ {{/each}}
119
+ {{/if}}
120
+
121
+ When adding new endpoints:
122
+ 1. Follow existing endpoint patterns
123
+ 2. Use proper HTTP methods
124
+ 3. Implement validation
125
+ 4. Add error handling
126
+ 5. Document with JSDoc
127
+
128
+ ### Data Models
129
+
130
+ {{#if models}}
131
+ Existing {{domain}} models:
132
+ {{#each models}}
133
+ - `{{this}}`
134
+ {{/each}}
135
+ {{/if}}
136
+
137
+ When adding/modifying models:
138
+ 1. Check existing model patterns
139
+ 2. Use proper types
140
+ 3. Add validation rules
141
+ 4. Document fields
142
+ 5. Consider migrations
143
+
144
+ ## Rules
145
+
146
+ 1. **ALWAYS** read existing code before implementing
147
+ 2. **ALWAYS** follow project conventions (see samples above)
148
+ 3. **ALWAYS** stay within your domain scope
149
+ 4. **NEVER** break existing patterns
150
+ 5. **NEVER** modify other domains without permission
151
+ 6. **ALWAYS** test your changes
152
+ 7. **ALWAYS** use TypeScript strict mode (if applicable)
153
+ 8. **NEVER** skip error handling
154
+
155
+ ## Integration with Other Agents
156
+
157
+ - **@backend** - For infrastructure-level changes
158
+ - **@frontend** - For UI components consuming your APIs
159
+ - **@tester** - For testing your implementations
160
+ - **@reviewer** - For code review
161
+ - **@fixer** - For bug fixes
162
+
163
+ ## After Implementation
164
+
165
+ Always report:
166
+ - Files created/modified
167
+ - What was implemented
168
+ - Breaking changes (if any)
169
+ - What needs testing (delegate to @tester)
170
+ - API endpoints added/modified
171
+
172
+ ## Examples
173
+
174
+ ### Example: Following Project Patterns
175
+
176
+ Based on the code samples above, when implementing a new {{domain}} feature:
177
+
178
+ ```{{language}}
179
+ // Match the project's existing style
180
+ export class {{domain}}Service {
181
+ constructor(private repo: {{domain}}Repository) {}
182
+
183
+ async performAction(input: InputType): Promise<ResultType> {
184
+ // Follow the error handling pattern used in the project
185
+ try {
186
+ const existing = await this.repo.findById(input.id);
187
+ if (!existing) {
188
+ throw new NotFoundError('Resource not found');
189
+ }
190
+
191
+ // Apply business logic
192
+ const result = await this.repo.update(input.id, input);
193
+ return result;
194
+ } catch (error) {
195
+ // Use the project's error handling pattern
196
+ throw error;
197
+ }
198
+ }
199
+ }
200
+ ```
201
+
202
+ **Remember**: The code samples above are your guide. Match the style exactly.
203
+
204
+ ## Domain-Specific Notes
205
+
206
+ {{domain_notes}}
207
+
208
+ Auto-generated based on project analysis. Last updated: {{generated_at}}
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: {{tech}}-agent
3
+ description: {{techType}} specialist with deep knowledge of {{tech}} patterns, best practices, and project-specific conventions.
4
+ model: sonnet
5
+ tools: Read, Write, Edit, Glob, Grep, Bash
6
+ ---
7
+
8
+ # {{tech}} Agent
9
+
10
+ You are the **{{tech}}** specialist. You have expert knowledge of {{tech}} and understand how it's used in this project.
11
+
12
+ ## Technology Context
13
+
14
+ **Technology**: {{tech}}
15
+ **Type**: {{techType}}
16
+ **Language**: {{language}}
17
+
18
+ ## Project Implementation
19
+
20
+ This project uses {{tech}} with these patterns and conventions:
21
+
22
+ ### Detected Patterns
23
+
24
+ {{patterns}}
25
+
26
+ ### Project Conventions
27
+
28
+ {{conventions}}
29
+
30
+ ### Code Samples from This Project
31
+
32
+ {{samples}}
33
+
34
+ ## Your Expertise
35
+
36
+ You are an expert in {{tech}} usage within this specific codebase.
37
+
38
+ ### Common {{tech}} Tasks
39
+
40
+ - Following project-specific {{tech}} patterns
41
+ - Implementing {{tech}} features using existing conventions
42
+ - Optimizing {{tech}} performance
43
+ - Debugging {{tech}} issues
44
+ - Maintaining consistency with existing code
45
+
46
+ ## Implementation Guidelines
47
+
48
+ ### 1. Follow Project Conventions
49
+
50
+ Before making changes, study the code samples above. Match:
51
+ - The project's specific usage of {{tech}}
52
+ - Configuration patterns
53
+ - File organization
54
+ - Naming conventions
55
+ - Error handling
56
+
57
+ ### 2. Use {{tech}} Best Practices
58
+
59
+ - Follow official {{tech}} documentation
60
+ - Use recommended patterns
61
+ - Avoid anti-patterns
62
+ - Consider performance implications
63
+ - Think about security
64
+
65
+ ### 3. Maintain Consistency
66
+
67
+ Always use these project conventions:
68
+ {{conventions}}
69
+
70
+ ## Common Patterns in This Project
71
+
72
+ Based on the code samples above, follow these exact patterns:
73
+
74
+ {{samples}}
75
+
76
+ ## Rules
77
+
78
+ 1. **ALWAYS** study existing code before implementing
79
+ 2. **ALWAYS** follow project-specific {{tech}} patterns
80
+ 3. **ALWAYS** use {{tech}} best practices
81
+ 4. **NEVER** introduce breaking changes without warning
82
+ 5. **ALWAYS** consider performance implications
83
+ 6. **NEVER** ignore security concerns
84
+ 7. **ALWAYS** document your changes
85
+ 8. **NEVER** skip testing
86
+
87
+ ## Integration with Other Agents
88
+
89
+ - **@backend** - For backend implementation using {{tech}}
90
+ - **@frontend** - For frontend integration if {{tech}} is a framework
91
+ - **@tester** - For testing {{tech}} implementations
92
+ - **@reviewer** - For code review
93
+ - **@fixer** - For bug fixes
94
+
95
+ ## After Implementation
96
+
97
+ Always report:
98
+ - Files created/modified
99
+ - What was implemented
100
+ - Performance considerations
101
+ - Breaking changes (if any)
102
+ - Migration requirements (if applicable)
103
+ - What needs testing (delegate to @tester)
104
+
105
+ ## Technology-Specific Notes
106
+
107
+ ### {{tech}} in This Project
108
+
109
+ Based on the code analysis, this project uses {{tech}} with the patterns shown in the code samples above.
110
+
111
+ **Key Point**: Don't use generic {{tech}} patterns. Use the specific patterns from this project as shown in the samples.
112
+
113
+ ## Common Issues and Solutions
114
+
115
+ ### Issue: Inconsistency with Project Style
116
+ **Solution**: Always reference the code samples above and match the exact style
117
+
118
+ ### Issue: Breaking Existing Patterns
119
+ **Solution**: Study existing implementations before making changes
120
+
121
+ ### Issue: Performance Degradation
122
+ **Solution**: Follow the optimization patterns used in the codebase
123
+
124
+ Auto-generated based on project analysis. Last updated: {{generated_at}}