@specforge/mcp 3.0.7 → 3.1.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.
- package/dist/autopilot/agents/agent-runner.d.ts.map +1 -1
- package/dist/autopilot/agents/agent-runner.js +7 -0
- package/dist/autopilot/agents/agent-runner.js.map +1 -1
- package/dist/autopilot/api/autopilot-api-client.d.ts +5 -4
- package/dist/autopilot/api/autopilot-api-client.d.ts.map +1 -1
- package/dist/autopilot/api/autopilot-api-client.js +21 -26
- package/dist/autopilot/api/autopilot-api-client.js.map +1 -1
- package/dist/autopilot/cli/run.d.ts.map +1 -1
- package/dist/autopilot/cli/run.js +28 -0
- package/dist/autopilot/cli/run.js.map +1 -1
- package/dist/autopilot/core/dependency-resolver.d.ts +10 -1
- package/dist/autopilot/core/dependency-resolver.d.ts.map +1 -1
- package/dist/autopilot/core/dependency-resolver.js +27 -1
- package/dist/autopilot/core/dependency-resolver.js.map +1 -1
- package/dist/autopilot/core/dispatcher.d.ts +26 -0
- package/dist/autopilot/core/dispatcher.d.ts.map +1 -1
- package/dist/autopilot/core/dispatcher.js +116 -6
- package/dist/autopilot/core/dispatcher.js.map +1 -1
- package/dist/autopilot/readiness/aggregation.d.ts +56 -0
- package/dist/autopilot/readiness/aggregation.d.ts.map +1 -0
- package/dist/autopilot/readiness/aggregation.js +94 -0
- package/dist/autopilot/readiness/aggregation.js.map +1 -0
- package/dist/autopilot/readiness/config.d.ts +15 -0
- package/dist/autopilot/readiness/config.d.ts.map +1 -0
- package/dist/autopilot/readiness/config.js +76 -0
- package/dist/autopilot/readiness/config.js.map +1 -0
- package/dist/autopilot/readiness/index.d.ts +16 -0
- package/dist/autopilot/readiness/index.d.ts.map +1 -0
- package/dist/autopilot/readiness/index.js +11 -0
- package/dist/autopilot/readiness/index.js.map +1 -0
- package/dist/autopilot/readiness/post-scoring.d.ts +28 -0
- package/dist/autopilot/readiness/post-scoring.d.ts.map +1 -0
- package/dist/autopilot/readiness/post-scoring.js +41 -0
- package/dist/autopilot/readiness/post-scoring.js.map +1 -0
- package/dist/autopilot/readiness/preflight.d.ts +36 -0
- package/dist/autopilot/readiness/preflight.d.ts.map +1 -0
- package/dist/autopilot/readiness/preflight.js +93 -0
- package/dist/autopilot/readiness/preflight.js.map +1 -0
- package/dist/autopilot/readiness/prompt-section.d.ts +19 -0
- package/dist/autopilot/readiness/prompt-section.d.ts.map +1 -0
- package/dist/autopilot/readiness/prompt-section.js +33 -0
- package/dist/autopilot/readiness/prompt-section.js.map +1 -0
- package/dist/autopilot/readiness/types.d.ts +25 -0
- package/dist/autopilot/readiness/types.d.ts.map +1 -0
- package/dist/autopilot/readiness/types.js +8 -0
- package/dist/autopilot/readiness/types.js.map +1 -0
- package/dist/autopilot/sync/sync-manager.d.ts.map +1 -1
- package/dist/autopilot/sync/sync-manager.js +2 -1
- package/dist/autopilot/sync/sync-manager.js.map +1 -1
- package/dist/autopilot/types.d.ts +28 -0
- package/dist/autopilot/types.d.ts.map +1 -1
- package/dist/autopilot/types.js.map +1 -1
- package/dist/cli/commands/index.d.ts +5 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +5 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +184 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.types.d.ts +37 -0
- package/dist/cli/commands/init.types.d.ts.map +1 -1
- package/dist/cli/commands/init.types.js +18 -0
- package/dist/cli/commands/init.types.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +18 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +154 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/plan.types.d.ts +60 -0
- package/dist/cli/commands/plan.types.d.ts.map +1 -0
- package/dist/cli/commands/plan.types.js +8 -0
- package/dist/cli/commands/plan.types.js.map +1 -0
- package/dist/cli/commands/review-implementation.d.ts +16 -0
- package/dist/cli/commands/review-implementation.d.ts.map +1 -0
- package/dist/cli/commands/review-implementation.js +226 -0
- package/dist/cli/commands/review-implementation.js.map +1 -0
- package/dist/cli/commands/review-planning.d.ts +15 -0
- package/dist/cli/commands/review-planning.d.ts.map +1 -0
- package/dist/cli/commands/review-planning.js +177 -0
- package/dist/cli/commands/review-planning.js.map +1 -0
- package/dist/cli/commands/score/display.d.ts +20 -0
- package/dist/cli/commands/score/display.d.ts.map +1 -0
- package/dist/cli/commands/score/display.js +111 -0
- package/dist/cli/commands/score/display.js.map +1 -0
- package/dist/cli/commands/score/index.d.ts +9 -0
- package/dist/cli/commands/score/index.d.ts.map +1 -0
- package/dist/cli/commands/score/index.js +12 -0
- package/dist/cli/commands/score/index.js.map +1 -0
- package/dist/cli/commands/score/score.d.ts +17 -0
- package/dist/cli/commands/score/score.d.ts.map +1 -0
- package/dist/cli/commands/score/score.js +144 -0
- package/dist/cli/commands/score/score.js.map +1 -0
- package/dist/cli/commands/score/types.d.ts +79 -0
- package/dist/cli/commands/score/types.d.ts.map +1 -0
- package/dist/cli/commands/score/types.js +51 -0
- package/dist/cli/commands/score/types.js.map +1 -0
- package/dist/cli/commands/spec-activate.d.ts +29 -0
- package/dist/cli/commands/spec-activate.d.ts.map +1 -0
- package/dist/cli/commands/spec-activate.js +155 -0
- package/dist/cli/commands/spec-activate.js.map +1 -0
- package/dist/cli/commands/spec-activate.types.d.ts +24 -0
- package/dist/cli/commands/spec-activate.types.d.ts.map +1 -0
- package/dist/cli/commands/spec-activate.types.js +8 -0
- package/dist/cli/commands/spec-activate.types.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +89 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/status.types.d.ts +2 -0
- package/dist/cli/commands/status.types.d.ts.map +1 -1
- package/dist/cli/commands/status.types.js.map +1 -1
- package/dist/cli/config/agent-teams.types.d.ts +194 -0
- package/dist/cli/config/agent-teams.types.d.ts.map +1 -0
- package/dist/cli/config/agent-teams.types.js +36 -0
- package/dist/cli/config/agent-teams.types.js.map +1 -0
- package/dist/cli/config/index.d.ts +2 -0
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -0
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/config/loader.d.ts +36 -2
- package/dist/cli/config/loader.d.ts.map +1 -1
- package/dist/cli/config/loader.js +65 -0
- package/dist/cli/config/loader.js.map +1 -1
- package/dist/cli/config/validation.d.ts +69 -0
- package/dist/cli/config/validation.d.ts.map +1 -0
- package/dist/cli/config/validation.js +295 -0
- package/dist/cli/config/validation.js.map +1 -0
- package/dist/cli/config/writer.d.ts +39 -0
- package/dist/cli/config/writer.d.ts.map +1 -1
- package/dist/cli/config/writer.js +58 -0
- package/dist/cli/config/writer.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +10 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +3 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/monorepo-detector.d.ts +31 -0
- package/dist/lib/monorepo-detector.d.ts.map +1 -0
- package/dist/lib/monorepo-detector.js +271 -0
- package/dist/lib/monorepo-detector.js.map +1 -0
- package/dist/lib/prompt-generator.d.ts +65 -0
- package/dist/lib/prompt-generator.d.ts.map +1 -0
- package/dist/lib/prompt-generator.js +174 -0
- package/dist/lib/prompt-generator.js.map +1 -0
- package/dist/lib/strategy-analyzer.d.ts +59 -0
- package/dist/lib/strategy-analyzer.d.ts.map +1 -0
- package/dist/lib/strategy-analyzer.js +137 -0
- package/dist/lib/strategy-analyzer.js.map +1 -0
- package/dist/tools/core/context-helper.d.ts +22 -0
- package/dist/tools/core/context-helper.d.ts.map +1 -1
- package/dist/tools/core/context-helper.js +37 -1
- package/dist/tools/core/context-helper.js.map +1 -1
- package/dist/tools/core/workspace-files.d.ts +49 -0
- package/dist/tools/core/workspace-files.d.ts.map +1 -0
- package/dist/tools/core/workspace-files.js +259 -0
- package/dist/tools/core/workspace-files.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +147 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +3 -2
- package/src/cli/templates/agents/content/core/sfag-implementer.ts +113 -0
- package/src/cli/templates/agents/content/core/sfag-orchestrator.ts +107 -0
- package/src/cli/templates/agents/content/core/sfag-spec-creator.ts +126 -0
- package/src/cli/templates/agents/content/core/sfag-ticket-implementer.ts +132 -0
- package/src/cli/templates/agents/content/research/sfag-package-researcher.ts +153 -0
- package/src/cli/templates/agents/content/task-type/sfag-api-implementer.ts +132 -0
- package/src/cli/templates/agents/content/task-type/sfag-docs-writer.ts +183 -0
- package/src/cli/templates/agents/content/task-type/sfag-frontend-builder.ts +141 -0
- package/src/cli/templates/agents/content/task-type/sfag-infra-architect.ts +149 -0
- package/src/cli/templates/agents/content/task-type/sfag-schema-designer.ts +132 -0
- package/src/cli/templates/agents/content/task-type/sfag-test-writer.ts +171 -0
- package/src/cli/templates/agents/index.ts +74 -0
- package/src/cli/templates/commands.ts +179 -0
- package/src/cli/templates/content/sf-autonomous.ts +78 -0
- package/src/cli/templates/content/sf-blockers.ts +68 -0
- package/src/cli/templates/content/sf-commit.ts +78 -0
- package/src/cli/templates/content/sf-context.ts +64 -0
- package/src/cli/templates/content/sf-create-epics.ts +129 -0
- package/src/cli/templates/content/sf-create-spec.ts +136 -0
- package/src/cli/templates/content/sf-create-tickets.ts +148 -0
- package/src/cli/templates/content/sf-epic.ts +69 -0
- package/src/cli/templates/content/sf-help.ts +61 -0
- package/src/cli/templates/content/sf-import.ts +88 -0
- package/src/cli/templates/content/sf-init.ts +61 -0
- package/src/cli/templates/content/sf-next.ts +67 -0
- package/src/cli/templates/content/sf-reset.ts +78 -0
- package/src/cli/templates/content/sf-review.ts +67 -0
- package/src/cli/templates/content/sf-search.ts +64 -0
- package/src/cli/templates/content/sf-status.ts +67 -0
- package/src/cli/templates/content/sf-ticket.ts +76 -0
- package/src/cli/templates/content/sf-validate.ts +78 -0
- package/src/cli/templates/index.ts +16 -0
- package/src/cli/templates/skills/specforge-conventions.md +109 -0
- package/src/cli/templates/skills/specforge-orchestrator.md +401 -0
- package/src/cli/templates/skills/specforge-validator.md +122 -0
- package/src/cli/templates/skills/specforge-worker.md +378 -0
|
@@ -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,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review Implementation Command
|
|
3
|
+
*
|
|
4
|
+
* CLI command to evaluate the implementation review gate for a specification.
|
|
5
|
+
* Calls the review_implementation API operation and displays the result.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
interface ReviewImplementationOptions {
|
|
9
|
+
json?: boolean;
|
|
10
|
+
fix?: boolean;
|
|
11
|
+
verbose?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function reviewImplementationCommand(specId: string | undefined, options: ReviewImplementationOptions): Promise<void>;
|
|
14
|
+
export declare function registerReviewImplementationCommand(program: Command): void;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=review-implementation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-implementation.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/review-implementation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,UAAU,2BAA2B;IACnC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmMD,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAuDf;AAMD,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyB1E"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review Implementation Command
|
|
3
|
+
*
|
|
4
|
+
* CLI command to evaluate the implementation review gate for a specification.
|
|
5
|
+
* Calls the review_implementation API operation and displays the result.
|
|
6
|
+
*/
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { resolveConfig } from '../config/index.js';
|
|
10
|
+
import { ApiClient } from '../../client/api-client.js';
|
|
11
|
+
import { withErrorHandler, CliError } from '../middleware/error-handler.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Display helpers
|
|
14
|
+
// =============================================================================
|
|
15
|
+
const SEVERITY_ICONS = {
|
|
16
|
+
error: chalk.red('\u2717'),
|
|
17
|
+
warning: chalk.yellow('\u26A0'),
|
|
18
|
+
info: chalk.blue('\u2139'),
|
|
19
|
+
};
|
|
20
|
+
const CATEGORY_LABELS = {
|
|
21
|
+
structural: 'Structural',
|
|
22
|
+
semantic: 'Semantic',
|
|
23
|
+
'cross-entity': 'Cross-Entity',
|
|
24
|
+
};
|
|
25
|
+
function formatImplementationResult(response, showFix, verbose) {
|
|
26
|
+
const lines = [];
|
|
27
|
+
const { result } = response;
|
|
28
|
+
lines.push('');
|
|
29
|
+
if (result.passed) {
|
|
30
|
+
lines.push(chalk.green('\u2713') + chalk.bold(' Implementation review passed'));
|
|
31
|
+
lines.push(chalk.gray('\u2500'.repeat(40)));
|
|
32
|
+
if (response.autoTransitioned) {
|
|
33
|
+
lines.push(chalk.green(` Specification auto-transitioned to: ${response.newStatus}`));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
lines.push(chalk.dim(' Specification eligible for transition: in_progress \u2192 completed'));
|
|
37
|
+
}
|
|
38
|
+
if (response.message) {
|
|
39
|
+
lines.push(chalk.dim(` ${response.message}`));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
lines.push(chalk.red('\u2717') + chalk.bold(' Implementation review failed'));
|
|
44
|
+
lines.push(chalk.gray('\u2500'.repeat(40)));
|
|
45
|
+
if (response.message) {
|
|
46
|
+
lines.push(chalk.dim(` ${response.message}`));
|
|
47
|
+
}
|
|
48
|
+
// Group findings by category
|
|
49
|
+
const grouped = groupByCategory(result.findings);
|
|
50
|
+
for (const [category, findings] of Object.entries(grouped)) {
|
|
51
|
+
lines.push('');
|
|
52
|
+
lines.push(chalk.bold(` ${CATEGORY_LABELS[category] || category} Findings`));
|
|
53
|
+
lines.push(chalk.gray(' ' + '\u2500'.repeat(36)));
|
|
54
|
+
for (const finding of findings) {
|
|
55
|
+
const icon = SEVERITY_ICONS[finding.severity] || chalk.dim('\u2022');
|
|
56
|
+
lines.push(` ${icon} ${finding.message}`);
|
|
57
|
+
if (showFix && finding.suggestion) {
|
|
58
|
+
lines.push(chalk.dim(` Fix: ${finding.suggestion}`));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Show suggestions
|
|
63
|
+
if (result.suggestions.length > 0) {
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push(chalk.bold(' Suggestions'));
|
|
66
|
+
lines.push(chalk.gray(' ' + '\u2500'.repeat(36)));
|
|
67
|
+
for (const suggestion of result.suggestions) {
|
|
68
|
+
lines.push(chalk.dim(` \u2022 ${suggestion}`));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Verbose: per-ticket breakdown
|
|
73
|
+
if (verbose) {
|
|
74
|
+
lines.push('');
|
|
75
|
+
lines.push(formatVerboseBreakdown(result));
|
|
76
|
+
}
|
|
77
|
+
// Show summary counts
|
|
78
|
+
const errorCount = result.findings.filter(f => f.severity === 'error').length;
|
|
79
|
+
const warningCount = result.findings.filter(f => f.severity === 'warning').length;
|
|
80
|
+
const infoCount = result.findings.filter(f => f.severity === 'info').length;
|
|
81
|
+
if (result.findings.length > 0) {
|
|
82
|
+
lines.push('');
|
|
83
|
+
const parts = [];
|
|
84
|
+
if (errorCount > 0)
|
|
85
|
+
parts.push(chalk.red(`${errorCount} error(s)`));
|
|
86
|
+
if (warningCount > 0)
|
|
87
|
+
parts.push(chalk.yellow(`${warningCount} warning(s)`));
|
|
88
|
+
if (infoCount > 0)
|
|
89
|
+
parts.push(chalk.blue(`${infoCount} info`));
|
|
90
|
+
lines.push(` ${parts.join(', ')}`);
|
|
91
|
+
}
|
|
92
|
+
lines.push('');
|
|
93
|
+
return lines.join('\n');
|
|
94
|
+
}
|
|
95
|
+
function formatVerboseBreakdown(result) {
|
|
96
|
+
const lines = [];
|
|
97
|
+
lines.push(chalk.bold(' Per-Ticket Breakdown'));
|
|
98
|
+
lines.push(chalk.gray(' ' + '\u2500'.repeat(36)));
|
|
99
|
+
// Extract ticket-scoped findings
|
|
100
|
+
const ticketFindings = new Map();
|
|
101
|
+
for (const finding of result.findings) {
|
|
102
|
+
const match = finding.field.match(/^ticket:([^:]+):/);
|
|
103
|
+
if (match) {
|
|
104
|
+
const ticketId = match[1];
|
|
105
|
+
if (!ticketFindings.has(ticketId)) {
|
|
106
|
+
ticketFindings.set(ticketId, []);
|
|
107
|
+
}
|
|
108
|
+
ticketFindings.get(ticketId).push(finding);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (ticketFindings.size === 0) {
|
|
112
|
+
lines.push(chalk.dim(' No per-ticket findings'));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
for (const [ticketId, findings] of ticketFindings) {
|
|
116
|
+
lines.push(` ${chalk.bold(ticketId)}`);
|
|
117
|
+
for (const finding of findings) {
|
|
118
|
+
const icon = SEVERITY_ICONS[finding.severity] || chalk.dim('\u2022');
|
|
119
|
+
lines.push(` ${icon} ${finding.message}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Show aggregate stats from findings
|
|
124
|
+
const ticketCompletion = result.findings.find(f => f.field === 'ticketCompletion');
|
|
125
|
+
const timeTracking = result.findings.find(f => f.field === 'timeTracking');
|
|
126
|
+
if (ticketCompletion || timeTracking) {
|
|
127
|
+
lines.push('');
|
|
128
|
+
lines.push(chalk.bold(' Aggregate Stats'));
|
|
129
|
+
lines.push(chalk.gray(' ' + '\u2500'.repeat(36)));
|
|
130
|
+
if (ticketCompletion) {
|
|
131
|
+
lines.push(` ${SEVERITY_ICONS[ticketCompletion.severity]} ${ticketCompletion.message}`);
|
|
132
|
+
}
|
|
133
|
+
if (timeTracking) {
|
|
134
|
+
lines.push(` ${SEVERITY_ICONS[timeTracking.severity]} ${timeTracking.message}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return lines.join('\n');
|
|
138
|
+
}
|
|
139
|
+
function groupByCategory(findings) {
|
|
140
|
+
const grouped = {};
|
|
141
|
+
for (const finding of findings) {
|
|
142
|
+
const cat = finding.category;
|
|
143
|
+
if (!grouped[cat]) {
|
|
144
|
+
grouped[cat] = [];
|
|
145
|
+
}
|
|
146
|
+
grouped[cat].push(finding);
|
|
147
|
+
}
|
|
148
|
+
return grouped;
|
|
149
|
+
}
|
|
150
|
+
// =============================================================================
|
|
151
|
+
// Command handler
|
|
152
|
+
// =============================================================================
|
|
153
|
+
export async function reviewImplementationCommand(specId, options) {
|
|
154
|
+
const config = resolveConfig();
|
|
155
|
+
if (!config.apiKey) {
|
|
156
|
+
throw new CliError('Not authenticated', 1, 'Run `specforge login` to authenticate first');
|
|
157
|
+
}
|
|
158
|
+
// Resolve spec ID from arg or config
|
|
159
|
+
const specificationId = specId || config.specificationId;
|
|
160
|
+
if (!specificationId) {
|
|
161
|
+
console.error(chalk.red('\nError: No specification specified and no active specification.'));
|
|
162
|
+
console.error('Usage: specforge review-implementation [specId]');
|
|
163
|
+
console.error(chalk.dim("Run 'specforge init' or 'specforge switch' to set an active specification."));
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
const spinner = options.json ? null : ora('Running implementation review gate...').start();
|
|
167
|
+
try {
|
|
168
|
+
const client = new ApiClient({
|
|
169
|
+
apiKey: config.apiKey,
|
|
170
|
+
apiUrl: config.apiUrl,
|
|
171
|
+
debug: config.debug,
|
|
172
|
+
});
|
|
173
|
+
const response = await client.call('review_implementation', {
|
|
174
|
+
specificationId,
|
|
175
|
+
});
|
|
176
|
+
spinner?.stop();
|
|
177
|
+
if (options.json) {
|
|
178
|
+
console.log(JSON.stringify(response, null, 2));
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.log(formatImplementationResult(response, !!options.fix, !!options.verbose));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
spinner?.fail('Implementation review failed');
|
|
186
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
187
|
+
console.error(chalk.red(`\nError: ${message}`));
|
|
188
|
+
if (!options.json) {
|
|
189
|
+
console.error(chalk.dim('\nPossible causes:'));
|
|
190
|
+
console.error(chalk.dim(' - Invalid specification ID'));
|
|
191
|
+
console.error(chalk.dim(' - Network connectivity issues'));
|
|
192
|
+
console.error(chalk.dim(' - Authentication expired (try: specforge login)'));
|
|
193
|
+
}
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// =============================================================================
|
|
198
|
+
// Command registration
|
|
199
|
+
// =============================================================================
|
|
200
|
+
export function registerReviewImplementationCommand(program) {
|
|
201
|
+
program
|
|
202
|
+
.command('review-implementation [specId]')
|
|
203
|
+
.description('Run implementation review gate on a specification')
|
|
204
|
+
.addHelpText('after', `
|
|
205
|
+
Arguments:
|
|
206
|
+
specId Specification ID (defaults to active specification)
|
|
207
|
+
|
|
208
|
+
Examples:
|
|
209
|
+
$ specforge review-implementation # Review active specification
|
|
210
|
+
$ specforge review-implementation spec_abc123 # Review specific specification
|
|
211
|
+
$ specforge review-implementation --json # JSON output
|
|
212
|
+
$ specforge review-implementation --fix # Show remediation suggestions
|
|
213
|
+
$ specforge review-implementation --verbose # Per-ticket breakdown
|
|
214
|
+
|
|
215
|
+
Implementation Gate Checks:
|
|
216
|
+
Ticket Completion All tickets should be done
|
|
217
|
+
File Coverage Planned vs actual files delivered
|
|
218
|
+
Test Coverage Test tickets have reported results
|
|
219
|
+
Time Tracking Estimated vs actual hours comparison
|
|
220
|
+
`)
|
|
221
|
+
.option('--json', 'Output as JSON')
|
|
222
|
+
.option('--fix', 'Show auto-remediation suggestions')
|
|
223
|
+
.option('--verbose', 'Show per-ticket implementation breakdown')
|
|
224
|
+
.action(withErrorHandler(reviewImplementationCommand));
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=review-implementation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-implementation.js","sourceRoot":"","sources":["../../../src/cli/commands/review-implementation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review Planning Command
|
|
3
|
+
*
|
|
4
|
+
* CLI command to evaluate the planning review gate for a specification.
|
|
5
|
+
* Calls the review_planning API operation and displays the result.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
interface ReviewPlanningOptions {
|
|
9
|
+
json?: boolean;
|
|
10
|
+
fix?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function reviewPlanningCommand(specId: string | undefined, options: ReviewPlanningOptions): Promise<void>;
|
|
13
|
+
export declare function registerReviewPlanningCommand(program: Command): void;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=review-planning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-planning.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/review-planning.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,UAAU,qBAAqB;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAqID,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAuDf;AAMD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyBpE"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review Planning Command
|
|
3
|
+
*
|
|
4
|
+
* CLI command to evaluate the planning review gate for a specification.
|
|
5
|
+
* Calls the review_planning API operation and displays the result.
|
|
6
|
+
*/
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { resolveConfig } from '../config/index.js';
|
|
10
|
+
import { ApiClient } from '../../client/api-client.js';
|
|
11
|
+
import { withErrorHandler, CliError } from '../middleware/error-handler.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Display helpers
|
|
14
|
+
// =============================================================================
|
|
15
|
+
const SEVERITY_ICONS = {
|
|
16
|
+
error: chalk.red('\u2717'),
|
|
17
|
+
warning: chalk.yellow('\u26A0'),
|
|
18
|
+
info: chalk.blue('\u2139'),
|
|
19
|
+
};
|
|
20
|
+
const CATEGORY_LABELS = {
|
|
21
|
+
structural: 'Structural',
|
|
22
|
+
semantic: 'Semantic',
|
|
23
|
+
'cross-entity': 'Cross-Entity',
|
|
24
|
+
};
|
|
25
|
+
function formatPlanningResult(response, showFix) {
|
|
26
|
+
const lines = [];
|
|
27
|
+
const { result } = response;
|
|
28
|
+
lines.push('');
|
|
29
|
+
if (result.passed) {
|
|
30
|
+
lines.push(chalk.green('\u2713') + chalk.bold(' Planning review passed'));
|
|
31
|
+
lines.push(chalk.gray('\u2500'.repeat(40)));
|
|
32
|
+
if (response.autoTransitioned) {
|
|
33
|
+
lines.push(chalk.green(` Specification auto-transitioned to: ${response.newStatus}`));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
lines.push(chalk.dim(' Specification eligible for transition: planning \u2192 ready'));
|
|
37
|
+
}
|
|
38
|
+
if (response.message) {
|
|
39
|
+
lines.push(chalk.dim(` ${response.message}`));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
lines.push(chalk.red('\u2717') + chalk.bold(' Planning review failed'));
|
|
44
|
+
lines.push(chalk.gray('\u2500'.repeat(40)));
|
|
45
|
+
if (response.message) {
|
|
46
|
+
lines.push(chalk.dim(` ${response.message}`));
|
|
47
|
+
}
|
|
48
|
+
// Group findings by category
|
|
49
|
+
const grouped = groupByCategory(result.findings);
|
|
50
|
+
for (const [category, findings] of Object.entries(grouped)) {
|
|
51
|
+
lines.push('');
|
|
52
|
+
lines.push(chalk.bold(` ${CATEGORY_LABELS[category] || category} Findings`));
|
|
53
|
+
lines.push(chalk.gray(' ' + '\u2500'.repeat(36)));
|
|
54
|
+
for (const finding of findings) {
|
|
55
|
+
const icon = SEVERITY_ICONS[finding.severity] || chalk.dim('\u2022');
|
|
56
|
+
lines.push(` ${icon} ${finding.message}`);
|
|
57
|
+
if (showFix && finding.suggestion) {
|
|
58
|
+
lines.push(chalk.dim(` Fix: ${finding.suggestion}`));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Show suggestions
|
|
63
|
+
if (result.suggestions.length > 0) {
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push(chalk.bold(' Suggestions'));
|
|
66
|
+
lines.push(chalk.gray(' ' + '\u2500'.repeat(36)));
|
|
67
|
+
for (const suggestion of result.suggestions) {
|
|
68
|
+
lines.push(chalk.dim(` \u2022 ${suggestion}`));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Show summary counts
|
|
73
|
+
const errorCount = result.findings.filter(f => f.severity === 'error').length;
|
|
74
|
+
const warningCount = result.findings.filter(f => f.severity === 'warning').length;
|
|
75
|
+
const infoCount = result.findings.filter(f => f.severity === 'info').length;
|
|
76
|
+
if (result.findings.length > 0) {
|
|
77
|
+
lines.push('');
|
|
78
|
+
const parts = [];
|
|
79
|
+
if (errorCount > 0)
|
|
80
|
+
parts.push(chalk.red(`${errorCount} error(s)`));
|
|
81
|
+
if (warningCount > 0)
|
|
82
|
+
parts.push(chalk.yellow(`${warningCount} warning(s)`));
|
|
83
|
+
if (infoCount > 0)
|
|
84
|
+
parts.push(chalk.blue(`${infoCount} info`));
|
|
85
|
+
lines.push(` ${parts.join(', ')}`);
|
|
86
|
+
}
|
|
87
|
+
lines.push('');
|
|
88
|
+
return lines.join('\n');
|
|
89
|
+
}
|
|
90
|
+
function groupByCategory(findings) {
|
|
91
|
+
const grouped = {};
|
|
92
|
+
for (const finding of findings) {
|
|
93
|
+
const cat = finding.category;
|
|
94
|
+
if (!grouped[cat]) {
|
|
95
|
+
grouped[cat] = [];
|
|
96
|
+
}
|
|
97
|
+
grouped[cat].push(finding);
|
|
98
|
+
}
|
|
99
|
+
return grouped;
|
|
100
|
+
}
|
|
101
|
+
// =============================================================================
|
|
102
|
+
// Command handler
|
|
103
|
+
// =============================================================================
|
|
104
|
+
export async function reviewPlanningCommand(specId, options) {
|
|
105
|
+
const config = resolveConfig();
|
|
106
|
+
if (!config.apiKey) {
|
|
107
|
+
throw new CliError('Not authenticated', 1, 'Run `specforge login` to authenticate first');
|
|
108
|
+
}
|
|
109
|
+
// Resolve spec ID from arg or config
|
|
110
|
+
const specificationId = specId || config.specificationId;
|
|
111
|
+
if (!specificationId) {
|
|
112
|
+
console.error(chalk.red('\nError: No specification specified and no active specification.'));
|
|
113
|
+
console.error('Usage: specforge review-planning [specId]');
|
|
114
|
+
console.error(chalk.dim("Run 'specforge init' or 'specforge switch' to set an active specification."));
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
const spinner = options.json ? null : ora('Running planning review gate...').start();
|
|
118
|
+
try {
|
|
119
|
+
const client = new ApiClient({
|
|
120
|
+
apiKey: config.apiKey,
|
|
121
|
+
apiUrl: config.apiUrl,
|
|
122
|
+
debug: config.debug,
|
|
123
|
+
});
|
|
124
|
+
const response = await client.call('review_planning', {
|
|
125
|
+
specificationId,
|
|
126
|
+
});
|
|
127
|
+
spinner?.stop();
|
|
128
|
+
if (options.json) {
|
|
129
|
+
console.log(JSON.stringify(response, null, 2));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
console.log(formatPlanningResult(response, !!options.fix));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
spinner?.fail('Planning review failed');
|
|
137
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
138
|
+
console.error(chalk.red(`\nError: ${message}`));
|
|
139
|
+
if (!options.json) {
|
|
140
|
+
console.error(chalk.dim('\nPossible causes:'));
|
|
141
|
+
console.error(chalk.dim(' - Invalid specification ID'));
|
|
142
|
+
console.error(chalk.dim(' - Network connectivity issues'));
|
|
143
|
+
console.error(chalk.dim(' - Authentication expired (try: specforge login)'));
|
|
144
|
+
}
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// =============================================================================
|
|
149
|
+
// Command registration
|
|
150
|
+
// =============================================================================
|
|
151
|
+
export function registerReviewPlanningCommand(program) {
|
|
152
|
+
program
|
|
153
|
+
.command('review-planning [specId]')
|
|
154
|
+
.description('Run planning review gate on a specification')
|
|
155
|
+
.addHelpText('after', `
|
|
156
|
+
Arguments:
|
|
157
|
+
specId Specification ID (defaults to active specification)
|
|
158
|
+
|
|
159
|
+
Examples:
|
|
160
|
+
$ specforge review-planning # Review active specification
|
|
161
|
+
$ specforge review-planning spec_abc123 # Review specific specification
|
|
162
|
+
$ specforge review-planning --json # JSON output
|
|
163
|
+
$ specforge review-planning --fix # Show remediation suggestions
|
|
164
|
+
|
|
165
|
+
Planning Gate Checks:
|
|
166
|
+
Goals At least one goal defined
|
|
167
|
+
Requirements At least one requirement defined
|
|
168
|
+
Architecture Architecture section populated
|
|
169
|
+
Tech Stack At least one technology listed
|
|
170
|
+
Epics At least one epic exists
|
|
171
|
+
Tickets At least one epic has tickets
|
|
172
|
+
`)
|
|
173
|
+
.option('--json', 'Output as JSON')
|
|
174
|
+
.option('--fix', 'Show auto-remediation suggestions')
|
|
175
|
+
.action(withErrorHandler(reviewPlanningCommand));
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=review-planning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-planning.js","sourceRoot":"","sources":["../../../src/cli/commands/review-planning.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score Display Utilities
|
|
3
|
+
*
|
|
4
|
+
* Formats and displays readiness scores in the terminal
|
|
5
|
+
* with colored output based on readiness level.
|
|
6
|
+
*/
|
|
7
|
+
import type { ScoreResult, ReadinessReportResponse } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Format a readiness score with color based on level
|
|
10
|
+
*/
|
|
11
|
+
export declare function formatScore(score: number | null, level: string | null): string;
|
|
12
|
+
/**
|
|
13
|
+
* Format a single entity's score for display
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatScoreResult(result: ScoreResult): string;
|
|
16
|
+
/**
|
|
17
|
+
* Format the full readiness report for display
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatScoreReport(report: ReadinessReportResponse): string;
|
|
20
|
+
//# sourceMappingURL=display.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/score/display.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAYvE;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAI9E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAW7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,MAAM,CAwCzE"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score Display Utilities
|
|
3
|
+
*
|
|
4
|
+
* Formats and displays readiness scores in the terminal
|
|
5
|
+
* with colored output based on readiness level.
|
|
6
|
+
*/
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
/**
|
|
9
|
+
* Color mapping for readiness levels
|
|
10
|
+
*/
|
|
11
|
+
const LEVEL_COLORS = {
|
|
12
|
+
exemplary: chalk.green,
|
|
13
|
+
complete: chalk.blue,
|
|
14
|
+
partial: chalk.yellow,
|
|
15
|
+
minimal: chalk.red,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Format a readiness score with color based on level
|
|
19
|
+
*/
|
|
20
|
+
export function formatScore(score, level) {
|
|
21
|
+
if (score === null || level === null)
|
|
22
|
+
return chalk.gray('unscored');
|
|
23
|
+
const colorFn = LEVEL_COLORS[level] || chalk.white;
|
|
24
|
+
return colorFn(`${score}/100 (${level})`);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Format a single entity's score for display
|
|
28
|
+
*/
|
|
29
|
+
export function formatScoreResult(result) {
|
|
30
|
+
const lines = [];
|
|
31
|
+
lines.push('');
|
|
32
|
+
lines.push(chalk.bold(`${capitalize(result.type)}: ${result.title}`));
|
|
33
|
+
lines.push(chalk.gray('─'.repeat(40)));
|
|
34
|
+
lines.push(` ID: ${chalk.dim(result.id)}`);
|
|
35
|
+
lines.push(` Score: ${formatScore(result.readinessScore, result.readinessLevel)}`);
|
|
36
|
+
lines.push('');
|
|
37
|
+
return lines.join('\n');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format the full readiness report for display
|
|
41
|
+
*/
|
|
42
|
+
export function formatScoreReport(report) {
|
|
43
|
+
const lines = [];
|
|
44
|
+
lines.push('');
|
|
45
|
+
lines.push(chalk.bold('Readiness Report'));
|
|
46
|
+
lines.push(chalk.gray('═'.repeat(50)));
|
|
47
|
+
// Format the report sections generically since the shape may vary
|
|
48
|
+
for (const [key, value] of Object.entries(report)) {
|
|
49
|
+
if (key === 'type' || key === 'scope' || key === 'scopeId' || key === 'format')
|
|
50
|
+
continue;
|
|
51
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
52
|
+
lines.push('');
|
|
53
|
+
lines.push(chalk.bold(` ${formatKey(key)}`));
|
|
54
|
+
lines.push(chalk.gray(' ' + '─'.repeat(36)));
|
|
55
|
+
for (const [subKey, subValue] of Object.entries(value)) {
|
|
56
|
+
lines.push(` ${formatKey(subKey)}: ${formatValue(subValue)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (Array.isArray(value)) {
|
|
60
|
+
lines.push('');
|
|
61
|
+
lines.push(chalk.bold(` ${formatKey(key)}`));
|
|
62
|
+
lines.push(chalk.gray(' ' + '─'.repeat(36)));
|
|
63
|
+
for (const item of value) {
|
|
64
|
+
if (typeof item === 'object' && item !== null) {
|
|
65
|
+
const obj = item;
|
|
66
|
+
const title = obj.title || obj.name || obj.id || '';
|
|
67
|
+
const score = typeof obj.readinessScore === 'number' ? obj.readinessScore : null;
|
|
68
|
+
const level = typeof obj.readinessLevel === 'string' ? obj.readinessLevel : null;
|
|
69
|
+
lines.push(` ${title}: ${formatScore(score, level)}`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
lines.push(` ${chalk.dim('•')} ${String(item)}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
lines.push(` ${formatKey(key)}: ${formatValue(value)}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
lines.push('');
|
|
81
|
+
return lines.join('\n');
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Format a camelCase or snake_case key for display
|
|
85
|
+
*/
|
|
86
|
+
function formatKey(key) {
|
|
87
|
+
return key
|
|
88
|
+
.replace(/([A-Z])/g, ' $1')
|
|
89
|
+
.replace(/_/g, ' ')
|
|
90
|
+
.replace(/^\s/, '')
|
|
91
|
+
.replace(/\b\w/g, c => c.toUpperCase());
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Format a value for display
|
|
95
|
+
*/
|
|
96
|
+
function formatValue(value) {
|
|
97
|
+
if (value === null || value === undefined)
|
|
98
|
+
return chalk.gray('N/A');
|
|
99
|
+
if (typeof value === 'number')
|
|
100
|
+
return chalk.cyan(String(value));
|
|
101
|
+
if (typeof value === 'boolean')
|
|
102
|
+
return value ? chalk.green('Yes') : chalk.red('No');
|
|
103
|
+
return String(value);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Capitalize first letter
|
|
107
|
+
*/
|
|
108
|
+
function capitalize(str) {
|
|
109
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=display.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../../../../src/cli/commands/score/display.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score Command Module
|
|
3
|
+
*
|
|
4
|
+
* Exports all score-related functionality.
|
|
5
|
+
*/
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export { formatScore, formatScoreResult, formatScoreReport } from './display.js';
|
|
8
|
+
export { scoreCommand, registerScoreCommand } from './score.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/score/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score Command Module
|
|
3
|
+
*
|
|
4
|
+
* Exports all score-related functionality.
|
|
5
|
+
*/
|
|
6
|
+
// Types
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
// Display utilities
|
|
9
|
+
export { formatScore, formatScoreResult, formatScoreReport } from './display.js';
|
|
10
|
+
// Command registration
|
|
11
|
+
export { scoreCommand, registerScoreCommand } from './score.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/commands/score/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,oBAAoB;AACpB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjF,uBAAuB;AACvB,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
|