claude-flow-novice 1.3.0 โ 1.3.2
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/.claude-flow-novice/preferences/generation.json +147 -0
- package/.claude-flow-novice/preferences/language-configs/javascript.json +51 -0
- package/.claude-flow-novice/preferences/language-configs/python.json +50 -0
- package/.claude-flow-novice/preferences/language-configs/rust.json +237 -0
- package/.claude-flow-novice/preferences/language-configs/typescript.json +54 -0
- package/.claude-flow-novice/preferences/project-local.json +91 -0
- package/.claude-flow-novice/preferences/resource-delegation.json +120 -0
- package/.claude-flow-novice/preferences/team-shared.json +195 -0
- package/.claude-flow-novice/preferences/user-global.json +247 -0
- package/.claude-flow-novice/templates/claude-md-templates/CLAUDE-JAVASCRIPT.md +769 -0
- package/.claude-flow-novice/templates/claude-md-templates/CLAUDE-PYTHON.md +1214 -0
- package/.claude-flow-novice/templates/claude-md-templates/CLAUDE-RUST.md +475 -0
- package/.claude-flow-novice/templates/claude-md-templates/CLAUDE-TYPESCRIPT.md +851 -0
- package/.claude-flow-novice/templates/claude-md-templates/README.md +263 -0
- package/CLAUDE.md +81 -0
- package/README-NPM.md +0 -0
- package/package.json +11 -7
- package/scripts/build/README.md +167 -0
- package/scripts/build/build-config.js +27 -0
- package/scripts/build/build-prompt-copier.sh +30 -0
- package/scripts/build/performance-monitor.js +869 -0
- package/scripts/build/prepare-publish.js +150 -0
- package/scripts/build/typescript-fixer.js +621 -0
- package/scripts/build/unified-builder.sh +428 -0
- package/scripts/build/update-bin-version.js +32 -0
- package/scripts/dev/README.md +264 -0
- package/scripts/dev/claude-flow-wrapper.sh +35 -0
- package/scripts/dev/claude-monitor.py +419 -0
- package/scripts/dev/claude-sparc.sh +562 -0
- package/scripts/dev/claude-wrapper.sh +17 -0
- package/scripts/dev/demo-phase3-compliance.js +172 -0
- package/scripts/dev/demo-task-system.ts +224 -0
- package/scripts/dev/deployment-validator.js +315 -0
- package/scripts/dev/spawn-claude-terminal.sh +32 -0
- package/scripts/dev/start-portal.sh +506 -0
- package/scripts/dev/start-web-ui.js +15 -0
- package/scripts/dev/stop-portal.sh +311 -0
- package/scripts/dev/validate-examples.ts +288 -0
- package/scripts/dev/validate-phase2.cjs +451 -0
- package/scripts/dev/validate-phase2.js +785 -0
- package/scripts/dev/validate-phase3.cjs +208 -0
- package/scripts/dev/validate-security-remediation.js +1 -0
- package/scripts/legacy/README.md +272 -0
- package/scripts/legacy/batch-fix-ts.sh +54 -0
- package/scripts/legacy/build-migration.sh +105 -0
- package/scripts/legacy/build-monitor.js +209 -0
- package/scripts/legacy/build-with-filter.sh +84 -0
- package/scripts/legacy/build-workaround.sh +71 -0
- package/scripts/legacy/fix-ts-advanced.js +358 -0
- package/scripts/legacy/fix-ts-final.sh +50 -0
- package/scripts/legacy/fix-ts-targeted.sh +49 -0
- package/scripts/legacy/fix-typescript-errors.js +305 -0
- package/scripts/legacy/force-build.sh +63 -0
- package/scripts/legacy/optimize-performance.js +400 -0
- package/scripts/legacy/performance-monitor.js +263 -0
- package/scripts/legacy/performance-monitoring.js +532 -0
- package/scripts/legacy/performance-test-runner.js +645 -0
- package/scripts/legacy/quick-fix-ts.js +281 -0
- package/scripts/legacy/safe-build.sh +63 -0
- package/scripts/migration/README.md +434 -0
- package/scripts/migration/install-arm64.js +78 -0
- package/scripts/migration/install.js +83 -0
- package/scripts/migration/migrate-hooks.js +173 -0
- package/scripts/migration/migration-examples.ts +318 -0
- package/scripts/optimization/build-optimizer.js +438 -0
- package/scripts/optimization/config-validator.js +761 -0
- package/scripts/optimization/test-optimization.js +432 -0
- package/scripts/optimization/unified-activation.js +839 -0
- package/scripts/performance/ACTIVATION_COMMANDS.md +292 -0
- package/scripts/performance/sqlite-enhanced-activation.sh +583 -0
- package/scripts/performance/test-enhanced-backend.sh +504 -0
- package/scripts/performance-test-runner.js +698 -0
- package/scripts/security/README.md +339 -0
- package/scripts/security/install-git-hooks.sh +132 -0
- package/scripts/security/ruv-swarm-safe.js +74 -0
- package/scripts/test/README.md +236 -0
- package/scripts/test/check-links.ts +274 -0
- package/scripts/test/check-performance-regression.ts +168 -0
- package/scripts/test/coverage-report.ts +692 -0
- package/scripts/test/generate-swarm-tests.js +633 -0
- package/scripts/test/integration-test-validation.cjs +253 -0
- package/scripts/test/load-test-swarm.js +576 -0
- package/scripts/test/run-phase3-compliance-tests.js +427 -0
- package/scripts/test/test-batch-tasks.ts +29 -0
- package/scripts/test/test-byzantine-resolution.js +246 -0
- package/scripts/test/test-claude-spawn-options.sh +63 -0
- package/scripts/test/test-cli-wizard.js +331 -0
- package/scripts/test/test-comprehensive.js +401 -0
- package/scripts/test/test-coordination-features.ts +238 -0
- package/scripts/test/test-fallback-systems.js +276 -0
- package/scripts/test/test-init-command.ts +302 -0
- package/scripts/test/test-mcp.ts +251 -0
- package/scripts/test/test-runner.ts +568 -0
- package/scripts/test/test-swarm-integration.sh +92 -0
- package/scripts/test/test-swarm.ts +142 -0
- package/scripts/test/validation-summary.ts +408 -0
- package/scripts/utils/README.md +261 -0
- package/scripts/utils/clean-build-artifacts.sh +94 -0
- package/scripts/utils/cleanup-root.sh +69 -0
- package/scripts/utils/fix-cliffy-imports.js +307 -0
- package/scripts/utils/fix-duplicate-imports.js +114 -0
- package/scripts/utils/fix-error-handling.cjs +70 -0
- package/scripts/utils/fix-import-paths.js +104 -0
- package/scripts/utils/fix-imports.js +116 -0
- package/scripts/utils/fix-shebang.js +78 -0
- package/scripts/utils/fix-test-modules.js +27 -0
- package/scripts/utils/fix-timezone-issue-246.js +200 -0
- package/scripts/utils/fix-ts-comprehensive.py +182 -0
- package/scripts/utils/fix-ts-targeted-batch.js +250 -0
- package/scripts/utils/remove-benchmark-conflicts.sh +140 -0
- package/scripts/utils/simple-test-fixer.js +190 -0
- package/scripts/utils/validate-metrics-structure.cjs +144 -0
- package/scripts/verify-mcp-server.js +86 -0
- package/src/cli/simple-commands/__tests__/agent.test.js +291 -0
- package/src/cli/simple-commands/__tests__/memory.test.js +8 -0
- package/src/cli/simple-commands/__tests__/swarm.test.js +371 -0
- package/src/cli/simple-commands/__tests__/task.test.js +8 -0
- package/src/cli/simple-commands/agent.js +216 -0
- package/src/cli/simple-commands/analysis.js +570 -0
- package/src/cli/simple-commands/automation-executor.js +1603 -0
- package/src/cli/simple-commands/automation.js +627 -0
- package/src/cli/simple-commands/batch-manager.js +338 -0
- package/src/cli/simple-commands/claude-telemetry.js +311 -0
- package/src/cli/simple-commands/claude-track.js +102 -0
- package/src/cli/simple-commands/concurrent-display.js +348 -0
- package/src/cli/simple-commands/config.js +319 -0
- package/src/cli/simple-commands/coordination.js +307 -0
- package/src/cli/simple-commands/enhanced-ui-views.js +654 -0
- package/src/cli/simple-commands/enhanced-webui-complete.js +1038 -0
- package/src/cli/simple-commands/fix-hook-variables.js +363 -0
- package/src/cli/simple-commands/github/gh-coordinator.js +605 -0
- package/src/cli/simple-commands/github/github-api.js +624 -0
- package/src/cli/simple-commands/github/init.js +543 -0
- package/src/cli/simple-commands/github.js +377 -0
- package/src/cli/simple-commands/goal.js +145 -0
- package/src/cli/simple-commands/hive-mind/auto-save-middleware.js +311 -0
- package/src/cli/simple-commands/hive-mind/communication.js +740 -0
- package/src/cli/simple-commands/hive-mind/core.js +1031 -0
- package/src/cli/simple-commands/hive-mind/db-optimizer.js +872 -0
- package/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1364 -0
- package/src/cli/simple-commands/hive-mind/memory.js +1292 -0
- package/src/cli/simple-commands/hive-mind/performance-optimizer.js +618 -0
- package/src/cli/simple-commands/hive-mind/performance-test.js +373 -0
- package/src/cli/simple-commands/hive-mind/queen.js +809 -0
- package/src/cli/simple-commands/hive-mind/session-manager.js +1223 -0
- package/src/cli/simple-commands/hive-mind-optimize.js +361 -0
- package/src/cli/simple-commands/hive-mind-wizard.js +281 -0
- package/src/cli/simple-commands/hive-mind.js +3112 -0
- package/src/cli/simple-commands/hive.js +140 -0
- package/src/cli/simple-commands/hook-safety.js +671 -0
- package/src/cli/simple-commands/hooks.js +1268 -0
- package/src/cli/simple-commands/init/.claude/checkpoints/1756224542.json +7 -0
- package/src/cli/simple-commands/init/.claude/checkpoints/1756224544.json +8 -0
- package/src/cli/simple-commands/init/README.md +106 -0
- package/src/cli/simple-commands/init/VALIDATION_ROLLBACK.md +488 -0
- package/src/cli/simple-commands/init/agent-copier.js +347 -0
- package/src/cli/simple-commands/init/batch-init.js +663 -0
- package/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +438 -0
- package/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +876 -0
- package/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +356 -0
- package/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +501 -0
- package/src/cli/simple-commands/init/claude-commands/slash-commands.js +57 -0
- package/src/cli/simple-commands/init/claude-commands/sparc-commands.js +296 -0
- package/src/cli/simple-commands/init/copy-revised-templates.js +175 -0
- package/src/cli/simple-commands/init/executable-wrapper.js +122 -0
- package/src/cli/simple-commands/init/gitignore-updater.js +137 -0
- package/src/cli/simple-commands/init/help.js +110 -0
- package/src/cli/simple-commands/init/hive-mind-init.js +749 -0
- package/src/cli/simple-commands/init/index.js +1953 -0
- package/src/cli/simple-commands/init/performance-monitor.js +344 -0
- package/src/cli/simple-commands/init/rollback/backup-manager.js +542 -0
- package/src/cli/simple-commands/init/rollback/index.js +399 -0
- package/src/cli/simple-commands/init/rollback/recovery-manager.js +778 -0
- package/src/cli/simple-commands/init/rollback/rollback-executor.js +521 -0
- package/src/cli/simple-commands/init/rollback/state-tracker.js +486 -0
- package/src/cli/simple-commands/init/sparc/roo-readme.js +61 -0
- package/src/cli/simple-commands/init/sparc/roomodes-config.js +102 -0
- package/src/cli/simple-commands/init/sparc/workflows.js +40 -0
- package/src/cli/simple-commands/init/sparc-structure.js +68 -0
- package/src/cli/simple-commands/init/template-copier.js +640 -0
- package/src/cli/simple-commands/init/templates/CLAUDE.md +1185 -0
- package/src/cli/simple-commands/init/templates/CLAUDE.md.optimized +265 -0
- package/src/cli/simple-commands/init/templates/claude-flow-universal +81 -0
- package/src/cli/simple-commands/init/templates/claude-flow.bat +18 -0
- package/src/cli/simple-commands/init/templates/claude-flow.ps1 +24 -0
- package/src/cli/simple-commands/init/templates/claude-md.js +1101 -0
- package/src/cli/simple-commands/init/templates/commands/analysis/bottleneck-detect.md +162 -0
- package/src/cli/simple-commands/init/templates/commands/automation/auto-agent.md +122 -0
- package/src/cli/simple-commands/init/templates/commands/coordination/swarm-init.md +85 -0
- package/src/cli/simple-commands/init/templates/commands/github/github-swarm.md +121 -0
- package/src/cli/simple-commands/init/templates/commands/helpers/standard-checkpoint-hooks.sh +179 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/notification.md +113 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/post-command.md +116 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/post-edit.md +117 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/post-task.md +112 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/pre-command.md +113 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/pre-edit.md +113 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/pre-search.md +112 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/pre-task.md +111 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/session-end.md +118 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/session-restore.md +118 -0
- package/src/cli/simple-commands/init/templates/commands/hooks/session-start.md +117 -0
- package/src/cli/simple-commands/init/templates/coordination-md.js +340 -0
- package/src/cli/simple-commands/init/templates/coordination.md +16 -0
- package/src/cli/simple-commands/init/templates/enhanced-templates.js +2347 -0
- package/src/cli/simple-commands/init/templates/github-safe-enhanced.js +331 -0
- package/src/cli/simple-commands/init/templates/github-safe.js +106 -0
- package/src/cli/simple-commands/init/templates/memory-bank-md.js +259 -0
- package/src/cli/simple-commands/init/templates/memory-bank.md +16 -0
- package/src/cli/simple-commands/init/templates/readme-files.js +72 -0
- package/src/cli/simple-commands/init/templates/safe-hook-patterns.js +430 -0
- package/src/cli/simple-commands/init/templates/settings.json +109 -0
- package/src/cli/simple-commands/init/templates/settings.json.enhanced +35 -0
- package/src/cli/simple-commands/init/templates/sparc-modes.js +1401 -0
- package/src/cli/simple-commands/init/templates/verification-claude-md.js +432 -0
- package/src/cli/simple-commands/init/validation/config-validator.js +354 -0
- package/src/cli/simple-commands/init/validation/health-checker.js +599 -0
- package/src/cli/simple-commands/init/validation/index.js +388 -0
- package/src/cli/simple-commands/init/validation/mode-validator.js +387 -0
- package/src/cli/simple-commands/init/validation/post-init-validator.js +390 -0
- package/src/cli/simple-commands/init/validation/pre-init-validator.js +290 -0
- package/src/cli/simple-commands/init/validation/test-runner.js +488 -0
- package/src/cli/simple-commands/init.js +4 -0
- package/src/cli/simple-commands/mcp-health.js +163 -0
- package/src/cli/simple-commands/mcp-integration-layer.js +689 -0
- package/src/cli/simple-commands/mcp.js +420 -0
- package/src/cli/simple-commands/memory-consolidation.js +631 -0
- package/src/cli/simple-commands/memory.js +345 -0
- package/src/cli/simple-commands/migrate-hooks.js +63 -0
- package/src/cli/simple-commands/monitor.js +417 -0
- package/src/cli/simple-commands/neural.js +148 -0
- package/src/cli/simple-commands/pair-autofix-only.js +755 -0
- package/src/cli/simple-commands/pair-basic.js +751 -0
- package/src/cli/simple-commands/pair-old.js +623 -0
- package/src/cli/simple-commands/pair-working.js +849 -0
- package/src/cli/simple-commands/pair.js +849 -0
- package/src/cli/simple-commands/performance-hooks.js +149 -0
- package/src/cli/simple-commands/performance-metrics.js +601 -0
- package/src/cli/simple-commands/process-ui-enhanced.js +821 -0
- package/src/cli/simple-commands/process-ui.js +274 -0
- package/src/cli/simple-commands/realtime-update-system.js +659 -0
- package/src/cli/simple-commands/sparc/architecture.js +1750 -0
- package/src/cli/simple-commands/sparc/commands.js +575 -0
- package/src/cli/simple-commands/sparc/completion.js +1831 -0
- package/src/cli/simple-commands/sparc/coordinator.js +1045 -0
- package/src/cli/simple-commands/sparc/index.js +321 -0
- package/src/cli/simple-commands/sparc/phase-base.js +430 -0
- package/src/cli/simple-commands/sparc/pseudocode.js +984 -0
- package/src/cli/simple-commands/sparc/refinement.js +1856 -0
- package/src/cli/simple-commands/sparc/specification.js +736 -0
- package/src/cli/simple-commands/sparc-modes/architect.js +125 -0
- package/src/cli/simple-commands/sparc-modes/ask.js +126 -0
- package/src/cli/simple-commands/sparc-modes/code.js +148 -0
- package/src/cli/simple-commands/sparc-modes/debug.js +112 -0
- package/src/cli/simple-commands/sparc-modes/devops.js +137 -0
- package/src/cli/simple-commands/sparc-modes/docs-writer.js +38 -0
- package/src/cli/simple-commands/sparc-modes/generic.js +34 -0
- package/src/cli/simple-commands/sparc-modes/index.js +201 -0
- package/src/cli/simple-commands/sparc-modes/integration.js +55 -0
- package/src/cli/simple-commands/sparc-modes/mcp.js +38 -0
- package/src/cli/simple-commands/sparc-modes/monitoring.js +38 -0
- package/src/cli/simple-commands/sparc-modes/optimization.js +38 -0
- package/src/cli/simple-commands/sparc-modes/security-review.js +130 -0
- package/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +167 -0
- package/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +38 -0
- package/src/cli/simple-commands/sparc-modes/supabase-admin.js +149 -0
- package/src/cli/simple-commands/sparc-modes/swarm.js +436 -0
- package/src/cli/simple-commands/sparc-modes/tdd.js +112 -0
- package/src/cli/simple-commands/sparc-modes/tutorial.js +277 -0
- package/src/cli/simple-commands/sparc.js +530 -0
- package/src/cli/simple-commands/start-ui.js +147 -0
- package/src/cli/simple-commands/start-wrapper.js +285 -0
- package/src/cli/simple-commands/start.js +2 -0
- package/src/cli/simple-commands/status.js +303 -0
- package/src/cli/simple-commands/stream-chain-clean.js +221 -0
- package/src/cli/simple-commands/stream-chain-fixed.js +89 -0
- package/src/cli/simple-commands/stream-chain-real.js +408 -0
- package/src/cli/simple-commands/stream-chain-working.js +323 -0
- package/src/cli/simple-commands/stream-chain.js +491 -0
- package/src/cli/simple-commands/stream-processor.js +340 -0
- package/src/cli/simple-commands/swarm-executor.js +253 -0
- package/src/cli/simple-commands/swarm-metrics-integration.js +371 -0
- package/src/cli/simple-commands/swarm-ui.js +741 -0
- package/src/cli/simple-commands/swarm-webui-integration.js +311 -0
- package/src/cli/simple-commands/swarm.js +2277 -0
- package/src/cli/simple-commands/task.js +228 -0
- package/src/cli/simple-commands/templates/mle-star-workflow.json +294 -0
- package/src/cli/simple-commands/timestamp-fix.js +104 -0
- package/src/cli/simple-commands/token-tracker.js +372 -0
- package/src/cli/simple-commands/tool-execution-framework.js +555 -0
- package/src/cli/simple-commands/train-and-stream.js +354 -0
- package/src/cli/simple-commands/training-pipeline.js +874 -0
- package/src/cli/simple-commands/training.js +288 -0
- package/src/cli/simple-commands/verification-hooks.js +336 -0
- package/src/cli/simple-commands/verification-integration.js +464 -0
- package/src/cli/simple-commands/verification-training-integration.js +646 -0
- package/src/cli/simple-commands/verification.js +551 -0
- package/src/cli/simple-commands/web-server.js +929 -0
- package/src/cli/simple-commands/webui-validator.js +136 -0
- package/src/language/README.md +503 -0
- package/src/language/claude-md-generator.js +618 -0
- package/src/language/cli.js +422 -0
- package/src/language/example.js +347 -0
- package/src/language/integration-system.js +619 -0
- package/src/language/language-detector.js +581 -0
|
@@ -0,0 +1,1603 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modular Automation Executor for Claude Flow
|
|
3
|
+
*
|
|
4
|
+
* This module provides the core infrastructure for executing automation
|
|
5
|
+
* workflows with Claude CLI integration, while preserving existing
|
|
6
|
+
* swarm and hive-mind functionality.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { promises as fs } from 'fs';
|
|
10
|
+
import { spawn } from 'child_process';
|
|
11
|
+
import { join, dirname } from 'path';
|
|
12
|
+
import { printSuccess, printError, printWarning } from '../utils.js';
|
|
13
|
+
|
|
14
|
+
// Simple ID generator
|
|
15
|
+
function generateId(prefix = 'id') {
|
|
16
|
+
return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* WorkflowExecutor - Core class for executing automation workflows
|
|
21
|
+
*/
|
|
22
|
+
export class WorkflowExecutor {
|
|
23
|
+
constructor(options = {}) {
|
|
24
|
+
this.options = {
|
|
25
|
+
enableClaude: false,
|
|
26
|
+
nonInteractive: false,
|
|
27
|
+
outputFormat: 'text',
|
|
28
|
+
maxConcurrency: 3,
|
|
29
|
+
timeout: 3600000, // 1 hour default
|
|
30
|
+
logLevel: 'info',
|
|
31
|
+
...options,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Increase timeout for ML workflows
|
|
35
|
+
if (options.workflowType === 'ml' || options.workflowName?.toLowerCase().includes('mle')) {
|
|
36
|
+
this.options.timeout = 7200000; // 2 hours for ML workflows
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Execution state
|
|
40
|
+
this.executionId = generateId('workflow-exec');
|
|
41
|
+
this.startTime = Date.now();
|
|
42
|
+
this.activeTasks = new Map();
|
|
43
|
+
this.claudeInstances = new Map();
|
|
44
|
+
this.results = new Map();
|
|
45
|
+
this.errors = [];
|
|
46
|
+
this.currentWorkflow = null;
|
|
47
|
+
|
|
48
|
+
// Stream chaining support
|
|
49
|
+
this.taskOutputStreams = new Map(); // Store output streams for chaining
|
|
50
|
+
this.enableChaining = options.enableChaining !== false; // Default to true
|
|
51
|
+
|
|
52
|
+
// Hooks integration
|
|
53
|
+
this.hooksEnabled = true;
|
|
54
|
+
this.sessionId = generateId('automation-session');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Execute a workflow from JSON definition
|
|
59
|
+
*/
|
|
60
|
+
async executeWorkflow(workflowData, variables = {}) {
|
|
61
|
+
try {
|
|
62
|
+
// Store workflow for reference
|
|
63
|
+
this.currentWorkflow = workflowData;
|
|
64
|
+
|
|
65
|
+
if (this.options.logLevel === 'quiet') {
|
|
66
|
+
console.log(`๐ Executing workflow: ${this.executionId}`);
|
|
67
|
+
} else {
|
|
68
|
+
console.log(`๐ Starting workflow execution: ${this.executionId}`);
|
|
69
|
+
console.log(`๐ Workflow: ${workflowData.name}`);
|
|
70
|
+
console.log(`๐ฏ Strategy: MLE-STAR Machine Learning Engineering`);
|
|
71
|
+
|
|
72
|
+
if (this.options.enableClaude) {
|
|
73
|
+
console.log(`๐ค Claude CLI Integration: Enabled`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (this.options.nonInteractive) {
|
|
77
|
+
console.log(`๐ฅ๏ธ Non-Interactive Mode: Enabled`);
|
|
78
|
+
if (this.options.outputFormat === 'stream-json') {
|
|
79
|
+
console.log();
|
|
80
|
+
console.log('โ Running MLE-STAR workflow with Claude CLI integration');
|
|
81
|
+
console.log(
|
|
82
|
+
' โฟ Command format: claude --print --output-format stream-json --verbose --dangerously-skip-permissions',
|
|
83
|
+
);
|
|
84
|
+
console.log(' โฟ Each agent will show real-time stream output below');
|
|
85
|
+
console.log(' โฟ Interactive-style formatting enabled');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
console.log();
|
|
91
|
+
|
|
92
|
+
// Pre-execution hooks
|
|
93
|
+
if (this.hooksEnabled) {
|
|
94
|
+
await this.executeHook('pre-task', {
|
|
95
|
+
description: `Execute workflow: ${workflowData.name}`,
|
|
96
|
+
sessionId: this.sessionId,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Validate workflow
|
|
101
|
+
this.validateWorkflow(workflowData);
|
|
102
|
+
|
|
103
|
+
// Apply variable substitutions
|
|
104
|
+
const processedWorkflow = this.applyVariables(workflowData, variables);
|
|
105
|
+
|
|
106
|
+
// Initialize agents if Claude integration is enabled
|
|
107
|
+
if (this.options.enableClaude) {
|
|
108
|
+
await this.initializeClaudeAgents(processedWorkflow.agents);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Execute workflow phases
|
|
112
|
+
const result = await this.executeWorkflowTasks(processedWorkflow);
|
|
113
|
+
|
|
114
|
+
// Post-execution hooks
|
|
115
|
+
if (this.hooksEnabled) {
|
|
116
|
+
await this.executeHook('post-task', {
|
|
117
|
+
taskId: this.executionId,
|
|
118
|
+
sessionId: this.sessionId,
|
|
119
|
+
result: result.success ? 'success' : 'failure',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const duration = Date.now() - this.startTime;
|
|
124
|
+
|
|
125
|
+
if (result.success) {
|
|
126
|
+
printSuccess(`โ
Workflow completed successfully in ${this.formatDuration(duration)}`);
|
|
127
|
+
console.log(`๐ Tasks: ${result.completedTasks}/${result.totalTasks} completed`);
|
|
128
|
+
console.log(`๐ Execution ID: ${this.executionId}`);
|
|
129
|
+
} else {
|
|
130
|
+
printError(`โ Workflow failed after ${this.formatDuration(duration)}`);
|
|
131
|
+
console.log(`๐ Tasks: ${result.completedTasks}/${result.totalTasks} completed`);
|
|
132
|
+
console.log(`โ Errors: ${this.errors.length}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Cleanup Claude instances
|
|
136
|
+
if (this.options.enableClaude) {
|
|
137
|
+
await this.cleanupClaudeInstances();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return result;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
printError(`Workflow execution failed: ${error.message}`);
|
|
143
|
+
await this.cleanupClaudeInstances();
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Initialize Claude CLI instances for agents
|
|
150
|
+
*/
|
|
151
|
+
async initializeClaudeAgents(agents) {
|
|
152
|
+
if (!agents || agents.length === 0) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Check if Claude CLI is available
|
|
157
|
+
if (!(await this.isClaudeAvailable())) {
|
|
158
|
+
throw new Error('Claude CLI not found. Please install Claude Code: https://claude.ai/code');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (this.options.nonInteractive) {
|
|
162
|
+
// Non-interactive mode: agents are spawned per task instead
|
|
163
|
+
if (this.options.logLevel !== 'quiet') {
|
|
164
|
+
console.log(`๐ค Non-interactive mode: Claude instances will be spawned per task`);
|
|
165
|
+
console.log(`๐ Each task will launch its own Claude process with specific prompts`);
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
} else {
|
|
169
|
+
// Interactive mode: spawn single Claude instance with master coordination prompt
|
|
170
|
+
console.log(
|
|
171
|
+
`๐ค Interactive mode: Initializing single Claude instance for workflow coordination...`,
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
// Create master coordination prompt for all agents and workflow
|
|
176
|
+
const masterPrompt = this.createMasterCoordinationPrompt(agents);
|
|
177
|
+
|
|
178
|
+
// Spawn single Claude instance for workflow coordination
|
|
179
|
+
const claudeProcess = await this.spawnClaudeInstance(
|
|
180
|
+
{
|
|
181
|
+
id: 'master-coordinator',
|
|
182
|
+
name: 'Workflow Coordinator',
|
|
183
|
+
type: 'coordinator',
|
|
184
|
+
},
|
|
185
|
+
masterPrompt,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// Store as master coordinator
|
|
189
|
+
this.claudeInstances.set('master-coordinator', {
|
|
190
|
+
process: claudeProcess,
|
|
191
|
+
agent: { id: 'master-coordinator', name: 'Workflow Coordinator', type: 'coordinator' },
|
|
192
|
+
status: 'active',
|
|
193
|
+
startTime: Date.now(),
|
|
194
|
+
agents: agents, // Store agent definitions for reference
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
console.log(` โ
Master Workflow Coordinator (PID: ${claudeProcess.pid})`);
|
|
198
|
+
console.log(` ๐ฏ Coordinating ${agents.length} sub-agents via concurrent streams`);
|
|
199
|
+
console.log(` ๐ Agents: ${agents.map((a) => a.name).join(', ')}`);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
console.error(` โ Failed to initialize master coordinator: ${error.message}`);
|
|
202
|
+
this.errors.push({
|
|
203
|
+
type: 'master_coordinator_initialization',
|
|
204
|
+
error: error.message,
|
|
205
|
+
timestamp: new Date(),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
console.log();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Check if Claude CLI is available
|
|
215
|
+
*/
|
|
216
|
+
async isClaudeAvailable() {
|
|
217
|
+
try {
|
|
218
|
+
const { execSync } = await import('child_process');
|
|
219
|
+
execSync('which claude', { stdio: 'ignore' });
|
|
220
|
+
return true;
|
|
221
|
+
} catch {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Spawn a Claude CLI instance for an agent
|
|
228
|
+
* @param {Object} agent - The agent configuration
|
|
229
|
+
* @param {string} prompt - The prompt for the agent
|
|
230
|
+
* @param {Object} options - Additional options
|
|
231
|
+
* @param {Stream} options.inputStream - Optional input stream from previous agent
|
|
232
|
+
* @param {boolean} options.enableChaining - Whether to enable stream-json chaining
|
|
233
|
+
*/
|
|
234
|
+
async spawnClaudeInstance(agent, prompt, options = {}) {
|
|
235
|
+
const claudeArgs = [];
|
|
236
|
+
|
|
237
|
+
// Add flags based on mode
|
|
238
|
+
if (this.options.nonInteractive) {
|
|
239
|
+
// Non-interactive mode: use --print with stream-json output
|
|
240
|
+
claudeArgs.push('--print');
|
|
241
|
+
if (this.options.outputFormat === 'stream-json') {
|
|
242
|
+
claudeArgs.push('--output-format', 'stream-json');
|
|
243
|
+
claudeArgs.push('--verbose'); // Required for stream-json
|
|
244
|
+
|
|
245
|
+
// Add input format if we're chaining from a previous agent
|
|
246
|
+
if (options.inputStream) {
|
|
247
|
+
claudeArgs.push('--input-format', 'stream-json');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Always skip permissions for automated workflows (both interactive and non-interactive)
|
|
253
|
+
claudeArgs.push('--dangerously-skip-permissions');
|
|
254
|
+
|
|
255
|
+
// Always add the prompt as the final argument
|
|
256
|
+
claudeArgs.push(prompt);
|
|
257
|
+
|
|
258
|
+
// Only show command details in verbose mode
|
|
259
|
+
if (this.options.logLevel === 'debug') {
|
|
260
|
+
const displayPrompt = prompt.length > 100 ? prompt.substring(0, 100) + '...' : prompt;
|
|
261
|
+
const flagsDisplay = this.options.nonInteractive
|
|
262
|
+
? this.options.outputFormat === 'stream-json'
|
|
263
|
+
? options.inputStream
|
|
264
|
+
? '--print --input-format stream-json --output-format stream-json --verbose --dangerously-skip-permissions'
|
|
265
|
+
: '--print --output-format stream-json --verbose --dangerously-skip-permissions'
|
|
266
|
+
: '--print --dangerously-skip-permissions'
|
|
267
|
+
: '--dangerously-skip-permissions';
|
|
268
|
+
console.log(
|
|
269
|
+
` ๐ค Spawning Claude for ${agent.name}: claude ${flagsDisplay} "${displayPrompt}"`,
|
|
270
|
+
);
|
|
271
|
+
} else if (this.options.logLevel !== 'quiet') {
|
|
272
|
+
console.log(` ๐ Starting ${agent.name}`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Determine stdio configuration based on mode and chaining
|
|
276
|
+
const stdioConfig = this.options.nonInteractive
|
|
277
|
+
? [options.inputStream ? 'pipe' : 'inherit', 'pipe', 'pipe'] // Non-interactive: pipe for chaining
|
|
278
|
+
: ['inherit', 'inherit', 'inherit']; // Interactive: inherit all for normal Claude interaction
|
|
279
|
+
|
|
280
|
+
// Spawn Claude process
|
|
281
|
+
const claudeProcess = spawn('claude', claudeArgs, {
|
|
282
|
+
stdio: stdioConfig,
|
|
283
|
+
shell: false,
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// If we have an input stream, pipe it to Claude's stdin
|
|
287
|
+
if (options.inputStream && claudeProcess.stdin) {
|
|
288
|
+
console.log(` ๐ Chaining: Piping output from previous agent to ${agent.name}`);
|
|
289
|
+
options.inputStream.pipe(claudeProcess.stdin);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Handle stdout with stream processor for better formatting (only in non-interactive mode)
|
|
293
|
+
if (
|
|
294
|
+
this.options.nonInteractive &&
|
|
295
|
+
this.options.outputFormat === 'stream-json' &&
|
|
296
|
+
claudeProcess.stdout
|
|
297
|
+
) {
|
|
298
|
+
// Import and use stream processor
|
|
299
|
+
const { createStreamProcessor } = await import('./stream-processor.js');
|
|
300
|
+
const streamProcessor = createStreamProcessor(agent.name, this.getAgentIcon(agent.id), {
|
|
301
|
+
verbose: this.options.logLevel === 'debug',
|
|
302
|
+
logLevel: this.options.logLevel,
|
|
303
|
+
taskId: agent.taskId,
|
|
304
|
+
agentId: agent.id,
|
|
305
|
+
display: null, // Interactive-style formatting instead of concurrent display
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// Pipe stdout through processor
|
|
309
|
+
claudeProcess.stdout.pipe(streamProcessor);
|
|
310
|
+
|
|
311
|
+
// Handle stderr for non-interactive mode
|
|
312
|
+
claudeProcess.stderr.on('data', (data) => {
|
|
313
|
+
const message = data.toString().trim();
|
|
314
|
+
if (message) {
|
|
315
|
+
console.error(` โ [${agent.name}] Error: ${message}`);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
} else if (this.options.nonInteractive && this.options.outputFormat !== 'stream-json') {
|
|
319
|
+
// For non-interactive non-stream-json output, show stdout directly
|
|
320
|
+
claudeProcess.stdout.on('data', (data) => {
|
|
321
|
+
console.log(data.toString().trimEnd());
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
claudeProcess.stderr.on('data', (data) => {
|
|
325
|
+
console.error(data.toString().trimEnd());
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
// Note: In interactive mode, stdio is inherited so Claude handles its own I/O
|
|
329
|
+
|
|
330
|
+
// Handle process events
|
|
331
|
+
claudeProcess.on('error', (error) => {
|
|
332
|
+
console.error(`โ Claude instance error for ${agent.name}:`, error.message);
|
|
333
|
+
this.errors.push({
|
|
334
|
+
type: 'claude_instance_error',
|
|
335
|
+
agent: agent.id,
|
|
336
|
+
error: error.message,
|
|
337
|
+
timestamp: new Date(),
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
claudeProcess.on('exit', (code) => {
|
|
342
|
+
const instance = this.claudeInstances.get(agent.id);
|
|
343
|
+
if (instance) {
|
|
344
|
+
instance.status = code === 0 ? 'completed' : 'failed';
|
|
345
|
+
instance.exitCode = code;
|
|
346
|
+
instance.endTime = Date.now();
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
return claudeProcess;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Handle Claude stream events
|
|
355
|
+
*/
|
|
356
|
+
handleClaudeStreamEvent(agent, event) {
|
|
357
|
+
if (this.options.outputFormat === 'stream-json') {
|
|
358
|
+
// Create concise formatted JSON with summary
|
|
359
|
+
const summary = this.getEventSummary(event);
|
|
360
|
+
const icon = this.getEventIcon(event.type);
|
|
361
|
+
|
|
362
|
+
// Simplified output for better readability
|
|
363
|
+
const output = {
|
|
364
|
+
t: new Date().toISOString().split('T')[1].split('.')[0], // HH:MM:SS
|
|
365
|
+
agent: `${this.getAgentIcon(agent.id)} ${agent.name}`,
|
|
366
|
+
phase: this.currentPhase,
|
|
367
|
+
event: `${icon} ${summary}`,
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
// Add relevant details based on event type
|
|
371
|
+
if (event.type === 'tool_use' && event.name) {
|
|
372
|
+
output.tool = event.name;
|
|
373
|
+
} else if (event.type === 'error' && event.error) {
|
|
374
|
+
output.error = event.error;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
console.log(JSON.stringify(output));
|
|
378
|
+
} else {
|
|
379
|
+
// Format output for text mode
|
|
380
|
+
switch (event.type) {
|
|
381
|
+
case 'tool_use':
|
|
382
|
+
console.log(` [${agent.name}] ๐ง Using tool: ${event.name}`);
|
|
383
|
+
break;
|
|
384
|
+
case 'message':
|
|
385
|
+
console.log(` [${agent.name}] ๐ฌ ${event.content}`);
|
|
386
|
+
break;
|
|
387
|
+
case 'completion':
|
|
388
|
+
console.log(` [${agent.name}] โ
Task completed`);
|
|
389
|
+
break;
|
|
390
|
+
case 'error':
|
|
391
|
+
console.error(` [${agent.name}] โ Error: ${event.error}`);
|
|
392
|
+
break;
|
|
393
|
+
default:
|
|
394
|
+
// Log other events in debug mode
|
|
395
|
+
if (this.options.logLevel === 'debug') {
|
|
396
|
+
console.log(` [${agent.name}] ${event.type}: ${JSON.stringify(event)}`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Get a brief summary of an event
|
|
404
|
+
*/
|
|
405
|
+
getEventSummary(event) {
|
|
406
|
+
switch (event.type) {
|
|
407
|
+
case 'tool_use':
|
|
408
|
+
return `Using ${event.name} tool`;
|
|
409
|
+
case 'message':
|
|
410
|
+
return event.content?.substring(0, 100) + (event.content?.length > 100 ? '...' : '');
|
|
411
|
+
case 'completion':
|
|
412
|
+
return 'Task completed successfully';
|
|
413
|
+
case 'error':
|
|
414
|
+
return `Error: ${event.error}`;
|
|
415
|
+
case 'status':
|
|
416
|
+
return event.status || 'Status update';
|
|
417
|
+
default:
|
|
418
|
+
return event.type;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Get icon for event type
|
|
424
|
+
*/
|
|
425
|
+
getEventIcon(eventType) {
|
|
426
|
+
const icons = {
|
|
427
|
+
tool_use: '๐ง',
|
|
428
|
+
message: '๐ฌ',
|
|
429
|
+
completion: 'โ
',
|
|
430
|
+
error: 'โ',
|
|
431
|
+
status: '๐',
|
|
432
|
+
init: '๐',
|
|
433
|
+
thinking: '๐ค',
|
|
434
|
+
result: '๐',
|
|
435
|
+
};
|
|
436
|
+
return icons[eventType] || '๐';
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Create task-specific Claude prompt with comprehensive MLE-STAR instructions
|
|
441
|
+
*/
|
|
442
|
+
createTaskPrompt(task, agent, workflow) {
|
|
443
|
+
// Use the claudePrompt from the task if available
|
|
444
|
+
if (task.claudePrompt) {
|
|
445
|
+
// Apply variable substitutions to the prompt
|
|
446
|
+
let basePrompt = task.claudePrompt;
|
|
447
|
+
const allVariables = { ...workflow.variables, ...task.input };
|
|
448
|
+
|
|
449
|
+
for (const [key, value] of Object.entries(allVariables)) {
|
|
450
|
+
const pattern = new RegExp(`\\$\\{${key}\\}`, 'g');
|
|
451
|
+
basePrompt = basePrompt.replace(pattern, value);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Create comprehensive task prompt with MLE-STAR methodology
|
|
455
|
+
return `๐ฏ MLE-STAR AGENT TASK EXECUTION
|
|
456
|
+
|
|
457
|
+
You are the **${agent.name}** (${agent.type}) in a coordinated MLE-STAR automation workflow.
|
|
458
|
+
|
|
459
|
+
๐ IMMEDIATE TASK:
|
|
460
|
+
${basePrompt}
|
|
461
|
+
|
|
462
|
+
๐ค AGENT ROLE & SPECIALIZATION:
|
|
463
|
+
${this.getAgentRoleDescription(agent.type)}
|
|
464
|
+
|
|
465
|
+
๐ฏ AGENT CAPABILITIES:
|
|
466
|
+
${agent.config?.capabilities?.join(', ') || 'general automation'}
|
|
467
|
+
|
|
468
|
+
๐ฌ MLE-STAR METHODOLOGY FOCUS:
|
|
469
|
+
${this.getMethodologyGuidance(agent.type)}
|
|
470
|
+
|
|
471
|
+
๐ง COORDINATION REQUIREMENTS:
|
|
472
|
+
1. **HOOKS INTEGRATION** (CRITICAL):
|
|
473
|
+
- BEFORE starting: \`npx claude-flow@alpha hooks pre-task --description "${task.description}"\`
|
|
474
|
+
- AFTER each file operation: \`npx claude-flow@alpha hooks post-edit --file "[filepath]"\`
|
|
475
|
+
- WHEN complete: \`npx claude-flow@alpha hooks post-task --task-id "${task.id}"\`
|
|
476
|
+
|
|
477
|
+
2. **MEMORY STORAGE** (CRITICAL):
|
|
478
|
+
- Store findings: \`npx claude-flow@alpha memory store "agent/${agent.id}/findings" "[your_findings]"\`
|
|
479
|
+
- Store results: \`npx claude-flow@alpha memory store "agent/${agent.id}/results" "[your_results]"\`
|
|
480
|
+
- Check other agents: \`npx claude-flow@alpha memory search "agent/*"\`
|
|
481
|
+
|
|
482
|
+
3. **SESSION COORDINATION**:
|
|
483
|
+
- Session ID: ${this.sessionId}
|
|
484
|
+
- Execution ID: ${this.executionId}
|
|
485
|
+
- Task ID: ${task.id}
|
|
486
|
+
- Agent ID: ${agent.id}
|
|
487
|
+
|
|
488
|
+
4. **WORKFLOW PIPELINE AWARENESS**:
|
|
489
|
+
- Your position: ${this.getAgentPositionInPipeline(agent.type)}
|
|
490
|
+
- Coordinate with: ${this.getCoordinationPartners(agent.type)}
|
|
491
|
+
- File naming: Use \`${agent.id}_[component].[ext]\` convention
|
|
492
|
+
|
|
493
|
+
5. **OUTPUT REQUIREMENTS**:
|
|
494
|
+
- Use detailed progress reporting
|
|
495
|
+
- Document methodology decisions
|
|
496
|
+
- Provide clear deliverables
|
|
497
|
+
- Follow MLE-STAR best practices for your role
|
|
498
|
+
|
|
499
|
+
๐ EXECUTION INSTRUCTIONS:
|
|
500
|
+
1. Start with hooks pre-task command
|
|
501
|
+
2. Execute your specialized MLE-STAR role
|
|
502
|
+
3. Store all findings and results in memory
|
|
503
|
+
4. Coordinate with other agents as needed
|
|
504
|
+
5. Complete with hooks post-task command
|
|
505
|
+
6. Exit when task is fully complete
|
|
506
|
+
|
|
507
|
+
๐ฏ SUCCESS CRITERIA:
|
|
508
|
+
- Task objective completed according to MLE-STAR methodology
|
|
509
|
+
- All coordination hooks executed successfully
|
|
510
|
+
- Results stored in memory for other agents
|
|
511
|
+
- Clear documentation of approach and findings
|
|
512
|
+
- Ready for next pipeline phase
|
|
513
|
+
|
|
514
|
+
Begin execution now with the hooks pre-task command.`;
|
|
515
|
+
} else {
|
|
516
|
+
// Fallback to full agent prompt
|
|
517
|
+
return this.createAgentPrompt(agent);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Create agent-specific Claude prompt
|
|
523
|
+
*/
|
|
524
|
+
createAgentPrompt(agent) {
|
|
525
|
+
const { config } = agent;
|
|
526
|
+
const capabilities = config?.capabilities?.join(', ') || 'general automation';
|
|
527
|
+
|
|
528
|
+
return `You are the ${agent.name} in a coordinated MLE-STAR automation workflow.
|
|
529
|
+
|
|
530
|
+
๐ฏ AGENT ROLE: ${agent.type.toUpperCase()}
|
|
531
|
+
๐ CAPABILITIES: ${capabilities}
|
|
532
|
+
๐ AGENT ID: ${agent.id}
|
|
533
|
+
|
|
534
|
+
CRITICAL COORDINATION REQUIREMENTS:
|
|
535
|
+
1. HOOKS: Use claude-flow hooks for coordination:
|
|
536
|
+
- Run "npx claude-flow@alpha hooks pre-task --description '[your task]'" before starting
|
|
537
|
+
- Run "npx claude-flow@alpha hooks post-edit --file '[file]'" after each file operation
|
|
538
|
+
- Run "npx claude-flow@alpha hooks post-task --task-id '${agent.id}'" when complete
|
|
539
|
+
|
|
540
|
+
2. MEMORY: Store all findings and results:
|
|
541
|
+
- Use "npx claude-flow@alpha memory store 'agent/${agent.id}/[key]' '[value]'" for important data
|
|
542
|
+
- Check "npx claude-flow@alpha memory search 'agent/*'" for coordination with other agents
|
|
543
|
+
|
|
544
|
+
3. SESSION: Maintain session coordination:
|
|
545
|
+
- Session ID: ${this.sessionId}
|
|
546
|
+
- Execution ID: ${this.executionId}
|
|
547
|
+
|
|
548
|
+
AGENT-SPECIFIC CONFIGURATION:
|
|
549
|
+
${JSON.stringify(config, null, 2)}
|
|
550
|
+
|
|
551
|
+
MLE-STAR METHODOLOGY FOCUS:
|
|
552
|
+
${this.getMethodologyGuidance(agent.type)}
|
|
553
|
+
|
|
554
|
+
WORKFLOW COORDINATION:
|
|
555
|
+
- Work with other agents in the pipeline: Search โ Foundation โ Refinement โ Ensemble โ Validation
|
|
556
|
+
- Share findings through memory system
|
|
557
|
+
- Use proper file naming conventions: ${agent.id}_[component].[ext]
|
|
558
|
+
- Follow MLE-STAR best practices for your role
|
|
559
|
+
|
|
560
|
+
Execute your role in the MLE-STAR workflow with full coordination and hook integration.`;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Create master coordination prompt for interactive mode
|
|
565
|
+
*/
|
|
566
|
+
createMasterCoordinationPrompt(agents) {
|
|
567
|
+
const workflowData = this.currentWorkflow || {
|
|
568
|
+
name: 'MLE-STAR Workflow',
|
|
569
|
+
description: 'Machine Learning Engineering via Search and Targeted Refinement',
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
return `๐ MLE-STAR WORKFLOW COORDINATION MASTER
|
|
573
|
+
|
|
574
|
+
You are the MASTER COORDINATOR for a comprehensive MLE-STAR (Machine Learning Engineering via Search and Targeted Refinement) workflow.
|
|
575
|
+
|
|
576
|
+
๐ WORKFLOW: ${workflowData.name}
|
|
577
|
+
๐ฏ DESCRIPTION: ${workflowData.description}
|
|
578
|
+
๐ EXECUTION ID: ${this.executionId}
|
|
579
|
+
๐ SESSION ID: ${this.sessionId}
|
|
580
|
+
|
|
581
|
+
๐ค SUB-AGENTS TO COORDINATE (${agents.length} total):
|
|
582
|
+
${agents
|
|
583
|
+
.map(
|
|
584
|
+
(agent, index) => `
|
|
585
|
+
${index + 1}. ${agent.name} (${agent.type})
|
|
586
|
+
๐ฏ Role: ${this.getAgentRoleDescription(agent.type)}
|
|
587
|
+
๐ Capabilities: ${agent.config?.capabilities?.join(', ') || 'general automation'}
|
|
588
|
+
๐ ID: ${agent.id}`,
|
|
589
|
+
)
|
|
590
|
+
.join('')}
|
|
591
|
+
|
|
592
|
+
๐ง CRITICAL: USE CONCURRENT STREAMS FOR PARALLEL EXECUTION
|
|
593
|
+
|
|
594
|
+
You MUST coordinate these agents using Claude's concurrent execution capabilities:
|
|
595
|
+
|
|
596
|
+
1. **USE TASK TOOL FOR CONCURRENT AGENTS**:
|
|
597
|
+
For each sub-agent, use the Task tool to spawn them with detailed prompts:
|
|
598
|
+
|
|
599
|
+
Task("You are ${agent.name}. ${detailed_role_prompt}", "${agent.id}", "agent-${agent.type}")
|
|
600
|
+
|
|
601
|
+
2. **PARALLEL EXECUTION PATTERN**:
|
|
602
|
+
Execute multiple agents simultaneously using the Task tool in a single response:
|
|
603
|
+
|
|
604
|
+
\`\`\`
|
|
605
|
+
Task("Detailed prompt for Search Agent...", "search_agent", "researcher")
|
|
606
|
+
Task("Detailed prompt for Foundation Agent...", "foundation_agent", "coder")
|
|
607
|
+
Task("Detailed prompt for Refinement Agent...", "refinement_agent", "optimizer")
|
|
608
|
+
Task("Detailed prompt for Ensemble Agent...", "ensemble_agent", "analyst")
|
|
609
|
+
Task("Detailed prompt for Validation Agent...", "validation_agent", "tester")
|
|
610
|
+
\`\`\`
|
|
611
|
+
|
|
612
|
+
3. **DETAILED SUB-AGENT PROMPTS**:
|
|
613
|
+
Each Task call should include comprehensive instructions:
|
|
614
|
+
- Specific MLE-STAR role and responsibilities
|
|
615
|
+
- Required actions and deliverables
|
|
616
|
+
- Coordination requirements with other agents
|
|
617
|
+
- Output format specifications
|
|
618
|
+
- Use of --output-format stream-json for progress tracking
|
|
619
|
+
|
|
620
|
+
4. **COORDINATION WORKFLOW**:
|
|
621
|
+
Phase 1: Search & Foundation (parallel)
|
|
622
|
+
Phase 2: Refinement & Optimization (depends on Phase 1)
|
|
623
|
+
Phase 3: Ensemble & Validation (depends on Phase 2)
|
|
624
|
+
|
|
625
|
+
5. **OUTPUT MANAGEMENT**:
|
|
626
|
+
Instruct each agent to use appropriate Claude CLI flags:
|
|
627
|
+
- Use --print --output-format stream-json --verbose for real-time progress
|
|
628
|
+
- Coordinate results through file system and memory
|
|
629
|
+
|
|
630
|
+
๐ฏ YOUR MISSION:
|
|
631
|
+
1. Launch all ${agents.length} sub-agents using concurrent Task calls
|
|
632
|
+
2. Provide detailed, specific prompts for each agent's MLE-STAR role
|
|
633
|
+
3. Coordinate the workflow execution phases
|
|
634
|
+
4. Monitor progress and provide updates
|
|
635
|
+
5. Synthesize final results
|
|
636
|
+
|
|
637
|
+
METHODOLOGY PHASES:
|
|
638
|
+
${this.getMasterMethodologyGuide()}
|
|
639
|
+
|
|
640
|
+
๐ BEGIN: Start by deploying all sub-agents with detailed prompts using the Task tool for concurrent execution. Each agent should receive comprehensive instructions for their specific MLE-STAR role.`;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Get agent role description for coordination
|
|
645
|
+
*/
|
|
646
|
+
getAgentRoleDescription(agentType) {
|
|
647
|
+
const roles = {
|
|
648
|
+
researcher: 'Web Search & Foundation Discovery - Find state-of-the-art approaches',
|
|
649
|
+
coder: 'Model Implementation & Training Pipeline - Build foundation models',
|
|
650
|
+
optimizer: 'Performance Tuning & Architecture Refinement - Optimize models',
|
|
651
|
+
analyst: 'Ensemble Methods & Meta-Learning - Combine multiple approaches',
|
|
652
|
+
tester: 'Validation & Debugging - Ensure quality and performance',
|
|
653
|
+
coordinator: 'Workflow Orchestration - Manage overall pipeline',
|
|
654
|
+
};
|
|
655
|
+
return roles[agentType] || 'Specialized automation task execution';
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Get comprehensive methodology guide for master coordinator
|
|
660
|
+
*/
|
|
661
|
+
getMasterMethodologyGuide() {
|
|
662
|
+
return `
|
|
663
|
+
PHASE 1 - SEARCH & FOUNDATION (Parallel):
|
|
664
|
+
๐ฌ Search Agent: Research ML approaches, algorithms, and best practices
|
|
665
|
+
๐ป Foundation Agent: Implement baseline models and training infrastructure
|
|
666
|
+
|
|
667
|
+
PHASE 2 - REFINEMENT (Sequential, depends on Phase 1):
|
|
668
|
+
โก Refinement Agent: Optimize models, tune hyperparameters, improve performance
|
|
669
|
+
|
|
670
|
+
PHASE 3 - ENSEMBLE & VALIDATION (Parallel, depends on Phase 2):
|
|
671
|
+
๐๏ธ Ensemble Agent: Combine models, implement voting/stacking strategies
|
|
672
|
+
๐งช Validation Agent: Test, debug, validate performance, generate reports
|
|
673
|
+
|
|
674
|
+
COORDINATION KEY POINTS:
|
|
675
|
+
- Use shared file system for intermediate results
|
|
676
|
+
- Maintain communication through progress updates
|
|
677
|
+
- Each phase builds on previous phases
|
|
678
|
+
- Final deliverable: Production-ready ML pipeline`;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Get agent position in MLE-STAR pipeline
|
|
683
|
+
*/
|
|
684
|
+
getAgentPositionInPipeline(agentType) {
|
|
685
|
+
const positions = {
|
|
686
|
+
researcher: 'Phase 1: Search & Foundation Discovery (Parallel with Foundation)',
|
|
687
|
+
coder: 'Phase 1: Foundation Model Building (Parallel with Search)',
|
|
688
|
+
optimizer: 'Phase 2: Refinement & Optimization (Sequential, depends on Phase 1)',
|
|
689
|
+
analyst: 'Phase 3: Ensemble & Meta-Learning (Parallel with Validation)',
|
|
690
|
+
tester: 'Phase 3: Validation & Debugging (Parallel with Ensemble)',
|
|
691
|
+
coordinator: 'All Phases: Workflow Orchestration & Coordination',
|
|
692
|
+
};
|
|
693
|
+
return positions[agentType] || 'Specialized task execution';
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Get coordination partners for agent type
|
|
698
|
+
*/
|
|
699
|
+
getCoordinationPartners(agentType) {
|
|
700
|
+
const partners = {
|
|
701
|
+
researcher: 'Foundation Agent (parallel), Refinement Agent (handoff)',
|
|
702
|
+
coder: 'Search Agent (parallel), Refinement Agent (handoff)',
|
|
703
|
+
optimizer: 'Search & Foundation Agents (input), Ensemble & Validation Agents (handoff)',
|
|
704
|
+
analyst: 'Refinement Agent (input), Validation Agent (parallel)',
|
|
705
|
+
tester: 'All previous agents (validation), Ensemble Agent (parallel)',
|
|
706
|
+
coordinator: 'All agents (orchestration and monitoring)',
|
|
707
|
+
};
|
|
708
|
+
return partners[agentType] || 'Other workflow agents as needed';
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Get methodology guidance for agent type
|
|
713
|
+
*/
|
|
714
|
+
getMethodologyGuidance(agentType) {
|
|
715
|
+
const guidance = {
|
|
716
|
+
researcher: `SEARCH PHASE - Web Research & Foundation Discovery:
|
|
717
|
+
- Search for state-of-the-art ML approaches for the problem domain
|
|
718
|
+
- Find winning Kaggle solutions and benchmark results
|
|
719
|
+
- Identify promising model architectures and techniques
|
|
720
|
+
- Document implementation examples and model cards
|
|
721
|
+
- Focus on proven, recent approaches with good performance`,
|
|
722
|
+
|
|
723
|
+
coder: `FOUNDATION PHASE - Initial Model Building:
|
|
724
|
+
- Analyze dataset characteristics and problem type
|
|
725
|
+
- Implement baseline models based on research findings
|
|
726
|
+
- Create robust preprocessing pipelines
|
|
727
|
+
- Build modular, testable code components
|
|
728
|
+
- Establish performance baselines for comparison`,
|
|
729
|
+
|
|
730
|
+
optimizer: `REFINEMENT PHASE - Targeted Component Optimization:
|
|
731
|
+
- Perform ablation analysis to identify high-impact components
|
|
732
|
+
- Focus deep optimization on most impactful pipeline elements
|
|
733
|
+
- Use iterative improvement with structured feedback
|
|
734
|
+
- Implement advanced feature engineering techniques
|
|
735
|
+
- Optimize hyperparameters systematically`,
|
|
736
|
+
|
|
737
|
+
architect: `ENSEMBLE PHASE - Intelligent Model Combination:
|
|
738
|
+
- Create sophisticated ensemble strategies beyond simple averaging
|
|
739
|
+
- Implement stacking with meta-learners
|
|
740
|
+
- Use dynamic weighting and mixture of experts
|
|
741
|
+
- Apply Bayesian model averaging where appropriate
|
|
742
|
+
- Optimize ensemble composition for maximum performance`,
|
|
743
|
+
|
|
744
|
+
tester: `VALIDATION PHASE - Comprehensive Testing & Debugging:
|
|
745
|
+
- Implement rigorous cross-validation strategies
|
|
746
|
+
- Detect and prevent data leakage
|
|
747
|
+
- Perform error analysis and debugging
|
|
748
|
+
- Validate model robustness and generalization
|
|
749
|
+
- Ensure production readiness with quality checks`,
|
|
750
|
+
|
|
751
|
+
coordinator: `ORCHESTRATION PHASE - Workflow Management:
|
|
752
|
+
- Coordinate between all agents and phases
|
|
753
|
+
- Monitor progress and performance metrics
|
|
754
|
+
- Manage resource allocation and scheduling
|
|
755
|
+
- Handle error recovery and workflow adaptation
|
|
756
|
+
- Prepare final deployment and documentation`,
|
|
757
|
+
};
|
|
758
|
+
|
|
759
|
+
return (
|
|
760
|
+
guidance[agentType] ||
|
|
761
|
+
'Focus on your specialized capabilities and coordinate with other agents.'
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Execute workflow tasks with dependency management
|
|
767
|
+
*/
|
|
768
|
+
async executeWorkflowTasks(workflow) {
|
|
769
|
+
const { tasks, dependencies = {} } = workflow;
|
|
770
|
+
|
|
771
|
+
let completedTasks = 0;
|
|
772
|
+
let failedTasks = 0;
|
|
773
|
+
const totalTasks = tasks.length;
|
|
774
|
+
|
|
775
|
+
// Task status tracking
|
|
776
|
+
const taskStatuses = new Map();
|
|
777
|
+
tasks.forEach((task) => {
|
|
778
|
+
taskStatuses.set(task.id, {
|
|
779
|
+
name: task.name || task.id,
|
|
780
|
+
status: 'pending',
|
|
781
|
+
agent: task.assignTo,
|
|
782
|
+
startTime: null,
|
|
783
|
+
endTime: null,
|
|
784
|
+
summary: '',
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
// Create task execution plan based on dependencies
|
|
789
|
+
const executionPlan = this.createExecutionPlan(tasks, dependencies);
|
|
790
|
+
|
|
791
|
+
console.log(`๐ Executing ${totalTasks} tasks in ${executionPlan.length} phases...`);
|
|
792
|
+
console.log();
|
|
793
|
+
|
|
794
|
+
// Note: Concurrent display disabled in favor of interactive-style stream processing
|
|
795
|
+
let concurrentDisplay = null;
|
|
796
|
+
// if (this.options.nonInteractive && this.options.outputFormat === 'stream-json') {
|
|
797
|
+
// const { createConcurrentDisplay } = await import('./concurrent-display.js');
|
|
798
|
+
//
|
|
799
|
+
// // Get all agents and their tasks
|
|
800
|
+
// const agentTasks = workflow.agents?.map(agent => ({
|
|
801
|
+
// id: agent.id,
|
|
802
|
+
// name: agent.name,
|
|
803
|
+
// type: agent.type,
|
|
804
|
+
// tasks: tasks.filter(t => t.assignTo === agent.id).map(t => t.name)
|
|
805
|
+
// })) || [];
|
|
806
|
+
//
|
|
807
|
+
// concurrentDisplay = createConcurrentDisplay(agentTasks);
|
|
808
|
+
// concurrentDisplay.start();
|
|
809
|
+
//
|
|
810
|
+
// // Store reference for stream processors
|
|
811
|
+
// this.concurrentDisplay = concurrentDisplay;
|
|
812
|
+
// }
|
|
813
|
+
|
|
814
|
+
// Execute tasks phase by phase
|
|
815
|
+
for (const [phaseIndex, phaseTasks] of executionPlan.entries()) {
|
|
816
|
+
this.currentPhase = `Phase ${phaseIndex + 1}`;
|
|
817
|
+
|
|
818
|
+
// Show regular task board or update concurrent display
|
|
819
|
+
if (!concurrentDisplay) {
|
|
820
|
+
if (this.options.logLevel === 'quiet') {
|
|
821
|
+
console.log(`\n๐ Phase ${phaseIndex + 1}: Running ${phaseTasks.length} tasks`);
|
|
822
|
+
} else {
|
|
823
|
+
console.log(`\n๐ Phase ${phaseIndex + 1}: ${phaseTasks.length} concurrent tasks`);
|
|
824
|
+
}
|
|
825
|
+
this.displayTaskBoard(taskStatuses, phaseTasks);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// Mark tasks as in-progress
|
|
829
|
+
phaseTasks.forEach((task) => {
|
|
830
|
+
const status = taskStatuses.get(task.id);
|
|
831
|
+
status.status = 'in-progress';
|
|
832
|
+
status.startTime = Date.now();
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
// Execute tasks in this phase (potentially in parallel)
|
|
836
|
+
const phasePromises = phaseTasks.map(async (task) => {
|
|
837
|
+
const taskStatus = taskStatuses.get(task.id);
|
|
838
|
+
|
|
839
|
+
try {
|
|
840
|
+
// Show task starting
|
|
841
|
+
console.log(`\n ๐ Starting: ${task.name || task.id}`);
|
|
842
|
+
console.log(` Agent: ${task.assignTo}`);
|
|
843
|
+
console.log(` Description: ${task.description?.substring(0, 80)}...`);
|
|
844
|
+
|
|
845
|
+
const result = await this.executeTask(task, workflow);
|
|
846
|
+
|
|
847
|
+
taskStatus.status = result.success ? 'completed' : 'failed';
|
|
848
|
+
taskStatus.endTime = Date.now();
|
|
849
|
+
taskStatus.summary = result.success
|
|
850
|
+
? `โ
Completed in ${this.formatDuration(result.duration)}`
|
|
851
|
+
: `โ Failed: ${result.error?.message || 'Unknown error'}`;
|
|
852
|
+
|
|
853
|
+
return result;
|
|
854
|
+
} catch (error) {
|
|
855
|
+
taskStatus.status = 'failed';
|
|
856
|
+
taskStatus.endTime = Date.now();
|
|
857
|
+
taskStatus.summary = `โ Error: ${error.message}`;
|
|
858
|
+
throw error;
|
|
859
|
+
}
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
// Wait for all phase tasks to complete
|
|
863
|
+
const phaseResults = await Promise.allSettled(phasePromises);
|
|
864
|
+
|
|
865
|
+
// Process phase results
|
|
866
|
+
for (const [taskIndex, result] of phaseResults.entries()) {
|
|
867
|
+
const task = phaseTasks[taskIndex];
|
|
868
|
+
const taskStatus = taskStatuses.get(task.id);
|
|
869
|
+
|
|
870
|
+
if (result.status === 'fulfilled' && result.value.success) {
|
|
871
|
+
completedTasks++;
|
|
872
|
+
this.results.set(task.id, result.value);
|
|
873
|
+
} else {
|
|
874
|
+
failedTasks++;
|
|
875
|
+
const error = result.status === 'rejected' ? result.reason : result.value.error;
|
|
876
|
+
this.errors.push({
|
|
877
|
+
type: 'task_execution',
|
|
878
|
+
task: task.id,
|
|
879
|
+
error: error.message || error,
|
|
880
|
+
timestamp: new Date(),
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
// Check if we should fail fast
|
|
884
|
+
if (workflow.settings?.failurePolicy === 'fail-fast') {
|
|
885
|
+
console.log(`\n๐ Failing fast due to task failure`);
|
|
886
|
+
break;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// Show updated task board
|
|
892
|
+
if (!concurrentDisplay) {
|
|
893
|
+
console.log(`\n๐ Phase ${phaseIndex + 1} Complete:`);
|
|
894
|
+
this.displayTaskBoard(taskStatuses);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Stop if fail-fast and we have failures
|
|
898
|
+
if (workflow.settings?.failurePolicy === 'fail-fast' && failedTasks > 0) {
|
|
899
|
+
break;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// Final summary
|
|
904
|
+
if (!concurrentDisplay) {
|
|
905
|
+
console.log(`\n๐ Final Workflow Summary:`);
|
|
906
|
+
this.displayTaskBoard(taskStatuses);
|
|
907
|
+
} else {
|
|
908
|
+
// Stop concurrent display
|
|
909
|
+
concurrentDisplay.stop();
|
|
910
|
+
console.log(); // Add some space after display
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
return {
|
|
914
|
+
success: failedTasks === 0,
|
|
915
|
+
totalTasks,
|
|
916
|
+
completedTasks,
|
|
917
|
+
failedTasks,
|
|
918
|
+
executionId: this.executionId,
|
|
919
|
+
duration: Date.now() - this.startTime,
|
|
920
|
+
results: Object.fromEntries(this.results),
|
|
921
|
+
errors: this.errors,
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Display task board showing current status
|
|
927
|
+
*/
|
|
928
|
+
displayTaskBoard(taskStatuses, highlightTasks = []) {
|
|
929
|
+
// In quiet mode, just show simple progress
|
|
930
|
+
if (this.options.logLevel === 'quiet') {
|
|
931
|
+
const totalTasks = taskStatuses.size;
|
|
932
|
+
const completedTasks = Array.from(taskStatuses.values()).filter(
|
|
933
|
+
(s) => s.status === 'completed',
|
|
934
|
+
).length;
|
|
935
|
+
const activeTasks = Array.from(taskStatuses.values()).filter(
|
|
936
|
+
(s) => s.status === 'in-progress',
|
|
937
|
+
).length;
|
|
938
|
+
console.log(`๐ Progress: ${completedTasks}/${totalTasks} completed, ${activeTasks} active`);
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
const frames = ['โ ', 'โ ', 'โ น', 'โ ธ', 'โ ผ', 'โ ด', 'โ ฆ', 'โ ง', 'โ ', 'โ '];
|
|
943
|
+
const frameIndex = Math.floor(Date.now() / 100) % frames.length;
|
|
944
|
+
const spinner = frames[frameIndex];
|
|
945
|
+
|
|
946
|
+
console.log('\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
947
|
+
console.log('โ ๐ค CONCURRENT TASK STATUS โ');
|
|
948
|
+
console.log('โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ');
|
|
949
|
+
|
|
950
|
+
// Group by status
|
|
951
|
+
const statusGroups = {
|
|
952
|
+
'in-progress': [],
|
|
953
|
+
completed: [],
|
|
954
|
+
failed: [],
|
|
955
|
+
pending: [],
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
taskStatuses.forEach((status, taskId) => {
|
|
959
|
+
statusGroups[status.status].push({ taskId, ...status });
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
// Show in-progress tasks with animation
|
|
963
|
+
if (statusGroups['in-progress'].length > 0) {
|
|
964
|
+
console.log(
|
|
965
|
+
`โ ${spinner} RUNNING (${statusGroups['in-progress'].length} agents): โ`,
|
|
966
|
+
);
|
|
967
|
+
statusGroups['in-progress'].forEach((task) => {
|
|
968
|
+
const duration = task.startTime ? this.formatDuration(Date.now() - task.startTime) : '';
|
|
969
|
+
const progress = this.getProgressBar(Date.now() - task.startTime, 60000); // 1 min expected
|
|
970
|
+
const agentIcon = this.getAgentIcon(task.agent);
|
|
971
|
+
console.log(
|
|
972
|
+
`โ ${agentIcon} ${task.name.padEnd(25)} ${progress} ${duration.padStart(8)} โ`,
|
|
973
|
+
);
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// Show completed tasks
|
|
978
|
+
if (statusGroups['completed'].length > 0) {
|
|
979
|
+
console.log(
|
|
980
|
+
`โ โ
COMPLETED (${statusGroups['completed'].length}): โ`,
|
|
981
|
+
);
|
|
982
|
+
statusGroups['completed'].forEach((task) => {
|
|
983
|
+
const duration =
|
|
984
|
+
task.endTime && task.startTime ? this.formatDuration(task.endTime - task.startTime) : '';
|
|
985
|
+
console.log(`โ โ ${task.name.padEnd(35)} ${duration.padStart(10)} โ`);
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// Show failed tasks
|
|
990
|
+
if (statusGroups['failed'].length > 0) {
|
|
991
|
+
console.log(
|
|
992
|
+
`โ โ FAILED (${statusGroups['failed'].length}): โ`,
|
|
993
|
+
);
|
|
994
|
+
statusGroups['failed'].forEach((task) => {
|
|
995
|
+
const errorMsg = (task.summary || '').substring(0, 25);
|
|
996
|
+
console.log(`โ โ ${task.name.padEnd(25)} ${errorMsg.padEnd(20)} โ`);
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// Show pending tasks count
|
|
1001
|
+
if (statusGroups['pending'].length > 0) {
|
|
1002
|
+
console.log(
|
|
1003
|
+
`โ โณ QUEUED: ${statusGroups['pending'].length} tasks waiting โ`,
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// Summary stats
|
|
1008
|
+
const total = taskStatuses.size;
|
|
1009
|
+
const completed = statusGroups['completed'].length;
|
|
1010
|
+
const failed = statusGroups['failed'].length;
|
|
1011
|
+
const progress = total > 0 ? Math.floor(((completed + failed) / total) * 100) : 0;
|
|
1012
|
+
|
|
1013
|
+
console.log('โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ');
|
|
1014
|
+
console.log(
|
|
1015
|
+
`โ ๐ Progress: ${progress}% (${completed}/${total}) โ โก Active: ${statusGroups['in-progress'].length} โ โ Failed: ${failed} โ`,
|
|
1016
|
+
);
|
|
1017
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Get progress bar visualization
|
|
1022
|
+
*/
|
|
1023
|
+
getProgressBar(elapsed, expected) {
|
|
1024
|
+
const progress = Math.min(elapsed / expected, 1);
|
|
1025
|
+
const filled = Math.floor(progress * 10);
|
|
1026
|
+
const empty = 10 - filled;
|
|
1027
|
+
return '[' + 'โ'.repeat(filled) + 'โ'.repeat(empty) + ']';
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Get agent icon based on type
|
|
1032
|
+
*/
|
|
1033
|
+
getAgentIcon(agentId) {
|
|
1034
|
+
const icons = {
|
|
1035
|
+
search: '๐',
|
|
1036
|
+
foundation: '๐๏ธ',
|
|
1037
|
+
refinement: '๐ง',
|
|
1038
|
+
ensemble: '๐ฏ',
|
|
1039
|
+
validation: 'โ
',
|
|
1040
|
+
coordinator: '๐ฎ',
|
|
1041
|
+
researcher: '๐ฌ',
|
|
1042
|
+
coder: '๐ป',
|
|
1043
|
+
optimizer: 'โก',
|
|
1044
|
+
architect: '๐๏ธ',
|
|
1045
|
+
tester: '๐งช',
|
|
1046
|
+
};
|
|
1047
|
+
|
|
1048
|
+
// Extract agent type from ID
|
|
1049
|
+
const type = agentId?.split('_')[0] || 'default';
|
|
1050
|
+
return icons[type] || '๐ค';
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Execute a single task
|
|
1055
|
+
*/
|
|
1056
|
+
async executeTask(task, workflow) {
|
|
1057
|
+
const startTime = Date.now();
|
|
1058
|
+
|
|
1059
|
+
try {
|
|
1060
|
+
// Store task execution in memory if hooks enabled
|
|
1061
|
+
if (this.hooksEnabled) {
|
|
1062
|
+
await this.executeHook('notify', {
|
|
1063
|
+
message: `Starting task: ${task.name || task.id}`,
|
|
1064
|
+
sessionId: this.sessionId,
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
if (this.options.nonInteractive && this.options.outputFormat === 'stream-json') {
|
|
1069
|
+
console.log(`\nโ ${task.name || task.id} - Starting Execution`);
|
|
1070
|
+
console.log(` โฟ ${task.description}`);
|
|
1071
|
+
console.log(` โฟ Agent: ${task.assignTo}`);
|
|
1072
|
+
} else {
|
|
1073
|
+
console.log(` ๐ Executing: ${task.description}`);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// For demonstration/testing mode (when Claude integration is disabled)
|
|
1077
|
+
// we simulate successful task completion
|
|
1078
|
+
if (!this.options.enableClaude) {
|
|
1079
|
+
// Simulate variable execution time
|
|
1080
|
+
const executionTime = Math.min(
|
|
1081
|
+
1000 + Math.random() * 3000, // 1-4 seconds simulation
|
|
1082
|
+
task.timeout || 30000,
|
|
1083
|
+
);
|
|
1084
|
+
|
|
1085
|
+
await new Promise((resolve) => setTimeout(resolve, executionTime));
|
|
1086
|
+
|
|
1087
|
+
// Simulate successful completion for demo/testing
|
|
1088
|
+
const result = {
|
|
1089
|
+
success: true,
|
|
1090
|
+
taskId: task.id,
|
|
1091
|
+
duration: Date.now() - startTime,
|
|
1092
|
+
output: {
|
|
1093
|
+
status: 'completed',
|
|
1094
|
+
agent: task.assignTo,
|
|
1095
|
+
executionTime: Date.now() - startTime,
|
|
1096
|
+
metadata: {
|
|
1097
|
+
timestamp: new Date().toISOString(),
|
|
1098
|
+
executionId: this.executionId,
|
|
1099
|
+
mode: 'simulation',
|
|
1100
|
+
},
|
|
1101
|
+
},
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
// Store result in memory
|
|
1105
|
+
if (this.hooksEnabled) {
|
|
1106
|
+
await this.storeTaskResult(task.id, result.output);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
return result;
|
|
1110
|
+
} else {
|
|
1111
|
+
// When Claude integration is enabled, delegate to actual Claude instance
|
|
1112
|
+
|
|
1113
|
+
// Check if we have a master coordinator (interactive mode)
|
|
1114
|
+
const masterCoordinator = this.claudeInstances.get('master-coordinator');
|
|
1115
|
+
if (masterCoordinator && !this.options.nonInteractive) {
|
|
1116
|
+
// Interactive mode: All tasks are coordinated by the master coordinator
|
|
1117
|
+
console.log(` ๐ฏ Task delegated to Master Coordinator: ${task.description}`);
|
|
1118
|
+
|
|
1119
|
+
// In interactive mode, the master coordinator handles all tasks
|
|
1120
|
+
// We just wait for the master coordinator process to complete
|
|
1121
|
+
const completionPromise = new Promise((resolve, reject) => {
|
|
1122
|
+
masterCoordinator.process.on('exit', (code) => {
|
|
1123
|
+
if (code === 0) {
|
|
1124
|
+
resolve({ success: true, code });
|
|
1125
|
+
} else {
|
|
1126
|
+
reject(new Error(`Master coordinator exited with code ${code}`));
|
|
1127
|
+
}
|
|
1128
|
+
});
|
|
1129
|
+
|
|
1130
|
+
masterCoordinator.process.on('error', (err) => {
|
|
1131
|
+
reject(err);
|
|
1132
|
+
});
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
// For interactive mode, we use a longer timeout since user interaction is involved
|
|
1136
|
+
const timeout = Math.max(this.options.timeout, 1800000); // 30 minutes minimum for interactive
|
|
1137
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1138
|
+
setTimeout(() => reject(new Error('Interactive session timeout')), timeout);
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
try {
|
|
1142
|
+
await Promise.race([completionPromise, timeoutPromise]);
|
|
1143
|
+
|
|
1144
|
+
const result = {
|
|
1145
|
+
success: true,
|
|
1146
|
+
taskId: task.id,
|
|
1147
|
+
duration: Date.now() - startTime,
|
|
1148
|
+
output: {
|
|
1149
|
+
status: 'completed',
|
|
1150
|
+
agent: 'master-coordinator',
|
|
1151
|
+
executionTime: Date.now() - startTime,
|
|
1152
|
+
metadata: {
|
|
1153
|
+
timestamp: new Date().toISOString(),
|
|
1154
|
+
executionId: this.executionId,
|
|
1155
|
+
mode: 'interactive-coordination',
|
|
1156
|
+
},
|
|
1157
|
+
},
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
// Store result in memory
|
|
1161
|
+
if (this.hooksEnabled) {
|
|
1162
|
+
await this.storeTaskResult(task.id, result.output);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
return result;
|
|
1166
|
+
} catch (error) {
|
|
1167
|
+
throw new Error(`Task execution failed: ${error.message}`);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// Non-interactive mode or no master coordinator: use individual Claude instances
|
|
1172
|
+
const claudeInstance = this.claudeInstances.get(task.assignTo);
|
|
1173
|
+
if (!claudeInstance) {
|
|
1174
|
+
// If no pre-spawned instance, create one for this task
|
|
1175
|
+
const agent = workflow.agents.find((a) => a.id === task.assignTo);
|
|
1176
|
+
if (!agent) {
|
|
1177
|
+
throw new Error(`No agent definition found for: ${task.assignTo}`);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// Create task-specific prompt
|
|
1181
|
+
const taskPrompt = this.createTaskPrompt(task, agent, workflow);
|
|
1182
|
+
|
|
1183
|
+
// Check if we should chain from a previous task
|
|
1184
|
+
let chainOptions = {};
|
|
1185
|
+
if (
|
|
1186
|
+
this.enableChaining &&
|
|
1187
|
+
this.options.outputFormat === 'stream-json' &&
|
|
1188
|
+
task.depends?.length > 0
|
|
1189
|
+
) {
|
|
1190
|
+
// Get the output stream from the last dependency
|
|
1191
|
+
const lastDependency = task.depends[task.depends.length - 1];
|
|
1192
|
+
const dependencyStream = this.taskOutputStreams.get(lastDependency);
|
|
1193
|
+
if (dependencyStream) {
|
|
1194
|
+
console.log(` ๐ Enabling stream chaining from ${lastDependency} to ${task.id}`);
|
|
1195
|
+
chainOptions.inputStream = dependencyStream;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// Spawn Claude instance for this specific task
|
|
1200
|
+
const taskClaudeProcess = await this.spawnClaudeInstance(agent, taskPrompt, chainOptions);
|
|
1201
|
+
|
|
1202
|
+
// Store the output stream for potential chaining
|
|
1203
|
+
if (
|
|
1204
|
+
this.enableChaining &&
|
|
1205
|
+
this.options.outputFormat === 'stream-json' &&
|
|
1206
|
+
taskClaudeProcess.stdout
|
|
1207
|
+
) {
|
|
1208
|
+
this.taskOutputStreams.set(task.id, taskClaudeProcess.stdout);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
// Store the instance
|
|
1212
|
+
this.claudeInstances.set(agent.id, {
|
|
1213
|
+
process: taskClaudeProcess,
|
|
1214
|
+
agent: agent,
|
|
1215
|
+
status: 'active',
|
|
1216
|
+
startTime: Date.now(),
|
|
1217
|
+
taskId: task.id,
|
|
1218
|
+
});
|
|
1219
|
+
|
|
1220
|
+
// Wait for task completion or timeout
|
|
1221
|
+
// Use longer timeout for ML tasks
|
|
1222
|
+
const baseTimeout = this.options.timeout || 60000;
|
|
1223
|
+
const isMLTask =
|
|
1224
|
+
task.type?.toLowerCase().includes('ml') ||
|
|
1225
|
+
task.type?.toLowerCase().includes('model') ||
|
|
1226
|
+
task.type?.toLowerCase().includes('search') ||
|
|
1227
|
+
task.type?.toLowerCase().includes('analysis') ||
|
|
1228
|
+
this.options.workflowType === 'ml';
|
|
1229
|
+
const timeout = task.timeout || (isMLTask ? Math.max(baseTimeout, 300000) : baseTimeout); // Min 5 minutes for ML tasks
|
|
1230
|
+
|
|
1231
|
+
if (this.options.logLevel === 'debug' || this.options.verbose) {
|
|
1232
|
+
console.log(
|
|
1233
|
+
` โฑ๏ธ Timeout: ${this.formatDuration(timeout)} (Base: ${this.formatDuration(baseTimeout)}, ML Task: ${isMLTask})`,
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
const completionPromise = new Promise((resolve, reject) => {
|
|
1238
|
+
taskClaudeProcess.on('exit', (code) => {
|
|
1239
|
+
if (code === 0) {
|
|
1240
|
+
resolve({ success: true, code });
|
|
1241
|
+
} else {
|
|
1242
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
taskClaudeProcess.on('error', (err) => {
|
|
1247
|
+
reject(err);
|
|
1248
|
+
});
|
|
1249
|
+
});
|
|
1250
|
+
|
|
1251
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1252
|
+
// Use a much longer timeout for ML tasks since Claude is actively working
|
|
1253
|
+
const actualTimeout = isMLTask ? Math.max(timeout, 600000) : timeout; // 10 min minimum for ML
|
|
1254
|
+
setTimeout(() => reject(new Error('Task timeout')), actualTimeout);
|
|
1255
|
+
});
|
|
1256
|
+
|
|
1257
|
+
try {
|
|
1258
|
+
await Promise.race([completionPromise, timeoutPromise]);
|
|
1259
|
+
|
|
1260
|
+
const result = {
|
|
1261
|
+
success: true,
|
|
1262
|
+
taskId: task.id,
|
|
1263
|
+
duration: Date.now() - startTime,
|
|
1264
|
+
output: {
|
|
1265
|
+
status: 'completed',
|
|
1266
|
+
agent: task.assignTo,
|
|
1267
|
+
executionTime: Date.now() - startTime,
|
|
1268
|
+
metadata: {
|
|
1269
|
+
timestamp: new Date().toISOString(),
|
|
1270
|
+
executionId: this.executionId,
|
|
1271
|
+
mode: 'claude-task-execution',
|
|
1272
|
+
},
|
|
1273
|
+
},
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
// Store result in memory
|
|
1277
|
+
if (this.hooksEnabled) {
|
|
1278
|
+
await this.storeTaskResult(task.id, result.output);
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
return result;
|
|
1282
|
+
} catch (error) {
|
|
1283
|
+
throw error;
|
|
1284
|
+
}
|
|
1285
|
+
} else {
|
|
1286
|
+
// Use existing Claude instance
|
|
1287
|
+
// In a full implementation, this would send the task to the running instance
|
|
1288
|
+
// For now, we'll spawn a new instance per task for simplicity
|
|
1289
|
+
|
|
1290
|
+
const agent = claudeInstance.agent;
|
|
1291
|
+
const taskPrompt = this.createTaskPrompt(task, agent, workflow);
|
|
1292
|
+
|
|
1293
|
+
// Check if we should chain from a previous task
|
|
1294
|
+
let chainOptions = {};
|
|
1295
|
+
if (
|
|
1296
|
+
this.enableChaining &&
|
|
1297
|
+
this.options.outputFormat === 'stream-json' &&
|
|
1298
|
+
task.depends?.length > 0
|
|
1299
|
+
) {
|
|
1300
|
+
// Get the output stream from the last dependency
|
|
1301
|
+
const lastDependency = task.depends[task.depends.length - 1];
|
|
1302
|
+
const dependencyStream = this.taskOutputStreams.get(lastDependency);
|
|
1303
|
+
if (dependencyStream) {
|
|
1304
|
+
console.log(` ๐ Enabling stream chaining from ${lastDependency} to ${task.id}`);
|
|
1305
|
+
chainOptions.inputStream = dependencyStream;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
// For now, spawn a new instance for each task
|
|
1310
|
+
const taskClaudeProcess = await this.spawnClaudeInstance(agent, taskPrompt, chainOptions);
|
|
1311
|
+
|
|
1312
|
+
// Store the output stream for potential chaining
|
|
1313
|
+
if (
|
|
1314
|
+
this.enableChaining &&
|
|
1315
|
+
this.options.outputFormat === 'stream-json' &&
|
|
1316
|
+
taskClaudeProcess.stdout
|
|
1317
|
+
) {
|
|
1318
|
+
this.taskOutputStreams.set(task.id, taskClaudeProcess.stdout);
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
// Wait for completion
|
|
1322
|
+
// Use longer timeout for ML tasks
|
|
1323
|
+
const baseTimeout = this.options.timeout || 60000;
|
|
1324
|
+
const isMLTask =
|
|
1325
|
+
task.type?.toLowerCase().includes('ml') ||
|
|
1326
|
+
task.type?.toLowerCase().includes('model') ||
|
|
1327
|
+
task.type?.toLowerCase().includes('search') ||
|
|
1328
|
+
task.type?.toLowerCase().includes('analysis') ||
|
|
1329
|
+
this.options.workflowType === 'ml';
|
|
1330
|
+
const timeout = task.timeout || (isMLTask ? Math.max(baseTimeout, 300000) : baseTimeout); // Min 5 minutes for ML tasks
|
|
1331
|
+
|
|
1332
|
+
if (this.options.logLevel === 'debug' || this.options.verbose) {
|
|
1333
|
+
console.log(
|
|
1334
|
+
` โฑ๏ธ Timeout: ${this.formatDuration(timeout)} (Base: ${this.formatDuration(baseTimeout)}, ML Task: ${isMLTask})`,
|
|
1335
|
+
);
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
const completionPromise = new Promise((resolve, reject) => {
|
|
1339
|
+
taskClaudeProcess.on('exit', (code) => {
|
|
1340
|
+
if (code === 0) {
|
|
1341
|
+
resolve({ success: true, code });
|
|
1342
|
+
} else {
|
|
1343
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
1344
|
+
}
|
|
1345
|
+
});
|
|
1346
|
+
|
|
1347
|
+
taskClaudeProcess.on('error', (err) => {
|
|
1348
|
+
reject(err);
|
|
1349
|
+
});
|
|
1350
|
+
});
|
|
1351
|
+
|
|
1352
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1353
|
+
// Use a much longer timeout for ML tasks since Claude is actively working
|
|
1354
|
+
const actualTimeout = isMLTask ? Math.max(timeout, 600000) : timeout; // 10 min minimum for ML
|
|
1355
|
+
setTimeout(() => reject(new Error('Task timeout')), actualTimeout);
|
|
1356
|
+
});
|
|
1357
|
+
|
|
1358
|
+
try {
|
|
1359
|
+
await Promise.race([completionPromise, timeoutPromise]);
|
|
1360
|
+
|
|
1361
|
+
const result = {
|
|
1362
|
+
success: true,
|
|
1363
|
+
taskId: task.id,
|
|
1364
|
+
duration: Date.now() - startTime,
|
|
1365
|
+
output: {
|
|
1366
|
+
status: 'completed',
|
|
1367
|
+
agent: task.assignTo,
|
|
1368
|
+
executionTime: Date.now() - startTime,
|
|
1369
|
+
metadata: {
|
|
1370
|
+
timestamp: new Date().toISOString(),
|
|
1371
|
+
executionId: this.executionId,
|
|
1372
|
+
mode: 'claude-task-execution',
|
|
1373
|
+
},
|
|
1374
|
+
},
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
// Store result in memory
|
|
1378
|
+
if (this.hooksEnabled) {
|
|
1379
|
+
await this.storeTaskResult(task.id, result.output);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
return result;
|
|
1383
|
+
} catch (error) {
|
|
1384
|
+
throw error;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
} catch (error) {
|
|
1389
|
+
return {
|
|
1390
|
+
success: false,
|
|
1391
|
+
taskId: task.id,
|
|
1392
|
+
duration: Date.now() - startTime,
|
|
1393
|
+
error: error,
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* Create execution plan based on task dependencies
|
|
1400
|
+
*/
|
|
1401
|
+
createExecutionPlan(tasks, dependencies) {
|
|
1402
|
+
const taskMap = new Map(tasks.map((task) => [task.id, task]));
|
|
1403
|
+
const completed = new Set();
|
|
1404
|
+
const phases = [];
|
|
1405
|
+
|
|
1406
|
+
while (completed.size < tasks.length) {
|
|
1407
|
+
const readyTasks = tasks.filter((task) => {
|
|
1408
|
+
if (completed.has(task.id)) return false;
|
|
1409
|
+
|
|
1410
|
+
const deps = task.depends || dependencies[task.id] || [];
|
|
1411
|
+
return deps.every((dep) => completed.has(dep));
|
|
1412
|
+
});
|
|
1413
|
+
|
|
1414
|
+
if (readyTasks.length === 0) {
|
|
1415
|
+
throw new Error('Circular dependency detected or invalid dependencies');
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
phases.push(readyTasks);
|
|
1419
|
+
readyTasks.forEach((task) => completed.add(task.id));
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
return phases;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
/**
|
|
1426
|
+
* Execute a hook command
|
|
1427
|
+
*/
|
|
1428
|
+
async executeHook(hookType, params) {
|
|
1429
|
+
try {
|
|
1430
|
+
const { execSync } = await import('child_process');
|
|
1431
|
+
|
|
1432
|
+
let hookCommand = `npx claude-flow@alpha hooks ${hookType}`;
|
|
1433
|
+
|
|
1434
|
+
if (params.description) {
|
|
1435
|
+
hookCommand += ` --description "${params.description}"`;
|
|
1436
|
+
}
|
|
1437
|
+
if (params.file) {
|
|
1438
|
+
hookCommand += ` --file "${params.file}"`;
|
|
1439
|
+
}
|
|
1440
|
+
if (params.taskId) {
|
|
1441
|
+
hookCommand += ` --task-id "${params.taskId}"`;
|
|
1442
|
+
}
|
|
1443
|
+
if (params.sessionId) {
|
|
1444
|
+
hookCommand += ` --session-id "${params.sessionId}"`;
|
|
1445
|
+
}
|
|
1446
|
+
if (params.message) {
|
|
1447
|
+
hookCommand += ` --message "${params.message}"`;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
execSync(hookCommand, { stdio: 'pipe' });
|
|
1451
|
+
} catch (error) {
|
|
1452
|
+
// Hooks are optional, don't fail the workflow if they fail
|
|
1453
|
+
console.debug(`Hook ${hookType} failed:`, error.message);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
/**
|
|
1458
|
+
* Store task result in memory
|
|
1459
|
+
*/
|
|
1460
|
+
async storeTaskResult(taskId, result) {
|
|
1461
|
+
try {
|
|
1462
|
+
const { execSync } = await import('child_process');
|
|
1463
|
+
const resultJson = JSON.stringify(result);
|
|
1464
|
+
|
|
1465
|
+
execSync(
|
|
1466
|
+
`npx claude-flow@alpha memory store "workflow/${this.executionId}/${taskId}" '${resultJson}'`,
|
|
1467
|
+
{
|
|
1468
|
+
stdio: 'pipe',
|
|
1469
|
+
},
|
|
1470
|
+
);
|
|
1471
|
+
} catch (error) {
|
|
1472
|
+
console.debug(`Failed to store task result for ${taskId}:`, error.message);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
/**
|
|
1477
|
+
* Validate workflow definition
|
|
1478
|
+
*/
|
|
1479
|
+
validateWorkflow(workflow) {
|
|
1480
|
+
if (!workflow.name) {
|
|
1481
|
+
throw new Error('Workflow name is required');
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
if (!workflow.tasks || workflow.tasks.length === 0) {
|
|
1485
|
+
throw new Error('Workflow must contain at least one task');
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// Validate task structure
|
|
1489
|
+
for (const task of workflow.tasks) {
|
|
1490
|
+
if (!task.id || !task.type || !task.description) {
|
|
1491
|
+
throw new Error(`Task ${task.id || 'unknown'} is missing required fields`);
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
// Validate agent assignments
|
|
1496
|
+
if (workflow.agents) {
|
|
1497
|
+
const agentIds = new Set(workflow.agents.map((a) => a.id));
|
|
1498
|
+
for (const task of workflow.tasks) {
|
|
1499
|
+
if (task.assignTo && !agentIds.has(task.assignTo)) {
|
|
1500
|
+
throw new Error(`Task ${task.id} assigned to unknown agent: ${task.assignTo}`);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
/**
|
|
1507
|
+
* Apply variable substitutions to workflow
|
|
1508
|
+
*/
|
|
1509
|
+
applyVariables(workflow, variables) {
|
|
1510
|
+
const allVariables = { ...workflow.variables, ...variables };
|
|
1511
|
+
const workflowStr = JSON.stringify(workflow);
|
|
1512
|
+
|
|
1513
|
+
// Simple variable substitution
|
|
1514
|
+
let processedStr = workflowStr;
|
|
1515
|
+
for (const [key, value] of Object.entries(allVariables)) {
|
|
1516
|
+
const pattern = new RegExp(`\\$\\{${key}\\}`, 'g');
|
|
1517
|
+
processedStr = processedStr.replace(pattern, value);
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
return JSON.parse(processedStr);
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Cleanup Claude instances
|
|
1525
|
+
*/
|
|
1526
|
+
async cleanupClaudeInstances() {
|
|
1527
|
+
if (this.claudeInstances.size === 0) return;
|
|
1528
|
+
|
|
1529
|
+
console.log('๐งน Cleaning up Claude instances...');
|
|
1530
|
+
|
|
1531
|
+
for (const [agentId, instance] of this.claudeInstances.entries()) {
|
|
1532
|
+
try {
|
|
1533
|
+
if (instance.process && !instance.process.killed) {
|
|
1534
|
+
instance.process.kill('SIGTERM');
|
|
1535
|
+
|
|
1536
|
+
// Wait for graceful shutdown, then force kill if needed
|
|
1537
|
+
setTimeout(() => {
|
|
1538
|
+
if (!instance.process.killed) {
|
|
1539
|
+
instance.process.kill('SIGKILL');
|
|
1540
|
+
}
|
|
1541
|
+
}, 5000);
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
console.log(` โ
Cleaned up ${instance.agent.name}`);
|
|
1545
|
+
} catch (error) {
|
|
1546
|
+
console.error(` โ Error cleaning up ${instance.agent.name}:`, error.message);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
this.claudeInstances.clear();
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* Format duration in human readable format
|
|
1555
|
+
*/
|
|
1556
|
+
formatDuration(ms) {
|
|
1557
|
+
const seconds = Math.floor(ms / 1000);
|
|
1558
|
+
const minutes = Math.floor(seconds / 60);
|
|
1559
|
+
const hours = Math.floor(minutes / 60);
|
|
1560
|
+
|
|
1561
|
+
if (hours > 0) {
|
|
1562
|
+
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
1563
|
+
} else if (minutes > 0) {
|
|
1564
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
1565
|
+
} else {
|
|
1566
|
+
return `${seconds}s`;
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
/**
|
|
1572
|
+
* Load workflow from file
|
|
1573
|
+
*/
|
|
1574
|
+
export async function loadWorkflowFromFile(filePath) {
|
|
1575
|
+
try {
|
|
1576
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
1577
|
+
|
|
1578
|
+
if (filePath.endsWith('.json')) {
|
|
1579
|
+
return JSON.parse(content);
|
|
1580
|
+
} else if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {
|
|
1581
|
+
// For now, just return error - YAML support can be added later
|
|
1582
|
+
throw new Error('YAML workflows not yet supported');
|
|
1583
|
+
} else {
|
|
1584
|
+
throw new Error('Unsupported workflow file format. Use .json or .yaml');
|
|
1585
|
+
}
|
|
1586
|
+
} catch (error) {
|
|
1587
|
+
throw new Error(`Failed to load workflow: ${error.message}`);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
/**
|
|
1592
|
+
* Get default MLE-STAR workflow path
|
|
1593
|
+
*/
|
|
1594
|
+
export function getMLEStarWorkflowPath() {
|
|
1595
|
+
return join(
|
|
1596
|
+
process.cwd(),
|
|
1597
|
+
'src',
|
|
1598
|
+
'cli',
|
|
1599
|
+
'simple-commands',
|
|
1600
|
+
'templates',
|
|
1601
|
+
'mle-star-workflow.json',
|
|
1602
|
+
);
|
|
1603
|
+
}
|