@specforge/mcp 3.0.6 → 3.1.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 (123) hide show
  1. package/dist/cli/commands/index.d.ts +2 -0
  2. package/dist/cli/commands/index.d.ts.map +1 -1
  3. package/dist/cli/commands/index.js +2 -0
  4. package/dist/cli/commands/index.js.map +1 -1
  5. package/dist/cli/commands/init.d.ts.map +1 -1
  6. package/dist/cli/commands/init.js +268 -2
  7. package/dist/cli/commands/init.js.map +1 -1
  8. package/dist/cli/commands/init.types.d.ts +39 -0
  9. package/dist/cli/commands/init.types.d.ts.map +1 -1
  10. package/dist/cli/commands/init.types.js +18 -0
  11. package/dist/cli/commands/init.types.js.map +1 -1
  12. package/dist/cli/commands/plan.d.ts +18 -0
  13. package/dist/cli/commands/plan.d.ts.map +1 -0
  14. package/dist/cli/commands/plan.js +154 -0
  15. package/dist/cli/commands/plan.js.map +1 -0
  16. package/dist/cli/commands/plan.types.d.ts +60 -0
  17. package/dist/cli/commands/plan.types.d.ts.map +1 -0
  18. package/dist/cli/commands/plan.types.js +8 -0
  19. package/dist/cli/commands/plan.types.js.map +1 -0
  20. package/dist/cli/commands/spec-activate.d.ts +29 -0
  21. package/dist/cli/commands/spec-activate.d.ts.map +1 -0
  22. package/dist/cli/commands/spec-activate.js +155 -0
  23. package/dist/cli/commands/spec-activate.js.map +1 -0
  24. package/dist/cli/commands/spec-activate.types.d.ts +24 -0
  25. package/dist/cli/commands/spec-activate.types.d.ts.map +1 -0
  26. package/dist/cli/commands/spec-activate.types.js +8 -0
  27. package/dist/cli/commands/spec-activate.types.js.map +1 -0
  28. package/dist/cli/commands/status.d.ts.map +1 -1
  29. package/dist/cli/commands/status.js +89 -1
  30. package/dist/cli/commands/status.js.map +1 -1
  31. package/dist/cli/commands/status.types.d.ts +2 -0
  32. package/dist/cli/commands/status.types.d.ts.map +1 -1
  33. package/dist/cli/commands/status.types.js.map +1 -1
  34. package/dist/cli/config/agent-teams.types.d.ts +194 -0
  35. package/dist/cli/config/agent-teams.types.d.ts.map +1 -0
  36. package/dist/cli/config/agent-teams.types.js +36 -0
  37. package/dist/cli/config/agent-teams.types.js.map +1 -0
  38. package/dist/cli/config/index.d.ts +2 -0
  39. package/dist/cli/config/index.d.ts.map +1 -1
  40. package/dist/cli/config/index.js +2 -0
  41. package/dist/cli/config/index.js.map +1 -1
  42. package/dist/cli/config/loader.d.ts +36 -2
  43. package/dist/cli/config/loader.d.ts.map +1 -1
  44. package/dist/cli/config/loader.js +65 -0
  45. package/dist/cli/config/loader.js.map +1 -1
  46. package/dist/cli/config/validation.d.ts +69 -0
  47. package/dist/cli/config/validation.d.ts.map +1 -0
  48. package/dist/cli/config/validation.js +295 -0
  49. package/dist/cli/config/validation.js.map +1 -0
  50. package/dist/cli/config/writer.d.ts +39 -0
  51. package/dist/cli/config/writer.d.ts.map +1 -1
  52. package/dist/cli/config/writer.js +58 -0
  53. package/dist/cli/config/writer.js.map +1 -1
  54. package/dist/cli/index.d.ts.map +1 -1
  55. package/dist/cli/index.js +5 -1
  56. package/dist/cli/index.js.map +1 -1
  57. package/dist/lib/index.d.ts +3 -0
  58. package/dist/lib/index.d.ts.map +1 -1
  59. package/dist/lib/index.js +3 -0
  60. package/dist/lib/index.js.map +1 -1
  61. package/dist/lib/monorepo-detector.d.ts +31 -0
  62. package/dist/lib/monorepo-detector.d.ts.map +1 -0
  63. package/dist/lib/monorepo-detector.js +271 -0
  64. package/dist/lib/monorepo-detector.js.map +1 -0
  65. package/dist/lib/prompt-generator.d.ts +65 -0
  66. package/dist/lib/prompt-generator.d.ts.map +1 -0
  67. package/dist/lib/prompt-generator.js +172 -0
  68. package/dist/lib/prompt-generator.js.map +1 -0
  69. package/dist/lib/strategy-analyzer.d.ts +59 -0
  70. package/dist/lib/strategy-analyzer.d.ts.map +1 -0
  71. package/dist/lib/strategy-analyzer.js +137 -0
  72. package/dist/lib/strategy-analyzer.js.map +1 -0
  73. package/dist/tools/core/blueprint.d.ts.map +1 -1
  74. package/dist/tools/core/blueprint.js +6 -0
  75. package/dist/tools/core/blueprint.js.map +1 -1
  76. package/dist/tools/core/context-helper.d.ts +22 -0
  77. package/dist/tools/core/context-helper.d.ts.map +1 -1
  78. package/dist/tools/core/context-helper.js +37 -1
  79. package/dist/tools/core/context-helper.js.map +1 -1
  80. package/dist/tools/core/workspace-files.d.ts +49 -0
  81. package/dist/tools/core/workspace-files.d.ts.map +1 -0
  82. package/dist/tools/core/workspace-files.js +259 -0
  83. package/dist/tools/core/workspace-files.js.map +1 -0
  84. package/dist/tools/index.d.ts.map +1 -1
  85. package/dist/tools/index.js +147 -0
  86. package/dist/tools/index.js.map +1 -1
  87. package/package.json +3 -2
  88. package/src/cli/templates/agents/content/core/sfag-implementer.ts +113 -0
  89. package/src/cli/templates/agents/content/core/sfag-orchestrator.ts +107 -0
  90. package/src/cli/templates/agents/content/core/sfag-spec-creator.ts +126 -0
  91. package/src/cli/templates/agents/content/core/sfag-ticket-implementer.ts +132 -0
  92. package/src/cli/templates/agents/content/research/sfag-package-researcher.ts +153 -0
  93. package/src/cli/templates/agents/content/task-type/sfag-api-implementer.ts +132 -0
  94. package/src/cli/templates/agents/content/task-type/sfag-docs-writer.ts +183 -0
  95. package/src/cli/templates/agents/content/task-type/sfag-frontend-builder.ts +141 -0
  96. package/src/cli/templates/agents/content/task-type/sfag-infra-architect.ts +149 -0
  97. package/src/cli/templates/agents/content/task-type/sfag-schema-designer.ts +132 -0
  98. package/src/cli/templates/agents/content/task-type/sfag-test-writer.ts +171 -0
  99. package/src/cli/templates/agents/index.ts +74 -0
  100. package/src/cli/templates/commands.ts +179 -0
  101. package/src/cli/templates/content/sf-autonomous.ts +78 -0
  102. package/src/cli/templates/content/sf-blockers.ts +68 -0
  103. package/src/cli/templates/content/sf-commit.ts +78 -0
  104. package/src/cli/templates/content/sf-context.ts +64 -0
  105. package/src/cli/templates/content/sf-create-epics.ts +129 -0
  106. package/src/cli/templates/content/sf-create-spec.ts +136 -0
  107. package/src/cli/templates/content/sf-create-tickets.ts +148 -0
  108. package/src/cli/templates/content/sf-epic.ts +69 -0
  109. package/src/cli/templates/content/sf-help.ts +61 -0
  110. package/src/cli/templates/content/sf-import.ts +88 -0
  111. package/src/cli/templates/content/sf-init.ts +61 -0
  112. package/src/cli/templates/content/sf-next.ts +67 -0
  113. package/src/cli/templates/content/sf-reset.ts +78 -0
  114. package/src/cli/templates/content/sf-review.ts +67 -0
  115. package/src/cli/templates/content/sf-search.ts +64 -0
  116. package/src/cli/templates/content/sf-status.ts +67 -0
  117. package/src/cli/templates/content/sf-ticket.ts +76 -0
  118. package/src/cli/templates/content/sf-validate.ts +78 -0
  119. package/src/cli/templates/index.ts +16 -0
  120. package/src/cli/templates/skills/specforge-conventions.md +109 -0
  121. package/src/cli/templates/skills/specforge-orchestrator.md +401 -0
  122. package/src/cli/templates/skills/specforge-validator.md +122 -0
  123. package/src/cli/templates/skills/specforge-worker.md +378 -0
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Plan Command
3
+ *
4
+ * Dry-run visualization of the Agent Teams implementation plan.
5
+ * Calls get_implementation_plan via MCP and displays an ASCII tree
6
+ * showing team-worker mapping, execution phases, and dependency status.
7
+ */
8
+ import ora from 'ora';
9
+ import { resolveConfig } from '../config/index.js';
10
+ import { loadProjectConfig, getActiveSpecification } from '../config/loader.js';
11
+ import { withErrorHandler, CliError, NetworkError } from '../middleware/error-handler.js';
12
+ import { printBlank, printJson } from '../ui/output.js';
13
+ import { colors } from '../ui/colors.js';
14
+ import { ApiClient } from '../../client/api-client.js';
15
+ /**
16
+ * Resolve the specification ID from options or active spec config
17
+ */
18
+ function resolveSpecificationId(options, configSpecId) {
19
+ if (options.spec) {
20
+ return options.spec;
21
+ }
22
+ // Try active specification from .specforge.json
23
+ const projectConfig = loadProjectConfig();
24
+ const activeSpec = getActiveSpecification(projectConfig);
25
+ if (activeSpec?.id) {
26
+ return activeSpec.id;
27
+ }
28
+ // Fall back to specificationId from resolved config
29
+ if (configSpecId) {
30
+ return configSpecId;
31
+ }
32
+ throw new CliError('No active specification', 1, "Run 'specforge spec activate <id>' to set an active specification, or use --spec <id>");
33
+ }
34
+ /**
35
+ * Render the ASCII tree visualization of the implementation plan
36
+ */
37
+ function renderPlanTree(plan) {
38
+ printBlank();
39
+ // Strategy header
40
+ console.log(`${colors.bold('Strategy:')} ${colors.primary(plan.strategy)} ${colors.muted(`(${plan.reasoning})`)}`);
41
+ printBlank();
42
+ if (plan.teams.length === 0) {
43
+ console.log(colors.muted('No teams to display. The specification may have no remaining work.'));
44
+ printBlank();
45
+ return;
46
+ }
47
+ // Build a lookup: team name -> phase number
48
+ const teamPhaseMap = new Map();
49
+ for (const phase of plan.executionOrder) {
50
+ for (const teamName of phase.teams) {
51
+ teamPhaseMap.set(teamName, phase.phase);
52
+ }
53
+ }
54
+ // Render by execution phase
55
+ for (const phase of plan.executionOrder) {
56
+ const phaseLabel = phase.phase === 1
57
+ ? 'parallel'
58
+ : `after phase ${phase.phase - 1}`;
59
+ console.log(colors.bold(`Phase ${phase.phase}`) + colors.muted(` (${phaseLabel}):`));
60
+ // Find teams in this phase
61
+ const phaseTeams = plan.teams.filter(t => phase.teams.includes(t.name));
62
+ for (const team of phaseTeams) {
63
+ console.log(` ${colors.bold('Team:')} ${colors.primary(team.name)} ${colors.muted(`(${team.suggestedWorkers} worker${team.suggestedWorkers === 1 ? '' : 's'})`)}`);
64
+ for (const task of team.tasks) {
65
+ const isBlocked = task.blockedBy.length > 0;
66
+ if (isBlocked) {
67
+ const deps = task.blockedBy.join(', ');
68
+ console.log(` ${colors.warning('[BLOCKED]')} ${task.slug}: ${task.title} ${colors.muted(`(by ${deps})`)}`);
69
+ }
70
+ else {
71
+ console.log(` ${colors.success('[READY]')} ${task.slug}: ${task.title}`);
72
+ }
73
+ }
74
+ }
75
+ printBlank();
76
+ }
77
+ // Summary line
78
+ console.log(`${colors.bold('Total:')} ${plan.estimatedTotalTickets} tickets, ` +
79
+ `${plan.estimatedParallelizableTickets} parallelizable`);
80
+ printBlank();
81
+ }
82
+ /**
83
+ * Plan command action handler
84
+ */
85
+ export async function planAction(options) {
86
+ const config = resolveConfig();
87
+ if (!config.apiKey) {
88
+ throw new CliError('Not authenticated', 1, 'Run `specforge login` to authenticate first');
89
+ }
90
+ const specificationId = resolveSpecificationId(options, config.specificationId);
91
+ const spinner = ora({
92
+ text: 'Generating implementation plan...',
93
+ color: 'cyan',
94
+ }).start();
95
+ try {
96
+ const client = new ApiClient({
97
+ apiKey: config.apiKey,
98
+ apiUrl: config.apiUrl,
99
+ debug: config.debug,
100
+ });
101
+ const plan = await client.call('get_implementation_plan', {
102
+ specificationId,
103
+ ...(options.strategy && options.strategy !== 'auto' ? { strategy: options.strategy } : {}),
104
+ });
105
+ spinner.stop();
106
+ if (options.json) {
107
+ printJson(plan);
108
+ }
109
+ else {
110
+ renderPlanTree(plan);
111
+ }
112
+ }
113
+ catch (error) {
114
+ spinner.fail('Failed to generate implementation plan');
115
+ const message = error instanceof Error ? error.message : 'Unknown error';
116
+ if (message.includes('401') || message.includes('Unauthorized')) {
117
+ throw new CliError('Authentication failed', 1, 'Your API key may be invalid. Run `specforge login` to re-authenticate');
118
+ }
119
+ if (message.includes('404') || message.includes('Not Found') || message.includes('not found')) {
120
+ throw new CliError(`Specification not found: ${specificationId}`, 1, "Run 'specforge specs' to list available specifications.");
121
+ }
122
+ throw new NetworkError(`Failed to generate plan: ${message}`);
123
+ }
124
+ }
125
+ /**
126
+ * Register plan command with Commander
127
+ */
128
+ export function registerPlanCommand(program) {
129
+ program
130
+ .command('plan')
131
+ .description('Preview Agent Teams implementation plan (dry-run)')
132
+ .option('--strategy <type>', 'Override strategy: epic-as-team | spec-as-team | single-session | auto')
133
+ .option('--spec <id>', 'Specification ID (overrides active spec)')
134
+ .option('--json', 'Output raw JSON plan')
135
+ .addHelpText('after', `
136
+ Examples:
137
+ $ specforge plan # Preview plan for active spec
138
+ $ specforge plan --strategy epic-as-team # Force epic-as-team strategy
139
+ $ specforge plan --spec ff1f8edb-4976-458b-acb0 # Plan for a specific spec
140
+ $ specforge plan --json # Output raw JSON for scripting
141
+
142
+ Output shows:
143
+ - Strategy name and reasoning
144
+ - Execution phases with team groupings
145
+ - Ticket-to-worker mapping with dependency indicators
146
+ - [READY] for tickets that can start immediately
147
+ - [BLOCKED] for tickets waiting on dependencies
148
+
149
+ This is a dry-run visualization - it does NOT execute anything.
150
+ Use 'specforge spec activate <specId>' to set the active specification.
151
+ `)
152
+ .action(withErrorHandler(planAction));
153
+ }
154
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/cli/commands/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Plan Command Types
3
+ *
4
+ * Type definitions for the plan dry-run visualization command
5
+ * that previews Agent Teams implementation plans.
6
+ */
7
+ /**
8
+ * Command line options for plan command
9
+ */
10
+ export interface PlanOptions {
11
+ /** Output as raw JSON */
12
+ json?: boolean;
13
+ /** Override strategy: epic-as-team | spec-as-team | single-session | auto */
14
+ strategy?: string;
15
+ /** Override specification ID (instead of using active spec) */
16
+ spec?: string;
17
+ }
18
+ /**
19
+ * A single task within a team
20
+ */
21
+ export interface TaskDefinition {
22
+ ticketId: string;
23
+ title: string;
24
+ slug: string;
25
+ blockedBy: string[];
26
+ estimatedComplexity: string;
27
+ workspace: string | null;
28
+ }
29
+ /**
30
+ * A team definition from the implementation plan
31
+ */
32
+ export interface TeamDefinition {
33
+ name: string;
34
+ epicId: string;
35
+ epicTitle: string;
36
+ suggestedWorkers: number;
37
+ targetWorkspace: string | null;
38
+ canParallelizeWith: string[];
39
+ mustPrecede: string[];
40
+ tasks: TaskDefinition[];
41
+ }
42
+ /**
43
+ * An execution phase grouping teams
44
+ */
45
+ export interface ExecutionPhase {
46
+ phase: number;
47
+ teams: string[];
48
+ }
49
+ /**
50
+ * Full implementation plan response from the API
51
+ */
52
+ export interface ImplementationPlan {
53
+ strategy: string;
54
+ reasoning: string;
55
+ teams: TeamDefinition[];
56
+ executionOrder: ExecutionPhase[];
57
+ estimatedTotalTickets: number;
58
+ estimatedParallelizableTickets: number;
59
+ }
60
+ //# sourceMappingURL=plan.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.types.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plan.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,8BAA8B,EAAE,MAAM,CAAC;CACxC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Plan Command Types
3
+ *
4
+ * Type definitions for the plan dry-run visualization command
5
+ * that previews Agent Teams implementation plans.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=plan.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.types.js","sourceRoot":"","sources":["../../../src/cli/commands/plan.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Spec Activate Command
3
+ *
4
+ * Sets or clears the active specification in .specforge.json.
5
+ * The active specification tells Agent Teams which spec to implement.
6
+ */
7
+ import { Command } from 'commander';
8
+ /**
9
+ * Activate a specification as the active spec for Agent Teams
10
+ *
11
+ * @param specId Specification ID to activate
12
+ * @param options Command options
13
+ */
14
+ export declare function specActivateAction(specId: string, options: {
15
+ json?: boolean;
16
+ }): Promise<void>;
17
+ /**
18
+ * Deactivate the current active specification
19
+ *
20
+ * @param options Command options
21
+ */
22
+ export declare function specDeactivateAction(options: {
23
+ json?: boolean;
24
+ }): Promise<void>;
25
+ /**
26
+ * Register spec activate/deactivate commands with Commander
27
+ */
28
+ export declare function registerSpecActivateCommand(program: Command): void;
29
+ //# sourceMappingURL=spec-activate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-activate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/spec-activate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CA2Gf;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuClE"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Spec Activate Command
3
+ *
4
+ * Sets or clears the active specification in .specforge.json.
5
+ * The active specification tells Agent Teams which spec to implement.
6
+ */
7
+ import ora from 'ora';
8
+ import { resolveConfig } from '../config/index.js';
9
+ import { setActiveSpecification } from '../config/writer.js';
10
+ import { withErrorHandler, CliError, NetworkError, ValidationError } from '../middleware/error-handler.js';
11
+ import { printBlank, printSuccess, printJson } from '../ui/output.js';
12
+ import { colors } from '../ui/colors.js';
13
+ import { ApiClient } from '../../client/api-client.js';
14
+ /**
15
+ * Activate a specification as the active spec for Agent Teams
16
+ *
17
+ * @param specId Specification ID to activate
18
+ * @param options Command options
19
+ */
20
+ export async function specActivateAction(specId, options) {
21
+ if (!specId || specId.trim() === '') {
22
+ throw new ValidationError('Specification ID is required', 'Usage: specforge spec activate <specId>');
23
+ }
24
+ const config = resolveConfig();
25
+ if (!config.apiKey) {
26
+ throw new CliError('Not authenticated', 1, 'Run `specforge login` to authenticate first');
27
+ }
28
+ const spinner = ora({
29
+ text: 'Validating specification...',
30
+ color: 'cyan',
31
+ }).start();
32
+ try {
33
+ const client = new ApiClient({
34
+ apiKey: config.apiKey,
35
+ apiUrl: config.apiUrl,
36
+ debug: config.debug,
37
+ });
38
+ // Validate the specification exists
39
+ const spec = await client.call('get_specification', {
40
+ specificationId: specId,
41
+ summary: true,
42
+ });
43
+ if (!spec || !spec.id) {
44
+ spinner.fail('Specification not found');
45
+ throw new CliError(`Specification not found: ${specId}`, 1, "Run 'specforge specs' to list available specifications.");
46
+ }
47
+ // Set active specification in .specforge.json
48
+ spinner.text = 'Setting active specification...';
49
+ setActiveSpecification({
50
+ id: spec.id,
51
+ title: spec.title,
52
+ activatedAt: new Date().toISOString(),
53
+ });
54
+ spinner.succeed(`Active specification set to: ${colors.primary(spec.title)}`);
55
+ if (options.json) {
56
+ printJson({
57
+ action: 'activate',
58
+ specification: {
59
+ id: spec.id,
60
+ title: spec.title,
61
+ status: spec.status,
62
+ epicCount: spec.epicCount,
63
+ ticketCount: spec.ticketCount,
64
+ completedTicketCount: spec.completedTicketCount,
65
+ },
66
+ });
67
+ }
68
+ else {
69
+ printBlank();
70
+ console.log(colors.muted(` ID: ${spec.id}`));
71
+ console.log(colors.muted(` Status: ${spec.status}`));
72
+ if (spec.ticketCount !== undefined) {
73
+ const completed = spec.completedTicketCount ?? 0;
74
+ console.log(colors.muted(` Tickets: ${completed}/${spec.ticketCount} completed`));
75
+ }
76
+ printBlank();
77
+ console.log(colors.muted("Run 'specforge status' to see the current context."));
78
+ printBlank();
79
+ }
80
+ }
81
+ catch (error) {
82
+ if (error instanceof CliError || error instanceof ValidationError) {
83
+ spinner.stop();
84
+ throw error;
85
+ }
86
+ spinner.fail('Failed to activate specification');
87
+ const message = error instanceof Error ? error.message : 'Unknown error';
88
+ if (message.includes('401') || message.includes('Unauthorized')) {
89
+ throw new CliError('Authentication failed', 1, 'Your API key may be invalid. Run `specforge login` to re-authenticate');
90
+ }
91
+ if (message.includes('404') || message.includes('Not Found') || message.includes('not found')) {
92
+ throw new CliError(`Specification not found: ${specId}`, 1, "Run 'specforge specs' to list available specifications.");
93
+ }
94
+ throw new NetworkError(`Failed to activate specification: ${message}`);
95
+ }
96
+ }
97
+ /**
98
+ * Deactivate the current active specification
99
+ *
100
+ * @param options Command options
101
+ */
102
+ export async function specDeactivateAction(options) {
103
+ setActiveSpecification(null);
104
+ if (options.json) {
105
+ printJson({ action: 'deactivate', specification: null });
106
+ }
107
+ else {
108
+ printSuccess('Active specification cleared');
109
+ printBlank();
110
+ console.log(colors.muted("No specification is active. Run 'specforge spec activate <specId>' to set one."));
111
+ printBlank();
112
+ }
113
+ }
114
+ /**
115
+ * Register spec activate/deactivate commands with Commander
116
+ */
117
+ export function registerSpecActivateCommand(program) {
118
+ const spec = program
119
+ .command('spec')
120
+ .description('Manage active specification for Agent Teams');
121
+ spec
122
+ .command('activate <specId>')
123
+ .description('Set active specification for Agent Teams implementation')
124
+ .option('--json', 'Output in JSON format')
125
+ .addHelpText('after', `
126
+ Arguments:
127
+ specId Specification ID to activate
128
+
129
+ Examples:
130
+ $ specforge spec activate ff1f8edb-4976-458b-acb0-b0860cd9a60d
131
+ $ specforge spec activate ff1f8edb --json
132
+
133
+ The active specification is stored in .specforge.json and tells Agent Teams
134
+ which specification to implement when you say "implement the active spec".
135
+
136
+ Use 'specforge specs' to list available specifications.
137
+ Use 'specforge spec deactivate' to clear the active specification.
138
+ `)
139
+ .action(withErrorHandler(specActivateAction));
140
+ spec
141
+ .command('deactivate')
142
+ .description('Clear the active specification')
143
+ .option('--json', 'Output in JSON format')
144
+ .addHelpText('after', `
145
+ Examples:
146
+ $ specforge spec deactivate
147
+ $ specforge spec deactivate --json
148
+
149
+ Removes the activeSpecification section from .specforge.json.
150
+ `)
151
+ .action(withErrorHandler(async (options) => {
152
+ await specDeactivateAction(options);
153
+ }));
154
+ }
155
+ //# sourceMappingURL=spec-activate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-activate.js","sourceRoot":"","sources":["../../../src/cli/commands/spec-activate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Spec Activate Command Types
3
+ *
4
+ * Type definitions for the spec activate/deactivate commands
5
+ * that manage the active specification in .specforge.json.
6
+ */
7
+ /**
8
+ * Specification summary from get_specification API (summary mode)
9
+ */
10
+ export interface SpecificationSummary {
11
+ /** Specification ID */
12
+ id: string;
13
+ /** Specification title */
14
+ title: string;
15
+ /** Current status */
16
+ status: string;
17
+ /** Number of epics */
18
+ epicCount?: number;
19
+ /** Total number of tickets */
20
+ ticketCount?: number;
21
+ /** Number of completed tickets */
22
+ completedTicketCount?: number;
23
+ }
24
+ //# sourceMappingURL=spec-activate.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-activate.types.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/spec-activate.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Spec Activate Command Types
3
+ *
4
+ * Type definitions for the spec activate/deactivate commands
5
+ * that manage the active specification in .specforge.json.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=spec-activate.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-activate.types.js","sourceRoot":"","sources":["../../../src/cli/commands/spec-activate.types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,EACL,aAAa,EAad,MAAM,mBAAmB,CAAC;AAsK3B;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkGxE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmC5D"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EACL,aAAa,EAad,MAAM,mBAAmB,CAAC;AAmO3B;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsIxE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2C5D"}
@@ -6,8 +6,9 @@
6
6
  */
