musubi-sdd 5.1.0 → 5.6.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.
Files changed (232) hide show
  1. package/README.ja.md +106 -48
  2. package/README.md +110 -32
  3. package/bin/musubi-analyze.js +74 -67
  4. package/bin/musubi-browser.js +27 -26
  5. package/bin/musubi-change.js +48 -47
  6. package/bin/musubi-checkpoint.js +10 -7
  7. package/bin/musubi-convert.js +25 -25
  8. package/bin/musubi-costs.js +27 -10
  9. package/bin/musubi-gui.js +52 -46
  10. package/bin/musubi-init.js +1952 -10
  11. package/bin/musubi-orchestrate.js +327 -239
  12. package/bin/musubi-remember.js +69 -56
  13. package/bin/musubi-resolve.js +53 -45
  14. package/bin/musubi-trace.js +51 -22
  15. package/bin/musubi-validate.js +39 -30
  16. package/bin/musubi-workflow.js +33 -34
  17. package/bin/musubi.js +39 -2
  18. package/package.json +1 -1
  19. package/src/agents/agent-loop.js +94 -95
  20. package/src/agents/agentic/code-generator.js +119 -109
  21. package/src/agents/agentic/code-reviewer.js +105 -108
  22. package/src/agents/agentic/index.js +4 -4
  23. package/src/agents/browser/action-executor.js +13 -13
  24. package/src/agents/browser/ai-comparator.js +11 -10
  25. package/src/agents/browser/context-manager.js +6 -6
  26. package/src/agents/browser/index.js +5 -5
  27. package/src/agents/browser/nl-parser.js +31 -46
  28. package/src/agents/browser/screenshot.js +2 -2
  29. package/src/agents/browser/test-generator.js +6 -4
  30. package/src/agents/function-tool.js +71 -65
  31. package/src/agents/index.js +7 -7
  32. package/src/agents/schema-generator.js +98 -94
  33. package/src/analyzers/ast-extractor.js +158 -146
  34. package/src/analyzers/codegraph-auto-update.js +858 -0
  35. package/src/analyzers/complexity-analyzer.js +536 -0
  36. package/src/analyzers/context-optimizer.js +241 -126
  37. package/src/analyzers/impact-analyzer.js +1 -1
  38. package/src/analyzers/large-project-analyzer.js +766 -0
  39. package/src/analyzers/repository-map.js +77 -81
  40. package/src/analyzers/security-analyzer.js +19 -11
  41. package/src/analyzers/stuck-detector.js +19 -17
  42. package/src/converters/index.js +78 -57
  43. package/src/converters/ir/types.js +12 -12
  44. package/src/converters/parsers/musubi-parser.js +134 -126
  45. package/src/converters/parsers/openapi-parser.js +70 -53
  46. package/src/converters/parsers/speckit-parser.js +239 -175
  47. package/src/converters/writers/musubi-writer.js +123 -118
  48. package/src/converters/writers/speckit-writer.js +124 -113
  49. package/src/generators/rust-migration-generator.js +512 -0
  50. package/src/gui/public/index.html +1365 -1211
  51. package/src/gui/server.js +41 -40
  52. package/src/gui/services/file-watcher.js +23 -8
  53. package/src/gui/services/project-scanner.js +26 -20
  54. package/src/gui/services/replanning-service.js +27 -23
  55. package/src/gui/services/traceability-service.js +8 -8
  56. package/src/gui/services/workflow-service.js +14 -7
  57. package/src/index.js +151 -0
  58. package/src/integrations/cicd.js +90 -104
  59. package/src/integrations/codegraph-mcp.js +643 -0
  60. package/src/integrations/documentation.js +142 -103
  61. package/src/integrations/examples.js +95 -80
  62. package/src/integrations/github-client.js +17 -17
  63. package/src/integrations/index.js +5 -5
  64. package/src/integrations/mcp/index.js +21 -21
  65. package/src/integrations/mcp/mcp-context-provider.js +76 -78
  66. package/src/integrations/mcp/mcp-discovery.js +74 -72
  67. package/src/integrations/mcp/mcp-tool-registry.js +99 -94
  68. package/src/integrations/mcp-connector.js +70 -66
  69. package/src/integrations/platforms.js +50 -49
  70. package/src/integrations/tool-discovery.js +37 -31
  71. package/src/llm-providers/anthropic-provider.js +11 -11
  72. package/src/llm-providers/base-provider.js +16 -18
  73. package/src/llm-providers/copilot-provider.js +22 -19
  74. package/src/llm-providers/index.js +26 -25
  75. package/src/llm-providers/ollama-provider.js +11 -11
  76. package/src/llm-providers/openai-provider.js +12 -12
  77. package/src/managers/agent-memory.js +36 -24
  78. package/src/managers/checkpoint-manager.js +4 -8
  79. package/src/managers/delta-spec.js +19 -19
  80. package/src/managers/index.js +13 -4
  81. package/src/managers/memory-condenser.js +35 -45
  82. package/src/managers/repo-skill-manager.js +57 -31
  83. package/src/managers/skill-loader.js +25 -22
  84. package/src/managers/skill-tools.js +36 -72
  85. package/src/managers/workflow.js +30 -22
  86. package/src/monitoring/cost-tracker.js +48 -46
  87. package/src/monitoring/incident-manager.js +116 -106
  88. package/src/monitoring/index.js +144 -134
  89. package/src/monitoring/observability.js +75 -62
  90. package/src/monitoring/quality-dashboard.js +45 -41
  91. package/src/monitoring/release-manager.js +63 -53
  92. package/src/orchestration/agent-skill-binding.js +39 -47
  93. package/src/orchestration/error-handler.js +65 -107
  94. package/src/orchestration/guardrails/base-guardrail.js +26 -24
  95. package/src/orchestration/guardrails/guardrail-rules.js +50 -64
  96. package/src/orchestration/guardrails/index.js +5 -5
  97. package/src/orchestration/guardrails/input-guardrail.js +58 -45
  98. package/src/orchestration/guardrails/output-guardrail.js +104 -81
  99. package/src/orchestration/guardrails/safety-check.js +79 -79
  100. package/src/orchestration/index.js +38 -55
  101. package/src/orchestration/mcp-tool-adapters.js +96 -99
  102. package/src/orchestration/orchestration-engine.js +21 -21
  103. package/src/orchestration/pattern-registry.js +60 -45
  104. package/src/orchestration/patterns/auto.js +34 -47
  105. package/src/orchestration/patterns/group-chat.js +59 -65
  106. package/src/orchestration/patterns/handoff.js +67 -65
  107. package/src/orchestration/patterns/human-in-loop.js +51 -72
  108. package/src/orchestration/patterns/nested.js +25 -40
  109. package/src/orchestration/patterns/sequential.js +35 -34
  110. package/src/orchestration/patterns/swarm.js +63 -56
  111. package/src/orchestration/patterns/triage.js +150 -109
  112. package/src/orchestration/reasoning/index.js +9 -9
  113. package/src/orchestration/reasoning/planning-engine.js +143 -140
  114. package/src/orchestration/reasoning/reasoning-engine.js +206 -144
  115. package/src/orchestration/reasoning/self-correction.js +121 -128
  116. package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
  117. package/src/orchestration/replanning/alternative-generator.js +37 -42
  118. package/src/orchestration/replanning/config.js +63 -59
  119. package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
  120. package/src/orchestration/replanning/index.js +24 -20
  121. package/src/orchestration/replanning/plan-evaluator.js +49 -50
  122. package/src/orchestration/replanning/plan-monitor.js +32 -28
  123. package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
  124. package/src/orchestration/replanning/replan-history.js +33 -26
  125. package/src/orchestration/replanning/replanning-engine.js +106 -108
  126. package/src/orchestration/skill-executor.js +107 -109
  127. package/src/orchestration/skill-registry.js +85 -89
  128. package/src/orchestration/workflow-examples.js +228 -231
  129. package/src/orchestration/workflow-executor.js +65 -68
  130. package/src/orchestration/workflow-orchestrator.js +72 -73
  131. package/src/phase4-integration.js +47 -40
  132. package/src/phase5-integration.js +89 -30
  133. package/src/reporters/coverage-report.js +82 -30
  134. package/src/reporters/hierarchical-reporter.js +498 -0
  135. package/src/reporters/traceability-matrix-report.js +29 -20
  136. package/src/resolvers/issue-resolver.js +43 -31
  137. package/src/steering/advanced-validation.js +133 -124
  138. package/src/steering/auto-updater.js +60 -73
  139. package/src/steering/index.js +6 -6
  140. package/src/steering/quality-metrics.js +41 -35
  141. package/src/steering/steering-auto-update.js +83 -86
  142. package/src/steering/steering-validator.js +98 -106
  143. package/src/steering/template-constraints.js +53 -54
  144. package/src/templates/agents/claude-code/CLAUDE.md +32 -32
  145. package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
  146. package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
  147. package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
  148. package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
  149. package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
  150. package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
  151. package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
  152. package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
  153. package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
  154. package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
  155. package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
  156. package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
  157. package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
  158. package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
  159. package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
  160. package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
  161. package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
  162. package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
  163. package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
  164. package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
  165. package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
  166. package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
  167. package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
  168. package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
  169. package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
  170. package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
  171. package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
  172. package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
  173. package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
  174. package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
  175. package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
  176. package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
  177. package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
  178. package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
  179. package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
  180. package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
  181. package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
  182. package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
  183. package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
  184. package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
  185. package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
  186. package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
  187. package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
  188. package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
  189. package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
  190. package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
  191. package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
  192. package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
  193. package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
  194. package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
  195. package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
  196. package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
  197. package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
  198. package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
  199. package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
  200. package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
  201. package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
  202. package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
  203. package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
  204. package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
  205. package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
  206. package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
  207. package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
  208. package/src/templates/agents/codex/AGENTS.md +74 -42
  209. package/src/templates/agents/cursor/AGENTS.md +74 -42
  210. package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
  211. package/src/templates/agents/github-copilot/AGENTS.md +83 -51
  212. package/src/templates/agents/qwen-code/QWEN.md +74 -42
  213. package/src/templates/agents/windsurf/AGENTS.md +74 -42
  214. package/src/templates/architectures/README.md +41 -0
  215. package/src/templates/architectures/clean-architecture/README.md +113 -0
  216. package/src/templates/architectures/event-driven/README.md +162 -0
  217. package/src/templates/architectures/hexagonal/README.md +130 -0
  218. package/src/templates/index.js +6 -1
  219. package/src/templates/locale-manager.js +16 -16
  220. package/src/templates/shared/delta-spec-template.md +20 -13
  221. package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
  222. package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
  223. package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
  224. package/src/templates/shared/steering/structure.md +95 -0
  225. package/src/templates/skills/browser-agent.md +21 -16
  226. package/src/templates/skills/web-gui.md +8 -0
  227. package/src/templates/template-constraints.js +50 -53
  228. package/src/validators/advanced-validation.js +30 -36
  229. package/src/validators/constitutional-validator.js +77 -73
  230. package/src/validators/critic-system.js +49 -59
  231. package/src/validators/delta-format.js +59 -55
  232. package/src/validators/traceability-validator.js +7 -11
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * MUSUBI Skill Loader
3
- *
3
+ *
4
4
  * キーワードトリガー型スキルのロードと活性化
