sdd-mcp-server 3.3.0 → 3.5.0

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 (102) hide show
  1. package/README.md +120 -54
  2. package/dist/adapters/cli/SDDToolAdapter.d.ts +5 -1
  3. package/dist/adapters/cli/SDDToolAdapter.js +111 -18
  4. package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
  5. package/dist/application/services/ContextCompactionService.d.ts +39 -0
  6. package/dist/application/services/ContextCompactionService.js +253 -0
  7. package/dist/application/services/ContextCompactionService.js.map +1 -0
  8. package/dist/application/services/ProjectService.d.ts +7 -1
  9. package/dist/application/services/ProjectService.js +56 -1
  10. package/dist/application/services/ProjectService.js.map +1 -1
  11. package/dist/application/services/TemplateService.js +27 -5
  12. package/dist/application/services/TemplateService.js.map +1 -1
  13. package/dist/application/services/WorkflowEngineService.d.ts +3 -1
  14. package/dist/application/services/WorkflowEngineService.js +20 -5
  15. package/dist/application/services/WorkflowEngineService.js.map +1 -1
  16. package/dist/application/services/WorkflowService.js +8 -0
  17. package/dist/application/services/WorkflowService.js.map +1 -1
  18. package/dist/application/services/staticSteering.js +12 -13
  19. package/dist/application/services/staticSteering.js.map +1 -1
  20. package/dist/cli/install-skills.d.ts +13 -31
  21. package/dist/cli/install-skills.js +230 -173
  22. package/dist/cli/install-skills.js.map +1 -1
  23. package/dist/cli/install-target.d.ts +127 -0
  24. package/dist/cli/install-target.js +127 -0
  25. package/dist/cli/install-target.js.map +1 -0
  26. package/dist/cli/migrate-steering.js +13 -13
  27. package/dist/cli/migrate-steering.js.map +1 -1
  28. package/dist/cli/sdd-mcp-cli.d.ts +1 -1
  29. package/dist/cli/sdd-mcp-cli.js +14 -10
  30. package/dist/cli/sdd-mcp-cli.js.map +1 -1
  31. package/dist/cli/tool-support/antigravity.d.ts +6 -1
  32. package/dist/cli/tool-support/antigravity.js +55 -12
  33. package/dist/cli/tool-support/antigravity.js.map +1 -1
  34. package/dist/cli/tool-support/claude-code.d.ts +5 -0
  35. package/dist/cli/tool-support/claude-code.js +93 -0
  36. package/dist/cli/tool-support/claude-code.js.map +1 -0
  37. package/dist/cli/tool-support/codex.d.ts +18 -1
  38. package/dist/cli/tool-support/codex.js +161 -36
  39. package/dist/cli/tool-support/codex.js.map +1 -1
  40. package/dist/cli/tool-support/index.d.ts +2 -2
  41. package/dist/cli/tool-support/root-guidance.d.ts +9 -0
  42. package/dist/cli/tool-support/root-guidance.js +40 -0
  43. package/dist/cli/tool-support/root-guidance.js.map +1 -0
  44. package/dist/cli/tool-support/target-agent-renderer.d.ts +11 -0
  45. package/dist/cli/tool-support/target-agent-renderer.js +52 -0
  46. package/dist/cli/tool-support/target-agent-renderer.js.map +1 -0
  47. package/dist/cli/tool-support/target-installer.d.ts +40 -0
  48. package/dist/cli/tool-support/target-installer.js +116 -0
  49. package/dist/cli/tool-support/target-installer.js.map +1 -0
  50. package/dist/cli/utils/gitignore-manager.d.ts +5 -0
  51. package/dist/cli/utils/gitignore-manager.js +85 -0
  52. package/dist/cli/utils/gitignore-manager.js.map +1 -0
  53. package/dist/cli/utils/preserving-writer.d.ts +13 -0
  54. package/dist/cli/utils/preserving-writer.js +106 -0
  55. package/dist/cli/utils/preserving-writer.js.map +1 -0
  56. package/dist/domain/services/DomainService.d.ts +1 -0
  57. package/dist/domain/services/DomainService.js +12 -2
  58. package/dist/domain/services/DomainService.js.map +1 -1
  59. package/dist/domain/types.d.ts +13 -0
  60. package/dist/domain/types.js.map +1 -1
  61. package/dist/domain/workflow/WorkflowStateMachine.js +7 -2
  62. package/dist/domain/workflow/WorkflowStateMachine.js.map +1 -1
  63. package/dist/hooks/HookLoader.js +9 -1
  64. package/dist/hooks/HookLoader.js.map +1 -1
  65. package/dist/index.js +347 -26
  66. package/dist/index.js.map +1 -1
  67. package/dist/infrastructure/di/container.js +4 -0
  68. package/dist/infrastructure/di/container.js.map +1 -1
  69. package/dist/infrastructure/di/types.d.ts +1 -0
  70. package/dist/infrastructure/di/types.js +1 -0
  71. package/dist/infrastructure/di/types.js.map +1 -1
  72. package/dist/infrastructure/mcp/ResourceManager.js +21 -1
  73. package/dist/infrastructure/mcp/ResourceManager.js.map +1 -1
  74. package/dist/infrastructure/mcp/ToolRegistry.js +34 -2
  75. package/dist/infrastructure/mcp/ToolRegistry.js.map +1 -1
  76. package/dist/infrastructure/schemas/project.schema.d.ts +47 -4
  77. package/dist/infrastructure/schemas/project.schema.js +39 -2
  78. package/dist/infrastructure/schemas/project.schema.js.map +1 -1
  79. package/dist/shared/BaseManager.d.ts +10 -1
  80. package/dist/shared/BaseManager.js +34 -5
  81. package/dist/shared/BaseManager.js.map +1 -1
  82. package/dist/skills/SkillManager.d.ts +3 -1
  83. package/dist/skills/SkillManager.js +15 -3
  84. package/dist/skills/SkillManager.js.map +1 -1
  85. package/package.json +2 -2
  86. package/sdd-entry.js +2 -2
  87. package/skills/sdd-design/SKILL.md +4 -0
  88. package/skills/sdd-implement/SKILL.md +10 -4
  89. package/skills/sdd-requirements/SKILL.md +4 -0
  90. package/skills/sdd-review/SKILL.md +4 -0
  91. package/skills/sdd-security-check/SKILL.md +4 -0
  92. package/skills/sdd-steering/SKILL.md +4 -0
  93. package/skills/sdd-steering-custom/SKILL.md +4 -0
  94. package/skills/sdd-tasks/SKILL.md +24 -7
  95. package/skills/sdd-test-gen/SKILL.md +4 -0
  96. package/skills/simple-task/SKILL.md +4 -0
  97. package/templates/CLAUDE.md +2 -36
  98. package/templates/codex-AGENTS.md +1 -2
  99. package/templates/codex-hook-runner.js +85 -0
  100. package/dist/utils/sddPaths.d.ts +0 -69
  101. package/dist/utils/sddPaths.js +0 -138
  102. package/dist/utils/sddPaths.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
