musubi-sdd 6.2.2 → 6.3.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.
- package/README.ja.md +3 -3
- package/README.md +3 -3
- package/bin/musubi-dashboard.js +22 -13
- package/bin/musubi-design.js +3 -3
- package/bin/musubi-gaps.js +9 -9
- package/bin/musubi-init.js +14 -1310
- package/bin/musubi-requirements.js +1 -1
- package/bin/musubi-tasks.js +5 -5
- package/bin/musubi-trace.js +23 -23
- package/bin/musubi-upgrade.js +7 -2
- package/bin/musubi.js +1 -1
- package/package.json +2 -2
- package/src/analyzers/gap-detector.js +3 -3
- package/src/analyzers/traceability.js +17 -17
- package/src/cli/dashboard-cli.js +54 -60
- package/src/cli/init-generators.js +464 -0
- package/src/cli/init-helpers.js +884 -0
- package/src/constitutional/checker.js +67 -65
- package/src/constitutional/ci-reporter.js +50 -43
- package/src/constitutional/index.js +2 -2
- package/src/constitutional/phase-minus-one.js +22 -25
- package/src/constitutional/steering-sync.js +28 -39
- package/src/dashboard/index.js +2 -2
- package/src/dashboard/sprint-planner.js +17 -19
- package/src/dashboard/sprint-reporter.js +46 -37
- package/src/dashboard/transition-recorder.js +12 -18
- package/src/dashboard/workflow-dashboard.js +27 -38
- package/src/enterprise/error-recovery.js +109 -49
- package/src/enterprise/experiment-report.js +62 -36
- package/src/enterprise/index.js +5 -5
- package/src/enterprise/rollback-manager.js +28 -29
- package/src/enterprise/tech-article.js +41 -35
- package/src/generators/design.js +3 -3
- package/src/generators/requirements.js +5 -3
- package/src/generators/tasks.js +2 -2
- package/src/integrations/platforms.js +1 -1
- package/src/templates/agents/claude-code/CLAUDE.md +1 -1
- package/src/templates/agents/claude-code/skills/design-reviewer/SKILL.md +132 -113
- package/src/templates/agents/claude-code/skills/requirements-reviewer/SKILL.md +85 -56
- package/src/templates/agents/codex/AGENTS.md +2 -2
- package/src/templates/agents/cursor/AGENTS.md +2 -2
- package/src/templates/agents/gemini-cli/GEMINI.md +2 -2
- package/src/templates/agents/github-copilot/AGENTS.md +2 -2
- package/src/templates/agents/github-copilot/commands/sdd-requirements.prompt.md +23 -4
- package/src/templates/agents/qwen-code/QWEN.md +2 -2
- package/src/templates/agents/shared/AGENTS.md +1 -1
- package/src/templates/agents/windsurf/AGENTS.md +2 -2
- package/src/templates/skills/browser-agent.md +1 -1
- package/src/traceability/extractor.js +21 -20
- package/src/traceability/gap-detector.js +19 -17
- package/src/traceability/index.js +2 -2
- package/src/traceability/matrix-storage.js +20 -22
- package/src/validators/constitution.js +5 -2
- package/src/validators/critic-system.js +6 -6
- package/src/validators/traceability-validator.js +3 -3
|
@@ -30,7 +30,7 @@ program
|
|
|
30
30
|
program
|
|
31
31
|
.command('init <feature>')
|
|
32
32
|
.description('Initialize requirements document for a feature')
|
|
33
|
-
.option('-o, --output <path>', 'Output directory', '
|
|
33
|
+
.option('-o, --output <path>', 'Output directory', 'storage/specs')
|
|
34
34
|
.option('-a, --author <name>', 'Author name')
|
|
35
35
|
.option('--project <name>', 'Project name')
|
|
36
36
|
.option('--dry-run', 'Show what would be created without writing files')
|
package/bin/musubi-tasks.js
CHANGED
|
@@ -42,11 +42,11 @@ program
|
|
|
42
42
|
program
|
|
43
43
|
.command('init <feature>')
|
|
44
44
|
.description('Initialize task breakdown document from design')
|
|
45
|
-
.option('-o, --output <path>', 'Output directory', '
|
|
45
|
+
.option('-o, --output <path>', 'Output directory', 'storage/tasks')
|
|
46
46
|
.option('-a, --author <name>', 'Author name')
|
|
47
47
|
.option('--project <name>', 'Project name')
|
|
48
|
-
.option('-d, --design <path>', 'Design document
|
|
49
|
-
.option('-r, --requirements <path>', 'Requirements document
|
|
48
|
+
.option('-d, --design <path>', 'Design document directory', 'storage/design')
|
|
49
|
+
.option('-r, --requirements <path>', 'Requirements document directory', 'storage/specs')
|
|
50
50
|
.option('--dry-run', 'Show what would be created without writing files')
|
|
51
51
|
.option('--verbose', 'Show detailed output')
|
|
52
52
|
.option('--json', 'Output result as JSON')
|
|
@@ -61,8 +61,8 @@ program
|
|
|
61
61
|
console.log(chalk.dim(` Output: ${options.output}`));
|
|
62
62
|
console.log(chalk.dim(` Author: ${options.author || 'Not specified'}`));
|
|
63
63
|
console.log(chalk.dim(` Project: ${options.project || 'Not specified'}`));
|
|
64
|
-
console.log(chalk.dim(` Design: ${options.design
|
|
65
|
-
console.log(chalk.dim(` Requirements: ${options.requirements
|
|
64
|
+
console.log(chalk.dim(` Design: ${options.design}`));
|
|
65
|
+
console.log(chalk.dim(` Requirements: ${options.requirements}`));
|
|
66
66
|
console.log(chalk.dim(` Dry run: ${options.dryRun || false}`));
|
|
67
67
|
console.log();
|
|
68
68
|
}
|
package/bin/musubi-trace.js
CHANGED
|
@@ -31,9 +31,9 @@ program
|
|
|
31
31
|
.description('Generate full traceability matrix')
|
|
32
32
|
.option('-f, --format <type>', 'Output format (table|markdown|json|html)', 'table')
|
|
33
33
|
.option('-o, --output <path>', 'Output file path')
|
|
34
|
-
.option('--requirements <path>', 'Requirements directory', '
|
|
35
|
-
.option('--design <path>', 'Design directory', '
|
|
36
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
34
|
+
.option('--requirements <path>', 'Requirements directory', 'storage/specs')
|
|
35
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
36
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
37
37
|
.option('--code <path>', 'Source code directory', 'src')
|
|
38
38
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
39
39
|
.action(async options => {
|
|
@@ -79,9 +79,9 @@ program
|
|
|
79
79
|
program
|
|
80
80
|
.command('coverage')
|
|
81
81
|
.description('Calculate requirement coverage statistics')
|
|
82
|
-
.option('--requirements <path>', 'Requirements directory', '
|
|
83
|
-
.option('--design <path>', 'Design directory', '
|
|
84
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
82
|
+
.option('--requirements <path>', 'Requirements directory', 'storage/specs')
|
|
83
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
84
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
85
85
|
.option('--code <path>', 'Source code directory', 'src')
|
|
86
86
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
87
87
|
.option('--min-coverage <percent>', 'Minimum required coverage', '100')
|
|
@@ -148,9 +148,9 @@ program
|
|
|
148
148
|
program
|
|
149
149
|
.command('gaps')
|
|
150
150
|
.description('Detect orphaned requirements, design, tasks, and untested code')
|
|
151
|
-
.option('--requirements <path>', 'Requirements directory', '
|
|
152
|
-
.option('--design <path>', 'Design directory', '
|
|
153
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
151
|
+
.option('--requirements <path>', 'Requirements directory', 'storage/specs')
|
|
152
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
153
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
154
154
|
.option('--code <path>', 'Source code directory', 'src')
|
|
155
155
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
156
156
|
.option('-v, --verbose', 'Show detailed gap information')
|
|
@@ -243,9 +243,9 @@ program
|
|
|
243
243
|
program
|
|
244
244
|
.command('requirement <id>')
|
|
245
245
|
.description('Trace specific requirement through design, tasks, code, and tests')
|
|
246
|
-
.option('--requirements <path>', 'Requirements directory', '
|
|
247
|
-
.option('--design <path>', 'Design directory', '
|
|
248
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
246
|
+
.option('--requirements <path>', 'Requirements directory', 'storage/specs')
|
|
247
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
248
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
249
249
|
.option('--code <path>', 'Source code directory', 'src')
|
|
250
250
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
251
251
|
.action(async (id, options) => {
|
|
@@ -339,9 +339,9 @@ program
|
|
|
339
339
|
program
|
|
340
340
|
.command('validate')
|
|
341
341
|
.description('Validate 100% traceability coverage (Constitutional Article V)')
|
|
342
|
-
.option('--requirements <path>', 'Requirements directory', '
|
|
343
|
-
.option('--design <path>', 'Design directory', '
|
|
344
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
342
|
+
.option('--requirements <path>', 'Requirements directory', 'storage/specs')
|
|
343
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
344
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
345
345
|
.option('--code <path>', 'Source code directory', 'src')
|
|
346
346
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
347
347
|
.option('--strict', 'Fail on any gaps (default: true)', true)
|
|
@@ -395,9 +395,9 @@ program
|
|
|
395
395
|
program
|
|
396
396
|
.command('bidirectional')
|
|
397
397
|
.description('Analyze bidirectional traceability (forward and backward)')
|
|
398
|
-
.option('--requirements <path>', 'Requirements directory', '
|
|
399
|
-
.option('--design <path>', 'Design directory', '
|
|
400
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
398
|
+
.option('--requirements <path>', 'Requirements directory', 'storage/specs')
|
|
399
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
400
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
401
401
|
.option('--code <path>', 'Source code directory', 'src')
|
|
402
402
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
403
403
|
.option('-f, --format <type>', 'Output format (table|json)', 'table')
|
|
@@ -465,8 +465,8 @@ program
|
|
|
465
465
|
program
|
|
466
466
|
.command('impact <requirementId>')
|
|
467
467
|
.description('Analyze impact of requirement changes')
|
|
468
|
-
.option('--design <path>', 'Design directory', '
|
|
469
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
468
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
469
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
470
470
|
.option('--code <path>', 'Source code directory', 'src')
|
|
471
471
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
472
472
|
.option('-f, --format <type>', 'Output format (table|json)', 'table')
|
|
@@ -528,9 +528,9 @@ program
|
|
|
528
528
|
program
|
|
529
529
|
.command('statistics')
|
|
530
530
|
.description('Generate comprehensive traceability statistics')
|
|
531
|
-
.option('--requirements <path>', 'Requirements directory', '
|
|
532
|
-
.option('--design <path>', 'Design directory', '
|
|
533
|
-
.option('--tasks <path>', 'Tasks directory', '
|
|
531
|
+
.option('--requirements <path>', 'Requirements directory', 'storage/specs')
|
|
532
|
+
.option('--design <path>', 'Design directory', 'storage/design')
|
|
533
|
+
.option('--tasks <path>', 'Tasks directory', 'storage/tasks')
|
|
534
534
|
.option('--code <path>', 'Source code directory', 'src')
|
|
535
535
|
.option('--tests <path>', 'Tests directory', 'tests')
|
|
536
536
|
.option('-f, --format <type>', 'Output format (table|json)', 'table')
|
package/bin/musubi-upgrade.js
CHANGED
|
@@ -88,7 +88,10 @@ async function migrateToV620(projectDir, _options) {
|
|
|
88
88
|
const nextSectionIndex = content.indexOf('###', promptsIndex + 10);
|
|
89
89
|
if (nextSectionIndex !== -1) {
|
|
90
90
|
content =
|
|
91
|
-
content.slice(0, nextSectionIndex) +
|
|
91
|
+
content.slice(0, nextSectionIndex) +
|
|
92
|
+
reviewPrompts +
|
|
93
|
+
'\n' +
|
|
94
|
+
content.slice(nextSectionIndex);
|
|
92
95
|
} else {
|
|
93
96
|
content += '\n' + reviewPrompts;
|
|
94
97
|
}
|
|
@@ -380,7 +383,9 @@ program
|
|
|
380
383
|
|
|
381
384
|
const comparison = compareVersions(currentVersion, packageJson.version);
|
|
382
385
|
if (comparison < 0) {
|
|
383
|
-
console.log(
|
|
386
|
+
console.log(
|
|
387
|
+
chalk.yellow(`\n⚠️ Upgrade available: ${currentVersion} → ${packageJson.version}`)
|
|
388
|
+
);
|
|
384
389
|
console.log(chalk.gray('\nRun: npx musubi-sdd upgrade\n'));
|
|
385
390
|
} else {
|
|
386
391
|
console.log(chalk.green('\n✅ Project is up to date.\n'));
|
package/bin/musubi.js
CHANGED
|
@@ -437,7 +437,7 @@ program
|
|
|
437
437
|
console.log('');
|
|
438
438
|
|
|
439
439
|
console.log(chalk.white('Documentation:'));
|
|
440
|
-
console.log(chalk.gray(' https://github.com/
|
|
440
|
+
console.log(chalk.gray(' https://github.com/nahisaho/MUSUBI\n'));
|
|
441
441
|
|
|
442
442
|
console.log(chalk.white('27 Claude Code Skills:'));
|
|
443
443
|
console.log(chalk.gray(' Orchestration: orchestrator, steering, constitution-enforcer'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "musubi-sdd",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"description": "Ultimate Specification Driven Development Tool with 27 Agents for 7 AI Coding Platforms + MCP Integration (Claude Code, GitHub Copilot, Cursor, Gemini CLI, Windsurf, Codex, Qwen Code)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"license": "MIT",
|
|
54
54
|
"repository": {
|
|
55
55
|
"type": "git",
|
|
56
|
-
"url": "git+https://github.com/nahisaho/
|
|
56
|
+
"url": "git+https://github.com/nahisaho/MUSUBI.git"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">=18.0.0"
|
|
@@ -8,9 +8,9 @@ const chalk = require('chalk');
|
|
|
8
8
|
*/
|
|
9
9
|
class GapDetector {
|
|
10
10
|
constructor(options = {}) {
|
|
11
|
-
this.requirementsDir = options.requirementsDir || '
|
|
12
|
-
this.designDir = options.designDir || '
|
|
13
|
-
this.tasksDir = options.tasksDir || '
|
|
11
|
+
this.requirementsDir = options.requirementsDir || 'storage/specs';
|
|
12
|
+
this.designDir = options.designDir || 'storage/design';
|
|
13
|
+
this.tasksDir = options.tasksDir || 'storage/tasks';
|
|
14
14
|
this.srcDir = options.srcDir || 'src';
|
|
15
15
|
this.testsDir = options.testsDir || 'tests';
|
|
16
16
|
}
|
|
@@ -18,9 +18,9 @@ class TraceabilityAnalyzer {
|
|
|
18
18
|
* Generate full traceability matrix
|
|
19
19
|
*/
|
|
20
20
|
async generateMatrix(options = {}) {
|
|
21
|
-
const requirements = await this.findRequirements(options.requirements || '
|
|
22
|
-
const design = await this.findDesign(options.design || '
|
|
23
|
-
const tasks = await this.findTasks(options.tasks || '
|
|
21
|
+
const requirements = await this.findRequirements(options.requirements || 'storage/specs');
|
|
22
|
+
const design = await this.findDesign(options.design || 'storage/design');
|
|
23
|
+
const tasks = await this.findTasks(options.tasks || 'storage/tasks');
|
|
24
24
|
const code = await this.findCode(options.code || 'src');
|
|
25
25
|
const tests = await this.findTests(options.tests || 'tests');
|
|
26
26
|
|
|
@@ -84,9 +84,9 @@ class TraceabilityAnalyzer {
|
|
|
84
84
|
* Detect gaps in traceability
|
|
85
85
|
*/
|
|
86
86
|
async detectGaps(options = {}) {
|
|
87
|
-
const requirements = await this.findRequirements(options.requirements || '
|
|
88
|
-
const design = await this.findDesign(options.design || '
|
|
89
|
-
const tasks = await this.findTasks(options.tasks || '
|
|
87
|
+
const requirements = await this.findRequirements(options.requirements || 'storage/specs');
|
|
88
|
+
const design = await this.findDesign(options.design || 'storage/design');
|
|
89
|
+
const tasks = await this.findTasks(options.tasks || 'storage/tasks');
|
|
90
90
|
const code = await this.findCode(options.code || 'src');
|
|
91
91
|
const tests = await this.findTests(options.tests || 'tests');
|
|
92
92
|
|
|
@@ -149,9 +149,9 @@ class TraceabilityAnalyzer {
|
|
|
149
149
|
* Trace specific requirement
|
|
150
150
|
*/
|
|
151
151
|
async traceRequirement(requirementId, options = {}) {
|
|
152
|
-
const requirements = await this.findRequirements(options.requirements || '
|
|
153
|
-
const design = await this.findDesign(options.design || '
|
|
154
|
-
const tasks = await this.findTasks(options.tasks || '
|
|
152
|
+
const requirements = await this.findRequirements(options.requirements || 'storage/specs');
|
|
153
|
+
const design = await this.findDesign(options.design || 'storage/design');
|
|
154
|
+
const tasks = await this.findTasks(options.tasks || 'storage/tasks');
|
|
155
155
|
const code = await this.findCode(options.code || 'src');
|
|
156
156
|
const tests = await this.findTests(options.tests || 'tests');
|
|
157
157
|
|
|
@@ -199,9 +199,9 @@ class TraceabilityAnalyzer {
|
|
|
199
199
|
* Traces both forward (req->design->tasks->code->tests) and backward (tests->code->tasks->design->req)
|
|
200
200
|
*/
|
|
201
201
|
async analyzeBidirectional(options = {}) {
|
|
202
|
-
const requirements = await this.findRequirements(options.requirements || '
|
|
203
|
-
const design = await this.findDesign(options.design || '
|
|
204
|
-
const tasks = await this.findTasks(options.tasks || '
|
|
202
|
+
const requirements = await this.findRequirements(options.requirements || 'storage/specs');
|
|
203
|
+
const design = await this.findDesign(options.design || 'storage/design');
|
|
204
|
+
const tasks = await this.findTasks(options.tasks || 'storage/tasks');
|
|
205
205
|
const code = await this.findCode(options.code || 'src');
|
|
206
206
|
const tests = await this.findTests(options.tests || 'tests');
|
|
207
207
|
|
|
@@ -302,8 +302,8 @@ class TraceabilityAnalyzer {
|
|
|
302
302
|
* Analyze impact of requirement changes
|
|
303
303
|
*/
|
|
304
304
|
async analyzeImpact(requirementId, options = {}) {
|
|
305
|
-
const design = await this.findDesign(options.design || '
|
|
306
|
-
const tasks = await this.findTasks(options.tasks || '
|
|
305
|
+
const design = await this.findDesign(options.design || 'storage/design');
|
|
306
|
+
const tasks = await this.findTasks(options.tasks || 'storage/tasks');
|
|
307
307
|
const code = await this.findCode(options.code || 'src');
|
|
308
308
|
const tests = await this.findTests(options.tests || 'tests');
|
|
309
309
|
|
|
@@ -350,9 +350,9 @@ class TraceabilityAnalyzer {
|
|
|
350
350
|
* Generate detailed statistics
|
|
351
351
|
*/
|
|
352
352
|
async generateStatistics(options = {}) {
|
|
353
|
-
const requirements = await this.findRequirements(options.requirements || '
|
|
354
|
-
const design = await this.findDesign(options.design || '
|
|
355
|
-
const tasks = await this.findTasks(options.tasks || '
|
|
353
|
+
const requirements = await this.findRequirements(options.requirements || 'storage/specs');
|
|
354
|
+
const design = await this.findDesign(options.design || 'storage/design');
|
|
355
|
+
const tasks = await this.findTasks(options.tasks || 'storage/tasks');
|
|
356
356
|
const code = await this.findCode(options.code || 'src');
|
|
357
357
|
const tests = await this.findTests(options.tests || 'tests');
|
|
358
358
|
|
package/src/cli/dashboard-cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dashboard CLI
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Command-line interface for dashboard operations.
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* Requirement: IMP-6.2-003-05
|
|
7
7
|
* Design: Section 4.5
|
|
8
8
|
*/
|
|
@@ -17,7 +17,7 @@ const { MatrixStorage } = require('../traceability/matrix-storage');
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* DashboardCLI
|
|
20
|
-
*
|
|
20
|
+
*
|
|
21
21
|
* Provides CLI commands for dashboard operations.
|
|
22
22
|
*/
|
|
23
23
|
class DashboardCLI {
|
|
@@ -49,7 +49,7 @@ class DashboardCLI {
|
|
|
49
49
|
'workflow:status': () => this.getWorkflowStatus(args[0]),
|
|
50
50
|
'workflow:advance': () => this.advanceWorkflow(args[0], options),
|
|
51
51
|
'workflow:list': () => this.listWorkflows(),
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
// Sprint commands
|
|
54
54
|
'sprint:create': () => this.createSprint(options),
|
|
55
55
|
'sprint:start': () => this.startSprint(args[0]),
|
|
@@ -57,16 +57,16 @@ class DashboardCLI {
|
|
|
57
57
|
'sprint:status': () => this.getSprintStatus(args[0]),
|
|
58
58
|
'sprint:add-task': () => this.addSprintTask(args[0], options),
|
|
59
59
|
'sprint:report': () => this.generateSprintReport(args[0]),
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
// Traceability commands
|
|
62
62
|
'trace:scan': () => this.scanTraceability(args[0], options),
|
|
63
63
|
'trace:gaps': () => this.detectGaps(args[0]),
|
|
64
64
|
'trace:matrix': () => this.showMatrix(args[0]),
|
|
65
65
|
'trace:save': () => this.saveMatrix(args[0], options),
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
// Summary commands
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
summary: () => this.getSummary(args[0]),
|
|
69
|
+
help: () => this.showHelp(),
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
const handler = commands[command];
|
|
@@ -90,13 +90,13 @@ class DashboardCLI {
|
|
|
90
90
|
|
|
91
91
|
const workflow = await this.dashboard.createWorkflow(featureId, {
|
|
92
92
|
title: options.name || featureId,
|
|
93
|
-
description: options.description || ''
|
|
93
|
+
description: options.description || '',
|
|
94
94
|
});
|
|
95
95
|
|
|
96
96
|
return {
|
|
97
97
|
success: true,
|
|
98
98
|
message: `Workflow created: ${workflow.featureId}`,
|
|
99
|
-
workflow
|
|
99
|
+
workflow,
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -120,7 +120,7 @@ class DashboardCLI {
|
|
|
120
120
|
return {
|
|
121
121
|
success: true,
|
|
122
122
|
workflow,
|
|
123
|
-
summary
|
|
123
|
+
summary,
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -147,27 +147,19 @@ class DashboardCLI {
|
|
|
147
147
|
fromStage: workflow.currentStage,
|
|
148
148
|
toStage: nextStage,
|
|
149
149
|
reviewer: options.reviewer,
|
|
150
|
-
status: 'approved'
|
|
150
|
+
status: 'approved',
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
// Complete current stage
|
|
154
|
-
await this.dashboard.updateStage(
|
|
155
|
-
workflowId,
|
|
156
|
-
workflow.currentStage,
|
|
157
|
-
'completed'
|
|
158
|
-
);
|
|
154
|
+
await this.dashboard.updateStage(workflowId, workflow.currentStage, 'completed');
|
|
159
155
|
|
|
160
156
|
// Start next stage
|
|
161
|
-
const updated = await this.dashboard.updateStage(
|
|
162
|
-
workflowId,
|
|
163
|
-
nextStage,
|
|
164
|
-
'in-progress'
|
|
165
|
-
);
|
|
157
|
+
const updated = await this.dashboard.updateStage(workflowId, nextStage, 'in-progress');
|
|
166
158
|
|
|
167
159
|
return {
|
|
168
160
|
success: true,
|
|
169
161
|
message: `Workflow advanced to ${updated.currentStage}`,
|
|
170
|
-
workflow: updated
|
|
162
|
+
workflow: updated,
|
|
171
163
|
};
|
|
172
164
|
}
|
|
173
165
|
|
|
@@ -186,14 +178,14 @@ class DashboardCLI {
|
|
|
186
178
|
name: w.title,
|
|
187
179
|
currentStage: w.currentStage,
|
|
188
180
|
status: w.status || 'active',
|
|
189
|
-
completion
|
|
181
|
+
completion,
|
|
190
182
|
});
|
|
191
183
|
}
|
|
192
184
|
|
|
193
185
|
return {
|
|
194
186
|
success: true,
|
|
195
187
|
count: workflows.length,
|
|
196
|
-
workflows: workflowSummaries
|
|
188
|
+
workflows: workflowSummaries,
|
|
197
189
|
};
|
|
198
190
|
}
|
|
199
191
|
|
|
@@ -208,13 +200,13 @@ class DashboardCLI {
|
|
|
208
200
|
name: options.name,
|
|
209
201
|
featureId: options.featureId,
|
|
210
202
|
goal: options.goal,
|
|
211
|
-
velocity: options.velocity ? parseInt(options.velocity) : undefined
|
|
203
|
+
velocity: options.velocity ? parseInt(options.velocity) : undefined,
|
|
212
204
|
});
|
|
213
205
|
|
|
214
206
|
return {
|
|
215
207
|
success: true,
|
|
216
208
|
message: `Sprint created: ${sprint.id}`,
|
|
217
|
-
sprint
|
|
209
|
+
sprint,
|
|
218
210
|
};
|
|
219
211
|
}
|
|
220
212
|
|
|
@@ -233,7 +225,7 @@ class DashboardCLI {
|
|
|
233
225
|
return {
|
|
234
226
|
success: true,
|
|
235
227
|
message: `Sprint started: ${sprint.id}`,
|
|
236
|
-
sprint
|
|
228
|
+
sprint,
|
|
237
229
|
};
|
|
238
230
|
}
|
|
239
231
|
|
|
@@ -252,7 +244,7 @@ class DashboardCLI {
|
|
|
252
244
|
return {
|
|
253
245
|
success: true,
|
|
254
246
|
message: `Sprint completed: ${sprint.id}`,
|
|
255
|
-
sprint
|
|
247
|
+
sprint,
|
|
256
248
|
};
|
|
257
249
|
}
|
|
258
250
|
|
|
@@ -276,7 +268,7 @@ class DashboardCLI {
|
|
|
276
268
|
return {
|
|
277
269
|
success: true,
|
|
278
270
|
sprint,
|
|
279
|
-
metrics
|
|
271
|
+
metrics,
|
|
280
272
|
};
|
|
281
273
|
}
|
|
282
274
|
|
|
@@ -295,19 +287,21 @@ class DashboardCLI {
|
|
|
295
287
|
throw new Error('Task title is required');
|
|
296
288
|
}
|
|
297
289
|
|
|
298
|
-
const sprint = await this.planner.addTasks(sprintId, [
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
290
|
+
const sprint = await this.planner.addTasks(sprintId, [
|
|
291
|
+
{
|
|
292
|
+
id: options.taskId,
|
|
293
|
+
title: options.title,
|
|
294
|
+
description: options.description,
|
|
295
|
+
requirementId: options.requirementId,
|
|
296
|
+
storyPoints: options.points ? parseInt(options.points) : 1,
|
|
297
|
+
priority: options.priority || PRIORITY.MEDIUM,
|
|
298
|
+
},
|
|
299
|
+
]);
|
|
306
300
|
|
|
307
301
|
return {
|
|
308
302
|
success: true,
|
|
309
303
|
message: 'Task added to sprint',
|
|
310
|
-
sprint
|
|
304
|
+
sprint,
|
|
311
305
|
};
|
|
312
306
|
}
|
|
313
307
|
|
|
@@ -331,7 +325,7 @@ class DashboardCLI {
|
|
|
331
325
|
return {
|
|
332
326
|
success: true,
|
|
333
327
|
message: 'Report generated',
|
|
334
|
-
report: markdown
|
|
328
|
+
report: markdown,
|
|
335
329
|
};
|
|
336
330
|
}
|
|
337
331
|
|
|
@@ -343,7 +337,7 @@ class DashboardCLI {
|
|
|
343
337
|
*/
|
|
344
338
|
async scanTraceability(directory = '.', options = {}) {
|
|
345
339
|
const artifacts = await this.extractor.scanDirectory(directory, {
|
|
346
|
-
extensions: options.extensions ? options.extensions.split(',') : undefined
|
|
340
|
+
extensions: options.extensions ? options.extensions.split(',') : undefined,
|
|
347
341
|
});
|
|
348
342
|
|
|
349
343
|
return {
|
|
@@ -351,7 +345,7 @@ class DashboardCLI {
|
|
|
351
345
|
directory,
|
|
352
346
|
artifacts: artifacts.length,
|
|
353
347
|
requirements: new Set(artifacts.map(a => a.requirementId)).size,
|
|
354
|
-
results: artifacts
|
|
348
|
+
results: artifacts,
|
|
355
349
|
};
|
|
356
350
|
}
|
|
357
351
|
|
|
@@ -363,11 +357,11 @@ class DashboardCLI {
|
|
|
363
357
|
async detectGaps(directory = '.') {
|
|
364
358
|
// Scan artifacts
|
|
365
359
|
const codeArtifacts = await this.extractor.scanDirectory(directory, {
|
|
366
|
-
extensions: ['.js', '.ts']
|
|
360
|
+
extensions: ['.js', '.ts'],
|
|
367
361
|
});
|
|
368
|
-
|
|
362
|
+
|
|
369
363
|
const testArtifacts = await this.extractor.scanDirectory(directory, {
|
|
370
|
-
extensions: ['.test.js', '.spec.js', '.test.ts', '.spec.ts']
|
|
364
|
+
extensions: ['.test.js', '.spec.js', '.test.ts', '.spec.ts'],
|
|
371
365
|
});
|
|
372
366
|
|
|
373
367
|
// Build matrix in format expected by GapDetector
|
|
@@ -382,7 +376,7 @@ class DashboardCLI {
|
|
|
382
376
|
code: [],
|
|
383
377
|
tests: [],
|
|
384
378
|
design: [],
|
|
385
|
-
commits: []
|
|
379
|
+
commits: [],
|
|
386
380
|
};
|
|
387
381
|
}
|
|
388
382
|
matrix[artifact.requirementId].code.push(artifact);
|
|
@@ -396,7 +390,7 @@ class DashboardCLI {
|
|
|
396
390
|
code: [],
|
|
397
391
|
tests: [],
|
|
398
392
|
design: [],
|
|
399
|
-
commits: []
|
|
393
|
+
commits: [],
|
|
400
394
|
};
|
|
401
395
|
}
|
|
402
396
|
matrix[artifact.requirementId].tests.push(artifact);
|
|
@@ -410,7 +404,7 @@ class DashboardCLI {
|
|
|
410
404
|
success: true,
|
|
411
405
|
requirements: allRequirements.size,
|
|
412
406
|
gaps: report.gaps.length,
|
|
413
|
-
report
|
|
407
|
+
report,
|
|
414
408
|
};
|
|
415
409
|
}
|
|
416
410
|
|
|
@@ -427,14 +421,14 @@ class DashboardCLI {
|
|
|
427
421
|
}
|
|
428
422
|
return {
|
|
429
423
|
success: true,
|
|
430
|
-
matrix
|
|
424
|
+
matrix,
|
|
431
425
|
};
|
|
432
426
|
}
|
|
433
427
|
|
|
434
428
|
const matrices = await this.matrixStorage.list();
|
|
435
429
|
return {
|
|
436
430
|
success: true,
|
|
437
|
-
matrices
|
|
431
|
+
matrices,
|
|
438
432
|
};
|
|
439
433
|
}
|
|
440
434
|
|
|
@@ -446,14 +440,14 @@ class DashboardCLI {
|
|
|
446
440
|
*/
|
|
447
441
|
async saveMatrix(directory = '.', options = {}) {
|
|
448
442
|
const codeArtifacts = await this.extractor.scanDirectory(directory);
|
|
449
|
-
|
|
443
|
+
|
|
450
444
|
const entries = this.extractor.groupByRequirement(codeArtifacts);
|
|
451
|
-
|
|
445
|
+
|
|
452
446
|
const featureId = options.id || `MATRIX-${Date.now()}`;
|
|
453
447
|
const matrix = {
|
|
454
448
|
name: options.name || 'Traceability Matrix',
|
|
455
449
|
entries,
|
|
456
|
-
createdAt: new Date().toISOString()
|
|
450
|
+
createdAt: new Date().toISOString(),
|
|
457
451
|
};
|
|
458
452
|
|
|
459
453
|
const filePath = await this.matrixStorage.save(featureId, matrix);
|
|
@@ -461,7 +455,7 @@ class DashboardCLI {
|
|
|
461
455
|
return {
|
|
462
456
|
success: true,
|
|
463
457
|
message: `Matrix saved: ${featureId}`,
|
|
464
|
-
path: filePath
|
|
458
|
+
path: filePath,
|
|
465
459
|
};
|
|
466
460
|
}
|
|
467
461
|
|
|
@@ -472,7 +466,7 @@ class DashboardCLI {
|
|
|
472
466
|
*/
|
|
473
467
|
async getSummary(featureId) {
|
|
474
468
|
const workflows = await this.dashboard.listWorkflows();
|
|
475
|
-
const filteredWorkflows = featureId
|
|
469
|
+
const filteredWorkflows = featureId
|
|
476
470
|
? workflows.filter(w => w.featureId === featureId)
|
|
477
471
|
: workflows;
|
|
478
472
|
|
|
@@ -480,13 +474,13 @@ class DashboardCLI {
|
|
|
480
474
|
workflows: {
|
|
481
475
|
total: filteredWorkflows.length,
|
|
482
476
|
active: filteredWorkflows.filter(w => w.status === 'active').length,
|
|
483
|
-
completed: filteredWorkflows.filter(w => w.status === 'completed').length
|
|
484
|
-
}
|
|
477
|
+
completed: filteredWorkflows.filter(w => w.status === 'completed').length,
|
|
478
|
+
},
|
|
485
479
|
};
|
|
486
480
|
|
|
487
481
|
return {
|
|
488
482
|
success: true,
|
|
489
|
-
summary
|
|
483
|
+
summary,
|
|
490
484
|
};
|
|
491
485
|
}
|
|
492
486
|
|
|
@@ -513,8 +507,8 @@ class DashboardCLI {
|
|
|
513
507
|
'trace:matrix [matrixId]': 'Show traceability matrix',
|
|
514
508
|
'trace:save [directory]': 'Save traceability matrix',
|
|
515
509
|
'summary [featureId]': 'Get overall summary',
|
|
516
|
-
|
|
517
|
-
}
|
|
510
|
+
help: 'Show this help',
|
|
511
|
+
},
|
|
518
512
|
};
|
|
519
513
|
}
|
|
520
514
|
|