musubi-sdd 6.2.1 → 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.
Files changed (55) hide show
  1. package/README.ja.md +3 -3
  2. package/README.md +3 -3
  3. package/bin/musubi-dashboard.js +23 -14
  4. package/bin/musubi-design.js +3 -3
  5. package/bin/musubi-gaps.js +9 -9
  6. package/bin/musubi-init.js +14 -1310
  7. package/bin/musubi-requirements.js +1 -1
  8. package/bin/musubi-tasks.js +5 -5
  9. package/bin/musubi-trace.js +23 -23
  10. package/bin/musubi-upgrade.js +400 -0
  11. package/bin/musubi.js +16 -1
  12. package/package.json +4 -3
  13. package/src/analyzers/gap-detector.js +3 -3
  14. package/src/analyzers/traceability.js +17 -17
  15. package/src/cli/dashboard-cli.js +54 -60
  16. package/src/cli/init-generators.js +464 -0
  17. package/src/cli/init-helpers.js +884 -0
  18. package/src/constitutional/checker.js +67 -65
  19. package/src/constitutional/ci-reporter.js +58 -49
  20. package/src/constitutional/index.js +2 -2
  21. package/src/constitutional/phase-minus-one.js +24 -27
  22. package/src/constitutional/steering-sync.js +29 -40
  23. package/src/dashboard/index.js +2 -2
  24. package/src/dashboard/sprint-planner.js +17 -19
  25. package/src/dashboard/sprint-reporter.js +47 -38
  26. package/src/dashboard/transition-recorder.js +12 -18
  27. package/src/dashboard/workflow-dashboard.js +28 -39
  28. package/src/enterprise/error-recovery.js +109 -49
  29. package/src/enterprise/experiment-report.js +63 -37
  30. package/src/enterprise/index.js +5 -5
  31. package/src/enterprise/rollback-manager.js +28 -29
  32. package/src/enterprise/tech-article.js +41 -35
  33. package/src/generators/design.js +3 -3
  34. package/src/generators/requirements.js +5 -3
  35. package/src/generators/tasks.js +2 -2
  36. package/src/integrations/platforms.js +1 -1
  37. package/src/templates/agents/claude-code/CLAUDE.md +1 -1
  38. package/src/templates/agents/claude-code/skills/design-reviewer/SKILL.md +132 -113
  39. package/src/templates/agents/claude-code/skills/requirements-reviewer/SKILL.md +85 -56
  40. package/src/templates/agents/codex/AGENTS.md +2 -2
  41. package/src/templates/agents/cursor/AGENTS.md +2 -2
  42. package/src/templates/agents/gemini-cli/GEMINI.md +2 -2
  43. package/src/templates/agents/github-copilot/AGENTS.md +2 -2
  44. package/src/templates/agents/github-copilot/commands/sdd-requirements.prompt.md +23 -4
  45. package/src/templates/agents/qwen-code/QWEN.md +2 -2
  46. package/src/templates/agents/shared/AGENTS.md +1 -1
  47. package/src/templates/agents/windsurf/AGENTS.md +2 -2
  48. package/src/templates/skills/browser-agent.md +1 -1
  49. package/src/traceability/extractor.js +22 -21
  50. package/src/traceability/gap-detector.js +19 -17
  51. package/src/traceability/index.js +2 -2
  52. package/src/traceability/matrix-storage.js +20 -22
  53. package/src/validators/constitution.js +5 -2
  54. package/src/validators/critic-system.js +6 -6
  55. package/src/validators/traceability-validator.js +3 -3
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * GapDetector Implementation
3
- *
3
+ *
4
4
  * Detects requirements without implementation or tests.
5
- *
5
+ *
6
6
  * Requirement: IMP-6.2-004-02
7
7
  * Design: Section 5.2
8
8
  */
@@ -14,32 +14,35 @@ const SEVERITY_MAP = {
14
14
  'no-test': 'critical',
15
15
  'no-code': 'high',
16
16
  'no-design': 'medium',
17
- 'no-commit': 'low'
17
+ 'no-commit': 'low',
18
18
  };
19
19
 
20
20
  /**
21
21
  * Severity ordering for sorting
22
22
  */
23
23
  const SEVERITY_ORDER = {
24
- 'critical': 0,
25
- 'high': 1,
26
- 'medium': 2,
27
- 'low': 3
24
+ critical: 0,
25
+ high: 1,
26
+ medium: 2,
27
+ low: 3,
28
28
  };
29
29
 