+ import { createInterface } from 'readline/promises';
4
5
  import { SkillManager } from '../skills/SkillManager.js';
5
6
  import { RulesManager } from '../rules/RulesManager.js';
6
7
  import { ContextManager } from '../contexts/ContextManager.js';
@@ -8,7 +9,11 @@ import { AgentManager } from '../agents/AgentManager.js';
8
9
  import { HookLoader } from '../hooks/HookLoader.js';
9
10
  import { generateCodexAgentsMd } from './tool-support/codex.js';
10
11
  import { createAntigravitySymlinks } from './tool-support/antigravity.js';
11
- import { getDistCliDir, findTemplate } from './utils/find-package-root.js';
12
+ import { getDistCliDir } from './utils/find-package-root.js';
13
+ import { CliUsageError, InstallCancelledError, getTargetPolicy, isInstallTarget, resolveInstallPaths, resolveInstallTarget, } from './install-target.js';
14
+ import { installClaudeCodeTarget } from './tool-support/claude-code.js';
15
+ import { installCodexTarget } from './tool-support/codex.js';
16
+ import { updateGeneratedIgnores } from './utils/gitignore-manager.js';
12
17
  /**
13
18
  * CLI for installing SDD components to a project
14
19
  */
@@ -19,12 +24,13 @@ export class InstallSkillsCLI {
19
24
  agentManager;
20
25
  hookLoader;
21
26
  steeringPath;
27
+ promptIO;
22
28
  /**
23
29
  * Create CLI instance
24
30
  * @param skillsPath - Optional path to skills directory (for testing)
25
31
  * @param steeringPath - Optional path to steering directory (for testing)
26
32
  */
27
- constructor(skillsPath, steeringPath) {
33
+ constructor(skillsPath, steeringPath, promptIO) {
28
34
  // If no path provided, determine from package location
29
35
  const resolvedSkillsPath = skillsPath || this.getDefaultPath('skills');
30
36
  const resolvedSteeringPath = steeringPath || this.getDefaultPath('steering');
@@ -38,6 +44,7 @@ export class InstallSkillsCLI {
38
44
  this.agentManager = new AgentManager(resolvedAgentsPath);
39
45
  this.hookLoader = new HookLoader(resolvedHooksPath);
40
46
  this.steeringPath = resolvedSteeringPath;
47
+ this.promptIO = promptIO ?? createProcessTargetPromptIO();
41
48
  }
42
49
  /**
43
50
  * Get the default path for a component type based on package location
@@ -99,40 +106,44 @@ export class InstallSkillsCLI {
99
106
  codex: false,
100
107
  antigravity: false,
101
108
  allTools: false,
109
+ installProfile: 'lean',
110
+ pathOverrides: {},
102
111
  };
103
112
  for (let i = 0; i < args.length; i++) {
104
113
  const arg = args[i];
105
114
  switch (arg) {
106
115
  case '--path':
107
- if (i + 1 < args.length) {
108
- options.targetPath = args[++i];
109
- }
116
+ options.targetPath = requireOptionValue(args, ++i, '--path');
117
+ options.pathOverrides.skills = options.targetPath;
110
118
  break;
111
119
  case '--steering-path':
112
- if (i + 1 < args.length) {
113
- options.steeringPath = args[++i];
114
- }
120
+ options.steeringPath = requireOptionValue(args, ++i, '--steering-path');
121
+ options.pathOverrides.steering = options.steeringPath;
115
122
  break;
116
123
  case '--rules-path':
117
- if (i + 1 < args.length) {
118
- options.rulesPath = args[++i];
119
- }
124
+ options.rulesPath = requireOptionValue(args, ++i, '--rules-path');
125
+ options.pathOverrides.rules = options.rulesPath;
120
126
  break;
121
127
  case '--contexts-path':
122
- if (i + 1 < args.length) {
123
- options.contextsPath = args[++i];
124
- }
128
+ options.contextsPath = requireOptionValue(args, ++i, '--contexts-path');
129
+ options.pathOverrides.contexts = options.contextsPath;
125
130
  break;
126
131
  case '--agents-path':
127
- if (i + 1 < args.length) {
128
- options.agentsPath = args[++i];
129
- }
132
+ options.agentsPath = requireOptionValue(args, ++i, '--agents-path');
133
+ options.pathOverrides.agents = options.agentsPath;
130
134
  break;
131
135
  case '--hooks-path':
132
- if (i + 1 < args.length) {
133
- options.hooksPath = args[++i];
136
+ options.hooksPath = requireOptionValue(args, ++i, '--hooks-path');
137
+ options.pathOverrides.hooks = options.hooksPath;
138
+ break;
139
+ case '--target': {
140
+ const target = requireOptionValue(args, ++i, '--target');
141
+ if (!isInstallTarget(target)) {
142
+ throw new CliUsageError(`Unsupported target "${target}". Choose codex or claude-code.`);
134
143
  }
144
+ options.target = target;
135
145
  break;
146
+ }
136
147
  case '--list':
137
148
  case '-l':
138
149
  options.listOnly = true;
@@ -165,8 +176,18 @@ export class InstallSkillsCLI {
165
176
  options.hooksOnly = true;
166
177
  options.components.push('hooks');
167
178
  break;
179
+ case '--profile':
180
+ {
181
+ const profile = requireOptionValue(args, ++i, '--profile');
182
+ if (profile !== 'lean' && profile !== 'full') {
183
+ throw new CliUsageError(`Unsupported profile "${profile}". Choose lean or full.`);
184
+ }
185
+ options.installProfile = profile;
186
+ }
187
+ break;
168
188
  case '--all':
169
189
  // Install all component types
190
+ options.installProfile = 'full';
170
191
  options.components = ['skills', 'steering', 'rules', 'contexts', 'agents', 'hooks'];
171
192
  break;
172
193
  case '--codex':
@@ -198,7 +219,7 @@ export class InstallSkillsCLI {
198
219
  await this.installSkills(options.targetPath);
199
220
  }
200
221
  /**
201
- * Run unified install (all components)
222
+ * Run a target-aware component install
202
223
  * @param options - CLI options
203
224
  */
204
225
  async runUnified(options) {
@@ -210,89 +231,109 @@ export class InstallSkillsCLI {
210
231
  await this.listAll();
211
232
  return;
212
233
  }
234
+ const resolvedTarget = await resolveInstallTarget({
235
+ target: options.target,
236
+ legacyCodex: options.codex,
237
+ profile: options.installProfile,
238
+ }, this.promptIO);
239
+ const policy = getTargetPolicy(resolvedTarget.target);
240
+ const paths = resolveInstallPaths(policy, options.pathOverrides ?? legacyPathOverrides(options));
213
241
  // If specific components requested, install only those
214
242
  const hasSpecificComponents = options.components.length > 0;
215
243
  const componentsToInstall = hasSpecificComponents
216
244
  ? options.components
217
- : ['skills', 'steering', 'rules', 'contexts', 'agents', 'hooks'];
218
- console.log('\n🚀 SDD Component Installer\n');
219
- for (const component of componentsToInstall) {
220
- switch (component) {
221
- case 'skills':
222
- await this.installSkills(options.targetPath);
223
- break;
224
- case 'steering':
225
- await this.installSteering(options.steeringPath);
226
- break;
227
- case 'rules':
228
- await this.installRules(options.rulesPath);
229
- break;
230
- case 'contexts':
231
- await this.installContexts(options.contextsPath);
232
- break;
233
- case 'agents':
234
- await this.installAgents(options.agentsPath);
235
- break;
236
- case 'hooks':
237
- await this.installHooks(options.hooksPath);
238
- break;
239
- }
245
+ : this.getDefaultComponents(options.installProfile);
246
+ console.log(`\n🚀 SDD Component Installer (${options.installProfile} profile, ${resolvedTarget.target})\n`);
247
+ const projectRoot = process.cwd();
248
+ const request = {
249
+ projectRoot,
250
+ paths,
251
+ components: componentsToInstall,
252
+ sources: {
253
+ skillManager: this.skillManager,
254
+ rulesManager: this.rulesManager,
255
+ contextManager: this.contextManager,
256
+ agentManager: this.agentManager,
257
+ hookLoader: this.hookLoader,
258
+ steeringSource: this.steeringPath,
259
+ },
260
+ };
261
+ const report = resolvedTarget.target === 'codex'
262
+ ? await installCodexTarget(request)
263
+ : await installClaudeCodeTarget(request);
264
+ try {
265
+ const ignore = await updateGeneratedIgnores(projectRoot, policy.ignoreEntries);
266
+ console.log(` .gitignore: ${ignore.status}`);
267
+ }
268
+ catch (error) {
269
+ report.failed.push({
270
+ component: 'root',
271
+ name: '.gitignore',
272
+ path: path.join(projectRoot, '.gitignore'),
273
+ error: error instanceof Error ? error.message : String(error),
274
+ });
240
275
  }
241
- // Generate CLAUDE.md in project root
242
- this.generateClaudeMd();
243
276
  // Multi-tool support: Codex CLI
244
- if (options.codex || options.allTools) {
245
- const projectRoot = process.cwd();
246
- await generateCodexAgentsMd(projectRoot, {
277
+ if (options.allTools && resolvedTarget.target !== 'codex') {
278
+ const failures = await generateCodexAgentsMd(projectRoot, {
247
279
  skillManager: this.skillManager,
248
280
  rulesManager: this.rulesManager,
249
281
  agentManager: this.agentManager,
250
282
  listSteering: () => this.listSteering(),
251
283
  }, {
252
- skillsPath: options.targetPath,
253
- rulesPath: options.rulesPath,
254
- agentsPath: options.agentsPath,
255
- steeringPath: options.steeringPath,
284
+ skillsPath: paths.skills,
285
+ rulesPath: paths.rules,
286
+ agentsPath: paths.agents,
287
+ steeringPath: paths.steering,
256
288
  }, {
257
289
  skills: componentsToInstall.includes('skills'),
258
290
  rules: componentsToInstall.includes('rules'),
259
291
  agents: componentsToInstall.includes('agents'),
260
292
  steering: componentsToInstall.includes('steering'),
261
293
  });
294
+ for (const failure of failures) {
295
+ report.failed.push({
296
+ component: 'root',
297
+ name: `codex/${failure.name}`,
298
+ path: failure.path,
299
+ error: failure.error,
300
+ });
301
+ }
262
302
  }
263
303
  // Multi-tool support: Google Antigravity
264
304
  if (options.antigravity || options.allTools) {
265
- const projectRoot = process.cwd();
266
- await createAntigravitySymlinks(projectRoot, {
267
- skillsPath: options.targetPath,
268
- rulesPath: options.rulesPath,
305
+ const failures = await createAntigravitySymlinks(projectRoot, {
306
+ skillsPath: paths.skills,
307
+ rulesPath: paths.rules,
269
308
  });
309
+ for (const failure of failures) {
310
+ report.failed.push({
311
+ component: 'root',
312
+ name: failure.name === '.agent' ? failure.name : `.agent/${failure.name}`,
313
+ path: failure.path,
314
+ error: failure.error,
315
+ });
316
+ }
270
317
  }
271
- console.log('\n✨ Installation complete!\n');
272
- }
273
- /**
274
- * Generate CLAUDE.md in the user's project root from the template
275
- */
276
- generateClaudeMd() {
277
- const targetPath = path.resolve(process.cwd(), 'CLAUDE.md');
278
- // Don't overwrite if user already has one
279
- if (fs.existsSync(targetPath)) {
280
- console.log(' ⏭️ CLAUDE.md already exists, skipping');
281
- return;
282
- }
283
- // Find the template
284
- const templatePath = findTemplate('CLAUDE.md');
285
- if (!templatePath) {
286
- console.log(' ⚠️ CLAUDE.md template not found, skipping');
318
+ console.log(`\nTarget: ${resolvedTarget.target} (${resolvedTarget.source})`);
319
+ console.log(`Installed: ${report.installed.length}`);
320
+ console.log(`Skipped: ${report.skipped.length}`);
321
+ console.log(`Failed: ${report.failed.length}`);
322
+ if (report.failed.length > 0) {
323
+ for (const failure of report.failed) {
324
+ console.error(` ${failure.component}/${failure.name} (${failure.path}): ${failure.error}`);
325
+ }
326
+ process.exitCode = 1;
327
+ console.error('\nInstallation incomplete.\n');
287
328
  return;
288
329
  }
289
- try {
290
- fs.copyFileSync(templatePath, targetPath);
291
- console.log(' ✅ Created CLAUDE.md in project root');
292
- }
293
- catch (error) {
294
- console.error(' ❌ Failed to create CLAUDE.md:', error.message);
330
+ console.log('\n✨ Installation complete!\n');
331
+ }
332
+ getDefaultComponents(profile) {
333
+ if (profile === 'full') {
334
+ return ['skills', 'steering', 'rules', 'contexts', 'agents', 'hooks'];
295
335
  }
336
+ return ['skills', 'steering', 'hooks'];
296
337
  }
297
338
  /**
298
339
  * List available skills
@@ -426,7 +467,7 @@ export class InstallSkillsCLI {
426
467
  }
427
468
  console.log(`\n Total: ${hooks.length} hooks\n`);
428
469
  }
429
- console.log('Run "npx sdd-mcp-server install" to install all components.\n');
470
+ console.log('Run "npx sdd-mcp-server install --profile full" to install all components.\n');
430
471
  }
431
472
  /**
432
473
  * Install skills to target directory
@@ -440,49 +481,6 @@ export class InstallSkillsCLI {
440
481
  console.log(' Use /sdd-requirements, /sdd-design, etc. in Claude Code.\n');
441
482
  }
442
483
  }
443
- /**
444
- * Install steering documents to target directory
445
- */
446
- async installSteering(targetPath) {
447
- console.log(`\nInstalling steering documents to: ${targetPath}\n`);
448
- const result = await this.installSteeringFiles(targetPath);
449
- this.logInstallResult(result, 'steering documents');
450
- if (result.installed.length > 0) {
451
- console.log('Steering documents installed successfully!');
452
- console.log(' These provide project-wide guidance for AI interactions.\n');
453
- }
454
- }
455
- /**
456
- * Copy steering files to target directory
457
- */
458
- async installSteeringFiles(targetPath) {
459
- const installed = [];
460
- const failed = [];
461
- try {
462
- await fs.promises.mkdir(targetPath, { recursive: true });
463
- const entries = await fs.promises.readdir(this.steeringPath);
464
- for (const entry of entries) {
465
- if (!entry.endsWith('.md'))
466
- continue;
467
- try {
468
- const sourceFile = path.join(this.steeringPath, entry);
469
- const destFile = path.join(targetPath, entry);
470
- await fs.promises.copyFile(sourceFile, destFile);
471
- installed.push(entry);
472
- }
473
- catch (error) {
474
- failed.push({
475
- name: entry,
476
- error: error instanceof Error ? error.message : String(error),
477
- });
478
- }
479
- }
480
- }
481
- catch (error) {
482
- console.error(`Failed to read steering directory: ${error instanceof Error ? error.message : String(error)}`);
483
- }
484
- return { installed, failed };
485
- }
486
484
  /**
487
485
  * Log installation results with consistent formatting
488
486
  */
@@ -502,38 +500,6 @@ export class InstallSkillsCLI {
502
500
  console.log('');
503
501
  }
504
502
  }
505
- /**
506
- * Install rules to target directory
507
- */
508
- async installRules(targetPath) {
509
- console.log(`Installing rules to: ${targetPath}\n`);
510
- const result = await this.rulesManager.installComponents(targetPath);
511
- this.logInstallResult(result, 'rules');
512
- }
513
- /**
514
- * Install contexts to target directory
515
- */
516
- async installContexts(targetPath) {
517
- console.log(`Installing contexts to: ${targetPath}\n`);
518
- const result = await this.contextManager.installComponents(targetPath);
519
- this.logInstallResult(result, 'contexts');
520
- }
521
- /**
522
- * Install agents to target directory
523
- */
524
- async installAgents(targetPath) {
525
- console.log(`Installing agents to: ${targetPath}\n`);
526
- const result = await this.agentManager.installComponents(targetPath);
527
- this.logInstallResult(result, 'agents');
528
- }
529
- /**
530
- * Install hooks to target directory
531
- */
532
- async installHooks(targetPath) {
533
- console.log(`Installing hooks to: ${targetPath}\n`);
534
- const result = await this.hookLoader.installComponents(targetPath);
535
- this.logInstallResult(result, 'hooks');
536
- }
537
503
  /**
538
504
  * Get help text
539
505
  * @returns Help message
@@ -574,27 +540,31 @@ SDD Unified Installer
574
540
 
575
541
  Usage: npx sdd-mcp-server install [options]
576
542
 
577
- Installs SDD components (skills, steering, rules, contexts, agents, hooks) to your project.
543
+ Installs SDD components to your project. The default lean profile installs skills,
544
+ steering, and hooks only to reduce always-on context and token usage.
578
545
 
579
546
  Component Options (install specific types):
580
- --skills Install skills only (to .claude/skills)
547
+ --target <target> Primary agent target: codex or claude-code
548
+ --skills Install skills only (to the selected target)
581
549
  --steering Install steering documents only (to .spec/steering)
582
- --rules Install rules only (to .claude/rules)
583
- --contexts Install contexts only (to .claude/contexts)
584
- --agents Install agents only (to .claude/agents)
585
- --hooks Install hooks only (to .claude/hooks)
586
- --all Install all component types (default behavior)
550
+ --rules Install rules only (to the selected target)
551
+ --contexts Install contexts only (to the selected target)
552
+ --agents Install agents only (to the selected target)
553
+ --hooks Install hooks only (to the selected target)
554
+ --all Install all component types
555
+ --profile <profile> Install profile when no component flags are provided:
556
+ lean (default) or full
587
557
 
588
558
  Path Options (customize installation targets):
589
- --path <dir> Target for skills (default: .claude/skills)
559
+ --path <dir> Override the selected target's skills path
590
560
  --steering-path <dir> Target for steering (default: .spec/steering)
591
- --rules-path <dir> Target for rules (default: .claude/rules)
592
- --contexts-path <dir> Target for contexts (default: .claude/contexts)
593
- --agents-path <dir> Target for agents (default: .claude/agents)
594
- --hooks-path <dir> Target for hooks (default: .claude/hooks)
561
+ --rules-path <dir> Override the selected target's rules path
562
+ --contexts-path <dir> Override the selected target's contexts path
563
+ --agents-path <dir> Override the selected target's agents path
564
+ --hooks-path <dir> Override the selected target's hooks path
595
565
 
596
566
  Multi-Tool Support:
597
- --codex Also generate AGENTS.md for OpenAI Codex CLI
567
+ --codex Deprecated alias for --target codex
598
568
  --antigravity Also create .agent/ symlinks for Google Antigravity
599
569
  --all-tools Enable all tool integrations (codex + antigravity)
600
570
 
@@ -603,12 +573,14 @@ Other Options:
603
573
  --help, -h Show this help message
604
574
 
605
575
  Examples:
606
- npx sdd-mcp-server install # Install all components
576
+ npx sdd-mcp-server install # Lean install for lower token usage
607
577
  npx sdd-mcp-server install --skills --rules # Install skills and rules only
608
578
  npx sdd-mcp-server install --list # List available components
609
- npx sdd-mcp-server install --codex # Claude + Codex CLI support
610
- npx sdd-mcp-server install --antigravity # Claude + Antigravity support
611
- npx sdd-mcp-server install --all-tools # Claude + all tool integrations
579
+ npx sdd-mcp-server install --profile full # Prompt for Codex or Claude Code
580
+ npx sdd-mcp-server install --target codex # Native Codex files
581
+ npx sdd-mcp-server install --target claude-code # Native Claude Code files
582
+ npx sdd-mcp-server install --antigravity # Add Antigravity support
583
+ npx sdd-mcp-server install --all-tools # Add all tool integrations
612
584
 
613
585
  Component Types:
614
586
  Skills - Workflow guidance for SDD phases (/sdd-requirements, /sdd-design, etc.)
@@ -618,7 +590,7 @@ Component Types:
618
590
  Agents - Specialized AI personas (planner, architect, reviewer)
619
591
  Hooks - Event-driven automation (pre-tool-use, post-tool-use, etc.)
620
592
 
621
- After installation, use skills in Claude Code:
593
+ After installation, use skills in the selected agent:
622
594
  /sdd-requirements <feature-name>
623
595
  /sdd-design <feature-name>
624
596
  /sdd-tasks <feature-name>
@@ -626,6 +598,11 @@ After installation, use skills in Claude Code:
626
598
  /sdd-review [file-path]
627
599
  /sdd-security-check [scope]
628
600
  /sdd-test-gen [file-path]
601
+
602
+ Model Routing:
603
+ Codex high-level roles: gpt-5.6-sol (xhigh); default implementation/TDD: gpt-5.6-luna (max)
604
+ Codex supported models: gpt-5.6-sol, gpt-5.6-luna, gpt-5.6-terra
605
+ Claude Code high-level roles: opus; implementation/TDD: sonnet
629
606
  `;
630
607
  }
631
608
  }
@@ -641,6 +618,11 @@ export async function mainInstall() {
641
618
  const options = cli.parseArgs(process.argv.slice(2));
642
619
  await cli.runUnified(options);
643
620
  }
621
+ export function cliExitCode(error) {
622
+ if (error instanceof InstallCancelledError)
623
+ return 130;
624
+ return 1;
625
+ }
644
626
  // ESM main module detection: check if this file is the entry point
645
627
  // Use path matching instead of import.meta.url for Jest compatibility
646
628
  const isMainModule = process.argv[1] && (process.argv[1].endsWith('/install-skills.js') ||
@@ -650,7 +632,82 @@ const isMainModule = process.argv[1] && (process.argv[1].endsWith('/install-skil
650
632
  if (isMainModule) {
651
633
  main().catch((error) => {
652
634
  console.error('Error:', error.message);
653
- process.exit(1);
635
+ process.exit(cliExitCode(error));
654
636
  });
655
637
  }
638
+ function requireOptionValue(args, index, option) {
639
+ const value = args[index];
640
+ if (!value || value.startsWith('--')) {
641
+ throw new CliUsageError(`${option} requires a value`);
642
+ }
643
+ return value;
644
+ }
645
+ function legacyPathOverrides(options) {
646
+ const defaults = getTargetPolicy('claude-code').defaultPaths;
647
+ return {
648
+ ...(options.targetPath !== defaults.skills ? { skills: options.targetPath } : {}),
649
+ ...(options.steeringPath !== defaults.steering ? { steering: options.steeringPath } : {}),
650
+ ...(options.rulesPath !== defaults.rules ? { rules: options.rulesPath } : {}),
651
+ ...(options.contextsPath !== defaults.contexts ? { contexts: options.contextsPath } : {}),
652
+ ...(options.agentsPath !== defaults.agents ? { agents: options.agentsPath } : {}),
653
+ ...(options.hooksPath !== defaults.hooks ? { hooks: options.hooksPath } : {}),
654
+ };
655
+ }
656
+ function createProcessTargetPromptIO() {
657
+ return {
658
+ isInteractive: () => Boolean(process.stdin.isTTY && process.stdout.isTTY),
659
+ writeNotice: message => console.warn(message),
660
+ async chooseTarget() {
661
+ const prompt = createInterface({ input: process.stdin, output: process.stdout });
662
+ let cancelled = false;
663
+ try {
664
+ while (!cancelled) {
665
+ const answer = await new Promise(resolve => {
666
+ let settled = false;
667
+ const cleanup = () => {
668
+ prompt.off('line', onLine);
669
+ prompt.off('close', onClose);
670
+ prompt.off('SIGINT', onSigint);
671
+ };
672
+ const settle = (value) => {
673
+ if (settled)
674
+ return;
675
+ settled = true;
676
+ cleanup();
677
+ resolve(value);
678
+ };
679
+ const onLine = (line) => settle(line);
680
+ const onClose = () => settle(null);
681
+ const onSigint = () => {
682
+ settle(null);
683
+ prompt.close();
684
+ };
685
+ prompt.once('line', onLine);
686
+ prompt.once('close', onClose);
687
+ prompt.once('SIGINT', onSigint);
688
+ prompt.question('Choose the primary LLM agent target:\n 1) Codex\n 2) Claude Code\nSelection: ').then(settle).catch(() => settle(null));
689
+ });
690
+ if (answer === null) {
691
+ cancelled = true;
692
+ continue;
693
+ }
694
+ const normalized = answer.trim().toLowerCase();
695
+ if (normalized === '1' || normalized === 'codex')
696
+ return 'codex';
697
+ if (normalized === '2' || normalized === 'claude' || normalized === 'claude-code') {
698
+ return 'claude-code';
699
+ }
700
+ console.warn('Choose 1 (Codex) or 2 (Claude Code).');
701
+ }
702
+ return null;
703
+ }
704
+ catch {
705
+ return null;
706
+ }
707
+ finally {
708
+ prompt.close();
709
+ }
710
+ },
711
+ };
712
+ }
656
713
  //# sourceMappingURL=install-skills.js.map