agents-templated 2.2.12 → 2.2.14

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.
Files changed (56) hide show
  1. package/README.md +53 -12
  2. package/bin/cli.js +76 -18
  3. package/index.js +2 -2
  4. package/lib/layout.js +27 -3
  5. package/lib/orchestrator.js +562 -0
  6. package/lib/workflow.js +472 -3
  7. package/package.json +1 -1
  8. package/templates/.claude/agents/README.md +15 -1
  9. package/templates/.claude/agents/architect.md +79 -106
  10. package/templates/.claude/agents/backend-specialist.md +79 -0
  11. package/templates/.claude/agents/build-error-resolver.md +78 -119
  12. package/templates/.claude/agents/code-reviewer.md +79 -116
  13. package/templates/.claude/agents/compatibility-checker.md +79 -79
  14. package/templates/.claude/agents/configuration-validator.md +79 -85
  15. package/templates/.claude/agents/database-migrator.md +79 -83
  16. package/templates/.claude/agents/dependency-auditor.md +79 -92
  17. package/templates/.claude/agents/deployment-specialist.md +91 -0
  18. package/templates/.claude/agents/doc-updater.md +78 -130
  19. package/templates/.claude/agents/e2e-runner.md +78 -122
  20. package/templates/.claude/agents/frontend-specialist.md +79 -0
  21. package/templates/.claude/agents/load-tester.md +79 -80
  22. package/templates/.claude/agents/performance-profiler.md +79 -103
  23. package/templates/.claude/agents/performance-specialist.md +91 -0
  24. package/templates/.claude/agents/planner.md +81 -87
  25. package/templates/.claude/agents/qa-specialist.md +92 -0
  26. package/templates/.claude/agents/refactor-cleaner.md +79 -137
  27. package/templates/.claude/agents/release-ops-specialist.md +80 -0
  28. package/templates/.claude/agents/security-reviewer.md +80 -138
  29. package/templates/.claude/agents/tdd-guide.md +79 -98
  30. package/templates/.claude/agents/test-data-builder.md +79 -0
  31. package/templates/CLAUDE.md +7 -0
  32. package/templates/README.md +37 -9
  33. package/templates/agent-docs/ARCHITECTURE.md +6 -0
  34. package/templates/agents/commands/README.md +84 -4
  35. package/templates/agents/commands/SCHEMA.md +21 -1
  36. package/templates/agents/commands/test-data.md +56 -0
  37. package/agents/commands/README.md +0 -64
  38. package/agents/commands/SCHEMA.md +0 -22
  39. package/agents/commands/arch-check.md +0 -58
  40. package/agents/commands/audit.md +0 -58
  41. package/agents/commands/debug-track.md +0 -58
  42. package/agents/commands/docs.md +0 -58
  43. package/agents/commands/fix.md +0 -58
  44. package/agents/commands/learn-loop.md +0 -58
  45. package/agents/commands/perf.md +0 -58
  46. package/agents/commands/plan.md +0 -58
  47. package/agents/commands/pr.md +0 -58
  48. package/agents/commands/problem-map.md +0 -58
  49. package/agents/commands/release-ready.md +0 -58
  50. package/agents/commands/release.md +0 -58
  51. package/agents/commands/risk-review.md +0 -58
  52. package/agents/commands/scope-shape.md +0 -58
  53. package/agents/commands/task.md +0 -58
  54. package/agents/commands/test.md +0 -58
  55. package/agents/commands/ux-bar.md +0 -58
  56. package/agents/rules/planning.mdc +0 -69
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
  [![GitHub stars](https://img.shields.io/github/stars/rickandrew2/agents-templated?style=social)](https://github.com/rickandrew2/agents-templated)
7
7
 
8
- > **Agents Templated** is a CLI tool and npm package that instantly scaffolds production-ready project structures with enterprise-grade development patterns, security guidelines, and AI assistant configurations. Designed for developers who want to start projects the right way—with proven OWASP security practices, comprehensive testing strategies (80/15/5 coverage targets), and agent-based architecture patterns—without being locked into specific frameworks. It generates unified configuration files that work seamlessly with Cursor, GitHub Copilot, Claude, and Google Gemini, allowing AI assistants to automatically follow best practices from day one. Whether you're building a Next.js app, Django API, Go microservice, or any custom stack, Agents Templated provides the guardrails and patterns you need while giving you complete freedom to choose your technology.
8
+ > **Agents Templated** is a technology-agnostic CLI that scaffolds the AI development operating layer around your app: policy rules, deterministic command contracts, reusable skills, and compatibility files for Cursor, GitHub Copilot, Claude, and generic agent hosts. It does not scaffold your product framework. It scaffolds how your team and agents plan, build, test, review, and release.
9
9
 
10
10
  ---
11
11
 
@@ -16,12 +16,28 @@ Most starter templates only create files. This package creates operating rules f
16
16
  You get:
17
17
 
18
18
  - Multi-agent configuration for Cursor, Copilot, Claude, and generic hosts
19
- - Deterministic command contracts in `agents/commands/`
19
+ - Deterministic command contracts in `.claude/commands/`
20
20
  - Security-first and testing-first rule baselines
21
21
  - Reusable skills and optional subagents
22
22
 
23
23
  Important: this package does not install your framework. It installs the operating layer around your framework.
24
24
 
25
+ ## What Agents Templated Actually Is
26
+
27
+ Agents Templated is a project governance and agent-orchestration scaffold.
28
+
29
+ - It installs a canonical AI policy source (`CLAUDE.md`) and compatibility shims (`AGENTS.MD`, `.github/copilot-instructions.md`, `.cursorrules`).
30
+ - It installs deterministic command contracts in `.claude/commands/` for repeatable specialist workflows.
31
+ - It installs reusable skills in `.github/skills/` and optional subagents in `.claude/agents/`.
32
+ - It installs rule modules in `.claude/rules/` for security, testing, planning, workflows, and guardrails.
33
+ - It includes `validate`, `doctor`, `update`, and `workflow` commands to keep scaffolds healthy over time.
34
+
35
+ What it is not:
36
+
37
+ - Not a framework generator.
38
+ - Not a dependency installer for your app stack.
39
+ - Not a replacement for your application architecture.
40
+
25
41
  ## 30-Second Start
26
42
 
27
43
  ### 1. Install setup
@@ -161,10 +177,8 @@ your-project/
161
177
  │ │ ├── system-workflow.md
162
178
  │ │ ├── hardening.md
163
179
  │ │ └── lessons-learned.md
164
- └── agents/ # Optional subagents
165
-
166
- ├── agents/ # Deterministic command contracts
167
- │ └── commands/
180
+ ├── agents/ # Optional subagents
181
+ └── commands/ # Deterministic command contracts
168
182
  │ │ ├── SCHEMA.md # Global slash-command response schema
169
183
  │ │ ├── plan.md # /plan contract
170
184
  │ │ ├── fix.md # /fix contract
@@ -237,13 +251,31 @@ These commands provide deterministic specialist guidance aligned to the sprint l
237
251
  | `arch-check` | Architecture Reviewer | Lock architecture and edge-case coverage |
238
252
  | `ux-bar` | Design Quality Lead | Raise UX quality before implementation |
239
253
  | `debug-track` | Root-Cause Investigator | Reproduce and isolate root cause |
254
+ | `test-data` | Test Data Builder | Prepare deterministic fixtures/seeds for downstream validation |
240
255
  | `risk-review` | Release Risk Reviewer | Surface production-risk issues before merge |
241
256
  | `perf` | Performance Analyst | Optimize performance and guard against regressions |
242
257
  | `release-ready` | Release Coordinator | Prepare release artifacts and final checks |
243
258
  | `docs` | Documentation Engineer | Sync docs with shipped behavior |
244
259
  | `learn-loop` | Iteration Lead | Capture lessons and next-cycle actions |
245
260
 
246
- Each command maps to deterministic contract files in `agents/commands/` and uses the schema in `agents/commands/SCHEMA.md`.
261
+ Each command maps to deterministic contract files in `.claude/commands/` and uses the schema in `.claude/commands/SCHEMA.md`.
262
+
263
+ ### Deprecated Workflow Aliases
264
+
265
+ The CLI keeps selected legacy names as non-breaking redirects with deterministic notices.
266
+
267
+ | Deprecated | Canonical |
268
+ |------------|-----------|
269
+ | `quality-gate` | `risk-review` |
270
+ | `perf-scan` | `perf` |
271
+ | `docs-sync` | `docs` |
272
+
273
+ Migration guidance:
274
+
275
+ - Existing scripts continue to work.
276
+ - Alias invocations print a deprecation warning and redirect deterministically.
277
+ - New automation should use canonical names only.
278
+ - Sunset guidance: deprecated aliases remain supported through v2.x and are scheduled for removal in v3.0.
247
279
 
248
280
 
249
281
  ---
@@ -361,11 +393,20 @@ Your AI will follow the enterprise patterns automatically!
361
393
 
362
394
  | Agent | Responsibility |
363
395
  |-------|---------------|
364
- | **FrontendAgent** | UI/UX, components, design system, accessibility |
365
- | **BackendAgent** | API, business logic, authentication, middleware |
366
- | **DatabaseAgent** | Schema design, migrations, query optimization |
367
- | **TestAgent** | Unit, integration, E2E, accessibility testing |
368
- | **SecurityAgent** | Input validation, authentication, OWASP compliance |
396
+ | **backend-specialist** | API, business logic, auth middleware, persistence changes |
397
+ | **frontend-specialist** | UI/UX implementation, accessibility, interaction behavior |
398
+ | **qa-specialist** | Design-mode test planning and validation-mode regression gates |
399
+ | **performance-specialist** | Mode-locked performance profiling and load threshold validation |
400
+ | **test-data-builder** | Deterministic fixtures, seeds, and downstream handoff contracts |
401
+ | **security-reviewer** | Conditional security invocation based on trigger thresholds |
402
+ | **dependency-auditor** | CVE/dependency risk auditing and upgrade hygiene |
403
+ | **deployment-specialist** | Ordered deployment phase contract and rollback readiness |
404
+
405
+ #### Separation-Preservation Sequence Contracts
406
+
407
+ - Backend implementation lane: `backend-specialist -> build-error-resolver -> compatibility-checker`
408
+ - Review/governance lane: `code-reviewer -> dependency-auditor -> doc-updater`
409
+ - Test-data handoff lane: `qa-specialist(mode=design) -> test-data-builder -> qa-specialist(mode=validation) -> e2e-runner -> performance-specialist(mode=load)`
369
410
 
370
411
  **Reference**: [AGENTS.MD](AGENTS.MD)
371
412
 
package/bin/cli.js CHANGED
@@ -10,6 +10,7 @@ const {
10
10
  LAYOUT,
11
11
  resolveRulesDir,
12
12
  resolveSkillsDir,
13
+ resolveCommandsDir,
13
14
  resolveSubagentsDir,
14
15
  hasAnyLayout,
15
16
  getLegacyMigrationPlan
@@ -27,9 +28,14 @@ const {
27
28
  WORKFLOW_COMMANDS,
28
29
  CONTRACT_FILES,
29
30
  SPECIALIST_CONTRACT_FILES,
31
+ DEPRECATED_COMMAND_ALIASES,
30
32
  formatWorkflowOutput,
31
33
  validateWorkflowDefinitions
32
34
  } = require('../lib/workflow');
35
+ const {
36
+ WorkflowOrchestrator,
37
+ formatOrchestrationOutput
38
+ } = require('../lib/orchestrator');
33
39
 
34
40
  // Resolve the templates directory - works in both dev and installed contexts
35
41
  const getTemplatesDir = () => {
@@ -141,7 +147,7 @@ program
141
147
  { name: 'Documentation files (agent-docs/)', value: 'docs' },
142
148
  { name: 'Agent rules (.claude/rules/*.md)', value: 'rules' },
143
149
  { name: 'Skills (.github/skills/*)', value: 'skills' },
144
- { name: 'Command contracts (agents/commands/*.md)', value: 'commands' },
150
+ { name: 'Command contracts (.claude/commands/*.md)', value: 'commands' },
145
151
  { name: 'AI Agent instructions (Cursor, Copilot, Claude, Generic AGENTS)', value: 'github' },
146
152
  { name: 'Agent subagents (.claude/agents/*.md)', value: 'subagents' }
147
153
  ],
@@ -205,10 +211,10 @@ program
205
211
  // Install deterministic command contracts
206
212
  if (installAll || choices.includes('commands')) {
207
213
  console.log(chalk.yellow('Installing command contracts...'));
208
- await fs.ensureDir(path.join(targetDir, 'agents', 'commands'));
214
+ await fs.ensureDir(path.join(targetDir, LAYOUT.canonical.commandsDir));
209
215
  await copyDirectory(
210
216
  path.join(templateDir, 'agents', 'commands'),
211
- path.join(targetDir, 'agents', 'commands'),
217
+ path.join(targetDir, LAYOUT.canonical.commandsDir),
212
218
  options.force
213
219
  );
214
220
  }
@@ -286,7 +292,7 @@ program
286
292
  { name: 'Documentation (agent-docs/)', value: 'docs' },
287
293
  { name: 'Agent Rules (security, testing, database, etc.)', value: 'rules' },
288
294
  { name: 'Skills (reusable agent capabilities)', value: 'skills' },
289
- { name: 'Command contracts (agents/commands/*.md)', value: 'commands' },
295
+ { name: 'Command contracts (.claude/commands/*.md)', value: 'commands' },
290
296
  { name: 'AI Agent instructions (Cursor, Copilot, Claude, Generic AGENTS)', value: 'github' },
291
297
  { name: 'Agent subagents (.claude/agents/*.md)', value: 'subagents' }
292
298
  ],
@@ -324,7 +330,7 @@ program
324
330
  { name: 'Documentation (agent-docs/)', value: 'docs', checked: true },
325
331
  { name: 'Agent Rules (security, testing, database, etc.)', value: 'rules', checked: true },
326
332
  { name: 'Skills (reusable agent capabilities)', value: 'skills', checked: true },
327
- { name: 'Command contracts (agents/commands/*.md)', value: 'commands', checked: true },
333
+ { name: 'Command contracts (.claude/commands/*.md)', value: 'commands', checked: true },
328
334
  { name: 'AI Agent instructions (Cursor, Copilot, Claude, Generic AGENTS)', value: 'github', checked: true },
329
335
  { name: 'Agent subagents (.claude/agents/*.md)', value: 'subagents', checked: true }
330
336
  ],
@@ -390,10 +396,10 @@ program
390
396
  // Install deterministic command contracts
391
397
  if (options.commands) {
392
398
  console.log(chalk.yellow('Installing command contracts...'));
393
- await fs.ensureDir(path.join(targetDir, 'agents', 'commands'));
399
+ await fs.ensureDir(path.join(targetDir, LAYOUT.canonical.commandsDir));
394
400
  await copyDirectory(
395
401
  path.join(templateDir, 'agents', 'commands'),
396
- path.join(targetDir, 'agents', 'commands'),
402
+ path.join(targetDir, LAYOUT.canonical.commandsDir),
397
403
  options.force
398
404
  );
399
405
  }
@@ -447,7 +453,7 @@ program
447
453
  console.log(chalk.yellow('docs') + ' - Documentation files (agent-docs/ directory)');
448
454
  console.log(chalk.yellow('rules') + ' - Agent rules (.claude/rules/*.md)');
449
455
  console.log(chalk.yellow('skills') + ' - Agent skills (.github/skills/*)');
450
- console.log(chalk.yellow('commands') + ' - Deterministic command contracts (agents/commands/*.md)');
456
+ console.log(chalk.yellow('commands') + ' - Deterministic command contracts (.claude/commands/*.md)');
451
457
  console.log(chalk.yellow('github') + ' - AI Agent instructions (Cursor, Copilot, Claude, Generic AGENTS)');
452
458
  console.log(chalk.yellow('subagents') + ' - Agent subagents (.claude/agents/*.md)');
453
459
  console.log(chalk.yellow('all') + ' - All components');
@@ -542,27 +548,35 @@ program
542
548
  warnings.push(`⚠ ${LAYOUT.canonical.skillsDir} directory missing - run 'agents-templated init --skills'`);
543
549
  }