30
30
  /**
31
31
  * Suggestions for each gap type
32
32
  */
33
33
  const SUGGESTIONS = {
34
- 'no-test': 'この要件に対するテストを作成してください。Article III (Test-First) に従い、実装前にテストを書くことを推奨します。',
34
+ 'no-test':
35
+ 'この要件に対するテストを作成してください。Article III (Test-First) に従い、実装前にテストを書くことを推奨します。',
35
36
  'no-code': '要件の実装が必要です。設計ドキュメントを参照して実装を開始してください。',
36
- 'no-design': '設計ドキュメントを作成してください。C4モデルに従い、コンポーネント図とADRを追加することを推奨します。',
37
- 'no-commit': 'この要件に関連するコミットがありません。コミットメッセージに要件IDを含めてください。'
37
+ 'no-design':
38
+ '設計ドキュメントを作成してください。C4モデルに従い、コンポーネント図とADRを追加することを推奨します。',
39
+ 'no-commit':
40
+ 'この要件に関連するコミットがありません。コミットメッセージに要件IDを含めてください。',
38
41
  };
39
42
 
40
43
  /**
41
44
  * GapDetector
42
- *
45
+ *
43
46
  * Detects gaps in traceability between requirements and artifacts.
44
47
  */
45
48
  class GapDetector {
@@ -82,7 +85,7 @@ class GapDetector {
82
85
  requirementId,
83
86
  gapType,
84
87
  severity: SEVERITY_MAP[gapType],
85
- suggestion: SUGGESTIONS[gapType]
88
+ suggestion: SUGGESTIONS[gapType],
86
89
  };
87
90
  }
88
91
 
