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
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * GroupChatPattern - Multi-skill collaborative discussion pattern
3
- *
3
+ *
4
4
  * Enables multiple skills to collaborate on a task through
5
5
  * iterative discussion and consensus building.
6
6
  */
@@ -12,18 +12,18 @@ const { PatternType, ExecutionContext, ExecutionStatus } = require('../orchestra
12
12
  * Discussion mode
13
13
  */
14
14
  const DiscussionMode = {
15
- ROUND_ROBIN: 'round-robin', // Each skill speaks in turn
16
- OPEN_FLOOR: 'open-floor', // Skills speak based on relevance
17
- MODERATED: 'moderated' // Moderator skill controls discussion
15
+ ROUND_ROBIN: 'round-robin', // Each skill speaks in turn
16
+ OPEN_FLOOR: 'open-floor', // Skills speak based on relevance
17
+ MODERATED: 'moderated', // Moderator skill controls discussion
18
18
  };
19
19
 
20
20
  /**
21
21
  * Consensus type
22
22
  */
23
23
  const ConsensusType = {
24
- UNANIMOUS: 'unanimous', // All must agree
25
- MAJORITY: 'majority', // 50%+ must agree
26
- FIRST_AGREEMENT: 'first' // First agreement wins
24
+ UNANIMOUS: 'unanimous', // All must agree
25
+ MAJORITY: 'majority', // 50%+ must agree
26
+ FIRST_AGREEMENT: 'first', // First agreement wins
27
27
  };
28
28
 
29
29
  /**
@@ -37,15 +37,10 @@ class GroupChatPattern extends BasePattern {
37
37
  description: 'Enable multi-skill collaborative discussion and consensus',
38
38
  version: '1.0.0',
39
39
  tags: ['collaboration', 'discussion', 'consensus', 'multi-agent'],
40
- useCases: [
41
- 'Design reviews',
42
- 'Code reviews',
43
- 'Decision making',
44
- 'Brainstorming'
45
- ],
40
+ useCases: ['Design reviews', 'Code reviews', 'Decision making', 'Brainstorming'],
46
41
  complexity: 'high',
47
42
  supportsParallel: false,
48
- requiresHuman: false
43
+ requiresHuman: false,
49
44
  });
50
45
 
51
46
  this.options = {
@@ -54,7 +49,7 @@ class GroupChatPattern extends BasePattern {
54
49
  maxRounds: options.maxRounds || 5,
55
50
  moderator: options.moderator || null,
56
51
  convergenceThreshold: options.convergenceThreshold || 0.8,
57
- ...options
52
+ ...options,
58
53
  };
59
54
  }
60
55
 
@@ -99,7 +94,7 @@ class GroupChatPattern extends BasePattern {
99
94
 
100
95
  return {
101
96
  valid: errors.length === 0,
102
- errors
97
+ errors,
103
98
  };
104
99
  }
105
100
 
@@ -125,7 +120,7 @@ class GroupChatPattern extends BasePattern {
125
120
  context,
126
121
  participants,
127
122
  topic,
128
- mode: this.options.mode
123
+ mode: this.options.mode,
129
124
  });
130
125
 
131
126
  try {
@@ -135,7 +130,7 @@ class GroupChatPattern extends BasePattern {
135
130
  engine.emit('groupChatRoundStarted', {
136
131
  context,
137
132
  round,
138
- maxRounds: this.options.maxRounds
133
+ maxRounds: this.options.maxRounds,
139
134
  });
140
135
 
141
136
  const roundResponses = await this._executeRound(
@@ -150,13 +145,13 @@ class GroupChatPattern extends BasePattern {
150
145
 
151
146
  transcript.push({
152
147
  round,
153
- responses: roundResponses
148
+ responses: roundResponses,
154
149
  });
155
150
 
156
151
  // Check for consensus
157
152
  const consensusResult = this._checkConsensus(roundResponses);
158
153
  consensusReached = consensusResult.reached;
159
-
154
+
160
155
  if (consensusReached) {
161
156
  finalDecision = consensusResult.decision;
162
157
  }
@@ -165,7 +160,7 @@ class GroupChatPattern extends BasePattern {
165
160
  context,
166
161
  round,
167
162
  responses: roundResponses,
168
- consensusReached
163
+ consensusReached,
169
164
  });
170
165
  }
171
166
 
@@ -176,7 +171,7 @@ class GroupChatPattern extends BasePattern {
176
171
  transcript,
177
172
  consensusReached,
178
173
  finalDecision,
179
- summary
174
+ summary,
180
175
  });
181
176
 
182
177
  return {
@@ -184,15 +179,14 @@ class GroupChatPattern extends BasePattern {
184
179
  rounds: round,
185
180
  consensusReached,
186
181
  finalDecision,
187
- summary
182
+ summary,
188
183
  };
189
-
190
184
  } catch (error) {
191
185
  engine.emit('groupChatFailed', {
192
186
  context,
193
187
  transcript,
194
188
  round,
195
- error
189
+ error,
196
190
  });
197
191
  throw error;
198
192
  }
@@ -202,13 +196,21 @@ class GroupChatPattern extends BasePattern {
202
196
  * Execute a single round of discussion
203
197
  * @private
204
198
  */
205
- async _executeRound(participants, topic, transcript, initialContext, parentContext, engine, round) {
199
+ async _executeRound(
200
+ participants,
201
+ topic,
202
+ transcript,
203
+ initialContext,
204
+ parentContext,
205
+ engine,
206
+ round
207
+ ) {
206
208
  const responses = [];
207
209
  const discussionContext = {
208
210
  topic,
209
211
  round,
210
212
  previousRounds: transcript,
211
- ...initialContext
213
+ ...initialContext,
212
214
  };
213
215
 
214
216
  for (const participant of participants) {
@@ -218,48 +220,43 @@ class GroupChatPattern extends BasePattern {
218
220
  input: {
219
221
  ...discussionContext,
220
222
  previousResponses: responses,
221
- role: 'participant'
223
+ role: 'participant',
222
224
  },
223
225
  parentId: parentContext.id,
224
226
  metadata: {
225
227
  pattern: PatternType.GROUP_CHAT,
226
228
  round,
227
- participant
228
- }
229
+ participant,
230
+ },
229
231
  });
230
232
 
231
233
  parentContext.children.push(stepContext);
232
234
 
233
235
  try {
234
236
  stepContext.start();
235
-
236
- const response = await engine.executeSkill(
237
- participant,
238
- stepContext.input,
239
- parentContext
240
- );
237
+
238
+ const response = await engine.executeSkill(participant, stepContext.input, parentContext);
241
239
 
242
240
  stepContext.complete(response);
243
241
 
244
242
  responses.push({
245
243
  participant,
246
244
  response,
247
- status: ExecutionStatus.COMPLETED
245
+ status: ExecutionStatus.COMPLETED,
248
246
  });
249
247
 
250
248
  engine.emit('groupChatResponse', {
251
249
  participant,
252
250
  round,
253
- response
251
+ response,
254
252
  });
255
-
256
253
  } catch (error) {
257
254
  stepContext.fail(error);
258
-
255
+
259
256
  responses.push({
260
257
  participant,
261
258
  error: error.message,
262
- status: ExecutionStatus.FAILED
259
+ status: ExecutionStatus.FAILED,
263
260
  });
264
261
  }
265
262
  }
@@ -272,21 +269,21 @@ class GroupChatPattern extends BasePattern {
272
269
  * @private
273
270
  */
274
271
  _checkConsensus(responses) {
275
- const validResponses = responses.filter(r =>
276
- r.status === ExecutionStatus.COMPLETED
277
- );
272
+ const validResponses = responses.filter(r => r.status === ExecutionStatus.COMPLETED);
278
273
 
279
274
  if (validResponses.length === 0) {
280
275
  return { reached: false, decision: null };
281
276
  }
282
277
 
283
278
  // Extract decisions from responses
284
- const decisions = validResponses.map(r => {
285
- if (r.response && typeof r.response === 'object') {
286
- return r.response.decision || r.response.recommendation || r.response.answer;
287
- }
288
- return r.response;
289
- }).filter(d => d !== undefined && d !== null);
279
+ const decisions = validResponses
280
+ .map(r => {
281
+ if (r.response && typeof r.response === 'object') {
282
+ return r.response.decision || r.response.recommendation || r.response.answer;
283
+ }
284
+ return r.response;
285
+ })
286
+ .filter(d => d !== undefined && d !== null);
290
287
 
291
288
  if (decisions.length === 0) {
292
289
  return { reached: false, decision: null };
@@ -295,9 +292,7 @@ class GroupChatPattern extends BasePattern {
295
292
  // Count votes for each decision
296
293
  const votes = {};
297
294
  for (const decision of decisions) {
298
- const key = typeof decision === 'object'
299
- ? JSON.stringify(decision)
300
- : String(decision);
295
+ const key = typeof decision === 'object' ? JSON.stringify(decision) : String(decision);
301
296
  votes[key] = (votes[key] || 0) + 1;
302
297
  }
303
298
 
@@ -317,30 +312,30 @@ class GroupChatPattern extends BasePattern {
317
312
 
318
313
  // Check consensus based on type
319
314
  const total = validResponses.length;
320
-
315
+
321
316
  switch (this.options.consensusType) {
322
317
  case ConsensusType.UNANIMOUS:
323
318
  return {
324
319
  reached: maxVotes === total,
325
- decision: maxVotes === total ? winningDecision : null
320
+ decision: maxVotes === total ? winningDecision : null,
326
321
  };
327
-
322
+
328
323
  case ConsensusType.MAJORITY:
329
324
  return {
330
325
  reached: maxVotes > total / 2,
331
- decision: maxVotes > total / 2 ? winningDecision : null
326
+ decision: maxVotes > total / 2 ? winningDecision : null,
332
327
  };
333
-
328
+
334
329
  case ConsensusType.FIRST_AGREEMENT:
335
330
  return {
336
331
  reached: maxVotes >= 2,
337
- decision: maxVotes >= 2 ? winningDecision : null
332
+ decision: maxVotes >= 2 ? winningDecision : null,
338
333
  };
339
-
334
+
340
335
  default:
341
336
  return {
342
337
  reached: maxVotes >= total * this.options.convergenceThreshold,
343
- decision: winningDecision
338
+ decision: winningDecision,
344
339
  };
345
340
  }
346
341
  }
@@ -371,9 +366,8 @@ class GroupChatPattern extends BasePattern {
371
366
  successfulResponses,
372
367
  failedResponses,
373
368
  consensusReached,
374
- successRate: totalResponses > 0
375
- ? (successfulResponses / totalResponses * 100).toFixed(1) + '%'
376
- : '0%'
369
+ successRate:
370
+ totalResponses > 0 ? ((successfulResponses / totalResponses) * 100).toFixed(1) + '%' : '0%',
377
371
  };
378
372
  }
379
373
  }
@@ -391,5 +385,5 @@ module.exports = {
391
385
  GroupChatPattern,
392
386
  DiscussionMode,
393
387
  ConsensusType,
394
- createGroupChatPattern
388
+ createGroupChatPattern,
395
389
  };
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * HandoffPattern - Agent delegation pattern
3
- *
3
+ *
4
4
  * Enables conversation control transfer between agents.
5
5
  * Implements OpenAI Agents SDK-style handoff mechanism for MUSUBI.
6
- *
6
+ *
7
7
  * @module orchestration/patterns/handoff
8
8
  * @version 1.0.0
9
9
  */
10
10
 
11
11
  const { BasePattern } = require('../pattern-registry');
12
- const { PatternType, ExecutionContext, ExecutionStatus } = require('../orchestration-engine');
12
+ const { PatternType, ExecutionContext, _ExecutionStatus } = require('../orchestration-engine');
13
13
 
14
14
  /**
15
15
  * Extended PatternType with HANDOFF
@@ -17,17 +17,17 @@ const { PatternType, ExecutionContext, ExecutionStatus } = require('../orchestra
17
17
  const HandoffPatternType = {
18
18
  ...PatternType,
19
19
  HANDOFF: 'handoff',
20
- TRIAGE: 'triage'
20
+ TRIAGE: 'triage',
21
21
  };
22
22
 
23
23
  /**
24
24
  * Handoff strategy options
25
25
  */
26
26
  const HandoffStrategy = {
27
- FIRST_MATCH: 'first-match', // Use first matching agent
28
- BEST_MATCH: 'best-match', // Use best scoring agent
29
- ROUND_ROBIN: 'round-robin', // Rotate through agents
30
- WEIGHTED: 'weighted' // Use weighted selection
27
+ FIRST_MATCH: 'first-match', // Use first matching agent
28
+ BEST_MATCH: 'best-match', // Use best scoring agent
29
+ ROUND_ROBIN: 'round-robin', // Rotate through agents
30
+ WEIGHTED: 'weighted', // Use weighted selection
31
31
  };
32
32
 
33
33
  /**
@@ -37,49 +37,51 @@ const HandoffFilters = {
37
37
  /**
38
38
  * Remove all tool calls from history
39
39
  */
40
- removeAllTools: (history) => {
40
+ removeAllTools: history => {
41
41
  return history.filter(msg => msg.type !== 'tool_call' && msg.type !== 'tool_result');
42
42
  },
43
43
 
44
44
  /**
45
45
  * Remove tool results only (keep calls)
46
46
  */
47
- removeToolResults: (history) => {
47
+ removeToolResults: history => {
48
48
  return history.filter(msg => msg.type !== 'tool_result');
49
49
  },
50
50
 
51
51
  /**
52
52
  * Keep only user messages
53
53
  */
54
- userMessagesOnly: (history) => {
54
+ userMessagesOnly: history => {
55
55
  return history.filter(msg => msg.role === 'user');
56
56
  },
57
57
 
58
58
  /**
59
59
  * Keep last N messages
60
60
  */
61
- lastN: (n) => (history) => {
61
+ lastN: n => history => {
62
62
  return history.slice(-n);
63
63
  },
64
64
 
65
65
  /**
66
66
  * Keep everything (no filter)
67
67
  */
68
- keepAll: (history) => history,
68
+ keepAll: history => history,
69
69
 
70
70
  /**
71
71
  * Summarize history to single message
72
72
  */
73
- summarize: (history) => {
73
+ summarize: history => {
74
74
  if (history.length === 0) return [];
75
- const summary = history.map(msg =>
76
- `[${msg.role || msg.type}]: ${msg.content?.substring(0, 100) || '...'}`
77
- ).join('\n');
78
- return [{
79
- role: 'system',
80
- content: `Previous conversation summary:\n${summary}`
81
- }];
82
- }
75
+ const summary = history
76
+ .map(msg => `[${msg.role || msg.type}]: ${msg.content?.substring(0, 100) || '...'}`)
77
+ .join('\n');
78
+ return [
79
+ {
80
+ role: 'system',
81
+ content: `Previous conversation summary:\n${summary}`,
82
+ },
83
+ ];
84
+ },
83
85
  };
84
86
 
85
87
  /**
@@ -102,7 +104,7 @@ class EscalationData {
102
104
  sourceAgent: this.sourceAgent,
103
105
  context: this.context,
104
106
  timestamp: this.timestamp.toISOString(),
105
- metadata: this.metadata
107
+ metadata: this.metadata,
106
108
  };
107
109
  }
108
110
  }
@@ -112,13 +114,13 @@ class EscalationData {
112
114
  */
113
115
  class HandoffConfig {
114
116
  constructor(options = {}) {
115
- this.agent = options.agent; // Target agent
117
+ this.agent = options.agent; // Target agent
116
118
  this.toolNameOverride = options.toolNameOverride || null;
117
119
  this.inputType = options.inputType || EscalationData;
118
120
  this.inputFilter = options.inputFilter || HandoffFilters.keepAll;
119
- this.onHandoff = options.onHandoff || null; // Callback when handoff occurs
120
- this.condition = options.condition || null; // Condition function
121
- this.priority = options.priority || 0; // Selection priority
121
+ this.onHandoff = options.onHandoff || null; // Callback when handoff occurs
122
+ this.condition = options.condition || null; // Condition function
123
+ this.priority = options.priority || 0; // Selection priority
122
124
  }
123
125
  }
124
126
 
@@ -151,12 +153,12 @@ class HandoffPattern extends BasePattern {
151
153
  'Escalation workflows',
152
154
  'Customer service routing',
153
155
  'Multi-expert consultation',
154
- 'Fallback handling'
156
+ 'Fallback handling',
155
157
  ],
156
158
  complexity: 'medium',
157
159
  supportsParallel: false,
158
160
  supportsReplanning: true,
159
- requiresHuman: false
161
+ requiresHuman: false,
160
162
  });
161
163
 
162
164
  this.options = {
@@ -167,7 +169,7 @@ class HandoffPattern extends BasePattern {
167
169
  inputFilter: options.inputFilter || HandoffFilters.keepAll,
168
170
  onHandoff: options.onHandoff || null,
169
171
  onHandoffComplete: options.onHandoffComplete || null,
170
- ...options
172
+ ...options,
171
173
  };
172
174
 
173
175
  // Track handoff chain
@@ -199,7 +201,7 @@ class HandoffPattern extends BasePattern {
199
201
  for (let i = 0; i < input.targetAgents.length; i++) {
200
202
  const target = input.targetAgents[i];
201
203
  const agent = target.agent || target;
202
-
204
+
203
205
  // Check if agent is a HandoffConfig or direct agent
204
206
  if (!agent) {
205
207
  errors.push(`Target agent ${i} is invalid`);
@@ -216,7 +218,7 @@ class HandoffPattern extends BasePattern {
216
218
 
217
219
  return {
218
220
  valid: errors.length === 0,
219
- errors
221
+ errors,
220
222
  };
221
223
  }
222
224
 
@@ -238,7 +240,7 @@ class HandoffPattern extends BasePattern {
238
240
  message,
239
241
  history = [],
240
242
  escalationData = null,
241
- sharedContext = {}
243
+ sharedContext = {},
242
244
  } = context.input;
243
245
 
244
246
  const startTime = Date.now();
@@ -248,7 +250,7 @@ class HandoffPattern extends BasePattern {
248
250
  context,
249
251
  sourceAgent: this._getAgentName(sourceAgent),
250
252
  targetAgents: targetAgents.map(t => this._getAgentName(t.agent || t)),
251
- escalationData
253
+ escalationData,
252
254
  });
253
255
 
254
256
  try {
@@ -256,33 +258,32 @@ class HandoffPattern extends BasePattern {
256
258
  engine.emit('handoff:selecting', {
257
259
  context,
258
260
  strategy: this.options.strategy,
259
- candidates: targetAgents.length
261
+ candidates: targetAgents.length,
260
262
  });
261
263
 
262
- const selectedTarget = await this.selectTargetAgent(
263
- context,
264
- targetAgents,
265
- engine
266
- );
264
+ const selectedTarget = await this.selectTargetAgent(context, targetAgents, engine);
267
265
 
268
266
  if (!selectedTarget) {
269
267
  throw new Error('No suitable target agent found for handoff');
270
268
  }
271
269
 
272
- const selectedConfig = selectedTarget instanceof HandoffConfig
273
- ? selectedTarget
274
- : new HandoffConfig({ agent: selectedTarget });
270
+ const selectedConfig =
271
+ selectedTarget instanceof HandoffConfig
272
+ ? selectedTarget
273
+ : new HandoffConfig({ agent: selectedTarget });
275
274
 
276
275
  // Step 2: Apply input filter to history
277
276
  const inputFilter = selectedConfig.inputFilter || this.options.inputFilter;
278
277
  const filteredHistory = inputFilter(history);
279
278
 
280
279
  // Step 3: Create escalation data if not provided
281
- const escalation = escalationData || new EscalationData({
282
- reason: context.input.reason || 'Agent handoff',
283
- sourceAgent: this._getAgentName(sourceAgent),
284
- context: sharedContext
285
- });
280
+ const escalation =
281
+ escalationData ||
282
+ new EscalationData({
283
+ reason: context.input.reason || 'Agent handoff',
284
+ sourceAgent: this._getAgentName(sourceAgent),
285
+ context: sharedContext,
286
+ });
286
287
 
287
288
  // Step 4: Execute onHandoff callback if provided
288
289
  if (selectedConfig.onHandoff) {
@@ -297,7 +298,7 @@ class HandoffPattern extends BasePattern {
297
298
  from: this._getAgentName(sourceAgent),
298
299
  to: this._getAgentName(selectedConfig.agent),
299
300
  reason: escalation.reason,
300
- timestamp: new Date()
301
+ timestamp: new Date(),
301
302
  });
302
303
 
303
304
  // Step 6: Perform handoff (execute target agent)
@@ -308,7 +309,7 @@ class HandoffPattern extends BasePattern {
308
309
  message,
309
310
  history: filteredHistory,
310
311
  escalation,
311
- sharedContext
312
+ sharedContext,
312
313
  },
313
314
  context,
314
315
  engine
@@ -328,7 +329,7 @@ class HandoffPattern extends BasePattern {
328
329
  targetAgent: this._getAgentName(selectedConfig.agent),
329
330
  result,
330
331
  duration: endTime - startTime,
331
- handoffChain: this.handoffChain
332
+ handoffChain: this.handoffChain,
332
333
  });
333
334
 
334
335
  return {
@@ -337,15 +338,14 @@ class HandoffPattern extends BasePattern {
337
338
  targetAgent: this._getAgentName(selectedConfig.agent),
338
339
  result,
339
340
  handoffChain: [...this.handoffChain],
340
- duration: endTime - startTime
341
+ duration: endTime - startTime,
341
342
  };
342
-
343
343
  } catch (error) {
344
344
  engine.emit('handoff:failed', {
345
345
  context,
346
346
  sourceAgent: this._getAgentName(sourceAgent),
347
347
  error: error.message,
348
- handoffChain: this.handoffChain
348
+ handoffChain: this.handoffChain,
349
349
  });
350
350
 
351
351
  throw error;
@@ -360,7 +360,7 @@ class HandoffPattern extends BasePattern {
360
360
  * @returns {Promise<HandoffConfig|Agent>} Selected agent
361
361
  */
362
362
  async selectTargetAgent(context, targetAgents, engine) {
363
- const { message, history, sharedContext } = context.input;
363
+ const { _message, _history, _sharedContext } = context.input;
364
364
 
365
365
  switch (this.options.strategy) {
366
366
  case HandoffStrategy.FIRST_MATCH:
@@ -385,8 +385,9 @@ class HandoffPattern extends BasePattern {
385
385
  */
386
386
  async _selectFirstMatch(targetAgents, context) {
387
387
  for (const target of targetAgents) {
388
- const config = target instanceof HandoffConfig ? target : new HandoffConfig({ agent: target });
389
-
388
+ const config =
389
+ target instanceof HandoffConfig ? target : new HandoffConfig({ agent: target });
390
+
390
391
  if (config.condition) {
391
392
  const matches = await config.condition(context);
392
393
  if (matches) return config;
@@ -400,13 +401,14 @@ class HandoffPattern extends BasePattern {
400
401
  /**
401
402
  * Select best matching agent based on scoring
402
403
  */
403
- async _selectBestMatch(targetAgents, context, engine) {
404
+ async _selectBestMatch(targetAgents, context, _engine) {
404
405
  let bestScore = -1;
405
406
  let bestTarget = null;
406
407
 
407
408
  for (const target of targetAgents) {
408
- const config = target instanceof HandoffConfig ? target : new HandoffConfig({ agent: target });
409
-
409
+ const config =
410
+ target instanceof HandoffConfig ? target : new HandoffConfig({ agent: target });
411
+
410
412
  let score = config.priority || 0;
411
413
 
412
414
  // If condition function exists, use it for scoring
@@ -473,7 +475,7 @@ class HandoffPattern extends BasePattern {
473
475
  */
474
476
  async performHandoff(source, target, handoffData, parentContext, engine) {
475
477
  const targetName = this._getAgentName(target);
476
-
478
+
477
479
  // Create child context for target execution
478
480
  const childContext = new ExecutionContext({
479
481
  parentId: parentContext.id,
@@ -485,12 +487,12 @@ class HandoffPattern extends BasePattern {
485
487
  escalation: handoffData.escalation?.toJSON?.() || handoffData.escalation,
486
488
  sharedContext: handoffData.sharedContext,
487
489
  isHandoff: true,
488
- sourceAgent: this._getAgentName(source)
490
+ sourceAgent: this._getAgentName(source),
489
491
  },
490
492
  metadata: {
491
493
  handoffChain: this.handoffChain,
492
- handoffDepth: this.handoffChain.length
493
- }
494
+ handoffDepth: this.handoffChain.length,
495
+ },
494
496
  });
495
497
 
496
498
  parentContext.children.push(childContext);
@@ -554,5 +556,5 @@ module.exports = {
554
556
  HandoffConfig,
555
557
  EscalationData,
556
558
  handoff,
557
- createHandoffPattern
559
+ createHandoffPattern,
558
560
  };