7
7
  import ora from 'ora';
8
8
  import { resolveConfig } from '../config/index.js';
9
+ import { loadProjectConfig, getActiveSpecification } from '../config/loader.js';
9
10
  import { withErrorHandler, CliError, NetworkError } from '../middleware/error-handler.js';
10
- import { printBlank } from '../ui/output.js';
11
+ import { printBlank, printWarning } from '../ui/output.js';
11
12
  import { colors } from '../ui/colors.js';
12
13
  import { ApiClient } from '../../client/api-client.js';
13
14
  import { formatTicketNumber, formatDuration, hasWorkingContext, transformApiResponse, transformToDashboardData, calculateSessionProgress, } from './status.types.js';
@@ -102,6 +103,55 @@ function displayNextActionable(nextActionable) {
102
103
  console.log(colors.muted(` in ${nextActionable.epicTitle}`));
103
104
  }
104
105
  }
106
+ /**
107
+ * Build an ASCII progress bar
108
+ */
109
+ function buildProgressBar(percent, width = 10) {
110
+ const filled = Math.round((percent / 100) * width);
111
+ const empty = width - filled;
112
+ const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(empty);
113
+ // Color by progress: green >70%, yellow 30-70%, red <30%
114
+ const colorFn = percent > 70 ? colors.success : percent >= 30 ? colors.warning : colors.error;
115
+ return colorFn(`[${bar}]`);
116
+ }
117
+ /**
118
+ * Display Agent Teams progress
119
+ */
120
+ function displayTeamsProgress(plan) {
121
+ printBlank();
122
+ console.log(colors.bold('Agent Teams Progress'));
123
+ console.log(colors.muted('────────────────────'));
124
+ if (plan.teams.length === 0) {
125
+ console.log(colors.muted('No teams configured for this specification.'));
126
+ return;
127
+ }
128
+ // Strategy info
129
+ console.log(`Strategy: ${colors.primary(plan.strategy)}`);
130
+ printBlank();
131
+ // Per-team progress
132
+ for (const team of plan.teams) {
133
+ const total = team.tasks.length;
134
+ // Tasks with no blockers are considered "ready" (approximation of done + ready)
135
+ const blocked = team.tasks.filter(t => t.blockedBy.length > 0).length;
136
+ const ready = total - blocked;
137
+ const percent = total > 0 ? Math.round((ready / total) * 100) : 0;
138
+ const bar = buildProgressBar(percent);
139
+ console.log(` ${colors.bold(team.name)}: ${bar} ${percent}% (${ready}/${total} ready)`);
140
+ // Show blocked tasks
141
+ const blockedTasks = team.tasks.filter(t => t.blockedBy.length > 0);
142
+ for (const task of blockedTasks) {
143
+ const deps = task.blockedBy.join(', ');
144
+ console.log(` ${colors.warning('Blocked')}: ${task.slug} ${colors.muted(`(by ${deps})`)}`);
145
+ }
146
+ }
147
+ // Summary
148
+ printBlank();
149
+ const totalTickets = plan.estimatedTotalTickets;
150
+ const parallelizable = plan.estimatedParallelizableTickets;
151
+ console.log(`${colors.bold('Total:')} ${totalTickets} tickets, ` +
152
+ `${parallelizable} parallelizable, ` +
153
+ `${plan.teams.length} team${plan.teams.length === 1 ? '' : 's'}`);
154
+ }
105
155
  /**
106
156
  * Display status in console format
107
157
  */