5
- *
5
+ *
6
6
  * @module src/managers/skill-loader
7
7
  * @see REQ-P0-B002
8
8
  * @inspired-by OpenHands openhands/microagent/microagent.py
@@ -59,7 +59,7 @@ class Skill {
59
59
 
60
60
  /**
61
61
  * メッセージがこのスキルをトリガーするか判定
62
- * @param {string} message
62
+ * @param {string} message
63
63
  * @returns {boolean}
64
64
  */
65
65
  matchesTrigger(message) {
@@ -87,7 +87,7 @@ class Skill {
87
87
 
88
88
  /**
89
89
  * エージェントがこのスキルを使用可能か判定
90
- * @param {string} agentType
90
+ * @param {string} agentType
91
91
  * @returns {boolean}
92
92
  */
93
93
  isAvailableFor(agentType) {
@@ -126,7 +126,7 @@ class SkillLoader {
126
126
  this.globalDir = options.globalDir || path.join(__dirname, '../../steering/templates/skills');
127
127
  this.userDir = options.userDir || path.join(os.homedir(), '.musubi/skills');
128
128
  this.repoDir = options.repoDir || path.join(this.projectRoot, '.musubi/skills');
129
-
129
+
130
130
  this.loadedSkills = new Map();
131
131
  this.initialized = false;
132
132
  }
@@ -153,9 +153,9 @@ class SkillLoader {
153
153
 
154
154
  /**
155
155
  * ディレクトリからスキルをロード
156
- * @param {string} dir
157
- * @param {string} defaultType
158
- * @param {number} basePriority
156
+ * @param {string} dir
157
+ * @param {string} defaultType
158
+ * @param {number} basePriority
159
159
  */
160
160
  async _loadFromDirectory(dir, defaultType, basePriority) {
161
161
  if (!fs.existsSync(dir)) {
@@ -183,9 +183,9 @@ class SkillLoader {
183
183
 
184
184
  /**
185
185
  * スキルファイルをパース
186
- * @param {string} filePath
187
- * @param {string} defaultType
188
- * @param {number} basePriority
186
+ * @param {string} filePath
187
+ * @param {string} defaultType
188
+ * @param {number} basePriority
189
189
  * @returns {Skill|null}
190
190
  */
191
191
  async parseSkill(filePath, defaultType = SkillType.GLOBAL, basePriority = 0) {
@@ -215,7 +215,7 @@ class SkillLoader {
215
215
 
216
216
  /**
217
217
  * Frontmatterをパース
218
- * @param {string} content
218
+ * @param {string} content
219
219
  * @returns {{ frontmatter: Object, body: string }}
220
220
  */
221
221
  _parseFrontmatter(content) {
@@ -280,7 +280,7 @@ class SkillLoader {
280
280
 
281
281
  /**
282
282
  * 値をパース
283
- * @param {string} value
283
+ * @param {string} value
284
284
  * @returns {any}
285
285
  */
286
286
  _parseValue(value) {
@@ -296,7 +296,10 @@ class SkillLoader {
296
296
  if (value.toLowerCase() === 'false') return false;
297
297
  // 配列(インライン)
298
298
  if (value.startsWith('[') && value.endsWith(']')) {
299
- return value.slice(1, -1).split(',').map(v => v.trim().replace(/^["']|["']$/g, ''));
299
+ return value
300
+ .slice(1, -1)
301
+ .split(',')
302
+ .map(v => v.trim().replace(/^["']|["']$/g, ''));
300
303
  }
301
304
  // 文字列
302
305
  return value.replace(/^["']|["']$/g, '');
@@ -336,7 +339,7 @@ class SkillLoader {
336
339
 
337
340
  /**
338
341
  * 名前でスキルを取得
339
- * @param {string} name
342
+ * @param {string} name
340
343
  * @returns {Skill|undefined}
341
344
  */
342
345
  getSkill(name) {
@@ -353,7 +356,7 @@ class SkillLoader {
353
356
 
354
357
  /**
355
358
  * スキルタイプでフィルタリング
356
- * @param {string} type
359
+ * @param {string} type
357
360
  * @returns {Skill[]}
358
361
  */
359
362
  getSkillsByType(type) {
@@ -365,8 +368,7 @@ class SkillLoader {
365
368
  * @returns {boolean}
366
369
  */
367
370
  hasRepoSkills() {
368
- return fs.existsSync(this.repoDir) &&
369
- fs.readdirSync(this.repoDir).some(f => f.endsWith('.md'));
371
+ return fs.existsSync(this.repoDir) && fs.readdirSync(this.repoDir).some(f => f.endsWith('.md'));
370
372
  }
371
373
 
372
374
  /**
@@ -385,9 +387,10 @@ class SkillLoader {
385
387
 
386
388
  const sortedSkills = this.getSkills().sort((a, b) => b.priority - a.priority);
387
389
  for (const skill of sortedSkills) {
388
- const triggers = skill.triggers.length > 3
389
- ? skill.triggers.slice(0, 3).join(', ') + '...'
390
- : skill.triggers.join(', ');
390
+ const triggers =
391
+ skill.triggers.length > 3
392
+ ? skill.triggers.slice(0, 3).join(', ') + '...'
393
+ : skill.triggers.join(', ');
391
394
  md += `| ${skill.name} | ${skill.type} | ${skill.priority} | ${triggers} | ${skill.agent} |\n`;
392
395
  }
393
396
 
@@ -396,7 +399,7 @@ class SkillLoader {
396
399
 
397
400
  /**
398
401
  * 活性化されたスキルをプロンプトに変換
399
- * @param {Skill[]} skills
402
+ * @param {Skill[]} skills
400
403
  * @returns {string}
401
404
  */
402
405
  formatSkillsForPrompt(skills) {
@@ -2,7 +2,7 @@
2
2
  * @fileoverview Skill Tools Manager
3
3
  * @description Manage allowed-tools configuration for MUSUBI skills
4
4
  * @version 3.11.0
5
- *
5
+ *
6
6
  * Features:
7
7
  * - Load skill tool configurations from YAML
8
8
  * - Validate tool availability
@@ -22,19 +22,8 @@ const { EventEmitter } = require('events');
22
22
  * Default tool sets for common skill categories
23
23
  */
24
24
  const DEFAULT_TOOL_SETS = {
25
- requirements: [
26
- 'file_read',
27
- 'file_write',
28
- 'search_files',
29
- 'read_resource'
30
- ],
31
- design: [
32
- 'file_read',
33
- 'file_write',
34
- 'search_files',
35
- 'create_directory',
36
- 'read_resource'
37
- ],
25
+ requirements: ['file_read', 'file_write', 'search_files', 'read_resource'],
26
+ design: ['file_read', 'file_write', 'search_files', 'create_directory', 'read_resource'],
38
27
  implementation: [
39
28
  'file_read',
40
29
  'file_write',
@@ -42,48 +31,23 @@ const DEFAULT_TOOL_SETS = {
42
31
  'create_directory',
43
32
  'run_command',
44
33
  'read_resource',
45
- 'code_analysis'
46
- ],
47
- testing: [
48
- 'file_read',
49
- 'file_write',
50
- 'search_files',
51
- 'run_command',
52
- 'test_runner'
53
- ],
54
- validation: [
55
- 'file_read',
56
- 'search_files',
57
- 'read_resource',
58
- 'validate'
59
- ],
60
- documentation: [
61
- 'file_read',
62
- 'file_write',
63
- 'search_files',
64
- 'read_resource'
65
- ],
66
- analysis: [
67
- 'file_read',
68
- 'search_files',
69
34
  'code_analysis',
70
- 'read_resource'
71
35
  ],
72
- deployment: [
73
- 'file_read',
74
- 'run_command',
75
- 'deploy'
76
- ]
36
+ testing: ['file_read', 'file_write', 'search_files', 'run_command', 'test_runner'],
37
+ validation: ['file_read', 'search_files', 'read_resource', 'validate'],
38
+ documentation: ['file_read', 'file_write', 'search_files', 'read_resource'],
39
+ analysis: ['file_read', 'search_files', 'code_analysis', 'read_resource'],
40
+ deployment: ['file_read', 'run_command', 'deploy'],
77
41
  };
78
42
 
79
43
  /**
80
44
  * Tool restriction levels
81
45
  */
82
46
  const RestrictionLevel = {
83
- NONE: 'none', // No restrictions
84
- STANDARD: 'standard', // Default restrictions
85
- STRICT: 'strict', // Minimal tools only
86
- CUSTOM: 'custom' // Custom configuration
47
+ NONE: 'none', // No restrictions
48
+ STANDARD: 'standard', // Default restrictions
49
+ STRICT: 'strict', // Minimal tools only
50
+ CUSTOM: 'custom', // Custom configuration
87
51
  };
88
52
 
89
53
  /**
@@ -161,7 +125,7 @@ class SkillToolConfig {
161
125
  deniedTools: this.deniedTools,
162
126
  restrictionLevel: this.restrictionLevel,
163
127
  toolOverrides: this.toolOverrides,
164
- inheritFrom: this.inheritFrom
128
+ inheritFrom: this.inheritFrom,
165
129
  };
166
130
  }
167
131
  }
@@ -176,7 +140,7 @@ class SkillToolsManager extends EventEmitter {
176
140
  configDir: options.configDir || '.musubi/tools',
177
141
  defaultToolSet: options.defaultToolSet || 'standard',
178
142
  enableInheritance: options.enableInheritance !== false,
179
- ...options
143
+ ...options,
180
144
  };
181
145
 
182
146
  this.skillConfigs = new Map();
@@ -206,7 +170,6 @@ class SkillToolsManager extends EventEmitter {
206
170
  await this._processConfig(config);
207
171
  this.emit('configLoaded', configPath);
208
172
  return config;
209
-
210
173
  } catch (error) {
211
174
  if (error.code === 'ENOENT') {
212
175
  return null;
@@ -266,7 +229,7 @@ class SkillToolsManager extends EventEmitter {
266
229
  */
267
230
  setSkillConfig(skillName, config) {
268
231
  const skillConfig = new SkillToolConfig(skillName, config);
269
-
232
+
270
233
  // Handle inheritance
271
234
  if (this.options.enableInheritance && skillConfig.inheritFrom) {
272
235
  const parentConfig = this.skillConfigs.get(skillConfig.inheritFrom);
@@ -302,7 +265,7 @@ class SkillToolsManager extends EventEmitter {
302
265
  */
303
266
  getAllowedTools(skillName, options = {}) {
304
267
  const config = this.skillConfigs.get(skillName);
305
-
268
+
306
269
  if (!config) {
307
270
  // Return default tools based on skill category
308
271
  return this._getDefaultToolsForSkill(skillName);
@@ -324,7 +287,7 @@ class SkillToolsManager extends EventEmitter {
324
287
  */
325
288
  _getDefaultToolsForSkill(skillName) {
326
289
  const lowerName = skillName.toLowerCase();
327
-
290
+
328
291
  for (const [category, tools] of Object.entries(DEFAULT_TOOL_SETS)) {
329
292
  if (lowerName.includes(category)) {
330
293
  return [...tools];
@@ -366,7 +329,7 @@ class SkillToolsManager extends EventEmitter {
366
329
  valid: missing.length === 0,
367
330
  available,
368
331
  missing,
369
- coverage: available.length / allowedTools.length
332
+ coverage: available.length / allowedTools.length,
370
333
  };
371
334
  }
372
335
 
@@ -385,22 +348,22 @@ class SkillToolsManager extends EventEmitter {
385
348
 
386
349
  if (context.readOnly) {
387
350
  // Remove write operations
388
- optimizedTools = optimizedTools.filter(t =>
389
- !t.includes('write') && !t.includes('create') && !t.includes('delete')
351
+ optimizedTools = optimizedTools.filter(
352
+ t => !t.includes('write') && !t.includes('create') && !t.includes('delete')
390
353
  );
391
354
  }
392
355
 
393
356
  if (context.noNetwork) {
394
357
  // Remove network operations
395
- optimizedTools = optimizedTools.filter(t =>
396
- !t.includes('http') && !t.includes('api') && !t.includes('fetch')
358
+ optimizedTools = optimizedTools.filter(
359
+ t => !t.includes('http') && !t.includes('api') && !t.includes('fetch')
397
360
  );
398
361
  }
399
362
 
400
363
  if (context.minimalPermissions) {
401
364
  // Keep only essential tools
402
- optimizedTools = optimizedTools.filter(t =>
403
- t.includes('read') || t.includes('search') || t.includes('list')
365
+ optimizedTools = optimizedTools.filter(
366
+ t => t.includes('read') || t.includes('search') || t.includes('list')
404
367
  );
405
368
  }
406
369
 
@@ -408,7 +371,7 @@ class SkillToolsManager extends EventEmitter {
408
371
  skillName,
409
372
  allowedTools: optimizedTools,
410
373
  restrictionLevel: config?.restrictionLevel || RestrictionLevel.STANDARD,
411
- context
374
+ context,
412
375
  };
413
376
  }
414
377
 
@@ -422,19 +385,19 @@ class SkillToolsManager extends EventEmitter {
422
385
 
423
386
  for (const skill of skills) {
424
387
  const skillName = skill.name || skill.id;
425
-
388
+
426
389
  // Determine category from skill metadata
427
390
  const category = this._detectSkillCategory(skill);
428
391
  const defaultTools = DEFAULT_TOOL_SETS[category] || DEFAULT_TOOL_SETS.validation;
429
392
 
430
393
  // Merge with explicitly defined tools
431
- const allowedTools = skill.allowedTools
394
+ const allowedTools = skill.allowedTools
432
395
  ? [...new Set([...defaultTools, ...skill.allowedTools])]
433
396
  : defaultTools;
434
397
 
435
398
  const config = this.setSkillConfig(skillName, {
436
399
  allowedTools,
437
- restrictionLevel: skill.restrictionLevel || RestrictionLevel.STANDARD
400
+ restrictionLevel: skill.restrictionLevel || RestrictionLevel.STANDARD,
438
401
  });
439
402
 
440
403
  configs.set(skillName, config);
@@ -448,7 +411,8 @@ class SkillToolsManager extends EventEmitter {
448
411
  * @private
449
412
  */
450
413
  _detectSkillCategory(skill) {
451
- const text = `${skill.name || ''} ${skill.description || ''} ${skill.purpose || ''}`.toLowerCase();
414
+ const text =
415
+ `${skill.name || ''} ${skill.description || ''} ${skill.purpose || ''}`.toLowerCase();
452
416
 
453
417
  const categoryKeywords = {
454
418
  requirements: ['requirement', 'ears', 'spec', 'feature'],
@@ -458,7 +422,7 @@ class SkillToolsManager extends EventEmitter {
458
422
  validation: ['validate', 'check', 'verify', 'lint'],
459
423
  documentation: ['document', 'readme', 'guide', 'doc'],
460
424
  analysis: ['analyze', 'audit', 'review', 'inspect'],
461
- deployment: ['deploy', 'release', 'publish', 'ci']
425
+ deployment: ['deploy', 'release', 'publish', 'ci'],
462
426
  };
463
427
 
464
428
  for (const [category, keywords] of Object.entries(categoryKeywords)) {
@@ -491,10 +455,10 @@ class SkillToolsManager extends EventEmitter {
491
455
  version: '1.0.0',
492
456
  exportedAt: new Date().toISOString(),
493
457
  defaults: {
494
- toolSet: this.options.defaultToolSet
458
+ toolSet: this.options.defaultToolSet,
495
459
  },
496
460
  toolDependencies,
497
- skills
461
+ skills,
498
462
  };
499
463
  }
500
464
 
@@ -535,7 +499,7 @@ class SkillToolsManager extends EventEmitter {
535
499
  */
536
500
  getStats() {
537
501
  const skills = Array.from(this.skillConfigs.values());
538
-
502
+
539
503
  const byRestriction = {};
540
504
  for (const level of Object.values(RestrictionLevel)) {
541
505
  byRestriction[level] = skills.filter(s => s.restrictionLevel === level).length;
@@ -552,7 +516,7 @@ class SkillToolsManager extends EventEmitter {
552
516
  totalSkills: this.skillConfigs.size,
553
517
  totalUniqueTools: allTools.size,
554
518
  availableTools: this.availableTools.size,
555
- byRestrictionLevel: byRestriction
519
+ byRestrictionLevel: byRestriction,
556
520
  };
557
521
  }
558
522
  }
@@ -561,5 +525,5 @@ module.exports = {
561
525
  SkillToolsManager,
562
526
  SkillToolConfig,
563
527
  RestrictionLevel,
564
- DEFAULT_TOOL_SETS
528
+ DEFAULT_TOOL_SETS,
565
529
  };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Workflow Engine for MUSUBI SDD
3
- *
3
+ *
4
4
  * Manages workflow state, stage transitions, and metrics collection.
5
5
  */
6
6
 
@@ -22,7 +22,7 @@ const WORKFLOW_STAGES = {
22
22
  testing: { next: ['deployment', 'implementation', 'requirements'] }, // Feedback loops
23
23
  deployment: { next: ['monitoring'] },
24
24
  monitoring: { next: ['retrospective'] },
25
- retrospective: { next: ['requirements'] } // New iteration
25
+ retrospective: { next: ['requirements'] }, // New iteration
26
26
  };
27
27
 
28
28
  /**
@@ -51,20 +51,20 @@ class WorkflowEngine {
51
51
  currentStage: options.startStage || 'requirements',
52
52
  startedAt: new Date().toISOString(),
53
53
  stages: {},
54
- history: []
54
+ history: [],
55
55
  };
56
56
 
57
57
  // Record initial stage
58
58
  state.stages[state.currentStage] = {
59
59
  enteredAt: new Date().toISOString(),
60
- status: 'in-progress'
60
+ status: 'in-progress',
61
61
  };
62
62
 
63
63
  state.history.push({
64
64
  timestamp: new Date().toISOString(),
65
65
  action: 'workflow-started',
66
66
  stage: state.currentStage,
67
- feature: featureName
67
+ feature: featureName,
68
68
  });
69
69
 
70
70
  await this.saveState(state);
@@ -77,7 +77,7 @@ class WorkflowEngine {
77
77
  * Get current workflow state
78
78
  */
79
79
  async getState() {
80
- if (!await fs.pathExists(this.stateFile)) {
80
+ if (!(await fs.pathExists(this.stateFile))) {
81
81
  return null;
82
82
  }
83
83
  const content = await fs.readFile(this.stateFile, 'utf8');
@@ -107,7 +107,7 @@ class WorkflowEngine {
107
107
  if (!validTransitions.includes(targetStage)) {
108
108
  throw new Error(
109
109
  `Invalid transition: ${currentStage} → ${targetStage}. ` +
110
- `Valid transitions: ${validTransitions.join(', ')}`
110
+ `Valid transitions: ${validTransitions.join(', ')}`
111
111
  );
112
112
  }
113
113
 
@@ -135,14 +135,14 @@ class WorkflowEngine {
135
135
  action: 'stage-transition',
136
136
  from: currentStage,
137
137
  to: targetStage,
138
- notes
138
+ notes,
139
139
  });
140
140
 
141
141
  await this.saveState(state);
142
142
  await this.recordMetric('stage_transition', {
143
143
  from: currentStage,
144
144
  to: targetStage,
145
- feature: state.feature
145
+ feature: state.feature,
146
146
  });
147
147
 
148
148
  return state;
@@ -160,7 +160,7 @@ class WorkflowEngine {
160
160
  action: 'feedback-loop',
161
161
  from: fromStage,
162
162
  to: toStage,
163
- reason
163
+ reason,
164
164
  });
165
165
 
166
166
  await this.saveState(state);
@@ -168,7 +168,7 @@ class WorkflowEngine {
168
168
  from: fromStage,
169
169
  to: toStage,
170
170
  reason,
171
- feature: state.feature
171
+ feature: state.feature,
172
172
  });
173
173
  }
174
174
 
@@ -194,14 +194,14 @@ class WorkflowEngine {
194
194
  state.history.push({
195
195
  timestamp: new Date().toISOString(),
196
196
  action: 'workflow-completed',
197
- notes
197
+ notes,
198
198
  });
199
199
 
200
200
  await this.saveState(state);
201
201
  await this.recordMetric('workflow_completed', {
202
202
  feature: state.feature,
203
203
  totalDuration: state.totalDuration,
204
- stageCount: Object.keys(state.stages).length
204
+ stageCount: Object.keys(state.stages).length,
205
205
  });
206
206
 
207
207
  // Generate summary
@@ -221,7 +221,7 @@ class WorkflowEngine {
221
221
  metrics.push({
222
222
  timestamp: new Date().toISOString(),
223
223
  name,
224
- data
224
+ data,
225
225
  });
226
226
 
227
227
  await fs.ensureDir(path.dirname(this.metricsFile));
@@ -232,7 +232,7 @@ class WorkflowEngine {
232
232
  * Get workflow metrics summary
233
233
  */
234
234
  async getMetricsSummary() {
235
- if (!await fs.pathExists(this.metricsFile)) {
235
+ if (!(await fs.pathExists(this.metricsFile))) {
236
236
  return { message: 'No metrics recorded yet.' };
237
237
  }
238
238
 
@@ -245,7 +245,7 @@ class WorkflowEngine {
245
245
  feedbackLoops: 0,
246
246
  stageTransitions: 0,
247
247
  averageDuration: null,
248
- stageStats: {}
248
+ stageStats: {},
249
249
  };
250
250
 
251
251
  const durations = [];
@@ -289,7 +289,7 @@ class WorkflowEngine {
289
289
  const stages = Object.entries(state.stages).map(([name, data]) => ({
290
290
  name,
291
291
  duration: data.duration || 'N/A',
292
- attempts: data.attempts || 1
292
+ attempts: data.attempts || 1,
293
293
  }));
294
294
 
295
295
  const feedbackLoops = state.history.filter(h => h.action === 'feedback-loop');
@@ -299,7 +299,7 @@ class WorkflowEngine {
299
299
  totalDuration: state.totalDuration,
300
300
  stages,
301
301
  feedbackLoops: feedbackLoops.length,
302
- feedbackDetails: feedbackLoops
302
+ feedbackDetails: feedbackLoops,
303
303
  };
304
304
  }
305
305
 
@@ -338,10 +338,18 @@ class WorkflowEngine {
338
338
  const value = parseInt(part);
339
339
  const unit = part.slice(-1);
340
340
  switch (unit) {
341
- case 'd': ms += value * 24 * 60 * 60 * 1000; break;
342
- case 'h': ms += value * 60 * 60 * 1000; break;
343
- case 'm': ms += value * 60 * 1000; break;
344
- case 's': ms += value * 1000; break;
341
+ case 'd':
342
+ ms += value * 24 * 60 * 60 * 1000;
343
+ break;
344
+ case 'h':
345
+ ms += value * 60 * 60 * 1000;
346
+ break;
347
+ case 'm':
348
+ ms += value * 60 * 1000;
349
+ break;
350
+ case 's':
351
+ ms += value * 1000;
352
+ break;
345
353
  }
346
354
  });
347
355
  return ms;