544
550
 
545
- const commandsDir = path.join(targetDir, 'agents', 'commands');
551
+ const canonicalCommandsDir = path.join(targetDir, LAYOUT.canonical.commandsDir);
552
+ const legacyCommandsDir = path.join(targetDir, LAYOUT.legacy.commandsDirs[0]);
553
+ const commandsDir = path.join(targetDir, resolveCommandsDir(targetDir));
554
+
555
+ if (!(await fs.pathExists(canonicalCommandsDir)) && await fs.pathExists(legacyCommandsDir)) {
556
+ issues.push(`✗ Legacy command contract layout detected at ${LAYOUT.legacy.commandsDirs[0]} - run 'agents-templated update --all' to migrate`);
557
+ }
558
+
546
559
  if (await fs.pathExists(commandsDir)) {
560
+ const relativeCommandsDir = path.relative(targetDir, commandsDir) || LAYOUT.canonical.commandsDir;
547
561
  for (const contractFile of CONTRACT_FILES) {
548
562
  const contractPath = path.join(commandsDir, contractFile);
549
563
  if (await fs.pathExists(contractPath)) {
550
- passed.push(`✓ agents/commands/${contractFile} found`);
564
+ passed.push(`✓ ${relativeCommandsDir}/${contractFile} found`);
551
565
  } else {
552
- warnings.push(`⚠ agents/commands/${contractFile} missing`);
566
+ warnings.push(`⚠ ${relativeCommandsDir}/${contractFile} missing`);
553
567
  }
554
568
  }
555
569
 
556
570
  for (const contractFile of SPECIALIST_CONTRACT_FILES) {
557
571
  const contractPath = path.join(commandsDir, contractFile);
558
572
  if (await fs.pathExists(contractPath)) {
559
- passed.push(`✓ agents/commands/${contractFile} found`);
573
+ passed.push(`✓ ${relativeCommandsDir}/${contractFile} found`);
560
574
  } else {
561
- warnings.push(`⚠ agents/commands/${contractFile} missing`);
575
+ warnings.push(`⚠ ${relativeCommandsDir}/${contractFile} missing`);
562
576
  }
563
577
  }
564
578
  } else {
565
- warnings.push(`⚠ agents/commands directory missing - run 'agents-templated init --commands'`);
579
+ warnings.push(`⚠ ${LAYOUT.canonical.commandsDir} directory missing - run 'agents-templated init --commands'`);
566
580
  }