@@ -207,6 +257,36 @@ export async function statusAction(options) {
207
257
  }
208
258
  return;
209
259
  }
260
+ // Teams mode
261
+ if (options.teams) {
262
+ // Resolve specification ID
263
+ const projectConfig = loadProjectConfig();
264
+ const activeSpec = getActiveSpecification(projectConfig);
265
+ const specId = activeSpec?.id || config.specificationId;
266
+ if (!specId) {
267
+ spinner.stop();
268
+ printBlank();
269
+ printWarning("No active specification. Run 'specforge spec activate <id>' to set one.");
270
+ printBlank();
271
+ return;
272
+ }
273
+ try {
274
+ const plan = await client.call('get_implementation_plan', { specificationId: specId });
275
+ spinner.stop();
276
+ if (options.json) {
277
+ console.log(JSON.stringify(plan, null, 2));
278
+ }
279
+ else {
280
+ displayTeamsProgress(plan);
281
+ }
282
+ }
283
+ catch (teamsError) {
284
+ spinner.stop();
285
+ const msg = teamsError instanceof Error ? teamsError.message : 'Unknown error';
286
+ throw new NetworkError(`Failed to fetch teams progress: ${msg}`);
287
+ }
288
+ return;
289
+ }
210
290
  // Transform API response to status
