musubi-sdd 5.0.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 +164 -145
  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 +247 -125
  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 +83 -80
  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 +53 -44
  87. package/src/monitoring/incident-manager.js +123 -103
  88. package/src/monitoring/index.js +144 -134
  89. package/src/monitoring/observability.js +82 -59
  90. package/src/monitoring/quality-dashboard.js +51 -39
  91. package/src/monitoring/release-manager.js +70 -50
  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
@@ -2,7 +2,7 @@
2
2
  * @file steering-auto-update.js
3
3
  * @description Automatic steering file update engine
4
4
  * @version 1.0.0
5
- *
5
+ *
6
6
  * Part of MUSUBI v5.0.0 - Phase 5 Advanced Features
7
7
  */
8
8
 
@@ -22,7 +22,7 @@ const TRIGGER = {
22
22
  DEPENDENCY_UPDATE: 'dependency-update',
23
23
  CONFIG_CHANGE: 'config-change',
24
24
  MANUAL: 'manual',
25
- SCHEDULED: 'scheduled'
25
+ SCHEDULED: 'scheduled',
26
26
  };
27
27
 
28
28
  /**
@@ -34,7 +34,7 @@ const STEERING_TYPE = {
34
34
  TECH: 'tech',
35
35
  PRODUCT: 'product',
36
36
  RULES: 'rules',
37
- CUSTOM: 'custom'
37
+ CUSTOM: 'custom',
38
38
  };
39
39
 
40
40
  /**
@@ -76,10 +76,10 @@ const DEFAULT_RULES = [
76
76
  trigger: TRIGGER.DEPENDENCY_UPDATE,
77
77
  target: STEERING_TYPE.TECH,
78
78
  priority: 10,
79
- condition: (context) => context.packageJsonChanged,
79
+ condition: context => context.packageJsonChanged,
80
80
  update: async (steering, context) => {
81
81
  const changes = [];
82
-
82
+
83
83
  if (context.newDependencies?.length > 0) {
84
84
  changes.push(`Added dependencies: ${context.newDependencies.join(', ')}`);
85
85
  }
@@ -89,9 +89,9 @@ const DEFAULT_RULES = [
89
89
  if (context.updatedDependencies?.length > 0) {
90
90
  changes.push(`Updated dependencies: ${context.updatedDependencies.join(', ')}`);
91
91
  }
92
-
92
+
93
93
  return { section: 'dependencies', changes };
94
- }
94
+ },
95
95
  },
96
96
  {
97
97
  id: 'structure-dirs-update',
@@ -99,11 +99,11 @@ const DEFAULT_RULES = [
99
99
  trigger: TRIGGER.CODE_CHANGE,
100
100
  target: STEERING_TYPE.STRUCTURE,
101
101
  priority: 5,
102
- condition: (context) => context.newDirectories?.length > 0,
102
+ condition: context => context.newDirectories?.length > 0,
103
103
  update: async (steering, context) => {
104
104
  const changes = context.newDirectories.map(dir => `Added directory: ${dir}`);
105
105
  return { section: 'directories', changes };
106
- }
106
+ },
107
107
  },
108
108
  {
109
109
  id: 'structure-files-update',
@@ -111,7 +111,7 @@ const DEFAULT_RULES = [
111
111
  trigger: TRIGGER.CODE_CHANGE,
112
112
  target: STEERING_TYPE.STRUCTURE,
113
113
  priority: 4,
114
- condition: (context) => context.significantFileChanges,
114
+ condition: context => context.significantFileChanges,
115
115
  update: async (steering, context) => {
116
116
  const changes = [];
117
117
  if (context.newEntryPoints?.length > 0) {
@@ -121,7 +121,7 @@ const DEFAULT_RULES = [
121
121
  changes.push(`New modules: ${context.newModules.join(', ')}`);
122
122
  }
123
123
  return { section: 'files', changes };
124
- }
124
+ },
125
125
  },
126
126
  {
127
127
  id: 'product-features-update',
@@ -129,14 +129,14 @@ const DEFAULT_RULES = [
129
129
  trigger: TRIGGER.AGENT_WORK,
130
130
  target: STEERING_TYPE.PRODUCT,
131
131
  priority: 8,
132
- condition: (context) => context.featureCompleted,
132
+ condition: context => context.featureCompleted,
133
133
  update: async (steering, context) => {
134
134
  const changes = [`Completed feature: ${context.featureName}`];
135
135
  if (context.featureDescription) {
136
136
  changes.push(`Description: ${context.featureDescription}`);
137
137
  }
138
138
  return { section: 'features', changes };
139
- }
139
+ },
140
140
  },
141
141
  {
142
142
  id: 'rules-patterns-update',
@@ -144,12 +144,12 @@ const DEFAULT_RULES = [
144
144
  trigger: TRIGGER.AGENT_WORK,
145
145
  target: STEERING_TYPE.RULES,
146
146
  priority: 3,
147
- condition: (context) => context.newPatterns?.length > 0,
147
+ condition: context => context.newPatterns?.length > 0,
148
148
  update: async (steering, context) => {
149
149
  const changes = context.newPatterns.map(p => `New pattern: ${p}`);
150
150
  return { section: 'patterns', changes };
151
- }
152
- }
151
+ },
152
+ },
153
153
  ];
154
154
 
155
155
  /**
@@ -163,22 +163,22 @@ class SteeringAutoUpdate extends EventEmitter {
163
163
  */