567
581
 
568
582
  // Check subagents
@@ -786,10 +800,10 @@ async function updateSelectedComponents(targetDir, templateDir, selectedComponen
786
800
 
787
801
  if (components.includes('commands')) {
788
802
  console.log(chalk.yellow('Updating command contracts...'));
789
- await fs.ensureDir(path.join(targetDir, 'agents', 'commands'));
803
+ await fs.ensureDir(path.join(targetDir, LAYOUT.canonical.commandsDir));
790
804
  await copyDirectory(
791
805
  path.join(templateDir, 'agents', 'commands'),
792
- path.join(targetDir, 'agents', 'commands'),
806
+ path.join(targetDir, LAYOUT.canonical.commandsDir),
793
807
  overwrite
794
808
  );
795
809
  }
@@ -930,8 +944,8 @@ program
930
944
  { targetFile: `${LAYOUT.canonical.skillsDir}/error-patterns/SKILL.md`, templateFile: 'agents/skills/error-patterns/SKILL.md', component: 'skills' },
931
945
  { targetFile: `${LAYOUT.canonical.skillsDir}/ui-ux-pro-max/SKILL.md`, templateFile: 'agents/skills/ui-ux-pro-max/SKILL.md', component: 'skills' },
932
946
  { targetFile: `${LAYOUT.canonical.skillsDir}/shadcn-ui/SKILL.md`, templateFile: 'agents/skills/shadcn-ui/SKILL.md', component: 'skills' },
933
- { targetFile: 'agents/commands/SCHEMA.md', templateFile: 'agents/commands/SCHEMA.md', component: 'commands' },
934
- { targetFile: 'agents/commands/README.md', templateFile: 'agents/commands/README.md', component: 'commands' }
947
+ { targetFile: `${LAYOUT.canonical.commandsDir}/SCHEMA.md`, templateFile: 'agents/commands/SCHEMA.md', component: 'commands' },
948
+ { targetFile: `${LAYOUT.canonical.commandsDir}/README.md`, templateFile: 'agents/commands/README.md', component: 'commands' }
935
949
  ];
