musubi-sdd 3.0.1 → 3.5.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 (49) hide show
  1. package/bin/musubi-change.js +623 -10
  2. package/bin/musubi-orchestrate.js +456 -0
  3. package/bin/musubi-trace.js +393 -0
  4. package/package.json +3 -2
  5. package/src/analyzers/impact-analyzer.js +682 -0
  6. package/src/integrations/cicd.js +782 -0
  7. package/src/integrations/documentation.js +740 -0
  8. package/src/integrations/examples.js +789 -0
  9. package/src/integrations/index.js +23 -0
  10. package/src/integrations/platforms.js +929 -0
  11. package/src/managers/delta-spec.js +484 -0
  12. package/src/monitoring/incident-manager.js +890 -0
  13. package/src/monitoring/index.js +633 -0
  14. package/src/monitoring/observability.js +938 -0
  15. package/src/monitoring/release-manager.js +622 -0
  16. package/src/orchestration/index.js +168 -0
  17. package/src/orchestration/orchestration-engine.js +409 -0
  18. package/src/orchestration/pattern-registry.js +319 -0
  19. package/src/orchestration/patterns/auto.js +386 -0
  20. package/src/orchestration/patterns/group-chat.js +395 -0
  21. package/src/orchestration/patterns/human-in-loop.js +506 -0
  22. package/src/orchestration/patterns/nested.js +322 -0
  23. package/src/orchestration/patterns/sequential.js +278 -0
  24. package/src/orchestration/patterns/swarm.js +395 -0
  25. package/src/orchestration/workflow-orchestrator.js +738 -0
  26. package/src/reporters/coverage-report.js +452 -0
  27. package/src/reporters/traceability-matrix-report.js +684 -0
  28. package/src/steering/advanced-validation.js +812 -0
  29. package/src/steering/auto-updater.js +670 -0
  30. package/src/steering/index.js +119 -0
  31. package/src/steering/quality-metrics.js +650 -0
  32. package/src/steering/template-constraints.js +789 -0
  33. package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +22 -0
  34. package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +21 -0
  35. package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +90 -28
  36. package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +32 -0
  37. package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +27 -0
  38. package/src/templates/agents/claude-code/skills/steering/SKILL.md +30 -0
  39. package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +21 -0
  40. package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +27 -0
  41. package/src/templates/agents/codex/AGENTS.md +36 -1
  42. package/src/templates/agents/cursor/AGENTS.md +36 -1
  43. package/src/templates/agents/gemini-cli/GEMINI.md +36 -1
  44. package/src/templates/agents/github-copilot/AGENTS.md +65 -1
  45. package/src/templates/agents/qwen-code/QWEN.md +36 -1
  46. package/src/templates/agents/windsurf/AGENTS.md +36 -1
  47. package/src/templates/shared/delta-spec-template.md +246 -0
  48. package/src/validators/delta-format.js +474 -0
  49. package/src/validators/traceability-validator.js +561 -0