164
164
  constructor(options = {}) {
165
165
  super();
166
-
166
+
167
167
  this.steeringPath = options.steeringPath || 'steering';
168
168
  this.autoSave = options.autoSave !== false;
169
169
  this.backup = options.backup !== false;
170
170
  this.rules = [...DEFAULT_RULES, ...(options.rules || [])];
171
-
171
+
172
172
  // Sort rules by priority
173
173
  this.rules.sort((a, b) => (b.priority || 0) - (a.priority || 0));
174
-
174
+
175
175
  // State
176
176
  this.updates = new Map();
177
177
  this.updateCounter = 0;
178
178
  this.steering = new Map();
179
179
  this.pendingChanges = new Map();
180
180
  }
181
-
181
+
182
182
  /**
183
183
  * Load steering files
184
184
  * @param {string} [basePath='.'] - Base path
@@ -186,14 +186,14 @@ class SteeringAutoUpdate extends EventEmitter {
186
186
  */
187
187
  async loadSteering(basePath = '.') {
188
188
  const steeringDir = path.join(basePath, this.steeringPath);
189
-
189
+
190
190
  const files = {
191
191
  [STEERING_TYPE.STRUCTURE]: 'structure.md',
192
192
  [STEERING_TYPE.TECH]: 'tech.md',
193
193
  [STEERING_TYPE.PRODUCT]: 'product.md',
194
- [STEERING_TYPE.RULES]: 'rules/constitution.md'
194
+ [STEERING_TYPE.RULES]: 'rules/constitution.md',
195
195
  };
196
-
196
+
197
197
  for (const [type, file] of Object.entries(files)) {
198
198
  const filePath = path.join(steeringDir, file);
199
199
  try {
@@ -203,14 +203,14 @@ class SteeringAutoUpdate extends EventEmitter {
203
203
  path: filePath,
204
204
  content,
205
205
  parsed: this.parseMarkdown(content),
206
- lastModified: fs.statSync(filePath).mtime
206
+ lastModified: fs.statSync(filePath).mtime,
207
207
  });
208
208
  }
209
209
  } catch (error) {
210
210
  this.emit('error', { type, file, error });
211
211
  }
212
212
  }
213
-
213
+
214
214
  // Load custom steering files
215
215
  const customDir = path.join(steeringDir, 'custom');