936
950
 
937
951
  for (const {targetFile, templateFile, component} of checkFiles) {
@@ -1109,6 +1123,32 @@ program
1109
1123
  console.log(chalk.white(' agents-templated problem-map "daily briefing app for founders"\n'));
1110
1124
  });
1111
1125
 
1126
+ program
1127
+ .command('orchestrate [objective...]')
1128
+ .description('Automatically route a high-level objective across specialist subagents')
1129
+ .option('--scenario <id>', 'Force a specific scenario id (feature-delivery, backend-api, frontend-feature, bug-fix, deployment)')
1130
+ .option('--mode <mode>', 'slash-command or slash-command-auto', 'slash-command-auto')
1131
+ .option('--retry-cycle <n>', 'Current retry cycle for refactor-cleaner/build-error-resolver loop control', '0')
1132
+ .option('--json', 'Emit structured JSON only')
1133
+ .action((objective, options) => {
1134
+ const objectiveText = Array.isArray(objective) ? objective.join(' ') : '';
1135
+ const retryCycle = Number.parseInt(options.retryCycle, 10);
1136
+ const orchestrator = new WorkflowOrchestrator();
1137
+ const result = orchestrator.orchestrate({
1138
+ objective: objectiveText,
1139
+ scenarioId: options.scenario,
1140
+ mode: options.mode,
1141
+ retryCycle: Number.isNaN(retryCycle) ? 0 : retryCycle
1142
+ });
1143
+
1144
+ if (options.json) {
1145
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
1146
+ return;
1147
+ }
1148
+
1149
+ process.stdout.write(formatOrchestrationOutput(result));
1150
+ });
1151
+
1112
1152
  for (const workflow of WORKFLOW_COMMANDS) {
1113
1153
  program
1114
1154
  .command(`${workflow.cli} [objective...]`)
@@ -1119,6 +1159,24 @@ for (const workflow of WORKFLOW_COMMANDS) {
1119
1159
  });
