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
@@ -19,7 +19,7 @@ const PLAN_STATUS = {
19
19
  PAUSED: 'paused',
20
20
  COMPLETED: 'completed',
21
21
  FAILED: 'failed',
22
- CANCELLED: 'cancelled'
22
+ CANCELLED: 'cancelled',
23
23
  };
24
24
 
25
25
  /**
@@ -33,7 +33,7 @@ const TASK_STATUS = {
33
33
  BLOCKED: 'blocked',
34
34
  COMPLETED: 'completed',
35
35
  FAILED: 'failed',
36
- SKIPPED: 'skipped'
36
+ SKIPPED: 'skipped',
37
37
  };
38
38
 
39
39
  /**
@@ -45,7 +45,7 @@ const PRIORITY = {
45
45
  HIGH: 1,
46
46
  MEDIUM: 2,
47
47
  LOW: 3,
48
- OPTIONAL: 4
48
+ OPTIONAL: 4,
49
49
  };
50
50
 
51
51
  /**
@@ -96,19 +96,19 @@ class PlanningEngine extends EventEmitter {
96
96
  */
97
97
  constructor(options = {}) {
98
98
  super();
99
-
99
+
100
100
  this.maxTasks = options.maxTasks ?? 50;
101
101
  this.parallelExecution = options.parallelExecution ?? true;
102
102
  this.maxParallel = options.maxParallel ?? 4;
103
103
  this.adaptivePlanning = options.adaptivePlanning ?? true;
104
104
  this.replanThreshold = options.replanThreshold ?? 0.3;
105
-
105
+
106
106
  // State
107
107
  this.plans = new Map();
108
108
  this.activePlan = null;
109
109
  this.taskCounter = 0;
110
110
  }
111
-
111
+
112
112
  /**
113
113
  * Create a plan from a goal
114
114
  * @param {string} goal - High-level goal description
@@ -117,7 +117,7 @@ class PlanningEngine extends EventEmitter {
117
117
  */
118
118
  async createPlan(goal, context = {}) {
119
119
  const planId = this.generateId('plan');
120
-
120
+
121
121
  const plan = {
122
122
  id: planId,
123
123
  goal,
@@ -133,43 +133,43 @@ class PlanningEngine extends EventEmitter {
133
133
  failedTasks: 0,
134
134
  skippedTasks: 0,
135
135
  totalEstimatedTime: 0,
136
- actualTime: 0
137
- }
136
+ actualTime: 0,
137
+ },
138
138
  };
139
-
139
+
140
140
  this.emit('plan:creating', { planId, goal });
141
-
141
+
142
142
  // Decompose goal into tasks
143
143
  const tasks = await this.decomposeGoal(goal, context);
144
144
  plan.tasks = tasks;
145
145
  plan.metrics.totalTasks = tasks.length;
146
146
  plan.metrics.totalEstimatedTime = tasks.reduce((sum, t) => sum + t.estimatedTime, 0);
147
-
147
+
148
148
  // Optimize task order
149
149
  this.optimizeTaskOrder(plan);
150
-
150
+
151
151
  // Update status
152
152
  plan.status = PLAN_STATUS.READY;
153
-
153
+
154
154
  this.plans.set(planId, plan);
155
155
  this.emit('plan:created', { plan });
156
-
156
+
157
157
  return plan;
158
158
  }
159
-
159
+
160
160
  /**
161
161
  * Decompose goal into tasks
162
162
  * @private
163
163
  */