216
216
  if (fs.existsSync(customDir)) {
@@ -222,15 +222,15 @@ class SteeringAutoUpdate extends EventEmitter {
222
222
  path: filePath,
223
223
  content,
224
224
  parsed: this.parseMarkdown(content),
225
- lastModified: fs.statSync(filePath).mtime
225
+ lastModified: fs.statSync(filePath).mtime,
226
226
  });
227
227
  }
228
228
  }
229
-
229
+
230
230
  this.emit('steering:loaded', { count: this.steering.size });
231
231
  return this.steering;
232
232
  }
233
-
233
+
234
234
  /**
235
235
  * Parse markdown into sections
236
236
  * @private
@@ -240,7 +240,7 @@ class SteeringAutoUpdate extends EventEmitter {
240
240
  const lines = content.split('\n');
241
241
  let currentSection = 'header';
242
242
  let currentContent = [];
243
-
243
+
244
244
  for (const line of lines) {
245
245
  const headerMatch = line.match(/^(#{1,6})\s+(.+)$/);
246
246
  if (headerMatch) {
@@ -254,15 +254,15 @@ class SteeringAutoUpdate extends EventEmitter {
254
254
  currentContent.push(line);
255
255
  }
256
256
  }
257
-
257
+
258
258
  // Save last section
259
259
  if (currentContent.length > 0) {
260
260
  sections.set(currentSection, currentContent.join('\n'));
261
261
  }
262
-
262
+
263
263
  return sections;
264
264
  }
265
-
265
+
266
266
  /**
267
267
  * Process an update trigger
268
268
  * @param {string} trigger - Trigger type
@@ -272,9 +272,9 @@ class SteeringAutoUpdate extends EventEmitter {
272
272
  async processTrigger(trigger, context = {}) {
273
273
  const id = this.generateId();
274
274
  this.emit('trigger:received', { id, trigger, context });
275
-
275
+
276
276
  const results = [];
277
-
277
+
278
278
  // Find applicable rules
279
279
  const applicableRules = this.rules.filter(rule => {
280
280
  if (rule.trigger !== trigger) return false;
@@ -285,20 +285,20 @@ class SteeringAutoUpdate extends EventEmitter {
285
285
  return false;
286
286
  }
287
287
  });
288
-
288
+
289
289
  // Apply each rule
290
290
  for (const rule of applicableRules) {
291
291
  try {
292
292
  this.emit('rule:applying', { rule: rule.id, target: rule.target });
293
-
293
+
294
294
  const steering = this.steering.get(rule.target);
295
295
  if (!steering) {
296
296
  this.emit('rule:skipped', { rule: rule.id, reason: 'target not found' });
297
297
  continue;
298
298
  }
299
-
299
+
300
300
  const updateResult = await rule.update(steering, context);
301
-
301
+
302
302
  if (updateResult && updateResult.changes?.length > 0) {
303
303
  // Queue changes
304
304
  if (!this.pendingChanges.has(rule.target)) {
@@ -308,9 +308,9 @@ class SteeringAutoUpdate extends EventEmitter {
308
308
  rule: rule.id,
309
309
  section: updateResult.section,
310
310
  changes: updateResult.changes,
311
- timestamp: Date.now()
311
+ timestamp: Date.now(),
312
312
  });
313
-
313
+
314
314
  const result = {
315
315
  id: `update-${++this.updateCounter}`,
316
316
  success: true,
@@ -318,12 +318,12 @@ class SteeringAutoUpdate extends EventEmitter {
318
318
  trigger,
319
319
  rule: rule.id,
320
320
  changes: updateResult.changes,
321
- timestamp: Date.now()
321
+ timestamp: Date.now(),
322
322
  };
323
-
323
+
324
324
  results.push(result);
325
325
  this.updates.set(result.id, result);
326
-
326
+
327
327
  this.emit('rule:applied', { rule: rule.id, changes: updateResult.changes });
328
328
  }
329
329
  } catch (error) {
@@ -334,77 +334,74 @@ class SteeringAutoUpdate extends EventEmitter {
334
334
  trigger,
335
335
  rule: rule.id,
336
336
  error: error.message,
337
- timestamp: Date.now()
337
+ timestamp: Date.now(),
338
338
  };
339
-
339
+
340
340
  results.push(result);
341
341
  this.emit('rule:failed', { rule: rule.id, error });
342
342
  }
343
343
  }
344
-
344
+
345
345
  // Auto-save if enabled
346
346
  if (this.autoSave && results.some(r => r.success)) {
347
347
  await this.applyPendingChanges();
348
348
  }
349
-
349
+
350
350
  this.emit('trigger:processed', { id, results });
351
351
  return results;
352
352
  }
353
-
353
+
354
354
  /**
355
355
  * Apply pending changes to files
356
356
  * @returns {Promise<Object>} Apply result
357
357
  */