211
291
  const status = transformApiResponse(contextResponse, ticketsResponse);
212
292
  // Output based on format
@@ -237,6 +317,7 @@ export function registerStatusCommand(program) {
237
317
  .command('status')
238
318
  .description('Show current working context and session status')
239
319
  .option('-d, --dashboard', 'Show full project dashboard with analytics')
320
+ .option('-t, --teams', 'Show Agent Teams progress')
240
321
  .option('--json', 'Output as JSON')
241
322
  .option('--toon', 'Output as TOON format')
242
323
  .addHelpText('after', `
@@ -244,6 +325,7 @@ Examples:
244
325
  $ specforge status # Show current status
245
326
  $ specforge status -d # Show full dashboard with analytics
246
327
  $ specforge status --dashboard # Show full dashboard with analytics
328
+ $ specforge status --teams # Show Agent Teams progress
247
329
  $ specforge status --json # Output as JSON
248
330
  $ specforge status --toon # Output as TOON format
249
331
 
@@ -252,6 +334,12 @@ Displays:
252
334
  - Implementation Session: Active session status and statistics
253
335
  - Next Actionable: Suggested next ticket to work on
254
336
 
337
+ Teams View (--teams):
338
+ - Strategy and team structure
339
+ - Per-team progress bars with ticket completion
340
+ - Blocked tickets with dependency reasons
341
+ - Overall ticket and parallelization summary
342
+
255
343
  Dashboard View (--dashboard):
256
344
  - Overall Progress: Ticket completion with progress bar
257
345
  - Time Metrics: Estimated, actual, remaining hours and velocity