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.
- package/README.ja.md +106 -48
- package/README.md +110 -32
- package/bin/musubi-analyze.js +74 -67
- package/bin/musubi-browser.js +27 -26
- package/bin/musubi-change.js +48 -47
- package/bin/musubi-checkpoint.js +10 -7
- package/bin/musubi-convert.js +25 -25
- package/bin/musubi-costs.js +27 -10
- package/bin/musubi-gui.js +52 -46
- package/bin/musubi-init.js +1952 -10
- package/bin/musubi-orchestrate.js +327 -239
- package/bin/musubi-remember.js +69 -56
- package/bin/musubi-resolve.js +53 -45
- package/bin/musubi-trace.js +51 -22
- package/bin/musubi-validate.js +39 -30
- package/bin/musubi-workflow.js +33 -34
- package/bin/musubi.js +39 -2
- package/package.json +1 -1
- package/src/agents/agent-loop.js +94 -95
- package/src/agents/agentic/code-generator.js +119 -109
- package/src/agents/agentic/code-reviewer.js +105 -108
- package/src/agents/agentic/index.js +4 -4
- package/src/agents/browser/action-executor.js +13 -13
- package/src/agents/browser/ai-comparator.js +11 -10
- package/src/agents/browser/context-manager.js +6 -6
- package/src/agents/browser/index.js +5 -5
- package/src/agents/browser/nl-parser.js +31 -46
- package/src/agents/browser/screenshot.js +2 -2
- package/src/agents/browser/test-generator.js +6 -4
- package/src/agents/function-tool.js +71 -65
- package/src/agents/index.js +7 -7
- package/src/agents/schema-generator.js +98 -94
- package/src/analyzers/ast-extractor.js +158 -146
- package/src/analyzers/codegraph-auto-update.js +858 -0
- package/src/analyzers/complexity-analyzer.js +536 -0
- package/src/analyzers/context-optimizer.js +241 -126
- package/src/analyzers/impact-analyzer.js +1 -1
- package/src/analyzers/large-project-analyzer.js +766 -0
- package/src/analyzers/repository-map.js +77 -81
- package/src/analyzers/security-analyzer.js +19 -11
- package/src/analyzers/stuck-detector.js +19 -17
- package/src/converters/index.js +78 -57
- package/src/converters/ir/types.js +12 -12
- package/src/converters/parsers/musubi-parser.js +134 -126
- package/src/converters/parsers/openapi-parser.js +70 -53
- package/src/converters/parsers/speckit-parser.js +239 -175
- package/src/converters/writers/musubi-writer.js +123 -118
- package/src/converters/writers/speckit-writer.js +124 -113
- package/src/generators/rust-migration-generator.js +512 -0
- package/src/gui/public/index.html +1365 -1211
- package/src/gui/server.js +41 -40
- package/src/gui/services/file-watcher.js +23 -8
- package/src/gui/services/project-scanner.js +26 -20
- package/src/gui/services/replanning-service.js +27 -23
- package/src/gui/services/traceability-service.js +8 -8
- package/src/gui/services/workflow-service.js +14 -7
- package/src/index.js +151 -0
- package/src/integrations/cicd.js +90 -104
- package/src/integrations/codegraph-mcp.js +643 -0
- package/src/integrations/documentation.js +142 -103
- package/src/integrations/examples.js +95 -80
- package/src/integrations/github-client.js +17 -17
- package/src/integrations/index.js +5 -5
- package/src/integrations/mcp/index.js +21 -21
- package/src/integrations/mcp/mcp-context-provider.js +76 -78
- package/src/integrations/mcp/mcp-discovery.js +74 -72
- package/src/integrations/mcp/mcp-tool-registry.js +99 -94
- package/src/integrations/mcp-connector.js +70 -66
- package/src/integrations/platforms.js +50 -49
- package/src/integrations/tool-discovery.js +37 -31
- package/src/llm-providers/anthropic-provider.js +11 -11
- package/src/llm-providers/base-provider.js +16 -18
- package/src/llm-providers/copilot-provider.js +22 -19
- package/src/llm-providers/index.js +26 -25
- package/src/llm-providers/ollama-provider.js +11 -11
- package/src/llm-providers/openai-provider.js +12 -12
- package/src/managers/agent-memory.js +36 -24
- package/src/managers/checkpoint-manager.js +4 -8
- package/src/managers/delta-spec.js +19 -19
- package/src/managers/index.js +13 -4
- package/src/managers/memory-condenser.js +35 -45
- package/src/managers/repo-skill-manager.js +57 -31
- package/src/managers/skill-loader.js +25 -22
- package/src/managers/skill-tools.js +36 -72
- package/src/managers/workflow.js +30 -22
- package/src/monitoring/cost-tracker.js +48 -46
- package/src/monitoring/incident-manager.js +116 -106
- package/src/monitoring/index.js +144 -134
- package/src/monitoring/observability.js +75 -62
- package/src/monitoring/quality-dashboard.js +45 -41
- package/src/monitoring/release-manager.js +63 -53
- package/src/orchestration/agent-skill-binding.js +39 -47
- package/src/orchestration/error-handler.js +65 -107
- package/src/orchestration/guardrails/base-guardrail.js +26 -24
- package/src/orchestration/guardrails/guardrail-rules.js +50 -64
- package/src/orchestration/guardrails/index.js +5 -5
- package/src/orchestration/guardrails/input-guardrail.js +58 -45
- package/src/orchestration/guardrails/output-guardrail.js +104 -81
- package/src/orchestration/guardrails/safety-check.js +79 -79
- package/src/orchestration/index.js +38 -55
- package/src/orchestration/mcp-tool-adapters.js +96 -99
- package/src/orchestration/orchestration-engine.js +21 -21
- package/src/orchestration/pattern-registry.js +60 -45
- package/src/orchestration/patterns/auto.js +34 -47
- package/src/orchestration/patterns/group-chat.js +59 -65
- package/src/orchestration/patterns/handoff.js +67 -65
- package/src/orchestration/patterns/human-in-loop.js +51 -72
- package/src/orchestration/patterns/nested.js +25 -40
- package/src/orchestration/patterns/sequential.js +35 -34
- package/src/orchestration/patterns/swarm.js +63 -56
- package/src/orchestration/patterns/triage.js +150 -109
- package/src/orchestration/reasoning/index.js +9 -9
- package/src/orchestration/reasoning/planning-engine.js +143 -140
- package/src/orchestration/reasoning/reasoning-engine.js +206 -144
- package/src/orchestration/reasoning/self-correction.js +121 -128
- package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
- package/src/orchestration/replanning/alternative-generator.js +37 -42
- package/src/orchestration/replanning/config.js +63 -59
- package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
- package/src/orchestration/replanning/index.js +24 -20
- package/src/orchestration/replanning/plan-evaluator.js +49 -50
- package/src/orchestration/replanning/plan-monitor.js +32 -28
- package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
- package/src/orchestration/replanning/replan-history.js +33 -26
- package/src/orchestration/replanning/replanning-engine.js +106 -108
- package/src/orchestration/skill-executor.js +107 -109
- package/src/orchestration/skill-registry.js +85 -89
- package/src/orchestration/workflow-examples.js +228 -231
- package/src/orchestration/workflow-executor.js +65 -68
- package/src/orchestration/workflow-orchestrator.js +72 -73
- package/src/phase4-integration.js +47 -40
- package/src/phase5-integration.js +89 -30
- package/src/reporters/coverage-report.js +82 -30
- package/src/reporters/hierarchical-reporter.js +498 -0
- package/src/reporters/traceability-matrix-report.js +29 -20
- package/src/resolvers/issue-resolver.js +43 -31
- package/src/steering/advanced-validation.js +133 -124
- package/src/steering/auto-updater.js +60 -73
- package/src/steering/index.js +6 -6
- package/src/steering/quality-metrics.js +41 -35
- package/src/steering/steering-auto-update.js +83 -86
- package/src/steering/steering-validator.js +98 -106
- package/src/steering/template-constraints.js +53 -54
- package/src/templates/agents/claude-code/CLAUDE.md +32 -32
- package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
- package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
- package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
- package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
- package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
- package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
- package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
- package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
- package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
- package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
- package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
- package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
- package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
- package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
- package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
- package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
- package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
- package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
- package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
- package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
- package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
- package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
- package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
- package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
- package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
- package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
- package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
- package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
- package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
- package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
- package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
- package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
- package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
- package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
- package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
- package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
- package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
- package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
- package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
- package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
- package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
- package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
- package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
- package/src/templates/agents/codex/AGENTS.md +74 -42
- package/src/templates/agents/cursor/AGENTS.md +74 -42
- package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
- package/src/templates/agents/github-copilot/AGENTS.md +83 -51
- package/src/templates/agents/qwen-code/QWEN.md +74 -42
- package/src/templates/agents/windsurf/AGENTS.md +74 -42
- package/src/templates/architectures/README.md +41 -0
- package/src/templates/architectures/clean-architecture/README.md +113 -0
- package/src/templates/architectures/event-driven/README.md +162 -0
- package/src/templates/architectures/hexagonal/README.md +130 -0
- package/src/templates/index.js +6 -1
- package/src/templates/locale-manager.js +16 -16
- package/src/templates/shared/delta-spec-template.md +20 -13
- package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
- package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
- package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
- package/src/templates/shared/steering/structure.md +95 -0
- package/src/templates/skills/browser-agent.md +21 -16
- package/src/templates/skills/web-gui.md +8 -0
- package/src/templates/template-constraints.js +50 -53
- package/src/validators/advanced-validation.js +30 -36
- package/src/validators/constitutional-validator.js +77 -73
- package/src/validators/critic-system.js +49 -59
- package/src/validators/delta-format.js +59 -55
- package/src/validators/traceability-validator.js +7 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WorkflowExecutor - End-to-end workflow execution engine
|
|
3
3
|
* Sprint 3.5: Advanced Workflows
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* Provides comprehensive workflow execution with:
|
|
6
6
|
* - Step-by-step execution with state management
|
|
7
7
|
* - Parallel and sequential step execution
|
|
@@ -22,7 +22,7 @@ const StepType = {
|
|
|
22
22
|
PARALLEL: 'parallel',
|
|
23
23
|
LOOP: 'loop',
|
|
24
24
|
CHECKPOINT: 'checkpoint',
|
|
25
|
-
HUMAN_REVIEW: 'human-review'
|
|
25
|
+
HUMAN_REVIEW: 'human-review',
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -35,7 +35,7 @@ const ExecutionState = {
|
|
|
35
35
|
COMPLETED: 'completed',
|
|
36
36
|
FAILED: 'failed',
|
|
37
37
|
CANCELLED: 'cancelled',
|
|
38
|
-
WAITING_REVIEW: 'waiting-review'
|
|
38
|
+
WAITING_REVIEW: 'waiting-review',
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -47,7 +47,7 @@ const RecoveryStrategy = {
|
|
|
47
47
|
FALLBACK: 'fallback',
|
|
48
48
|
ROLLBACK: 'rollback',
|
|
49
49
|
ABORT: 'abort',
|
|
50
|
-
MANUAL: 'manual'
|
|
50
|
+
MANUAL: 'manual',
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
/**
|
|
@@ -98,7 +98,7 @@ class ExecutionContext {
|
|
|
98
98
|
name,
|
|
99
99
|
timestamp: new Date().toISOString(),
|
|
100
100
|
variables: new Map(this.variables),
|
|
101
|
-
currentStep: this.currentStep
|
|
101
|
+
currentStep: this.currentStep,
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -138,15 +138,15 @@ class WorkflowDefinition {
|
|
|
138
138
|
|
|
139
139
|
validate() {
|
|
140
140
|
const errors = [];
|
|
141
|
-
|
|
141
|
+
|
|
142
142
|
if (!this.id) {
|
|
143
143
|
errors.push('Workflow ID is required');
|
|
144
144
|
}
|
|
145
|
-
|
|
145
|
+
|
|
146
146
|
if (!this.name) {
|
|
147
147
|
errors.push('Workflow name is required');
|
|
148
148
|
}
|
|
149
|
-
|
|
149
|
+
|
|
150
150
|
if (!this.steps || this.steps.length === 0) {
|
|
151
151
|
errors.push('Workflow must have at least one step');
|
|
152
152
|
}
|
|
@@ -169,7 +169,7 @@ class WorkflowDefinition {
|
|
|
169
169
|
|
|
170
170
|
return {
|
|
171
171
|
valid: errors.length === 0,
|
|
172
|
-
errors
|
|
172
|
+
errors,
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -185,7 +185,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
185
185
|
this.mcpConnector = options.mcpConnector || null;
|
|
186
186
|
this.executions = new Map();
|
|
187
187
|
this.stepHandlers = new Map();
|
|
188
|
-
|
|
188
|
+
|
|
189
189
|
// Register default step handlers
|
|
190
190
|
this._registerDefaultHandlers();
|
|
191
191
|
}
|
|
@@ -197,7 +197,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
197
197
|
// Skill execution handler
|
|
198
198
|
this.stepHandlers.set(StepType.SKILL, async (step, context) => {
|
|
199
199
|
const { skillId, input } = step;
|
|
200
|
-
|
|
200
|
+
|
|
201
201
|
if (!this.skillRegistry) {
|
|
202
202
|
throw new Error('Skill registry not configured');
|
|
203
203
|
}
|
|
@@ -209,10 +209,10 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
209
209
|
|
|
210
210
|
// Resolve input variables
|
|
211
211
|
const resolvedInput = this._resolveVariables(input, context);
|
|
212
|
-
|
|
212
|
+
|
|
213
213
|
// Execute skill
|
|
214
214
|
const result = await skill.execute(resolvedInput, context);
|
|
215
|
-
|
|
215
|
+
|
|
216
216
|
// Store output in context
|
|
217
217
|
if (step.outputVariable) {
|
|
218
218
|
context.setVariable(step.outputVariable, result);
|
|
@@ -224,17 +224,17 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
224
224
|
// Tool execution handler
|
|
225
225
|
this.stepHandlers.set(StepType.TOOL, async (step, context) => {
|
|
226
226
|
const { toolName, serverName, arguments: args } = step;
|
|
227
|
-
|
|
227
|
+
|
|
228
228
|
if (!this.mcpConnector) {
|
|
229
229
|
throw new Error('MCP connector not configured');
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
// Resolve arguments
|
|
233
233
|
const resolvedArgs = this._resolveVariables(args, context);
|
|
234
|
-
|
|
234
|
+
|
|
235
235
|
// Call tool
|
|
236
236
|
const result = await this.mcpConnector.callTool(toolName, resolvedArgs, serverName);
|
|
237
|
-
|
|
237
|
+
|
|
238
238
|
if (step.outputVariable) {
|
|
239
239
|
context.setVariable(step.outputVariable, result);
|
|
240
240
|
}
|
|
@@ -245,13 +245,13 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
245
245
|
// Condition handler
|
|
246
246
|
this.stepHandlers.set(StepType.CONDITION, async (step, context) => {
|
|
247
247
|
const { condition, thenSteps, elseSteps } = step;
|
|
248
|
-
|
|
248
|
+
|
|
249
249
|
// Evaluate condition
|
|
250
250
|
const conditionResult = this._evaluateCondition(condition, context);
|
|
251
|
-
|
|
251
|
+
|
|
252
252
|
// Execute appropriate branch
|
|
253
253
|
const stepsToExecute = conditionResult ? thenSteps : elseSteps;
|
|
254
|
-
|
|
254
|
+
|
|
255
255
|
if (stepsToExecute && stepsToExecute.length > 0) {
|
|
256
256
|
for (const subStep of stepsToExecute) {
|
|
257
257
|
await this._executeStep(subStep, context);
|
|
@@ -264,22 +264,21 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
264
264
|
// Parallel execution handler
|
|
265
265
|
this.stepHandlers.set(StepType.PARALLEL, async (step, context) => {
|
|
266
266
|
const { steps, maxConcurrency = 5 } = step;
|
|
267
|
-
|
|
267
|
+
|
|
268
268
|
const results = [];
|
|
269
269
|
const executing = new Set();
|
|
270
|
-
|
|
270
|
+
|
|
271
271
|
for (const subStep of steps) {
|
|
272
272
|
if (executing.size >= maxConcurrency) {
|
|
273
273
|
const completed = await Promise.race([...executing]);
|
|
274
274
|
executing.delete(completed.promise);
|
|
275
275
|
results.push(completed.result);
|
|
276
276
|
}
|
|
277
|
-
|
|
278
|
-
const promise = this._executeStep(subStep, context)
|
|
279
|
-
.then(result => ({ promise, result }));
|
|
277
|
+
|
|
278
|
+
const promise = this._executeStep(subStep, context).then(result => ({ promise, result }));
|
|
280
279
|
executing.add(promise);
|
|
281
280
|
}
|
|
282
|
-
|
|
281
|
+
|
|
283
282
|
// Wait for remaining
|
|
284
283
|
const remaining = await Promise.all([...executing]);
|
|
285
284
|
results.push(...remaining.map(r => r.result));
|
|
@@ -294,31 +293,31 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
294
293
|
// Loop handler
|
|
295
294
|
this.stepHandlers.set(StepType.LOOP, async (step, context) => {
|
|
296
295
|
const { items, itemVariable, indexVariable, steps: loopSteps, maxIterations = 1000 } = step;
|
|
297
|
-
|
|
296
|
+
|
|
298
297
|
// Resolve items
|
|
299
298
|
const resolvedItems = this._resolveVariables(items, context);
|
|
300
|
-
|
|
299
|
+
|
|
301
300
|
if (!Array.isArray(resolvedItems)) {
|
|
302
301
|
throw new Error('Loop items must be an array');
|
|
303
302
|
}
|
|
304
303
|
|
|
305
304
|
const results = [];
|
|
306
305
|
let iteration = 0;
|
|
307
|
-
|
|
306
|
+
|
|
308
307
|
for (const item of resolvedItems) {
|
|
309
308
|
if (iteration >= maxIterations) {
|
|
310
309
|
this.emit('warning', { message: `Loop reached max iterations: ${maxIterations}` });
|
|
311
310
|
break;
|
|
312
311
|
}
|
|
313
|
-
|
|
312
|
+
|
|
314
313
|
context.setVariable(itemVariable || 'item', item);
|
|
315
314
|
context.setVariable(indexVariable || 'index', iteration);
|
|
316
|
-
|
|
315
|
+
|
|
317
316
|
for (const subStep of loopSteps) {
|
|
318
317
|
const result = await this._executeStep(subStep, context);
|
|
319
318
|
results.push(result);
|
|
320
319
|
}
|
|
321
|
-
|
|
320
|
+
|
|
322
321
|
iteration++;
|
|
323
322
|
}
|
|
324
323
|
|
|
@@ -340,15 +339,15 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
340
339
|
// Human review handler
|
|
341
340
|
this.stepHandlers.set(StepType.HUMAN_REVIEW, async (step, context) => {
|
|
342
341
|
const { message, options = ['approve', 'reject'] } = step;
|
|
343
|
-
|
|
342
|
+
|
|
344
343
|
context.state = ExecutionState.WAITING_REVIEW;
|
|
345
|
-
this.emit('review-required', {
|
|
344
|
+
this.emit('review-required', {
|
|
346
345
|
stepId: step.id,
|
|
347
346
|
message: this._resolveVariables(message, context),
|
|
348
347
|
options,
|
|
349
|
-
context
|
|
348
|
+
context,
|
|
350
349
|
});
|
|
351
|
-
|
|
350
|
+
|
|
352
351
|
// Wait for review (in real implementation, this would wait for external input)
|
|
353
352
|
return { reviewRequested: true, message };
|
|
354
353
|
});
|
|
@@ -375,7 +374,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
375
374
|
const context = new ExecutionContext(workflow.id);
|
|
376
375
|
context.state = ExecutionState.RUNNING;
|
|
377
376
|
context.startTime = Date.now();
|
|
378
|
-
|
|
377
|
+
|
|
379
378
|
// Set initial variables
|
|
380
379
|
for (const [key, value] of Object.entries(initialVariables)) {
|
|
381
380
|
context.setVariable(key, value);
|
|
@@ -383,10 +382,10 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
383
382
|
|
|
384
383
|
// Store execution
|
|
385
384
|
this.executions.set(context.executionId, context);
|
|
386
|
-
|
|
387
|
-
this.emit('execution-started', {
|
|
388
|
-
executionId: context.executionId,
|
|
389
|
-
workflowId: workflow.id
|
|
385
|
+
|
|
386
|
+
this.emit('execution-started', {
|
|
387
|
+
executionId: context.executionId,
|
|
388
|
+
workflowId: workflow.id,
|
|
390
389
|
});
|
|
391
390
|
|
|
392
391
|
try {
|
|
@@ -395,7 +394,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
395
394
|
if (context.state === ExecutionState.CANCELLED) {
|
|
396
395
|
break;
|
|
397
396
|
}
|
|
398
|
-
|
|
397
|
+
|
|
399
398
|
if (context.state === ExecutionState.PAUSED) {
|
|
400
399
|
await this._waitForResume(context);
|
|
401
400
|
}
|
|
@@ -405,27 +404,26 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
405
404
|
|
|
406
405
|
context.state = ExecutionState.COMPLETED;
|
|
407
406
|
context.endTime = Date.now();
|
|
408
|
-
|
|
407
|
+
|
|
409
408
|
this.emit('execution-completed', {
|
|
410
409
|
executionId: context.executionId,
|
|
411
410
|
duration: context.getDuration(),
|
|
412
|
-
results: Object.fromEntries(context.stepResults)
|
|
411
|
+
results: Object.fromEntries(context.stepResults),
|
|
413
412
|
});
|
|
414
|
-
|
|
415
413
|
} catch (error) {
|
|
416
414
|
context.state = ExecutionState.FAILED;
|
|
417
415
|
context.endTime = Date.now();
|
|
418
416
|
context.errors.push(error);
|
|
419
|
-
|
|
417
|
+
|
|
420
418
|
this.emit('execution-failed', {
|
|
421
419
|
executionId: context.executionId,
|
|
422
420
|
error: error.message,
|
|
423
|
-
step: context.currentStep
|
|
421
|
+
step: context.currentStep,
|
|
424
422
|
});
|
|
425
423
|
|
|
426
424
|
// Apply error handling strategy
|
|
427
425
|
await this._handleExecutionError(error, context, workflow);
|
|
428
|
-
|
|
426
|
+
|
|
429
427
|
throw error;
|
|
430
428
|
}
|
|
431
429
|
|
|
@@ -434,7 +432,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
434
432
|
state: context.state,
|
|
435
433
|
duration: context.getDuration(),
|
|
436
434
|
outputs: this._collectOutputs(context, workflow.outputs),
|
|
437
|
-
stepResults: Object.fromEntries(context.stepResults)
|
|
435
|
+
stepResults: Object.fromEntries(context.stepResults),
|
|
438
436
|
};
|
|
439
437
|
}
|
|
440
438
|
|
|
@@ -444,7 +442,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
444
442
|
async _executeStep(step, context, workflow = null) {
|
|
445
443
|
context.currentStep = step.id;
|
|
446
444
|
const startTime = Date.now();
|
|
447
|
-
|
|
445
|
+
|
|
448
446
|
this.emit('step-started', { stepId: step.id, type: step.type });
|
|
449
447
|
|
|
450
448
|
try {
|
|
@@ -466,23 +464,22 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
466
464
|
// Execute with retry logic
|
|
467
465
|
const result = await this._executeWithRetry(
|
|
468
466
|
() => handler(step, context),
|
|
469
|
-
step.retry ||
|
|
467
|
+
step.retry || workflow?.retryPolicy,
|
|
470
468
|
step.id
|
|
471
469
|
);
|
|
472
470
|
|
|
473
471
|
const duration = Date.now() - startTime;
|
|
474
472
|
const stepResult = new StepResult(step.id, true, result, null, duration);
|
|
475
473
|
context.addStepResult(step.id, stepResult);
|
|
476
|
-
|
|
474
|
+
|
|
477
475
|
this.emit('step-completed', { stepId: step.id, duration, result });
|
|
478
476
|
|
|
479
477
|
return result;
|
|
480
|
-
|
|
481
478
|
} catch (error) {
|
|
482
479
|
const duration = Date.now() - startTime;
|
|
483
480
|
const stepResult = new StepResult(step.id, false, null, error.message, duration);
|
|
484
481
|
context.addStepResult(step.id, stepResult);
|
|
485
|
-
|
|
482
|
+
|
|
486
483
|
this.emit('step-failed', { stepId: step.id, error: error.message, duration });
|
|
487
484
|
|
|
488
485
|
// Apply step-level error handling
|
|
@@ -510,15 +507,15 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
510
507
|
return await fn();
|
|
511
508
|
} catch (error) {
|
|
512
509
|
lastError = error;
|
|
513
|
-
|
|
510
|
+
|
|
514
511
|
if (attempt < maxRetries) {
|
|
515
|
-
this.emit('step-retry', {
|
|
516
|
-
stepId,
|
|
517
|
-
attempt: attempt + 1,
|
|
512
|
+
this.emit('step-retry', {
|
|
513
|
+
stepId,
|
|
514
|
+
attempt: attempt + 1,
|
|
518
515
|
maxRetries,
|
|
519
|
-
nextRetryMs: currentBackoff
|
|
516
|
+
nextRetryMs: currentBackoff,
|
|
520
517
|
});
|
|
521
|
-
|
|
518
|
+
|
|
522
519
|
await this._sleep(currentBackoff);
|
|
523
520
|
currentBackoff *= backoffMultiplier;
|
|
524
521
|
}
|
|
@@ -582,7 +579,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
582
579
|
executionId: context.executionId,
|
|
583
580
|
error: error.message,
|
|
584
581
|
step: context.currentStep,
|
|
585
|
-
strategy
|
|
582
|
+
strategy,
|
|
586
583
|
});
|
|
587
584
|
}
|
|
588
585
|
|
|
@@ -597,24 +594,24 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
597
594
|
return resolved !== null ? String(resolved) : '';
|
|
598
595
|
});
|
|
599
596
|
}
|
|
600
|
-
|
|
597
|
+
|
|
601
598
|
if (Array.isArray(value)) {
|
|
602
599
|
return value.map(item => this._resolveVariables(item, context));
|
|
603
600
|
}
|
|
604
|
-
|
|
601
|
+
|
|
605
602
|
if (typeof value === 'object' && value !== null) {
|
|
606
603
|
// Check if it's a variable reference
|
|
607
604
|
if (value.$var) {
|
|
608
605
|
return context.getVariable(value.$var, value.default);
|
|
609
606
|
}
|
|
610
|
-
|
|
607
|
+
|
|
611
608
|
const resolved = {};
|
|
612
609
|
for (const [key, val] of Object.entries(value)) {
|
|
613
610
|
resolved[key] = this._resolveVariables(val, context);
|
|
614
611
|
}
|
|
615
612
|
return resolved;
|
|
616
613
|
}
|
|
617
|
-
|
|
614
|
+
|
|
618
615
|
return value;
|
|
619
616
|
}
|
|
620
617
|
|
|
@@ -673,13 +670,13 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
673
670
|
*/
|
|
674
671
|
_collectOutputs(context, outputDefs) {
|
|
675
672
|
const outputs = {};
|
|
676
|
-
|
|
673
|
+
|
|
677
674
|
for (const outputDef of outputDefs) {
|
|
678
675
|
const name = typeof outputDef === 'string' ? outputDef : outputDef.name;
|
|
679
676
|
const source = typeof outputDef === 'string' ? outputDef : outputDef.from;
|
|
680
677
|
outputs[name] = context.getVariable(source);
|
|
681
678
|
}
|
|
682
|
-
|
|
679
|
+
|
|
683
680
|
return outputs;
|
|
684
681
|
}
|
|
685
682
|
|
|
@@ -756,7 +753,7 @@ class WorkflowExecutor extends EventEmitter {
|
|
|
756
753
|
duration: context.getDuration(),
|
|
757
754
|
stepsCompleted: context.stepResults.size,
|
|
758
755
|
errors: context.errors.map(e => e.message),
|
|
759
|
-
checkpoints: context.checkpoints.map(cp => cp.name)
|
|
756
|
+
checkpoints: context.checkpoints.map(cp => cp.name),
|
|
760
757
|
};
|
|
761
758
|
}
|
|
762
759
|
|
|
@@ -775,5 +772,5 @@ module.exports = {
|
|
|
775
772
|
StepResult,
|
|
776
773
|
StepType,
|
|
777
774
|
ExecutionState,
|
|
778
|
-
RecoveryStrategy
|
|
775
|
+
RecoveryStrategy,
|
|
779
776
|
};
|