358
358
  async applyPendingChanges() {
359
359
  const applied = [];
360
-
360
+
361
361
  for (const [target, changes] of this.pendingChanges.entries()) {
362
362
  const steering = this.steering.get(target);
363
363
  if (!steering) continue;
364
-
364
+
365
365
  try {
366
366
  // Create backup
367
367
  if (this.backup) {
368
368
  const backupPath = `${steering.path}.backup`;
369
369
  fs.writeFileSync(backupPath, steering.content);
370
370
  }
371
-
371
+
372
372
  // Generate changelog section
373
373
  const changelog = this.generateChangelog(changes);
374
-
374
+
375
375
  // Update content
376
376
  let newContent = steering.content;
377
-
377
+
378
378
  // Add or update changelog section
379
379
  if (newContent.includes('## Changelog')) {
380
- newContent = newContent.replace(
381
- /## Changelog\n/,
382
- `## Changelog\n\n${changelog}\n`
383
- );
380
+ newContent = newContent.replace(/## Changelog\n/, `## Changelog\n\n${changelog}\n`);
384
381
  } else {
385
382
  newContent += `\n\n## Changelog\n\n${changelog}`;
386
383
  }
387
-
384
+
388
385
  // Write file
389
386
  fs.writeFileSync(steering.path, newContent);
390
-
387
+
391
388
  // Update in-memory state
392
389
  steering.content = newContent;
393
390
  steering.parsed = this.parseMarkdown(newContent);
394
391
  steering.lastModified = new Date();
395
-
392
+
396
393
  applied.push({ target, changesCount: changes.length });
397
-
394
+
398
395
  this.emit('changes:applied', { target, changes });
399
396
  } catch (error) {
400
397
  this.emit('changes:failed', { target, error });
401
398
  }
402
399
  }
403
-
400
+
404
401
  this.pendingChanges.clear();
405
402
  return { applied };
406
403
  }
407
-
404
+
408
405
  /**
409
406
  * Generate changelog entry
410
407
  * @private
@@ -412,16 +409,16 @@ class SteeringAutoUpdate extends EventEmitter {
412
409
  generateChangelog(changes) {
413
410
  const date = new Date().toISOString().split('T')[0];
414
411
  const entries = [];
415
-
412
+
416
413
  for (const change of changes) {
417
414
  for (const item of change.changes) {
418
415
  entries.push(`- ${item}`);
419
416
  }
420
417
  }
421
-
418
+
422
419
  return `### ${date}\n${entries.join('\n')}`;
423
420
  }
424
-
421
+
425
422
  /**
426
423
  * Add custom rule
427
424
  * @param {UpdateRule} rule - Rule to add
@@ -430,13 +427,13 @@ class SteeringAutoUpdate extends EventEmitter {
430
427
  if (!rule.id || !rule.trigger || !rule.target) {
431
428
  throw new Error('Rule must have id, trigger, and target');
432
429
  }
433
-
430
+
434
431
  this.rules.push(rule);
435
432
  this.rules.sort((a, b) => (b.priority || 0) - (a.priority || 0));
436
-
433
+
437
434
  this.emit('rule:added', { ruleId: rule.id });
438
435
  }
439
-
436
+
440
437
  /**
441
438
  * Remove rule
442
439
  * @param {string} ruleId - Rule ID to remove
@@ -448,7 +445,7 @@ class SteeringAutoUpdate extends EventEmitter {
448
445
  this.emit('rule:removed', { ruleId });
449
446
  }
450
447
  }
451
-
448
+
452
449
  /**
453
450
  * Get update history
454
451
  * @param {Object} [filter={}] - Filter options
@@ -456,7 +453,7 @@ class SteeringAutoUpdate extends EventEmitter {
456
453
  */
457
454
  getHistory(filter = {}) {
458
455
  let results = Array.from(this.updates.values());
459
-
456
+
460
457
  if (filter.trigger) {
461
458
  results = results.filter(r => r.trigger === filter.trigger);
462
459
  }
@@ -466,17 +463,17 @@ class SteeringAutoUpdate extends EventEmitter {
466
463
  if (filter.success !== undefined) {
467
464
  results = results.filter(r => r.success === filter.success);
468
465
  }
469
-
466
+
470
467
  return results.sort((a, b) => b.timestamp - a.timestamp);
471
468
  }
472
-
469
+
473
470
  /**
474
471
  * Get statistics
475
472
  * @returns {Object}
476
473
  */
477
474
  getStats() {
478
475
  const updates = Array.from(this.updates.values());
479
-
476
+
480
477
  return {
481
478
  totalUpdates: updates.length,
482
479
  successful: updates.filter(u => u.success).length,
@@ -487,10 +484,10 @@ class SteeringAutoUpdate extends EventEmitter {
487
484
  }, {}),
488
485
  rulesCount: this.rules.length,
489
486
  steeringFilesLoaded: this.steering.size,
490
- pendingChanges: this.pendingChanges.size
487
+ pendingChanges: this.pendingChanges.size,
491
488
  };
492
489
  }
493
-
490
+
494
491
  /**
495
492
  * Generate unique ID
496
493
  * @private
@@ -498,47 +495,47 @@ class SteeringAutoUpdate extends EventEmitter {
498
495
  generateId() {
499
496
  return `trigger-${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 6)}`;
500
497
  }
501
-
498
+
502
499
  /**
503
500
  * Clear history
504
501
  */
505
502
  clearHistory() {
506
503
  this.updates.clear();
507
504
  }
508
-
505
+
509
506
  /**
510
507
  * Validate steering consistency
511
508
  * @returns {Object} Validation result
512
509
  */
513
510
  validateConsistency() {
514
511
  const issues = [];
515
-
512
+
516
513
  // Check cross-file references
517
514
  const structure = this.steering.get(STEERING_TYPE.STRUCTURE);
518
515
  const tech = this.steering.get(STEERING_TYPE.TECH);
519
-
516
+
520
517
  if (structure && tech) {
521
518
  // Check if tech references match structure
522
519
  const structureDirs = this.extractDirectories(structure.content);
523
520
  const techDirs = this.extractDirectories(tech.content);
524
-
521
+
525
522
  for (const dir of techDirs) {
526
523
  if (!structureDirs.includes(dir)) {
527
524
  issues.push({
528
525
  type: 'mismatch',
529
526
  file: STEERING_TYPE.TECH,
530
- message: `Directory "${dir}" referenced in tech.md but not in structure.md`
527
+ message: `Directory "${dir}" referenced in tech.md but not in structure.md`,
531
528
  });
532
529
  }
533
530
  }
534
531
  }
535
-
532
+
536
533
  return {
537
534
  valid: issues.length === 0,
538
- issues
535
+ issues,
539
536
  };
540
537
  }
541
-
538
+
542
539
  /**
543
540
  * Extract directories from content
544
541
  * @private
@@ -568,5 +565,5 @@ module.exports = {
568
565
  createSteeringAutoUpdate,
569
566
  TRIGGER,
570
567
  STEERING_TYPE,
571
- DEFAULT_RULES
568
+ DEFAULT_RULES,
572
569
  };