@@ -117,8 +120,7 @@ class GapDetector {
117
120
  gapsByType[gap.gapType] = (gapsByType[gap.gapType] || 0) + 1;
118
121
 
119
122
  // Count by requirement
120
- gapsByRequirement[gap.requirementId] =
121
- (gapsByRequirement[gap.requirementId] || 0) + 1;
123
+ gapsByRequirement[gap.requirementId] = (gapsByRequirement[gap.requirementId] || 0) + 1;
122
124
 
123
125
  // Count by severity
124
126
  switch (gap.severity) {
@@ -144,7 +146,7 @@ class GapDetector {
144
146
  mediumGaps,
145
147
  lowGaps,
146
148
  gapsByType,
147
- gapsByRequirement
149
+ gapsByRequirement,
148
150
  };
149
151
  }
150
152
 
@@ -161,7 +163,7 @@ class GapDetector {
161
163
  return {
162
164
  generatedAt: new Date().toISOString(),
163
165
  gaps: sortedGaps,
164
- summary
166
+ summary,
165
167
  };
166
168
  }
167
169
 
@@ -222,7 +224,7 @@ class GapDetector {
222
224
 
223
225
  const reqsWithGaps = this.getRequirementsWithGaps(links);
224
226
  const covered = links.length - reqsWithGaps.length;
225
-
227
+
226
228
  return Math.round((covered / links.length) * 100);
227
229
  }
228
230
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Traceability Module
3
- *
3
+ *
4
4
  * Requirement: IMP-6.2-004
5
5
  */
6
6
 
@@ -11,5 +11,5 @@ const { MatrixStorage } = require('./matrix-storage');
11
11
  module.exports = {
12
12
  TraceabilityExtractor,
13
13
  GapDetector,
14
- MatrixStorage
14
+ MatrixStorage,
15
15
  };
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * MatrixStorage Implementation
3
- *
3
+ *
4
4
  * YAML-based persistence for traceability matrices.
5
- *
5
+ *
6
6
  * Requirement: IMP-6.2-004-03
7
7
  * Design: ADR-6.2-002
8
8
  */
@@ -15,12 +15,12 @@ const yaml = require('yaml');
15
15
  * Default configuration
16
16
  */
17
17
  const DEFAULT_CONFIG = {
18
- storageDir: 'storage/traceability'
18
+ storageDir: 'storage/traceability',
19
19
  };
20
20
 
21
21
  /**
22
22
  * MatrixStorage
23
- *
23
+ *
24
24
  * Persists traceability matrices as YAML files.
25
25
  */
26
26
  class MatrixStorage {
@@ -46,11 +46,11 @@ class MatrixStorage {
46
46
 
47
47
  const yamlContent = yaml.stringify(matrix, {
48
48
  indent: 2,
49
- lineWidth: 0
49
+ lineWidth: 0,
50
50
  });
51
51
 
52
52
  await fs.writeFile(filePath, yamlContent, 'utf-8');
53
-
53
+
54
54
  return filePath;
55
55
  }
56
56
 
@@ -62,7 +62,7 @@ class MatrixStorage {
62
62
  async load(filename) {
63
63
  try {
64
64
  let filePath;
65
-
65
+
66
66
  if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {
67
67
  filePath = path.join(this.config.storageDir, filename);
68
68
  } else {
@@ -74,7 +74,7 @@ class MatrixStorage {
74
74
 
75
75
  await fs.access(filePath);
76
76
  const content = await fs.readFile(filePath, 'utf-8');
77
-
77
+
78
78
  return yaml.parse(content);
79
79
  } catch {
80
80
  return null;
@@ -88,15 +88,15 @@ class MatrixStorage {
88
88
  */
89
89
  async loadLatest(featureId) {
90
90
  const files = await this.list(featureId);
91
-
91
+
92
92
  if (files.length === 0) return null;
93
93
 
94
94
  // Sort by date (newest first)
95
95
  files.sort().reverse();
96
-
96
+
97
97
  const latestFile = files[0];
98
98
  const filePath = path.join(this.config.storageDir, latestFile);
99
-
99
+
100
100
  const content = await fs.readFile(filePath, 'utf-8');
101
101
  return yaml.parse(content);
102
102
  }
@@ -109,9 +109,7 @@ class MatrixStorage {
109
109
  async list(prefix) {
110
110
  try {
111
111
  const files = await fs.readdir(this.config.storageDir);
112
- const yamlFiles = files.filter(f =>
113
- f.endsWith('.yaml') || f.endsWith('.yml')
114
- );
112
+ const yamlFiles = files.filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
115
113
 
116
114
  if (prefix) {
117
115
  return yamlFiles.filter(f => f.startsWith(prefix));
@@ -145,7 +143,7 @@ class MatrixStorage {
145
143
  // Get all requirement IDs
146
144
  const allReqIds = new Set([
147
145
  ...Object.keys(matrix1.requirements),
148
- ...Object.keys(matrix2.requirements)
146
+ ...Object.keys(matrix2.requirements),
149
147
  ]);
150
148
 
151
149
  for (const reqId of allReqIds) {
@@ -159,7 +157,7 @@ class MatrixStorage {
159
157
  design: this.mergeLinks(link1.design, link2.design),
160
158
  code: this.mergeLinks(link1.code, link2.code),
161
159
  tests: this.mergeLinks(link1.tests, link2.tests),
162
- commits: this.mergeLinks(link1.commits, link2.commits)
160
+ commits: this.mergeLinks(link1.commits, link2.commits),
163
161
  };
164
162
  } else {
165
163
  requirements[reqId] = link1 || link2;
@@ -170,7 +168,7 @@ class MatrixStorage {
170
168
  version: matrix2.version,
171
169
  generatedAt: new Date().toISOString(),
172
170
  requirements,
173
- summary: this.calculateSummary(requirements)
171
+ summary: this.calculateSummary(requirements),
174
172
  };
175
173
  }
176
174
 
@@ -182,7 +180,7 @@ class MatrixStorage {
182
180
  */
183
181
  mergeLinks(links1, links2) {
184
182
  const merged = [...links1];
185
-
183
+
186
184
  for (const link of links2) {
187
185
  const exists = merged.some(l => {
188
186
  if (l.path && link.path) {
@@ -219,7 +217,7 @@ class MatrixStorage {
219
217
  withCode: 0,
220
218
  withTests: 0,
221
219
  gaps: 0,
222
- coveragePercentage: 0
220
+ coveragePercentage: 0,
223
221
  };
224
222
  }
225
223
 
@@ -249,8 +247,8 @@ class MatrixStorage {
249
247
  }
250
248
 
251
249
  // Calculate coverage as percentage of requirements with full coverage
252
- const fullyLinked = links.filter(l =>
253
- l.design.length > 0 && l.code.length > 0 && l.tests.length > 0
250
+ const fullyLinked = links.filter(
251
+ l => l.design.length > 0 && l.code.length > 0 && l.tests.length > 0
254
252
  ).length;
255
253
 
256
254
  return {
@@ -260,7 +258,7 @@ class MatrixStorage {
260
258
  withCode,
261
259
  withTests,
262
260
  gaps: gapCount,
263
- coveragePercentage: Math.round((fullyLinked / total) * 100)
261
+ coveragePercentage: Math.round((fullyLinked / total) * 100),
264
262
  };
265
263
  }
266
264
 
@@ -567,12 +567,15 @@ class ConstitutionValidator {
567
567
  files: [],
568
568
  };
569
569
 
570
- // Find all source files
570
+ // Find all source files (excluding node_modules)
571
571
  const sourcePatterns = ['src/**/*.js', 'lib/**/*.js', 'bin/**/*.js'];
572
572
 
573
573
  const files = [];
574
574
  for (const pattern of sourcePatterns) {
575
- const matches = await glob(pattern, { cwd: this.projectRoot });
575
+ const matches = await glob(pattern, {
576
+ cwd: this.projectRoot,
577
+ ignore: ['**/node_modules/**'],
578
+ });
576
579
  files.push(...matches.map(f => path.join(this.projectRoot, f)));
577
580
  }
578
581
 
@@ -211,7 +211,7 @@ class RequirementsCritic extends BaseCritic {
211
211
  */
212
212
  checkEarsFormat(context) {
213
213
  const content =
214
- context.content || this.readFile('docs/requirements/srs/srs-musubi-v3.0.0.ja.md') || '';
214
+ context.content || this.readFile('storage/specs/srs/srs-musubi-v3.0.0.ja.md') || '';
215
215
 
216
216
  // EARS キーワードパターン
217
217
  const earsPatterns = [
@@ -241,7 +241,7 @@ class RequirementsCritic extends BaseCritic {
241
241
  */
242
242
  checkCompleteness(context) {
243
243
  const content =
244
- context.content || this.readFile('docs/requirements/srs/srs-musubi-v3.0.0.ja.md') || '';
244
+ context.content || this.readFile('storage/specs/srs/srs-musubi-v3.0.0.ja.md') || '';
245
245
 
246
246
  const requiredSections = [
247
247
  /## 機能要件|## Functional Requirements/i,
@@ -258,7 +258,7 @@ class RequirementsCritic extends BaseCritic {
258
258
  */
259
259
  checkTestability(context) {
260
260
  const content =
261
- context.content || this.readFile('docs/requirements/srs/srs-musubi-v3.0.0.ja.md') || '';
261
+ context.content || this.readFile('storage/specs/srs/srs-musubi-v3.0.0.ja.md') || '';
262
262
 
263
263
  // 数値目標や測定可能な基準があるかチェック
264
264
  const measurablePatterns = [
@@ -340,7 +340,7 @@ class DesignCritic extends BaseCritic {
340
340
  * C4モデル準拠チェック
341
341
  */
342
342
  checkC4Format(_context) {
343
- const designDir = path.join(this.projectRoot, 'docs/design');
343
+ const designDir = path.join(this.projectRoot, 'storage/design');
344
344
  if (!fs.existsSync(designDir)) return 0;
345
345
 
346
346
  // C4レベルのキーワードをチェック
@@ -362,7 +362,7 @@ class DesignCritic extends BaseCritic {
362
362
  * ADR存在チェック
363
363
  */
364
364
  checkAdrPresence(_context) {
365
- const adrDir = path.join(this.projectRoot, 'docs/design/adr');
365
+ const adrDir = path.join(this.projectRoot, 'storage/design/adr');
366
366
  if (!fs.existsSync(adrDir)) return 0;
367
367
 
368
368
  const adrFiles = fs.readdirSync(adrDir).filter(f => f.startsWith('ADR-') && f.endsWith('.md'));
@@ -375,7 +375,7 @@ class DesignCritic extends BaseCritic {
375
375
  * 要件カバレッジチェック
376
376
  */
377
377
  checkRequirementCoverage(_context) {
378
- const designDir = path.join(this.projectRoot, 'docs/design');
378
+ const designDir = path.join(this.projectRoot, 'storage/design');
379
379
  if (!fs.existsSync(designDir)) return 0;
380
380
 
381
381
  const files = fs.readdirSync(designDir).filter(f => f.endsWith('.md'));
@@ -67,9 +67,9 @@ const defaultConfig = {
67
67
 
68
68
  // Paths configuration
69
69
  paths: {
70
- requirements: 'docs/requirements',
71
- design: 'docs/design',
72
- tasks: 'docs/tasks',
70
+ requirements: 'storage/specs',
71
+ design: 'storage/design',
72
+ tasks: 'storage/tasks',
73
73
  code: 'src',
74
74
  tests: 'tests',
75
75
  },