164
- async decomposeGoal(goal, context) {
164
+ async decomposeGoal(goal, _context) {
165
165
  const tasks = [];
166
-
166
+
167
167
  // Analyze goal for key components
168
168
  const components = this.analyzeGoal(goal);
169
-
169
+
170
170
  for (let i = 0; i < components.length; i++) {
171
171
  const component = components[i];
172
-
172
+
173
173
  const task = {
174
174
  id: this.generateId('task'),
175
175
  name: component.name,
@@ -183,21 +183,21 @@ class PlanningEngine extends EventEmitter {
183
183
  result: null,
184
184
  metadata: {
185
185
  component: component.type,
186
- index: i
187
- }
186
+ index: i,
187
+ },
188
188
  };
189
-
189
+
190
190
  // Add dependencies from previous tasks if sequential
191
191
  if (i > 0 && component.dependsOnPrevious !== false) {
192
192
  task.dependencies.push(tasks[i - 1].id);
193
193
  }
194
-
194
+
195
195
  tasks.push(task);
196
196
  }
197
-
197
+
198
198
  return tasks;
199
199
  }
200
-
200
+
201
201
  /**
202
202
  * Analyze goal to extract components
203
203
  * @private
@@ -205,7 +205,7 @@ class PlanningEngine extends EventEmitter {
205
205
  analyzeGoal(goal) {
206
206
  const components = [];
207
207
  const goalLower = goal.toLowerCase();
208
-
208
+
209
209
  // Pattern matching for common goal structures
210
210
  const patterns = [
211
211
  { keyword: 'create', type: 'creation', priority: PRIORITY.HIGH },
@@ -217,9 +217,9 @@ class PlanningEngine extends EventEmitter {
217
217
  { keyword: 'refactor', type: 'refactoring', priority: PRIORITY.MEDIUM },
218
218
  { keyword: 'document', type: 'documentation', priority: PRIORITY.LOW },
219
219
  { keyword: 'analyze', type: 'analysis', priority: PRIORITY.MEDIUM },
220
- { keyword: 'review', type: 'review', priority: PRIORITY.MEDIUM }
220
+ { keyword: 'review', type: 'review', priority: PRIORITY.MEDIUM },
221
221
  ];
222
-
222
+
223
223
  // Match patterns
224
224
  for (const pattern of patterns) {
225
225
  if (goalLower.includes(pattern.keyword)) {
@@ -228,11 +228,11 @@ class PlanningEngine extends EventEmitter {
228
228
  description: `${pattern.type} task for: ${goal.substring(0, 50)}`,
229
229
  type: pattern.type,
230
230
  priority: pattern.priority,
231
- estimatedTime: this.estimateTime(pattern.type)
231
+ estimatedTime: this.estimateTime(pattern.type),
232
232
  });
233
233
  }
234
234
  }
235
-
235
+
236
236
  // If no patterns matched, create generic decomposition
237
237
  if (components.length === 0) {
238
238
  components.push(
@@ -241,35 +241,35 @@ class PlanningEngine extends EventEmitter {
241
241
  description: 'Analyze requirements and context',
242
242
  type: 'analysis',
243
243
  priority: PRIORITY.HIGH,
244
- estimatedTime: 3000
244
+ estimatedTime: 3000,
245
245
  },
246
246
  {
247
247
  name: 'Planning',
248
248
  description: 'Create detailed implementation plan',
249
249
  type: 'planning',
250
250
  priority: PRIORITY.HIGH,
251
- estimatedTime: 2000
251
+ estimatedTime: 2000,
252
252
  },
253
253
  {
254
254
  name: 'Execution',
255
255
  description: 'Execute the main task',
256
256
  type: 'execution',
257
257
  priority: PRIORITY.HIGH,
258
- estimatedTime: 10000
258
+ estimatedTime: 10000,
259
259
  },
260
260
  {
261
261
  name: 'Validation',
262
262
  description: 'Validate results and quality',
263
263
  type: 'validation',
264
264
  priority: PRIORITY.MEDIUM,
265
- estimatedTime: 3000
265
+ estimatedTime: 3000,
266
266
  }
267
267
  );
268
268
  }
269
-
269
+
270
270
  return components;
271
271
  }
272
-
272
+
273
273
  /**
274
274
  * Estimate time for task type
275
275
  * @private
@@ -285,12 +285,12 @@ class PlanningEngine extends EventEmitter {
285
285
  refactoring: 15000,
286
286
  documentation: 5000,
287
287
  analysis: 5000,
288
- review: 6000
288
+ review: 6000,
289
289
  };
290
-
290
+
291
291
  return estimates[type] || 10000;
292
292
  }
293
-
293
+
294
294
  /**
295
295
  * Optimize task order based on dependencies and priorities
296
296
  * @private
@@ -300,15 +300,15 @@ class PlanningEngine extends EventEmitter {
300
300
  const sorted = [];
301
301
  const visited = new Set();
302
302
  const visiting = new Set();
303
-
304
- const visit = (taskId) => {
303
+
304
+ const visit = taskId => {
305
305
  if (visited.has(taskId)) return;
306
306
  if (visiting.has(taskId)) {
307
307
  throw new Error(`Circular dependency detected for task ${taskId}`);
308
308
  }
309
-
309
+
310
310
  visiting.add(taskId);
311
-
311
+
312
312
  const task = plan.tasks.find(t => t.id === taskId);
313
313
  if (task) {
314
314
  for (const depId of task.dependencies) {
@@ -317,18 +317,18 @@ class PlanningEngine extends EventEmitter {
317
317
  visited.add(taskId);
318
318
  sorted.push(task);
319
319
  }
320
-
320
+
321
321
  visiting.delete(taskId);
322
322
  };
323
-
323
+
324
324
  // Sort by priority first, then visit
325
325
  const byPriority = [...plan.tasks].sort((a, b) => a.priority - b.priority);
326
326
  for (const task of byPriority) {
327
327
  visit(task.id);
328
328
  }
329
-
329
+
330
330
  plan.tasks = sorted;
331
-
331
+
332
332
  // Update ready status for tasks with no dependencies
333
333
  for (const task of plan.tasks) {
334
334
  if (task.dependencies.length === 0) {
@@ -336,7 +336,7 @@ class PlanningEngine extends EventEmitter {
336
336
  }
337
337
  }
338
338
  }
339
-
339
+
340
340
  /**
341
341
  * Execute a plan
342
342
  * @param {string} planId - Plan identifier
@@ -349,38 +349,37 @@ class PlanningEngine extends EventEmitter {
349
349
  if (plan.status === PLAN_STATUS.EXECUTING) {
350
350
  throw new Error('Plan is already executing');
351
351
  }
352
-
352
+
353
353
  plan.status = PLAN_STATUS.EXECUTING;
354
354
  plan.startedAt = Date.now();
355
355
  this.activePlan = plan;
356
-
356
+
357
357
  this.emit('plan:executing', { planId });
358
-
358
+
359
359
  try {
360
360
  if (this.parallelExecution) {
361
361
  await this.executeParallel(plan, executor);
362
362
  } else {
363
363
  await this.executeSequential(plan, executor);
364
364
  }
365
-
365
+
366
366
  // Determine final status
367
367
  const hasFailures = plan.tasks.some(t => t.status === TASK_STATUS.FAILED);
368
368
  plan.status = hasFailures ? PLAN_STATUS.FAILED : PLAN_STATUS.COMPLETED;
369
-
370
369
  } catch (error) {
371
370
  plan.status = PLAN_STATUS.FAILED;
372
371
  this.emit('plan:error', { planId, error: error.message });
373
372
  }
374
-
373
+
375
374
  plan.completedAt = Date.now();
376
375
  plan.metrics.actualTime = plan.completedAt - plan.startedAt;
377
376
  this.activePlan = null;
378
-
377
+
379
378
  this.emit('plan:completed', { plan });
380
-
379
+
381
380
  return plan;
382
381
  }
383
-
382
+
384
383
  /**
385
384
  * Execute tasks sequentially
386
385
  * @private
@@ -388,31 +387,31 @@ class PlanningEngine extends EventEmitter {
388
387
  async executeSequential(plan, executor) {
389
388
  for (const task of plan.tasks) {
390
389
  if (task.status === TASK_STATUS.SKIPPED) continue;
391
-
390
+
392
391
  // Check dependencies
393
392
  const blocked = task.dependencies.some(depId => {
394
393
  const dep = plan.tasks.find(t => t.id === depId);
395
394
  return dep && dep.status === TASK_STATUS.FAILED;
396
395
  });
397
-
396
+
398
397
  if (blocked) {
399
398
  task.status = TASK_STATUS.SKIPPED;
400
399
  plan.metrics.skippedTasks++;
401
400
  continue;
402
401
  }
403
-
402
+
404
403
  await this.executeTask(task, executor, plan);
405
404
  }
406
405
  }
407
-
406
+
408
407
  /**
409
408
  * Execute tasks in parallel where possible
410
409
  * @private
411
410
  */
412
411
  async executeParallel(plan, executor) {
413
412
  const completed = new Set();
414
-
415
- while (true) {
413
+
414
+ for (;;) {
416
415
  // Find tasks that are ready to execute
417
416
  const ready = plan.tasks.filter(task => {
418
417
  if (task.status !== TASK_STATUS.READY && task.status !== TASK_STATUS.PENDING) {
@@ -421,16 +420,17 @@ class PlanningEngine extends EventEmitter {
421
420
  // Check all dependencies are completed
422
421
  return task.dependencies.every(depId => completed.has(depId));
423
422
  });
424
-
423
+
425
424
  if (ready.length === 0) {
426
425
  // No more tasks ready - check if we're done
427
- const remaining = plan.tasks.filter(t =>
428
- t.status === TASK_STATUS.PENDING ||
429
- t.status === TASK_STATUS.READY ||
430
- t.status === TASK_STATUS.IN_PROGRESS
426
+ const remaining = plan.tasks.filter(
427
+ t =>
428
+ t.status === TASK_STATUS.PENDING ||
429
+ t.status === TASK_STATUS.READY ||
430
+ t.status === TASK_STATUS.IN_PROGRESS
431
431
  );
432
432
  if (remaining.length === 0) break;
433
-
433
+
434
434
  // Check for blocked tasks (dependencies failed)
435
435
  for (const task of remaining) {
436
436
  const hasFailed = task.dependencies.some(depId => {
@@ -444,14 +444,16 @@ class PlanningEngine extends EventEmitter {
444
444
  }
445
445
  break;
446
446
  }
447
-
447
+
448
448
  // Execute batch of ready tasks
449
449
  const batch = ready.slice(0, this.maxParallel);
450
- await Promise.all(batch.map(async (task) => {
451
- await this.executeTask(task, executor, plan);
452
- completed.add(task.id);
453
- }));
454
-
450
+ await Promise.all(
451
+ batch.map(async task => {
452
+ await this.executeTask(task, executor, plan);
453
+ completed.add(task.id);
454
+ })
455
+ );
456
+
455
457
  // Mark newly ready tasks
456
458
  for (const task of plan.tasks) {
457
459
  if (task.status === TASK_STATUS.PENDING) {
@@ -463,7 +465,7 @@ class PlanningEngine extends EventEmitter {
463
465
  }
464
466
  }
465
467
  }
466
-
468
+
467
469
  /**
468
470
  * Execute a single task
469
471
  * @private
@@ -471,33 +473,32 @@ class PlanningEngine extends EventEmitter {
471
473
  async executeTask(task, executor, plan) {
472
474
  task.status = TASK_STATUS.IN_PROGRESS;
473
475
  const startTime = Date.now();
474
-
476
+
475
477
  this.emit('task:start', { taskId: task.id, planId: plan.id, task });
476
-
478
+
477
479
  try {
478
480
  const result = await executor(task);
479
481
  task.result = result;
480
482
  task.status = TASK_STATUS.COMPLETED;
481
483
  plan.metrics.completedTasks++;
482
-
484
+
483
485
  this.emit('task:complete', { taskId: task.id, planId: plan.id, result });
484
-
486
+
485
487
  // Check for replanning
486
488
  if (this.adaptivePlanning) {
487
489
  await this.checkReplan(plan, task);
488
490
  }
489
-
490
491
  } catch (error) {
491
492
  task.result = { error: error.message };
492
493
  task.status = TASK_STATUS.FAILED;
493
494
  plan.metrics.failedTasks++;
494
-
495
+
495
496
  this.emit('task:error', { taskId: task.id, planId: plan.id, error: error.message });
496
497
  }
497
-
498
+
498
499
  task.actualTime = Date.now() - startTime;
499
500
  }
500
-
501
+
501
502
  /**
502
503
  * Check if replanning is needed
503
504
  * @private
@@ -505,21 +506,23 @@ class PlanningEngine extends EventEmitter {
505
506
  async checkReplan(plan, completedTask) {
506
507
  // Calculate deviation from estimates
507
508
  if (!completedTask.actualTime || !completedTask.estimatedTime) return;
508
-
509
- const deviation = Math.abs(completedTask.actualTime - completedTask.estimatedTime) / completedTask.estimatedTime;
510
-
509
+
510
+ const deviation =
511
+ Math.abs(completedTask.actualTime - completedTask.estimatedTime) /
512
+ completedTask.estimatedTime;
513
+
511
514
  if (deviation > this.replanThreshold) {
512
- this.emit('plan:replan-trigger', {
513
- planId: plan.id,
514
- taskId: completedTask.id,
515
- deviation
515
+ this.emit('plan:replan-trigger', {
516
+ planId: plan.id,
517
+ taskId: completedTask.id,
518
+ deviation,
516
519
  });
517
-
520
+
518
521
  // Adjust estimates for remaining tasks
519
- const remaining = plan.tasks.filter(t =>
520
- t.status === TASK_STATUS.PENDING || t.status === TASK_STATUS.READY
522
+ const remaining = plan.tasks.filter(
523
+ t => t.status === TASK_STATUS.PENDING || t.status === TASK_STATUS.READY
521
524
  );
522
-
525
+
523
526
  for (const task of remaining) {
524
527
  if (task.metadata.component === completedTask.metadata.component) {
525
528
  // Adjust based on actual vs estimated ratio
@@ -529,7 +532,7 @@ class PlanningEngine extends EventEmitter {
529
532
  }
530
533
  }
531
534
  }
532
-
535
+
533
536
  /**
534
537
  * Pause plan execution
535
538
  * @param {string} planId - Plan identifier
@@ -537,13 +540,13 @@ class PlanningEngine extends EventEmitter {
537
540
  pausePlan(planId) {
538
541
  const plan = this.plans.get(planId);
539
542
  if (!plan) throw new Error(`Plan ${planId} not found`);
540
-
543
+
541
544
  if (plan.status === PLAN_STATUS.EXECUTING) {
542
545
  plan.status = PLAN_STATUS.PAUSED;
543
546
  this.emit('plan:paused', { planId });
544
547
  }
545
548
  }
546
-
549
+
547
550
  /**
548
551
  * Resume plan execution
549
552
  * @param {string} planId - Plan identifier
@@ -553,15 +556,15 @@ class PlanningEngine extends EventEmitter {
553
556
  async resumePlan(planId, executor) {
554
557
  const plan = this.plans.get(planId);
555
558
  if (!plan) throw new Error(`Plan ${planId} not found`);
556
-
559
+
557
560
  if (plan.status !== PLAN_STATUS.PAUSED) {
558
561
  throw new Error('Plan is not paused');
559
562
  }
560
-
563
+
561
564
  this.emit('plan:resuming', { planId });
562
565
  return this.executePlan(planId, executor);
563
566
  }
564
-
567
+
565
568
  /**
566
569
  * Cancel plan execution
567
570
  * @param {string} planId - Plan identifier
@@ -569,10 +572,10 @@ class PlanningEngine extends EventEmitter {
569
572
  cancelPlan(planId) {
570
573
  const plan = this.plans.get(planId);
571
574
  if (!plan) throw new Error(`Plan ${planId} not found`);
572
-
575
+
573
576
  plan.status = PLAN_STATUS.CANCELLED;
574
577
  plan.completedAt = Date.now();
575
-
578
+
576
579
  // Mark pending tasks as skipped
577
580
  for (const task of plan.tasks) {
578
581
  if (task.status === TASK_STATUS.PENDING || task.status === TASK_STATUS.READY) {
@@ -580,10 +583,10 @@ class PlanningEngine extends EventEmitter {
580
583
  plan.metrics.skippedTasks++;
581
584
  }
582
585
  }
583
-
586
+
584
587
  this.emit('plan:cancelled', { planId });
585
588
  }
586
-
589
+
587
590
  /**
588
591
  * Add task to existing plan
589
592
  * @param {string} planId - Plan identifier
@@ -593,7 +596,7 @@ class PlanningEngine extends EventEmitter {
593
596
  addTask(planId, taskDef) {
594
597
  const plan = this.plans.get(planId);
595
598
  if (!plan) throw new Error(`Plan ${planId} not found`);
596
-
599
+
597
600
  const task = {
598
601
  id: this.generateId('task'),
599
602
  name: taskDef.name,
@@ -605,9 +608,9 @@ class PlanningEngine extends EventEmitter {
605
608
  estimatedTime: taskDef.estimatedTime || 5000,
606
609
  actualTime: null,
607
610
  result: null,
608
- metadata: taskDef.metadata || {}
611
+ metadata: taskDef.metadata || {},
609
612
  };
610
-
613
+
611
614
  // Insert at appropriate position based on dependencies
612
615
  if (taskDef.after) {
613
616
  const afterIndex = plan.tasks.findIndex(t => t.id === taskDef.after);
@@ -620,15 +623,15 @@ class PlanningEngine extends EventEmitter {
620
623
  } else {
621
624
  plan.tasks.push(task);
622
625
  }
623
-
626
+
624
627
  plan.metrics.totalTasks++;
625
628
  plan.metrics.totalEstimatedTime += task.estimatedTime;
626
-
629
+
627
630
  this.emit('task:added', { planId, task });
628
-
631
+
629
632
  return task;
630
633
  }
631
-
634
+
632
635
  /**
633
636
  * Remove task from plan
634
637
  * @param {string} planId - Plan identifier
@@ -637,24 +640,24 @@ class PlanningEngine extends EventEmitter {
637
640
  removeTask(planId, taskId) {
638
641
  const plan = this.plans.get(planId);
639
642
  if (!plan) throw new Error(`Plan ${planId} not found`);
640
-
643
+
641
644
  const index = plan.tasks.findIndex(t => t.id === taskId);
642
645
  if (index < 0) throw new Error(`Task ${taskId} not found`);
643
-
646
+
644
647
  const task = plan.tasks[index];
645
-
648
+
646
649
  // Remove from other tasks' dependencies
647
650
  for (const t of plan.tasks) {
648
651
  t.dependencies = t.dependencies.filter(d => d !== taskId);
649
652
  }
650
-
653
+
651
654
  plan.tasks.splice(index, 1);
652
655
  plan.metrics.totalTasks--;
653
656
  plan.metrics.totalEstimatedTime -= task.estimatedTime;
654
-
657
+
655
658
  this.emit('task:removed', { planId, taskId });
656
659
  }
657
-
660
+
658
661
  /**
659
662
  * Get plan by ID
660
663
  * @param {string} planId - Plan identifier
@@ -663,7 +666,7 @@ class PlanningEngine extends EventEmitter {
663
666
  getPlan(planId) {
664
667
  return this.plans.get(planId) || null;
665
668
  }
666
-
669
+
667
670
  /**
668
671
  * Get all plans
669
672
  * @returns {Plan[]}
@@ -671,7 +674,7 @@ class PlanningEngine extends EventEmitter {
671
674
  getAllPlans() {
672
675
  return Array.from(this.plans.values());
673
676
  }
674
-
677
+
675
678
  /**
676
679
  * Get plan progress
677
680
  * @param {string} planId - Plan identifier
@@ -680,14 +683,14 @@ class PlanningEngine extends EventEmitter {
680
683
  getProgress(planId) {
681
684
  const plan = this.plans.get(planId);
682
685
  if (!plan) return null;
683
-
686
+
684
687
  const total = plan.metrics.totalTasks;
685
688
  const completed = plan.metrics.completedTasks;
686
689
  const failed = plan.metrics.failedTasks;
687
690
  const skipped = plan.metrics.skippedTasks;
688
691
  const inProgress = plan.tasks.filter(t => t.status === TASK_STATUS.IN_PROGRESS).length;
689
692
  const pending = total - completed - failed - skipped - inProgress;
690
-
693
+
691
694
  return {
692
695
  total,
693
696
  completed,
@@ -698,10 +701,10 @@ class PlanningEngine extends EventEmitter {
698
701
  percentage: total > 0 ? Math.round((completed / total) * 100) : 0,
699
702
  estimatedRemaining: plan.tasks
700
703
  .filter(t => t.status === TASK_STATUS.PENDING || t.status === TASK_STATUS.READY)
701
- .reduce((sum, t) => sum + t.estimatedTime, 0)
704
+ .reduce((sum, t) => sum + t.estimatedTime, 0),
702
705
  };
703
706
  }
704
-
707
+
705
708
  /**
706
709
  * Get dependency graph
707
710
  * @param {string} planId - Plan identifier
@@ -710,24 +713,24 @@ class PlanningEngine extends EventEmitter {
710
713
  getDependencyGraph(planId) {
711
714
  const plan = this.plans.get(planId);
712
715
  if (!plan) return null;
713
-
716
+
714
717
  const nodes = plan.tasks.map(t => ({
715
718
  id: t.id,
716
719
  name: t.name,
717
720
  status: t.status,
718
- priority: t.priority
721
+ priority: t.priority,
719
722
  }));
720
-
723
+
721
724
  const edges = [];
722
725
  for (const task of plan.tasks) {
723
726
  for (const dep of task.dependencies) {
724
727
  edges.push({ from: dep, to: task.id });
725
728
  }
726
729
  }
727
-
730
+
728
731
  return { nodes, edges };
729
732
  }
730
-
733
+
731
734
  /**
732
735
  * Generate unique ID
733
736
  * @private
@@ -735,7 +738,7 @@ class PlanningEngine extends EventEmitter {
735
738
  generateId(prefix) {
736
739
  return `${prefix}-${++this.taskCounter}-${Date.now().toString(36)}`;
737
740
  }
738
-
741
+
739
742
  /**
740
743
  * Clear all plans
741
744
  */
@@ -744,7 +747,7 @@ class PlanningEngine extends EventEmitter {
744
747
  this.activePlan = null;
745
748
  this.taskCounter = 0;
746
749
  }
747
-
750
+
748
751
  /**
749
752
  * Export plan to readable format
750
753
  * @param {string} planId - Plan identifier
@@ -753,14 +756,14 @@ class PlanningEngine extends EventEmitter {
753
756
  exportPlan(planId) {
754
757
  const plan = this.plans.get(planId);
755
758
  if (!plan) return '';
756
-
759
+
757
760
  let output = `# Plan: ${plan.goal}\n\n`;
758
761
  output += `**ID:** ${plan.id}\n`;
759
762
  output += `**Status:** ${plan.status}\n`;
760
763
  output += `**Created:** ${new Date(plan.createdAt).toISOString()}\n\n`;
761
-
764
+
762
765
  output += `## Tasks (${plan.metrics.totalTasks})\n\n`;
763
-
766
+
764
767
  for (let i = 0; i < plan.tasks.length; i++) {
765
768
  const task = plan.tasks[i];
766
769
  const statusIcon = this.getStatusIcon(task.status);
@@ -771,7 +774,7 @@ class PlanningEngine extends EventEmitter {
771
774
  }
772
775
  output += `\n`;
773
776
  }
774
-
777
+
775
778
  output += `## Metrics\n\n`;
776
779
  output += `- Completed: ${plan.metrics.completedTasks}\n`;
777
780
  output += `- Failed: ${plan.metrics.failedTasks}\n`;
@@ -779,10 +782,10 @@ class PlanningEngine extends EventEmitter {
779
782
  if (plan.metrics.actualTime) {
780
783
  output += `- Total Time: ${plan.metrics.actualTime}ms\n`;
781
784
  }
782
-
785
+
783
786
  return output;
784
787
  }
785
-
788
+
786
789
  /**
787
790
  * Get status icon
788
791
  * @private
@@ -795,7 +798,7 @@ class PlanningEngine extends EventEmitter {
795
798
  [TASK_STATUS.BLOCKED]: '🚫',
796
799
  [TASK_STATUS.COMPLETED]: '✅',
797
800
  [TASK_STATUS.FAILED]: '❌',
798
- [TASK_STATUS.SKIPPED]: '⏭️'
801
+ [TASK_STATUS.SKIPPED]: '⏭️',
799
802
  };
800
803
  return icons[status] || '•';
801
804
  }
@@ -827,5 +830,5 @@ module.exports = {
827
830
  createPlan,
828
831
  PLAN_STATUS,
829
832
  TASK_STATUS,
830
- PRIORITY
833
+ PRIORITY,
831
834
  };