@@ -0,0 +1,322 @@
1
+ /**
2
+ * NestedPattern - Hierarchical skill delegation pattern
3
+ *
4
+ * Executes tasks by delegating to sub-skills in a hierarchical manner.
5
+ * Each skill can spawn child tasks creating a tree-like execution structure.
6
+ */
7
+
8
+ const { BasePattern } = require('../pattern-registry');
9
+ const { PatternType, ExecutionContext, ExecutionStatus } = require('../orchestration-engine');
10
+
11
+ /**
12
+ * Nested execution mode
13
+ */
14
+ const NestedMode = {
15
+ DEPTH_FIRST: 'depth-first',
16
+ BREADTH_FIRST: 'breadth-first'
17
+ };
18
+
19
+ /**
20
+ * NestedPattern - Hierarchical task delegation
21
+ */
22
+ class NestedPattern extends BasePattern {
23
+ constructor(options = {}) {
24
+ super({
25
+ name: PatternType.NESTED,
26
+ type: PatternType.NESTED,
27
+ description: 'Execute tasks hierarchically, delegating to sub-skills',
28
+ version: '1.0.0',
29
+ tags: ['hierarchical', 'delegation', 'decomposition'],
30
+ useCases: [
31
+ 'Complex task breakdown',
32
+ 'Hierarchical processing',
33
+ 'Multi-level delegation'
34
+ ],
35
+ complexity: 'high',
36
+ supportsParallel: false,
37
+ requiresHuman: false
38
+ });
39
+
40
+ this.options = {
41
+ maxDepth: options.maxDepth || 5,
42
+ mode: options.mode || NestedMode.DEPTH_FIRST,
43
+ allowSelfDelegation: options.allowSelfDelegation || false,
44
+ aggregateResults: options.aggregateResults || true,
45
+ ...options
46
+ };
47
+ }
48
+
49
+ /**
50
+ * Validate the execution context
51
+ * @param {ExecutionContext} context - Execution context
52
+ * @param {OrchestrationEngine} engine - Orchestration engine
53
+ * @returns {object} Validation result
54
+ */
55
+ validate(context, engine) {
56
+ const errors = [];
57
+ const input = context.input;
58
+
59
+ // Check for root skill or task
60
+ if (!input.rootSkill && !input.task) {
61
+ errors.push('Nested pattern requires input.rootSkill or input.task');
62
+ }
63
+
64
+ // Check root skill exists
65
+ if (input.rootSkill && !engine.getSkill(input.rootSkill)) {
66
+ errors.push(`Unknown root skill: ${input.rootSkill}`);
67
+ }
68
+
69
+ // Check delegation map if provided
70
+ if (input.delegationMap) {
71
+ for (const [parent, children] of Object.entries(input.delegationMap)) {
72
+ if (!engine.getSkill(parent)) {
73
+ errors.push(`Unknown skill in delegation map: ${parent}`);
74
+ }
75
+ for (const child of children) {
76
+ if (!engine.getSkill(child)) {
77
+ errors.push(`Unknown child skill: ${child}`);
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ return {
84
+ valid: errors.length === 0,
85
+ errors
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Execute nested pattern
91
+ * @param {ExecutionContext} context - Execution context
92
+ * @param {OrchestrationEngine} engine - Orchestration engine
93
+ * @returns {Promise<object>} Execution result
94
+ */
95
+ async execute(context, engine) {
96
+ const validation = this.validate(context, engine);
97
+ if (!validation.valid) {
98
+ throw new Error(`Validation failed: ${validation.errors.join(', ')}`);
99
+ }
100
+
101
+ const { rootSkill, task, delegationMap = {}, initialInput = {} } = context.input;
102
+
103
+ engine.emit('nestedStarted', {
104
+ context,
105
+ rootSkill,
106
+ delegationMap
107
+ });
108
+
109
+ // Determine root skill from task if not provided
110
+ let actualRootSkill = rootSkill;
111
+ if (!actualRootSkill && task) {
112
+ actualRootSkill = await engine.resolveSkill(task);
113
+ if (!actualRootSkill) {
114
+ throw new Error(`Cannot resolve skill for task: ${task}`);
115
+ }
116
+ }
117
+
118
+ const executionTree = {
119
+ skill: actualRootSkill,
120
+ children: [],
121
+ output: null,
122
+ status: ExecutionStatus.PENDING,
123
+ depth: 0
124
+ };
125
+
126
+ try {
127
+ await this._executeNode(
128
+ executionTree,
129
+ initialInput,
130
+ delegationMap,
131
+ context,
132
+ engine,
133
+ 0
134
+ );
135
+
136
+ const aggregatedResult = this.options.aggregateResults
137
+ ? this._aggregateResults(executionTree)
138
+ : executionTree;
139
+
140
+ engine.emit('nestedCompleted', {
141
+ context,
142
+ tree: executionTree,
143
+ aggregatedResult
144
+ });
145
+
146
+ return {
147
+ tree: executionTree,
148
+ aggregatedResult,
149
+ summary: this._createSummary(executionTree)
150
+ };
151
+
152
+ } catch (error) {
153
+ engine.emit('nestedFailed', {
154
+ context,
155
+ tree: executionTree,
156
+ error
157
+ });
158
+ throw error;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Execute a single node in the tree
164
+ * @private
165
+ */
166
+ async _executeNode(node, input, delegationMap, parentContext, engine, depth) {
167
+ if (depth >= this.options.maxDepth) {
168
+ node.status = ExecutionStatus.FAILED;
169
+ node.error = `Max depth (${this.options.maxDepth}) exceeded`;
170
+ return;
171
+ }
172
+
173
+ const stepContext = new ExecutionContext({
174
+ task: `Nested: ${node.skill} (depth: ${depth})`,
175
+ skill: node.skill,
176
+ input,
177
+ parentId: parentContext.id,
178
+ metadata: {
179
+ pattern: PatternType.NESTED,
180
+ depth,
181
+ hasChildren: delegationMap[node.skill]?.length > 0
182
+ }
183
+ });
184
+
185
+ parentContext.children.push(stepContext);
186
+
187
+ engine.emit('nestedNodeStarted', {
188
+ node,
189
+ depth,
190
+ stepContext
191
+ });
192
+
193
+ try {
194
+ stepContext.start();
195
+ node.status = ExecutionStatus.RUNNING;
196
+
197
+ // Execute the skill
198
+ const output = await engine.executeSkill(node.skill, input, parentContext);
199
+ node.output = output;
200
+ stepContext.complete(output);
201
+
202
+ // Check for child skills to delegate to
203
+ const childSkills = delegationMap[node.skill] || [];
204
+
205
+ if (childSkills.length > 0) {
206
+ for (const childSkill of childSkills) {
207
+ // Skip self-delegation unless allowed
208
+ if (!this.options.allowSelfDelegation && childSkill === node.skill) {
209
+ continue;
210
+ }
211
+
212
+ const childNode = {
213
+ skill: childSkill,
214
+ children: [],
215
+ output: null,
216
+ status: ExecutionStatus.PENDING,
217
+ depth: depth + 1
218
+ };
219
+ node.children.push(childNode);
220
+
221
+ // Use parent output as child input
222
+ await this._executeNode(
223
+ childNode,
224
+ output,
225
+ delegationMap,
226
+ parentContext,
227
+ engine,
228
+ depth + 1
229
+ );
230
+ }
231
+ }
232
+
233
+ node.status = ExecutionStatus.COMPLETED;
234
+
235
+ engine.emit('nestedNodeCompleted', {
236
+ node,
237
+ depth,
238
+ output
239
+ });
240
+
241
+ } catch (error) {
242
+ node.status = ExecutionStatus.FAILED;
243
+ node.error = error.message;
244
+ stepContext.fail(error);
245
+
246
+ engine.emit('nestedNodeFailed', {
247
+ node,
248
+ depth,
249
+ error
250
+ });
251
+
252
+ throw error;
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Aggregate results from tree
258
+ * @private
259
+ */
260
+ _aggregateResults(node) {
261
+ const result = {
262
+ skill: node.skill,
263
+ output: node.output,
264
+ childOutputs: []
265
+ };
266
+
267
+ for (const child of node.children) {
268
+ result.childOutputs.push(this._aggregateResults(child));
269
+ }
270
+
271
+ return result;
272
+ }
273
+
274
+ /**
275
+ * Create execution summary
276
+ * @private
277
+ */
278
+ _createSummary(tree) {
279
+ let totalNodes = 0;
280
+ let completed = 0;
281
+ let failed = 0;
282
+ let maxDepth = 0;
283
+
284
+ const traverse = (node) => {
285
+ totalNodes++;
286
+ if (node.status === ExecutionStatus.COMPLETED) completed++;
287
+ if (node.status === ExecutionStatus.FAILED) failed++;
288
+ if (node.depth > maxDepth) maxDepth = node.depth;
289
+
290
+ for (const child of node.children) {
291
+ traverse(child);
292
+ }
293
+ };
294
+
295
+ traverse(tree);
296
+
297
+ return {
298
+ totalNodes,
299
+ completed,
300
+ failed,
301
+ maxDepth,
302
+ successRate: totalNodes > 0
303
+ ? (completed / totalNodes * 100).toFixed(1) + '%'
304
+ : '0%'
305
+ };
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Create a nested pattern with custom options
311
+ * @param {object} options - Pattern options
312
+ * @returns {NestedPattern} Nested pattern instance
313
+ */
314
+ function createNestedPattern(options = {}) {
315
+ return new NestedPattern(options);
316
+ }
317
+
318
+ module.exports = {
319
+ NestedPattern,
320
+ NestedMode,
321
+ createNestedPattern
322
+ };
@@ -0,0 +1,278 @@
1
+ /**
2
+ * SequentialPattern - Linear skill execution pattern
3
+ *
4
+ * Executes skills in sequence, passing output from one skill
5
+ * as input to the next. Supports error handling and recovery.
6
+ */
7
+
8
+ const { BasePattern } = require('../pattern-registry');
9
+ const { PatternType, ExecutionContext, ExecutionStatus } = require('../orchestration-engine');
10
+
11
+ /**
12
+ * Sequential execution options
13
+ */
14
+ const SequentialOptions = {
15
+ STOP_ON_ERROR: 'stop-on-error',
16
+ CONTINUE_ON_ERROR: 'continue-on-error',
17
+ RETRY_ON_ERROR: 'retry-on-error'
18
+ };
19
+
20
+ /**
21
+ * SequentialPattern - Execute skills one after another
22
+ */
23
+ class SequentialPattern extends BasePattern {
24
+ constructor(options = {}) {
25
+ super({
26
+ name: PatternType.SEQUENTIAL,
27
+ type: PatternType.SEQUENTIAL,
28
+ description: 'Execute skills in sequence, passing output as input to next skill',
29
+ version: '1.0.0',
30
+ tags: ['linear', 'pipeline', 'workflow'],
31
+ useCases: [
32
+ 'Step-by-step workflows',
33
+ 'Data transformation pipelines',
34
+ 'Dependent task chains'
35
+ ],
36
+ complexity: 'low',
37
+ supportsParallel: false,
38
+ requiresHuman: false
39
+ });
40
+
41
+ this.options = {
42
+ errorHandling: options.errorHandling || SequentialOptions.STOP_ON_ERROR,
43
+ maxRetries: options.maxRetries || 3,
44
+ retryDelay: options.retryDelay || 1000,
45
+ transformOutput: options.transformOutput || ((output, context) => output),
46
+ ...options
47
+ };
48
+ }
49
+
50
+ /**
51
+ * Validate the execution context
52
+ * @param {ExecutionContext} context - Execution context
53
+ * @param {OrchestrationEngine} engine - Orchestration engine
54
+ * @returns {object} Validation result
55
+ */
56
+ validate(context, engine) {
57
+ const errors = [];
58
+ const input = context.input;
59
+
60
+ // Check for skills array
61
+ if (!input.skills || !Array.isArray(input.skills)) {
62
+ errors.push('Sequential pattern requires input.skills array');
63
+ } else if (input.skills.length === 0) {
64
+ errors.push('Sequential pattern requires at least one skill');
65
+ } else {
66
+ // Validate each skill exists
67
+ for (const skillName of input.skills) {
68
+ if (!engine.getSkill(skillName)) {
69
+ errors.push(`Unknown skill: ${skillName}`);
70
+ }
71
+ }
72
+ }
73
+
74
+ return {
75
+ valid: errors.length === 0,
76
+ errors
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Execute skills sequentially
82
+ * @param {ExecutionContext} context - Execution context
83
+ * @param {OrchestrationEngine} engine - Orchestration engine
84
+ * @returns {Promise<object>} Execution result
85
+ */
86
+ async execute(context, engine) {
87
+ const validation = this.validate(context, engine);
88
+ if (!validation.valid) {
89
+ throw new Error(`Validation failed: ${validation.errors.join(', ')}`);
90
+ }
91
+
92
+ const { skills, initialInput = {} } = context.input;
93
+ const results = [];
94
+ let currentInput = { ...initialInput };
95
+ let lastOutput = null;
96
+
97
+ engine.emit('sequentialStarted', {
98
+ context,
99
+ skills,
100
+ totalSteps: skills.length
101
+ });
102
+
103
+ for (let i = 0; i < skills.length; i++) {
104
+ const skillName = skills[i];
105
+ const stepContext = new ExecutionContext({
106
+ task: `Step ${i + 1}: ${skillName}`,
107
+ skill: skillName,
108
+ input: currentInput,
109
+ parentId: context.id,
110
+ metadata: {
111
+ stepIndex: i,
112
+ totalSteps: skills.length,
113
+ pattern: PatternType.SEQUENTIAL
114
+ }
115
+ });
116
+
117
+ context.children.push(stepContext);
118
+
119
+ engine.emit('sequentialStepStarted', {
120
+ context,
121
+ stepContext,
122
+ stepIndex: i,
123
+ skillName
124
+ });
125
+
126
+ try {
127
+ stepContext.start();
128
+
129
+ const output = await this._executeWithRetry(
130
+ () => engine.executeSkill(skillName, currentInput, context),
131
+ skillName,
132
+ engine
133
+ );
134
+
135
+ stepContext.complete(output);
136
+ lastOutput = output;
137
+
138
+ // Transform output for next step
139
+ currentInput = this.options.transformOutput(output, stepContext);
140
+
141
+ results.push({
142
+ step: i + 1,
143
+ skill: skillName,
144
+ status: ExecutionStatus.COMPLETED,
145
+ output
146
+ });
147
+
148
+ engine.emit('sequentialStepCompleted', {
149
+ context,
150
+ stepContext,
151
+ stepIndex: i,
152
+ skillName,
153
+ output
154
+ });
155
+
156
+ } catch (error) {
157
+ stepContext.fail(error);
158
+
159
+ results.push({
160
+ step: i + 1,
161
+ skill: skillName,
162
+ status: ExecutionStatus.FAILED,
163
+ error: error.message
164
+ });
165
+
166
+ engine.emit('sequentialStepFailed', {
167
+ context,
168
+ stepContext,
169
+ stepIndex: i,
170
+ skillName,
171
+ error
172
+ });
173
+
174
+ // Handle error based on configuration
175
+ if (this.options.errorHandling === SequentialOptions.STOP_ON_ERROR) {
176
+ throw new Error(
177
+ `Sequential execution failed at step ${i + 1} (${skillName}): ${error.message}`
178
+ );
179
+ }
180
+
181
+ // Continue on error - use previous output as input
182
+ engine.emit('sequentialContinuingAfterError', {
183
+ context,
184
+ stepIndex: i,
185
+ skillName,
186
+ error
187
+ });
188
+ }
189
+ }
190
+
191
+ const summary = this._createSummary(results, skills);
192
+
193
+ engine.emit('sequentialCompleted', {
194
+ context,
195
+ results,
196
+ summary
197
+ });
198
+
199
+ return {
200
+ results,
201
+ summary,
202
+ finalOutput: lastOutput
203
+ };
204
+ }
205
+
206
+ /**
207
+ * Execute with retry
208
+ * @private
209
+ */
210
+ async _executeWithRetry(fn, skillName, engine) {
211
+ let lastError;
212
+
213
+ for (let attempt = 1; attempt <= this.options.maxRetries; attempt++) {
214
+ try {
215
+ return await fn();
216
+ } catch (error) {
217
+ lastError = error;
218
+
219
+ if (attempt < this.options.maxRetries &&
220
+ this.options.errorHandling === SequentialOptions.RETRY_ON_ERROR) {
221
+ engine.emit('sequentialRetrying', {
222
+ skillName,
223
+ attempt,
224
+ maxRetries: this.options.maxRetries,
225
+ error
226
+ });
227
+
228
+ await this._delay(this.options.retryDelay * attempt);
229
+ } else {
230
+ throw error;
231
+ }
232
+ }
233
+ }
234
+
235
+ throw lastError;
236
+ }
237
+
238
+ /**
239
+ * Delay helper
240
+ * @private
241
+ */
242
+ _delay(ms) {
243
+ return new Promise(resolve => setTimeout(resolve, ms));
244
+ }
245
+
246
+ /**
247
+ * Create execution summary
248
+ * @private
249
+ */
250
+ _createSummary(results, skills) {
251
+ const completed = results.filter(r => r.status === ExecutionStatus.COMPLETED).length;
252
+ const failed = results.filter(r => r.status === ExecutionStatus.FAILED).length;
253
+
254
+ return {
255
+ totalSteps: skills.length,
256
+ completed,
257
+ failed,
258
+ successRate: skills.length > 0 ? (completed / skills.length * 100).toFixed(1) + '%' : '0%',
259
+ allCompleted: completed === skills.length,
260
+ hasFailed: failed > 0
261
+ };
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Create a sequential pattern with custom options
267
+ * @param {object} options - Pattern options
268
+ * @returns {SequentialPattern} Sequential pattern instance
269
+ */
270
+ function createSequentialPattern(options = {}) {
271
+ return new SequentialPattern(options);
272
+ }
273
+
274
+ module.exports = {
275
+ SequentialPattern,
276
+ SequentialOptions,
277
+ createSequentialPattern
278
+ };