agentic-qe 3.2.3 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/v3/qe-accessibility-auditor.md +90 -0
- package/README.md +49 -7
- package/package.json +8 -2
- package/scripts/cloud-db-config.json +37 -0
- package/scripts/cloud-db-connect.sh +37 -0
- package/scripts/cloud-db-tunnel.sh +23 -0
- package/v3/CHANGELOG.md +253 -0
- package/v3/README.md +59 -1
- package/v3/assets/agents/v3/qe-accessibility-auditor.md +90 -0
- package/v3/dist/adapters/claude-flow/index.d.ts +54 -0
- package/v3/dist/adapters/claude-flow/index.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/index.js +79 -0
- package/v3/dist/adapters/claude-flow/index.js.map +1 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts +70 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.js +203 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts +73 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js +276 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts +70 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js +205 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/types.d.ts +99 -0
- package/v3/dist/adapters/claude-flow/types.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/types.js +6 -0
- package/v3/dist/adapters/claude-flow/types.js.map +1 -0
- package/v3/dist/causal-discovery/causal-graph.d.ts +80 -1
- package/v3/dist/causal-discovery/causal-graph.d.ts.map +1 -1
- package/v3/dist/causal-discovery/causal-graph.js +111 -1
- package/v3/dist/causal-discovery/causal-graph.js.map +1 -1
- package/v3/dist/cli/bundle.js +25321 -15378
- package/v3/dist/cli/command-registry.d.ts +55 -0
- package/v3/dist/cli/command-registry.d.ts.map +1 -0
- package/v3/dist/cli/command-registry.js +103 -0
- package/v3/dist/cli/command-registry.js.map +1 -0
- package/v3/dist/cli/commands/claude-flow-setup.d.ts +82 -0
- package/v3/dist/cli/commands/claude-flow-setup.d.ts.map +1 -0
- package/v3/dist/cli/commands/claude-flow-setup.js +334 -0
- package/v3/dist/cli/commands/claude-flow-setup.js.map +1 -0
- package/v3/dist/cli/commands/code.d.ts +9 -0
- package/v3/dist/cli/commands/code.d.ts.map +1 -0
- package/v3/dist/cli/commands/code.js +254 -0
- package/v3/dist/cli/commands/code.js.map +1 -0
- package/v3/dist/cli/commands/completions.d.ts +8 -0
- package/v3/dist/cli/commands/completions.d.ts.map +1 -0
- package/v3/dist/cli/commands/completions.js +99 -0
- package/v3/dist/cli/commands/completions.js.map +1 -0
- package/v3/dist/cli/commands/coverage.d.ts +9 -0
- package/v3/dist/cli/commands/coverage.d.ts.map +1 -0
- package/v3/dist/cli/commands/coverage.js +208 -0
- package/v3/dist/cli/commands/coverage.js.map +1 -0
- package/v3/dist/cli/commands/fleet.d.ts +11 -0
- package/v3/dist/cli/commands/fleet.d.ts.map +1 -0
- package/v3/dist/cli/commands/fleet.js +338 -0
- package/v3/dist/cli/commands/fleet.js.map +1 -0
- package/v3/dist/cli/commands/hooks.d.ts +2 -0
- package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
- package/v3/dist/cli/commands/hooks.js +13 -2
- package/v3/dist/cli/commands/hooks.js.map +1 -1
- package/v3/dist/cli/commands/init.d.ts +19 -0
- package/v3/dist/cli/commands/init.d.ts.map +1 -0
- package/v3/dist/cli/commands/init.js +345 -0
- package/v3/dist/cli/commands/init.js.map +1 -0
- package/v3/dist/cli/commands/migrate.d.ts +9 -0
- package/v3/dist/cli/commands/migrate.d.ts.map +1 -0
- package/v3/dist/cli/commands/migrate.js +566 -0
- package/v3/dist/cli/commands/migrate.js.map +1 -0
- package/v3/dist/cli/commands/quality.d.ts +9 -0
- package/v3/dist/cli/commands/quality.d.ts.map +1 -0
- package/v3/dist/cli/commands/quality.js +40 -0
- package/v3/dist/cli/commands/quality.js.map +1 -0
- package/v3/dist/cli/commands/security.d.ts +9 -0
- package/v3/dist/cli/commands/security.d.ts.map +1 -0
- package/v3/dist/cli/commands/security.js +124 -0
- package/v3/dist/cli/commands/security.js.map +1 -0
- package/v3/dist/cli/commands/sync.d.ts +19 -0
- package/v3/dist/cli/commands/sync.d.ts.map +1 -0
- package/v3/dist/cli/commands/sync.js +283 -0
- package/v3/dist/cli/commands/sync.js.map +1 -0
- package/v3/dist/cli/commands/test.d.ts +9 -0
- package/v3/dist/cli/commands/test.d.ts.map +1 -0
- package/v3/dist/cli/commands/test.js +166 -0
- package/v3/dist/cli/commands/test.js.map +1 -0
- package/v3/dist/cli/handlers/agent-handler.d.ts +20 -0
- package/v3/dist/cli/handlers/agent-handler.d.ts.map +1 -0
- package/v3/dist/cli/handlers/agent-handler.js +158 -0
- package/v3/dist/cli/handlers/agent-handler.js.map +1 -0
- package/v3/dist/cli/handlers/domain-handler.d.ts +20 -0
- package/v3/dist/cli/handlers/domain-handler.d.ts.map +1 -0
- package/v3/dist/cli/handlers/domain-handler.js +115 -0
- package/v3/dist/cli/handlers/domain-handler.js.map +1 -0
- package/v3/dist/cli/handlers/index.d.ts +13 -0
- package/v3/dist/cli/handlers/index.d.ts.map +1 -0
- package/v3/dist/cli/handlers/index.js +15 -0
- package/v3/dist/cli/handlers/index.js.map +1 -0
- package/v3/dist/cli/handlers/init-handler.d.ts +38 -0
- package/v3/dist/cli/handlers/init-handler.d.ts.map +1 -0
- package/v3/dist/cli/handlers/init-handler.js +288 -0
- package/v3/dist/cli/handlers/init-handler.js.map +1 -0
- package/v3/dist/cli/handlers/interfaces.d.ts +104 -0
- package/v3/dist/cli/handlers/interfaces.d.ts.map +1 -0
- package/v3/dist/cli/handlers/interfaces.js +109 -0
- package/v3/dist/cli/handlers/interfaces.js.map +1 -0
- package/v3/dist/cli/handlers/protocol-handler.d.ts +19 -0
- package/v3/dist/cli/handlers/protocol-handler.d.ts.map +1 -0
- package/v3/dist/cli/handlers/protocol-handler.js +79 -0
- package/v3/dist/cli/handlers/protocol-handler.js.map +1 -0
- package/v3/dist/cli/handlers/status-handler.d.ts +30 -0
- package/v3/dist/cli/handlers/status-handler.d.ts.map +1 -0
- package/v3/dist/cli/handlers/status-handler.js +218 -0
- package/v3/dist/cli/handlers/status-handler.js.map +1 -0
- package/v3/dist/cli/handlers/task-handler.d.ts +22 -0
- package/v3/dist/cli/handlers/task-handler.d.ts.map +1 -0
- package/v3/dist/cli/handlers/task-handler.js +271 -0
- package/v3/dist/cli/handlers/task-handler.js.map +1 -0
- package/v3/dist/cli/index.d.ts +4 -0
- package/v3/dist/cli/index.d.ts.map +1 -1
- package/v3/dist/cli/index.js +62 -2583
- package/v3/dist/cli/index.js.map +1 -1
- package/v3/dist/cli/wizards/core/index.d.ts +11 -0
- package/v3/dist/cli/wizards/core/index.d.ts.map +1 -0
- package/v3/dist/cli/wizards/core/index.js +15 -0
- package/v3/dist/cli/wizards/core/index.js.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-base.d.ts +87 -0
- package/v3/dist/cli/wizards/core/wizard-base.d.ts.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-base.js +120 -0
- package/v3/dist/cli/wizards/core/wizard-base.js.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-command.d.ts +182 -0
- package/v3/dist/cli/wizards/core/wizard-command.d.ts.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-command.js +45 -0
- package/v3/dist/cli/wizards/core/wizard-command.js.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-step.d.ts +109 -0
- package/v3/dist/cli/wizards/core/wizard-step.d.ts.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-step.js +384 -0
- package/v3/dist/cli/wizards/core/wizard-step.js.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-utils.d.ts +117 -0
- package/v3/dist/cli/wizards/core/wizard-utils.d.ts.map +1 -0
- package/v3/dist/cli/wizards/core/wizard-utils.js +291 -0
- package/v3/dist/cli/wizards/core/wizard-utils.js.map +1 -0
- package/v3/dist/cli/wizards/coverage-wizard.d.ts +13 -68
- package/v3/dist/cli/wizards/coverage-wizard.d.ts.map +1 -1
- package/v3/dist/cli/wizards/coverage-wizard.js +127 -391
- package/v3/dist/cli/wizards/coverage-wizard.js.map +1 -1
- package/v3/dist/cli/wizards/fleet-wizard.d.ts +13 -64
- package/v3/dist/cli/wizards/fleet-wizard.d.ts.map +1 -1
- package/v3/dist/cli/wizards/fleet-wizard.js +150 -363
- package/v3/dist/cli/wizards/fleet-wizard.js.map +1 -1
- package/v3/dist/cli/wizards/index.d.ts +2 -0
- package/v3/dist/cli/wizards/index.d.ts.map +1 -1
- package/v3/dist/cli/wizards/index.js +3 -0
- package/v3/dist/cli/wizards/index.js.map +1 -1
- package/v3/dist/cli/wizards/security-wizard.d.ts +13 -64
- package/v3/dist/cli/wizards/security-wizard.d.ts.map +1 -1
- package/v3/dist/cli/wizards/security-wizard.js +152 -395
- package/v3/dist/cli/wizards/security-wizard.js.map +1 -1
- package/v3/dist/cli/wizards/test-wizard.d.ts +13 -77
- package/v3/dist/cli/wizards/test-wizard.d.ts.map +1 -1
- package/v3/dist/cli/wizards/test-wizard.js +196 -328
- package/v3/dist/cli/wizards/test-wizard.js.map +1 -1
- package/v3/dist/coordination/mincut/interfaces.d.ts +8 -2
- package/v3/dist/coordination/mincut/interfaces.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/interfaces.js.map +1 -1
- package/v3/dist/coordination/mincut/mincut-health-monitor.d.ts +8 -0
- package/v3/dist/coordination/mincut/mincut-health-monitor.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/mincut-health-monitor.js +26 -4
- package/v3/dist/coordination/mincut/mincut-health-monitor.js.map +1 -1
- package/v3/dist/coordination/mincut/queen-integration.d.ts +7 -0
- package/v3/dist/coordination/mincut/queen-integration.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/queen-integration.js +19 -1
- package/v3/dist/coordination/mincut/queen-integration.js.map +1 -1
- package/v3/dist/coordination/queen-coordinator.d.ts +5 -0
- package/v3/dist/coordination/queen-coordinator.d.ts.map +1 -1
- package/v3/dist/coordination/queen-coordinator.js +45 -7
- package/v3/dist/coordination/queen-coordinator.js.map +1 -1
- package/v3/dist/coordination/task-executor.js +2 -2
- package/v3/dist/coordination/task-executor.js.map +1 -1
- package/v3/dist/domains/chaos-resilience/plugin.js +2 -2
- package/v3/dist/domains/chaos-resilience/plugin.js.map +1 -1
- package/v3/dist/domains/code-intelligence/plugin.js +2 -2
- package/v3/dist/domains/code-intelligence/plugin.js.map +1 -1
- package/v3/dist/domains/contract-testing/plugin.js +2 -2
- package/v3/dist/domains/contract-testing/plugin.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/plugin.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/plugin.js +2 -1
- package/v3/dist/domains/coverage-analysis/plugin.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/plugin.js +2 -2
- package/v3/dist/domains/defect-intelligence/plugin.js.map +1 -1
- package/v3/dist/domains/domain-interface.d.ts.map +1 -1
- package/v3/dist/domains/domain-interface.js +3 -1
- package/v3/dist/domains/domain-interface.js.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.d.ts +5 -0
- package/v3/dist/domains/learning-optimization/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.js +79 -0
- package/v3/dist/domains/learning-optimization/coordinator.js.map +1 -1
- package/v3/dist/domains/learning-optimization/plugin.js +2 -2
- package/v3/dist/domains/learning-optimization/plugin.js.map +1 -1
- package/v3/dist/domains/quality-assessment/plugin.js +2 -2
- package/v3/dist/domains/quality-assessment/plugin.js.map +1 -1
- package/v3/dist/domains/requirements-validation/plugin.js +2 -2
- package/v3/dist/domains/requirements-validation/plugin.js.map +1 -1
- package/v3/dist/domains/security-compliance/plugin.js +2 -2
- package/v3/dist/domains/security-compliance/plugin.js.map +1 -1
- package/v3/dist/domains/test-execution/index.d.ts +2 -1
- package/v3/dist/domains/test-execution/index.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/index.js +0 -2
- package/v3/dist/domains/test-execution/index.js.map +1 -1
- package/v3/dist/domains/test-execution/interfaces.d.ts +222 -25
- package/v3/dist/domains/test-execution/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/interfaces.js +130 -3
- package/v3/dist/domains/test-execution/interfaces.js.map +1 -1
- package/v3/dist/domains/test-execution/plugin.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/plugin.js +2 -1
- package/v3/dist/domains/test-execution/plugin.js.map +1 -1
- package/v3/dist/domains/test-execution/test-prioritization-types.d.ts +5 -172
- package/v3/dist/domains/test-execution/test-prioritization-types.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/test-prioritization-types.js +6 -129
- package/v3/dist/domains/test-execution/test-prioritization-types.js.map +1 -1
- package/v3/dist/domains/test-execution/types/index.d.ts +7 -3
- package/v3/dist/domains/test-execution/types/index.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/types/index.js +7 -17
- package/v3/dist/domains/test-execution/types/index.js.map +1 -1
- package/v3/dist/domains/test-generation/coordinator.d.ts +32 -1
- package/v3/dist/domains/test-generation/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/coordinator.js +72 -3
- package/v3/dist/domains/test-generation/coordinator.js.map +1 -1
- package/v3/dist/domains/test-generation/factories/index.d.ts +8 -0
- package/v3/dist/domains/test-generation/factories/index.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/factories/index.js +8 -0
- package/v3/dist/domains/test-generation/factories/index.js.map +1 -0
- package/v3/dist/domains/test-generation/factories/test-generator-factory.d.ts +108 -0
- package/v3/dist/domains/test-generation/factories/test-generator-factory.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/factories/test-generator-factory.js +158 -0
- package/v3/dist/domains/test-generation/factories/test-generator-factory.js.map +1 -0
- package/v3/dist/domains/test-generation/generators/base-test-generator.d.ts +79 -0
- package/v3/dist/domains/test-generation/generators/base-test-generator.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/generators/base-test-generator.js +252 -0
- package/v3/dist/domains/test-generation/generators/base-test-generator.js.map +1 -0
- package/v3/dist/domains/test-generation/generators/index.d.ts +11 -0
- package/v3/dist/domains/test-generation/generators/index.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/generators/index.js +13 -0
- package/v3/dist/domains/test-generation/generators/index.js.map +1 -0
- package/v3/dist/domains/test-generation/generators/jest-vitest-generator.d.ts +77 -0
- package/v3/dist/domains/test-generation/generators/jest-vitest-generator.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/generators/jest-vitest-generator.js +365 -0
- package/v3/dist/domains/test-generation/generators/jest-vitest-generator.js.map +1 -0
- package/v3/dist/domains/test-generation/generators/mocha-generator.d.ts +56 -0
- package/v3/dist/domains/test-generation/generators/mocha-generator.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/generators/mocha-generator.js +197 -0
- package/v3/dist/domains/test-generation/generators/mocha-generator.js.map +1 -0
- package/v3/dist/domains/test-generation/generators/pytest-generator.d.ts +66 -0
- package/v3/dist/domains/test-generation/generators/pytest-generator.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/generators/pytest-generator.js +240 -0
- package/v3/dist/domains/test-generation/generators/pytest-generator.js.map +1 -0
- package/v3/dist/domains/test-generation/index.d.ts +2 -1
- package/v3/dist/domains/test-generation/index.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/index.js +5 -1
- package/v3/dist/domains/test-generation/index.js.map +1 -1
- package/v3/dist/domains/test-generation/interfaces/index.d.ts +9 -0
- package/v3/dist/domains/test-generation/interfaces/index.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/interfaces/index.js +9 -0
- package/v3/dist/domains/test-generation/interfaces/index.js.map +1 -0
- package/v3/dist/domains/test-generation/interfaces/test-generator.interface.d.ts +166 -0
- package/v3/dist/domains/test-generation/interfaces/test-generator.interface.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/interfaces/test-generator.interface.js +8 -0
- package/v3/dist/domains/test-generation/interfaces/test-generator.interface.js.map +1 -0
- package/v3/dist/domains/test-generation/interfaces.d.ts +163 -24
- package/v3/dist/domains/test-generation/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/interfaces.js +2 -2
- package/v3/dist/domains/test-generation/plugin.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/plugin.js +6 -5
- package/v3/dist/domains/test-generation/plugin.js.map +1 -1
- package/v3/dist/domains/test-generation/services/coherence-gate-service.d.ts +245 -0
- package/v3/dist/domains/test-generation/services/coherence-gate-service.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/services/coherence-gate-service.js +454 -0
- package/v3/dist/domains/test-generation/services/coherence-gate-service.js.map +1 -0
- package/v3/dist/domains/test-generation/services/index.d.ts +8 -1
- package/v3/dist/domains/test-generation/services/index.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/services/index.js +10 -1
- package/v3/dist/domains/test-generation/services/index.js.map +1 -1
- package/v3/dist/domains/test-generation/services/property-test-generator.d.ts +34 -0
- package/v3/dist/domains/test-generation/services/property-test-generator.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/services/property-test-generator.js +306 -0
- package/v3/dist/domains/test-generation/services/property-test-generator.js.map +1 -0
- package/v3/dist/domains/test-generation/services/tdd-generator.d.ts +33 -0
- package/v3/dist/domains/test-generation/services/tdd-generator.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/services/tdd-generator.js +342 -0
- package/v3/dist/domains/test-generation/services/tdd-generator.js.map +1 -0
- package/v3/dist/domains/test-generation/services/test-data-generator.d.ts +34 -0
- package/v3/dist/domains/test-generation/services/test-data-generator.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/services/test-data-generator.js +245 -0
- package/v3/dist/domains/test-generation/services/test-data-generator.js.map +1 -0
- package/v3/dist/domains/test-generation/services/test-generator.d.ts +51 -160
- package/v3/dist/domains/test-generation/services/test-generator.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/services/test-generator.js +101 -1858
- package/v3/dist/domains/test-generation/services/test-generator.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/index.d.ts +2 -1
- package/v3/dist/domains/visual-accessibility/index.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/index.js +1 -0
- package/v3/dist/domains/visual-accessibility/index.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/interfaces.d.ts +131 -0
- package/v3/dist/domains/visual-accessibility/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.d.ts +26 -0
- package/v3/dist/domains/visual-accessibility/plugin.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.js +153 -2
- package/v3/dist/domains/visual-accessibility/plugin.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts +42 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js +69 -0
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.d.ts +138 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.d.ts.map +1 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.js +830 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.js.map +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.d.ts +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/index.js +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.js.map +1 -1
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts +84 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts.map +1 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.js +250 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.js.map +1 -0
- package/v3/dist/init/enhancements/detector.d.ts +10 -0
- package/v3/dist/init/enhancements/detector.d.ts.map +1 -0
- package/v3/dist/init/enhancements/detector.js +87 -0
- package/v3/dist/init/enhancements/detector.js.map +1 -0
- package/v3/dist/init/enhancements/index.d.ts +13 -0
- package/v3/dist/init/enhancements/index.d.ts.map +1 -0
- package/v3/dist/init/enhancements/index.js +25 -0
- package/v3/dist/init/enhancements/index.js.map +1 -0
- package/v3/dist/init/enhancements/types.d.ts +93 -0
- package/v3/dist/init/enhancements/types.d.ts.map +1 -0
- package/v3/dist/init/enhancements/types.js +6 -0
- package/v3/dist/init/enhancements/types.js.map +1 -0
- package/v3/dist/init/index.d.ts +8 -0
- package/v3/dist/init/index.d.ts.map +1 -1
- package/v3/dist/init/index.js +4 -0
- package/v3/dist/init/index.js.map +1 -1
- package/v3/dist/init/migration/config-migrator.d.ts +31 -0
- package/v3/dist/init/migration/config-migrator.d.ts.map +1 -0
- package/v3/dist/init/migration/config-migrator.js +133 -0
- package/v3/dist/init/migration/config-migrator.js.map +1 -0
- package/v3/dist/init/migration/data-migrator.d.ts +72 -0
- package/v3/dist/init/migration/data-migrator.d.ts.map +1 -0
- package/v3/dist/init/migration/data-migrator.js +233 -0
- package/v3/dist/init/migration/data-migrator.js.map +1 -0
- package/v3/dist/init/migration/detector.d.ts +44 -0
- package/v3/dist/init/migration/detector.d.ts.map +1 -0
- package/v3/dist/init/migration/detector.js +106 -0
- package/v3/dist/init/migration/detector.js.map +1 -0
- package/v3/dist/init/migration/index.d.ts +8 -0
- package/v3/dist/init/migration/index.d.ts.map +1 -0
- package/v3/dist/init/migration/index.js +8 -0
- package/v3/dist/init/migration/index.js.map +1 -0
- package/v3/dist/init/orchestrator.d.ts +68 -0
- package/v3/dist/init/orchestrator.d.ts.map +1 -0
- package/v3/dist/init/orchestrator.js +239 -0
- package/v3/dist/init/orchestrator.js.map +1 -0
- package/v3/dist/init/phases/01-detection.d.ts +30 -0
- package/v3/dist/init/phases/01-detection.d.ts.map +1 -0
- package/v3/dist/init/phases/01-detection.js +143 -0
- package/v3/dist/init/phases/01-detection.js.map +1 -0
- package/v3/dist/init/phases/02-analysis.d.ts +18 -0
- package/v3/dist/init/phases/02-analysis.d.ts.map +1 -0
- package/v3/dist/init/phases/02-analysis.js +28 -0
- package/v3/dist/init/phases/02-analysis.js.map +1 -0
- package/v3/dist/init/phases/03-configuration.d.ts +26 -0
- package/v3/dist/init/phases/03-configuration.d.ts.map +1 -0
- package/v3/dist/init/phases/03-configuration.js +98 -0
- package/v3/dist/init/phases/03-configuration.js.map +1 -0
- package/v3/dist/init/phases/04-database.d.ts +22 -0
- package/v3/dist/init/phases/04-database.d.ts.map +1 -0
- package/v3/dist/init/phases/04-database.js +88 -0
- package/v3/dist/init/phases/04-database.js.map +1 -0
- package/v3/dist/init/phases/05-learning.d.ts +28 -0
- package/v3/dist/init/phases/05-learning.d.ts.map +1 -0
- package/v3/dist/init/phases/05-learning.js +98 -0
- package/v3/dist/init/phases/05-learning.js.map +1 -0
- package/v3/dist/init/phases/06-code-intelligence.d.ts +33 -0
- package/v3/dist/init/phases/06-code-intelligence.d.ts.map +1 -0
- package/v3/dist/init/phases/06-code-intelligence.js +115 -0
- package/v3/dist/init/phases/06-code-intelligence.js.map +1 -0
- package/v3/dist/init/phases/07-hooks.d.ts +27 -0
- package/v3/dist/init/phases/07-hooks.d.ts.map +1 -0
- package/v3/dist/init/phases/07-hooks.js +209 -0
- package/v3/dist/init/phases/07-hooks.js.map +1 -0
- package/v3/dist/init/phases/08-mcp.d.ts +22 -0
- package/v3/dist/init/phases/08-mcp.d.ts.map +1 -0
- package/v3/dist/init/phases/08-mcp.js +62 -0
- package/v3/dist/init/phases/08-mcp.js.map +1 -0
- package/v3/dist/init/phases/09-assets.d.ts +23 -0
- package/v3/dist/init/phases/09-assets.d.ts.map +1 -0
- package/v3/dist/init/phases/09-assets.js +82 -0
- package/v3/dist/init/phases/09-assets.js.map +1 -0
- package/v3/dist/init/phases/10-workers.d.ts +23 -0
- package/v3/dist/init/phases/10-workers.d.ts.map +1 -0
- package/v3/dist/init/phases/10-workers.js +111 -0
- package/v3/dist/init/phases/10-workers.js.map +1 -0
- package/v3/dist/init/phases/11-claude-md.d.ts +26 -0
- package/v3/dist/init/phases/11-claude-md.d.ts.map +1 -0
- package/v3/dist/init/phases/11-claude-md.js +121 -0
- package/v3/dist/init/phases/11-claude-md.js.map +1 -0
- package/v3/dist/init/phases/12-verification.d.ts +61 -0
- package/v3/dist/init/phases/12-verification.d.ts.map +1 -0
- package/v3/dist/init/phases/12-verification.js +370 -0
- package/v3/dist/init/phases/12-verification.js.map +1 -0
- package/v3/dist/init/phases/index.d.ts +46 -0
- package/v3/dist/init/phases/index.d.ts.map +1 -0
- package/v3/dist/init/phases/index.js +64 -0
- package/v3/dist/init/phases/index.js.map +1 -0
- package/v3/dist/init/phases/phase-interface.d.ts +193 -0
- package/v3/dist/init/phases/phase-interface.d.ts.map +1 -0
- package/v3/dist/init/phases/phase-interface.js +119 -0
- package/v3/dist/init/phases/phase-interface.js.map +1 -0
- package/v3/dist/integrations/agentic-flow/model-router/complexity-analyzer.d.ts +24 -62
- package/v3/dist/integrations/agentic-flow/model-router/complexity-analyzer.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/complexity-analyzer.js +45 -497
- package/v3/dist/integrations/agentic-flow/model-router/complexity-analyzer.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/router.js +2 -2
- package/v3/dist/integrations/agentic-flow/model-router/router.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/score-calculator.d.ts +98 -0
- package/v3/dist/integrations/agentic-flow/model-router/score-calculator.d.ts.map +1 -0
- package/v3/dist/integrations/agentic-flow/model-router/score-calculator.js +197 -0
- package/v3/dist/integrations/agentic-flow/model-router/score-calculator.js.map +1 -0
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts +102 -0
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts.map +1 -0
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js +372 -0
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js.map +1 -0
- package/v3/dist/integrations/agentic-flow/model-router/tier-recommender.d.ts +64 -0
- package/v3/dist/integrations/agentic-flow/model-router/tier-recommender.d.ts.map +1 -0
- package/v3/dist/integrations/agentic-flow/model-router/tier-recommender.js +120 -0
- package/v3/dist/integrations/agentic-flow/model-router/tier-recommender.js.map +1 -0
- package/v3/dist/integrations/coherence/coherence-service.d.ts +323 -0
- package/v3/dist/integrations/coherence/coherence-service.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/coherence-service.js +856 -0
- package/v3/dist/integrations/coherence/coherence-service.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.d.ts +170 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.js +403 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.d.ts +159 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.js +348 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.d.ts +174 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.js +401 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.d.ts +201 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.js +324 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/index.d.ts +20 -0
- package/v3/dist/integrations/coherence/engines/index.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/index.js +26 -0
- package/v3/dist/integrations/coherence/engines/index.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.d.ts +193 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.js +565 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.d.ts +175 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.js +377 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/index.d.ts +84 -0
- package/v3/dist/integrations/coherence/index.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/index.js +114 -0
- package/v3/dist/integrations/coherence/index.js.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts +396 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.js +538 -0
- package/v3/dist/integrations/coherence/threshold-tuner.js.map +1 -0
- package/v3/dist/integrations/coherence/types.d.ts +879 -0
- package/v3/dist/integrations/coherence/types.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/types.js +134 -0
- package/v3/dist/integrations/coherence/types.js.map +1 -0
- package/v3/dist/integrations/coherence/wasm-loader.d.ts +351 -0
- package/v3/dist/integrations/coherence/wasm-loader.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/wasm-loader.js +842 -0
- package/v3/dist/integrations/coherence/wasm-loader.js.map +1 -0
- package/v3/dist/integrations/embeddings/index/HNSWIndex.d.ts.map +1 -1
- package/v3/dist/integrations/embeddings/index/HNSWIndex.js +4 -1
- package/v3/dist/integrations/embeddings/index/HNSWIndex.js.map +1 -1
- package/v3/dist/kernel/interfaces.d.ts +8 -1
- package/v3/dist/kernel/interfaces.d.ts.map +1 -1
- package/v3/dist/learning/aqe-learning-engine.d.ts +272 -0
- package/v3/dist/learning/aqe-learning-engine.d.ts.map +1 -0
- package/v3/dist/learning/aqe-learning-engine.js +708 -0
- package/v3/dist/learning/aqe-learning-engine.js.map +1 -0
- package/v3/dist/learning/causal-verifier.d.ts +244 -0
- package/v3/dist/learning/causal-verifier.d.ts.map +1 -0
- package/v3/dist/learning/causal-verifier.js +300 -0
- package/v3/dist/learning/causal-verifier.js.map +1 -0
- package/v3/dist/learning/experience-capture.d.ts +266 -0
- package/v3/dist/learning/experience-capture.d.ts.map +1 -0
- package/v3/dist/learning/experience-capture.js +647 -0
- package/v3/dist/learning/experience-capture.js.map +1 -0
- package/v3/dist/learning/index.d.ts +8 -0
- package/v3/dist/learning/index.d.ts.map +1 -1
- package/v3/dist/learning/index.js +16 -0
- package/v3/dist/learning/index.js.map +1 -1
- package/v3/dist/learning/memory-auditor.d.ts +235 -0
- package/v3/dist/learning/memory-auditor.d.ts.map +1 -0
- package/v3/dist/learning/memory-auditor.js +480 -0
- package/v3/dist/learning/memory-auditor.js.map +1 -0
- package/v3/dist/learning/pattern-store.d.ts.map +1 -1
- package/v3/dist/learning/pattern-store.js +27 -6
- package/v3/dist/learning/pattern-store.js.map +1 -1
- package/v3/dist/learning/qe-patterns.d.ts +15 -1
- package/v3/dist/learning/qe-patterns.d.ts.map +1 -1
- package/v3/dist/learning/qe-patterns.js +26 -5
- package/v3/dist/learning/qe-patterns.js.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.d.ts +38 -2
- package/v3/dist/learning/qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.js +86 -4
- package/v3/dist/learning/qe-reasoning-bank.js.map +1 -1
- package/v3/dist/learning/real-qe-reasoning-bank.d.ts +32 -2
- package/v3/dist/learning/real-qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/real-qe-reasoning-bank.js +61 -6
- package/v3/dist/learning/real-qe-reasoning-bank.js.map +1 -1
- package/v3/dist/mcp/bundle.js +8786 -1737
- package/v3/dist/mcp/security/cve-prevention.d.ts +31 -134
- package/v3/dist/mcp/security/cve-prevention.d.ts.map +1 -1
- package/v3/dist/mcp/security/cve-prevention.js +37 -562
- package/v3/dist/mcp/security/cve-prevention.js.map +1 -1
- package/v3/dist/mcp/security/index.d.ts +5 -1
- package/v3/dist/mcp/security/index.d.ts.map +1 -1
- package/v3/dist/mcp/security/validators/command-validator.d.ts +41 -0
- package/v3/dist/mcp/security/validators/command-validator.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/command-validator.js +123 -0
- package/v3/dist/mcp/security/validators/command-validator.js.map +1 -0
- package/v3/dist/mcp/security/validators/crypto-validator.d.ts +40 -0
- package/v3/dist/mcp/security/validators/crypto-validator.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/crypto-validator.js +72 -0
- package/v3/dist/mcp/security/validators/crypto-validator.js.map +1 -0
- package/v3/dist/mcp/security/validators/index.d.ts +12 -0
- package/v3/dist/mcp/security/validators/index.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/index.js +22 -0
- package/v3/dist/mcp/security/validators/index.js.map +1 -0
- package/v3/dist/mcp/security/validators/input-sanitizer.d.ts +56 -0
- package/v3/dist/mcp/security/validators/input-sanitizer.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/input-sanitizer.js +157 -0
- package/v3/dist/mcp/security/validators/input-sanitizer.js.map +1 -0
- package/v3/dist/mcp/security/validators/interfaces.d.ts +164 -0
- package/v3/dist/mcp/security/validators/interfaces.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/interfaces.js +6 -0
- package/v3/dist/mcp/security/validators/interfaces.js.map +1 -0
- package/v3/dist/mcp/security/validators/path-traversal-validator.d.ts +50 -0
- package/v3/dist/mcp/security/validators/path-traversal-validator.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/path-traversal-validator.js +242 -0
- package/v3/dist/mcp/security/validators/path-traversal-validator.js.map +1 -0
- package/v3/dist/mcp/security/validators/regex-safety-validator.d.ts +50 -0
- package/v3/dist/mcp/security/validators/regex-safety-validator.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/regex-safety-validator.js +183 -0
- package/v3/dist/mcp/security/validators/regex-safety-validator.js.map +1 -0
- package/v3/dist/mcp/security/validators/validation-orchestrator.d.ts +66 -0
- package/v3/dist/mcp/security/validators/validation-orchestrator.d.ts.map +1 -0
- package/v3/dist/mcp/security/validators/validation-orchestrator.js +146 -0
- package/v3/dist/mcp/security/validators/validation-orchestrator.js.map +1 -0
- package/v3/dist/mcp/server.d.ts.map +1 -1
- package/v3/dist/mcp/server.js +1 -0
- package/v3/dist/mcp/server.js.map +1 -1
- package/v3/dist/mcp/tool-registry.d.ts +3 -1
- package/v3/dist/mcp/tool-registry.d.ts.map +1 -1
- package/v3/dist/mcp/tool-registry.js +155 -2
- package/v3/dist/mcp/tool-registry.js.map +1 -1
- package/v3/dist/mcp/tools/coherence/audit.d.ts +107 -0
- package/v3/dist/mcp/tools/coherence/audit.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/audit.js +236 -0
- package/v3/dist/mcp/tools/coherence/audit.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/check.d.ts +106 -0
- package/v3/dist/mcp/tools/coherence/check.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/check.js +205 -0
- package/v3/dist/mcp/tools/coherence/check.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/collapse.d.ts +123 -0
- package/v3/dist/mcp/tools/coherence/collapse.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/collapse.js +279 -0
- package/v3/dist/mcp/tools/coherence/collapse.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/consensus.d.ts +100 -0
- package/v3/dist/mcp/tools/coherence/consensus.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/consensus.js +201 -0
- package/v3/dist/mcp/tools/coherence/consensus.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/index.d.ts +31 -0
- package/v3/dist/mcp/tools/coherence/index.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/index.js +42 -0
- package/v3/dist/mcp/tools/coherence/index.js.map +1 -0
- package/v3/dist/mcp/tools/index.d.ts +6 -1
- package/v3/dist/mcp/tools/index.d.ts.map +1 -1
- package/v3/dist/mcp/tools/index.js +9 -1
- package/v3/dist/mcp/tools/index.js.map +1 -1
- package/v3/dist/mcp/tools/mincut/index.d.ts +1 -1
- package/v3/dist/mcp/tools/mincut/index.d.ts.map +1 -1
- package/v3/dist/mcp/tools/mincut/index.js.map +1 -1
- package/v3/dist/mcp/tools/registry.d.ts +4 -0
- package/v3/dist/mcp/tools/registry.d.ts.map +1 -1
- package/v3/dist/mcp/tools/registry.js +5 -0
- package/v3/dist/mcp/tools/registry.js.map +1 -1
- package/v3/dist/mcp/tools/test-generation/generate.d.ts +1 -0
- package/v3/dist/mcp/tools/test-generation/generate.d.ts.map +1 -1
- package/v3/dist/mcp/tools/test-generation/generate.js +3 -2
- package/v3/dist/mcp/tools/test-generation/generate.js.map +1 -1
- package/v3/dist/mcp/types.d.ts +1 -1
- package/v3/dist/mcp/types.d.ts.map +1 -1
- package/v3/dist/strange-loop/belief-reconciler.d.ts +357 -0
- package/v3/dist/strange-loop/belief-reconciler.d.ts.map +1 -0
- package/v3/dist/strange-loop/belief-reconciler.js +696 -0
- package/v3/dist/strange-loop/belief-reconciler.js.map +1 -0
- package/v3/dist/strange-loop/index.d.ts +1 -0
- package/v3/dist/strange-loop/index.d.ts.map +1 -1
- package/v3/dist/strange-loop/index.js +2 -0
- package/v3/dist/strange-loop/index.js.map +1 -1
- package/v3/dist/strange-loop/strange-loop.d.ts +177 -5
- package/v3/dist/strange-loop/strange-loop.d.ts.map +1 -1
- package/v3/dist/strange-loop/strange-loop.js +452 -9
- package/v3/dist/strange-loop/strange-loop.js.map +1 -1
- package/v3/dist/strange-loop/types.d.ts +205 -1
- package/v3/dist/strange-loop/types.d.ts.map +1 -1
- package/v3/dist/strange-loop/types.js +5 -0
- package/v3/dist/strange-loop/types.js.map +1 -1
- package/v3/dist/sync/cloud/index.d.ts +8 -0
- package/v3/dist/sync/cloud/index.d.ts.map +1 -0
- package/v3/dist/sync/cloud/index.js +8 -0
- package/v3/dist/sync/cloud/index.js.map +1 -0
- package/v3/dist/sync/cloud/postgres-writer.d.ts +88 -0
- package/v3/dist/sync/cloud/postgres-writer.d.ts.map +1 -0
- package/v3/dist/sync/cloud/postgres-writer.js +319 -0
- package/v3/dist/sync/cloud/postgres-writer.js.map +1 -0
- package/v3/dist/sync/cloud/tunnel-manager.d.ts +75 -0
- package/v3/dist/sync/cloud/tunnel-manager.d.ts.map +1 -0
- package/v3/dist/sync/cloud/tunnel-manager.js +221 -0
- package/v3/dist/sync/cloud/tunnel-manager.js.map +1 -0
- package/v3/dist/sync/index.d.ts +35 -0
- package/v3/dist/sync/index.d.ts.map +1 -0
- package/v3/dist/sync/index.js +35 -0
- package/v3/dist/sync/index.js.map +1 -0
- package/v3/dist/sync/interfaces.d.ts +245 -0
- package/v3/dist/sync/interfaces.d.ts.map +1 -0
- package/v3/dist/sync/interfaces.js +160 -0
- package/v3/dist/sync/interfaces.js.map +1 -0
- package/v3/dist/sync/readers/index.d.ts +8 -0
- package/v3/dist/sync/readers/index.d.ts.map +1 -0
- package/v3/dist/sync/readers/index.js +8 -0
- package/v3/dist/sync/readers/index.js.map +1 -0
- package/v3/dist/sync/readers/json-reader.d.ts +95 -0
- package/v3/dist/sync/readers/json-reader.d.ts.map +1 -0
- package/v3/dist/sync/readers/json-reader.js +306 -0
- package/v3/dist/sync/readers/json-reader.js.map +1 -0
- package/v3/dist/sync/readers/sqlite-reader.d.ts +88 -0
- package/v3/dist/sync/readers/sqlite-reader.d.ts.map +1 -0
- package/v3/dist/sync/readers/sqlite-reader.js +255 -0
- package/v3/dist/sync/readers/sqlite-reader.js.map +1 -0
- package/v3/dist/sync/sync-agent.d.ts +116 -0
- package/v3/dist/sync/sync-agent.d.ts.map +1 -0
- package/v3/dist/sync/sync-agent.js +416 -0
- package/v3/dist/sync/sync-agent.js.map +1 -0
- package/v3/package.json +17 -2
package/v3/dist/cli/index.js
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Provides CLI access to the v3 DDD architecture through the Queen Coordinator.
|
|
6
6
|
* All commands delegate to domain services via the coordination layer.
|
|
7
|
+
*
|
|
8
|
+
* Refactored to use CommandRegistry and handlers for better maintainability.
|
|
9
|
+
* See: cli/handlers/ for command implementations
|
|
10
|
+
* See: cli/commands/ for additional command modules
|
|
7
11
|
*/
|
|
8
12
|
import { Command } from 'commander';
|
|
9
13
|
import chalk from 'chalk';
|
|
@@ -14,17 +18,16 @@ import { CrossDomainEventRouter } from '../coordination/cross-domain-router';
|
|
|
14
18
|
import { DefaultProtocolExecutor } from '../coordination/protocol-executor';
|
|
15
19
|
import { WorkflowOrchestrator } from '../coordination/workflow-orchestrator';
|
|
16
20
|
import { ALL_DOMAINS } from '../shared/types';
|
|
17
|
-
import { InitOrchestrator } from '../init/init-wizard';
|
|
18
|
-
import { integrateCodeIntelligence } from '../init/fleet-integration';
|
|
19
|
-
import { generateCompletion, detectShell, getInstallInstructions, DOMAINS as COMPLETION_DOMAINS, QE_AGENTS, OTHER_AGENTS, } from './completions/index.js';
|
|
20
|
-
import { FleetProgressManager, createTimedSpinner, } from './utils/progress';
|
|
21
21
|
import { bootstrapTokenTracking, shutdownTokenTracking } from '../init/token-bootstrap.js';
|
|
22
22
|
import { parsePipelineFile, validatePipeline, describeCronSchedule, } from './utils/workflow-parser.js';
|
|
23
|
-
import {
|
|
24
|
-
import { parseJsonOption, parseJsonFile } from './helpers/safe-json.js';
|
|
25
|
-
import { runFleetInitWizard, } from './wizards/fleet-wizard.js';
|
|
23
|
+
import { parseJsonOption } from './helpers/safe-json.js';
|
|
26
24
|
import { createPersistentScheduler, createScheduleEntry, } from './scheduler/index.js';
|
|
27
|
-
|
|
25
|
+
// Import handlers and registry
|
|
26
|
+
import { createCommandRegistry } from './command-registry.js';
|
|
27
|
+
import { formatDuration } from './handlers/interfaces.js';
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// CLI State
|
|
30
|
+
// ============================================================================
|
|
28
31
|
const context = {
|
|
29
32
|
kernel: null,
|
|
30
33
|
queen: null,
|
|
@@ -34,63 +37,42 @@ const context = {
|
|
|
34
37
|
persistentScheduler: null,
|
|
35
38
|
initialized: false,
|
|
36
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Register domain workflow actions with the WorkflowOrchestrator (Issue #206)
|
|
42
|
+
*/
|
|
43
|
+
function registerDomainWorkflowActions(kernel, orchestrator) {
|
|
44
|
+
const visualAccessibilityAPI = kernel.getDomainAPI('visual-accessibility');
|
|
45
|
+
if (visualAccessibilityAPI?.registerWorkflowActions) {
|
|
46
|
+
try {
|
|
47
|
+
visualAccessibilityAPI.registerWorkflowActions(orchestrator);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(chalk.yellow(` Warning: Could not register visual-accessibility workflow actions: ${error instanceof Error ? error.message : String(error)}`));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
37
54
|
// ============================================================================
|
|
38
55
|
// Helper Functions
|
|
39
56
|
// ============================================================================
|
|
40
|
-
function getStatusColor(status) {
|
|
41
|
-
switch (status) {
|
|
42
|
-
case 'healthy':
|
|
43
|
-
case 'completed':
|
|
44
|
-
return chalk.green(status);
|
|
45
|
-
case 'degraded':
|
|
46
|
-
case 'running':
|
|
47
|
-
return chalk.yellow(status);
|
|
48
|
-
case 'unhealthy':
|
|
49
|
-
case 'failed':
|
|
50
|
-
return chalk.red(status);
|
|
51
|
-
default:
|
|
52
|
-
return chalk.gray(status);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function formatDuration(ms) {
|
|
56
|
-
if (ms < 1000)
|
|
57
|
-
return `${ms}ms`;
|
|
58
|
-
if (ms < 60000)
|
|
59
|
-
return `${(ms / 1000).toFixed(1)}s`;
|
|
60
|
-
if (ms < 3600000)
|
|
61
|
-
return `${(ms / 60000).toFixed(1)}m`;
|
|
62
|
-
return `${(ms / 3600000).toFixed(1)}h`;
|
|
63
|
-
}
|
|
64
|
-
function formatUptime(ms) {
|
|
65
|
-
const hours = Math.floor(ms / 3600000);
|
|
66
|
-
const minutes = Math.floor((ms % 3600000) / 60000);
|
|
67
|
-
const seconds = Math.floor((ms % 60000) / 1000);
|
|
68
|
-
return `${hours}h ${minutes}m ${seconds}s`;
|
|
69
|
-
}
|
|
70
57
|
async function autoInitialize() {
|
|
71
|
-
// Create kernel with defaults
|
|
72
58
|
context.kernel = new QEKernelImpl({
|
|
73
59
|
maxConcurrentAgents: 15,
|
|
74
60
|
memoryBackend: 'sqlite',
|
|
75
61
|
hnswEnabled: true,
|
|
76
|
-
lazyLoading: true,
|
|
62
|
+
lazyLoading: true,
|
|
77
63
|
enabledDomains: [...ALL_DOMAINS],
|
|
78
64
|
});
|
|
79
65
|
await context.kernel.initialize();
|
|
80
|
-
// Create cross-domain router
|
|
81
66
|
context.router = new CrossDomainEventRouter(context.kernel.eventBus);
|
|
82
67
|
await context.router.initialize();
|
|
83
|
-
// Create protocol executor
|
|
84
68
|
const getDomainAPI = (domain) => {
|
|
85
69
|
return context.kernel.getDomainAPI(domain);
|
|
86
70
|
};
|
|
87
71
|
const protocolExecutor = new DefaultProtocolExecutor(context.kernel.eventBus, context.kernel.memory, getDomainAPI);
|
|
88
|
-
// Create workflow orchestrator
|
|
89
72
|
context.workflowOrchestrator = new WorkflowOrchestrator(context.kernel.eventBus, context.kernel.memory, context.kernel.coordinator);
|
|
90
73
|
await context.workflowOrchestrator.initialize();
|
|
91
|
-
|
|
74
|
+
registerDomainWorkflowActions(context.kernel, context.workflowOrchestrator);
|
|
92
75
|
context.persistentScheduler = createPersistentScheduler();
|
|
93
|
-
// Create Queen Coordinator
|
|
94
76
|
context.queen = createQueenCoordinator(context.kernel, context.router, protocolExecutor, undefined);
|
|
95
77
|
await context.queen.initialize();
|
|
96
78
|
context.initialized = true;
|
|
@@ -99,18 +81,14 @@ async function ensureInitialized() {
|
|
|
99
81
|
if (context.initialized && context.kernel && context.queen) {
|
|
100
82
|
return true;
|
|
101
83
|
}
|
|
102
|
-
// Auto-initialize with defaults and timeout
|
|
103
84
|
console.log(chalk.gray('Auto-initializing v3 system...'));
|
|
104
|
-
const timeout = 30000;
|
|
85
|
+
const timeout = 30000;
|
|
105
86
|
const timeoutPromise = new Promise((_, reject) => {
|
|
106
87
|
setTimeout(() => reject(new Error('Initialization timeout after 30 seconds')), timeout);
|
|
107
88
|
});
|
|
108
89
|
try {
|
|
109
|
-
await Promise.race([
|
|
110
|
-
|
|
111
|
-
timeoutPromise
|
|
112
|
-
]);
|
|
113
|
-
console.log(chalk.green('✓ System ready\n'));
|
|
90
|
+
await Promise.race([autoInitialize(), timeoutPromise]);
|
|
91
|
+
console.log(chalk.green('System ready\n'));
|
|
114
92
|
return true;
|
|
115
93
|
}
|
|
116
94
|
catch (err) {
|
|
@@ -131,7 +109,6 @@ async function ensureInitialized() {
|
|
|
131
109
|
*/
|
|
132
110
|
async function cleanupAndExit(code = 0) {
|
|
133
111
|
try {
|
|
134
|
-
// ADR-042: Save token metrics before shutdown
|
|
135
112
|
await shutdownTokenTracking();
|
|
136
113
|
if (context.workflowOrchestrator) {
|
|
137
114
|
await context.workflowOrchestrator.dispose();
|
|
@@ -145,8 +122,6 @@ async function cleanupAndExit(code = 0) {
|
|
|
145
122
|
if (context.kernel) {
|
|
146
123
|
await context.kernel.dispose();
|
|
147
124
|
}
|
|
148
|
-
// Close the UnifiedMemoryManager singleton to release database connection
|
|
149
|
-
// This is critical for CLI commands to exit properly
|
|
150
125
|
UnifiedMemoryManager.resetInstance();
|
|
151
126
|
}
|
|
152
127
|
catch {
|
|
@@ -158,655 +133,16 @@ async function cleanupAndExit(code = 0) {
|
|
|
158
133
|
// CLI Program
|
|
159
134
|
// ============================================================================
|
|
160
135
|
const program = new Command();
|
|
161
|
-
// Version injected at build time from root package.json
|
|
162
136
|
const VERSION = typeof __CLI_VERSION__ !== 'undefined' ? __CLI_VERSION__ : '0.0.0-dev';
|
|
163
137
|
program
|
|
164
138
|
.name('aqe')
|
|
165
139
|
.description('Agentic QE - Domain-Driven Quality Engineering')
|
|
166
140
|
.version(VERSION);
|
|
167
141
|
// ============================================================================
|
|
168
|
-
//
|
|
169
|
-
// ============================================================================
|
|
170
|
-
program
|
|
171
|
-
.command('init')
|
|
172
|
-
.description('Initialize the AQE v3 system')
|
|
173
|
-
.option('-d, --domains <domains>', 'Comma-separated list of domains to enable', 'all')
|
|
174
|
-
.option('-m, --max-agents <number>', 'Maximum concurrent agents', '15')
|
|
175
|
-
.option('--memory <backend>', 'Memory backend (sqlite|agentdb|hybrid)', 'hybrid')
|
|
176
|
-
.option('--lazy', 'Enable lazy loading of domains')
|
|
177
|
-
.option('--wizard', 'Run interactive setup wizard')
|
|
178
|
-
.option('--auto', 'Auto-configure based on project analysis')
|
|
179
|
-
.option('--minimal', 'Minimal configuration (skip optional features)')
|
|
180
|
-
.option('--skip-patterns', 'Skip loading pre-trained patterns')
|
|
181
|
-
.option('--with-n8n', 'Install n8n workflow testing agents and skills')
|
|
182
|
-
.option('--auto-migrate', 'Automatically migrate from v2 if detected')
|
|
183
|
-
.action(async (options) => {
|
|
184
|
-
try {
|
|
185
|
-
// --auto-migrate implies --auto (must use orchestrator for migration)
|
|
186
|
-
if (options.autoMigrate && !options.auto && !options.wizard) {
|
|
187
|
-
options.auto = true;
|
|
188
|
-
}
|
|
189
|
-
// Check if wizard mode requested
|
|
190
|
-
if (options.wizard || options.auto) {
|
|
191
|
-
console.log(chalk.blue('\n🚀 Agentic QE v3 Initialization\n'));
|
|
192
|
-
const orchestratorOptions = {
|
|
193
|
-
projectRoot: process.cwd(),
|
|
194
|
-
autoMode: options.auto,
|
|
195
|
-
minimal: options.minimal,
|
|
196
|
-
skipPatterns: options.skipPatterns,
|
|
197
|
-
withN8n: options.withN8n,
|
|
198
|
-
autoMigrate: options.autoMigrate,
|
|
199
|
-
};
|
|
200
|
-
const orchestrator = new InitOrchestrator(orchestratorOptions);
|
|
201
|
-
if (options.wizard) {
|
|
202
|
-
// Show wizard steps
|
|
203
|
-
console.log(chalk.white('📋 Setup Wizard Steps:\n'));
|
|
204
|
-
const steps = orchestrator.getWizardSteps();
|
|
205
|
-
for (let i = 0; i < steps.length; i++) {
|
|
206
|
-
console.log(chalk.gray(` ${i + 1}. ${steps[i].title}`));
|
|
207
|
-
console.log(chalk.gray(` ${steps[i].description}\n`));
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
console.log(chalk.white('🔍 Analyzing project...\n'));
|
|
211
|
-
const result = await orchestrator.initialize();
|
|
212
|
-
// Display step results
|
|
213
|
-
for (const step of result.steps) {
|
|
214
|
-
const statusIcon = step.status === 'success' ? '✓' : step.status === 'error' ? '✗' : '⚠';
|
|
215
|
-
const statusColor = step.status === 'success' ? chalk.green : step.status === 'error' ? chalk.red : chalk.yellow;
|
|
216
|
-
console.log(statusColor(` ${statusIcon} ${step.step} (${step.durationMs}ms)`));
|
|
217
|
-
}
|
|
218
|
-
console.log('');
|
|
219
|
-
if (result.success) {
|
|
220
|
-
console.log(chalk.green('✅ AQE v3 initialized successfully!\n'));
|
|
221
|
-
// Show summary
|
|
222
|
-
console.log(chalk.blue('📊 Summary:'));
|
|
223
|
-
console.log(chalk.gray(` • Patterns loaded: ${result.summary.patternsLoaded}`));
|
|
224
|
-
console.log(chalk.gray(` • Hooks configured: ${result.summary.hooksConfigured ? 'Yes' : 'No'}`));
|
|
225
|
-
console.log(chalk.gray(` • Workers started: ${result.summary.workersStarted}`));
|
|
226
|
-
if (result.summary.n8nInstalled) {
|
|
227
|
-
console.log(chalk.gray(` • N8n agents: ${result.summary.n8nInstalled.agents}`));
|
|
228
|
-
console.log(chalk.gray(` • N8n skills: ${result.summary.n8nInstalled.skills}`));
|
|
229
|
-
}
|
|
230
|
-
console.log(chalk.gray(` • Total time: ${result.totalDurationMs}ms\n`));
|
|
231
|
-
console.log(chalk.white('Next steps:'));
|
|
232
|
-
console.log(chalk.gray(' 1. Add MCP: claude mcp add aqe -- aqe-mcp'));
|
|
233
|
-
console.log(chalk.gray(' 2. Run tests: aqe test <path>'));
|
|
234
|
-
console.log(chalk.gray(' 3. Check status: aqe status\n'));
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
console.log(chalk.red('❌ Initialization failed. Check errors above.\n'));
|
|
238
|
-
await cleanupAndExit(1);
|
|
239
|
-
}
|
|
240
|
-
await cleanupAndExit(0);
|
|
241
|
-
}
|
|
242
|
-
// Standard init without wizard
|
|
243
|
-
console.log(chalk.blue('\n🚀 Initializing Agentic QE v3...\n'));
|
|
244
|
-
// Determine enabled domains
|
|
245
|
-
const enabledDomains = options.domains === 'all'
|
|
246
|
-
? [...ALL_DOMAINS]
|
|
247
|
-
: options.domains.split(',').filter((d) => ALL_DOMAINS.includes(d));
|
|
248
|
-
console.log(chalk.gray(` Domains: ${enabledDomains.length}`));
|
|
249
|
-
console.log(chalk.gray(` Max Agents: ${options.maxAgents}`));
|
|
250
|
-
console.log(chalk.gray(` Memory: ${options.memory}`));
|
|
251
|
-
console.log(chalk.gray(` Lazy Loading: ${options.lazy ? 'enabled' : 'disabled'}\n`));
|
|
252
|
-
// Create kernel
|
|
253
|
-
context.kernel = new QEKernelImpl({
|
|
254
|
-
maxConcurrentAgents: parseInt(options.maxAgents, 10),
|
|
255
|
-
memoryBackend: options.memory,
|
|
256
|
-
hnswEnabled: true,
|
|
257
|
-
lazyLoading: options.lazy || false,
|
|
258
|
-
enabledDomains,
|
|
259
|
-
});
|
|
260
|
-
await context.kernel.initialize();
|
|
261
|
-
console.log(chalk.green(' ✓ Kernel initialized'));
|
|
262
|
-
// Create cross-domain router
|
|
263
|
-
context.router = new CrossDomainEventRouter(context.kernel.eventBus);
|
|
264
|
-
await context.router.initialize();
|
|
265
|
-
console.log(chalk.green(' ✓ Cross-domain router initialized'));
|
|
266
|
-
// Create protocol executor
|
|
267
|
-
const getDomainAPI = (domain) => {
|
|
268
|
-
return context.kernel.getDomainAPI(domain);
|
|
269
|
-
};
|
|
270
|
-
const protocolExecutor = new DefaultProtocolExecutor(context.kernel.eventBus, context.kernel.memory, getDomainAPI);
|
|
271
|
-
console.log(chalk.green(' ✓ Protocol executor initialized'));
|
|
272
|
-
// Create workflow orchestrator
|
|
273
|
-
context.workflowOrchestrator = new WorkflowOrchestrator(context.kernel.eventBus, context.kernel.memory, context.kernel.coordinator);
|
|
274
|
-
await context.workflowOrchestrator.initialize();
|
|
275
|
-
console.log(chalk.green(' ✓ Workflow orchestrator initialized'));
|
|
276
|
-
// Create Queen Coordinator
|
|
277
|
-
// Note: workflowExecutor is omitted as WorkflowOrchestrator uses different interface
|
|
278
|
-
context.queen = createQueenCoordinator(context.kernel, context.router, protocolExecutor, undefined // WorkflowExecutor - optional, can be added later
|
|
279
|
-
);
|
|
280
|
-
await context.queen.initialize();
|
|
281
|
-
console.log(chalk.green(' ✓ Queen Coordinator initialized'));
|
|
282
|
-
context.initialized = true;
|
|
283
|
-
console.log(chalk.green('\n✅ AQE v3 initialized successfully!\n'));
|
|
284
|
-
// Show enabled domains
|
|
285
|
-
console.log(chalk.blue('📦 Enabled Domains:'));
|
|
286
|
-
for (const domain of enabledDomains) {
|
|
287
|
-
console.log(chalk.gray(` • ${domain}`));
|
|
288
|
-
}
|
|
289
|
-
console.log('');
|
|
290
|
-
await cleanupAndExit(0);
|
|
291
|
-
}
|
|
292
|
-
catch (error) {
|
|
293
|
-
console.error(chalk.red('\n❌ Failed to initialize:'), error);
|
|
294
|
-
await cleanupAndExit(1);
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
// ============================================================================
|
|
298
|
-
// Status Command
|
|
299
|
-
// ============================================================================
|
|
300
|
-
program
|
|
301
|
-
.command('status')
|
|
302
|
-
.description('Show system status')
|
|
303
|
-
.option('-v, --verbose', 'Show detailed status')
|
|
304
|
-
.action(async (options) => {
|
|
305
|
-
if (!await ensureInitialized())
|
|
306
|
-
return;
|
|
307
|
-
try {
|
|
308
|
-
const health = context.queen.getHealth();
|
|
309
|
-
const metrics = context.queen.getMetrics();
|
|
310
|
-
console.log(chalk.blue('\n📊 AQE v3 Status\n'));
|
|
311
|
-
// Overall health
|
|
312
|
-
console.log(` Status: ${getStatusColor(health.status)}`);
|
|
313
|
-
console.log(` Uptime: ${chalk.cyan(formatUptime(metrics.uptime))}`);
|
|
314
|
-
console.log(` Work Stealing: ${health.workStealingActive ? chalk.green('active') : chalk.gray('inactive')}`);
|
|
315
|
-
// Agents
|
|
316
|
-
console.log(chalk.blue('\n👥 Agents:'));
|
|
317
|
-
console.log(` Total: ${chalk.cyan(health.totalAgents)}`);
|
|
318
|
-
console.log(` Active: ${chalk.yellow(health.activeAgents)}`);
|
|
319
|
-
console.log(` Utilization: ${chalk.cyan((metrics.agentUtilization * 100).toFixed(1))}%`);
|
|
320
|
-
// Tasks
|
|
321
|
-
console.log(chalk.blue('\n📋 Tasks:'));
|
|
322
|
-
console.log(` Received: ${chalk.cyan(metrics.tasksReceived)}`);
|
|
323
|
-
console.log(` Completed: ${chalk.green(metrics.tasksCompleted)}`);
|
|
324
|
-
console.log(` Failed: ${chalk.red(metrics.tasksFailed)}`);
|
|
325
|
-
console.log(` Pending: ${chalk.yellow(health.pendingTasks)}`);
|
|
326
|
-
console.log(` Running: ${chalk.yellow(health.runningTasks)}`);
|
|
327
|
-
if (metrics.tasksStolen > 0) {
|
|
328
|
-
console.log(` Stolen (work stealing): ${chalk.cyan(metrics.tasksStolen)}`);
|
|
329
|
-
}
|
|
330
|
-
// Protocols & Workflows
|
|
331
|
-
if (metrics.protocolsExecuted > 0 || metrics.workflowsExecuted > 0) {
|
|
332
|
-
console.log(chalk.blue('\n🔄 Coordination:'));
|
|
333
|
-
console.log(` Protocols Executed: ${chalk.cyan(metrics.protocolsExecuted)}`);
|
|
334
|
-
console.log(` Workflows Executed: ${chalk.cyan(metrics.workflowsExecuted)}`);
|
|
335
|
-
}
|
|
336
|
-
// Verbose domain status
|
|
337
|
-
if (options.verbose) {
|
|
338
|
-
console.log(chalk.blue('\n📦 Domain Status:'));
|
|
339
|
-
for (const [domain, domainHealth] of health.domainHealth) {
|
|
340
|
-
console.log(` ${domain}: ${getStatusColor(domainHealth.status)}`);
|
|
341
|
-
console.log(chalk.gray(` Agents: ${domainHealth.agents.active}/${domainHealth.agents.total} active`));
|
|
342
|
-
if (domainHealth.errors.length > 0) {
|
|
343
|
-
console.log(chalk.red(` Errors: ${domainHealth.errors.length}`));
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
// Domain utilization
|
|
347
|
-
console.log(chalk.blue('\n📈 Domain Load:'));
|
|
348
|
-
for (const [domain, load] of metrics.domainUtilization) {
|
|
349
|
-
const bar = '█'.repeat(Math.min(load, 20)) + '░'.repeat(Math.max(0, 20 - load));
|
|
350
|
-
console.log(` ${domain.padEnd(25)} ${bar} ${load}`);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
// Health issues
|
|
354
|
-
if (health.issues.length > 0) {
|
|
355
|
-
console.log(chalk.red('\n⚠️ Issues:'));
|
|
356
|
-
for (const issue of health.issues) {
|
|
357
|
-
const color = issue.severity === 'high' ? chalk.red :
|
|
358
|
-
issue.severity === 'medium' ? chalk.yellow : chalk.gray;
|
|
359
|
-
console.log(` ${color(`[${issue.severity}]`)} ${issue.message}`);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
console.log('');
|
|
363
|
-
await cleanupAndExit(0);
|
|
364
|
-
}
|
|
365
|
-
catch (error) {
|
|
366
|
-
console.error(chalk.red('\n❌ Failed to get status:'), error);
|
|
367
|
-
await cleanupAndExit(1);
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
// ============================================================================
|
|
371
|
-
// Health Command
|
|
372
|
-
// ============================================================================
|
|
373
|
-
program
|
|
374
|
-
.command('health')
|
|
375
|
-
.description('Check system health')
|
|
376
|
-
.option('-d, --domain <domain>', 'Check specific domain health')
|
|
377
|
-
.action(async (options) => {
|
|
378
|
-
if (!await ensureInitialized())
|
|
379
|
-
return;
|
|
380
|
-
try {
|
|
381
|
-
if (options.domain) {
|
|
382
|
-
const domain = options.domain;
|
|
383
|
-
const health = context.queen.getDomainHealth(domain);
|
|
384
|
-
if (!health) {
|
|
385
|
-
console.log(chalk.red(`\n❌ Domain not found: ${domain}\n`));
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
console.log(chalk.blue(`\n🏥 Health: ${domain}\n`));
|
|
389
|
-
console.log(` Status: ${getStatusColor(health.status)}`);
|
|
390
|
-
console.log(` Agents: ${health.agents.active}/${health.agents.total} active`);
|
|
391
|
-
console.log(` Idle: ${health.agents.idle}`);
|
|
392
|
-
console.log(` Failed: ${health.agents.failed}`);
|
|
393
|
-
if (health.lastActivity) {
|
|
394
|
-
console.log(` Last Activity: ${health.lastActivity.toISOString()}`);
|
|
395
|
-
}
|
|
396
|
-
if (health.errors.length > 0) {
|
|
397
|
-
console.log(chalk.red(`\n Errors:`));
|
|
398
|
-
health.errors.forEach(err => console.log(chalk.red(` • ${err}`)));
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
const health = context.queen.getHealth();
|
|
403
|
-
console.log(chalk.blue('\n🏥 System Health\n'));
|
|
404
|
-
console.log(` Overall: ${getStatusColor(health.status)}`);
|
|
405
|
-
console.log(` Last Check: ${health.lastHealthCheck.toISOString()}`);
|
|
406
|
-
// Summary by status
|
|
407
|
-
let healthy = 0, degraded = 0, unhealthy = 0;
|
|
408
|
-
for (const [, domainHealth] of health.domainHealth) {
|
|
409
|
-
if (domainHealth.status === 'healthy')
|
|
410
|
-
healthy++;
|
|
411
|
-
else if (domainHealth.status === 'degraded')
|
|
412
|
-
degraded++;
|
|
413
|
-
else
|
|
414
|
-
unhealthy++;
|
|
415
|
-
}
|
|
416
|
-
console.log(chalk.blue('\n📦 Domains:'));
|
|
417
|
-
console.log(` ${chalk.green('●')} Healthy: ${healthy}`);
|
|
418
|
-
console.log(` ${chalk.yellow('●')} Degraded: ${degraded}`);
|
|
419
|
-
console.log(` ${chalk.red('●')} Unhealthy: ${unhealthy}`);
|
|
420
|
-
}
|
|
421
|
-
console.log('');
|
|
422
|
-
await cleanupAndExit(0);
|
|
423
|
-
}
|
|
424
|
-
catch (error) {
|
|
425
|
-
console.error(chalk.red('\n❌ Health check failed:'), error);
|
|
426
|
-
await cleanupAndExit(1);
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
|
-
// ============================================================================
|
|
430
|
-
// Task Command Group
|
|
431
|
-
// ============================================================================
|
|
432
|
-
const taskCmd = program
|
|
433
|
-
.command('task')
|
|
434
|
-
.description('Manage QE tasks');
|
|
435
|
-
taskCmd
|
|
436
|
-
.command('submit <type>')
|
|
437
|
-
.description('Submit a task to the Queen Coordinator')
|
|
438
|
-
.option('-p, --priority <priority>', 'Task priority (p0|p1|p2|p3)', 'p1')
|
|
439
|
-
.option('-d, --domain <domain>', 'Target domain')
|
|
440
|
-
.option('-t, --timeout <ms>', 'Task timeout in ms', '300000')
|
|
441
|
-
.option('--payload <json>', 'Task payload as JSON', '{}')
|
|
442
|
-
.option('--wait', 'Wait for task completion with progress')
|
|
443
|
-
.option('--no-progress', 'Disable progress indicator')
|
|
444
|
-
.action(async (type, options) => {
|
|
445
|
-
if (!await ensureInitialized())
|
|
446
|
-
return;
|
|
447
|
-
try {
|
|
448
|
-
const taskType = type;
|
|
449
|
-
const payload = parseJsonOption(options.payload, 'payload');
|
|
450
|
-
const targetDomains = options.domain ? [options.domain] : [];
|
|
451
|
-
console.log(chalk.blue(`\n Submitting task: ${taskType}\n`));
|
|
452
|
-
// Use spinner for submit operation
|
|
453
|
-
const spinner = options.progress !== false
|
|
454
|
-
? createTimedSpinner(`Submitting ${taskType} task`)
|
|
455
|
-
: null;
|
|
456
|
-
const result = await context.queen.submitTask({
|
|
457
|
-
type: taskType,
|
|
458
|
-
priority: options.priority,
|
|
459
|
-
targetDomains,
|
|
460
|
-
payload,
|
|
461
|
-
timeout: parseInt(options.timeout, 10),
|
|
462
|
-
});
|
|
463
|
-
if (spinner) {
|
|
464
|
-
if (result.success) {
|
|
465
|
-
spinner.succeed(`Task submitted successfully`);
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
spinner.fail(`Failed to submit task`);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
if (result.success) {
|
|
472
|
-
console.log(chalk.cyan(` ID: ${result.value}`));
|
|
473
|
-
console.log(chalk.gray(` Type: ${taskType}`));
|
|
474
|
-
console.log(chalk.gray(` Priority: ${options.priority}`));
|
|
475
|
-
// If --wait flag is provided, poll for task completion with progress
|
|
476
|
-
if (options.wait) {
|
|
477
|
-
console.log('');
|
|
478
|
-
const taskId = result.value;
|
|
479
|
-
const waitSpinner = createTimedSpinner('Waiting for task completion');
|
|
480
|
-
const timeout = parseInt(options.timeout, 10);
|
|
481
|
-
const startTime = Date.now();
|
|
482
|
-
let completed = false;
|
|
483
|
-
while (!completed && (Date.now() - startTime) < timeout) {
|
|
484
|
-
const taskStatus = context.queen.getTaskStatus(taskId);
|
|
485
|
-
if (taskStatus) {
|
|
486
|
-
if (taskStatus.status === 'completed') {
|
|
487
|
-
waitSpinner.succeed('Task completed successfully');
|
|
488
|
-
completed = true;
|
|
489
|
-
}
|
|
490
|
-
else if (taskStatus.status === 'failed') {
|
|
491
|
-
waitSpinner.fail(`Task failed: ${taskStatus.error || 'Unknown error'}`);
|
|
492
|
-
completed = true;
|
|
493
|
-
}
|
|
494
|
-
else {
|
|
495
|
-
// Update spinner with progress info
|
|
496
|
-
waitSpinner.spinner.text = `Task ${taskStatus.status}... (${Math.round((Date.now() - startTime) / 1000)}s)`;
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
if (!completed) {
|
|
500
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
if (!completed) {
|
|
504
|
-
waitSpinner.fail('Task timed out');
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
else {
|
|
509
|
-
console.log(chalk.red(` Error: ${result.error.message}`));
|
|
510
|
-
}
|
|
511
|
-
console.log('');
|
|
512
|
-
}
|
|
513
|
-
catch (error) {
|
|
514
|
-
console.error(chalk.red('\n Failed to submit task:'), error);
|
|
515
|
-
await cleanupAndExit(1);
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
|
-
taskCmd
|
|
519
|
-
.command('list')
|
|
520
|
-
.description('List all tasks')
|
|
521
|
-
.option('-s, --status <status>', 'Filter by status')
|
|
522
|
-
.option('-p, --priority <priority>', 'Filter by priority')
|
|
523
|
-
.option('-d, --domain <domain>', 'Filter by domain')
|
|
524
|
-
.action(async (options) => {
|
|
525
|
-
if (!await ensureInitialized())
|
|
526
|
-
return;
|
|
527
|
-
try {
|
|
528
|
-
const tasks = context.queen.listTasks({
|
|
529
|
-
status: options.status,
|
|
530
|
-
priority: options.priority,
|
|
531
|
-
domain: options.domain,
|
|
532
|
-
});
|
|
533
|
-
console.log(chalk.blue(`\n📋 Tasks (${tasks.length})\n`));
|
|
534
|
-
if (tasks.length === 0) {
|
|
535
|
-
console.log(chalk.gray(' No tasks found'));
|
|
536
|
-
}
|
|
537
|
-
else {
|
|
538
|
-
for (const task of tasks) {
|
|
539
|
-
console.log(` ${chalk.cyan(task.taskId)}`);
|
|
540
|
-
console.log(` Type: ${task.task.type}`);
|
|
541
|
-
console.log(` Status: ${getStatusColor(task.status)}`);
|
|
542
|
-
console.log(` Priority: ${task.task.priority}`);
|
|
543
|
-
if (task.assignedDomain) {
|
|
544
|
-
console.log(` Domain: ${task.assignedDomain}`);
|
|
545
|
-
}
|
|
546
|
-
if (task.startedAt) {
|
|
547
|
-
console.log(chalk.gray(` Started: ${task.startedAt.toISOString()}`));
|
|
548
|
-
}
|
|
549
|
-
console.log('');
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
catch (error) {
|
|
554
|
-
console.error(chalk.red('\n❌ Failed to list tasks:'), error);
|
|
555
|
-
await cleanupAndExit(1);
|
|
556
|
-
}
|
|
557
|
-
});
|
|
558
|
-
taskCmd
|
|
559
|
-
.command('cancel <taskId>')
|
|
560
|
-
.description('Cancel a task')
|
|
561
|
-
.action(async (taskId) => {
|
|
562
|
-
if (!await ensureInitialized())
|
|
563
|
-
return;
|
|
564
|
-
try {
|
|
565
|
-
const result = await context.queen.cancelTask(taskId);
|
|
566
|
-
if (result.success) {
|
|
567
|
-
console.log(chalk.green(`\n✅ Task cancelled: ${taskId}\n`));
|
|
568
|
-
}
|
|
569
|
-
else {
|
|
570
|
-
console.log(chalk.red(`\n❌ Failed to cancel task: ${result.error.message}\n`));
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
catch (error) {
|
|
574
|
-
console.error(chalk.red('\n❌ Failed to cancel task:'), error);
|
|
575
|
-
await cleanupAndExit(1);
|
|
576
|
-
}
|
|
577
|
-
});
|
|
578
|
-
taskCmd
|
|
579
|
-
.command('status <taskId>')
|
|
580
|
-
.description('Get task status')
|
|
581
|
-
.action(async (taskId) => {
|
|
582
|
-
if (!await ensureInitialized())
|
|
583
|
-
return;
|
|
584
|
-
try {
|
|
585
|
-
const task = context.queen.getTaskStatus(taskId);
|
|
586
|
-
if (!task) {
|
|
587
|
-
console.log(chalk.red(`\n❌ Task not found: ${taskId}\n`));
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
console.log(chalk.blue(`\n📋 Task: ${taskId}\n`));
|
|
591
|
-
console.log(` Type: ${task.task.type}`);
|
|
592
|
-
console.log(` Status: ${getStatusColor(task.status)}`);
|
|
593
|
-
console.log(` Priority: ${task.task.priority}`);
|
|
594
|
-
if (task.assignedDomain) {
|
|
595
|
-
console.log(` Domain: ${task.assignedDomain}`);
|
|
596
|
-
}
|
|
597
|
-
if (task.assignedAgents.length > 0) {
|
|
598
|
-
console.log(` Agents: ${task.assignedAgents.join(', ')}`);
|
|
599
|
-
}
|
|
600
|
-
console.log(` Created: ${task.task.createdAt.toISOString()}`);
|
|
601
|
-
if (task.startedAt) {
|
|
602
|
-
console.log(` Started: ${task.startedAt.toISOString()}`);
|
|
603
|
-
}
|
|
604
|
-
if (task.completedAt) {
|
|
605
|
-
console.log(` Completed: ${task.completedAt.toISOString()}`);
|
|
606
|
-
const duration = task.completedAt.getTime() - task.startedAt.getTime();
|
|
607
|
-
console.log(` Duration: ${formatDuration(duration)}`);
|
|
608
|
-
}
|
|
609
|
-
if (task.error) {
|
|
610
|
-
console.log(chalk.red(` Error: ${task.error}`));
|
|
611
|
-
}
|
|
612
|
-
if (task.retryCount > 0) {
|
|
613
|
-
console.log(chalk.yellow(` Retries: ${task.retryCount}`));
|
|
614
|
-
}
|
|
615
|
-
console.log('');
|
|
616
|
-
}
|
|
617
|
-
catch (error) {
|
|
618
|
-
console.error(chalk.red('\n❌ Failed to get task status:'), error);
|
|
619
|
-
await cleanupAndExit(1);
|
|
620
|
-
}
|
|
621
|
-
});
|
|
622
|
-
// ============================================================================
|
|
623
|
-
// Agent Command Group
|
|
624
|
-
// ============================================================================
|
|
625
|
-
const agentCmd = program
|
|
626
|
-
.command('agent')
|
|
627
|
-
.description('Manage QE agents');
|
|
628
|
-
agentCmd
|
|
629
|
-
.command('list')
|
|
630
|
-
.description('List all agents')
|
|
631
|
-
.option('-d, --domain <domain>', 'Filter by domain')
|
|
632
|
-
.option('-s, --status <status>', 'Filter by status')
|
|
633
|
-
.action(async (options) => {
|
|
634
|
-
if (!await ensureInitialized())
|
|
635
|
-
return;
|
|
636
|
-
try {
|
|
637
|
-
let agents = options.domain
|
|
638
|
-
? context.queen.getAgentsByDomain(options.domain)
|
|
639
|
-
: context.queen.listAllAgents();
|
|
640
|
-
if (options.status) {
|
|
641
|
-
agents = agents.filter(a => a.status === options.status);
|
|
642
|
-
}
|
|
643
|
-
console.log(chalk.blue(`\n👥 Agents (${agents.length})\n`));
|
|
644
|
-
if (agents.length === 0) {
|
|
645
|
-
console.log(chalk.gray(' No agents found'));
|
|
646
|
-
}
|
|
647
|
-
else {
|
|
648
|
-
// Group by domain
|
|
649
|
-
const byDomain = new Map();
|
|
650
|
-
for (const agent of agents) {
|
|
651
|
-
if (!byDomain.has(agent.domain)) {
|
|
652
|
-
byDomain.set(agent.domain, []);
|
|
653
|
-
}
|
|
654
|
-
byDomain.get(agent.domain).push(agent);
|
|
655
|
-
}
|
|
656
|
-
for (const [domain, domainAgents] of byDomain) {
|
|
657
|
-
console.log(chalk.cyan(` ${domain}:`));
|
|
658
|
-
for (const agent of domainAgents) {
|
|
659
|
-
console.log(` ${agent.id}`);
|
|
660
|
-
console.log(` Type: ${agent.type}`);
|
|
661
|
-
console.log(` Status: ${getStatusColor(agent.status)}`);
|
|
662
|
-
if (agent.startedAt) {
|
|
663
|
-
console.log(chalk.gray(` Started: ${agent.startedAt.toISOString()}`));
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
console.log('');
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
catch (error) {
|
|
671
|
-
console.error(chalk.red('\n❌ Failed to list agents:'), error);
|
|
672
|
-
await cleanupAndExit(1);
|
|
673
|
-
}
|
|
674
|
-
});
|
|
675
|
-
agentCmd
|
|
676
|
-
.command('spawn <domain>')
|
|
677
|
-
.description('Spawn an agent in a domain')
|
|
678
|
-
.option('-t, --type <type>', 'Agent type', 'worker')
|
|
679
|
-
.option('-c, --capabilities <caps>', 'Comma-separated capabilities', 'general')
|
|
680
|
-
.option('--no-progress', 'Disable progress indicator')
|
|
681
|
-
.action(async (domain, options) => {
|
|
682
|
-
if (!await ensureInitialized())
|
|
683
|
-
return;
|
|
684
|
-
try {
|
|
685
|
-
const capabilities = options.capabilities.split(',');
|
|
686
|
-
console.log(chalk.blue(`\n Spawning agent in ${domain}...\n`));
|
|
687
|
-
// Use spinner for spawn operation
|
|
688
|
-
const spinner = options.progress !== false
|
|
689
|
-
? createTimedSpinner(`Spawning ${options.type} agent`)
|
|
690
|
-
: null;
|
|
691
|
-
const result = await context.queen.requestAgentSpawn(domain, options.type, capabilities);
|
|
692
|
-
if (spinner) {
|
|
693
|
-
if (result.success) {
|
|
694
|
-
spinner.succeed(`Agent spawned successfully`);
|
|
695
|
-
}
|
|
696
|
-
else {
|
|
697
|
-
spinner.fail(`Failed to spawn agent`);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
if (result.success) {
|
|
701
|
-
console.log(chalk.cyan(` ID: ${result.value}`));
|
|
702
|
-
console.log(chalk.gray(` Domain: ${domain}`));
|
|
703
|
-
console.log(chalk.gray(` Type: ${options.type}`));
|
|
704
|
-
console.log(chalk.gray(` Capabilities: ${capabilities.join(', ')}`));
|
|
705
|
-
}
|
|
706
|
-
else {
|
|
707
|
-
console.log(chalk.red(` Error: ${result.error.message}`));
|
|
708
|
-
}
|
|
709
|
-
console.log('');
|
|
710
|
-
}
|
|
711
|
-
catch (error) {
|
|
712
|
-
console.error(chalk.red('\n Failed to spawn agent:'), error);
|
|
713
|
-
await cleanupAndExit(1);
|
|
714
|
-
}
|
|
715
|
-
});
|
|
716
|
-
// ============================================================================
|
|
717
|
-
// Domain Command Group
|
|
718
|
-
// ============================================================================
|
|
719
|
-
const domainCmd = program
|
|
720
|
-
.command('domain')
|
|
721
|
-
.description('Domain operations');
|
|
722
|
-
domainCmd
|
|
723
|
-
.command('list')
|
|
724
|
-
.description('List all domains')
|
|
725
|
-
.action(async () => {
|
|
726
|
-
if (!await ensureInitialized())
|
|
727
|
-
return;
|
|
728
|
-
try {
|
|
729
|
-
console.log(chalk.blue('\n📦 Domains\n'));
|
|
730
|
-
for (const domain of ALL_DOMAINS) {
|
|
731
|
-
const health = context.queen.getDomainHealth(domain);
|
|
732
|
-
const load = context.queen.getDomainLoad(domain);
|
|
733
|
-
console.log(` ${chalk.cyan(domain)}`);
|
|
734
|
-
console.log(` Status: ${getStatusColor(health?.status || 'unknown')}`);
|
|
735
|
-
console.log(` Load: ${load} tasks`);
|
|
736
|
-
if (health) {
|
|
737
|
-
console.log(` Agents: ${health.agents.active}/${health.agents.total}`);
|
|
738
|
-
}
|
|
739
|
-
console.log('');
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
catch (error) {
|
|
743
|
-
console.error(chalk.red('\n❌ Failed to list domains:'), error);
|
|
744
|
-
await cleanupAndExit(1);
|
|
745
|
-
}
|
|
746
|
-
});
|
|
747
|
-
domainCmd
|
|
748
|
-
.command('health <domain>')
|
|
749
|
-
.description('Get domain health')
|
|
750
|
-
.action(async (domain) => {
|
|
751
|
-
if (!await ensureInitialized())
|
|
752
|
-
return;
|
|
753
|
-
try {
|
|
754
|
-
const health = context.queen.getDomainHealth(domain);
|
|
755
|
-
if (!health) {
|
|
756
|
-
console.log(chalk.red(`\n❌ Domain not found: ${domain}\n`));
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
console.log(chalk.blue(`\n🏥 ${domain} Health\n`));
|
|
760
|
-
console.log(` Status: ${getStatusColor(health.status)}`);
|
|
761
|
-
console.log(` Agents Total: ${health.agents.total}`);
|
|
762
|
-
console.log(` Agents Active: ${chalk.green(health.agents.active)}`);
|
|
763
|
-
console.log(` Agents Idle: ${chalk.yellow(health.agents.idle)}`);
|
|
764
|
-
console.log(` Agents Failed: ${chalk.red(health.agents.failed)}`);
|
|
765
|
-
if (health.lastActivity) {
|
|
766
|
-
console.log(` Last Activity: ${health.lastActivity.toISOString()}`);
|
|
767
|
-
}
|
|
768
|
-
if (health.errors.length > 0) {
|
|
769
|
-
console.log(chalk.red('\n Errors:'));
|
|
770
|
-
health.errors.forEach(err => console.log(chalk.red(` • ${err}`)));
|
|
771
|
-
}
|
|
772
|
-
console.log('');
|
|
773
|
-
}
|
|
774
|
-
catch (error) {
|
|
775
|
-
console.error(chalk.red('\n❌ Failed to get domain health:'), error);
|
|
776
|
-
await cleanupAndExit(1);
|
|
777
|
-
}
|
|
778
|
-
});
|
|
779
|
-
// ============================================================================
|
|
780
|
-
// Protocol Command Group
|
|
142
|
+
// Register Handlers via CommandRegistry
|
|
781
143
|
// ============================================================================
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
.description('Execute coordination protocols');
|
|
785
|
-
protocolCmd
|
|
786
|
-
.command('run <protocolId>')
|
|
787
|
-
.description('Execute a protocol')
|
|
788
|
-
.option('--params <json>', 'Protocol parameters as JSON', '{}')
|
|
789
|
-
.action(async (protocolId, options) => {
|
|
790
|
-
if (!await ensureInitialized())
|
|
791
|
-
return;
|
|
792
|
-
try {
|
|
793
|
-
const params = parseJsonOption(options.params, 'params');
|
|
794
|
-
console.log(chalk.blue(`\n🔄 Executing protocol: ${protocolId}\n`));
|
|
795
|
-
const result = await context.queen.executeProtocol(protocolId, params);
|
|
796
|
-
if (result.success) {
|
|
797
|
-
console.log(chalk.green(`✅ Protocol execution started`));
|
|
798
|
-
console.log(chalk.cyan(` Execution ID: ${result.value}`));
|
|
799
|
-
}
|
|
800
|
-
else {
|
|
801
|
-
console.log(chalk.red(`❌ Failed to execute protocol: ${result.error.message}`));
|
|
802
|
-
}
|
|
803
|
-
console.log('');
|
|
804
|
-
}
|
|
805
|
-
catch (error) {
|
|
806
|
-
console.error(chalk.red('\n❌ Failed to execute protocol:'), error);
|
|
807
|
-
await cleanupAndExit(1);
|
|
808
|
-
}
|
|
809
|
-
});
|
|
144
|
+
const registry = createCommandRegistry(context, cleanupAndExit, ensureInitialized);
|
|
145
|
+
registry.registerAll(program);
|
|
810
146
|
// ============================================================================
|
|
811
147
|
// Workflow Command Group (ADR-041)
|
|
812
148
|
// ============================================================================
|
|
@@ -827,7 +163,6 @@ workflowCmd
|
|
|
827
163
|
const filePath = pathModule.resolve(file);
|
|
828
164
|
try {
|
|
829
165
|
console.log(chalk.blue(`\n Running workflow from: ${file}\n`));
|
|
830
|
-
// Parse the pipeline file
|
|
831
166
|
const parseResult = parsePipelineFile(filePath);
|
|
832
167
|
if (!parseResult.success || !parseResult.workflow) {
|
|
833
168
|
console.log(chalk.red('Failed to parse pipeline:'));
|
|
@@ -836,11 +171,8 @@ workflowCmd
|
|
|
836
171
|
}
|
|
837
172
|
await cleanupAndExit(1);
|
|
838
173
|
}
|
|
839
|
-
// Additional params (SEC-001: safe parsing prevents prototype pollution)
|
|
840
174
|
const additionalParams = parseJsonOption(options.params, 'params');
|
|
841
|
-
// Build input from pipeline params and additional params
|
|
842
175
|
const input = { ...additionalParams };
|
|
843
|
-
// Add stage params to input context
|
|
844
176
|
if (parseResult.pipeline) {
|
|
845
177
|
for (const stage of parseResult.pipeline.stages) {
|
|
846
178
|
if (stage.params) {
|
|
@@ -850,7 +182,6 @@ workflowCmd
|
|
|
850
182
|
}
|
|
851
183
|
}
|
|
852
184
|
}
|
|
853
|
-
// Register the workflow if not already registered
|
|
854
185
|
const existingWorkflow = context.workflowOrchestrator.getWorkflow(parseResult.workflow.id);
|
|
855
186
|
if (!existingWorkflow) {
|
|
856
187
|
const registerResult = context.workflowOrchestrator.registerWorkflow(parseResult.workflow);
|
|
@@ -859,19 +190,17 @@ workflowCmd
|
|
|
859
190
|
await cleanupAndExit(1);
|
|
860
191
|
}
|
|
861
192
|
}
|
|
862
|
-
// Execute the workflow
|
|
863
193
|
const execResult = await context.workflowOrchestrator.executeWorkflow(parseResult.workflow.id, input);
|
|
864
194
|
if (!execResult.success) {
|
|
865
195
|
console.log(chalk.red(`Failed to start workflow: ${execResult.error.message}`));
|
|
866
196
|
await cleanupAndExit(1);
|
|
867
|
-
return;
|
|
197
|
+
return;
|
|
868
198
|
}
|
|
869
199
|
const executionId = execResult.value;
|
|
870
200
|
console.log(chalk.cyan(` Execution ID: ${executionId}`));
|
|
871
201
|
console.log(chalk.gray(` Workflow: ${parseResult.workflow.name}`));
|
|
872
202
|
console.log(chalk.gray(` Stages: ${parseResult.workflow.steps.length}`));
|
|
873
203
|
console.log('');
|
|
874
|
-
// Watch progress if requested
|
|
875
204
|
if (options.watch) {
|
|
876
205
|
console.log(chalk.blue('Workflow Progress:\n'));
|
|
877
206
|
let lastStatus;
|
|
@@ -880,12 +209,10 @@ workflowCmd
|
|
|
880
209
|
const status = context.workflowOrchestrator.getWorkflowStatus(executionId);
|
|
881
210
|
if (!status)
|
|
882
211
|
break;
|
|
883
|
-
// Update display if status changed
|
|
884
212
|
if (!lastStatus ||
|
|
885
213
|
lastStatus.progress !== status.progress ||
|
|
886
214
|
lastStatus.status !== status.status ||
|
|
887
215
|
JSON.stringify(lastStatus.currentSteps) !== JSON.stringify(status.currentSteps)) {
|
|
888
|
-
// Clear line and show progress
|
|
889
216
|
process.stdout.write('\r\x1b[K');
|
|
890
217
|
const progressBar = String.fromCharCode(0x2588).repeat(Math.floor(status.progress / 5)) +
|
|
891
218
|
String.fromCharCode(0x2591).repeat(20 - Math.floor(status.progress / 5));
|
|
@@ -898,14 +225,11 @@ workflowCmd
|
|
|
898
225
|
}
|
|
899
226
|
lastStatus = status;
|
|
900
227
|
}
|
|
901
|
-
// Check if completed
|
|
902
228
|
if (status.status === 'completed' || status.status === 'failed' || status.status === 'cancelled') {
|
|
903
229
|
break;
|
|
904
230
|
}
|
|
905
|
-
// Wait before next check
|
|
906
231
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
907
232
|
}
|
|
908
|
-
// Show final status
|
|
909
233
|
const finalStatus = context.workflowOrchestrator.getWorkflowStatus(executionId);
|
|
910
234
|
if (finalStatus) {
|
|
911
235
|
console.log('');
|
|
@@ -948,12 +272,10 @@ workflowCmd
|
|
|
948
272
|
.action(async (file, options) => {
|
|
949
273
|
if (!await ensureInitialized())
|
|
950
274
|
return;
|
|
951
|
-
const fs = await import('fs');
|
|
952
275
|
const pathModule = await import('path');
|
|
953
276
|
const filePath = pathModule.resolve(file);
|
|
954
277
|
try {
|
|
955
278
|
console.log(chalk.blue(`\nScheduling workflow from: ${file}\n`));
|
|
956
|
-
// Parse the pipeline file
|
|
957
279
|
const parseResult = parsePipelineFile(filePath);
|
|
958
280
|
if (!parseResult.success || !parseResult.pipeline || !parseResult.workflow) {
|
|
959
281
|
console.log(chalk.red('Failed to parse pipeline:'));
|
|
@@ -962,14 +284,12 @@ workflowCmd
|
|
|
962
284
|
}
|
|
963
285
|
await cleanupAndExit(1);
|
|
964
286
|
}
|
|
965
|
-
// Get schedule from option or file
|
|
966
287
|
const schedule = options.cron || parseResult.pipeline.schedule;
|
|
967
288
|
if (!schedule) {
|
|
968
289
|
console.log(chalk.red('No schedule specified'));
|
|
969
290
|
console.log(chalk.gray(' Add "schedule" field to YAML or use --cron option'));
|
|
970
291
|
await cleanupAndExit(1);
|
|
971
292
|
}
|
|
972
|
-
// Register the workflow
|
|
973
293
|
const existingWorkflow = context.workflowOrchestrator.getWorkflow(parseResult.workflow.id);
|
|
974
294
|
if (!existingWorkflow) {
|
|
975
295
|
const registerResult = context.workflowOrchestrator.registerWorkflow(parseResult.workflow);
|
|
@@ -978,7 +298,6 @@ workflowCmd
|
|
|
978
298
|
await cleanupAndExit(1);
|
|
979
299
|
}
|
|
980
300
|
}
|
|
981
|
-
// Create scheduled workflow entry using persistent scheduler (ADR-041)
|
|
982
301
|
const persistedSchedule = createScheduleEntry({
|
|
983
302
|
workflowId: parseResult.workflow.id,
|
|
984
303
|
pipelinePath: filePath,
|
|
@@ -986,9 +305,7 @@ workflowCmd
|
|
|
986
305
|
scheduleDescription: describeCronSchedule(schedule),
|
|
987
306
|
enabled: options.enable !== false,
|
|
988
307
|
});
|
|
989
|
-
// Persist to disk using PersistentScheduler
|
|
990
308
|
await context.persistentScheduler.saveSchedule(persistedSchedule);
|
|
991
|
-
// Also keep in memory for backward compatibility
|
|
992
309
|
const scheduledWorkflow = {
|
|
993
310
|
id: persistedSchedule.id,
|
|
994
311
|
workflowId: persistedSchedule.workflowId,
|
|
@@ -1029,17 +346,15 @@ workflowCmd
|
|
|
1029
346
|
return;
|
|
1030
347
|
try {
|
|
1031
348
|
console.log(chalk.blue('\nWorkflows\n'));
|
|
1032
|
-
// Show scheduled workflows (from PersistentScheduler)
|
|
1033
349
|
if (options.scheduled || options.all) {
|
|
1034
350
|
console.log(chalk.cyan('Scheduled Workflows:'));
|
|
1035
|
-
// Load schedules from persistent storage (ADR-041)
|
|
1036
351
|
const scheduled = await context.persistentScheduler.getSchedules();
|
|
1037
352
|
if (scheduled.length === 0) {
|
|
1038
353
|
console.log(chalk.gray(' No scheduled workflows\n'));
|
|
1039
354
|
}
|
|
1040
355
|
else {
|
|
1041
356
|
for (const sched of scheduled) {
|
|
1042
|
-
const statusIcon = sched.enabled ? chalk.green('
|
|
357
|
+
const statusIcon = sched.enabled ? chalk.green('*') : chalk.gray('o');
|
|
1043
358
|
console.log(` ${statusIcon} ${chalk.white(sched.workflowId)}`);
|
|
1044
359
|
console.log(chalk.gray(` ID: ${sched.id}`));
|
|
1045
360
|
console.log(chalk.gray(` Schedule: ${sched.schedule} (${sched.scheduleDescription})`));
|
|
@@ -1053,7 +368,6 @@ workflowCmd
|
|
|
1053
368
|
}
|
|
1054
369
|
}
|
|
1055
370
|
}
|
|
1056
|
-
// Show active executions
|
|
1057
371
|
if (options.active || options.all) {
|
|
1058
372
|
console.log(chalk.cyan('Active Executions:'));
|
|
1059
373
|
const activeExecutions = context.workflowOrchestrator.getActiveExecutions();
|
|
@@ -1074,7 +388,6 @@ workflowCmd
|
|
|
1074
388
|
}
|
|
1075
389
|
}
|
|
1076
390
|
}
|
|
1077
|
-
// Show registered workflows (default behavior)
|
|
1078
391
|
if (!options.scheduled && !options.active || options.all) {
|
|
1079
392
|
console.log(chalk.cyan('Registered Workflows:'));
|
|
1080
393
|
const workflows = context.workflowOrchestrator.listWorkflows();
|
|
@@ -1116,12 +429,10 @@ workflowCmd
|
|
|
1116
429
|
const filePath = pathModule.resolve(file);
|
|
1117
430
|
try {
|
|
1118
431
|
console.log(chalk.blue(`\nValidating pipeline: ${file}\n`));
|
|
1119
|
-
// Check file exists
|
|
1120
432
|
if (!fs.existsSync(filePath)) {
|
|
1121
433
|
console.log(chalk.red(`File not found: ${filePath}`));
|
|
1122
434
|
await cleanupAndExit(1);
|
|
1123
435
|
}
|
|
1124
|
-
// Parse the pipeline file
|
|
1125
436
|
const parseResult = parsePipelineFile(filePath);
|
|
1126
437
|
if (!parseResult.success) {
|
|
1127
438
|
console.log(chalk.red('Parse errors:'));
|
|
@@ -1130,9 +441,7 @@ workflowCmd
|
|
|
1130
441
|
}
|
|
1131
442
|
await cleanupAndExit(1);
|
|
1132
443
|
}
|
|
1133
|
-
// Validate the pipeline structure
|
|
1134
444
|
const validationResult = validatePipeline(parseResult.pipeline);
|
|
1135
|
-
// Show results
|
|
1136
445
|
if (validationResult.valid) {
|
|
1137
446
|
console.log(chalk.green('Pipeline is valid\n'));
|
|
1138
447
|
}
|
|
@@ -1143,7 +452,6 @@ workflowCmd
|
|
|
1143
452
|
}
|
|
1144
453
|
console.log('');
|
|
1145
454
|
}
|
|
1146
|
-
// Show warnings
|
|
1147
455
|
if (validationResult.warnings.length > 0) {
|
|
1148
456
|
console.log(chalk.yellow('Warnings:'));
|
|
1149
457
|
for (const warning of validationResult.warnings) {
|
|
@@ -1151,7 +459,6 @@ workflowCmd
|
|
|
1151
459
|
}
|
|
1152
460
|
console.log('');
|
|
1153
461
|
}
|
|
1154
|
-
// Show pipeline details if verbose
|
|
1155
462
|
if (options.verbose && parseResult.pipeline) {
|
|
1156
463
|
const pipeline = parseResult.pipeline;
|
|
1157
464
|
console.log(chalk.cyan('Pipeline Details:\n'));
|
|
@@ -1191,7 +498,6 @@ workflowCmd
|
|
|
1191
498
|
}
|
|
1192
499
|
}
|
|
1193
500
|
}
|
|
1194
|
-
// Show converted workflow definition if verbose
|
|
1195
501
|
if (options.verbose && parseResult.workflow) {
|
|
1196
502
|
console.log(chalk.cyan('\n Converted Workflow ID: ') + chalk.white(parseResult.workflow.id));
|
|
1197
503
|
console.log(chalk.gray(` Steps: ${parseResult.workflow.steps.length}`));
|
|
@@ -1219,7 +525,7 @@ workflowCmd
|
|
|
1219
525
|
if (!status) {
|
|
1220
526
|
console.log(chalk.red(`\nExecution not found: ${executionId}\n`));
|
|
1221
527
|
await cleanupAndExit(1);
|
|
1222
|
-
return;
|
|
528
|
+
return;
|
|
1223
529
|
}
|
|
1224
530
|
console.log(chalk.blue(`\nWorkflow Execution Status\n`));
|
|
1225
531
|
const statusColor = status.status === 'completed' ? chalk.green :
|
|
@@ -1246,7 +552,6 @@ workflowCmd
|
|
|
1246
552
|
if (status.error) {
|
|
1247
553
|
console.log(chalk.red(`\n Error: ${status.error}`));
|
|
1248
554
|
}
|
|
1249
|
-
// Show detailed step results if verbose
|
|
1250
555
|
if (options.verbose && status.stepResults.size > 0) {
|
|
1251
556
|
console.log(chalk.cyan('\n Step Results:'));
|
|
1252
557
|
for (const [stepId, result] of status.stepResults) {
|
|
@@ -1295,1861 +600,36 @@ workflowCmd
|
|
|
1295
600
|
}
|
|
1296
601
|
});
|
|
1297
602
|
// ============================================================================
|
|
1298
|
-
// Shortcut Commands
|
|
603
|
+
// Shortcut Commands (test, coverage, quality, security, code)
|
|
1299
604
|
// ============================================================================
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
console.log(chalk.red('❌ Test generation domain not available'));
|
|
1318
|
-
return;
|
|
1319
|
-
}
|
|
1320
|
-
// Collect source files
|
|
1321
|
-
const fs = await import('fs');
|
|
1322
|
-
const path = await import('path');
|
|
1323
|
-
const targetPath = path.resolve(target || '.');
|
|
1324
|
-
let sourceFiles = [];
|
|
1325
|
-
if (fs.existsSync(targetPath)) {
|
|
1326
|
-
if (fs.statSync(targetPath).isDirectory()) {
|
|
1327
|
-
const walkDir = (dir, depth = 0) => {
|
|
1328
|
-
if (depth > 4)
|
|
1329
|
-
return [];
|
|
1330
|
-
const result = [];
|
|
1331
|
-
const items = fs.readdirSync(dir);
|
|
1332
|
-
for (const item of items) {
|
|
1333
|
-
if (item === 'node_modules' || item === 'dist' || item === 'tests' || item.includes('.test.') || item.includes('.spec.'))
|
|
1334
|
-
continue;
|
|
1335
|
-
const fullPath = path.join(dir, item);
|
|
1336
|
-
const stat = fs.statSync(fullPath);
|
|
1337
|
-
if (stat.isDirectory()) {
|
|
1338
|
-
result.push(...walkDir(fullPath, depth + 1));
|
|
1339
|
-
}
|
|
1340
|
-
else if (item.endsWith('.ts') && !item.endsWith('.d.ts')) {
|
|
1341
|
-
result.push(fullPath);
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
return result;
|
|
1345
|
-
};
|
|
1346
|
-
sourceFiles = walkDir(targetPath);
|
|
1347
|
-
}
|
|
1348
|
-
else {
|
|
1349
|
-
sourceFiles = [targetPath];
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
if (sourceFiles.length === 0) {
|
|
1353
|
-
console.log(chalk.yellow('No source files found'));
|
|
1354
|
-
return;
|
|
1355
|
-
}
|
|
1356
|
-
console.log(chalk.gray(` Found ${sourceFiles.length} source files\n`));
|
|
1357
|
-
// Generate tests
|
|
1358
|
-
const result = await testGenAPI.generateTests({
|
|
1359
|
-
sourceFiles,
|
|
1360
|
-
testType: options.type,
|
|
1361
|
-
framework: options.framework,
|
|
1362
|
-
coverageTarget: 80,
|
|
1363
|
-
});
|
|
1364
|
-
if (result.success && result.value) {
|
|
1365
|
-
const generated = result.value;
|
|
1366
|
-
console.log(chalk.green(`✅ Generated ${generated.tests.length} tests\n`));
|
|
1367
|
-
console.log(chalk.cyan(' Tests:'));
|
|
1368
|
-
for (const test of generated.tests.slice(0, 10)) {
|
|
1369
|
-
console.log(` ${chalk.white(test.name)}`);
|
|
1370
|
-
console.log(chalk.gray(` Source: ${path.basename(test.sourceFile)}`));
|
|
1371
|
-
console.log(chalk.gray(` Assertions: ${test.assertions}`));
|
|
1372
|
-
}
|
|
1373
|
-
if (generated.tests.length > 10) {
|
|
1374
|
-
console.log(chalk.gray(` ... and ${generated.tests.length - 10} more`));
|
|
1375
|
-
}
|
|
1376
|
-
console.log(`\n Coverage Estimate: ${chalk.yellow(generated.coverageEstimate + '%')}`);
|
|
1377
|
-
if (generated.patternsUsed.length > 0) {
|
|
1378
|
-
console.log(` Patterns Used: ${chalk.cyan(generated.patternsUsed.join(', '))}`);
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
else {
|
|
1382
|
-
console.log(chalk.red(`❌ Failed: ${result.error?.message || 'Unknown error'}`));
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
else if (action === 'execute') {
|
|
1386
|
-
console.log(chalk.blue(`\n🧪 Executing tests in ${target || 'current directory'}...\n`));
|
|
1387
|
-
// Get test execution domain API (with lazy loading support)
|
|
1388
|
-
const testExecAPI = await context.kernel.getDomainAPIAsync('test-execution');
|
|
1389
|
-
if (!testExecAPI) {
|
|
1390
|
-
console.log(chalk.red('❌ Test execution domain not available'));
|
|
1391
|
-
return;
|
|
1392
|
-
}
|
|
1393
|
-
// Collect test files
|
|
1394
|
-
const fs = await import('fs');
|
|
1395
|
-
const path = await import('path');
|
|
1396
|
-
const targetPath = path.resolve(target || '.');
|
|
1397
|
-
let testFiles = [];
|
|
1398
|
-
if (fs.existsSync(targetPath)) {
|
|
1399
|
-
if (fs.statSync(targetPath).isDirectory()) {
|
|
1400
|
-
const walkDir = (dir, depth = 0) => {
|
|
1401
|
-
if (depth > 4)
|
|
1402
|
-
return [];
|
|
1403
|
-
const result = [];
|
|
1404
|
-
const items = fs.readdirSync(dir);
|
|
1405
|
-
for (const item of items) {
|
|
1406
|
-
if (item === 'node_modules' || item === 'dist')
|
|
1407
|
-
continue;
|
|
1408
|
-
const fullPath = path.join(dir, item);
|
|
1409
|
-
const stat = fs.statSync(fullPath);
|
|
1410
|
-
if (stat.isDirectory()) {
|
|
1411
|
-
result.push(...walkDir(fullPath, depth + 1));
|
|
1412
|
-
}
|
|
1413
|
-
else if ((item.includes('.test.') || item.includes('.spec.')) && item.endsWith('.ts')) {
|
|
1414
|
-
result.push(fullPath);
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
return result;
|
|
1418
|
-
};
|
|
1419
|
-
testFiles = walkDir(targetPath);
|
|
1420
|
-
}
|
|
1421
|
-
else {
|
|
1422
|
-
testFiles = [targetPath];
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
if (testFiles.length === 0) {
|
|
1426
|
-
console.log(chalk.yellow('No test files found'));
|
|
1427
|
-
return;
|
|
1428
|
-
}
|
|
1429
|
-
console.log(chalk.gray(` Found ${testFiles.length} test files\n`));
|
|
1430
|
-
const result = await testExecAPI.runTests({
|
|
1431
|
-
testFiles,
|
|
1432
|
-
parallel: true,
|
|
1433
|
-
retryCount: 2,
|
|
1434
|
-
});
|
|
1435
|
-
if (result.success && result.value) {
|
|
1436
|
-
const run = result.value;
|
|
1437
|
-
const total = run.passed + run.failed + run.skipped;
|
|
1438
|
-
console.log(chalk.green(`✅ Test run complete`));
|
|
1439
|
-
console.log(`\n Results:`);
|
|
1440
|
-
console.log(` Total: ${chalk.white(total)}`);
|
|
1441
|
-
console.log(` Passed: ${chalk.green(run.passed)}`);
|
|
1442
|
-
console.log(` Failed: ${chalk.red(run.failed)}`);
|
|
1443
|
-
console.log(` Skipped: ${chalk.yellow(run.skipped)}`);
|
|
1444
|
-
console.log(` Duration: ${chalk.cyan(run.duration + 'ms')}`);
|
|
1445
|
-
}
|
|
1446
|
-
else {
|
|
1447
|
-
console.log(chalk.red(`❌ Failed: ${result.error?.message || 'Unknown error'}`));
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
else {
|
|
1451
|
-
console.log(chalk.red(`\n❌ Unknown action: ${action}\n`));
|
|
1452
|
-
await cleanupAndExit(1);
|
|
1453
|
-
}
|
|
1454
|
-
console.log('');
|
|
1455
|
-
await cleanupAndExit(0);
|
|
1456
|
-
}
|
|
1457
|
-
catch (error) {
|
|
1458
|
-
console.error(chalk.red('\n❌ Failed:'), error);
|
|
1459
|
-
await cleanupAndExit(1);
|
|
1460
|
-
}
|
|
1461
|
-
});
|
|
1462
|
-
// aqe coverage <target>
|
|
1463
|
-
program
|
|
1464
|
-
.command('coverage')
|
|
1465
|
-
.description('Coverage analysis shortcut')
|
|
1466
|
-
.argument('[target]', 'Target file or directory', '.')
|
|
1467
|
-
.option('--risk', 'Include risk scoring')
|
|
1468
|
-
.option('--gaps', 'Detect coverage gaps')
|
|
1469
|
-
.option('--threshold <percent>', 'Coverage threshold percentage', '80')
|
|
1470
|
-
.option('--sensitivity <level>', 'Gap detection sensitivity (low|medium|high)', 'medium')
|
|
1471
|
-
.option('--wizard', 'Run interactive coverage analysis wizard')
|
|
1472
|
-
.action(async (target, options) => {
|
|
1473
|
-
let analyzeTarget = target;
|
|
1474
|
-
let includeRisk = options.risk;
|
|
1475
|
-
let detectGaps = options.gaps;
|
|
1476
|
-
let threshold = parseInt(options.threshold, 10);
|
|
1477
|
-
// Run wizard if requested
|
|
1478
|
-
if (options.wizard) {
|
|
1479
|
-
try {
|
|
1480
|
-
const wizardResult = await runCoverageAnalysisWizard({
|
|
1481
|
-
defaultTarget: target !== '.' ? target : undefined,
|
|
1482
|
-
defaultThreshold: options.threshold !== '80' ? parseInt(options.threshold, 10) : undefined,
|
|
1483
|
-
defaultRiskScoring: options.risk,
|
|
1484
|
-
defaultSensitivity: options.sensitivity !== 'medium' ? options.sensitivity : undefined,
|
|
1485
|
-
});
|
|
1486
|
-
if (wizardResult.cancelled) {
|
|
1487
|
-
console.log(chalk.yellow('\n Coverage analysis cancelled.\n'));
|
|
1488
|
-
await cleanupAndExit(0);
|
|
1489
|
-
}
|
|
1490
|
-
// Use wizard results
|
|
1491
|
-
analyzeTarget = wizardResult.target;
|
|
1492
|
-
includeRisk = wizardResult.riskScoring;
|
|
1493
|
-
detectGaps = true; // Wizard always enables gap detection
|
|
1494
|
-
threshold = wizardResult.threshold;
|
|
1495
|
-
console.log(chalk.green('\n Starting coverage analysis...\n'));
|
|
1496
|
-
}
|
|
1497
|
-
catch (err) {
|
|
1498
|
-
console.error(chalk.red('\n Wizard error:'), err);
|
|
1499
|
-
await cleanupAndExit(1);
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
if (!await ensureInitialized())
|
|
1503
|
-
return;
|
|
1504
|
-
try {
|
|
1505
|
-
console.log(chalk.blue(`\n Analyzing coverage for ${analyzeTarget}...\n`));
|
|
1506
|
-
// Get coverage analysis domain API directly (with lazy loading support)
|
|
1507
|
-
const coverageAPI = await context.kernel.getDomainAPIAsync('coverage-analysis');
|
|
1508
|
-
if (!coverageAPI) {
|
|
1509
|
-
console.log(chalk.red('❌ Coverage analysis domain not available'));
|
|
1510
|
-
return;
|
|
1511
|
-
}
|
|
1512
|
-
// Collect source files and generate synthetic coverage data for analysis
|
|
1513
|
-
const fs = await import('fs');
|
|
1514
|
-
const path = await import('path');
|
|
1515
|
-
const targetPath = path.resolve(analyzeTarget);
|
|
1516
|
-
let sourceFiles = [];
|
|
1517
|
-
if (fs.existsSync(targetPath)) {
|
|
1518
|
-
if (fs.statSync(targetPath).isDirectory()) {
|
|
1519
|
-
const walkDir = (dir, depth = 0) => {
|
|
1520
|
-
if (depth > 4)
|
|
1521
|
-
return [];
|
|
1522
|
-
const result = [];
|
|
1523
|
-
const items = fs.readdirSync(dir);
|
|
1524
|
-
for (const item of items) {
|
|
1525
|
-
if (item === 'node_modules' || item === 'dist')
|
|
1526
|
-
continue;
|
|
1527
|
-
const fullPath = path.join(dir, item);
|
|
1528
|
-
const stat = fs.statSync(fullPath);
|
|
1529
|
-
if (stat.isDirectory()) {
|
|
1530
|
-
result.push(...walkDir(fullPath, depth + 1));
|
|
1531
|
-
}
|
|
1532
|
-
else if (item.endsWith('.ts') && !item.endsWith('.d.ts')) {
|
|
1533
|
-
result.push(fullPath);
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
return result;
|
|
1537
|
-
};
|
|
1538
|
-
sourceFiles = walkDir(targetPath);
|
|
1539
|
-
}
|
|
1540
|
-
else {
|
|
1541
|
-
sourceFiles = [targetPath];
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
if (sourceFiles.length === 0) {
|
|
1545
|
-
console.log(chalk.yellow('No source files found'));
|
|
1546
|
-
return;
|
|
1547
|
-
}
|
|
1548
|
-
console.log(chalk.gray(` Analyzing ${sourceFiles.length} files...\n`));
|
|
1549
|
-
// Build coverage data from file analysis
|
|
1550
|
-
const files = sourceFiles.map(filePath => {
|
|
1551
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
1552
|
-
const lines = content.split('\n');
|
|
1553
|
-
const totalLines = lines.length;
|
|
1554
|
-
// Estimate coverage based on presence of corresponding test file
|
|
1555
|
-
const testFile = filePath.replace('.ts', '.test.ts').replace('/src/', '/tests/');
|
|
1556
|
-
const hasTest = fs.existsSync(testFile);
|
|
1557
|
-
const coverageRate = hasTest ? 0.75 + Math.random() * 0.2 : 0.2 + Math.random() * 0.3;
|
|
1558
|
-
const coveredLines = Math.floor(totalLines * coverageRate);
|
|
1559
|
-
const uncoveredLines = Array.from({ length: totalLines - coveredLines }, (_, i) => i + coveredLines + 1);
|
|
1560
|
-
return {
|
|
1561
|
-
path: filePath,
|
|
1562
|
-
lines: { covered: coveredLines, total: totalLines },
|
|
1563
|
-
branches: { covered: Math.floor(coveredLines * 0.8), total: totalLines },
|
|
1564
|
-
functions: { covered: Math.floor(coveredLines * 0.9), total: Math.ceil(totalLines / 20) },
|
|
1565
|
-
statements: { covered: coveredLines, total: totalLines },
|
|
1566
|
-
uncoveredLines,
|
|
1567
|
-
uncoveredBranches: uncoveredLines.slice(0, Math.floor(uncoveredLines.length / 2)),
|
|
1568
|
-
};
|
|
1569
|
-
});
|
|
1570
|
-
const totalLines = files.reduce((sum, f) => sum + f.lines.total, 0);
|
|
1571
|
-
const coveredLines = files.reduce((sum, f) => sum + f.lines.covered, 0);
|
|
1572
|
-
const totalBranches = files.reduce((sum, f) => sum + f.branches.total, 0);
|
|
1573
|
-
const coveredBranches = files.reduce((sum, f) => sum + f.branches.covered, 0);
|
|
1574
|
-
const totalFunctions = files.reduce((sum, f) => sum + f.functions.total, 0);
|
|
1575
|
-
const coveredFunctions = files.reduce((sum, f) => sum + f.functions.covered, 0);
|
|
1576
|
-
const coverageData = {
|
|
1577
|
-
files,
|
|
1578
|
-
summary: {
|
|
1579
|
-
line: Math.round((coveredLines / totalLines) * 100),
|
|
1580
|
-
branch: Math.round((coveredBranches / totalBranches) * 100),
|
|
1581
|
-
function: Math.round((coveredFunctions / totalFunctions) * 100),
|
|
1582
|
-
statement: Math.round((coveredLines / totalLines) * 100),
|
|
1583
|
-
files: files.length,
|
|
1584
|
-
},
|
|
1585
|
-
};
|
|
1586
|
-
// Run coverage analysis
|
|
1587
|
-
const result = await coverageAPI.analyze({
|
|
1588
|
-
coverageData,
|
|
1589
|
-
threshold,
|
|
1590
|
-
includeFileDetails: true,
|
|
1591
|
-
});
|
|
1592
|
-
if (result.success && result.value) {
|
|
1593
|
-
const report = result.value;
|
|
1594
|
-
console.log(chalk.cyan(' Coverage Summary:'));
|
|
1595
|
-
console.log(` Lines: ${getColorForPercent(report.summary.line)(report.summary.line + '%')}`);
|
|
1596
|
-
console.log(` Branches: ${getColorForPercent(report.summary.branch)(report.summary.branch + '%')}`);
|
|
1597
|
-
console.log(` Functions: ${getColorForPercent(report.summary.function)(report.summary.function + '%')}`);
|
|
1598
|
-
console.log(` Statements: ${getColorForPercent(report.summary.statement)(report.summary.statement + '%')}`);
|
|
1599
|
-
console.log(`\n Threshold: ${report.meetsThreshold ? chalk.green(`Met (${threshold}%)`) : chalk.red(`Not met (${threshold}%)`)}`);
|
|
1600
|
-
if (report.recommendations.length > 0) {
|
|
1601
|
-
console.log(chalk.cyan('\n Recommendations:'));
|
|
1602
|
-
for (const rec of report.recommendations) {
|
|
1603
|
-
console.log(chalk.gray(` - ${rec}`));
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
// Detect gaps if requested
|
|
1608
|
-
if (detectGaps) {
|
|
1609
|
-
console.log(chalk.cyan('\n Coverage Gaps:'));
|
|
1610
|
-
const gapResult = await coverageAPI.detectGaps({
|
|
1611
|
-
coverageData,
|
|
1612
|
-
minCoverage: threshold,
|
|
1613
|
-
prioritize: includeRisk ? 'risk' : 'size',
|
|
1614
|
-
});
|
|
1615
|
-
if (gapResult.success && gapResult.value) {
|
|
1616
|
-
const gaps = gapResult.value;
|
|
1617
|
-
console.log(chalk.gray(` Total uncovered lines: ${gaps.totalUncoveredLines}`));
|
|
1618
|
-
console.log(chalk.gray(` Estimated effort: ${gaps.estimatedEffort} hours\n`));
|
|
1619
|
-
for (const gap of gaps.gaps.slice(0, 8)) {
|
|
1620
|
-
const severityColor = gap.severity === 'high' ? chalk.red : gap.severity === 'medium' ? chalk.yellow : chalk.gray;
|
|
1621
|
-
const filePath = gap.file.replace(process.cwd() + '/', '');
|
|
1622
|
-
console.log(` ${severityColor(`[${gap.severity}]`)} ${chalk.white(filePath)}`);
|
|
1623
|
-
console.log(chalk.gray(` ${gap.lines.length} uncovered lines, Risk: ${(gap.riskScore * 100).toFixed(0)}%`));
|
|
1624
|
-
}
|
|
1625
|
-
if (gaps.gaps.length > 8) {
|
|
1626
|
-
console.log(chalk.gray(` ... and ${gaps.gaps.length - 8} more gaps`));
|
|
1627
|
-
}
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
// Calculate risk if requested
|
|
1631
|
-
if (includeRisk) {
|
|
1632
|
-
console.log(chalk.cyan('\n⚠️ Risk Analysis:'));
|
|
1633
|
-
// Calculate risk for top 5 files with lowest coverage
|
|
1634
|
-
const lowCoverageFiles = [...files]
|
|
1635
|
-
.sort((a, b) => (a.lines.covered / a.lines.total) - (b.lines.covered / b.lines.total))
|
|
1636
|
-
.slice(0, 5);
|
|
1637
|
-
for (const file of lowCoverageFiles) {
|
|
1638
|
-
const riskResult = await coverageAPI.calculateRisk({
|
|
1639
|
-
file: file.path,
|
|
1640
|
-
uncoveredLines: file.uncoveredLines,
|
|
1641
|
-
});
|
|
1642
|
-
if (riskResult.success && riskResult.value) {
|
|
1643
|
-
const risk = riskResult.value;
|
|
1644
|
-
const riskColor = risk.riskLevel === 'high' ? chalk.red : risk.riskLevel === 'medium' ? chalk.yellow : chalk.green;
|
|
1645
|
-
const filePath = file.path.replace(process.cwd() + '/', '');
|
|
1646
|
-
console.log(` ${riskColor(`[${risk.riskLevel}]`)} ${chalk.white(filePath)}`);
|
|
1647
|
-
console.log(chalk.gray(` Risk: ${(risk.overallRisk * 100).toFixed(0)}%, Coverage: ${Math.round((file.lines.covered / file.lines.total) * 100)}%`));
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
console.log(chalk.green('\n✅ Coverage analysis complete\n'));
|
|
1652
|
-
await cleanupAndExit(0);
|
|
1653
|
-
}
|
|
1654
|
-
catch (error) {
|
|
1655
|
-
console.error(chalk.red('\n❌ Failed:'), error);
|
|
1656
|
-
await cleanupAndExit(1);
|
|
1657
|
-
}
|
|
1658
|
-
});
|
|
1659
|
-
function getColorForPercent(percent) {
|
|
1660
|
-
if (percent >= 80)
|
|
1661
|
-
return chalk.green;
|
|
1662
|
-
if (percent >= 50)
|
|
1663
|
-
return chalk.yellow;
|
|
1664
|
-
return chalk.red;
|
|
1665
|
-
}
|
|
1666
|
-
// aqe token-usage (ADR-042)
|
|
1667
|
-
import { createTokenUsageCommand } from './commands/token-usage.js';
|
|
1668
|
-
program.addCommand(createTokenUsageCommand());
|
|
1669
|
-
// aqe llm (ADR-043)
|
|
1670
|
-
import { createLLMRouterCommand } from './commands/llm-router.js';
|
|
1671
|
-
program.addCommand(createLLMRouterCommand());
|
|
1672
|
-
// aqe quality
|
|
1673
|
-
program
|
|
1674
|
-
.command('quality')
|
|
1675
|
-
.description('Quality assessment shortcut')
|
|
1676
|
-
.option('--gate', 'Run quality gate evaluation')
|
|
1677
|
-
.action(async (options) => {
|
|
1678
|
-
if (!await ensureInitialized())
|
|
1679
|
-
return;
|
|
1680
|
-
try {
|
|
1681
|
-
console.log(chalk.blue(`\n🎯 Running quality assessment...\n`));
|
|
1682
|
-
const result = await context.queen.submitTask({
|
|
1683
|
-
type: 'assess-quality',
|
|
1684
|
-
priority: 'p0',
|
|
1685
|
-
targetDomains: ['quality-assessment'],
|
|
1686
|
-
payload: { runGate: options.gate },
|
|
1687
|
-
timeout: 300000,
|
|
1688
|
-
});
|
|
1689
|
-
if (result.success) {
|
|
1690
|
-
console.log(chalk.green(`✅ Task submitted: ${result.value}`));
|
|
1691
|
-
console.log(chalk.gray(` Use 'aqe task status ${result.value}' to check progress`));
|
|
1692
|
-
}
|
|
1693
|
-
else {
|
|
1694
|
-
console.log(chalk.red(`❌ Failed: ${result.error.message}`));
|
|
1695
|
-
}
|
|
1696
|
-
console.log('');
|
|
1697
|
-
}
|
|
1698
|
-
catch (error) {
|
|
1699
|
-
console.error(chalk.red('\n❌ Failed:'), error);
|
|
1700
|
-
await cleanupAndExit(1);
|
|
1701
|
-
}
|
|
1702
|
-
});
|
|
1703
|
-
// aqe security
|
|
1704
|
-
program
|
|
1705
|
-
.command('security')
|
|
1706
|
-
.description('Security scanning shortcut')
|
|
1707
|
-
.option('--sast', 'Run SAST scan')
|
|
1708
|
-
.option('--dast', 'Run DAST scan')
|
|
1709
|
-
.option('--compliance <frameworks>', 'Check compliance (gdpr,hipaa,soc2)', '')
|
|
1710
|
-
.option('-t, --target <path>', 'Target directory to scan', '.')
|
|
1711
|
-
.action(async (options) => {
|
|
1712
|
-
if (!await ensureInitialized())
|
|
1713
|
-
return;
|
|
1714
|
-
try {
|
|
1715
|
-
console.log(chalk.blue(`\n🔒 Running security scan on ${options.target}...\n`));
|
|
1716
|
-
// Get security domain API directly (with lazy loading support)
|
|
1717
|
-
const securityAPI = await context.kernel.getDomainAPIAsync('security-compliance');
|
|
1718
|
-
if (!securityAPI) {
|
|
1719
|
-
console.log(chalk.red('❌ Security domain not available'));
|
|
1720
|
-
return;
|
|
1721
|
-
}
|
|
1722
|
-
// Collect files from target
|
|
1723
|
-
const fs = await import('fs');
|
|
1724
|
-
const path = await import('path');
|
|
1725
|
-
const targetPath = path.resolve(options.target);
|
|
1726
|
-
let files = [];
|
|
1727
|
-
if (fs.existsSync(targetPath)) {
|
|
1728
|
-
if (fs.statSync(targetPath).isDirectory()) {
|
|
1729
|
-
// Get TypeScript files recursively using fs
|
|
1730
|
-
const walkDir = (dir, depth = 0) => {
|
|
1731
|
-
if (depth > 4)
|
|
1732
|
-
return []; // Max depth limit
|
|
1733
|
-
const result = [];
|
|
1734
|
-
const items = fs.readdirSync(dir);
|
|
1735
|
-
for (const item of items) {
|
|
1736
|
-
if (item === 'node_modules' || item === 'dist')
|
|
1737
|
-
continue;
|
|
1738
|
-
const fullPath = path.join(dir, item);
|
|
1739
|
-
const stat = fs.statSync(fullPath);
|
|
1740
|
-
if (stat.isDirectory()) {
|
|
1741
|
-
result.push(...walkDir(fullPath, depth + 1));
|
|
1742
|
-
}
|
|
1743
|
-
else if (item.endsWith('.ts') && !item.endsWith('.d.ts')) {
|
|
1744
|
-
result.push(fullPath);
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
return result;
|
|
1748
|
-
};
|
|
1749
|
-
files = walkDir(targetPath);
|
|
1750
|
-
}
|
|
1751
|
-
else {
|
|
1752
|
-
files = [targetPath];
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
if (files.length === 0) {
|
|
1756
|
-
console.log(chalk.yellow('No files found to scan'));
|
|
1757
|
-
return;
|
|
1758
|
-
}
|
|
1759
|
-
console.log(chalk.gray(` Scanning ${files.length} files...\n`));
|
|
1760
|
-
// Run SAST if requested
|
|
1761
|
-
if (options.sast) {
|
|
1762
|
-
console.log(chalk.blue('📋 SAST Scan:'));
|
|
1763
|
-
const sastResult = await securityAPI.runSASTScan(files);
|
|
1764
|
-
if (sastResult.success && sastResult.value) {
|
|
1765
|
-
const result = sastResult.value;
|
|
1766
|
-
const vulns = result.vulnerabilities || [];
|
|
1767
|
-
if (vulns.length === 0) {
|
|
1768
|
-
console.log(chalk.green(' ✓ No vulnerabilities found'));
|
|
1769
|
-
}
|
|
1770
|
-
else {
|
|
1771
|
-
console.log(chalk.yellow(` ⚠ Found ${vulns.length} potential issues:`));
|
|
1772
|
-
for (const v of vulns.slice(0, 10)) {
|
|
1773
|
-
const color = v.severity === 'high' ? chalk.red : v.severity === 'medium' ? chalk.yellow : chalk.gray;
|
|
1774
|
-
console.log(color(` [${v.severity}] ${v.type}: ${v.file}:${v.line}`));
|
|
1775
|
-
console.log(chalk.gray(` ${v.message}`));
|
|
1776
|
-
}
|
|
1777
|
-
if (vulns.length > 10) {
|
|
1778
|
-
console.log(chalk.gray(` ... and ${vulns.length - 10} more`));
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
else {
|
|
1783
|
-
console.log(chalk.red(` ✗ SAST failed: ${sastResult.error?.message || 'Unknown error'}`));
|
|
1784
|
-
}
|
|
1785
|
-
console.log('');
|
|
1786
|
-
}
|
|
1787
|
-
// Run compliance check if requested
|
|
1788
|
-
if (options.compliance) {
|
|
1789
|
-
const frameworks = options.compliance.split(',');
|
|
1790
|
-
console.log(chalk.blue(`📜 Compliance Check (${frameworks.join(', ')}):`));
|
|
1791
|
-
const compResult = await securityAPI.checkCompliance(frameworks);
|
|
1792
|
-
if (compResult.success && compResult.value) {
|
|
1793
|
-
const result = compResult.value;
|
|
1794
|
-
if (result.compliant) {
|
|
1795
|
-
console.log(chalk.green(' ✓ Compliant with all frameworks'));
|
|
1796
|
-
}
|
|
1797
|
-
else {
|
|
1798
|
-
console.log(chalk.yellow(' ⚠ Compliance issues found:'));
|
|
1799
|
-
for (const issue of (result.issues || []).slice(0, 5)) {
|
|
1800
|
-
console.log(chalk.yellow(` [${issue.framework}] ${issue.issue}`));
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
}
|
|
1804
|
-
else {
|
|
1805
|
-
console.log(chalk.red(` ✗ Compliance check failed: ${compResult.error?.message || 'Unknown error'}`));
|
|
1806
|
-
}
|
|
1807
|
-
console.log('');
|
|
1808
|
-
}
|
|
1809
|
-
// DAST note
|
|
1810
|
-
if (options.dast) {
|
|
1811
|
-
console.log(chalk.gray('Note: DAST requires running application URLs. Use --target with URLs for DAST scanning.'));
|
|
1812
|
-
}
|
|
1813
|
-
console.log(chalk.green('✅ Security scan complete\n'));
|
|
1814
|
-
await cleanupAndExit(0);
|
|
1815
|
-
}
|
|
1816
|
-
catch (err) {
|
|
1817
|
-
console.error(chalk.red('\n❌ Failed:'), err);
|
|
1818
|
-
await cleanupAndExit(1);
|
|
1819
|
-
}
|
|
1820
|
-
});
|
|
1821
|
-
// aqe code (code intelligence)
|
|
1822
|
-
program
|
|
1823
|
-
.command('code')
|
|
1824
|
-
.description('Code intelligence analysis')
|
|
1825
|
-
.argument('<action>', 'Action (index|search|impact|deps)')
|
|
1826
|
-
.argument('[target]', 'Target path or query')
|
|
1827
|
-
.option('--depth <depth>', 'Analysis depth', '3')
|
|
1828
|
-
.option('--include-tests', 'Include test files')
|
|
1829
|
-
.action(async (action, target, options) => {
|
|
1830
|
-
if (!await ensureInitialized())
|
|
1831
|
-
return;
|
|
1832
|
-
try {
|
|
1833
|
-
// Get code intelligence domain API directly (with lazy loading support)
|
|
1834
|
-
const codeAPI = await context.kernel.getDomainAPIAsync('code-intelligence');
|
|
1835
|
-
if (!codeAPI) {
|
|
1836
|
-
console.log(chalk.red('❌ Code intelligence domain not available'));
|
|
1837
|
-
return;
|
|
1838
|
-
}
|
|
1839
|
-
const fs = await import('fs');
|
|
1840
|
-
const path = await import('path');
|
|
1841
|
-
if (action === 'index') {
|
|
1842
|
-
console.log(chalk.blue(`\n🗂️ Indexing codebase at ${target || '.'}...\n`));
|
|
1843
|
-
const targetPath = path.resolve(target || '.');
|
|
1844
|
-
let paths = [];
|
|
1845
|
-
if (fs.existsSync(targetPath)) {
|
|
1846
|
-
if (fs.statSync(targetPath).isDirectory()) {
|
|
1847
|
-
const walkDir = (dir, depth = 0) => {
|
|
1848
|
-
if (depth > 4)
|
|
1849
|
-
return [];
|
|
1850
|
-
const result = [];
|
|
1851
|
-
const items = fs.readdirSync(dir);
|
|
1852
|
-
for (const item of items) {
|
|
1853
|
-
if (item === 'node_modules' || item === 'dist')
|
|
1854
|
-
continue;
|
|
1855
|
-
const fullPath = path.join(dir, item);
|
|
1856
|
-
const stat = fs.statSync(fullPath);
|
|
1857
|
-
if (stat.isDirectory()) {
|
|
1858
|
-
result.push(...walkDir(fullPath, depth + 1));
|
|
1859
|
-
}
|
|
1860
|
-
else if (item.endsWith('.ts') && !item.endsWith('.d.ts')) {
|
|
1861
|
-
result.push(fullPath);
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
return result;
|
|
1865
|
-
};
|
|
1866
|
-
paths = walkDir(targetPath);
|
|
1867
|
-
}
|
|
1868
|
-
else {
|
|
1869
|
-
paths = [targetPath];
|
|
1870
|
-
}
|
|
1871
|
-
}
|
|
1872
|
-
console.log(chalk.gray(` Found ${paths.length} files to index...\n`));
|
|
1873
|
-
const result = await codeAPI.index({
|
|
1874
|
-
paths,
|
|
1875
|
-
incremental: false,
|
|
1876
|
-
includeTests: options.includeTests || false,
|
|
1877
|
-
});
|
|
1878
|
-
if (result.success && result.value) {
|
|
1879
|
-
const idx = result.value;
|
|
1880
|
-
console.log(chalk.green(`✅ Indexing complete\n`));
|
|
1881
|
-
console.log(chalk.cyan(' Results:'));
|
|
1882
|
-
console.log(` Files indexed: ${chalk.white(idx.filesIndexed)}`);
|
|
1883
|
-
console.log(` Nodes created: ${chalk.white(idx.nodesCreated)}`);
|
|
1884
|
-
console.log(` Edges created: ${chalk.white(idx.edgesCreated)}`);
|
|
1885
|
-
console.log(` Duration: ${chalk.yellow(idx.duration + 'ms')}`);
|
|
1886
|
-
if (idx.errors.length > 0) {
|
|
1887
|
-
console.log(chalk.red(`\n Errors (${idx.errors.length}):`));
|
|
1888
|
-
for (const err of idx.errors.slice(0, 5)) {
|
|
1889
|
-
console.log(chalk.red(` ${err.file}: ${err.error}`));
|
|
1890
|
-
}
|
|
1891
|
-
}
|
|
1892
|
-
}
|
|
1893
|
-
else {
|
|
1894
|
-
console.log(chalk.red(`❌ Failed: ${result.error?.message || 'Unknown error'}`));
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
else if (action === 'search') {
|
|
1898
|
-
if (!target) {
|
|
1899
|
-
console.log(chalk.red('❌ Search query required'));
|
|
1900
|
-
return;
|
|
1901
|
-
}
|
|
1902
|
-
console.log(chalk.blue(`\n🔎 Searching for: "${target}"...\n`));
|
|
1903
|
-
const result = await codeAPI.search({
|
|
1904
|
-
query: target,
|
|
1905
|
-
type: 'semantic',
|
|
1906
|
-
limit: 10,
|
|
1907
|
-
});
|
|
1908
|
-
if (result.success && result.value) {
|
|
1909
|
-
const search = result.value;
|
|
1910
|
-
console.log(chalk.green(`✅ Found ${search.total} results (${search.searchTime}ms)\n`));
|
|
1911
|
-
for (const r of search.results) {
|
|
1912
|
-
const filePath = r.file.replace(process.cwd() + '/', '');
|
|
1913
|
-
console.log(` ${chalk.cyan(filePath)}${r.line ? ':' + r.line : ''}`);
|
|
1914
|
-
console.log(chalk.gray(` ${r.snippet.slice(0, 100)}...`));
|
|
1915
|
-
console.log(chalk.gray(` Score: ${(r.score * 100).toFixed(0)}%\n`));
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
else {
|
|
1919
|
-
console.log(chalk.red(`❌ Failed: ${result.error?.message || 'Unknown error'}`));
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
else if (action === 'impact') {
|
|
1923
|
-
console.log(chalk.blue(`\n📊 Analyzing impact for ${target || 'recent changes'}...\n`));
|
|
1924
|
-
const targetPath = path.resolve(target || '.');
|
|
1925
|
-
let changedFiles = [];
|
|
1926
|
-
if (fs.existsSync(targetPath)) {
|
|
1927
|
-
if (fs.statSync(targetPath).isFile()) {
|
|
1928
|
-
changedFiles = [targetPath];
|
|
1929
|
-
}
|
|
1930
|
-
else {
|
|
1931
|
-
// Get recently modified files (simulated)
|
|
1932
|
-
const walkDir = (dir, depth = 0) => {
|
|
1933
|
-
if (depth > 2)
|
|
1934
|
-
return [];
|
|
1935
|
-
const result = [];
|
|
1936
|
-
const items = fs.readdirSync(dir);
|
|
1937
|
-
for (const item of items) {
|
|
1938
|
-
if (item === 'node_modules' || item === 'dist')
|
|
1939
|
-
continue;
|
|
1940
|
-
const fullPath = path.join(dir, item);
|
|
1941
|
-
const stat = fs.statSync(fullPath);
|
|
1942
|
-
if (stat.isDirectory()) {
|
|
1943
|
-
result.push(...walkDir(fullPath, depth + 1));
|
|
1944
|
-
}
|
|
1945
|
-
else if (item.endsWith('.ts') && !item.endsWith('.d.ts')) {
|
|
1946
|
-
result.push(fullPath);
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
return result;
|
|
1950
|
-
};
|
|
1951
|
-
changedFiles = walkDir(targetPath).slice(0, 10);
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
const result = await codeAPI.analyzeImpact({
|
|
1955
|
-
changedFiles,
|
|
1956
|
-
depth: parseInt(options.depth),
|
|
1957
|
-
includeTests: options.includeTests || false,
|
|
1958
|
-
});
|
|
1959
|
-
if (result.success && result.value) {
|
|
1960
|
-
const impact = result.value;
|
|
1961
|
-
const riskColor = impact.riskLevel === 'high' ? chalk.red : impact.riskLevel === 'medium' ? chalk.yellow : chalk.green;
|
|
1962
|
-
console.log(` Risk Level: ${riskColor(impact.riskLevel)}\n`);
|
|
1963
|
-
console.log(chalk.cyan(` Direct Impact (${impact.directImpact.length} files):`));
|
|
1964
|
-
for (const file of impact.directImpact.slice(0, 5)) {
|
|
1965
|
-
const filePath = file.file.replace(process.cwd() + '/', '');
|
|
1966
|
-
console.log(` ${chalk.white(filePath)}`);
|
|
1967
|
-
console.log(chalk.gray(` Reason: ${file.reason}, Risk: ${(file.riskScore * 100).toFixed(0)}%`));
|
|
1968
|
-
}
|
|
1969
|
-
if (impact.transitiveImpact.length > 0) {
|
|
1970
|
-
console.log(chalk.cyan(`\n Transitive Impact (${impact.transitiveImpact.length} files):`));
|
|
1971
|
-
for (const file of impact.transitiveImpact.slice(0, 5)) {
|
|
1972
|
-
const filePath = file.file.replace(process.cwd() + '/', '');
|
|
1973
|
-
console.log(` ${chalk.white(filePath)} (distance: ${file.distance})`);
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
if (impact.impactedTests.length > 0) {
|
|
1977
|
-
console.log(chalk.cyan(`\n Impacted Tests (${impact.impactedTests.length}):`));
|
|
1978
|
-
for (const test of impact.impactedTests.slice(0, 5)) {
|
|
1979
|
-
console.log(` ${chalk.gray(test)}`);
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
|
-
if (impact.recommendations.length > 0) {
|
|
1983
|
-
console.log(chalk.cyan('\n Recommendations:'));
|
|
1984
|
-
for (const rec of impact.recommendations) {
|
|
1985
|
-
console.log(chalk.gray(` • ${rec}`));
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
else {
|
|
1990
|
-
console.log(chalk.red(`❌ Failed: ${result.error?.message || 'Unknown error'}`));
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
|
-
else if (action === 'deps') {
|
|
1994
|
-
console.log(chalk.blue(`\n🔗 Mapping dependencies for ${target || '.'}...\n`));
|
|
1995
|
-
const targetPath = path.resolve(target || '.');
|
|
1996
|
-
let files = [];
|
|
1997
|
-
if (fs.existsSync(targetPath)) {
|
|
1998
|
-
if (fs.statSync(targetPath).isFile()) {
|
|
1999
|
-
files = [targetPath];
|
|
2000
|
-
}
|
|
2001
|
-
else {
|
|
2002
|
-
const walkDir = (dir, depth = 0) => {
|
|
2003
|
-
if (depth > 2)
|
|
2004
|
-
return [];
|
|
2005
|
-
const result = [];
|
|
2006
|
-
const items = fs.readdirSync(dir);
|
|
2007
|
-
for (const item of items) {
|
|
2008
|
-
if (item === 'node_modules' || item === 'dist')
|
|
2009
|
-
continue;
|
|
2010
|
-
const fullPath = path.join(dir, item);
|
|
2011
|
-
const stat = fs.statSync(fullPath);
|
|
2012
|
-
if (stat.isDirectory()) {
|
|
2013
|
-
result.push(...walkDir(fullPath, depth + 1));
|
|
2014
|
-
}
|
|
2015
|
-
else if (item.endsWith('.ts') && !item.endsWith('.d.ts')) {
|
|
2016
|
-
result.push(fullPath);
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
return result;
|
|
2020
|
-
};
|
|
2021
|
-
files = walkDir(targetPath).slice(0, 50);
|
|
2022
|
-
}
|
|
2023
|
-
}
|
|
2024
|
-
const result = await codeAPI.mapDependencies({
|
|
2025
|
-
files,
|
|
2026
|
-
direction: 'both',
|
|
2027
|
-
depth: parseInt(options.depth),
|
|
2028
|
-
});
|
|
2029
|
-
if (result.success && result.value) {
|
|
2030
|
-
const deps = result.value;
|
|
2031
|
-
console.log(chalk.cyan(' Dependency Metrics:'));
|
|
2032
|
-
console.log(` Nodes: ${chalk.white(deps.metrics.totalNodes)}`);
|
|
2033
|
-
console.log(` Edges: ${chalk.white(deps.metrics.totalEdges)}`);
|
|
2034
|
-
console.log(` Avg Degree: ${chalk.yellow(deps.metrics.avgDegree.toFixed(2))}`);
|
|
2035
|
-
console.log(` Max Depth: ${chalk.yellow(deps.metrics.maxDepth)}`);
|
|
2036
|
-
console.log(` Cyclomatic Complexity: ${chalk.yellow(deps.metrics.cyclomaticComplexity)}`);
|
|
2037
|
-
if (deps.cycles.length > 0) {
|
|
2038
|
-
console.log(chalk.red(`\n ⚠️ Circular Dependencies (${deps.cycles.length}):`));
|
|
2039
|
-
for (const cycle of deps.cycles.slice(0, 3)) {
|
|
2040
|
-
console.log(chalk.red(` ${cycle.join(' → ')}`));
|
|
2041
|
-
}
|
|
2042
|
-
}
|
|
2043
|
-
console.log(chalk.cyan(`\n Top Dependencies (by connections):`));
|
|
2044
|
-
const sortedNodes = [...deps.nodes].sort((a, b) => (b.inDegree + b.outDegree) - (a.inDegree + a.outDegree));
|
|
2045
|
-
for (const node of sortedNodes.slice(0, 8)) {
|
|
2046
|
-
const filePath = node.path.replace(process.cwd() + '/', '');
|
|
2047
|
-
console.log(` ${chalk.white(filePath)}`);
|
|
2048
|
-
console.log(chalk.gray(` In: ${node.inDegree}, Out: ${node.outDegree}, Type: ${node.type}`));
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
else {
|
|
2052
|
-
console.log(chalk.red(`❌ Failed: ${result.error?.message || 'Unknown error'}`));
|
|
2053
|
-
}
|
|
2054
|
-
}
|
|
2055
|
-
else {
|
|
2056
|
-
console.log(chalk.red(`\n❌ Unknown action: ${action}`));
|
|
2057
|
-
console.log(chalk.gray(' Available: index, search, impact, deps\n'));
|
|
2058
|
-
await cleanupAndExit(1);
|
|
2059
|
-
}
|
|
2060
|
-
console.log('');
|
|
2061
|
-
await cleanupAndExit(0);
|
|
2062
|
-
}
|
|
2063
|
-
catch (error) {
|
|
2064
|
-
console.error(chalk.red('\n❌ Failed:'), error);
|
|
2065
|
-
await cleanupAndExit(1);
|
|
2066
|
-
}
|
|
2067
|
-
});
|
|
2068
|
-
// ============================================================================
|
|
2069
|
-
// Migrate Command - V2 to V3 Migration (ADR-048)
|
|
2070
|
-
// ============================================================================
|
|
2071
|
-
const migrateCmd = program
|
|
2072
|
-
.command('migrate')
|
|
2073
|
-
.description('V2-to-V3 migration tools with agent compatibility (ADR-048)');
|
|
2074
|
-
// Helper to check path existence
|
|
2075
|
-
const pathExists = (p) => {
|
|
2076
|
-
try {
|
|
2077
|
-
require('fs').accessSync(p);
|
|
2078
|
-
return true;
|
|
2079
|
-
}
|
|
2080
|
-
catch {
|
|
2081
|
-
return false;
|
|
2082
|
-
}
|
|
2083
|
-
};
|
|
2084
|
-
// migrate run - Main migration command (default behavior)
|
|
2085
|
-
migrateCmd
|
|
2086
|
-
.command('run')
|
|
2087
|
-
.description('Run full migration from v2 to v3')
|
|
2088
|
-
.option('--dry-run', 'Preview migration without making changes')
|
|
2089
|
-
.option('--backup', 'Create backup before migration (recommended)', true)
|
|
2090
|
-
.option('--skip-memory', 'Skip memory database migration')
|
|
2091
|
-
.option('--skip-patterns', 'Skip pattern migration')
|
|
2092
|
-
.option('--skip-config', 'Skip configuration migration')
|
|
2093
|
-
.option('--skip-agents', 'Skip agent name migration')
|
|
2094
|
-
.option('--target <component>', 'Migrate specific component (agents, skills, config, memory)')
|
|
2095
|
-
.option('--force', 'Force migration even if v3 already exists')
|
|
2096
|
-
.action(async (options) => {
|
|
2097
|
-
const fs = await import('fs');
|
|
2098
|
-
const path = await import('path');
|
|
2099
|
-
console.log(chalk.blue('\n🔄 Agentic QE v2 to v3 Migration (ADR-048)\n'));
|
|
2100
|
-
const cwd = process.cwd();
|
|
2101
|
-
const v2Dir = path.join(cwd, '.agentic-qe');
|
|
2102
|
-
const v3Dir = path.join(cwd, '.aqe');
|
|
2103
|
-
const claudeAgentDir = path.join(cwd, '.claude', 'agents');
|
|
2104
|
-
// Step 1: Detect v2 installation
|
|
2105
|
-
console.log(chalk.white('1. Detecting v2 installation...'));
|
|
2106
|
-
const hasV2Dir = fs.existsSync(v2Dir);
|
|
2107
|
-
const hasClaudeAgents = fs.existsSync(claudeAgentDir);
|
|
2108
|
-
if (!hasV2Dir && !hasClaudeAgents) {
|
|
2109
|
-
console.log(chalk.yellow(' ⚠ No v2 installation found'));
|
|
2110
|
-
console.log(chalk.gray(' This might be a fresh project. Use `aqe init` instead.'));
|
|
2111
|
-
await cleanupAndExit(0);
|
|
2112
|
-
}
|
|
2113
|
-
const v2Files = {
|
|
2114
|
-
memoryDb: path.join(v2Dir, 'memory.db'),
|
|
2115
|
-
config: path.join(v2Dir, 'config.json'),
|
|
2116
|
-
patterns: path.join(v2Dir, 'patterns'),
|
|
2117
|
-
};
|
|
2118
|
-
const hasMemory = hasV2Dir && fs.existsSync(v2Files.memoryDb);
|
|
2119
|
-
const hasConfig = hasV2Dir && fs.existsSync(v2Files.config);
|
|
2120
|
-
const hasPatterns = hasV2Dir && fs.existsSync(v2Files.patterns);
|
|
2121
|
-
// Detect v2 agents needing migration
|
|
2122
|
-
const agentsToMigrate = [];
|
|
2123
|
-
if (hasClaudeAgents) {
|
|
2124
|
-
const files = fs.readdirSync(claudeAgentDir);
|
|
2125
|
-
for (const file of files) {
|
|
2126
|
-
if (file.endsWith('.md') && file.startsWith('qe-')) {
|
|
2127
|
-
const agentName = file.replace('.md', '');
|
|
2128
|
-
if (isDeprecatedAgent(agentName)) {
|
|
2129
|
-
agentsToMigrate.push(agentName);
|
|
2130
|
-
}
|
|
2131
|
-
}
|
|
2132
|
-
}
|
|
2133
|
-
}
|
|
2134
|
-
console.log(chalk.green(' ✓ Found v2 installation:'));
|
|
2135
|
-
console.log(chalk.gray(` Memory DB: ${hasMemory ? '✓' : '✗'}`));
|
|
2136
|
-
console.log(chalk.gray(` Config: ${hasConfig ? '✓' : '✗'}`));
|
|
2137
|
-
console.log(chalk.gray(` Patterns: ${hasPatterns ? '✓' : '✗'}`));
|
|
2138
|
-
console.log(chalk.gray(` Agents to migrate: ${agentsToMigrate.length}\n`));
|
|
2139
|
-
// Step 2: Check v3 existence
|
|
2140
|
-
console.log(chalk.white('2. Checking v3 status...'));
|
|
2141
|
-
if (fs.existsSync(v3Dir) && !options.force) {
|
|
2142
|
-
console.log(chalk.yellow(' ⚠ v3 directory already exists at .aqe/'));
|
|
2143
|
-
console.log(chalk.gray(' Use --force to overwrite existing v3 installation.'));
|
|
2144
|
-
await cleanupAndExit(1);
|
|
2145
|
-
}
|
|
2146
|
-
console.log(chalk.green(' ✓ Ready for migration\n'));
|
|
2147
|
-
// Dry run mode
|
|
2148
|
-
if (options.dryRun) {
|
|
2149
|
-
console.log(chalk.blue('📋 Dry Run - Migration Plan:\n'));
|
|
2150
|
-
if (!options.skipMemory && hasMemory) {
|
|
2151
|
-
const stats = fs.statSync(v2Files.memoryDb);
|
|
2152
|
-
console.log(chalk.gray(` • Migrate memory.db (${(stats.size / 1024).toFixed(1)} KB)`));
|
|
2153
|
-
}
|
|
2154
|
-
if (!options.skipConfig && hasConfig) {
|
|
2155
|
-
console.log(chalk.gray(' • Convert config.json to v3 format'));
|
|
2156
|
-
}
|
|
2157
|
-
if (!options.skipPatterns && hasPatterns) {
|
|
2158
|
-
const patternFiles = fs.readdirSync(v2Files.patterns);
|
|
2159
|
-
console.log(chalk.gray(` • Migrate ${patternFiles.length} pattern files`));
|
|
2160
|
-
}
|
|
2161
|
-
if (!options.skipAgents && agentsToMigrate.length > 0) {
|
|
2162
|
-
console.log(chalk.gray(` • Migrate ${agentsToMigrate.length} agent names:`));
|
|
2163
|
-
for (const agent of agentsToMigrate) {
|
|
2164
|
-
console.log(chalk.gray(` ${agent} → ${resolveAgentName(agent)}`));
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
console.log(chalk.yellow('\n⚠ This is a dry run. No changes were made.'));
|
|
2168
|
-
console.log(chalk.gray('Run without --dry-run to execute migration.\n'));
|
|
2169
|
-
await cleanupAndExit(0);
|
|
2170
|
-
}
|
|
2171
|
-
// Step 3: Create backup
|
|
2172
|
-
if (options.backup) {
|
|
2173
|
-
console.log(chalk.white('3. Creating backup...'));
|
|
2174
|
-
const backupDir = path.join(cwd, '.aqe-backup', `backup-${Date.now()}`);
|
|
2175
|
-
try {
|
|
2176
|
-
fs.mkdirSync(backupDir, { recursive: true });
|
|
2177
|
-
const copyDir = (src, dest) => {
|
|
2178
|
-
if (!fs.existsSync(src))
|
|
2179
|
-
return;
|
|
2180
|
-
if (fs.statSync(src).isDirectory()) {
|
|
2181
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
2182
|
-
for (const file of fs.readdirSync(src)) {
|
|
2183
|
-
copyDir(path.join(src, file), path.join(dest, file));
|
|
2184
|
-
}
|
|
2185
|
-
}
|
|
2186
|
-
else {
|
|
2187
|
-
fs.copyFileSync(src, dest);
|
|
2188
|
-
}
|
|
2189
|
-
};
|
|
2190
|
-
if (hasV2Dir)
|
|
2191
|
-
copyDir(v2Dir, path.join(backupDir, '.agentic-qe'));
|
|
2192
|
-
if (hasClaudeAgents)
|
|
2193
|
-
copyDir(claudeAgentDir, path.join(backupDir, '.claude', 'agents'));
|
|
2194
|
-
console.log(chalk.green(` ✓ Backup created at .aqe-backup/\n`));
|
|
2195
|
-
}
|
|
2196
|
-
catch (err) {
|
|
2197
|
-
console.log(chalk.red(` ✗ Backup failed: ${err}`));
|
|
2198
|
-
await cleanupAndExit(1);
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
else {
|
|
2202
|
-
console.log(chalk.yellow('3. Backup skipped (--no-backup)\n'));
|
|
2203
|
-
}
|
|
2204
|
-
// Step 4: Create v3 directory structure
|
|
2205
|
-
if (!options.target || options.target === 'config' || options.target === 'memory') {
|
|
2206
|
-
console.log(chalk.white('4. Creating v3 directory structure...'));
|
|
2207
|
-
try {
|
|
2208
|
-
fs.mkdirSync(v3Dir, { recursive: true });
|
|
2209
|
-
fs.mkdirSync(path.join(v3Dir, 'agentdb'), { recursive: true });
|
|
2210
|
-
fs.mkdirSync(path.join(v3Dir, 'reasoning-bank'), { recursive: true });
|
|
2211
|
-
fs.mkdirSync(path.join(v3Dir, 'cache'), { recursive: true });
|
|
2212
|
-
fs.mkdirSync(path.join(v3Dir, 'logs'), { recursive: true });
|
|
2213
|
-
console.log(chalk.green(' ✓ Directory structure created\n'));
|
|
2214
|
-
}
|
|
2215
|
-
catch (err) {
|
|
2216
|
-
console.log(chalk.red(` ✗ Failed: ${err}\n`));
|
|
2217
|
-
await cleanupAndExit(1);
|
|
2218
|
-
}
|
|
2219
|
-
}
|
|
2220
|
-
// Step 5: Migrate memory database
|
|
2221
|
-
if ((!options.target || options.target === 'memory') && !options.skipMemory && hasMemory) {
|
|
2222
|
-
console.log(chalk.white('5. Migrating memory database...'));
|
|
2223
|
-
try {
|
|
2224
|
-
const destDb = path.join(v3Dir, 'agentdb', 'memory.db');
|
|
2225
|
-
fs.copyFileSync(v2Files.memoryDb, destDb);
|
|
2226
|
-
const indexFile = path.join(v3Dir, 'agentdb', 'index.json');
|
|
2227
|
-
fs.writeFileSync(indexFile, JSON.stringify({
|
|
2228
|
-
version: '3.0.0',
|
|
2229
|
-
migratedFrom: 'v2',
|
|
2230
|
-
migratedAt: new Date().toISOString(),
|
|
2231
|
-
hnswEnabled: true,
|
|
2232
|
-
vectorDimensions: 128,
|
|
2233
|
-
}, null, 2));
|
|
2234
|
-
const stats = fs.statSync(v2Files.memoryDb);
|
|
2235
|
-
console.log(chalk.green(` ✓ Memory database migrated (${(stats.size / 1024).toFixed(1)} KB)\n`));
|
|
2236
|
-
}
|
|
2237
|
-
catch (err) {
|
|
2238
|
-
console.log(chalk.red(` ✗ Migration failed: ${err}\n`));
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
else if (options.target && options.target !== 'memory') {
|
|
2242
|
-
console.log(chalk.gray('5. Memory migration skipped (--target)\n'));
|
|
2243
|
-
}
|
|
2244
|
-
else if (options.skipMemory) {
|
|
2245
|
-
console.log(chalk.yellow('5. Memory migration skipped\n'));
|
|
2246
|
-
}
|
|
2247
|
-
else {
|
|
2248
|
-
console.log(chalk.gray('5. No memory database to migrate\n'));
|
|
2249
|
-
}
|
|
2250
|
-
// Step 6: Migrate configuration
|
|
2251
|
-
if ((!options.target || options.target === 'config') && !options.skipConfig && hasConfig) {
|
|
2252
|
-
console.log(chalk.white('6. Migrating configuration...'));
|
|
2253
|
-
try {
|
|
2254
|
-
const v2ConfigRaw = fs.readFileSync(v2Files.config, 'utf-8');
|
|
2255
|
-
const v2Config = parseJsonFile(v2ConfigRaw, v2Files.config);
|
|
2256
|
-
const v3Config = {
|
|
2257
|
-
version: '3.0.0',
|
|
2258
|
-
migratedFrom: v2Config.version || '2.x',
|
|
2259
|
-
migratedAt: new Date().toISOString(),
|
|
2260
|
-
kernel: { eventBus: 'in-memory', coordinator: 'queen' },
|
|
2261
|
-
domains: {
|
|
2262
|
-
'test-generation': { enabled: true },
|
|
2263
|
-
'test-execution': { enabled: true },
|
|
2264
|
-
'coverage-analysis': { enabled: true, algorithm: 'hnsw', dimensions: 128 },
|
|
2265
|
-
'quality-assessment': { enabled: true },
|
|
2266
|
-
'defect-intelligence': { enabled: true },
|
|
2267
|
-
'requirements-validation': { enabled: true },
|
|
2268
|
-
'code-intelligence': { enabled: true },
|
|
2269
|
-
'security-compliance': { enabled: true },
|
|
2270
|
-
'contract-testing': { enabled: true },
|
|
2271
|
-
'visual-accessibility': { enabled: false },
|
|
2272
|
-
'chaos-resilience': { enabled: true },
|
|
2273
|
-
'learning-optimization': { enabled: true },
|
|
2274
|
-
},
|
|
2275
|
-
memory: {
|
|
2276
|
-
backend: 'hybrid',
|
|
2277
|
-
path: '.aqe/agentdb/',
|
|
2278
|
-
hnsw: { M: 16, efConstruction: 200 },
|
|
2279
|
-
},
|
|
2280
|
-
learning: {
|
|
2281
|
-
reasoningBank: true,
|
|
2282
|
-
sona: true,
|
|
2283
|
-
patternRetention: v2Config.learning?.patternRetention || 180,
|
|
2284
|
-
},
|
|
2285
|
-
v2Migration: {
|
|
2286
|
-
originalConfig: v2Config,
|
|
2287
|
-
migrationDate: new Date().toISOString(),
|
|
2288
|
-
},
|
|
2289
|
-
};
|
|
2290
|
-
const destConfig = path.join(v3Dir, 'config.json');
|
|
2291
|
-
fs.writeFileSync(destConfig, JSON.stringify(v3Config, null, 2));
|
|
2292
|
-
console.log(chalk.green(' ✓ Configuration migrated\n'));
|
|
2293
|
-
}
|
|
2294
|
-
catch (err) {
|
|
2295
|
-
console.log(chalk.red(` ✗ Config migration failed: ${err}\n`));
|
|
2296
|
-
}
|
|
2297
|
-
}
|
|
2298
|
-
else if (options.target && options.target !== 'config') {
|
|
2299
|
-
console.log(chalk.gray('6. Config migration skipped (--target)\n'));
|
|
2300
|
-
}
|
|
2301
|
-
else if (options.skipConfig) {
|
|
2302
|
-
console.log(chalk.yellow('6. Configuration migration skipped\n'));
|
|
2303
|
-
}
|
|
2304
|
-
else {
|
|
2305
|
-
console.log(chalk.gray('6. No configuration to migrate\n'));
|
|
2306
|
-
}
|
|
2307
|
-
// Step 7: Migrate patterns
|
|
2308
|
-
if ((!options.target || options.target === 'memory') && !options.skipPatterns && hasPatterns) {
|
|
2309
|
-
console.log(chalk.white('7. Migrating patterns to ReasoningBank...'));
|
|
2310
|
-
try {
|
|
2311
|
-
const patternFiles = fs.readdirSync(v2Files.patterns);
|
|
2312
|
-
let migratedCount = 0;
|
|
2313
|
-
for (const file of patternFiles) {
|
|
2314
|
-
const srcPath = path.join(v2Files.patterns, file);
|
|
2315
|
-
const destPath = path.join(v3Dir, 'reasoning-bank', file);
|
|
2316
|
-
if (fs.statSync(srcPath).isFile()) {
|
|
2317
|
-
fs.copyFileSync(srcPath, destPath);
|
|
2318
|
-
migratedCount++;
|
|
2319
|
-
}
|
|
2320
|
-
}
|
|
2321
|
-
const indexPath = path.join(v3Dir, 'reasoning-bank', 'index.json');
|
|
2322
|
-
fs.writeFileSync(indexPath, JSON.stringify({
|
|
2323
|
-
version: '3.0.0',
|
|
2324
|
-
migratedFrom: 'v2',
|
|
2325
|
-
migratedAt: new Date().toISOString(),
|
|
2326
|
-
patternCount: migratedCount,
|
|
2327
|
-
hnswIndexed: false,
|
|
2328
|
-
}, null, 2));
|
|
2329
|
-
console.log(chalk.green(` ✓ ${migratedCount} patterns migrated\n`));
|
|
2330
|
-
}
|
|
2331
|
-
catch (err) {
|
|
2332
|
-
console.log(chalk.red(` ✗ Pattern migration failed: ${err}\n`));
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
else if (options.skipPatterns) {
|
|
2336
|
-
console.log(chalk.yellow('7. Pattern migration skipped\n'));
|
|
2337
|
-
}
|
|
2338
|
-
else {
|
|
2339
|
-
console.log(chalk.gray('7. No patterns to migrate\n'));
|
|
2340
|
-
}
|
|
2341
|
-
// Step 8: Migrate agent names (ADR-048)
|
|
2342
|
-
if ((!options.target || options.target === 'agents') && !options.skipAgents && agentsToMigrate.length > 0) {
|
|
2343
|
-
console.log(chalk.white('8. Migrating agent names (ADR-048)...'));
|
|
2344
|
-
let migratedAgents = 0;
|
|
2345
|
-
const deprecatedDir = path.join(claudeAgentDir, 'deprecated');
|
|
2346
|
-
// Create deprecated directory for old agents
|
|
2347
|
-
if (!fs.existsSync(deprecatedDir)) {
|
|
2348
|
-
fs.mkdirSync(deprecatedDir, { recursive: true });
|
|
2349
|
-
}
|
|
2350
|
-
for (const v2Name of agentsToMigrate) {
|
|
2351
|
-
const v3Name = resolveAgentName(v2Name);
|
|
2352
|
-
const v2FilePath = path.join(claudeAgentDir, `${v2Name}.md`);
|
|
2353
|
-
const v3FilePath = path.join(claudeAgentDir, `${v3Name}.md`);
|
|
2354
|
-
const deprecatedPath = path.join(deprecatedDir, `${v2Name}.md.v2`);
|
|
2355
|
-
try {
|
|
2356
|
-
// Read the original file
|
|
2357
|
-
const content = fs.readFileSync(v2FilePath, 'utf-8');
|
|
2358
|
-
// Parse frontmatter (between first two ---)
|
|
2359
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
2360
|
-
if (!frontmatterMatch) {
|
|
2361
|
-
console.log(chalk.yellow(` ⚠ ${v2Name}: No frontmatter found, skipping`));
|
|
2362
|
-
continue;
|
|
2363
|
-
}
|
|
2364
|
-
const frontmatter = frontmatterMatch[1];
|
|
2365
|
-
const bodyStart = content.indexOf('---', 4) + 4; // After second ---
|
|
2366
|
-
let body = content.slice(bodyStart);
|
|
2367
|
-
// Update frontmatter: change name and add v2_compat
|
|
2368
|
-
let newFrontmatter = frontmatter.replace(/^name:\s*.+$/m, `name: ${v3Name}`);
|
|
2369
|
-
// Add v2_compat field if not present
|
|
2370
|
-
if (!newFrontmatter.includes('v2_compat:')) {
|
|
2371
|
-
newFrontmatter += `\nv2_compat:\n name: ${v2Name}\n deprecated_in: "3.0.0"\n removed_in: "4.0.0"`;
|
|
2372
|
-
}
|
|
2373
|
-
// Update body content: replace old agent name references
|
|
2374
|
-
// Convert kebab-case to Title Case for display names
|
|
2375
|
-
const toTitleCase = (s) => s.replace('qe-', '').split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
2376
|
-
const v2DisplayName = toTitleCase(v2Name);
|
|
2377
|
-
const v3DisplayName = toTitleCase(v3Name);
|
|
2378
|
-
// Replace display names in body (e.g., "Test Generator" → "Test Architect")
|
|
2379
|
-
body = body.replace(new RegExp(v2DisplayName, 'g'), v3DisplayName);
|
|
2380
|
-
// Replace kebab-case references (e.g., "qe-test-generator" → "qe-test-architect")
|
|
2381
|
-
body = body.replace(new RegExp(v2Name, 'g'), v3Name);
|
|
2382
|
-
// Create new content
|
|
2383
|
-
const newContent = `---\n${newFrontmatter}\n---${body}`;
|
|
2384
|
-
// Write new v3 agent file
|
|
2385
|
-
fs.writeFileSync(v3FilePath, newContent, 'utf-8');
|
|
2386
|
-
// Move old file to deprecated folder
|
|
2387
|
-
fs.renameSync(v2FilePath, deprecatedPath);
|
|
2388
|
-
console.log(chalk.gray(` ${v2Name} → ${v3Name}`));
|
|
2389
|
-
migratedAgents++;
|
|
2390
|
-
}
|
|
2391
|
-
catch (err) {
|
|
2392
|
-
console.log(chalk.red(` ✗ ${v2Name}: ${err}`));
|
|
2393
|
-
}
|
|
2394
|
-
}
|
|
2395
|
-
if (migratedAgents > 0) {
|
|
2396
|
-
console.log(chalk.green(` ✓ ${migratedAgents} agents migrated`));
|
|
2397
|
-
console.log(chalk.gray(` Old files archived to: ${deprecatedDir}\n`));
|
|
2398
|
-
}
|
|
2399
|
-
else {
|
|
2400
|
-
console.log(chalk.yellow(' ⚠ No agents were migrated\n'));
|
|
2401
|
-
}
|
|
2402
|
-
}
|
|
2403
|
-
else if (options.skipAgents) {
|
|
2404
|
-
console.log(chalk.yellow('8. Agent migration skipped\n'));
|
|
2405
|
-
}
|
|
2406
|
-
else {
|
|
2407
|
-
console.log(chalk.gray('8. No agents need migration\n'));
|
|
2408
|
-
}
|
|
2409
|
-
// Step 9: Validation
|
|
2410
|
-
console.log(chalk.white('9. Validating migration...'));
|
|
2411
|
-
const validationResults = {
|
|
2412
|
-
v3DirExists: fs.existsSync(v3Dir),
|
|
2413
|
-
configExists: fs.existsSync(path.join(v3Dir, 'config.json')),
|
|
2414
|
-
agentdbExists: fs.existsSync(path.join(v3Dir, 'agentdb')),
|
|
2415
|
-
reasoningBankExists: fs.existsSync(path.join(v3Dir, 'reasoning-bank')),
|
|
2416
|
-
};
|
|
2417
|
-
const allValid = Object.values(validationResults).every(v => v);
|
|
2418
|
-
if (allValid) {
|
|
2419
|
-
console.log(chalk.green(' ✓ Migration validated successfully\n'));
|
|
2420
|
-
}
|
|
2421
|
-
else {
|
|
2422
|
-
console.log(chalk.yellow(' ⚠ Some validations failed:'));
|
|
2423
|
-
for (const [key, value] of Object.entries(validationResults)) {
|
|
2424
|
-
console.log(chalk.gray(` ${key}: ${value ? '✓' : '✗'}`));
|
|
2425
|
-
}
|
|
2426
|
-
}
|
|
2427
|
-
// Summary
|
|
2428
|
-
console.log(chalk.blue('═══════════════════════════════════════════════'));
|
|
2429
|
-
console.log(chalk.green.bold('✅ Migration Complete!\n'));
|
|
2430
|
-
console.log(chalk.white('Next steps:'));
|
|
2431
|
-
console.log(chalk.gray(' 1. Run `aqe migrate verify` to validate'));
|
|
2432
|
-
console.log(chalk.gray(' 2. Run `aqe migrate status` to check'));
|
|
2433
|
-
console.log(chalk.gray(' 3. Use `aqe migrate rollback` if needed\n'));
|
|
2434
|
-
await cleanupAndExit(0);
|
|
2435
|
-
});
|
|
2436
|
-
// migrate status - Check migration status
|
|
2437
|
-
migrateCmd
|
|
2438
|
-
.command('status')
|
|
2439
|
-
.description('Check migration status of current project')
|
|
2440
|
-
.option('--json', 'Output as JSON')
|
|
2441
|
-
.action(async (options) => {
|
|
2442
|
-
const fs = await import('fs');
|
|
2443
|
-
const path = await import('path');
|
|
2444
|
-
const cwd = process.cwd();
|
|
2445
|
-
const v2Dir = path.join(cwd, '.agentic-qe');
|
|
2446
|
-
const v3Dir = path.join(cwd, '.aqe');
|
|
2447
|
-
const claudeAgentDir = path.join(cwd, '.claude', 'agents');
|
|
2448
|
-
const isV2Project = fs.existsSync(v2Dir);
|
|
2449
|
-
const isV3Project = fs.existsSync(v3Dir);
|
|
2450
|
-
// Find agents needing migration
|
|
2451
|
-
const agentsToMigrate = [];
|
|
2452
|
-
const agentsMigrated = [];
|
|
2453
|
-
if (fs.existsSync(claudeAgentDir)) {
|
|
2454
|
-
const files = fs.readdirSync(claudeAgentDir);
|
|
2455
|
-
for (const file of files) {
|
|
2456
|
-
if (file.endsWith('.md') && file.startsWith('qe-')) {
|
|
2457
|
-
const agentName = file.replace('.md', '');
|
|
2458
|
-
if (isDeprecatedAgent(agentName)) {
|
|
2459
|
-
agentsToMigrate.push(agentName);
|
|
2460
|
-
}
|
|
2461
|
-
else if (v3Agents.includes(agentName)) {
|
|
2462
|
-
agentsMigrated.push(agentName);
|
|
2463
|
-
}
|
|
2464
|
-
}
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2467
|
-
const needsMigration = isV2Project && !isV3Project || agentsToMigrate.length > 0;
|
|
2468
|
-
const status = {
|
|
2469
|
-
version: '3.0.0',
|
|
2470
|
-
isV2Project,
|
|
2471
|
-
isV3Project,
|
|
2472
|
-
needsMigration,
|
|
2473
|
-
agentsToMigrate,
|
|
2474
|
-
agentsMigrated,
|
|
2475
|
-
components: [
|
|
2476
|
-
{ name: 'Data Directory', status: isV3Project ? 'migrated' : (isV2Project ? 'pending' : 'not-required') },
|
|
2477
|
-
{ name: 'Agent Names', status: agentsToMigrate.length === 0 ? 'migrated' : 'pending' },
|
|
2478
|
-
],
|
|
2479
|
-
};
|
|
2480
|
-
if (options.json) {
|
|
2481
|
-
console.log(JSON.stringify(status, null, 2));
|
|
2482
|
-
return;
|
|
2483
|
-
}
|
|
2484
|
-
console.log(chalk.bold('\n📊 Migration Status\n'));
|
|
2485
|
-
console.log(`Version: ${chalk.cyan(status.version)}`);
|
|
2486
|
-
console.log(`V2 Project: ${status.isV2Project ? chalk.yellow('Yes') : chalk.dim('No')}`);
|
|
2487
|
-
console.log(`V3 Project: ${status.isV3Project ? chalk.green('Yes') : chalk.dim('No')}`);
|
|
2488
|
-
console.log(`Needs Migration: ${status.needsMigration ? chalk.yellow('Yes') : chalk.green('No')}`);
|
|
2489
|
-
console.log(chalk.bold('\n📦 Components\n'));
|
|
2490
|
-
for (const comp of status.components) {
|
|
2491
|
-
const color = comp.status === 'migrated' ? chalk.green : comp.status === 'pending' ? chalk.yellow : chalk.dim;
|
|
2492
|
-
console.log(` ${comp.name}: ${color(comp.status)}`);
|
|
2493
|
-
}
|
|
2494
|
-
if (agentsToMigrate.length > 0) {
|
|
2495
|
-
console.log(chalk.bold('\n⚠️ Agents Needing Migration\n'));
|
|
2496
|
-
for (const agent of agentsToMigrate) {
|
|
2497
|
-
console.log(` ${chalk.yellow(agent)} → ${chalk.green(resolveAgentName(agent))}`);
|
|
2498
|
-
}
|
|
2499
|
-
}
|
|
2500
|
-
console.log();
|
|
2501
|
-
await cleanupAndExit(0);
|
|
2502
|
-
});
|
|
2503
|
-
// migrate verify - Verify migration
|
|
2504
|
-
migrateCmd
|
|
2505
|
-
.command('verify')
|
|
2506
|
-
.description('Verify migration integrity')
|
|
2507
|
-
.option('--fix', 'Attempt to fix issues automatically')
|
|
2508
|
-
.action(async (options) => {
|
|
2509
|
-
const fs = await import('fs');
|
|
2510
|
-
const path = await import('path');
|
|
2511
|
-
console.log(chalk.bold('\n🔍 Verifying Migration...\n'));
|
|
2512
|
-
const cwd = process.cwd();
|
|
2513
|
-
const v3Dir = path.join(cwd, '.aqe');
|
|
2514
|
-
const claudeAgentDir = path.join(cwd, '.claude', 'agents');
|
|
2515
|
-
// Find deprecated agents still in use
|
|
2516
|
-
const deprecatedInUse = [];
|
|
2517
|
-
if (fs.existsSync(claudeAgentDir)) {
|
|
2518
|
-
const files = fs.readdirSync(claudeAgentDir);
|
|
2519
|
-
for (const file of files) {
|
|
2520
|
-
if (file.endsWith('.md') && file.startsWith('qe-')) {
|
|
2521
|
-
const agentName = file.replace('.md', '');
|
|
2522
|
-
if (isDeprecatedAgent(agentName)) {
|
|
2523
|
-
deprecatedInUse.push(agentName);
|
|
2524
|
-
}
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2528
|
-
const checks = [
|
|
2529
|
-
{
|
|
2530
|
-
name: 'V3 Directory',
|
|
2531
|
-
passed: fs.existsSync(v3Dir),
|
|
2532
|
-
message: fs.existsSync(v3Dir) ? 'Exists' : 'Missing .aqe/',
|
|
2533
|
-
},
|
|
2534
|
-
{
|
|
2535
|
-
name: 'Agent Compatibility',
|
|
2536
|
-
passed: deprecatedInUse.length === 0,
|
|
2537
|
-
message: deprecatedInUse.length === 0 ? 'All agents use v3 names' : `${deprecatedInUse.length} deprecated agents`,
|
|
2538
|
-
},
|
|
2539
|
-
{
|
|
2540
|
-
name: 'Config Format',
|
|
2541
|
-
passed: fs.existsSync(path.join(v3Dir, 'config.json')),
|
|
2542
|
-
message: 'Valid v3 config',
|
|
2543
|
-
},
|
|
2544
|
-
];
|
|
2545
|
-
let allPassed = true;
|
|
2546
|
-
for (const check of checks) {
|
|
2547
|
-
const icon = check.passed ? chalk.green('✓') : chalk.red('✗');
|
|
2548
|
-
const color = check.passed ? chalk.green : chalk.red;
|
|
2549
|
-
console.log(` ${icon} ${check.name}: ${color(check.message)}`);
|
|
2550
|
-
if (!check.passed)
|
|
2551
|
-
allPassed = false;
|
|
2552
|
-
}
|
|
2553
|
-
console.log();
|
|
2554
|
-
if (allPassed) {
|
|
2555
|
-
console.log(chalk.green('✅ All verification checks passed!\n'));
|
|
2556
|
-
}
|
|
2557
|
-
else {
|
|
2558
|
-
console.log(chalk.yellow('⚠️ Some checks failed.'));
|
|
2559
|
-
if (options.fix) {
|
|
2560
|
-
console.log(chalk.dim(' Attempting automatic fixes...\n'));
|
|
2561
|
-
let fixedCount = 0;
|
|
2562
|
-
// Fix 1: Create v3 directory if missing
|
|
2563
|
-
if (!fs.existsSync(v3Dir)) {
|
|
2564
|
-
fs.mkdirSync(v3Dir, { recursive: true });
|
|
2565
|
-
fs.mkdirSync(path.join(v3Dir, 'agentdb'), { recursive: true });
|
|
2566
|
-
fs.mkdirSync(path.join(v3Dir, 'reasoning-bank'), { recursive: true });
|
|
2567
|
-
fs.writeFileSync(path.join(v3Dir, 'config.json'), JSON.stringify({
|
|
2568
|
-
version: '3.0.0',
|
|
2569
|
-
createdAt: new Date().toISOString(),
|
|
2570
|
-
autoCreated: true,
|
|
2571
|
-
}, null, 2));
|
|
2572
|
-
console.log(chalk.green(' ✓ Created .aqe/ directory structure'));
|
|
2573
|
-
fixedCount++;
|
|
2574
|
-
}
|
|
2575
|
-
// Fix 2: Migrate deprecated agents
|
|
2576
|
-
if (deprecatedInUse.length > 0) {
|
|
2577
|
-
const deprecatedDir = path.join(claudeAgentDir, 'deprecated');
|
|
2578
|
-
if (!fs.existsSync(deprecatedDir)) {
|
|
2579
|
-
fs.mkdirSync(deprecatedDir, { recursive: true });
|
|
2580
|
-
}
|
|
2581
|
-
for (const v2Name of deprecatedInUse) {
|
|
2582
|
-
const v3Name = resolveAgentName(v2Name);
|
|
2583
|
-
const v2FilePath = path.join(claudeAgentDir, `${v2Name}.md`);
|
|
2584
|
-
const v3FilePath = path.join(claudeAgentDir, `${v3Name}.md`);
|
|
2585
|
-
const deprecatedPath = path.join(deprecatedDir, `${v2Name}.md.v2`);
|
|
2586
|
-
try {
|
|
2587
|
-
const content = fs.readFileSync(v2FilePath, 'utf-8');
|
|
2588
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
2589
|
-
if (frontmatterMatch) {
|
|
2590
|
-
const frontmatter = frontmatterMatch[1];
|
|
2591
|
-
const bodyStart = content.indexOf('---', 4) + 4;
|
|
2592
|
-
let body = content.slice(bodyStart);
|
|
2593
|
-
let newFrontmatter = frontmatter.replace(/^name:\s*.+$/m, `name: ${v3Name}`);
|
|
2594
|
-
if (!newFrontmatter.includes('v2_compat:')) {
|
|
2595
|
-
newFrontmatter += `\nv2_compat:\n name: ${v2Name}\n deprecated_in: "3.0.0"\n removed_in: "4.0.0"`;
|
|
2596
|
-
}
|
|
2597
|
-
// Update body content: replace old agent name references
|
|
2598
|
-
const toTitleCase = (s) => s.replace('qe-', '').split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
2599
|
-
body = body.replace(new RegExp(toTitleCase(v2Name), 'g'), toTitleCase(v3Name));
|
|
2600
|
-
body = body.replace(new RegExp(v2Name, 'g'), v3Name);
|
|
2601
|
-
const newContent = `---\n${newFrontmatter}\n---${body}`;
|
|
2602
|
-
fs.writeFileSync(v3FilePath, newContent, 'utf-8');
|
|
2603
|
-
fs.renameSync(v2FilePath, deprecatedPath);
|
|
2604
|
-
console.log(chalk.green(` ✓ Migrated ${v2Name} → ${v3Name}`));
|
|
2605
|
-
fixedCount++;
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
catch (err) {
|
|
2609
|
-
console.log(chalk.red(` ✗ Failed to migrate ${v2Name}: ${err}`));
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2612
|
-
}
|
|
2613
|
-
if (fixedCount > 0) {
|
|
2614
|
-
console.log(chalk.green(`\n✅ Applied ${fixedCount} fixes. Re-run 'aqe migrate verify' to confirm.\n`));
|
|
2615
|
-
}
|
|
2616
|
-
else {
|
|
2617
|
-
console.log(chalk.yellow('\n⚠️ No automatic fixes available for remaining issues.\n'));
|
|
2618
|
-
}
|
|
2619
|
-
}
|
|
2620
|
-
else {
|
|
2621
|
-
console.log(chalk.dim(' Run with --fix to attempt fixes.\n'));
|
|
2622
|
-
}
|
|
2623
|
-
}
|
|
2624
|
-
await cleanupAndExit(0);
|
|
2625
|
-
});
|
|
2626
|
-
// migrate rollback - Rollback migration
|
|
2627
|
-
migrateCmd
|
|
2628
|
-
.command('rollback')
|
|
2629
|
-
.description('Rollback to previous version from backup')
|
|
2630
|
-
.option('--backup-id <id>', 'Specific backup to restore')
|
|
2631
|
-
.option('--force', 'Skip confirmation')
|
|
2632
|
-
.action(async (options) => {
|
|
2633
|
-
const fs = await import('fs');
|
|
2634
|
-
const path = await import('path');
|
|
2635
|
-
const cwd = process.cwd();
|
|
2636
|
-
const backupRoot = path.join(cwd, '.aqe-backup');
|
|
2637
|
-
if (!fs.existsSync(backupRoot)) {
|
|
2638
|
-
console.log(chalk.yellow('\n⚠️ No backups found.\n'));
|
|
2639
|
-
return;
|
|
2640
|
-
}
|
|
2641
|
-
const backups = fs.readdirSync(backupRoot)
|
|
2642
|
-
.filter(f => f.startsWith('backup-'))
|
|
2643
|
-
.sort()
|
|
2644
|
-
.reverse();
|
|
2645
|
-
if (backups.length === 0) {
|
|
2646
|
-
console.log(chalk.yellow('\n⚠️ No backups found.\n'));
|
|
2647
|
-
return;
|
|
2648
|
-
}
|
|
2649
|
-
console.log(chalk.bold('\n📦 Available Backups\n'));
|
|
2650
|
-
for (const backup of backups.slice(0, 5)) {
|
|
2651
|
-
const timestamp = backup.replace('backup-', '');
|
|
2652
|
-
const date = new Date(parseInt(timestamp));
|
|
2653
|
-
console.log(` ${chalk.cyan(backup)} - ${date.toLocaleString()}`);
|
|
2654
|
-
}
|
|
2655
|
-
const targetBackup = options.backupId || backups[0];
|
|
2656
|
-
const backupPath = path.join(backupRoot, targetBackup);
|
|
2657
|
-
if (!fs.existsSync(backupPath)) {
|
|
2658
|
-
console.log(chalk.red(`\n❌ Backup not found: ${targetBackup}\n`));
|
|
2659
|
-
await cleanupAndExit(1);
|
|
2660
|
-
}
|
|
2661
|
-
if (!options.force) {
|
|
2662
|
-
console.log(chalk.yellow(`\n⚠️ This will restore from: ${targetBackup}`));
|
|
2663
|
-
console.log(chalk.dim(' Run with --force to confirm.\n'));
|
|
2664
|
-
return;
|
|
2665
|
-
}
|
|
2666
|
-
console.log(chalk.bold(`\n🔄 Rolling back to ${targetBackup}...\n`));
|
|
2667
|
-
// Restore backup
|
|
2668
|
-
const v2Backup = path.join(backupPath, '.agentic-qe');
|
|
2669
|
-
const agentsBackup = path.join(backupPath, '.claude', 'agents');
|
|
2670
|
-
if (fs.existsSync(v2Backup)) {
|
|
2671
|
-
const v2Dir = path.join(cwd, '.agentic-qe');
|
|
2672
|
-
fs.cpSync(v2Backup, v2Dir, { recursive: true });
|
|
2673
|
-
console.log(chalk.dim(' Restored .agentic-qe/'));
|
|
2674
|
-
}
|
|
2675
|
-
if (fs.existsSync(agentsBackup)) {
|
|
2676
|
-
const agentsDir = path.join(cwd, '.claude', 'agents');
|
|
2677
|
-
fs.cpSync(agentsBackup, agentsDir, { recursive: true });
|
|
2678
|
-
console.log(chalk.dim(' Restored .claude/agents/'));
|
|
2679
|
-
}
|
|
2680
|
-
// Remove v3 directory
|
|
2681
|
-
const v3Dir = path.join(cwd, '.aqe');
|
|
2682
|
-
if (fs.existsSync(v3Dir)) {
|
|
2683
|
-
fs.rmSync(v3Dir, { recursive: true, force: true });
|
|
2684
|
-
console.log(chalk.dim(' Removed .aqe/'));
|
|
2685
|
-
}
|
|
2686
|
-
console.log(chalk.green('\n✅ Rollback complete!\n'));
|
|
2687
|
-
await cleanupAndExit(0);
|
|
2688
|
-
});
|
|
2689
|
-
// migrate mapping - Show agent name mappings
|
|
2690
|
-
migrateCmd
|
|
2691
|
-
.command('mapping')
|
|
2692
|
-
.description('Show v2 to v3 agent name mappings (ADR-048)')
|
|
2693
|
-
.option('--json', 'Output as JSON')
|
|
2694
|
-
.action(async (options) => {
|
|
2695
|
-
if (options.json) {
|
|
2696
|
-
console.log(JSON.stringify(v2AgentMapping, null, 2));
|
|
2697
|
-
return;
|
|
2698
|
-
}
|
|
2699
|
-
console.log(chalk.bold('\n🔄 Agent Name Mappings (V2 → V3)\n'));
|
|
2700
|
-
const entries = Object.entries(v2AgentMapping);
|
|
2701
|
-
for (const [v2Name, v3Name] of entries) {
|
|
2702
|
-
console.log(` ${chalk.yellow(v2Name)} → ${chalk.green(v3Name)}`);
|
|
2703
|
-
}
|
|
2704
|
-
console.log(chalk.dim(`\n Total: ${entries.length} mappings\n`));
|
|
2705
|
-
console.log(chalk.gray(' See ADR-048 for full migration strategy.\n'));
|
|
2706
|
-
await cleanupAndExit(0);
|
|
2707
|
-
});
|
|
2708
|
-
// ============================================================================
|
|
2709
|
-
// Completions Command
|
|
2710
|
-
// ============================================================================
|
|
2711
|
-
const completionsCmd = program
|
|
2712
|
-
.command('completions')
|
|
2713
|
-
.description('Generate shell completions for aqe');
|
|
2714
|
-
completionsCmd
|
|
2715
|
-
.command('bash')
|
|
2716
|
-
.description('Generate Bash completion script')
|
|
2717
|
-
.action(() => {
|
|
2718
|
-
console.log(generateCompletion('bash'));
|
|
2719
|
-
});
|
|
2720
|
-
completionsCmd
|
|
2721
|
-
.command('zsh')
|
|
2722
|
-
.description('Generate Zsh completion script')
|
|
2723
|
-
.action(() => {
|
|
2724
|
-
console.log(generateCompletion('zsh'));
|
|
2725
|
-
});
|
|
2726
|
-
completionsCmd
|
|
2727
|
-
.command('fish')
|
|
2728
|
-
.description('Generate Fish completion script')
|
|
2729
|
-
.action(() => {
|
|
2730
|
-
console.log(generateCompletion('fish'));
|
|
2731
|
-
});
|
|
2732
|
-
completionsCmd
|
|
2733
|
-
.command('powershell')
|
|
2734
|
-
.description('Generate PowerShell completion script')
|
|
2735
|
-
.action(() => {
|
|
2736
|
-
console.log(generateCompletion('powershell'));
|
|
2737
|
-
});
|
|
2738
|
-
completionsCmd
|
|
2739
|
-
.command('install')
|
|
2740
|
-
.description('Auto-install completions for current shell')
|
|
2741
|
-
.option('-s, --shell <shell>', 'Target shell (bash|zsh|fish|powershell)')
|
|
2742
|
-
.action(async (options) => {
|
|
2743
|
-
const fs = await import('fs');
|
|
2744
|
-
const path = await import('path');
|
|
2745
|
-
const shellInfo = options.shell
|
|
2746
|
-
? { name: options.shell, configFile: null, detected: false }
|
|
2747
|
-
: detectShell();
|
|
2748
|
-
if (shellInfo.name === 'unknown') {
|
|
2749
|
-
console.log(chalk.red('Could not detect shell. Please specify with --shell option.\n'));
|
|
2750
|
-
console.log(getInstallInstructions('unknown'));
|
|
2751
|
-
await cleanupAndExit(1);
|
|
2752
|
-
return; // TypeScript flow control hint - cleanupAndExit exits but TS doesn't know
|
|
2753
|
-
}
|
|
2754
|
-
console.log(chalk.blue(`\nInstalling completions for ${shellInfo.name}...\n`));
|
|
2755
|
-
const script = generateCompletion(shellInfo.name);
|
|
2756
|
-
// For Fish, write directly to completions directory
|
|
2757
|
-
if (shellInfo.name === 'fish') {
|
|
2758
|
-
const fishCompletionsDir = `${process.env.HOME}/.config/fish/completions`;
|
|
2759
|
-
try {
|
|
2760
|
-
fs.mkdirSync(fishCompletionsDir, { recursive: true });
|
|
2761
|
-
const completionFile = path.join(fishCompletionsDir, 'aqe.fish');
|
|
2762
|
-
fs.writeFileSync(completionFile, script);
|
|
2763
|
-
console.log(chalk.green(`Completions installed to: ${completionFile}`));
|
|
2764
|
-
console.log(chalk.gray('\nRestart your shell or run: source ~/.config/fish/completions/aqe.fish\n'));
|
|
2765
|
-
}
|
|
2766
|
-
catch (err) {
|
|
2767
|
-
console.log(chalk.red(`Failed to install: ${err}`));
|
|
2768
|
-
console.log(chalk.yellow('\nManual installation:'));
|
|
2769
|
-
console.log(getInstallInstructions('fish'));
|
|
2770
|
-
}
|
|
2771
|
-
}
|
|
2772
|
-
else {
|
|
2773
|
-
// For other shells, show instructions
|
|
2774
|
-
console.log(chalk.yellow('To install completions, follow these instructions:\n'));
|
|
2775
|
-
console.log(getInstallInstructions(shellInfo.name));
|
|
2776
|
-
console.log(chalk.gray('\n---\nCompletion script:\n'));
|
|
2777
|
-
console.log(script);
|
|
2778
|
-
}
|
|
2779
|
-
});
|
|
2780
|
-
completionsCmd
|
|
2781
|
-
.command('list')
|
|
2782
|
-
.description('List all completion values (domains, agents, etc.)')
|
|
2783
|
-
.option('-t, --type <type>', 'Type to list (domains|agents|v3-qe-agents)', 'all')
|
|
2784
|
-
.action((options) => {
|
|
2785
|
-
if (options.type === 'domains' || options.type === 'all') {
|
|
2786
|
-
console.log(chalk.blue('\n12 DDD Domains:'));
|
|
2787
|
-
COMPLETION_DOMAINS.forEach(d => console.log(chalk.gray(` ${d}`)));
|
|
2788
|
-
}
|
|
2789
|
-
if (options.type === 'v3-qe-agents' || options.type === 'all') {
|
|
2790
|
-
console.log(chalk.blue('\nQE Agents (' + QE_AGENTS.length + '):'));
|
|
2791
|
-
QE_AGENTS.forEach(a => console.log(chalk.gray(` ${a}`)));
|
|
2792
|
-
}
|
|
2793
|
-
if (options.type === 'agents' || options.type === 'all') {
|
|
2794
|
-
console.log(chalk.blue('\nOther Agents (' + OTHER_AGENTS.length + '):'));
|
|
2795
|
-
OTHER_AGENTS.forEach(a => console.log(chalk.gray(` ${a}`)));
|
|
2796
|
-
}
|
|
2797
|
-
console.log('');
|
|
2798
|
-
});
|
|
605
|
+
import { createTestCommand } from './commands/test.js';
|
|
606
|
+
import { createCoverageCommand } from './commands/coverage.js';
|
|
607
|
+
import { createQualityCommand } from './commands/quality.js';
|
|
608
|
+
import { createSecurityCommand } from './commands/security.js';
|
|
609
|
+
import { createCodeCommand } from './commands/code.js';
|
|
610
|
+
import { createMigrateCommand } from './commands/migrate.js';
|
|
611
|
+
import { createCompletionsCommand } from './commands/completions.js';
|
|
612
|
+
import { createFleetCommand } from './commands/fleet.js';
|
|
613
|
+
// Register shortcut commands
|
|
614
|
+
program.addCommand(createTestCommand(context, cleanupAndExit, ensureInitialized));
|
|
615
|
+
program.addCommand(createCoverageCommand(context, cleanupAndExit, ensureInitialized));
|
|
616
|
+
program.addCommand(createQualityCommand(context, cleanupAndExit, ensureInitialized));
|
|
617
|
+
program.addCommand(createSecurityCommand(context, cleanupAndExit, ensureInitialized));
|
|
618
|
+
program.addCommand(createCodeCommand(context, cleanupAndExit, ensureInitialized));
|
|
619
|
+
program.addCommand(createMigrateCommand(context, cleanupAndExit, ensureInitialized));
|
|
620
|
+
program.addCommand(createCompletionsCommand(cleanupAndExit));
|
|
621
|
+
program.addCommand(createFleetCommand(context, cleanupAndExit, ensureInitialized, registerDomainWorkflowActions));
|
|
2799
622
|
// ============================================================================
|
|
2800
|
-
//
|
|
2801
|
-
// ============================================================================
|
|
2802
|
-
const fleetCmd = program
|
|
2803
|
-
.command('fleet')
|
|
2804
|
-
.description('Fleet operations with multi-agent progress tracking');
|
|
2805
|
-
// Fleet init with wizard (ADR-041)
|
|
2806
|
-
fleetCmd
|
|
2807
|
-
.command('init')
|
|
2808
|
-
.description('Initialize fleet with interactive wizard')
|
|
2809
|
-
.option('--wizard', 'Run interactive fleet initialization wizard')
|
|
2810
|
-
.option('-t, --topology <type>', 'Fleet topology (hierarchical|mesh|ring|adaptive|hierarchical-mesh)', 'hierarchical-mesh')
|
|
2811
|
-
.option('-m, --max-agents <count>', 'Maximum agent count (5-50)', '15')
|
|
2812
|
-
.option('-d, --domains <domains>', 'Domains to enable (comma-separated or "all")', 'all')
|
|
2813
|
-
.option('--memory <backend>', 'Memory backend (sqlite|agentdb|hybrid)', 'hybrid')
|
|
2814
|
-
.option('--lazy', 'Enable lazy loading', true)
|
|
2815
|
-
.option('--skip-patterns', 'Skip loading pre-trained patterns')
|
|
2816
|
-
.option('--skip-code-scan', 'Skip code intelligence index check')
|
|
2817
|
-
.action(async (options) => {
|
|
2818
|
-
try {
|
|
2819
|
-
let topology = options.topology;
|
|
2820
|
-
let maxAgents = parseInt(options.maxAgents, 10);
|
|
2821
|
-
let domains = options.domains;
|
|
2822
|
-
let memoryBackend = options.memory;
|
|
2823
|
-
let lazyLoading = options.lazy;
|
|
2824
|
-
let loadPatterns = !options.skipPatterns;
|
|
2825
|
-
// CI-005: Check code intelligence index before fleet initialization
|
|
2826
|
-
console.log(chalk.blue('\n 🧠 Code Intelligence Check\n'));
|
|
2827
|
-
const ciResult = await integrateCodeIntelligence(process.cwd(), {
|
|
2828
|
-
skipCodeScan: options.skipCodeScan,
|
|
2829
|
-
nonInteractive: !options.wizard, // Only prompt in wizard mode
|
|
2830
|
-
});
|
|
2831
|
-
// If user requested scan, exit and let them run it
|
|
2832
|
-
if (!ciResult.shouldProceed) {
|
|
2833
|
-
console.log(chalk.blue('\n Please run the code intelligence scan first:'));
|
|
2834
|
-
console.log(chalk.cyan(' aqe code-intelligence index\n'));
|
|
2835
|
-
console.log(chalk.gray(' Then re-run fleet init when ready.\n'));
|
|
2836
|
-
await cleanupAndExit(0);
|
|
2837
|
-
return;
|
|
2838
|
-
}
|
|
2839
|
-
// Run wizard if requested (ADR-041)
|
|
2840
|
-
if (options.wizard) {
|
|
2841
|
-
console.log(chalk.blue('\n🚀 Fleet Initialization Wizard\n'));
|
|
2842
|
-
const wizardResult = await runFleetInitWizard({
|
|
2843
|
-
defaultTopology: options.topology !== 'hierarchical-mesh' ? options.topology : undefined,
|
|
2844
|
-
defaultMaxAgents: options.maxAgents !== '15' ? parseInt(options.maxAgents, 10) : undefined,
|
|
2845
|
-
defaultDomains: options.domains !== 'all' ? options.domains.split(',') : undefined,
|
|
2846
|
-
defaultMemoryBackend: options.memory !== 'hybrid' ? options.memory : undefined,
|
|
2847
|
-
});
|
|
2848
|
-
if (wizardResult.cancelled) {
|
|
2849
|
-
console.log(chalk.yellow('\n Fleet initialization cancelled.\n'));
|
|
2850
|
-
await cleanupAndExit(0);
|
|
2851
|
-
}
|
|
2852
|
-
// Use wizard results
|
|
2853
|
-
topology = wizardResult.topology;
|
|
2854
|
-
maxAgents = wizardResult.maxAgents;
|
|
2855
|
-
domains = wizardResult.domains.join(',');
|
|
2856
|
-
memoryBackend = wizardResult.memoryBackend;
|
|
2857
|
-
lazyLoading = wizardResult.lazyLoading;
|
|
2858
|
-
loadPatterns = wizardResult.loadPatterns;
|
|
2859
|
-
console.log(chalk.green('\n Starting fleet initialization...\n'));
|
|
2860
|
-
}
|
|
2861
|
-
// Parse domains
|
|
2862
|
-
const enabledDomains = domains === 'all'
|
|
2863
|
-
? [...ALL_DOMAINS]
|
|
2864
|
-
: domains.split(',').filter((d) => ALL_DOMAINS.includes(d));
|
|
2865
|
-
console.log(chalk.blue('\n Fleet Configuration\n'));
|
|
2866
|
-
console.log(chalk.gray(` Topology: ${topology}`));
|
|
2867
|
-
console.log(chalk.gray(` Max Agents: ${maxAgents}`));
|
|
2868
|
-
console.log(chalk.gray(` Domains: ${enabledDomains.length}`));
|
|
2869
|
-
console.log(chalk.gray(` Memory: ${memoryBackend}`));
|
|
2870
|
-
console.log(chalk.gray(` Lazy Loading: ${lazyLoading ? 'enabled' : 'disabled'}`));
|
|
2871
|
-
console.log(chalk.gray(` Pre-trained Patterns: ${loadPatterns ? 'load' : 'skip'}\n`));
|
|
2872
|
-
// Initialize if not already done
|
|
2873
|
-
if (!context.initialized) {
|
|
2874
|
-
context.kernel = new QEKernelImpl({
|
|
2875
|
-
maxConcurrentAgents: maxAgents,
|
|
2876
|
-
memoryBackend,
|
|
2877
|
-
hnswEnabled: true,
|
|
2878
|
-
lazyLoading,
|
|
2879
|
-
enabledDomains,
|
|
2880
|
-
});
|
|
2881
|
-
await context.kernel.initialize();
|
|
2882
|
-
console.log(chalk.green(' ✓ Kernel initialized'));
|
|
2883
|
-
context.router = new CrossDomainEventRouter(context.kernel.eventBus);
|
|
2884
|
-
await context.router.initialize();
|
|
2885
|
-
console.log(chalk.green(' ✓ Cross-domain router initialized'));
|
|
2886
|
-
context.workflowOrchestrator = new WorkflowOrchestrator(context.kernel.eventBus, context.kernel.memory, context.kernel.coordinator);
|
|
2887
|
-
await context.workflowOrchestrator.initialize();
|
|
2888
|
-
console.log(chalk.green(' ✓ Workflow orchestrator initialized'));
|
|
2889
|
-
context.persistentScheduler = createPersistentScheduler();
|
|
2890
|
-
console.log(chalk.green(' ✓ Persistent scheduler initialized'));
|
|
2891
|
-
const getDomainAPI = (domain) => {
|
|
2892
|
-
return context.kernel.getDomainAPI(domain);
|
|
2893
|
-
};
|
|
2894
|
-
const protocolExecutor = new DefaultProtocolExecutor(context.kernel.eventBus, context.kernel.memory, getDomainAPI);
|
|
2895
|
-
context.queen = createQueenCoordinator(context.kernel, context.router, protocolExecutor, undefined);
|
|
2896
|
-
await context.queen.initialize();
|
|
2897
|
-
console.log(chalk.green(' ✓ Queen coordinator initialized'));
|
|
2898
|
-
context.initialized = true;
|
|
2899
|
-
}
|
|
2900
|
-
console.log(chalk.green('\n✅ Fleet initialized successfully!\n'));
|
|
2901
|
-
console.log(chalk.white('Next steps:'));
|
|
2902
|
-
console.log(chalk.gray(' 1. Spawn agents: aqe fleet spawn --domains test-generation'));
|
|
2903
|
-
console.log(chalk.gray(' 2. Run operation: aqe fleet run test --target ./src'));
|
|
2904
|
-
console.log(chalk.gray(' 3. Check status: aqe fleet status\n'));
|
|
2905
|
-
await cleanupAndExit(0);
|
|
2906
|
-
}
|
|
2907
|
-
catch (error) {
|
|
2908
|
-
console.error(chalk.red('\n Fleet initialization failed:'), error);
|
|
2909
|
-
await cleanupAndExit(1);
|
|
2910
|
-
}
|
|
2911
|
-
});
|
|
2912
|
-
fleetCmd
|
|
2913
|
-
.command('spawn')
|
|
2914
|
-
.description('Spawn multiple agents with progress tracking')
|
|
2915
|
-
.option('-d, --domains <domains>', 'Comma-separated domains', 'test-generation,coverage-analysis')
|
|
2916
|
-
.option('-t, --type <type>', 'Agent type for all', 'worker')
|
|
2917
|
-
.option('-c, --count <count>', 'Number of agents per domain', '1')
|
|
2918
|
-
.action(async (options) => {
|
|
2919
|
-
if (!await ensureInitialized())
|
|
2920
|
-
return;
|
|
2921
|
-
try {
|
|
2922
|
-
const domains = options.domains.split(',');
|
|
2923
|
-
const countPerDomain = parseInt(options.count, 10);
|
|
2924
|
-
console.log(chalk.blue('\n Fleet Spawn Operation\n'));
|
|
2925
|
-
// Create fleet progress manager
|
|
2926
|
-
const progress = new FleetProgressManager({
|
|
2927
|
-
title: 'Agent Spawn Progress',
|
|
2928
|
-
showEta: true,
|
|
2929
|
-
});
|
|
2930
|
-
const totalAgents = domains.length * countPerDomain;
|
|
2931
|
-
progress.start(totalAgents);
|
|
2932
|
-
// Track spawned agents
|
|
2933
|
-
const spawnedAgents = [];
|
|
2934
|
-
let agentIndex = 0;
|
|
2935
|
-
// Spawn agents across domains
|
|
2936
|
-
for (const domain of domains) {
|
|
2937
|
-
for (let i = 0; i < countPerDomain; i++) {
|
|
2938
|
-
const agentName = `${domain}-${options.type}-${i + 1}`;
|
|
2939
|
-
const agentId = `agent-${agentIndex++}`;
|
|
2940
|
-
// Add agent to progress tracker
|
|
2941
|
-
progress.addAgent({
|
|
2942
|
-
id: agentId,
|
|
2943
|
-
name: agentName,
|
|
2944
|
-
status: 'pending',
|
|
2945
|
-
progress: 0,
|
|
2946
|
-
});
|
|
2947
|
-
// Update to running
|
|
2948
|
-
progress.updateAgent(agentId, 10, { status: 'running' });
|
|
2949
|
-
try {
|
|
2950
|
-
// Spawn the agent
|
|
2951
|
-
progress.updateAgent(agentId, 30, { message: 'Initializing...' });
|
|
2952
|
-
const result = await context.queen.requestAgentSpawn(domain, options.type, ['general']);
|
|
2953
|
-
progress.updateAgent(agentId, 80, { message: 'Configuring...' });
|
|
2954
|
-
if (result.success) {
|
|
2955
|
-
progress.completeAgent(agentId, true);
|
|
2956
|
-
spawnedAgents.push({ id: result.value, domain, success: true });
|
|
2957
|
-
}
|
|
2958
|
-
else {
|
|
2959
|
-
progress.completeAgent(agentId, false);
|
|
2960
|
-
spawnedAgents.push({ id: agentId, domain, success: false });
|
|
2961
|
-
}
|
|
2962
|
-
}
|
|
2963
|
-
catch {
|
|
2964
|
-
progress.completeAgent(agentId, false);
|
|
2965
|
-
spawnedAgents.push({ id: agentId, domain, success: false });
|
|
2966
|
-
}
|
|
2967
|
-
}
|
|
2968
|
-
}
|
|
2969
|
-
progress.stop();
|
|
2970
|
-
// Summary
|
|
2971
|
-
const successful = spawnedAgents.filter(a => a.success).length;
|
|
2972
|
-
const failed = spawnedAgents.filter(a => !a.success).length;
|
|
2973
|
-
console.log(chalk.blue('\n Fleet Summary:'));
|
|
2974
|
-
console.log(chalk.gray(` Domains: ${domains.join(', ')}`));
|
|
2975
|
-
console.log(chalk.green(` Successful: ${successful}`));
|
|
2976
|
-
if (failed > 0) {
|
|
2977
|
-
console.log(chalk.red(` Failed: ${failed}`));
|
|
2978
|
-
}
|
|
2979
|
-
console.log('');
|
|
2980
|
-
await cleanupAndExit(failed > 0 ? 1 : 0);
|
|
2981
|
-
}
|
|
2982
|
-
catch (error) {
|
|
2983
|
-
console.error(chalk.red('\n Fleet spawn failed:'), error);
|
|
2984
|
-
await cleanupAndExit(1);
|
|
2985
|
-
}
|
|
2986
|
-
});
|
|
2987
|
-
fleetCmd
|
|
2988
|
-
.command('run')
|
|
2989
|
-
.description('Run a coordinated fleet operation')
|
|
2990
|
-
.argument('<operation>', 'Operation type (test|analyze|scan)')
|
|
2991
|
-
.option('-t, --target <path>', 'Target path', '.')
|
|
2992
|
-
.option('--parallel <count>', 'Number of parallel agents', '4')
|
|
2993
|
-
.action(async (operation, options) => {
|
|
2994
|
-
if (!await ensureInitialized())
|
|
2995
|
-
return;
|
|
2996
|
-
try {
|
|
2997
|
-
const parallelCount = parseInt(options.parallel, 10);
|
|
2998
|
-
console.log(chalk.blue(`\n Fleet Operation: ${operation}\n`));
|
|
2999
|
-
// Create fleet progress manager
|
|
3000
|
-
const progress = new FleetProgressManager({
|
|
3001
|
-
title: `${operation.charAt(0).toUpperCase() + operation.slice(1)} Progress`,
|
|
3002
|
-
showEta: true,
|
|
3003
|
-
});
|
|
3004
|
-
progress.start(parallelCount);
|
|
3005
|
-
// Define agent operations based on operation type
|
|
3006
|
-
const domainMap = {
|
|
3007
|
-
test: 'test-generation',
|
|
3008
|
-
analyze: 'coverage-analysis',
|
|
3009
|
-
scan: 'security-compliance',
|
|
3010
|
-
};
|
|
3011
|
-
const domain = domainMap[operation] || 'test-generation';
|
|
3012
|
-
// Create parallel agent operations
|
|
3013
|
-
const agentOperations = Array.from({ length: parallelCount }, (_, i) => {
|
|
3014
|
-
const agentId = `${operation}-agent-${i + 1}`;
|
|
3015
|
-
return {
|
|
3016
|
-
id: agentId,
|
|
3017
|
-
name: `${operation}-worker-${i + 1}`,
|
|
3018
|
-
domain,
|
|
3019
|
-
};
|
|
3020
|
-
});
|
|
3021
|
-
// Add all agents to progress
|
|
3022
|
-
for (const op of agentOperations) {
|
|
3023
|
-
progress.addAgent({
|
|
3024
|
-
id: op.id,
|
|
3025
|
-
name: op.name,
|
|
3026
|
-
status: 'pending',
|
|
3027
|
-
progress: 0,
|
|
3028
|
-
});
|
|
3029
|
-
}
|
|
3030
|
-
// Execute operations in parallel with progress updates
|
|
3031
|
-
const results = await Promise.all(agentOperations.map(async (op, index) => {
|
|
3032
|
-
// Simulate staggered start
|
|
3033
|
-
await new Promise(resolve => setTimeout(resolve, index * 200));
|
|
3034
|
-
progress.updateAgent(op.id, 0, { status: 'running' });
|
|
3035
|
-
try {
|
|
3036
|
-
// Simulate operation phases with progress updates
|
|
3037
|
-
for (let p = 10; p <= 90; p += 20) {
|
|
3038
|
-
await new Promise(resolve => setTimeout(resolve, 300 + Math.random() * 200));
|
|
3039
|
-
progress.updateAgent(op.id, p, {
|
|
3040
|
-
eta: Math.round((100 - p) * 50),
|
|
3041
|
-
});
|
|
3042
|
-
}
|
|
3043
|
-
// Submit actual task
|
|
3044
|
-
const taskResult = await context.queen.submitTask({
|
|
3045
|
-
type: operation === 'test' ? 'generate-tests' :
|
|
3046
|
-
operation === 'analyze' ? 'analyze-coverage' :
|
|
3047
|
-
'scan-security',
|
|
3048
|
-
priority: 'p1',
|
|
3049
|
-
targetDomains: [domain],
|
|
3050
|
-
payload: { target: options.target, workerId: op.id },
|
|
3051
|
-
timeout: 60000,
|
|
3052
|
-
});
|
|
3053
|
-
progress.completeAgent(op.id, taskResult.success);
|
|
3054
|
-
return { id: op.id, success: taskResult.success };
|
|
3055
|
-
}
|
|
3056
|
-
catch {
|
|
3057
|
-
progress.completeAgent(op.id, false);
|
|
3058
|
-
return { id: op.id, success: false };
|
|
3059
|
-
}
|
|
3060
|
-
}));
|
|
3061
|
-
progress.stop();
|
|
3062
|
-
// Summary
|
|
3063
|
-
const successful = results.filter(r => r.success).length;
|
|
3064
|
-
const failed = results.filter(r => !r.success).length;
|
|
3065
|
-
console.log(chalk.blue('\n Operation Summary:'));
|
|
3066
|
-
console.log(chalk.gray(` Operation: ${operation}`));
|
|
3067
|
-
console.log(chalk.gray(` Target: ${options.target}`));
|
|
3068
|
-
console.log(chalk.green(` Successful: ${successful}`));
|
|
3069
|
-
if (failed > 0) {
|
|
3070
|
-
console.log(chalk.red(` Failed: ${failed}`));
|
|
3071
|
-
}
|
|
3072
|
-
console.log('');
|
|
3073
|
-
await cleanupAndExit(failed > 0 ? 1 : 0);
|
|
3074
|
-
}
|
|
3075
|
-
catch (error) {
|
|
3076
|
-
console.error(chalk.red('\n Fleet operation failed:'), error);
|
|
3077
|
-
await cleanupAndExit(1);
|
|
3078
|
-
}
|
|
3079
|
-
});
|
|
3080
|
-
fleetCmd
|
|
3081
|
-
.command('status')
|
|
3082
|
-
.description('Show fleet status with agent progress')
|
|
3083
|
-
.option('-w, --watch', 'Watch mode with live updates')
|
|
3084
|
-
.action(async (options) => {
|
|
3085
|
-
if (!await ensureInitialized())
|
|
3086
|
-
return;
|
|
3087
|
-
try {
|
|
3088
|
-
const showStatus = async () => {
|
|
3089
|
-
const health = context.queen.getHealth();
|
|
3090
|
-
const metrics = context.queen.getMetrics();
|
|
3091
|
-
console.log(chalk.blue('\n Fleet Status\n'));
|
|
3092
|
-
// Overall fleet bar
|
|
3093
|
-
const utilizationBar = '\u2588'.repeat(Math.min(Math.round(metrics.agentUtilization * 20), 20)) +
|
|
3094
|
-
'\u2591'.repeat(Math.max(20 - Math.round(metrics.agentUtilization * 20), 0));
|
|
3095
|
-
console.log(chalk.white(`Fleet Utilization ${chalk.cyan(utilizationBar)} ${(metrics.agentUtilization * 100).toFixed(0)}%`));
|
|
3096
|
-
console.log('');
|
|
3097
|
-
// Agent status by domain
|
|
3098
|
-
console.log(chalk.white('Agent Progress:'));
|
|
3099
|
-
for (const [domain, domainHealth] of health.domainHealth) {
|
|
3100
|
-
const active = domainHealth.agents.active;
|
|
3101
|
-
const total = domainHealth.agents.total;
|
|
3102
|
-
const progressPercent = total > 0 ? Math.round((active / total) * 100) : 0;
|
|
3103
|
-
const statusIcon = domainHealth.status === 'healthy' ? chalk.green('\u2713') :
|
|
3104
|
-
domainHealth.status === 'degraded' ? chalk.yellow('\u25B6') :
|
|
3105
|
-
chalk.red('\u2717');
|
|
3106
|
-
const bar = '\u2588'.repeat(Math.round(progressPercent / 5)) +
|
|
3107
|
-
'\u2591'.repeat(20 - Math.round(progressPercent / 5));
|
|
3108
|
-
console.log(` ${domain.padEnd(28)} ${chalk.cyan(bar)} ${progressPercent.toString().padStart(3)}% ${statusIcon}`);
|
|
3109
|
-
}
|
|
3110
|
-
console.log('');
|
|
3111
|
-
console.log(chalk.gray(` Active: ${health.activeAgents}/${health.totalAgents} agents`));
|
|
3112
|
-
console.log(chalk.gray(` Tasks: ${health.runningTasks} running, ${health.pendingTasks} pending`));
|
|
3113
|
-
console.log('');
|
|
3114
|
-
};
|
|
3115
|
-
if (options.watch) {
|
|
3116
|
-
const spinner = createTimedSpinner('Watching fleet status (Ctrl+C to exit)');
|
|
3117
|
-
// Initial display
|
|
3118
|
-
spinner.spinner.stop();
|
|
3119
|
-
await showStatus();
|
|
3120
|
-
// Watch mode - update every 2 seconds
|
|
3121
|
-
const interval = setInterval(async () => {
|
|
3122
|
-
console.clear();
|
|
3123
|
-
await showStatus();
|
|
3124
|
-
}, 2000);
|
|
3125
|
-
// Handle Ctrl+C - use once to avoid conflict with global handler
|
|
3126
|
-
process.once('SIGINT', async () => {
|
|
3127
|
-
clearInterval(interval);
|
|
3128
|
-
console.log(chalk.yellow('\nStopped watching.'));
|
|
3129
|
-
await cleanupAndExit(0);
|
|
3130
|
-
});
|
|
3131
|
-
}
|
|
3132
|
-
else {
|
|
3133
|
-
await showStatus();
|
|
3134
|
-
await cleanupAndExit(0);
|
|
3135
|
-
}
|
|
3136
|
-
}
|
|
3137
|
-
catch (error) {
|
|
3138
|
-
console.error(chalk.red('\n Failed to get fleet status:'), error);
|
|
3139
|
-
await cleanupAndExit(1);
|
|
3140
|
-
}
|
|
3141
|
-
});
|
|
3142
|
-
// ============================================================================
|
|
3143
|
-
// Hooks Command (AQE v3 Independent Hooks - using QEHookRegistry)
|
|
623
|
+
// External Command Modules
|
|
3144
624
|
// ============================================================================
|
|
625
|
+
import { createTokenUsageCommand } from './commands/token-usage.js';
|
|
626
|
+
import { createLLMRouterCommand } from './commands/llm-router.js';
|
|
627
|
+
import { createSyncCommands } from './commands/sync.js';
|
|
3145
628
|
import { createHooksCommand } from './commands/hooks.js';
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
program.addCommand(
|
|
3149
|
-
|
|
3150
|
-
// - QEHookRegistry for event handling
|
|
3151
|
-
// - QEReasoningBank for pattern learning
|
|
3152
|
-
// - setupQEHooks() for proper initialization
|
|
629
|
+
program.addCommand(createTokenUsageCommand());
|
|
630
|
+
program.addCommand(createLLMRouterCommand());
|
|
631
|
+
program.addCommand(createSyncCommands());
|
|
632
|
+
program.addCommand(createHooksCommand());
|
|
3153
633
|
// ============================================================================
|
|
3154
634
|
// Shutdown Handlers
|
|
3155
635
|
// ============================================================================
|
|
@@ -3166,7 +646,6 @@ process.on('SIGTERM', async () => {
|
|
|
3166
646
|
// Main
|
|
3167
647
|
// ============================================================================
|
|
3168
648
|
async function main() {
|
|
3169
|
-
// ADR-042: Initialize token tracking and optimization
|
|
3170
649
|
await bootstrapTokenTracking({
|
|
3171
650
|
enableOptimization: true,
|
|
3172
651
|
enablePersistence: true,
|