@agentic-qe/v3 3.0.0-alpha.5 → 3.0.0-alpha.7
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/assets/agents/v3/subagents/v3-qe-code-reviewer.md +339 -0
- package/assets/agents/v3/subagents/v3-qe-integration-reviewer.md +344 -0
- package/assets/agents/v3/subagents/v3-qe-performance-reviewer.md +351 -0
- package/assets/agents/v3/subagents/v3-qe-security-reviewer.md +374 -0
- package/assets/agents/v3/subagents/v3-qe-tdd-green.md +334 -0
- package/assets/agents/v3/subagents/v3-qe-tdd-red.md +329 -0
- package/assets/agents/v3/subagents/v3-qe-tdd-refactor.md +361 -0
- package/assets/agents/v3/v3-qe-accessibility-auditor.md +266 -0
- package/assets/agents/v3/v3-qe-bdd-generator.md +279 -0
- package/assets/agents/v3/v3-qe-chaos-engineer.md +265 -0
- package/assets/agents/v3/v3-qe-code-complexity.md +298 -0
- package/assets/agents/v3/v3-qe-code-intelligence.md +262 -0
- package/assets/agents/v3/v3-qe-contract-validator.md +267 -0
- package/assets/agents/v3/v3-qe-coverage-specialist.md +227 -0
- package/assets/agents/v3/v3-qe-defect-predictor.md +251 -0
- package/assets/agents/v3/v3-qe-dependency-mapper.md +277 -0
- package/assets/agents/v3/v3-qe-deployment-advisor.md +275 -0
- package/assets/agents/v3/v3-qe-flaky-hunter.md +248 -0
- package/assets/agents/v3/v3-qe-fleet-commander.md +293 -0
- package/assets/agents/v3/v3-qe-gap-detector.md +260 -0
- package/assets/agents/v3/v3-qe-graphql-tester.md +308 -0
- package/assets/agents/v3/v3-qe-impact-analyzer.md +299 -0
- package/assets/agents/v3/v3-qe-integration-tester.md +238 -0
- package/assets/agents/v3/v3-qe-kg-builder.md +273 -0
- package/assets/agents/v3/v3-qe-learning-coordinator.md +226 -0
- package/assets/agents/v3/v3-qe-load-tester.md +280 -0
- package/assets/agents/v3/v3-qe-metrics-optimizer.md +300 -0
- package/assets/agents/v3/v3-qe-mutation-tester.md +301 -0
- package/assets/agents/v3/v3-qe-parallel-executor.md +240 -0
- package/assets/agents/v3/v3-qe-pattern-learner.md +271 -0
- package/assets/agents/v3/v3-qe-performance-tester.md +262 -0
- package/assets/agents/v3/v3-qe-property-tester.md +247 -0
- package/assets/agents/v3/v3-qe-quality-gate.md +218 -0
- package/assets/agents/v3/v3-qe-queen-coordinator.md +214 -0
- package/assets/agents/v3/v3-qe-qx-partner.md +313 -0
- package/assets/agents/v3/v3-qe-regression-analyzer.md +322 -0
- package/assets/agents/v3/v3-qe-requirements-validator.md +360 -0
- package/assets/agents/v3/v3-qe-responsive-tester.md +311 -0
- package/assets/agents/v3/v3-qe-retry-handler.md +256 -0
- package/assets/agents/v3/v3-qe-risk-assessor.md +273 -0
- package/assets/agents/v3/v3-qe-root-cause-analyzer.md +286 -0
- package/assets/agents/v3/v3-qe-security-auditor.md +299 -0
- package/assets/agents/v3/v3-qe-security-scanner.md +235 -0
- package/assets/agents/v3/v3-qe-tdd-specialist.md +239 -0
- package/assets/agents/v3/v3-qe-test-architect.md +233 -0
- package/assets/agents/v3/v3-qe-transfer-specialist.md +295 -0
- package/assets/agents/v3/v3-qe-visual-tester.md +232 -0
- package/assets/skills/accessibility-testing/SKILL.md +216 -0
- package/assets/skills/agentdb-advanced/SKILL.md +550 -0
- package/assets/skills/agentdb-learning/SKILL.md +545 -0
- package/assets/skills/agentdb-memory-patterns/SKILL.md +339 -0
- package/assets/skills/agentdb-optimization/SKILL.md +509 -0
- package/assets/skills/agentdb-vector-search/SKILL.md +339 -0
- package/assets/skills/agentic-jujutsu/SKILL.md +645 -0
- package/assets/skills/agentic-quality-engineering/SKILL.md +335 -0
- package/assets/skills/api-testing-patterns/SKILL.md +294 -0
- package/assets/skills/aqe-v2-v3-migration/skill.md +322 -0
- package/assets/skills/brutal-honesty-review/README.md +218 -0
- package/assets/skills/brutal-honesty-review/SKILL.md +235 -0
- package/assets/skills/brutal-honesty-review/resources/assessment-rubrics.md +295 -0
- package/assets/skills/brutal-honesty-review/resources/review-template.md +102 -0
- package/assets/skills/brutal-honesty-review/scripts/assess-code.sh +179 -0
- package/assets/skills/brutal-honesty-review/scripts/assess-tests.sh +223 -0
- package/assets/skills/bug-reporting-excellence/SKILL.md +225 -0
- package/assets/skills/chaos-engineering-resilience/SKILL.md +158 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/README.md +304 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/SKILL.md +315 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/microservice-pipeline.md +239 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/mobile-pipeline.md +375 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/monolith-pipeline.md +268 -0
- package/assets/skills/code-review-quality/SKILL.md +227 -0
- package/assets/skills/compatibility-testing/SKILL.md +205 -0
- package/assets/skills/compliance-testing/SKILL.md +225 -0
- package/assets/skills/consultancy-practices/SKILL.md +202 -0
- package/assets/skills/context-driven-testing/SKILL.md +196 -0
- package/assets/skills/contract-testing/SKILL.md +222 -0
- package/assets/skills/database-testing/SKILL.md +244 -0
- package/assets/skills/exploratory-testing-advanced/SKILL.md +201 -0
- package/assets/skills/flow-nexus-neural/SKILL.md +738 -0
- package/assets/skills/flow-nexus-platform/SKILL.md +1157 -0
- package/assets/skills/flow-nexus-swarm/SKILL.md +610 -0
- package/assets/skills/github-code-review/SKILL.md +1140 -0
- package/assets/skills/github-multi-repo/SKILL.md +874 -0
- package/assets/skills/github-project-management/SKILL.md +1277 -0
- package/assets/skills/github-release-management/SKILL.md +1081 -0
- package/assets/skills/github-workflow-automation/SKILL.md +1065 -0
- package/assets/skills/hive-mind-advanced/SKILL.md +712 -0
- package/assets/skills/holistic-testing-pact/SKILL.md +171 -0
- package/assets/skills/hooks-automation/SKILL.md +1201 -0
- package/assets/skills/localization-testing/SKILL.md +221 -0
- package/assets/skills/mobile-testing/SKILL.md +219 -0
- package/assets/skills/mutation-testing/SKILL.md +229 -0
- package/assets/skills/n8n-expression-testing/SKILL.md +434 -0
- package/assets/skills/n8n-integration-testing-patterns/SKILL.md +540 -0
- package/assets/skills/n8n-security-testing/SKILL.md +599 -0
- package/assets/skills/n8n-trigger-testing-strategies/SKILL.md +541 -0
- package/assets/skills/n8n-workflow-testing-fundamentals/SKILL.md +447 -0
- package/assets/skills/pair-programming/SKILL.md +1202 -0
- package/assets/skills/performance-analysis/SKILL.md +563 -0
- package/assets/skills/performance-testing/SKILL.md +310 -0
- package/assets/skills/quality-metrics/SKILL.md +225 -0
- package/assets/skills/reasoningbank-agentdb/SKILL.md +446 -0
- package/assets/skills/reasoningbank-intelligence/SKILL.md +201 -0
- package/assets/skills/refactoring-patterns/SKILL.md +205 -0
- package/assets/skills/regression-testing/SKILL.md +227 -0
- package/assets/skills/risk-based-testing/SKILL.md +206 -0
- package/assets/skills/security-testing/SKILL.md +306 -0
- package/assets/skills/sherlock-review/SKILL.md +250 -0
- package/assets/skills/shift-left-testing/SKILL.md +225 -0
- package/assets/skills/shift-right-testing/SKILL.md +227 -0
- package/assets/skills/six-thinking-hats/README.md +190 -0
- package/assets/skills/six-thinking-hats/SKILL.md +280 -0
- package/assets/skills/six-thinking-hats/resources/examples/api-testing-example.md +345 -0
- package/assets/skills/six-thinking-hats/resources/templates/solo-session-template.md +167 -0
- package/assets/skills/six-thinking-hats/resources/templates/team-session-template.md +336 -0
- package/assets/skills/skill-builder/SKILL.md +910 -0
- package/assets/skills/sparc-methodology/SKILL.md +1115 -0
- package/assets/skills/stream-chain/SKILL.md +563 -0
- package/assets/skills/swarm-advanced/SKILL.md +973 -0
- package/assets/skills/swarm-orchestration/SKILL.md +179 -0
- package/assets/skills/tdd-london-chicago/SKILL.md +244 -0
- package/assets/skills/technical-writing/SKILL.md +178 -0
- package/assets/skills/test-automation-strategy/SKILL.md +230 -0
- package/assets/skills/test-data-management/SKILL.md +270 -0
- package/assets/skills/test-design-techniques/SKILL.md +244 -0
- package/assets/skills/test-environment-management/SKILL.md +243 -0
- package/assets/skills/test-reporting-analytics/SKILL.md +214 -0
- package/assets/skills/testability-scoring/README.md +71 -0
- package/assets/skills/testability-scoring/SKILL.md +346 -0
- package/assets/skills/testability-scoring/resources/templates/config.template.js +84 -0
- package/assets/skills/testability-scoring/resources/templates/testability-scoring.spec.template.js +532 -0
- package/assets/skills/testability-scoring/scripts/generate-html-report.js +1007 -0
- package/assets/skills/testability-scoring/scripts/run-assessment.sh +70 -0
- package/assets/skills/v3-qe-chaos-resilience/SKILL.md +238 -0
- package/assets/skills/v3-qe-code-intelligence/SKILL.md +209 -0
- package/assets/skills/v3-qe-contract-testing/SKILL.md +218 -0
- package/assets/skills/v3-qe-coverage-analysis/SKILL.md +187 -0
- package/assets/skills/v3-qe-defect-intelligence/SKILL.md +205 -0
- package/assets/skills/v3-qe-learning-optimization/SKILL.md +238 -0
- package/assets/skills/v3-qe-quality-assessment/SKILL.md +213 -0
- package/assets/skills/v3-qe-requirements-validation/SKILL.md +248 -0
- package/assets/skills/v3-qe-test-execution/SKILL.md +182 -0
- package/assets/skills/v3-qe-test-generation/SKILL.md +141 -0
- package/assets/skills/v3-qe-visual-accessibility/SKILL.md +242 -0
- package/assets/skills/verification-quality/SKILL.md +649 -0
- package/assets/skills/visual-testing-advanced/SKILL.md +219 -0
- package/assets/skills/xp-practices/SKILL.md +229 -0
- package/dist/cli/bundle.js +8 -8
- package/dist/init/agents-installer.js +4 -4
- package/dist/init/agents-installer.js.map +1 -1
- package/dist/init/skills-installer.js +4 -4
- package/dist/init/skills-installer.js.map +1 -1
- package/package.json +8 -2
- package/docs/analysis/V3-INIT-REQUIREMENTS-ANALYSIS.md +0 -352
- package/implementation/README.md +0 -90
- package/implementation/adrs/ADR-030-coherence-gated-quality-gates.md +0 -312
- package/implementation/adrs/ADR-031-strange-loop-self-awareness.md +0 -484
- package/implementation/adrs/ADR-032-time-crystal-scheduling.md +0 -530
- package/implementation/adrs/ADR-033-early-exit-testing.md +0 -634
- package/implementation/adrs/ADR-034-neural-topology-optimizer.md +0 -589
- package/implementation/adrs/ADR-035-causal-discovery.md +0 -610
- package/implementation/adrs/ADR-036-result-persistence.md +0 -326
- package/implementation/adrs/ADR-037-v3-qe-agent-naming.md +0 -105
- package/implementation/adrs/ADR-038-v3-qe-memory-unification.md +0 -154
- package/implementation/adrs/ADR-039-v3-qe-mcp-optimization.md +0 -179
- package/implementation/adrs/ADR-040-v3-qe-agentic-flow-integration.md +0 -240
- package/implementation/adrs/ADR-041-v3-qe-cli-enhancement.md +0 -296
- package/implementation/adrs/ADR-042-v3-qe-token-tracking-integration.md +0 -517
- package/implementation/adrs/v3-adrs.md +0 -2783
- package/implementation/planning/AQE-V3-MASTER-PLAN.md +0 -815
- package/security-scan-report-2026-01-11.md +0 -410
- package/security-verification-report-2026-01-11.md +0 -278
- package/src/benchmarks/performance-benchmarks.ts +0 -646
- package/src/benchmarks/run-benchmarks.ts +0 -324
- package/src/causal-discovery/causal-graph.ts +0 -450
- package/src/causal-discovery/discovery-engine.ts +0 -438
- package/src/causal-discovery/index.ts +0 -117
- package/src/causal-discovery/types.ts +0 -456
- package/src/causal-discovery/weight-matrix.ts +0 -453
- package/src/cli/commands/qe-tools.ts +0 -634
- package/src/cli/index.ts +0 -1976
- package/src/compatibility/agent-mapper.ts +0 -291
- package/src/compatibility/cli-adapter.ts +0 -277
- package/src/compatibility/config-migrator.ts +0 -334
- package/src/compatibility/index.ts +0 -112
- package/src/compatibility/mcp-adapter.ts +0 -248
- package/src/compatibility/types.ts +0 -156
- package/src/coordination/claims/claim-repository.ts +0 -636
- package/src/coordination/claims/claim-service.ts +0 -675
- package/src/coordination/claims/handoff-manager.ts +0 -535
- package/src/coordination/claims/index.ts +0 -276
- package/src/coordination/claims/interfaces.ts +0 -687
- package/src/coordination/claims/work-stealing.ts +0 -436
- package/src/coordination/cross-domain-router.ts +0 -492
- package/src/coordination/index.ts +0 -127
- package/src/coordination/interfaces.ts +0 -691
- package/src/coordination/protocol-executor.ts +0 -760
- package/src/coordination/protocols/code-intelligence-index.ts +0 -855
- package/src/coordination/protocols/defect-investigation.ts +0 -1184
- package/src/coordination/protocols/index.ts +0 -11
- package/src/coordination/protocols/learning-consolidation.ts +0 -1181
- package/src/coordination/protocols/morning-sync.ts +0 -1055
- package/src/coordination/protocols/quality-gate.ts +0 -1566
- package/src/coordination/protocols/security-audit.ts +0 -1587
- package/src/coordination/queen-coordinator.ts +0 -1176
- package/src/coordination/result-saver.ts +0 -780
- package/src/coordination/task-executor.ts +0 -1146
- package/src/coordination/workflow-orchestrator.ts +0 -1917
- package/src/domains/chaos-resilience/coordinator.ts +0 -1032
- package/src/domains/chaos-resilience/index.ts +0 -143
- package/src/domains/chaos-resilience/interfaces.ts +0 -659
- package/src/domains/chaos-resilience/plugin.ts +0 -691
- package/src/domains/chaos-resilience/services/chaos-engineer.ts +0 -1097
- package/src/domains/chaos-resilience/services/index.ts +0 -19
- package/src/domains/chaos-resilience/services/load-tester.ts +0 -799
- package/src/domains/chaos-resilience/services/performance-profiler.ts +0 -792
- package/src/domains/code-intelligence/coordinator.ts +0 -631
- package/src/domains/code-intelligence/index.ts +0 -86
- package/src/domains/code-intelligence/interfaces.ts +0 -162
- package/src/domains/code-intelligence/plugin.ts +0 -451
- package/src/domains/code-intelligence/services/impact-analyzer.ts +0 -567
- package/src/domains/code-intelligence/services/index.ts +0 -26
- package/src/domains/code-intelligence/services/knowledge-graph.ts +0 -1067
- package/src/domains/code-intelligence/services/semantic-analyzer.ts +0 -901
- package/src/domains/contract-testing/coordinator.ts +0 -1038
- package/src/domains/contract-testing/index.ts +0 -122
- package/src/domains/contract-testing/interfaces.ts +0 -458
- package/src/domains/contract-testing/plugin.ts +0 -746
- package/src/domains/contract-testing/services/api-compatibility.ts +0 -748
- package/src/domains/contract-testing/services/contract-validator.ts +0 -1700
- package/src/domains/contract-testing/services/index.ts +0 -19
- package/src/domains/contract-testing/services/schema-validator.ts +0 -1102
- package/src/domains/coverage-analysis/coordinator.ts +0 -485
- package/src/domains/coverage-analysis/index.ts +0 -114
- package/src/domains/coverage-analysis/interfaces.ts +0 -142
- package/src/domains/coverage-analysis/plugin.ts +0 -172
- package/src/domains/coverage-analysis/services/coverage-analyzer.ts +0 -449
- package/src/domains/coverage-analysis/services/coverage-embedder.ts +0 -733
- package/src/domains/coverage-analysis/services/coverage-parser.ts +0 -753
- package/src/domains/coverage-analysis/services/gap-detector.ts +0 -592
- package/src/domains/coverage-analysis/services/hnsw-index.ts +0 -728
- package/src/domains/coverage-analysis/services/index.ts +0 -61
- package/src/domains/coverage-analysis/services/risk-scorer.ts +0 -540
- package/src/domains/coverage-analysis/services/sublinear-analyzer.ts +0 -747
- package/src/domains/defect-intelligence/coordinator.ts +0 -635
- package/src/domains/defect-intelligence/index.ts +0 -83
- package/src/domains/defect-intelligence/interfaces.ts +0 -152
- package/src/domains/defect-intelligence/plugin.ts +0 -483
- package/src/domains/defect-intelligence/services/causal-root-cause-analyzer.ts +0 -494
- package/src/domains/defect-intelligence/services/defect-predictor.ts +0 -852
- package/src/domains/defect-intelligence/services/index.ts +0 -37
- package/src/domains/defect-intelligence/services/pattern-learner.ts +0 -738
- package/src/domains/defect-intelligence/services/root-cause-analyzer.ts +0 -637
- package/src/domains/domain-interface.ts +0 -77
- package/src/domains/index.ts +0 -23
- package/src/domains/learning-optimization/coordinator.ts +0 -1215
- package/src/domains/learning-optimization/index.ts +0 -127
- package/src/domains/learning-optimization/interfaces.ts +0 -570
- package/src/domains/learning-optimization/plugin.ts +0 -851
- package/src/domains/learning-optimization/services/index.ts +0 -29
- package/src/domains/learning-optimization/services/learning-coordinator.ts +0 -972
- package/src/domains/learning-optimization/services/metrics-optimizer.ts +0 -915
- package/src/domains/learning-optimization/services/production-intel.ts +0 -971
- package/src/domains/learning-optimization/services/transfer-specialist.ts +0 -723
- package/src/domains/quality-assessment/coherence/gate-controller.ts +0 -549
- package/src/domains/quality-assessment/coherence/index.ts +0 -211
- package/src/domains/quality-assessment/coherence/lambda-calculator.ts +0 -384
- package/src/domains/quality-assessment/coherence/partition-detector.ts +0 -469
- package/src/domains/quality-assessment/coherence/types.ts +0 -384
- package/src/domains/quality-assessment/coordinator.ts +0 -605
- package/src/domains/quality-assessment/index.ts +0 -97
- package/src/domains/quality-assessment/interfaces.ts +0 -152
- package/src/domains/quality-assessment/plugin.ts +0 -496
- package/src/domains/quality-assessment/services/coherence-gate.ts +0 -358
- package/src/domains/quality-assessment/services/deployment-advisor.ts +0 -571
- package/src/domains/quality-assessment/services/index.ts +0 -34
- package/src/domains/quality-assessment/services/quality-analyzer.ts +0 -670
- package/src/domains/quality-assessment/services/quality-gate.ts +0 -384
- package/src/domains/requirements-validation/coordinator.ts +0 -812
- package/src/domains/requirements-validation/index.ts +0 -92
- package/src/domains/requirements-validation/interfaces.ts +0 -303
- package/src/domains/requirements-validation/plugin.ts +0 -576
- package/src/domains/requirements-validation/services/bdd-scenario-writer.ts +0 -676
- package/src/domains/requirements-validation/services/index.ts +0 -20
- package/src/domains/requirements-validation/services/requirements-validator.ts +0 -559
- package/src/domains/requirements-validation/services/testability-scorer.ts +0 -639
- package/src/domains/security-compliance/coordinator.ts +0 -757
- package/src/domains/security-compliance/index.ts +0 -120
- package/src/domains/security-compliance/interfaces.ts +0 -434
- package/src/domains/security-compliance/plugin.ts +0 -509
- package/src/domains/security-compliance/services/compliance-validator.ts +0 -1226
- package/src/domains/security-compliance/services/index.ts +0 -31
- package/src/domains/security-compliance/services/security-auditor.ts +0 -2227
- package/src/domains/security-compliance/services/security-scanner.ts +0 -2354
- package/src/domains/security-compliance/services/semgrep-integration.ts +0 -289
- package/src/domains/test-execution/coordinator.ts +0 -426
- package/src/domains/test-execution/index.ts +0 -76
- package/src/domains/test-execution/interfaces.ts +0 -119
- package/src/domains/test-execution/plugin.ts +0 -208
- package/src/domains/test-execution/services/flaky-detector.ts +0 -1240
- package/src/domains/test-execution/services/index.ts +0 -8
- package/src/domains/test-execution/services/retry-handler.ts +0 -820
- package/src/domains/test-execution/services/test-executor.ts +0 -885
- package/src/domains/test-generation/coordinator.ts +0 -656
- package/src/domains/test-generation/index.ts +0 -77
- package/src/domains/test-generation/interfaces.ts +0 -118
- package/src/domains/test-generation/plugin.ts +0 -397
- package/src/domains/test-generation/services/index.ts +0 -23
- package/src/domains/test-generation/services/pattern-matcher.ts +0 -1725
- package/src/domains/test-generation/services/test-generator.ts +0 -2750
- package/src/domains/visual-accessibility/coordinator.ts +0 -860
- package/src/domains/visual-accessibility/index.ts +0 -116
- package/src/domains/visual-accessibility/interfaces.ts +0 -435
- package/src/domains/visual-accessibility/plugin.ts +0 -568
- package/src/domains/visual-accessibility/services/accessibility-tester.ts +0 -982
- package/src/domains/visual-accessibility/services/axe-core-audit.ts +0 -630
- package/src/domains/visual-accessibility/services/index.ts +0 -28
- package/src/domains/visual-accessibility/services/responsive-tester.ts +0 -934
- package/src/domains/visual-accessibility/services/visual-tester.ts +0 -458
- package/src/early-exit/early-exit-controller.ts +0 -490
- package/src/early-exit/early-exit-decision.ts +0 -391
- package/src/early-exit/index.ts +0 -115
- package/src/early-exit/quality-signal.ts +0 -389
- package/src/early-exit/speculative-executor.ts +0 -505
- package/src/early-exit/types.ts +0 -407
- package/src/feedback/coverage-learner.ts +0 -456
- package/src/feedback/feedback-loop.ts +0 -426
- package/src/feedback/index.ts +0 -72
- package/src/feedback/pattern-promotion.ts +0 -373
- package/src/feedback/quality-score-calculator.ts +0 -334
- package/src/feedback/test-outcome-tracker.ts +0 -450
- package/src/feedback/types.ts +0 -497
- package/src/index.ts +0 -224
- package/src/init/agents-installer.ts +0 -536
- package/src/init/index.ts +0 -80
- package/src/init/init-wizard.ts +0 -1061
- package/src/init/project-analyzer.ts +0 -696
- package/src/init/self-configurator.ts +0 -488
- package/src/init/skills-installer.ts +0 -467
- package/src/init/types.ts +0 -432
- package/src/integrations/ruvector/ast-complexity.ts +0 -470
- package/src/integrations/ruvector/coverage-router.ts +0 -594
- package/src/integrations/ruvector/diff-risk-classifier.ts +0 -759
- package/src/integrations/ruvector/fallback.ts +0 -942
- package/src/integrations/ruvector/graph-boundaries.ts +0 -809
- package/src/integrations/ruvector/index.ts +0 -363
- package/src/integrations/ruvector/interfaces.ts +0 -609
- package/src/integrations/ruvector/q-learning-router.ts +0 -550
- package/src/kernel/agent-coordinator.ts +0 -165
- package/src/kernel/agentdb-backend.ts +0 -504
- package/src/kernel/event-bus.ts +0 -129
- package/src/kernel/hybrid-backend.ts +0 -538
- package/src/kernel/index.ts +0 -28
- package/src/kernel/interfaces.ts +0 -257
- package/src/kernel/kernel.ts +0 -285
- package/src/kernel/memory-backend.ts +0 -169
- package/src/kernel/memory-factory.ts +0 -293
- package/src/kernel/plugin-loader.ts +0 -179
- package/src/learning/index.ts +0 -219
- package/src/learning/pattern-store.ts +0 -990
- package/src/learning/qe-guidance.ts +0 -832
- package/src/learning/qe-hooks.ts +0 -644
- package/src/learning/qe-patterns.ts +0 -449
- package/src/learning/qe-reasoning-bank.ts +0 -951
- package/src/learning/real-embeddings.ts +0 -277
- package/src/learning/real-qe-reasoning-bank.ts +0 -833
- package/src/learning/sqlite-persistence.ts +0 -554
- package/src/mcp/entry.ts +0 -59
- package/src/mcp/handlers/agent-handlers.ts +0 -285
- package/src/mcp/handlers/core-handlers.ts +0 -317
- package/src/mcp/handlers/domain-handlers.ts +0 -1444
- package/src/mcp/handlers/index.ts +0 -57
- package/src/mcp/handlers/memory-handlers.ts +0 -338
- package/src/mcp/handlers/task-handlers.ts +0 -363
- package/src/mcp/index.ts +0 -30
- package/src/mcp/metrics/index.ts +0 -14
- package/src/mcp/metrics/metrics-collector.ts +0 -503
- package/src/mcp/protocol-server.ts +0 -752
- package/src/mcp/security/cve-prevention.ts +0 -742
- package/src/mcp/security/index.ts +0 -356
- package/src/mcp/security/oauth21-provider.ts +0 -821
- package/src/mcp/security/rate-limiter.ts +0 -615
- package/src/mcp/security/sampling-server.ts +0 -662
- package/src/mcp/security/schema-validator.ts +0 -855
- package/src/mcp/server.ts +0 -657
- package/src/mcp/tool-registry.ts +0 -391
- package/src/mcp/tools/base.ts +0 -399
- package/src/mcp/tools/chaos-resilience/inject.ts +0 -699
- package/src/mcp/tools/code-intelligence/analyze.ts +0 -745
- package/src/mcp/tools/contract-testing/validate.ts +0 -708
- package/src/mcp/tools/coverage-analysis/index.ts +0 -770
- package/src/mcp/tools/defect-intelligence/predict.ts +0 -466
- package/src/mcp/tools/index.ts +0 -214
- package/src/mcp/tools/learning-optimization/optimize.ts +0 -772
- package/src/mcp/tools/quality-assessment/evaluate.ts +0 -385
- package/src/mcp/tools/registry.ts +0 -248
- package/src/mcp/tools/requirements-validation/validate.ts +0 -394
- package/src/mcp/tools/security-compliance/scan.ts +0 -365
- package/src/mcp/tools/test-execution/execute.ts +0 -291
- package/src/mcp/tools/test-generation/generate.ts +0 -544
- package/src/mcp/tools/visual-accessibility/index.ts +0 -791
- package/src/mcp/transport/index.ts +0 -31
- package/src/mcp/transport/stdio.ts +0 -318
- package/src/mcp/types.ts +0 -543
- package/src/neural-optimizer/index.ts +0 -111
- package/src/neural-optimizer/replay-buffer.ts +0 -455
- package/src/neural-optimizer/swarm-topology.ts +0 -508
- package/src/neural-optimizer/topology-optimizer.ts +0 -828
- package/src/neural-optimizer/types.ts +0 -481
- package/src/neural-optimizer/value-network.ts +0 -351
- package/src/optimization/auto-tuner.ts +0 -817
- package/src/optimization/index.ts +0 -77
- package/src/optimization/metric-collectors.ts +0 -474
- package/src/optimization/qe-workers.ts +0 -704
- package/src/optimization/tuning-algorithm.ts +0 -401
- package/src/optimization/types.ts +0 -314
- package/src/routing/index.ts +0 -51
- package/src/routing/qe-agent-registry.ts +0 -963
- package/src/routing/qe-task-router.ts +0 -564
- package/src/routing/routing-feedback.ts +0 -365
- package/src/routing/types.ts +0 -406
- package/src/shared/embeddings/embedding-cache.ts +0 -157
- package/src/shared/embeddings/index.ts +0 -50
- package/src/shared/embeddings/nomic-embedder.ts +0 -404
- package/src/shared/embeddings/ollama-client.ts +0 -195
- package/src/shared/embeddings/types.ts +0 -147
- package/src/shared/entities/agent.ts +0 -141
- package/src/shared/entities/base-entity.ts +0 -79
- package/src/shared/entities/index.ts +0 -6
- package/src/shared/events/domain-events.ts +0 -259
- package/src/shared/events/index.ts +0 -5
- package/src/shared/git/git-analyzer.ts +0 -656
- package/src/shared/git/index.ts +0 -11
- package/src/shared/http/http-client.ts +0 -420
- package/src/shared/http/index.ts +0 -13
- package/src/shared/index.ts +0 -41
- package/src/shared/io/file-reader.ts +0 -525
- package/src/shared/io/index.ts +0 -25
- package/src/shared/llm/cache.ts +0 -473
- package/src/shared/llm/circuit-breaker.ts +0 -369
- package/src/shared/llm/cost-tracker.ts +0 -460
- package/src/shared/llm/index.ts +0 -140
- package/src/shared/llm/interfaces.ts +0 -629
- package/src/shared/llm/provider-manager.ts +0 -685
- package/src/shared/llm/providers/claude.ts +0 -524
- package/src/shared/llm/providers/index.ts +0 -8
- package/src/shared/llm/providers/ollama.ts +0 -575
- package/src/shared/llm/providers/openai.ts +0 -609
- package/src/shared/metrics/code-metrics.ts +0 -520
- package/src/shared/metrics/index.ts +0 -23
- package/src/shared/metrics/system-metrics.ts +0 -353
- package/src/shared/parsers/index.ts +0 -6
- package/src/shared/parsers/typescript-parser.ts +0 -841
- package/src/shared/security/compliance-patterns.ts +0 -666
- package/src/shared/security/index.ts +0 -30
- package/src/shared/security/osv-client.ts +0 -468
- package/src/shared/types/index.ts +0 -150
- package/src/shared/value-objects/index.ts +0 -273
- package/src/strange-loop/healing-controller.ts +0 -833
- package/src/strange-loop/index.ts +0 -104
- package/src/strange-loop/self-model.ts +0 -494
- package/src/strange-loop/strange-loop.ts +0 -446
- package/src/strange-loop/swarm-observer.ts +0 -448
- package/src/strange-loop/topology-analyzer.ts +0 -565
- package/src/strange-loop/types.ts +0 -640
- package/src/time-crystal/default-phases.ts +0 -520
- package/src/time-crystal/index.ts +0 -164
- package/src/time-crystal/oscillator.ts +0 -425
- package/src/time-crystal/phase-executor.ts +0 -521
- package/src/time-crystal/scheduler.ts +0 -1025
- package/src/time-crystal/test-runner.ts +0 -787
- package/src/time-crystal/types.ts +0 -421
- package/src/workers/base-worker.ts +0 -304
- package/src/workers/daemon.ts +0 -264
- package/src/workers/index.ts +0 -119
- package/src/workers/interfaces.ts +0 -393
- package/src/workers/worker-manager.ts +0 -424
- package/src/workers/workers/compliance-checker.ts +0 -445
- package/src/workers/workers/coverage-tracker.ts +0 -344
- package/src/workers/workers/defect-predictor.ts +0 -375
- package/src/workers/workers/flaky-detector.ts +0 -390
- package/src/workers/workers/index.ts +0 -17
- package/src/workers/workers/learning-consolidation.ts +0 -442
- package/src/workers/workers/performance-baseline.ts +0 -434
- package/src/workers/workers/quality-gate.ts +0 -419
- package/src/workers/workers/regression-monitor.ts +0 -357
- package/src/workers/workers/security-scan.ts +0 -349
- package/src/workers/workers/test-health.ts +0 -359
- package/tests/integration/code-intelligence/knowledge-graph-real.test.ts +0 -540
- package/tests/integration/coordination/cross-domain-router.test.ts +0 -403
- package/tests/integration/coordination/protocol-executor.test.ts +0 -454
- package/tests/integration/coordination/workflow-orchestrator.test.ts +0 -418
- package/tests/integration/feedback/feedback-loop-integration.test.ts +0 -560
- package/tests/integration/migration/v2-to-v3-migration.test.ts +0 -471
- package/tests/integration/parsers/typescript-parser.test.ts +0 -463
- package/tests/integration/security/vulnerability-detection.test.ts +0 -628
- package/tests/integration/test-execution/coordinator.test.ts +0 -410
- package/tests/integration/test-generation/coordinator.test.ts +0 -361
- package/tests/mocks/index.ts +0 -228
- package/tests/time-crystal/default-phases.test.ts +0 -476
- package/tests/time-crystal/oscillator.test.ts +0 -541
- package/tests/time-crystal/phase-executor.test.ts +0 -653
- package/tests/time-crystal/scheduler.test.ts +0 -626
- package/tests/time-crystal/test-runner.test.ts +0 -594
- package/tests/unit/causal-discovery/causal-graph.test.ts +0 -504
- package/tests/unit/causal-discovery/causal-root-cause-analyzer.test.ts +0 -347
- package/tests/unit/causal-discovery/discovery-engine.test.ts +0 -435
- package/tests/unit/causal-discovery/weight-matrix.test.ts +0 -328
- package/tests/unit/cli/cli.test.ts +0 -341
- package/tests/unit/cli/commands.test.ts +0 -414
- package/tests/unit/cli/init-command.test.ts +0 -274
- package/tests/unit/cli/migrate-command.test.ts +0 -396
- package/tests/unit/coordination/claims/claim-service.test.ts +0 -949
- package/tests/unit/coordination/claims/handoff-manager.test.ts +0 -773
- package/tests/unit/coordination/claims/work-stealing.test.ts +0 -492
- package/tests/unit/coordination/queen-coordinator.test.ts +0 -966
- package/tests/unit/coordination/result-saver.test.ts +0 -653
- package/tests/unit/coordination/task-executor.test.ts +0 -810
- package/tests/unit/domains/chaos-resilience/chaos-engineer.test.ts +0 -484
- package/tests/unit/domains/chaos-resilience/load-tester.test.ts +0 -559
- package/tests/unit/domains/chaos-resilience/performance-profiler.test.ts +0 -490
- package/tests/unit/domains/code-intelligence/impact-analyzer.test.ts +0 -560
- package/tests/unit/domains/code-intelligence/knowledge-graph.test.ts +0 -460
- package/tests/unit/domains/code-intelligence/semantic-analyzer.test.ts +0 -584
- package/tests/unit/domains/contract-testing/api-compatibility.test.ts +0 -483
- package/tests/unit/domains/contract-testing/contract-validator.test.ts +0 -370
- package/tests/unit/domains/contract-testing/schema-validator.test.ts +0 -610
- package/tests/unit/domains/coverage-analysis/coverage-embedder.test.ts +0 -298
- package/tests/unit/domains/coverage-analysis/hnsw-index.test.ts +0 -292
- package/tests/unit/domains/coverage-analysis/sublinear-analyzer.test.ts +0 -506
- package/tests/unit/domains/defect-intelligence/defect-predictor.test.ts +0 -370
- package/tests/unit/domains/defect-intelligence/pattern-learner.test.ts +0 -546
- package/tests/unit/domains/defect-intelligence/root-cause-analyzer.test.ts +0 -534
- package/tests/unit/domains/learning-optimization/learning-coordinator.test.ts +0 -541
- package/tests/unit/domains/learning-optimization/metrics-optimizer.test.ts +0 -552
- package/tests/unit/domains/learning-optimization/production-intel.test.ts +0 -589
- package/tests/unit/domains/learning-optimization/transfer-specialist.test.ts +0 -453
- package/tests/unit/domains/quality-assessment/coherence-gate.test.ts +0 -1006
- package/tests/unit/domains/quality-assessment/deployment-advisor.test.ts +0 -515
- package/tests/unit/domains/quality-assessment/quality-analyzer.test.ts +0 -401
- package/tests/unit/domains/quality-assessment/quality-gate.test.ts +0 -324
- package/tests/unit/domains/requirements-validation/bdd-scenario-writer.test.ts +0 -479
- package/tests/unit/domains/requirements-validation/requirements-validator.test.ts +0 -452
- package/tests/unit/domains/requirements-validation/testability-scorer.test.ts +0 -505
- package/tests/unit/domains/security-compliance/compliance-validator.test.ts +0 -500
- package/tests/unit/domains/security-compliance/security-auditor.test.ts +0 -498
- package/tests/unit/domains/security-compliance/security-scanner.test.ts +0 -412
- package/tests/unit/domains/visual-accessibility/accessibility-tester.test.ts +0 -432
- package/tests/unit/domains/visual-accessibility/responsive-tester.test.ts +0 -506
- package/tests/unit/domains/visual-accessibility/visual-tester.test.ts +0 -412
- package/tests/unit/early-exit/early-exit-controller.test.ts +0 -548
- package/tests/unit/early-exit/early-exit-decision.test.ts +0 -617
- package/tests/unit/early-exit/index.test.ts +0 -254
- package/tests/unit/early-exit/quality-signal.test.ts +0 -589
- package/tests/unit/early-exit/speculative-executor.test.ts +0 -453
- package/tests/unit/feedback/coverage-learner.test.ts +0 -288
- package/tests/unit/feedback/feedback-loop.test.ts +0 -458
- package/tests/unit/feedback/pattern-promotion.test.ts +0 -390
- package/tests/unit/feedback/quality-score-calculator.test.ts +0 -364
- package/tests/unit/feedback/test-outcome-tracker.test.ts +0 -243
- package/tests/unit/init/init-wizard.test.ts +0 -881
- package/tests/unit/init/project-analyzer.test.ts +0 -807
- package/tests/unit/init/self-configurator.test.ts +0 -493
- package/tests/unit/integrations/ruvector/ast-complexity.test.ts +0 -240
- package/tests/unit/integrations/ruvector/coverage-router.test.ts +0 -366
- package/tests/unit/integrations/ruvector/diff-risk-classifier.test.ts +0 -340
- package/tests/unit/integrations/ruvector/graph-boundaries.test.ts +0 -355
- package/tests/unit/integrations/ruvector/q-learning-router.test.ts +0 -314
- package/tests/unit/kernel/agent-coordinator.test.ts +0 -220
- package/tests/unit/kernel/event-bus.test.ts +0 -197
- package/tests/unit/learning/qe-reasoning-bank.test.ts +0 -666
- package/tests/unit/learning/real-qe-reasoning-bank.benchmark.test.ts +0 -415
- package/tests/unit/mcp/mcp-server.test.ts +0 -544
- package/tests/unit/mcp/metrics/metrics-collector.test.ts +0 -340
- package/tests/unit/mcp/security/cve-prevention.test.ts +0 -512
- package/tests/unit/mcp/security/oauth21-provider.test.ts +0 -624
- package/tests/unit/mcp/security/rate-limiter.test.ts +0 -410
- package/tests/unit/mcp/security/sampling-server.test.ts +0 -420
- package/tests/unit/mcp/security/schema-validator.test.ts +0 -494
- package/tests/unit/mcp/tools/base.test.ts +0 -336
- package/tests/unit/mcp/tools/domain-tools.test.ts +0 -759
- package/tests/unit/mcp/tools/registry.test.ts +0 -240
- package/tests/unit/neural-optimizer/replay-buffer.test.ts +0 -403
- package/tests/unit/neural-optimizer/swarm-topology.test.ts +0 -473
- package/tests/unit/neural-optimizer/topology-optimizer.test.ts +0 -595
- package/tests/unit/neural-optimizer/value-network.test.ts +0 -343
- package/tests/unit/optimization/auto-tuner.test.ts +0 -506
- package/tests/unit/optimization/metric-collectors.test.ts +0 -352
- package/tests/unit/optimization/qe-workers.test.ts +0 -407
- package/tests/unit/optimization/tuning-algorithm.test.ts +0 -467
- package/tests/unit/routing/qe-agent-registry.test.ts +0 -229
- package/tests/unit/routing/qe-task-router.test.ts +0 -390
- package/tests/unit/routing/routing-feedback.test.ts +0 -339
- package/tests/unit/shared/embeddings/nomic-embedder.test.ts +0 -419
- package/tests/unit/shared/http/http-client.test.ts +0 -719
- package/tests/unit/shared/io/file-reader.test.ts +0 -511
- package/tests/unit/shared/llm/cache.test.ts +0 -391
- package/tests/unit/shared/llm/circuit-breaker.test.ts +0 -293
- package/tests/unit/shared/llm/cost-tracker.test.ts +0 -431
- package/tests/unit/shared/llm/provider-manager.test.ts +0 -550
- package/tests/unit/shared/llm/providers.test.ts +0 -532
- package/tests/unit/shared/parsers/typescript-parser.test.ts +0 -693
- package/tests/unit/shared/value-objects.test.ts +0 -184
- package/tests/unit/strange-loop/strange-loop.test.ts +0 -1170
- package/tests/unit/workers/base-worker.test.ts +0 -341
- package/tests/unit/workers/daemon.test.ts +0 -291
- package/tests/unit/workers/worker-manager.test.ts +0 -284
- package/tsconfig.json +0 -32
- package/vitest.config.ts +0 -27
|
@@ -1,1917 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agentic QE v3 - Workflow Orchestrator
|
|
3
|
-
* Coordinates complete QE workflows across all 12 domains
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
7
|
-
import {
|
|
8
|
-
Result,
|
|
9
|
-
ok,
|
|
10
|
-
err,
|
|
11
|
-
DomainName,
|
|
12
|
-
ALL_DOMAINS,
|
|
13
|
-
DomainEvent,
|
|
14
|
-
} from '../shared/types/index.js';
|
|
15
|
-
import {
|
|
16
|
-
EventBus,
|
|
17
|
-
MemoryBackend,
|
|
18
|
-
AgentCoordinator,
|
|
19
|
-
Subscription,
|
|
20
|
-
} from '../kernel/interfaces.js';
|
|
21
|
-
import { createEvent } from '../shared/events/domain-events.js';
|
|
22
|
-
|
|
23
|
-
// ============================================================================
|
|
24
|
-
// Workflow Types
|
|
25
|
-
// ============================================================================
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Step execution mode
|
|
29
|
-
*/
|
|
30
|
-
export type StepExecutionMode = 'sequential' | 'parallel';
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Step status
|
|
34
|
-
*/
|
|
35
|
-
export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Workflow status
|
|
39
|
-
*/
|
|
40
|
-
export type WorkflowStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'paused';
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Condition operator
|
|
44
|
-
*/
|
|
45
|
-
export type ConditionOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'exists';
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Step condition for conditional branching
|
|
49
|
-
*/
|
|
50
|
-
export interface StepCondition {
|
|
51
|
-
/** Path to the value in context (e.g., 'results.coverage.line') */
|
|
52
|
-
path: string;
|
|
53
|
-
/** Comparison operator */
|
|
54
|
-
operator: ConditionOperator;
|
|
55
|
-
/** Value to compare against */
|
|
56
|
-
value: unknown;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Workflow step definition
|
|
61
|
-
*/
|
|
62
|
-
export interface WorkflowStepDefinition {
|
|
63
|
-
/** Unique step identifier */
|
|
64
|
-
id: string;
|
|
65
|
-
/** Human-readable name */
|
|
66
|
-
name: string;
|
|
67
|
-
/** Target domain for execution */
|
|
68
|
-
domain: DomainName;
|
|
69
|
-
/** Action to invoke on the domain */
|
|
70
|
-
action: string;
|
|
71
|
-
/** Input mapping from context */
|
|
72
|
-
inputMapping?: Record<string, string>;
|
|
73
|
-
/** Output mapping to context */
|
|
74
|
-
outputMapping?: Record<string, string>;
|
|
75
|
-
/** Step dependencies (step IDs that must complete first) */
|
|
76
|
-
dependsOn?: string[];
|
|
77
|
-
/** Condition to execute this step */
|
|
78
|
-
condition?: StepCondition;
|
|
79
|
-
/** Skip condition (if true, step is skipped) */
|
|
80
|
-
skipCondition?: StepCondition;
|
|
81
|
-
/** Timeout in milliseconds */
|
|
82
|
-
timeout?: number;
|
|
83
|
-
/** Retry configuration */
|
|
84
|
-
retry?: {
|
|
85
|
-
maxAttempts: number;
|
|
86
|
-
backoffMs: number;
|
|
87
|
-
backoffMultiplier?: number;
|
|
88
|
-
};
|
|
89
|
-
/** Rollback action if step fails */
|
|
90
|
-
rollback?: {
|
|
91
|
-
domain: DomainName;
|
|
92
|
-
action: string;
|
|
93
|
-
input?: Record<string, unknown>;
|
|
94
|
-
};
|
|
95
|
-
/** Continue workflow on failure */
|
|
96
|
-
continueOnFailure?: boolean;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Workflow definition
|
|
101
|
-
*/
|
|
102
|
-
export interface WorkflowDefinition {
|
|
103
|
-
/** Unique workflow identifier */
|
|
104
|
-
id: string;
|
|
105
|
-
/** Human-readable name */
|
|
106
|
-
name: string;
|
|
107
|
-
/** Description */
|
|
108
|
-
description: string;
|
|
109
|
-
/** Workflow version */
|
|
110
|
-
version: string;
|
|
111
|
-
/** Workflow steps */
|
|
112
|
-
steps: WorkflowStepDefinition[];
|
|
113
|
-
/** Default execution mode for steps without dependencies */
|
|
114
|
-
defaultMode?: StepExecutionMode;
|
|
115
|
-
/** Global timeout in milliseconds */
|
|
116
|
-
timeout?: number;
|
|
117
|
-
/** Event triggers */
|
|
118
|
-
triggers?: WorkflowTrigger[];
|
|
119
|
-
/** Tags for categorization */
|
|
120
|
-
tags?: string[];
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Workflow trigger definition
|
|
125
|
-
*/
|
|
126
|
-
export interface WorkflowTrigger {
|
|
127
|
-
/** Event type to trigger on */
|
|
128
|
-
eventType: string;
|
|
129
|
-
/** Optional source domain filter */
|
|
130
|
-
sourceDomain?: DomainName;
|
|
131
|
-
/** Condition to evaluate on event payload */
|
|
132
|
-
condition?: StepCondition;
|
|
133
|
-
/** Input mapping from event payload to workflow context */
|
|
134
|
-
inputMapping?: Record<string, string>;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Step execution result
|
|
139
|
-
*/
|
|
140
|
-
export interface StepExecutionResult {
|
|
141
|
-
stepId: string;
|
|
142
|
-
status: StepStatus;
|
|
143
|
-
startedAt: Date;
|
|
144
|
-
completedAt?: Date;
|
|
145
|
-
duration?: number;
|
|
146
|
-
output?: unknown;
|
|
147
|
-
error?: string;
|
|
148
|
-
retryCount?: number;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Workflow execution context
|
|
153
|
-
*/
|
|
154
|
-
export interface WorkflowContext {
|
|
155
|
-
/** Input parameters */
|
|
156
|
-
input: Record<string, unknown>;
|
|
157
|
-
/** Accumulated results from steps */
|
|
158
|
-
results: Record<string, unknown>;
|
|
159
|
-
/** Metadata */
|
|
160
|
-
metadata: {
|
|
161
|
-
executionId: string;
|
|
162
|
-
workflowId: string;
|
|
163
|
-
correlationId?: string;
|
|
164
|
-
startedAt: Date;
|
|
165
|
-
triggeredBy?: string;
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Workflow execution status
|
|
171
|
-
*/
|
|
172
|
-
export interface WorkflowExecutionStatus {
|
|
173
|
-
executionId: string;
|
|
174
|
-
workflowId: string;
|
|
175
|
-
workflowName: string;
|
|
176
|
-
status: WorkflowStatus;
|
|
177
|
-
startedAt: Date;
|
|
178
|
-
completedAt?: Date;
|
|
179
|
-
duration?: number;
|
|
180
|
-
progress: number;
|
|
181
|
-
currentSteps: string[];
|
|
182
|
-
completedSteps: string[];
|
|
183
|
-
failedSteps: string[];
|
|
184
|
-
skippedSteps: string[];
|
|
185
|
-
context: WorkflowContext;
|
|
186
|
-
stepResults: Map<string, StepExecutionResult>;
|
|
187
|
-
error?: string;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Workflow list item
|
|
192
|
-
*/
|
|
193
|
-
export interface WorkflowListItem {
|
|
194
|
-
id: string;
|
|
195
|
-
name: string;
|
|
196
|
-
description: string;
|
|
197
|
-
version: string;
|
|
198
|
-
stepCount: number;
|
|
199
|
-
tags?: string[];
|
|
200
|
-
triggers?: string[];
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// ============================================================================
|
|
204
|
-
// Workflow Events
|
|
205
|
-
// ============================================================================
|
|
206
|
-
|
|
207
|
-
export const WorkflowEvents = {
|
|
208
|
-
WorkflowStarted: 'workflow.WorkflowStarted',
|
|
209
|
-
WorkflowCompleted: 'workflow.WorkflowCompleted',
|
|
210
|
-
WorkflowFailed: 'workflow.WorkflowFailed',
|
|
211
|
-
WorkflowCancelled: 'workflow.WorkflowCancelled',
|
|
212
|
-
StepStarted: 'workflow.StepStarted',
|
|
213
|
-
StepCompleted: 'workflow.StepCompleted',
|
|
214
|
-
StepFailed: 'workflow.StepFailed',
|
|
215
|
-
StepSkipped: 'workflow.StepSkipped',
|
|
216
|
-
} as const;
|
|
217
|
-
|
|
218
|
-
export interface WorkflowStartedPayload {
|
|
219
|
-
executionId: string;
|
|
220
|
-
workflowId: string;
|
|
221
|
-
workflowName: string;
|
|
222
|
-
stepCount: number;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
export interface WorkflowCompletedPayload {
|
|
226
|
-
executionId: string;
|
|
227
|
-
workflowId: string;
|
|
228
|
-
workflowName: string;
|
|
229
|
-
duration: number;
|
|
230
|
-
completedSteps: number;
|
|
231
|
-
skippedSteps: number;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export interface WorkflowFailedPayload {
|
|
235
|
-
executionId: string;
|
|
236
|
-
workflowId: string;
|
|
237
|
-
workflowName: string;
|
|
238
|
-
failedStep: string;
|
|
239
|
-
error: string;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export interface StepEventPayload {
|
|
243
|
-
executionId: string;
|
|
244
|
-
workflowId: string;
|
|
245
|
-
stepId: string;
|
|
246
|
-
stepName: string;
|
|
247
|
-
domain: DomainName;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// ============================================================================
|
|
251
|
-
// Workflow Orchestrator Interface
|
|
252
|
-
// ============================================================================
|
|
253
|
-
|
|
254
|
-
export interface IWorkflowOrchestrator {
|
|
255
|
-
/** Initialize the orchestrator */
|
|
256
|
-
initialize(): Promise<void>;
|
|
257
|
-
/** Dispose resources */
|
|
258
|
-
dispose(): Promise<void>;
|
|
259
|
-
/** Register a workflow definition */
|
|
260
|
-
registerWorkflow(definition: WorkflowDefinition): Result<void, Error>;
|
|
261
|
-
/** Unregister a workflow */
|
|
262
|
-
unregisterWorkflow(workflowId: string): Result<void, Error>;
|
|
263
|
-
/** Execute a workflow */
|
|
264
|
-
executeWorkflow(
|
|
265
|
-
workflowId: string,
|
|
266
|
-
input?: Record<string, unknown>,
|
|
267
|
-
correlationId?: string
|
|
268
|
-
): Promise<Result<string, Error>>;
|
|
269
|
-
/** Get workflow execution status */
|
|
270
|
-
getWorkflowStatus(executionId: string): WorkflowExecutionStatus | undefined;
|
|
271
|
-
/** Cancel a running workflow */
|
|
272
|
-
cancelWorkflow(executionId: string): Promise<Result<void, Error>>;
|
|
273
|
-
/** Pause a running workflow */
|
|
274
|
-
pauseWorkflow(executionId: string): Promise<Result<void, Error>>;
|
|
275
|
-
/** Resume a paused workflow */
|
|
276
|
-
resumeWorkflow(executionId: string): Promise<Result<void, Error>>;
|
|
277
|
-
/** List registered workflows */
|
|
278
|
-
listWorkflows(): WorkflowListItem[];
|
|
279
|
-
/** Get active executions */
|
|
280
|
-
getActiveExecutions(): WorkflowExecutionStatus[];
|
|
281
|
-
/** Get workflow definition */
|
|
282
|
-
getWorkflow(workflowId: string): WorkflowDefinition | undefined;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// ============================================================================
|
|
286
|
-
// Domain Action Registry
|
|
287
|
-
// ============================================================================
|
|
288
|
-
|
|
289
|
-
type DomainAction = (
|
|
290
|
-
input: Record<string, unknown>,
|
|
291
|
-
context: WorkflowContext
|
|
292
|
-
) => Promise<Result<unknown, Error>>;
|
|
293
|
-
|
|
294
|
-
interface DomainActionRegistry {
|
|
295
|
-
[domain: string]: {
|
|
296
|
-
[action: string]: DomainAction;
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// ============================================================================
|
|
301
|
-
// Workflow Orchestrator Implementation
|
|
302
|
-
// ============================================================================
|
|
303
|
-
|
|
304
|
-
export interface WorkflowOrchestratorConfig {
|
|
305
|
-
maxConcurrentWorkflows: number;
|
|
306
|
-
defaultStepTimeout: number;
|
|
307
|
-
defaultWorkflowTimeout: number;
|
|
308
|
-
enableEventTriggers: boolean;
|
|
309
|
-
persistExecutions: boolean;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const DEFAULT_CONFIG: WorkflowOrchestratorConfig = {
|
|
313
|
-
maxConcurrentWorkflows: 10,
|
|
314
|
-
defaultStepTimeout: 60000,
|
|
315
|
-
defaultWorkflowTimeout: 600000,
|
|
316
|
-
enableEventTriggers: true,
|
|
317
|
-
persistExecutions: true,
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
export class WorkflowOrchestrator implements IWorkflowOrchestrator {
|
|
321
|
-
private readonly config: WorkflowOrchestratorConfig;
|
|
322
|
-
private readonly workflows: Map<string, WorkflowDefinition> = new Map();
|
|
323
|
-
private readonly executions: Map<string, WorkflowExecutionStatus> = new Map();
|
|
324
|
-
private readonly actionRegistry: DomainActionRegistry = {};
|
|
325
|
-
private readonly eventSubscriptions: Subscription[] = [];
|
|
326
|
-
private initialized = false;
|
|
327
|
-
|
|
328
|
-
constructor(
|
|
329
|
-
private readonly eventBus: EventBus,
|
|
330
|
-
private readonly memory: MemoryBackend,
|
|
331
|
-
private readonly agentCoordinator: AgentCoordinator,
|
|
332
|
-
config: Partial<WorkflowOrchestratorConfig> = {}
|
|
333
|
-
) {
|
|
334
|
-
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Initialize the orchestrator
|
|
339
|
-
*/
|
|
340
|
-
async initialize(): Promise<void> {
|
|
341
|
-
if (this.initialized) return;
|
|
342
|
-
|
|
343
|
-
// Register built-in workflows
|
|
344
|
-
this.registerBuiltInWorkflows();
|
|
345
|
-
|
|
346
|
-
// Set up event triggers if enabled
|
|
347
|
-
if (this.config.enableEventTriggers) {
|
|
348
|
-
this.setupEventTriggers();
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Load persisted workflow definitions
|
|
352
|
-
await this.loadPersistedWorkflows();
|
|
353
|
-
|
|
354
|
-
this.initialized = true;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Dispose resources
|
|
359
|
-
*/
|
|
360
|
-
async dispose(): Promise<void> {
|
|
361
|
-
// Cancel all active executions
|
|
362
|
-
for (const execution of this.executions.values()) {
|
|
363
|
-
if (execution.status === 'running') {
|
|
364
|
-
await this.cancelWorkflow(execution.executionId);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Unsubscribe from events
|
|
369
|
-
for (const subscription of this.eventSubscriptions) {
|
|
370
|
-
subscription.unsubscribe();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Persist workflow definitions
|
|
374
|
-
await this.persistWorkflows();
|
|
375
|
-
|
|
376
|
-
this.initialized = false;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Register a workflow definition
|
|
381
|
-
*/
|
|
382
|
-
registerWorkflow(definition: WorkflowDefinition): Result<void, Error> {
|
|
383
|
-
try {
|
|
384
|
-
// Validate workflow
|
|
385
|
-
const validationResult = this.validateWorkflowDefinition(definition);
|
|
386
|
-
if (!validationResult.success) {
|
|
387
|
-
return validationResult;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Store workflow
|
|
391
|
-
this.workflows.set(definition.id, definition);
|
|
392
|
-
|
|
393
|
-
// Set up triggers
|
|
394
|
-
if (this.config.enableEventTriggers && definition.triggers) {
|
|
395
|
-
this.registerWorkflowTriggers(definition);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
return ok(undefined);
|
|
399
|
-
} catch (error) {
|
|
400
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Unregister a workflow
|
|
406
|
-
*/
|
|
407
|
-
unregisterWorkflow(workflowId: string): Result<void, Error> {
|
|
408
|
-
if (!this.workflows.has(workflowId)) {
|
|
409
|
-
return err(new Error(`Workflow not found: ${workflowId}`));
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Check for active executions
|
|
413
|
-
const activeExecutions = Array.from(this.executions.values()).filter(
|
|
414
|
-
(e) => e.workflowId === workflowId && e.status === 'running'
|
|
415
|
-
);
|
|
416
|
-
|
|
417
|
-
if (activeExecutions.length > 0) {
|
|
418
|
-
return err(
|
|
419
|
-
new Error(
|
|
420
|
-
`Cannot unregister workflow with ${activeExecutions.length} active execution(s)`
|
|
421
|
-
)
|
|
422
|
-
);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
this.workflows.delete(workflowId);
|
|
426
|
-
return ok(undefined);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Execute a workflow
|
|
431
|
-
*/
|
|
432
|
-
async executeWorkflow(
|
|
433
|
-
workflowId: string,
|
|
434
|
-
input: Record<string, unknown> = {},
|
|
435
|
-
correlationId?: string
|
|
436
|
-
): Promise<Result<string, Error>> {
|
|
437
|
-
const workflow = this.workflows.get(workflowId);
|
|
438
|
-
if (!workflow) {
|
|
439
|
-
return err(new Error(`Workflow not found: ${workflowId}`));
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
// Check concurrent execution limit
|
|
443
|
-
const activeCount = Array.from(this.executions.values()).filter(
|
|
444
|
-
(e) => e.status === 'running'
|
|
445
|
-
).length;
|
|
446
|
-
|
|
447
|
-
if (activeCount >= this.config.maxConcurrentWorkflows) {
|
|
448
|
-
return err(
|
|
449
|
-
new Error(
|
|
450
|
-
`Maximum concurrent workflows (${this.config.maxConcurrentWorkflows}) reached`
|
|
451
|
-
)
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
const executionId = uuidv4();
|
|
456
|
-
const startedAt = new Date();
|
|
457
|
-
|
|
458
|
-
// Initialize execution context
|
|
459
|
-
const context: WorkflowContext = {
|
|
460
|
-
input,
|
|
461
|
-
results: {},
|
|
462
|
-
metadata: {
|
|
463
|
-
executionId,
|
|
464
|
-
workflowId,
|
|
465
|
-
correlationId: correlationId || executionId,
|
|
466
|
-
startedAt,
|
|
467
|
-
},
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
// Initialize execution status
|
|
471
|
-
const execution: WorkflowExecutionStatus = {
|
|
472
|
-
executionId,
|
|
473
|
-
workflowId,
|
|
474
|
-
workflowName: workflow.name,
|
|
475
|
-
status: 'running',
|
|
476
|
-
startedAt,
|
|
477
|
-
progress: 0,
|
|
478
|
-
currentSteps: [],
|
|
479
|
-
completedSteps: [],
|
|
480
|
-
failedSteps: [],
|
|
481
|
-
skippedSteps: [],
|
|
482
|
-
context,
|
|
483
|
-
stepResults: new Map(),
|
|
484
|
-
};
|
|
485
|
-
|
|
486
|
-
this.executions.set(executionId, execution);
|
|
487
|
-
|
|
488
|
-
// Publish workflow started event
|
|
489
|
-
await this.publishWorkflowStarted(execution, workflow);
|
|
490
|
-
|
|
491
|
-
// Execute workflow asynchronously
|
|
492
|
-
this.runWorkflow(workflow, execution).catch(async (error) => {
|
|
493
|
-
execution.status = 'failed';
|
|
494
|
-
execution.error = String(error);
|
|
495
|
-
execution.completedAt = new Date();
|
|
496
|
-
execution.duration = execution.completedAt.getTime() - startedAt.getTime();
|
|
497
|
-
|
|
498
|
-
await this.publishWorkflowFailed(execution, 'unknown', String(error));
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
return ok(executionId);
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Get workflow execution status
|
|
506
|
-
*/
|
|
507
|
-
getWorkflowStatus(executionId: string): WorkflowExecutionStatus | undefined {
|
|
508
|
-
return this.executions.get(executionId);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Cancel a running workflow
|
|
513
|
-
*/
|
|
514
|
-
async cancelWorkflow(executionId: string): Promise<Result<void, Error>> {
|
|
515
|
-
const execution = this.executions.get(executionId);
|
|
516
|
-
if (!execution) {
|
|
517
|
-
return err(new Error(`Execution not found: ${executionId}`));
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
if (execution.status !== 'running' && execution.status !== 'paused') {
|
|
521
|
-
return err(new Error(`Cannot cancel workflow in status: ${execution.status}`));
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
execution.status = 'cancelled';
|
|
525
|
-
execution.completedAt = new Date();
|
|
526
|
-
execution.duration =
|
|
527
|
-
execution.completedAt.getTime() - execution.startedAt.getTime();
|
|
528
|
-
|
|
529
|
-
// Publish cancellation event
|
|
530
|
-
await this.publishEvent(
|
|
531
|
-
WorkflowEvents.WorkflowCancelled,
|
|
532
|
-
{
|
|
533
|
-
executionId,
|
|
534
|
-
workflowId: execution.workflowId,
|
|
535
|
-
workflowName: execution.workflowName,
|
|
536
|
-
},
|
|
537
|
-
execution.context.metadata.correlationId
|
|
538
|
-
);
|
|
539
|
-
|
|
540
|
-
return ok(undefined);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Pause a running workflow
|
|
545
|
-
*/
|
|
546
|
-
async pauseWorkflow(executionId: string): Promise<Result<void, Error>> {
|
|
547
|
-
const execution = this.executions.get(executionId);
|
|
548
|
-
if (!execution) {
|
|
549
|
-
return err(new Error(`Execution not found: ${executionId}`));
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
if (execution.status !== 'running') {
|
|
553
|
-
return err(new Error(`Cannot pause workflow in status: ${execution.status}`));
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
execution.status = 'paused';
|
|
557
|
-
return ok(undefined);
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
/**
|
|
561
|
-
* Resume a paused workflow
|
|
562
|
-
*/
|
|
563
|
-
async resumeWorkflow(executionId: string): Promise<Result<void, Error>> {
|
|
564
|
-
const execution = this.executions.get(executionId);
|
|
565
|
-
if (!execution) {
|
|
566
|
-
return err(new Error(`Execution not found: ${executionId}`));
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
if (execution.status !== 'paused') {
|
|
570
|
-
return err(new Error(`Cannot resume workflow in status: ${execution.status}`));
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const workflow = this.workflows.get(execution.workflowId);
|
|
574
|
-
if (!workflow) {
|
|
575
|
-
return err(new Error(`Workflow definition not found: ${execution.workflowId}`));
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
execution.status = 'running';
|
|
579
|
-
|
|
580
|
-
// Continue execution from where it was paused
|
|
581
|
-
this.runWorkflow(workflow, execution).catch(async (error) => {
|
|
582
|
-
execution.status = 'failed';
|
|
583
|
-
execution.error = String(error);
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
return ok(undefined);
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* List registered workflows
|
|
591
|
-
*/
|
|
592
|
-
listWorkflows(): WorkflowListItem[] {
|
|
593
|
-
return Array.from(this.workflows.values()).map((w) => ({
|
|
594
|
-
id: w.id,
|
|
595
|
-
name: w.name,
|
|
596
|
-
description: w.description,
|
|
597
|
-
version: w.version,
|
|
598
|
-
stepCount: w.steps.length,
|
|
599
|
-
tags: w.tags,
|
|
600
|
-
triggers: w.triggers?.map((t) => t.eventType),
|
|
601
|
-
}));
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Get active executions
|
|
606
|
-
*/
|
|
607
|
-
getActiveExecutions(): WorkflowExecutionStatus[] {
|
|
608
|
-
return Array.from(this.executions.values()).filter(
|
|
609
|
-
(e) => e.status === 'running' || e.status === 'paused'
|
|
610
|
-
);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
/**
|
|
614
|
-
* Get workflow definition
|
|
615
|
-
*/
|
|
616
|
-
getWorkflow(workflowId: string): WorkflowDefinition | undefined {
|
|
617
|
-
return this.workflows.get(workflowId);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
// ============================================================================
|
|
621
|
-
// Private Methods - Workflow Execution
|
|
622
|
-
// ============================================================================
|
|
623
|
-
|
|
624
|
-
private async runWorkflow(
|
|
625
|
-
workflow: WorkflowDefinition,
|
|
626
|
-
execution: WorkflowExecutionStatus
|
|
627
|
-
): Promise<void> {
|
|
628
|
-
const timeout = workflow.timeout || this.config.defaultWorkflowTimeout;
|
|
629
|
-
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
630
|
-
setTimeout(
|
|
631
|
-
() => reject(new Error(`Workflow timeout after ${timeout}ms`)),
|
|
632
|
-
timeout
|
|
633
|
-
);
|
|
634
|
-
});
|
|
635
|
-
|
|
636
|
-
try {
|
|
637
|
-
await Promise.race([
|
|
638
|
-
this.executeSteps(workflow, execution),
|
|
639
|
-
timeoutPromise,
|
|
640
|
-
]);
|
|
641
|
-
|
|
642
|
-
if (execution.status === 'running') {
|
|
643
|
-
execution.status = 'completed';
|
|
644
|
-
execution.completedAt = new Date();
|
|
645
|
-
execution.duration =
|
|
646
|
-
execution.completedAt.getTime() - execution.startedAt.getTime();
|
|
647
|
-
execution.progress = 100;
|
|
648
|
-
|
|
649
|
-
await this.publishWorkflowCompleted(execution);
|
|
650
|
-
}
|
|
651
|
-
} catch (error) {
|
|
652
|
-
if (execution.status === 'running') {
|
|
653
|
-
execution.status = 'failed';
|
|
654
|
-
execution.error = String(error);
|
|
655
|
-
execution.completedAt = new Date();
|
|
656
|
-
execution.duration =
|
|
657
|
-
execution.completedAt.getTime() - execution.startedAt.getTime();
|
|
658
|
-
|
|
659
|
-
const failedStep = execution.currentSteps[0] || 'unknown';
|
|
660
|
-
await this.publishWorkflowFailed(execution, failedStep, String(error));
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// Persist execution if configured
|
|
665
|
-
if (this.config.persistExecutions) {
|
|
666
|
-
await this.persistExecution(execution);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
private async executeSteps(
|
|
671
|
-
workflow: WorkflowDefinition,
|
|
672
|
-
execution: WorkflowExecutionStatus
|
|
673
|
-
): Promise<void> {
|
|
674
|
-
const steps = workflow.steps;
|
|
675
|
-
const completedSteps = new Set(execution.completedSteps);
|
|
676
|
-
const skippedSteps = new Set(execution.skippedSteps);
|
|
677
|
-
const failedSteps = new Set(execution.failedSteps);
|
|
678
|
-
|
|
679
|
-
// Build dependency graph
|
|
680
|
-
const pendingSteps = steps.filter(
|
|
681
|
-
(s) =>
|
|
682
|
-
!completedSteps.has(s.id) &&
|
|
683
|
-
!skippedSteps.has(s.id) &&
|
|
684
|
-
!failedSteps.has(s.id)
|
|
685
|
-
);
|
|
686
|
-
|
|
687
|
-
while (pendingSteps.length > 0 && execution.status === 'running') {
|
|
688
|
-
// Find steps that are ready to execute (all dependencies satisfied)
|
|
689
|
-
const readySteps = pendingSteps.filter((step) => {
|
|
690
|
-
const deps = step.dependsOn || [];
|
|
691
|
-
return deps.every(
|
|
692
|
-
(depId) => completedSteps.has(depId) || skippedSteps.has(depId)
|
|
693
|
-
);
|
|
694
|
-
});
|
|
695
|
-
|
|
696
|
-
if (readySteps.length === 0) {
|
|
697
|
-
// Deadlock or all remaining steps have failed dependencies
|
|
698
|
-
break;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
// Determine execution mode
|
|
702
|
-
const parallelSteps = readySteps.filter((s) => !s.dependsOn?.length);
|
|
703
|
-
const sequentialSteps = readySteps.filter((s) => s.dependsOn?.length);
|
|
704
|
-
|
|
705
|
-
// Execute parallel steps concurrently
|
|
706
|
-
if (parallelSteps.length > 0) {
|
|
707
|
-
execution.currentSteps = parallelSteps.map((s) => s.id);
|
|
708
|
-
|
|
709
|
-
const results = await Promise.allSettled(
|
|
710
|
-
parallelSteps.map((step) =>
|
|
711
|
-
this.executeStep(step, execution, workflow)
|
|
712
|
-
)
|
|
713
|
-
);
|
|
714
|
-
|
|
715
|
-
for (let i = 0; i < parallelSteps.length; i++) {
|
|
716
|
-
const step = parallelSteps[i];
|
|
717
|
-
const result = results[i];
|
|
718
|
-
|
|
719
|
-
if (result.status === 'fulfilled') {
|
|
720
|
-
const stepResult = result.value;
|
|
721
|
-
if (stepResult.status === 'completed') {
|
|
722
|
-
completedSteps.add(step.id);
|
|
723
|
-
execution.completedSteps.push(step.id);
|
|
724
|
-
} else if (stepResult.status === 'skipped') {
|
|
725
|
-
skippedSteps.add(step.id);
|
|
726
|
-
execution.skippedSteps.push(step.id);
|
|
727
|
-
} else if (stepResult.status === 'failed') {
|
|
728
|
-
failedSteps.add(step.id);
|
|
729
|
-
execution.failedSteps.push(step.id);
|
|
730
|
-
|
|
731
|
-
if (!step.continueOnFailure) {
|
|
732
|
-
execution.status = 'failed';
|
|
733
|
-
execution.error = stepResult.error;
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
} else {
|
|
738
|
-
failedSteps.add(step.id);
|
|
739
|
-
execution.failedSteps.push(step.id);
|
|
740
|
-
|
|
741
|
-
if (!step.continueOnFailure) {
|
|
742
|
-
execution.status = 'failed';
|
|
743
|
-
execution.error = result.reason?.message || 'Unknown error';
|
|
744
|
-
return;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
// Remove from pending
|
|
749
|
-
const pendingIndex = pendingSteps.indexOf(step);
|
|
750
|
-
if (pendingIndex !== -1) {
|
|
751
|
-
pendingSteps.splice(pendingIndex, 1);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
// Execute sequential steps one at a time
|
|
757
|
-
for (const step of sequentialSteps) {
|
|
758
|
-
if (execution.status !== 'running') break;
|
|
759
|
-
|
|
760
|
-
execution.currentSteps = [step.id];
|
|
761
|
-
|
|
762
|
-
const stepResult = await this.executeStep(step, execution, workflow);
|
|
763
|
-
|
|
764
|
-
if (stepResult.status === 'completed') {
|
|
765
|
-
completedSteps.add(step.id);
|
|
766
|
-
execution.completedSteps.push(step.id);
|
|
767
|
-
} else if (stepResult.status === 'skipped') {
|
|
768
|
-
skippedSteps.add(step.id);
|
|
769
|
-
execution.skippedSteps.push(step.id);
|
|
770
|
-
} else if (stepResult.status === 'failed') {
|
|
771
|
-
failedSteps.add(step.id);
|
|
772
|
-
execution.failedSteps.push(step.id);
|
|
773
|
-
|
|
774
|
-
if (!step.continueOnFailure) {
|
|
775
|
-
execution.status = 'failed';
|
|
776
|
-
execution.error = stepResult.error;
|
|
777
|
-
return;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
// Remove from pending
|
|
782
|
-
const pendingIndex = pendingSteps.indexOf(step);
|
|
783
|
-
if (pendingIndex !== -1) {
|
|
784
|
-
pendingSteps.splice(pendingIndex, 1);
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
// Update progress
|
|
789
|
-
const totalSteps = steps.length;
|
|
790
|
-
const processedSteps =
|
|
791
|
-
completedSteps.size + skippedSteps.size + failedSteps.size;
|
|
792
|
-
execution.progress = Math.round((processedSteps / totalSteps) * 100);
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
execution.currentSteps = [];
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
private async executeStep(
|
|
799
|
-
step: WorkflowStepDefinition,
|
|
800
|
-
execution: WorkflowExecutionStatus,
|
|
801
|
-
_workflow: WorkflowDefinition
|
|
802
|
-
): Promise<StepExecutionResult> {
|
|
803
|
-
const startedAt = new Date();
|
|
804
|
-
const result: StepExecutionResult = {
|
|
805
|
-
stepId: step.id,
|
|
806
|
-
status: 'pending',
|
|
807
|
-
startedAt,
|
|
808
|
-
};
|
|
809
|
-
|
|
810
|
-
try {
|
|
811
|
-
// Check skip condition
|
|
812
|
-
if (step.skipCondition && this.evaluateCondition(step.skipCondition, execution.context)) {
|
|
813
|
-
result.status = 'skipped';
|
|
814
|
-
result.completedAt = new Date();
|
|
815
|
-
result.duration = result.completedAt.getTime() - startedAt.getTime();
|
|
816
|
-
execution.stepResults.set(step.id, result);
|
|
817
|
-
|
|
818
|
-
await this.publishStepSkipped(execution, step);
|
|
819
|
-
return result;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
// Check execution condition
|
|
823
|
-
if (step.condition && !this.evaluateCondition(step.condition, execution.context)) {
|
|
824
|
-
result.status = 'skipped';
|
|
825
|
-
result.completedAt = new Date();
|
|
826
|
-
result.duration = result.completedAt.getTime() - startedAt.getTime();
|
|
827
|
-
execution.stepResults.set(step.id, result);
|
|
828
|
-
|
|
829
|
-
await this.publishStepSkipped(execution, step);
|
|
830
|
-
return result;
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
result.status = 'running';
|
|
834
|
-
await this.publishStepStarted(execution, step);
|
|
835
|
-
|
|
836
|
-
// Build input from mapping
|
|
837
|
-
const input = this.buildStepInput(step, execution.context);
|
|
838
|
-
|
|
839
|
-
// Execute with retry logic
|
|
840
|
-
let lastError: Error | undefined;
|
|
841
|
-
const maxAttempts = step.retry?.maxAttempts || 1;
|
|
842
|
-
let backoffMs = step.retry?.backoffMs || 1000;
|
|
843
|
-
const backoffMultiplier = step.retry?.backoffMultiplier || 2;
|
|
844
|
-
|
|
845
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
846
|
-
result.retryCount = attempt - 1;
|
|
847
|
-
|
|
848
|
-
try {
|
|
849
|
-
const stepTimeout = step.timeout || this.config.defaultStepTimeout;
|
|
850
|
-
const output = await this.executeStepAction(
|
|
851
|
-
step,
|
|
852
|
-
input,
|
|
853
|
-
execution.context,
|
|
854
|
-
stepTimeout
|
|
855
|
-
);
|
|
856
|
-
|
|
857
|
-
// Map output to context
|
|
858
|
-
this.mapStepOutput(step, output, execution.context);
|
|
859
|
-
|
|
860
|
-
result.status = 'completed';
|
|
861
|
-
result.output = output;
|
|
862
|
-
result.completedAt = new Date();
|
|
863
|
-
result.duration = result.completedAt.getTime() - startedAt.getTime();
|
|
864
|
-
execution.stepResults.set(step.id, result);
|
|
865
|
-
|
|
866
|
-
await this.publishStepCompleted(execution, step, result);
|
|
867
|
-
return result;
|
|
868
|
-
} catch (error) {
|
|
869
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
870
|
-
|
|
871
|
-
if (attempt < maxAttempts) {
|
|
872
|
-
await this.delay(backoffMs);
|
|
873
|
-
backoffMs *= backoffMultiplier;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
// All retries failed
|
|
879
|
-
result.status = 'failed';
|
|
880
|
-
result.error = lastError?.message || 'Unknown error';
|
|
881
|
-
result.completedAt = new Date();
|
|
882
|
-
result.duration = result.completedAt.getTime() - startedAt.getTime();
|
|
883
|
-
execution.stepResults.set(step.id, result);
|
|
884
|
-
|
|
885
|
-
// Execute rollback if defined
|
|
886
|
-
if (step.rollback) {
|
|
887
|
-
await this.executeRollback(step.rollback, execution.context);
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
await this.publishStepFailed(execution, step, result.error);
|
|
891
|
-
return result;
|
|
892
|
-
} catch (error) {
|
|
893
|
-
result.status = 'failed';
|
|
894
|
-
result.error = error instanceof Error ? error.message : String(error);
|
|
895
|
-
result.completedAt = new Date();
|
|
896
|
-
result.duration = result.completedAt.getTime() - startedAt.getTime();
|
|
897
|
-
execution.stepResults.set(step.id, result);
|
|
898
|
-
|
|
899
|
-
await this.publishStepFailed(execution, step, result.error);
|
|
900
|
-
return result;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
private async executeStepAction(
|
|
905
|
-
step: WorkflowStepDefinition,
|
|
906
|
-
input: Record<string, unknown>,
|
|
907
|
-
context: WorkflowContext,
|
|
908
|
-
timeout: number
|
|
909
|
-
): Promise<unknown> {
|
|
910
|
-
// Check if action is registered
|
|
911
|
-
const domainActions = this.actionRegistry[step.domain];
|
|
912
|
-
if (domainActions?.[step.action]) {
|
|
913
|
-
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
914
|
-
setTimeout(() => reject(new Error(`Step timeout after ${timeout}ms`)), timeout);
|
|
915
|
-
});
|
|
916
|
-
|
|
917
|
-
const actionResult = await Promise.race([
|
|
918
|
-
domainActions[step.action](input, context),
|
|
919
|
-
timeoutPromise,
|
|
920
|
-
]);
|
|
921
|
-
|
|
922
|
-
if (!actionResult.success) {
|
|
923
|
-
throw actionResult.error;
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
return actionResult.value;
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
// No action registered - throw error rather than fake success
|
|
930
|
-
throw new Error(
|
|
931
|
-
`Action '${step.action}' not registered for domain '${step.domain}'. ` +
|
|
932
|
-
`Register it using orchestrator.registerAction('${step.domain}', '${step.action}', handler)`
|
|
933
|
-
);
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
/**
|
|
937
|
-
* Check if an action is registered for a domain
|
|
938
|
-
*/
|
|
939
|
-
isActionRegistered(domain: DomainName, action: string): boolean {
|
|
940
|
-
return !!this.actionRegistry[domain]?.[action];
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
/**
|
|
944
|
-
* Get all registered actions for a domain
|
|
945
|
-
*/
|
|
946
|
-
getRegisteredActions(domain: DomainName): string[] {
|
|
947
|
-
return Object.keys(this.actionRegistry[domain] || {});
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
/**
|
|
951
|
-
* Get all domains with registered actions
|
|
952
|
-
*/
|
|
953
|
-
getDomainsWithActions(): DomainName[] {
|
|
954
|
-
return Object.keys(this.actionRegistry) as DomainName[];
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
/**
|
|
958
|
-
* Spawn a workflow agent for complex step execution
|
|
959
|
-
* Used when steps require dedicated agent resources
|
|
960
|
-
*/
|
|
961
|
-
async spawnWorkflowAgent(
|
|
962
|
-
workflowId: string,
|
|
963
|
-
stepId: string,
|
|
964
|
-
domain: DomainName
|
|
965
|
-
): Promise<Result<string, Error>> {
|
|
966
|
-
if (!this.agentCoordinator.canSpawn()) {
|
|
967
|
-
return err(new Error('Agent limit reached'));
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
return this.agentCoordinator.spawn({
|
|
971
|
-
name: `workflow-agent-${workflowId.slice(0, 8)}-${stepId}`,
|
|
972
|
-
domain,
|
|
973
|
-
type: 'coordinator',
|
|
974
|
-
capabilities: ['workflow-execution', stepId],
|
|
975
|
-
config: {
|
|
976
|
-
workflowId,
|
|
977
|
-
stepId,
|
|
978
|
-
},
|
|
979
|
-
});
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
/**
|
|
983
|
-
* Stop a workflow agent after step completion
|
|
984
|
-
*/
|
|
985
|
-
async stopWorkflowAgent(agentId: string): Promise<Result<void, Error>> {
|
|
986
|
-
return this.agentCoordinator.stop(agentId);
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
/**
|
|
990
|
-
* Get the number of agents available for workflow execution
|
|
991
|
-
*/
|
|
992
|
-
getAvailableAgentCapacity(): number {
|
|
993
|
-
return this.agentCoordinator.canSpawn()
|
|
994
|
-
? this.config.maxConcurrentWorkflows - this.getActiveExecutions().length
|
|
995
|
-
: 0;
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
private async executeRollback(
|
|
999
|
-
rollback: { domain: DomainName; action: string; input?: Record<string, unknown> },
|
|
1000
|
-
context: WorkflowContext
|
|
1001
|
-
): Promise<void> {
|
|
1002
|
-
try {
|
|
1003
|
-
// Check if rollback action is registered
|
|
1004
|
-
const domainActions = this.actionRegistry[rollback.domain];
|
|
1005
|
-
if (!domainActions?.[rollback.action]) {
|
|
1006
|
-
console.warn(
|
|
1007
|
-
`Rollback action '${rollback.action}' not registered for domain '${rollback.domain}'. Skipping rollback.`
|
|
1008
|
-
);
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
// Execute rollback action
|
|
1013
|
-
const result = await domainActions[rollback.action](
|
|
1014
|
-
rollback.input || {},
|
|
1015
|
-
context
|
|
1016
|
-
);
|
|
1017
|
-
|
|
1018
|
-
if (!result.success) {
|
|
1019
|
-
console.error(
|
|
1020
|
-
`Rollback failed for ${rollback.domain}.${rollback.action}:`,
|
|
1021
|
-
result.error
|
|
1022
|
-
);
|
|
1023
|
-
}
|
|
1024
|
-
} catch (error) {
|
|
1025
|
-
// Log but don't throw - rollback failures shouldn't cascade
|
|
1026
|
-
console.error(`Rollback failed for ${rollback.domain}.${rollback.action}:`, error);
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
// ============================================================================
|
|
1031
|
-
// Private Methods - Input/Output Mapping
|
|
1032
|
-
// ============================================================================
|
|
1033
|
-
|
|
1034
|
-
private buildStepInput(
|
|
1035
|
-
step: WorkflowStepDefinition,
|
|
1036
|
-
context: WorkflowContext
|
|
1037
|
-
): Record<string, unknown> {
|
|
1038
|
-
const input: Record<string, unknown> = {};
|
|
1039
|
-
|
|
1040
|
-
if (step.inputMapping) {
|
|
1041
|
-
for (const [targetKey, sourcePath] of Object.entries(step.inputMapping)) {
|
|
1042
|
-
const value = this.getValueByPath(context, sourcePath);
|
|
1043
|
-
if (value !== undefined) {
|
|
1044
|
-
input[targetKey] = value;
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
return input;
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
private mapStepOutput(
|
|
1053
|
-
step: WorkflowStepDefinition,
|
|
1054
|
-
output: unknown,
|
|
1055
|
-
context: WorkflowContext
|
|
1056
|
-
): void {
|
|
1057
|
-
// Store raw output
|
|
1058
|
-
context.results[step.id] = output;
|
|
1059
|
-
|
|
1060
|
-
// Apply output mapping
|
|
1061
|
-
if (step.outputMapping && typeof output === 'object' && output !== null) {
|
|
1062
|
-
for (const [sourcePath, targetPath] of Object.entries(step.outputMapping)) {
|
|
1063
|
-
const value = this.getValueByPath(output, sourcePath);
|
|
1064
|
-
if (value !== undefined) {
|
|
1065
|
-
this.setValueByPath(context.results, targetPath, value);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
private getValueByPath(obj: unknown, path: string): unknown {
|
|
1072
|
-
const parts = path.split('.');
|
|
1073
|
-
let current: unknown = obj;
|
|
1074
|
-
|
|
1075
|
-
for (const part of parts) {
|
|
1076
|
-
if (current === null || current === undefined) {
|
|
1077
|
-
return undefined;
|
|
1078
|
-
}
|
|
1079
|
-
if (typeof current === 'object') {
|
|
1080
|
-
current = (current as Record<string, unknown>)[part];
|
|
1081
|
-
} else {
|
|
1082
|
-
return undefined;
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
return current;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
private setValueByPath(
|
|
1090
|
-
obj: Record<string, unknown>,
|
|
1091
|
-
path: string,
|
|
1092
|
-
value: unknown
|
|
1093
|
-
): void {
|
|
1094
|
-
const parts = path.split('.');
|
|
1095
|
-
let current = obj;
|
|
1096
|
-
|
|
1097
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
1098
|
-
const part = parts[i];
|
|
1099
|
-
if (!(part in current)) {
|
|
1100
|
-
current[part] = {};
|
|
1101
|
-
}
|
|
1102
|
-
current = current[part] as Record<string, unknown>;
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
current[parts[parts.length - 1]] = value;
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
// ============================================================================
|
|
1109
|
-
// Private Methods - Condition Evaluation
|
|
1110
|
-
// ============================================================================
|
|
1111
|
-
|
|
1112
|
-
private evaluateCondition(
|
|
1113
|
-
condition: StepCondition,
|
|
1114
|
-
context: WorkflowContext
|
|
1115
|
-
): boolean {
|
|
1116
|
-
const value = this.getValueByPath(context, condition.path);
|
|
1117
|
-
|
|
1118
|
-
switch (condition.operator) {
|
|
1119
|
-
case 'eq':
|
|
1120
|
-
return value === condition.value;
|
|
1121
|
-
case 'neq':
|
|
1122
|
-
return value !== condition.value;
|
|
1123
|
-
case 'gt':
|
|
1124
|
-
return typeof value === 'number' && value > (condition.value as number);
|
|
1125
|
-
case 'gte':
|
|
1126
|
-
return typeof value === 'number' && value >= (condition.value as number);
|
|
1127
|
-
case 'lt':
|
|
1128
|
-
return typeof value === 'number' && value < (condition.value as number);
|
|
1129
|
-
case 'lte':
|
|
1130
|
-
return typeof value === 'number' && value <= (condition.value as number);
|
|
1131
|
-
case 'contains':
|
|
1132
|
-
if (Array.isArray(value)) {
|
|
1133
|
-
return value.includes(condition.value);
|
|
1134
|
-
}
|
|
1135
|
-
if (typeof value === 'string') {
|
|
1136
|
-
return value.includes(String(condition.value));
|
|
1137
|
-
}
|
|
1138
|
-
return false;
|
|
1139
|
-
case 'exists':
|
|
1140
|
-
return value !== undefined && value !== null;
|
|
1141
|
-
default:
|
|
1142
|
-
return false;
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
// ============================================================================
|
|
1147
|
-
// Private Methods - Event Publishing
|
|
1148
|
-
// ============================================================================
|
|
1149
|
-
|
|
1150
|
-
private async publishEvent<T>(
|
|
1151
|
-
type: string,
|
|
1152
|
-
payload: T,
|
|
1153
|
-
correlationId?: string
|
|
1154
|
-
): Promise<void> {
|
|
1155
|
-
const event = createEvent(
|
|
1156
|
-
type,
|
|
1157
|
-
'learning-optimization' as DomainName, // Workflow orchestrator publishes as coordination
|
|
1158
|
-
payload,
|
|
1159
|
-
correlationId
|
|
1160
|
-
);
|
|
1161
|
-
await this.eventBus.publish(event);
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
private async publishWorkflowStarted(
|
|
1165
|
-
execution: WorkflowExecutionStatus,
|
|
1166
|
-
workflow: WorkflowDefinition
|
|
1167
|
-
): Promise<void> {
|
|
1168
|
-
await this.publishEvent<WorkflowStartedPayload>(
|
|
1169
|
-
WorkflowEvents.WorkflowStarted,
|
|
1170
|
-
{
|
|
1171
|
-
executionId: execution.executionId,
|
|
1172
|
-
workflowId: execution.workflowId,
|
|
1173
|
-
workflowName: execution.workflowName,
|
|
1174
|
-
stepCount: workflow.steps.length,
|
|
1175
|
-
},
|
|
1176
|
-
execution.context.metadata.correlationId
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
private async publishWorkflowCompleted(
|
|
1181
|
-
execution: WorkflowExecutionStatus
|
|
1182
|
-
): Promise<void> {
|
|
1183
|
-
await this.publishEvent<WorkflowCompletedPayload>(
|
|
1184
|
-
WorkflowEvents.WorkflowCompleted,
|
|
1185
|
-
{
|
|
1186
|
-
executionId: execution.executionId,
|
|
1187
|
-
workflowId: execution.workflowId,
|
|
1188
|
-
workflowName: execution.workflowName,
|
|
1189
|
-
duration: execution.duration || 0,
|
|
1190
|
-
completedSteps: execution.completedSteps.length,
|
|
1191
|
-
skippedSteps: execution.skippedSteps.length,
|
|
1192
|
-
},
|
|
1193
|
-
execution.context.metadata.correlationId
|
|
1194
|
-
);
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
private async publishWorkflowFailed(
|
|
1198
|
-
execution: WorkflowExecutionStatus,
|
|
1199
|
-
failedStep: string,
|
|
1200
|
-
error: string
|
|
1201
|
-
): Promise<void> {
|
|
1202
|
-
await this.publishEvent<WorkflowFailedPayload>(
|
|
1203
|
-
WorkflowEvents.WorkflowFailed,
|
|
1204
|
-
{
|
|
1205
|
-
executionId: execution.executionId,
|
|
1206
|
-
workflowId: execution.workflowId,
|
|
1207
|
-
workflowName: execution.workflowName,
|
|
1208
|
-
failedStep,
|
|
1209
|
-
error,
|
|
1210
|
-
},
|
|
1211
|
-
execution.context.metadata.correlationId
|
|
1212
|
-
);
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
private async publishStepStarted(
|
|
1216
|
-
execution: WorkflowExecutionStatus,
|
|
1217
|
-
step: WorkflowStepDefinition
|
|
1218
|
-
): Promise<void> {
|
|
1219
|
-
await this.publishEvent<StepEventPayload>(
|
|
1220
|
-
WorkflowEvents.StepStarted,
|
|
1221
|
-
{
|
|
1222
|
-
executionId: execution.executionId,
|
|
1223
|
-
workflowId: execution.workflowId,
|
|
1224
|
-
stepId: step.id,
|
|
1225
|
-
stepName: step.name,
|
|
1226
|
-
domain: step.domain,
|
|
1227
|
-
},
|
|
1228
|
-
execution.context.metadata.correlationId
|
|
1229
|
-
);
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
private async publishStepCompleted(
|
|
1233
|
-
execution: WorkflowExecutionStatus,
|
|
1234
|
-
step: WorkflowStepDefinition,
|
|
1235
|
-
result: StepExecutionResult
|
|
1236
|
-
): Promise<void> {
|
|
1237
|
-
await this.publishEvent(
|
|
1238
|
-
WorkflowEvents.StepCompleted,
|
|
1239
|
-
{
|
|
1240
|
-
executionId: execution.executionId,
|
|
1241
|
-
workflowId: execution.workflowId,
|
|
1242
|
-
stepId: step.id,
|
|
1243
|
-
stepName: step.name,
|
|
1244
|
-
domain: step.domain,
|
|
1245
|
-
duration: result.duration,
|
|
1246
|
-
},
|
|
1247
|
-
execution.context.metadata.correlationId
|
|
1248
|
-
);
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
private async publishStepFailed(
|
|
1252
|
-
execution: WorkflowExecutionStatus,
|
|
1253
|
-
step: WorkflowStepDefinition,
|
|
1254
|
-
error: string
|
|
1255
|
-
): Promise<void> {
|
|
1256
|
-
await this.publishEvent(
|
|
1257
|
-
WorkflowEvents.StepFailed,
|
|
1258
|
-
{
|
|
1259
|
-
executionId: execution.executionId,
|
|
1260
|
-
workflowId: execution.workflowId,
|
|
1261
|
-
stepId: step.id,
|
|
1262
|
-
stepName: step.name,
|
|
1263
|
-
domain: step.domain,
|
|
1264
|
-
error,
|
|
1265
|
-
},
|
|
1266
|
-
execution.context.metadata.correlationId
|
|
1267
|
-
);
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
private async publishStepSkipped(
|
|
1271
|
-
execution: WorkflowExecutionStatus,
|
|
1272
|
-
step: WorkflowStepDefinition
|
|
1273
|
-
): Promise<void> {
|
|
1274
|
-
await this.publishEvent<StepEventPayload>(
|
|
1275
|
-
WorkflowEvents.StepSkipped,
|
|
1276
|
-
{
|
|
1277
|
-
executionId: execution.executionId,
|
|
1278
|
-
workflowId: execution.workflowId,
|
|
1279
|
-
stepId: step.id,
|
|
1280
|
-
stepName: step.name,
|
|
1281
|
-
domain: step.domain,
|
|
1282
|
-
},
|
|
1283
|
-
execution.context.metadata.correlationId
|
|
1284
|
-
);
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
// ============================================================================
|
|
1288
|
-
// Private Methods - Workflow Validation
|
|
1289
|
-
// ============================================================================
|
|
1290
|
-
|
|
1291
|
-
private validateWorkflowDefinition(
|
|
1292
|
-
definition: WorkflowDefinition
|
|
1293
|
-
): Result<void, Error> {
|
|
1294
|
-
if (!definition.id) {
|
|
1295
|
-
return err(new Error('Workflow ID is required'));
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
if (!definition.name) {
|
|
1299
|
-
return err(new Error('Workflow name is required'));
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
if (!definition.steps || definition.steps.length === 0) {
|
|
1303
|
-
return err(new Error('Workflow must have at least one step'));
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
// Validate steps
|
|
1307
|
-
const stepIds = new Set<string>();
|
|
1308
|
-
for (const step of definition.steps) {
|
|
1309
|
-
if (!step.id) {
|
|
1310
|
-
return err(new Error('Step ID is required'));
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
if (stepIds.has(step.id)) {
|
|
1314
|
-
return err(new Error(`Duplicate step ID: ${step.id}`));
|
|
1315
|
-
}
|
|
1316
|
-
stepIds.add(step.id);
|
|
1317
|
-
|
|
1318
|
-
if (!step.domain) {
|
|
1319
|
-
return err(new Error(`Step ${step.id} must have a domain`));
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
if (!ALL_DOMAINS.includes(step.domain)) {
|
|
1323
|
-
return err(new Error(`Invalid domain for step ${step.id}: ${step.domain}`));
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
if (!step.action) {
|
|
1327
|
-
return err(new Error(`Step ${step.id} must have an action`));
|
|
1328
|
-
}
|
|
1329
|
-
|
|
1330
|
-
// Validate dependencies
|
|
1331
|
-
if (step.dependsOn) {
|
|
1332
|
-
for (const dep of step.dependsOn) {
|
|
1333
|
-
if (!definition.steps.some((s) => s.id === dep)) {
|
|
1334
|
-
return err(
|
|
1335
|
-
new Error(`Step ${step.id} depends on unknown step: ${dep}`)
|
|
1336
|
-
);
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
|
|
1342
|
-
// Check for circular dependencies
|
|
1343
|
-
const circularCheck = this.detectCircularDependencies(definition.steps);
|
|
1344
|
-
if (circularCheck) {
|
|
1345
|
-
return err(new Error(`Circular dependency detected: ${circularCheck}`));
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
return ok(undefined);
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
private detectCircularDependencies(
|
|
1352
|
-
steps: WorkflowStepDefinition[]
|
|
1353
|
-
): string | null {
|
|
1354
|
-
const visited = new Set<string>();
|
|
1355
|
-
const recursionStack = new Set<string>();
|
|
1356
|
-
|
|
1357
|
-
const visit = (stepId: string, path: string[]): string | null => {
|
|
1358
|
-
if (recursionStack.has(stepId)) {
|
|
1359
|
-
return [...path, stepId].join(' -> ');
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
if (visited.has(stepId)) {
|
|
1363
|
-
return null;
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
visited.add(stepId);
|
|
1367
|
-
recursionStack.add(stepId);
|
|
1368
|
-
|
|
1369
|
-
const step = steps.find((s) => s.id === stepId);
|
|
1370
|
-
if (step?.dependsOn) {
|
|
1371
|
-
for (const dep of step.dependsOn) {
|
|
1372
|
-
const result = visit(dep, [...path, stepId]);
|
|
1373
|
-
if (result) return result;
|
|
1374
|
-
}
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
recursionStack.delete(stepId);
|
|
1378
|
-
return null;
|
|
1379
|
-
};
|
|
1380
|
-
|
|
1381
|
-
for (const step of steps) {
|
|
1382
|
-
const result = visit(step.id, []);
|
|
1383
|
-
if (result) return result;
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
return null;
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
// ============================================================================
|
|
1390
|
-
// Private Methods - Event Triggers
|
|
1391
|
-
// ============================================================================
|
|
1392
|
-
|
|
1393
|
-
private setupEventTriggers(): void {
|
|
1394
|
-
// Subscribe to all domain events for trigger matching
|
|
1395
|
-
const subscription = this.eventBus.subscribe('*', async (event: DomainEvent) => {
|
|
1396
|
-
await this.handleEventForTriggers(event);
|
|
1397
|
-
});
|
|
1398
|
-
|
|
1399
|
-
this.eventSubscriptions.push(subscription);
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
private registerWorkflowTriggers(_workflow: WorkflowDefinition): void {
|
|
1403
|
-
// Triggers are evaluated when events arrive via the * subscription
|
|
1404
|
-
// No additional subscription needed, just store the workflow with triggers
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
private async handleEventForTriggers(event: DomainEvent): Promise<void> {
|
|
1408
|
-
for (const workflow of this.workflows.values()) {
|
|
1409
|
-
if (!workflow.triggers) continue;
|
|
1410
|
-
|
|
1411
|
-
for (const trigger of workflow.triggers) {
|
|
1412
|
-
// Match event type
|
|
1413
|
-
if (trigger.eventType !== event.type) continue;
|
|
1414
|
-
|
|
1415
|
-
// Match source domain
|
|
1416
|
-
if (trigger.sourceDomain && trigger.sourceDomain !== event.source) continue;
|
|
1417
|
-
|
|
1418
|
-
// Evaluate condition if present
|
|
1419
|
-
if (trigger.condition) {
|
|
1420
|
-
const context: WorkflowContext = {
|
|
1421
|
-
input: { event: event.payload },
|
|
1422
|
-
results: {},
|
|
1423
|
-
metadata: {
|
|
1424
|
-
executionId: '',
|
|
1425
|
-
workflowId: workflow.id,
|
|
1426
|
-
startedAt: new Date(),
|
|
1427
|
-
},
|
|
1428
|
-
};
|
|
1429
|
-
|
|
1430
|
-
if (!this.evaluateCondition(trigger.condition, context)) {
|
|
1431
|
-
continue;
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
|
|
1435
|
-
// Build input from trigger mapping
|
|
1436
|
-
const input: Record<string, unknown> = {};
|
|
1437
|
-
if (trigger.inputMapping) {
|
|
1438
|
-
for (const [targetKey, sourcePath] of Object.entries(trigger.inputMapping)) {
|
|
1439
|
-
const value = this.getValueByPath({ event: event.payload }, sourcePath);
|
|
1440
|
-
if (value !== undefined) {
|
|
1441
|
-
input[targetKey] = value;
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
} else {
|
|
1445
|
-
// Default: pass entire payload as input
|
|
1446
|
-
input.triggerEvent = event.payload;
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
// Execute workflow
|
|
1450
|
-
await this.executeWorkflow(workflow.id, input, event.correlationId);
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
|
|
1455
|
-
// ============================================================================
|
|
1456
|
-
// Private Methods - Built-in Workflows
|
|
1457
|
-
// ============================================================================
|
|
1458
|
-
|
|
1459
|
-
private registerBuiltInWorkflows(): void {
|
|
1460
|
-
// 1. Comprehensive Testing Workflow
|
|
1461
|
-
this.registerWorkflow({
|
|
1462
|
-
id: 'comprehensive-testing',
|
|
1463
|
-
name: 'Comprehensive Testing Workflow',
|
|
1464
|
-
description:
|
|
1465
|
-
'test-generation -> test-execution -> coverage-analysis -> quality-assessment',
|
|
1466
|
-
version: '1.0.0',
|
|
1467
|
-
tags: ['testing', 'quality'],
|
|
1468
|
-
steps: [
|
|
1469
|
-
{
|
|
1470
|
-
id: 'generate-tests',
|
|
1471
|
-
name: 'Generate Tests',
|
|
1472
|
-
domain: 'test-generation',
|
|
1473
|
-
action: 'generateTests',
|
|
1474
|
-
inputMapping: {
|
|
1475
|
-
sourceFiles: 'input.sourceFiles',
|
|
1476
|
-
framework: 'input.framework',
|
|
1477
|
-
},
|
|
1478
|
-
outputMapping: {
|
|
1479
|
-
testFiles: 'generatedTests.files',
|
|
1480
|
-
testCount: 'generatedTests.count',
|
|
1481
|
-
},
|
|
1482
|
-
timeout: 120000,
|
|
1483
|
-
retry: { maxAttempts: 2, backoffMs: 1000 },
|
|
1484
|
-
},
|
|
1485
|
-
{
|
|
1486
|
-
id: 'execute-tests',
|
|
1487
|
-
name: 'Execute Tests',
|
|
1488
|
-
domain: 'test-execution',
|
|
1489
|
-
action: 'execute',
|
|
1490
|
-
dependsOn: ['generate-tests'],
|
|
1491
|
-
inputMapping: {
|
|
1492
|
-
testFiles: 'results.generatedTests.files',
|
|
1493
|
-
},
|
|
1494
|
-
outputMapping: {
|
|
1495
|
-
runId: 'execution.runId',
|
|
1496
|
-
passed: 'execution.passed',
|
|
1497
|
-
failed: 'execution.failed',
|
|
1498
|
-
},
|
|
1499
|
-
timeout: 300000,
|
|
1500
|
-
},
|
|
1501
|
-
{
|
|
1502
|
-
id: 'analyze-coverage',
|
|
1503
|
-
name: 'Analyze Coverage',
|
|
1504
|
-
domain: 'coverage-analysis',
|
|
1505
|
-
action: 'analyze',
|
|
1506
|
-
dependsOn: ['execute-tests'],
|
|
1507
|
-
inputMapping: {
|
|
1508
|
-
runId: 'results.execution.runId',
|
|
1509
|
-
},
|
|
1510
|
-
outputMapping: {
|
|
1511
|
-
line: 'coverage.line',
|
|
1512
|
-
branch: 'coverage.branch',
|
|
1513
|
-
overall: 'coverage.overall',
|
|
1514
|
-
},
|
|
1515
|
-
},
|
|
1516
|
-
{
|
|
1517
|
-
id: 'assess-quality',
|
|
1518
|
-
name: 'Assess Quality',
|
|
1519
|
-
domain: 'quality-assessment',
|
|
1520
|
-
action: 'evaluateGate',
|
|
1521
|
-
dependsOn: ['analyze-coverage'],
|
|
1522
|
-
inputMapping: {
|
|
1523
|
-
coverage: 'results.coverage',
|
|
1524
|
-
testResults: 'results.execution',
|
|
1525
|
-
},
|
|
1526
|
-
outputMapping: {
|
|
1527
|
-
passed: 'quality.gatePassed',
|
|
1528
|
-
score: 'quality.score',
|
|
1529
|
-
},
|
|
1530
|
-
},
|
|
1531
|
-
{
|
|
1532
|
-
id: 'generate-more-tests',
|
|
1533
|
-
name: 'Generate Additional Tests',
|
|
1534
|
-
domain: 'test-generation',
|
|
1535
|
-
action: 'generateTests',
|
|
1536
|
-
dependsOn: ['analyze-coverage'],
|
|
1537
|
-
condition: {
|
|
1538
|
-
path: 'results.coverage.overall',
|
|
1539
|
-
operator: 'lt',
|
|
1540
|
-
value: 80,
|
|
1541
|
-
},
|
|
1542
|
-
inputMapping: {
|
|
1543
|
-
sourceFiles: 'input.sourceFiles',
|
|
1544
|
-
targetCoverage: 'input.targetCoverage',
|
|
1545
|
-
},
|
|
1546
|
-
continueOnFailure: true,
|
|
1547
|
-
},
|
|
1548
|
-
],
|
|
1549
|
-
});
|
|
1550
|
-
|
|
1551
|
-
// 2. Defect Prevention Workflow
|
|
1552
|
-
this.registerWorkflow({
|
|
1553
|
-
id: 'defect-prevention',
|
|
1554
|
-
name: 'Defect Prevention Workflow',
|
|
1555
|
-
description:
|
|
1556
|
-
'code-intelligence (impact) -> defect-intelligence (predict) -> test-generation (for risky areas)',
|
|
1557
|
-
version: '1.0.0',
|
|
1558
|
-
tags: ['defect', 'prevention', 'ai'],
|
|
1559
|
-
steps: [
|
|
1560
|
-
{
|
|
1561
|
-
id: 'analyze-impact',
|
|
1562
|
-
name: 'Analyze Code Impact',
|
|
1563
|
-
domain: 'code-intelligence',
|
|
1564
|
-
action: 'analyzeImpact',
|
|
1565
|
-
inputMapping: {
|
|
1566
|
-
changedFiles: 'input.changedFiles',
|
|
1567
|
-
},
|
|
1568
|
-
outputMapping: {
|
|
1569
|
-
impactedFiles: 'impact.files',
|
|
1570
|
-
impactedTests: 'impact.tests',
|
|
1571
|
-
riskLevel: 'impact.riskLevel',
|
|
1572
|
-
},
|
|
1573
|
-
timeout: 60000,
|
|
1574
|
-
},
|
|
1575
|
-
{
|
|
1576
|
-
id: 'predict-defects',
|
|
1577
|
-
name: 'Predict Defects',
|
|
1578
|
-
domain: 'defect-intelligence',
|
|
1579
|
-
action: 'predictDefects',
|
|
1580
|
-
dependsOn: ['analyze-impact'],
|
|
1581
|
-
inputMapping: {
|
|
1582
|
-
files: 'results.impact.files',
|
|
1583
|
-
},
|
|
1584
|
-
outputMapping: {
|
|
1585
|
-
predictions: 'defects.predictions',
|
|
1586
|
-
highRiskFiles: 'defects.highRiskFiles',
|
|
1587
|
-
},
|
|
1588
|
-
},
|
|
1589
|
-
{
|
|
1590
|
-
id: 'generate-targeted-tests',
|
|
1591
|
-
name: 'Generate Targeted Tests',
|
|
1592
|
-
domain: 'test-generation',
|
|
1593
|
-
action: 'generateTests',
|
|
1594
|
-
dependsOn: ['predict-defects'],
|
|
1595
|
-
condition: {
|
|
1596
|
-
path: 'results.defects.highRiskFiles',
|
|
1597
|
-
operator: 'exists',
|
|
1598
|
-
value: true,
|
|
1599
|
-
},
|
|
1600
|
-
inputMapping: {
|
|
1601
|
-
sourceFiles: 'results.defects.highRiskFiles',
|
|
1602
|
-
priority: 'input.priority',
|
|
1603
|
-
},
|
|
1604
|
-
},
|
|
1605
|
-
],
|
|
1606
|
-
triggers: [
|
|
1607
|
-
{
|
|
1608
|
-
eventType: 'code-intelligence.ImpactAnalysisCompleted',
|
|
1609
|
-
inputMapping: {
|
|
1610
|
-
changedFiles: 'event.changedFiles',
|
|
1611
|
-
},
|
|
1612
|
-
},
|
|
1613
|
-
],
|
|
1614
|
-
});
|
|
1615
|
-
|
|
1616
|
-
// 3. Pre-Release Workflow
|
|
1617
|
-
this.registerWorkflow({
|
|
1618
|
-
id: 'pre-release',
|
|
1619
|
-
name: 'Pre-Release Workflow',
|
|
1620
|
-
description: 'security-audit -> quality-gate -> deployment-advisor',
|
|
1621
|
-
version: '1.0.0',
|
|
1622
|
-
tags: ['release', 'security', 'deployment'],
|
|
1623
|
-
steps: [
|
|
1624
|
-
{
|
|
1625
|
-
id: 'security-audit',
|
|
1626
|
-
name: 'Security Audit',
|
|
1627
|
-
domain: 'security-compliance',
|
|
1628
|
-
action: 'runAudit',
|
|
1629
|
-
inputMapping: {
|
|
1630
|
-
targetFiles: 'input.targetFiles',
|
|
1631
|
-
includeDependencies: 'input.includeDependencies',
|
|
1632
|
-
},
|
|
1633
|
-
outputMapping: {
|
|
1634
|
-
vulnerabilities: 'security.vulnerabilities',
|
|
1635
|
-
riskScore: 'security.riskScore',
|
|
1636
|
-
passed: 'security.passed',
|
|
1637
|
-
},
|
|
1638
|
-
timeout: 180000,
|
|
1639
|
-
},
|
|
1640
|
-
{
|
|
1641
|
-
id: 'quality-gate',
|
|
1642
|
-
name: 'Quality Gate Evaluation',
|
|
1643
|
-
domain: 'quality-assessment',
|
|
1644
|
-
action: 'evaluateGate',
|
|
1645
|
-
dependsOn: ['security-audit'],
|
|
1646
|
-
inputMapping: {
|
|
1647
|
-
securityResults: 'results.security',
|
|
1648
|
-
releaseCandidate: 'input.releaseCandidate',
|
|
1649
|
-
},
|
|
1650
|
-
outputMapping: {
|
|
1651
|
-
passed: 'quality.gatePassed',
|
|
1652
|
-
checks: 'quality.checks',
|
|
1653
|
-
},
|
|
1654
|
-
},
|
|
1655
|
-
{
|
|
1656
|
-
id: 'deployment-advice',
|
|
1657
|
-
name: 'Get Deployment Advice',
|
|
1658
|
-
domain: 'quality-assessment',
|
|
1659
|
-
action: 'getDeploymentAdvice',
|
|
1660
|
-
dependsOn: ['quality-gate'],
|
|
1661
|
-
inputMapping: {
|
|
1662
|
-
releaseCandidate: 'input.releaseCandidate',
|
|
1663
|
-
qualityResults: 'results.quality',
|
|
1664
|
-
securityResults: 'results.security',
|
|
1665
|
-
},
|
|
1666
|
-
outputMapping: {
|
|
1667
|
-
decision: 'deployment.decision',
|
|
1668
|
-
recommendations: 'deployment.recommendations',
|
|
1669
|
-
riskScore: 'deployment.riskScore',
|
|
1670
|
-
},
|
|
1671
|
-
},
|
|
1672
|
-
],
|
|
1673
|
-
triggers: [
|
|
1674
|
-
{
|
|
1675
|
-
eventType: 'quality-assessment.QualityGateEvaluated',
|
|
1676
|
-
condition: {
|
|
1677
|
-
path: 'event.passed',
|
|
1678
|
-
operator: 'eq',
|
|
1679
|
-
value: true,
|
|
1680
|
-
},
|
|
1681
|
-
},
|
|
1682
|
-
],
|
|
1683
|
-
});
|
|
1684
|
-
|
|
1685
|
-
// 4. Continuous Learning Workflow
|
|
1686
|
-
this.registerWorkflow({
|
|
1687
|
-
id: 'continuous-learning',
|
|
1688
|
-
name: 'Continuous Learning Workflow',
|
|
1689
|
-
description: 'Collect patterns -> consolidate -> transfer -> optimize',
|
|
1690
|
-
version: '1.0.0',
|
|
1691
|
-
tags: ['learning', 'optimization', 'ai'],
|
|
1692
|
-
steps: [
|
|
1693
|
-
{
|
|
1694
|
-
id: 'collect-patterns',
|
|
1695
|
-
name: 'Collect Patterns',
|
|
1696
|
-
domain: 'learning-optimization',
|
|
1697
|
-
action: 'runLearningCycle',
|
|
1698
|
-
inputMapping: {
|
|
1699
|
-
domain: 'input.targetDomain',
|
|
1700
|
-
},
|
|
1701
|
-
outputMapping: {
|
|
1702
|
-
patternsLearned: 'learning.patterns',
|
|
1703
|
-
experiencesProcessed: 'learning.experiences',
|
|
1704
|
-
},
|
|
1705
|
-
},
|
|
1706
|
-
{
|
|
1707
|
-
id: 'consolidate-patterns',
|
|
1708
|
-
name: 'Consolidate Patterns',
|
|
1709
|
-
domain: 'learning-optimization',
|
|
1710
|
-
action: 'shareCrossDomainLearnings',
|
|
1711
|
-
dependsOn: ['collect-patterns'],
|
|
1712
|
-
condition: {
|
|
1713
|
-
path: 'results.learning.patterns',
|
|
1714
|
-
operator: 'gt',
|
|
1715
|
-
value: 0,
|
|
1716
|
-
},
|
|
1717
|
-
outputMapping: {
|
|
1718
|
-
knowledgeShared: 'consolidation.shared',
|
|
1719
|
-
domainsUpdated: 'consolidation.domains',
|
|
1720
|
-
},
|
|
1721
|
-
},
|
|
1722
|
-
{
|
|
1723
|
-
id: 'transfer-knowledge',
|
|
1724
|
-
name: 'Transfer Knowledge',
|
|
1725
|
-
domain: 'learning-optimization',
|
|
1726
|
-
action: 'shareCrossDomainLearnings',
|
|
1727
|
-
dependsOn: ['consolidate-patterns'],
|
|
1728
|
-
outputMapping: {
|
|
1729
|
-
transferSuccessRate: 'transfer.successRate',
|
|
1730
|
-
newPatternsCreated: 'transfer.newPatterns',
|
|
1731
|
-
},
|
|
1732
|
-
},
|
|
1733
|
-
{
|
|
1734
|
-
id: 'optimize-strategies',
|
|
1735
|
-
name: 'Optimize Strategies',
|
|
1736
|
-
domain: 'learning-optimization',
|
|
1737
|
-
action: 'optimizeAllStrategies',
|
|
1738
|
-
dependsOn: ['transfer-knowledge'],
|
|
1739
|
-
outputMapping: {
|
|
1740
|
-
domainsOptimized: 'optimization.domains',
|
|
1741
|
-
avgImprovement: 'optimization.improvement',
|
|
1742
|
-
},
|
|
1743
|
-
},
|
|
1744
|
-
],
|
|
1745
|
-
});
|
|
1746
|
-
|
|
1747
|
-
// 5. Morning Sync Protocol Workflow
|
|
1748
|
-
this.registerWorkflow({
|
|
1749
|
-
id: 'morning-sync',
|
|
1750
|
-
name: 'Morning Sync Protocol',
|
|
1751
|
-
description: 'Daily quality synchronization across all domains',
|
|
1752
|
-
version: '1.0.0',
|
|
1753
|
-
tags: ['protocol', 'daily', 'sync'],
|
|
1754
|
-
steps: [
|
|
1755
|
-
{
|
|
1756
|
-
id: 'collect-metrics',
|
|
1757
|
-
name: 'Collect Quality Metrics',
|
|
1758
|
-
domain: 'quality-assessment',
|
|
1759
|
-
action: 'analyzeQuality',
|
|
1760
|
-
inputMapping: {
|
|
1761
|
-
sourceFiles: 'input.sourceFiles',
|
|
1762
|
-
},
|
|
1763
|
-
outputMapping: {
|
|
1764
|
-
score: 'metrics.qualityScore',
|
|
1765
|
-
},
|
|
1766
|
-
},
|
|
1767
|
-
{
|
|
1768
|
-
id: 'analyze-trends',
|
|
1769
|
-
name: 'Analyze Coverage Trends',
|
|
1770
|
-
domain: 'coverage-analysis',
|
|
1771
|
-
action: 'getTrend',
|
|
1772
|
-
inputMapping: {
|
|
1773
|
-
timeRange: 'input.timeRange',
|
|
1774
|
-
granularity: 'input.granularity',
|
|
1775
|
-
},
|
|
1776
|
-
outputMapping: {
|
|
1777
|
-
trend: 'trends.coverage',
|
|
1778
|
-
forecast: 'trends.forecast',
|
|
1779
|
-
},
|
|
1780
|
-
},
|
|
1781
|
-
{
|
|
1782
|
-
id: 'check-security',
|
|
1783
|
-
name: 'Check Security Posture',
|
|
1784
|
-
domain: 'security-compliance',
|
|
1785
|
-
action: 'getSecurityPosture',
|
|
1786
|
-
outputMapping: {
|
|
1787
|
-
overallScore: 'security.score',
|
|
1788
|
-
criticalIssues: 'security.critical',
|
|
1789
|
-
recommendations: 'security.recommendations',
|
|
1790
|
-
},
|
|
1791
|
-
},
|
|
1792
|
-
{
|
|
1793
|
-
id: 'get-defect-predictions',
|
|
1794
|
-
name: 'Get Defect Predictions',
|
|
1795
|
-
domain: 'defect-intelligence',
|
|
1796
|
-
action: 'predictDefects',
|
|
1797
|
-
inputMapping: {
|
|
1798
|
-
files: 'input.changedFiles',
|
|
1799
|
-
},
|
|
1800
|
-
outputMapping: {
|
|
1801
|
-
predictions: 'defects.predictions',
|
|
1802
|
-
},
|
|
1803
|
-
},
|
|
1804
|
-
{
|
|
1805
|
-
id: 'generate-learning-report',
|
|
1806
|
-
name: 'Generate Learning Dashboard',
|
|
1807
|
-
domain: 'learning-optimization',
|
|
1808
|
-
action: 'getLearningDashboard',
|
|
1809
|
-
dependsOn: ['collect-metrics', 'analyze-trends', 'check-security', 'get-defect-predictions'],
|
|
1810
|
-
outputMapping: {
|
|
1811
|
-
learningRate: 'learning.rate',
|
|
1812
|
-
topDomains: 'learning.topDomains',
|
|
1813
|
-
},
|
|
1814
|
-
},
|
|
1815
|
-
],
|
|
1816
|
-
});
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
// ============================================================================
|
|
1820
|
-
// Private Methods - Persistence
|
|
1821
|
-
// ============================================================================
|
|
1822
|
-
|
|
1823
|
-
private async loadPersistedWorkflows(): Promise<void> {
|
|
1824
|
-
try {
|
|
1825
|
-
const keys = await this.memory.search('workflow:definition:*', 100);
|
|
1826
|
-
|
|
1827
|
-
for (const key of keys) {
|
|
1828
|
-
const definition = await this.memory.get<WorkflowDefinition>(key);
|
|
1829
|
-
if (definition && !this.workflows.has(definition.id)) {
|
|
1830
|
-
this.workflows.set(definition.id, definition);
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
} catch (error) {
|
|
1834
|
-
console.error('Failed to load persisted workflows:', error);
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
private async persistWorkflows(): Promise<void> {
|
|
1839
|
-
try {
|
|
1840
|
-
for (const workflow of this.workflows.values()) {
|
|
1841
|
-
// Don't persist built-in workflows
|
|
1842
|
-
if (
|
|
1843
|
-
[
|
|
1844
|
-
'comprehensive-testing',
|
|
1845
|
-
'defect-prevention',
|
|
1846
|
-
'pre-release',
|
|
1847
|
-
'continuous-learning',
|
|
1848
|
-
'morning-sync',
|
|
1849
|
-
].includes(workflow.id)
|
|
1850
|
-
) {
|
|
1851
|
-
continue;
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
await this.memory.set(
|
|
1855
|
-
`workflow:definition:${workflow.id}`,
|
|
1856
|
-
workflow,
|
|
1857
|
-
{ namespace: 'coordination', persist: true }
|
|
1858
|
-
);
|
|
1859
|
-
}
|
|
1860
|
-
} catch (error) {
|
|
1861
|
-
console.error('Failed to persist workflows:', error);
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
|
|
1865
|
-
private async persistExecution(execution: WorkflowExecutionStatus): Promise<void> {
|
|
1866
|
-
try {
|
|
1867
|
-
// Convert Map to object for serialization
|
|
1868
|
-
const serializable = {
|
|
1869
|
-
...execution,
|
|
1870
|
-
stepResults: Object.fromEntries(execution.stepResults),
|
|
1871
|
-
};
|
|
1872
|
-
|
|
1873
|
-
await this.memory.set(
|
|
1874
|
-
`workflow:execution:${execution.executionId}`,
|
|
1875
|
-
serializable,
|
|
1876
|
-
{ namespace: 'coordination', ttl: 86400 * 7 } // 7 days
|
|
1877
|
-
);
|
|
1878
|
-
} catch (error) {
|
|
1879
|
-
console.error('Failed to persist execution:', error);
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
|
-
// ============================================================================
|
|
1884
|
-
// Private Methods - Utilities
|
|
1885
|
-
// ============================================================================
|
|
1886
|
-
|
|
1887
|
-
private delay(ms: number): Promise<void> {
|
|
1888
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
|
-
/**
|
|
1892
|
-
* Register a domain action handler
|
|
1893
|
-
*/
|
|
1894
|
-
registerAction(
|
|
1895
|
-
domain: DomainName,
|
|
1896
|
-
action: string,
|
|
1897
|
-
handler: DomainAction
|
|
1898
|
-
): void {
|
|
1899
|
-
if (!this.actionRegistry[domain]) {
|
|
1900
|
-
this.actionRegistry[domain] = {};
|
|
1901
|
-
}
|
|
1902
|
-
this.actionRegistry[domain][action] = handler;
|
|
1903
|
-
}
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
|
-
// ============================================================================
|
|
1907
|
-
// Factory Function
|
|
1908
|
-
// ============================================================================
|
|
1909
|
-
|
|
1910
|
-
export function createWorkflowOrchestrator(
|
|
1911
|
-
eventBus: EventBus,
|
|
1912
|
-
memory: MemoryBackend,
|
|
1913
|
-
agentCoordinator: AgentCoordinator,
|
|
1914
|
-
config?: Partial<WorkflowOrchestratorConfig>
|
|
1915
|
-
): IWorkflowOrchestrator {
|
|
1916
|
-
return new WorkflowOrchestrator(eventBus, memory, agentCoordinator, config);
|
|
1917
|
-
}
|