1120
1160
  }
1121
1161
 
1162
+ for (const deprecatedAlias of DEPRECATED_COMMAND_ALIASES) {
1163
+ program
1164
+ .command(`${deprecatedAlias.from} [objective...]`)
1165
+ .description(`Deprecated alias for ${deprecatedAlias.to}`)
1166
+ .action((objective) => {
1167
+ const objectiveText = Array.isArray(objective) ? objective.join(' ') : '';
1168
+ const redirectedWorkflow = WORKFLOW_COMMANDS.find((workflow) => workflow.cli === deprecatedAlias.to);
1169
+
1170
+ if (!redirectedWorkflow) {
1171
+ console.error(chalk.red(`Deprecated alias target not found: ${deprecatedAlias.to}`));
1172
+ process.exit(1);
1173
+ }
1174
+
1175
+ console.log(chalk.yellow(`[deprecated] ${deprecatedAlias.notice}`));
1176
+ process.stdout.write(formatWorkflowOutput(redirectedWorkflow, objectiveText));
1177
+ });
1178
+ }
1179
+
1122
1180
  program
1123
1181
  .command('new-skill <name>')
1124
1182
  .description('Scaffold a new skill in .github/skills/<name>/SKILL.md')
package/index.js CHANGED
@@ -72,10 +72,10 @@ async function install(targetDir, options = {}) {
72
72
 
73
73
  // Deterministic command contracts
74
74
  if (installAll || options.commands) {
75
- await fs.ensureDir(path.join(targetDir, 'agents', 'commands'));
75
+ await fs.ensureDir(path.join(targetDir, LAYOUT.canonical.commandsDir));
76
76
  await copyDirectory(
77
77
  path.join(templateDir, 'agents', 'commands'),
78
- path.join(targetDir, 'agents', 'commands'),
78
+ path.join(targetDir, LAYOUT.canonical.commandsDir),
79
79
  options.force
80
80
  );
81
81
  }
package/lib/layout.js CHANGED
@@ -6,11 +6,13 @@ const LAYOUT = {
6
6
  docsDir: 'agent-docs',
7
7
  rulesDir: '.claude/rules',
8
8
  skillsDir: '.github/skills',
9
- subagentsDir: '.claude/agents'
9
+ subagentsDir: '.claude/agents',
10
+ commandsDir: '.claude/commands'
10
11
  },
11
12
  legacy: {
12
13
  rulesDirs: ['agents/rules'],
13
- skillsDirs: ['agents/skills']
14
+ skillsDirs: ['agents/skills'],
15
+ commandsDirs: ['agents/commands']
14
16
  },
15
17
  compatible: {
16
18
  rulesDirs: [],
@@ -45,16 +47,26 @@ function resolveSubagentsDir(baseDir) {
45
47
  return firstExistingPath(baseDir, candidates) || LAYOUT.canonical.subagentsDir;
46
48
  }
47
49
 
50
+ function resolveCommandsDir(baseDir) {
51
+ const candidates = [
52
+ LAYOUT.canonical.commandsDir,
53
+ ...LAYOUT.legacy.commandsDirs
54
+ ];
55
+ return firstExistingPath(baseDir, candidates) || LAYOUT.canonical.commandsDir;
56
+ }
57
+
48
58
  async function hasAnyLayout(baseDir) {
49
59
  const checks = [
50
60
  path.join(baseDir, LAYOUT.canonical.rulesDir),
51
61
  path.join(baseDir, LAYOUT.canonical.skillsDir),
52
62
  path.join(baseDir, LAYOUT.canonical.subagentsDir),
63
+ path.join(baseDir, LAYOUT.canonical.commandsDir),
53
64
  path.join(baseDir, 'agents', 'subagents'),
54
65
  ...LAYOUT.compatible.rulesDirs.map((relPath) => path.join(baseDir, relPath)),
55
66
  ...LAYOUT.compatible.skillsDirs.map((relPath) => path.join(baseDir, relPath)),
56
67
  ...LAYOUT.legacy.rulesDirs.map((relPath) => path.join(baseDir, relPath)),
57
- ...LAYOUT.legacy.skillsDirs.map((relPath) => path.join(baseDir, relPath))
68
+ ...LAYOUT.legacy.skillsDirs.map((relPath) => path.join(baseDir, relPath)),
69
+ ...LAYOUT.legacy.commandsDirs.map((relPath) => path.join(baseDir, relPath))
58
70
  ];
59
71
 
60
72
  for (const checkPath of checks) {
@@ -91,6 +103,17 @@ async function getLegacyMigrationPlan(baseDir) {
91
103
  }
92
104
  }
93
105
 
106
+ for (const relPath of LAYOUT.legacy.commandsDirs) {
107
+ const from = path.join(baseDir, relPath);
108
+ if (await fs.pathExists(from)) {
109
+ plan.push({
110
+ type: 'directory',
111
+ source: relPath,
112
+ target: LAYOUT.canonical.commandsDir
113
+ });
114
+ }
115
+ }
116
+
94
117
  return plan;
95
118
  }
96
119
 
@@ -98,6 +121,7 @@ module.exports = {
98
121
  LAYOUT,
99
122
  resolveRulesDir,
100
123
  resolveSkillsDir,
124
+ resolveCommandsDir,
101
125
  resolveSubagentsDir,
102
126
  hasAnyLayout,
103
127
  getLegacyMigrationPlan