agentic-orchestrator 0.1.6 → 0.1.8
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/.prettierignore +10 -0
- package/.prettierrc.json +24 -0
- package/CLAUDE.md +3 -2
- package/README.md +71 -48
- package/agentic/orchestrator/defaults/policy.defaults.yaml +1 -1
- package/agentic/orchestrator/prompts/planner.system.md +1 -0
- package/agentic/orchestrator/schemas/agents.schema.json +5 -22
- package/agentic/orchestrator/schemas/gates.schema.json +4 -19
- package/agentic/orchestrator/schemas/index.schema.json +3 -14
- package/agentic/orchestrator/schemas/multi-project.schema.json +2 -8
- package/agentic/orchestrator/schemas/plan.schema.json +6 -26
- package/agentic/orchestrator/schemas/policy.schema.json +19 -81
- package/agentic/orchestrator/schemas/policy.user.schema.json +1 -5
- package/agentic/orchestrator/schemas/qa_test_index.schema.json +5 -29
- package/agentic/orchestrator/schemas/state.schema.json +11 -61
- package/agentic/orchestrator/tools/catalog.json +33 -164
- package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +10 -1
- package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +1 -3
- package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +4 -20
- package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +2 -7
- package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +1 -8
- package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +2 -7
- package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +1 -8
- package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +1 -7
- package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +22 -2
- package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +1 -4
- package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +1 -7
- package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +1 -6
- package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +1 -5
- package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +1 -4
- package/apps/control-plane/scripts/validate-architecture-rules.mjs +16 -5
- package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +30 -8
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +13 -7
- package/apps/control-plane/src/application/adapters/adapter-registry.ts +35 -15
- package/apps/control-plane/src/application/multi-project-loader.ts +27 -10
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +26 -14
- package/apps/control-plane/src/application/services/collision-queue-service.ts +31 -17
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +23 -16
- package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +12 -4
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +94 -58
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +19 -13
- package/apps/control-plane/src/application/services/feature-state-service.ts +29 -19
- package/apps/control-plane/src/application/services/gate-interpolation-service.ts +7 -2
- package/apps/control-plane/src/application/services/gate-service.ts +64 -41
- package/apps/control-plane/src/application/services/instance-isolation-service.ts +1 -1
- package/apps/control-plane/src/application/services/issue-tracker-service.ts +49 -38
- package/apps/control-plane/src/application/services/lock-service.ts +75 -49
- package/apps/control-plane/src/application/services/merge-service.ts +91 -50
- package/apps/control-plane/src/application/services/notifier-service.ts +42 -20
- package/apps/control-plane/src/application/services/patch-service.ts +73 -44
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +8 -6
- package/apps/control-plane/src/application/services/plan-service.ts +148 -89
- package/apps/control-plane/src/application/services/policy-loader-service.ts +10 -4
- package/apps/control-plane/src/application/services/pr-monitor-service.ts +33 -14
- package/apps/control-plane/src/application/services/qa-index-service.ts +20 -16
- package/apps/control-plane/src/application/services/reactions-service.ts +30 -15
- package/apps/control-plane/src/application/services/reporting-service.ts +16 -12
- package/apps/control-plane/src/application/services/run-lease-service.ts +138 -81
- package/apps/control-plane/src/application/tools/tool-metadata.ts +5 -5
- package/apps/control-plane/src/application/tools/tool-router.ts +6 -3
- package/apps/control-plane/src/cli/aop.ts +2 -2
- package/apps/control-plane/src/cli/attach-command-handler.ts +9 -9
- package/apps/control-plane/src/cli/cleanup-command-handler.ts +16 -11
- package/apps/control-plane/src/cli/cli-argument-parser.ts +6 -3
- package/apps/control-plane/src/cli/dashboard-command-handler.ts +28 -8
- package/apps/control-plane/src/cli/delete-command-handler.ts +7 -7
- package/apps/control-plane/src/cli/env-file.ts +115 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +61 -32
- package/apps/control-plane/src/cli/init-command-handler.ts +182 -56
- package/apps/control-plane/src/cli/io.ts +7 -3
- package/apps/control-plane/src/cli/resume-command-handler.ts +21 -13
- package/apps/control-plane/src/cli/retry-command-handler.ts +12 -11
- package/apps/control-plane/src/cli/run-command-handler.ts +12 -8
- package/apps/control-plane/src/cli/send-command-handler.ts +6 -6
- package/apps/control-plane/src/cli/spec-ingestion-service.ts +14 -8
- package/apps/control-plane/src/cli/spec-input-resolver.ts +6 -1
- package/apps/control-plane/src/cli/spec-utils.ts +2 -2
- package/apps/control-plane/src/cli/status-command-handler.ts +13 -12
- package/apps/control-plane/src/cli/tooling.ts +3 -3
- package/apps/control-plane/src/cli/types.ts +1 -1
- package/apps/control-plane/src/core/collisions.ts +27 -10
- package/apps/control-plane/src/core/constants.ts +13 -7
- package/apps/control-plane/src/core/error-codes.ts +1 -1
- package/apps/control-plane/src/core/fs.ts +11 -5
- package/apps/control-plane/src/core/gates.ts +53 -27
- package/apps/control-plane/src/core/git.ts +18 -6
- package/apps/control-plane/src/core/kernel.ts +513 -227
- package/apps/control-plane/src/core/patch.ts +7 -3
- package/apps/control-plane/src/core/path-layout.ts +5 -1
- package/apps/control-plane/src/core/path-rules.ts +19 -5
- package/apps/control-plane/src/core/qa-index.ts +26 -12
- package/apps/control-plane/src/core/response.ts +9 -6
- package/apps/control-plane/src/core/schemas.ts +29 -10
- package/apps/control-plane/src/core/tool-caller.ts +1 -1
- package/apps/control-plane/src/core/workspace-hooks.ts +5 -5
- package/apps/control-plane/src/index.ts +3 -9
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +79 -35
- package/apps/control-plane/src/mcp/kernel-tool-executor.ts +7 -3
- package/apps/control-plane/src/mcp/mcp-server-adapter.ts +12 -10
- package/apps/control-plane/src/mcp/operation-ledger.ts +18 -8
- package/apps/control-plane/src/mcp/protocol-contract.ts +2 -2
- package/apps/control-plane/src/mcp/runtime-factory.ts +15 -6
- package/apps/control-plane/src/mcp/token-auth-verifier.ts +3 -2
- package/apps/control-plane/src/mcp/token-claims-validator.ts +11 -7
- package/apps/control-plane/src/mcp/tool-authorizer.ts +1 -3
- package/apps/control-plane/src/mcp/tool-client.ts +17 -5
- package/apps/control-plane/src/mcp/tool-contract-validator.ts +17 -8
- package/apps/control-plane/src/mcp/tool-registry-loader.ts +7 -3
- package/apps/control-plane/src/mcp/tool-runtime.ts +66 -39
- package/apps/control-plane/src/mcp/tools-markdown-generator.ts +6 -1
- package/apps/control-plane/src/providers/providers.ts +137 -54
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +44 -25
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +46 -33
- package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +1 -1
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +38 -23
- package/apps/control-plane/src/supervisor/run-coordinator.ts +71 -36
- package/apps/control-plane/src/supervisor/runtime.ts +59 -35
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +48 -31
- package/apps/control-plane/src/supervisor/types.ts +22 -7
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +30 -20
- package/apps/control-plane/test/activity-monitor.spec.ts +54 -30
- package/apps/control-plane/test/adapter-registry.spec.ts +5 -5
- package/apps/control-plane/test/aop.spec.ts +4 -4
- package/apps/control-plane/test/batch-operations.spec.ts +20 -18
- package/apps/control-plane/test/bootstrap-attach.spec.ts +52 -19
- package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +58 -27
- package/apps/control-plane/test/bootstrap.spec.ts +72 -40
- package/apps/control-plane/test/cleanup-command.spec.ts +86 -32
- package/apps/control-plane/test/cli-helpers.spec.ts +119 -66
- package/apps/control-plane/test/cli.spec.ts +1 -1
- package/apps/control-plane/test/cli.unit.spec.ts +226 -167
- package/apps/control-plane/test/collision-queue.spec.ts +49 -40
- package/apps/control-plane/test/collisions.spec.ts +30 -30
- package/apps/control-plane/test/core-utils.spec.ts +29 -15
- package/apps/control-plane/test/cost-tracking.spec.ts +38 -22
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +68 -36
- package/apps/control-plane/test/dashboard-client.spec.ts +18 -12
- package/apps/control-plane/test/dashboard-command.spec.ts +11 -7
- package/apps/control-plane/test/delete-command-handler.spec.ts +49 -41
- package/apps/control-plane/test/dependency-scheduler.spec.ts +47 -20
- package/apps/control-plane/test/epoch-tracking.spec.ts +9 -9
- package/apps/control-plane/test/feature-deletion-service.spec.ts +60 -52
- package/apps/control-plane/test/feature-lifecycle.spec.ts +36 -17
- package/apps/control-plane/test/gates.spec.ts +101 -81
- package/apps/control-plane/test/git-spawn-error.spec.ts +1 -1
- package/apps/control-plane/test/helpers.ts +10 -6
- package/apps/control-plane/test/incremental-gates.spec.ts +59 -20
- package/apps/control-plane/test/init-wizard.spec.ts +328 -68
- package/apps/control-plane/test/instance-isolation.spec.ts +43 -10
- package/apps/control-plane/test/issue-tracker.spec.ts +368 -128
- package/apps/control-plane/test/kernel-collision-replay.spec.ts +50 -29
- package/apps/control-plane/test/kernel.branches.spec.ts +64 -40
- package/apps/control-plane/test/kernel.coverage.spec.ts +85 -49
- package/apps/control-plane/test/kernel.coverage2.spec.ts +109 -65
- package/apps/control-plane/test/kernel.spec.ts +134 -51
- package/apps/control-plane/test/lock-service.spec.ts +92 -68
- package/apps/control-plane/test/mcp-helpers.spec.ts +53 -39
- package/apps/control-plane/test/mcp.spec.ts +231 -115
- package/apps/control-plane/test/merge-service.spec.ts +142 -94
- package/apps/control-plane/test/multi-project.spec.ts +28 -22
- package/apps/control-plane/test/notifier-service.spec.ts +136 -92
- package/apps/control-plane/test/parallel-gates.spec.ts +51 -35
- package/apps/control-plane/test/patch-service.spec.ts +128 -48
- package/apps/control-plane/test/performance-analytics.spec.ts +99 -63
- package/apps/control-plane/test/plan-service.spec.ts +50 -39
- package/apps/control-plane/test/planning-wave-executor.spec.ts +95 -71
- package/apps/control-plane/test/policy-loader-service.spec.ts +41 -19
- package/apps/control-plane/test/pr-monitor.spec.ts +113 -64
- package/apps/control-plane/test/providers.spec.ts +208 -104
- package/apps/control-plane/test/qa-index-service.spec.ts +31 -33
- package/apps/control-plane/test/qa-index.spec.ts +58 -61
- package/apps/control-plane/test/reactions.spec.ts +88 -45
- package/apps/control-plane/test/response.spec.ts +5 -5
- package/apps/control-plane/test/resume-command.spec.ts +121 -80
- package/apps/control-plane/test/run-coordinator.spec.ts +205 -136
- package/apps/control-plane/test/schema-date-time.spec.ts +49 -41
- package/apps/control-plane/test/service-retry-paths.spec.ts +77 -57
- package/apps/control-plane/test/services.spec.ts +147 -129
- package/apps/control-plane/test/session-management.spec.ts +136 -74
- package/apps/control-plane/test/spec-ingestion.spec.ts +23 -21
- package/apps/control-plane/test/spec-input-resolver.spec.ts +11 -10
- package/apps/control-plane/test/supervisor-collaborators.spec.ts +168 -121
- package/apps/control-plane/test/supervisor.calltool.spec.ts +21 -18
- package/apps/control-plane/test/supervisor.spec.ts +67 -43
- package/apps/control-plane/test/supervisor.unit.spec.ts +195 -126
- package/apps/control-plane/test/token-auth-verifier.spec.ts +29 -14
- package/apps/control-plane/test/tool-registry-loader.spec.ts +51 -27
- package/apps/control-plane/test/tool-runtime.spec.ts +63 -46
- package/apps/control-plane/test/worker-decision-loop.spec.ts +143 -122
- package/apps/control-plane/test/workspace-hooks.spec.ts +61 -23
- package/apps/control-plane/tsconfig.build.json +2 -7
- package/apps/control-plane/tsconfig.json +1 -5
- package/apps/control-plane/vitest.config.ts +7 -7
- package/config/agentic/orchestrator/adapters.yaml +3 -0
- package/config/agentic/orchestrator/agents.yaml +14 -0
- package/config/agentic/orchestrator/gates.yaml +28 -0
- package/config/agentic/orchestrator/policy.yaml +22 -0
- package/config/agentic/orchestrator/prompts/builder.system.md +1 -0
- package/config/agentic/orchestrator/prompts/planner.system.md +16 -0
- package/config/agentic/orchestrator/prompts/qa.system.md +1 -0
- package/dist/apps/control-plane/application/adapters/adapter-registry.js +12 -5
- package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -1
- package/dist/apps/control-plane/application/multi-project-loader.js +26 -9
- package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -1
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +7 -7
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/collision-queue-service.js +7 -7
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +6 -8
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +37 -29
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +10 -10
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-state-service.js +11 -11
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js +3 -1
- package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-service.js +26 -26
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/instance-isolation-service.js +1 -1
- package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/issue-tracker-service.js +25 -15
- package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/lock-service.js +32 -32
- package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/merge-service.js +41 -27
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.js +29 -15
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/patch-service.js +21 -19
- package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +4 -4
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/plan-service.js +33 -33
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/pr-monitor-service.js +23 -11
- package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/qa-index-service.js +11 -11
- package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reactions-service.js +13 -9
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reporting-service.js +11 -9
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.js +34 -33
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-metadata.js +2 -2
- package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
- package/dist/apps/control-plane/cli/attach-command-handler.js +9 -9
- package/dist/apps/control-plane/cli/cleanup-command-handler.js +11 -9
- package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -3
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/dashboard-command-handler.js +23 -7
- package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/delete-command-handler.js +7 -7
- package/dist/apps/control-plane/cli/env-file.d.ts +4 -0
- package/dist/apps/control-plane/cli/env-file.js +89 -0
- package/dist/apps/control-plane/cli/env-file.js.map +1 -0
- package/dist/apps/control-plane/cli/help-command-handler.js +58 -30
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.js +97 -37
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/io.js +2 -2
- package/dist/apps/control-plane/cli/io.js.map +1 -1
- package/dist/apps/control-plane/cli/resume-command-handler.js +9 -9
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-command-handler.js +12 -11
- package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/run-command-handler.js +12 -8
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/send-command-handler.js +6 -6
- package/dist/apps/control-plane/cli/spec-ingestion-service.js +10 -8
- package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
- package/dist/apps/control-plane/cli/status-command-handler.js +8 -8
- package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/tooling.js +1 -1
- package/dist/apps/control-plane/core/collisions.js +11 -8
- package/dist/apps/control-plane/core/collisions.js.map +1 -1
- package/dist/apps/control-plane/core/constants.js +13 -7
- package/dist/apps/control-plane/core/constants.js.map +1 -1
- package/dist/apps/control-plane/core/error-codes.js +1 -1
- package/dist/apps/control-plane/core/fs.js.map +1 -1
- package/dist/apps/control-plane/core/gates.d.ts +2 -2
- package/dist/apps/control-plane/core/gates.js +26 -19
- package/dist/apps/control-plane/core/gates.js.map +1 -1
- package/dist/apps/control-plane/core/git.js +3 -3
- package/dist/apps/control-plane/core/git.js.map +1 -1
- package/dist/apps/control-plane/core/kernel.d.ts +1 -0
- package/dist/apps/control-plane/core/kernel.js +134 -81
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/patch.js +7 -3
- package/dist/apps/control-plane/core/patch.js.map +1 -1
- package/dist/apps/control-plane/core/path-layout.d.ts +1 -0
- package/dist/apps/control-plane/core/path-layout.js +4 -1
- package/dist/apps/control-plane/core/path-layout.js.map +1 -1
- package/dist/apps/control-plane/core/path-rules.js +3 -1
- package/dist/apps/control-plane/core/path-rules.js.map +1 -1
- package/dist/apps/control-plane/core/qa-index.js +5 -5
- package/dist/apps/control-plane/core/qa-index.js.map +1 -1
- package/dist/apps/control-plane/core/response.js +3 -3
- package/dist/apps/control-plane/core/response.js.map +1 -1
- package/dist/apps/control-plane/core/schemas.js +10 -6
- package/dist/apps/control-plane/core/schemas.js.map +1 -1
- package/dist/apps/control-plane/core/workspace-hooks.js +3 -3
- package/dist/apps/control-plane/index.d.ts +1 -1
- package/dist/apps/control-plane/index.js +1 -1
- package/dist/apps/control-plane/index.js.map +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +40 -23
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js +6 -7
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -1
- package/dist/apps/control-plane/mcp/operation-ledger.js +5 -5
- package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -1
- package/dist/apps/control-plane/mcp/protocol-contract.js +2 -2
- package/dist/apps/control-plane/mcp/runtime-factory.js +2 -2
- package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -1
- package/dist/apps/control-plane/mcp/token-auth-verifier.js +1 -1
- package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -1
- package/dist/apps/control-plane/mcp/token-claims-validator.js +5 -5
- package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-authorizer.js +1 -3
- package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-client.js +2 -2
- package/dist/apps/control-plane/mcp/tool-client.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-contract-validator.js +3 -3
- package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.js +1 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-runtime.js +17 -17
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js +6 -1
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +3 -2
- package/dist/apps/control-plane/providers/providers.js +81 -39
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +12 -12
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +19 -16
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +13 -13
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.js +37 -20
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.js +25 -21
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +29 -23
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/types.d.ts +3 -3
- package/dist/apps/control-plane/supervisor/types.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +14 -16
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/eslint.config.mjs +20 -20
- package/example-configurations/README.md +1 -1
- package/example-configurations/java/agents.yaml +3 -3
- package/example-configurations/java/policy.yaml +1 -1
- package/example-configurations/node/agents.yaml +3 -3
- package/example-configurations/node/policy.yaml +1 -1
- package/package.json +10 -5
- package/packages/web-dashboard/next.config.js +2 -2
- package/packages/web-dashboard/src/app/api/actions/route.ts +25 -9
- package/packages/web-dashboard/src/app/api/events/route.ts +20 -6
- package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +88 -37
- package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +8 -5
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +27 -9
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -2
- package/packages/web-dashboard/src/app/api/projects/route.ts +5 -5
- package/packages/web-dashboard/src/app/globals.css +10 -2
- package/packages/web-dashboard/src/app/page.tsx +100 -37
- package/packages/web-dashboard/src/lib/aop-client.ts +68 -37
- package/packages/web-dashboard/src/lib/multi-project-config.ts +28 -7
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +59 -36
- package/packages/web-dashboard/tsconfig.json +3 -11
- package/scripts/nx-safe.mjs +10 -10
- package/spec-files/completed/agentic_orchestrator_cli_delete_command_spec.md +5 -0
- package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +189 -90
- package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +49 -16
- package/spec-files/completed/agentic_orchestrator_mcp_formalization_spec.md +24 -1
- package/spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md +9 -0
- package/spec-files/completed/agentic_orchestrator_spec.md +171 -75
- package/spec-files/completed/agentic_orchestrator_validator_hardening_spec.md +25 -17
- package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +40 -5
- package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +23 -12
- package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +16 -4
- package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +42 -2
- package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +209 -130
- package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +56 -3
- package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +77 -10
- package/spec-files/outstanding/agentic_orchestrator_provider_auth_bootstrap_spec.md +384 -0
- package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +29 -14
- package/spec-files/progress.md +186 -175
- package/tsconfig.json +2 -8
|
@@ -8,20 +8,26 @@ const execFileMock = vi.hoisted(() => vi.fn());
|
|
|
8
8
|
|
|
9
9
|
vi.mock('node:child_process', () => ({
|
|
10
10
|
execFile: (...args: unknown[]) => {
|
|
11
|
-
const cb = args[args.length - 1] as (
|
|
12
|
-
|
|
11
|
+
const cb = args[args.length - 1] as (
|
|
12
|
+
err: null | Error,
|
|
13
|
+
result?: { stdout: string; stderr: string },
|
|
14
|
+
) => void;
|
|
15
|
+
const promise = execFileMock(...args.slice(0, -1)) as Promise<{
|
|
16
|
+
stdout: string;
|
|
17
|
+
stderr: string;
|
|
18
|
+
}>;
|
|
13
19
|
void promise.then(
|
|
14
20
|
(result) => cb(null, result),
|
|
15
|
-
(err: Error) => cb(err)
|
|
21
|
+
(err: Error) => cb(err),
|
|
16
22
|
);
|
|
17
|
-
}
|
|
23
|
+
},
|
|
18
24
|
}));
|
|
19
25
|
|
|
20
26
|
import { InitCommandHandler } from '../src/cli/init-command-handler.js';
|
|
21
27
|
import { HelpCommandHandler } from '../src/cli/help-command-handler.js';
|
|
22
28
|
|
|
23
29
|
function makePromptFactory(responses: string[]) {
|
|
24
|
-
const question = vi.fn(async () => responses.shift() ?? '');
|
|
30
|
+
const question = vi.fn(async (_query: string) => responses.shift() ?? '');
|
|
25
31
|
const close = vi.fn();
|
|
26
32
|
const factory = vi.fn(() => ({ question, close }));
|
|
27
33
|
return { factory, question, close };
|
|
@@ -46,7 +52,7 @@ describe('InitCommandHandler', () => {
|
|
|
46
52
|
await fs.writeFile(
|
|
47
53
|
path.join(cwd, '.git', 'config'),
|
|
48
54
|
`[core]\n repositoryformatversion = 0\n[remote "origin"]\n url = https://github.com/example/repo.git\n fetch = +refs/heads/*:refs/remotes/origin/*\n`,
|
|
49
|
-
'utf8'
|
|
55
|
+
'utf8',
|
|
50
56
|
);
|
|
51
57
|
|
|
52
58
|
// Mock git symbolic-ref to return origin/main
|
|
@@ -57,47 +63,69 @@ describe('InitCommandHandler', () => {
|
|
|
57
63
|
|
|
58
64
|
expect(result.ok).toBe(true);
|
|
59
65
|
expect(result.data.command).toBe('init');
|
|
60
|
-
expect(result.data.created).toContain('agentic/orchestrator/policy.yaml');
|
|
61
|
-
expect(result.data.created).toContain('agentic/orchestrator/gates.yaml');
|
|
62
|
-
expect(result.data.created).toContain('agentic/orchestrator/agents.yaml');
|
|
63
|
-
expect(result.data.created).toContain('agentic/orchestrator/adapters.yaml');
|
|
64
|
-
expect(result.data.created).toContain('agentic/orchestrator/prompts/planner.system.md');
|
|
66
|
+
expect(result.data.created).toContain('config/agentic/orchestrator/policy.yaml');
|
|
67
|
+
expect(result.data.created).toContain('config/agentic/orchestrator/gates.yaml');
|
|
68
|
+
expect(result.data.created).toContain('config/agentic/orchestrator/agents.yaml');
|
|
69
|
+
expect(result.data.created).toContain('config/agentic/orchestrator/adapters.yaml');
|
|
70
|
+
expect(result.data.created).toContain('config/agentic/orchestrator/prompts/planner.system.md');
|
|
65
71
|
expect(result.data.skipped).toHaveLength(0);
|
|
66
72
|
expect(result.data.updated).toHaveLength(0);
|
|
67
73
|
expect(result.data.validation_warnings).toHaveLength(0);
|
|
68
74
|
|
|
69
75
|
// Verify files were created
|
|
70
|
-
const policyContent = await fs.readFile(
|
|
76
|
+
const policyContent = await fs.readFile(
|
|
77
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
78
|
+
'utf8',
|
|
79
|
+
);
|
|
71
80
|
expect(policyContent).toContain('base_branch: main');
|
|
72
81
|
// lean policy does not include advanced fields like testing.framework
|
|
73
82
|
expect(policyContent).not.toContain('framework: vitest');
|
|
74
83
|
expect(policyContent).toContain('notifications:');
|
|
75
84
|
|
|
76
|
-
const gatesContent = await fs.readFile(
|
|
85
|
+
const gatesContent = await fs.readFile(
|
|
86
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'gates.yaml'),
|
|
87
|
+
'utf8',
|
|
88
|
+
);
|
|
77
89
|
expect(gatesContent).toContain('version: 1');
|
|
78
90
|
expect(gatesContent).toContain('profiles:');
|
|
79
91
|
|
|
80
|
-
const agentsContent = await fs.readFile(
|
|
92
|
+
const agentsContent = await fs.readFile(
|
|
93
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'agents.yaml'),
|
|
94
|
+
'utf8',
|
|
95
|
+
);
|
|
81
96
|
expect(agentsContent).toContain('version: 1');
|
|
82
97
|
expect(agentsContent).toContain('roles:');
|
|
83
98
|
expect(agentsContent).toContain('default_provider: custom');
|
|
84
99
|
expect(agentsContent).toContain('default_model: local-default');
|
|
100
|
+
expect(agentsContent).not.toContain('provider_config_env:');
|
|
85
101
|
|
|
86
|
-
const adaptersContent = await fs.readFile(
|
|
102
|
+
const adaptersContent = await fs.readFile(
|
|
103
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'adapters.yaml'),
|
|
104
|
+
'utf8',
|
|
105
|
+
);
|
|
87
106
|
expect(adaptersContent).toContain('activity-detector: process-heuristic');
|
|
88
107
|
expect(adaptersContent).toContain('scm-provider: github');
|
|
89
108
|
|
|
90
109
|
await expect(
|
|
91
|
-
fs.readFile(
|
|
110
|
+
fs.readFile(
|
|
111
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'prompts', 'planner.system.md'),
|
|
112
|
+
'utf8',
|
|
113
|
+
),
|
|
92
114
|
).resolves.toContain('planner');
|
|
93
|
-
await expect(
|
|
115
|
+
await expect(
|
|
116
|
+
fs.stat(path.join(cwd, 'config', 'agentic', 'orchestrator', 'schemas')),
|
|
117
|
+
).rejects.toThrow();
|
|
94
118
|
});
|
|
95
119
|
|
|
96
120
|
it('GIVEN_existing_config_WHEN_init_without_force_THEN_skips_existing_files', async () => {
|
|
97
121
|
// Pre-create the orchestrator directory and policy.yaml
|
|
98
|
-
const orchestratorDir = path.join(cwd, 'agentic', 'orchestrator');
|
|
122
|
+
const orchestratorDir = path.join(cwd, 'config', 'agentic', 'orchestrator');
|
|
99
123
|
await fs.mkdir(orchestratorDir, { recursive: true });
|
|
100
|
-
await fs.writeFile(
|
|
124
|
+
await fs.writeFile(
|
|
125
|
+
path.join(orchestratorDir, 'policy.yaml'),
|
|
126
|
+
'version: 1\n# existing\n',
|
|
127
|
+
'utf8',
|
|
128
|
+
);
|
|
101
129
|
|
|
102
130
|
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
103
131
|
|
|
@@ -105,9 +133,9 @@ describe('InitCommandHandler', () => {
|
|
|
105
133
|
const result = await handler.execute({ auto: true });
|
|
106
134
|
|
|
107
135
|
expect(result.ok).toBe(true);
|
|
108
|
-
expect(result.data.skipped).toContain('agentic/orchestrator/policy.yaml');
|
|
109
|
-
expect(result.data.created).not.toContain('agentic/orchestrator/policy.yaml');
|
|
110
|
-
expect(result.data.updated).not.toContain('agentic/orchestrator/policy.yaml');
|
|
136
|
+
expect(result.data.skipped).toContain('config/agentic/orchestrator/policy.yaml');
|
|
137
|
+
expect(result.data.created).not.toContain('config/agentic/orchestrator/policy.yaml');
|
|
138
|
+
expect(result.data.updated).not.toContain('config/agentic/orchestrator/policy.yaml');
|
|
111
139
|
|
|
112
140
|
// Verify file was NOT overwritten
|
|
113
141
|
const content = await fs.readFile(path.join(orchestratorDir, 'policy.yaml'), 'utf8');
|
|
@@ -116,9 +144,13 @@ describe('InitCommandHandler', () => {
|
|
|
116
144
|
|
|
117
145
|
it('GIVEN_existing_config_WHEN_init_with_force_THEN_overwrites_files', async () => {
|
|
118
146
|
// Pre-create the orchestrator directory and policy.yaml
|
|
119
|
-
const orchestratorDir = path.join(cwd, 'agentic', 'orchestrator');
|
|
147
|
+
const orchestratorDir = path.join(cwd, 'config', 'agentic', 'orchestrator');
|
|
120
148
|
await fs.mkdir(orchestratorDir, { recursive: true });
|
|
121
|
-
await fs.writeFile(
|
|
149
|
+
await fs.writeFile(
|
|
150
|
+
path.join(orchestratorDir, 'policy.yaml'),
|
|
151
|
+
'version: 1\n# existing\n',
|
|
152
|
+
'utf8',
|
|
153
|
+
);
|
|
122
154
|
|
|
123
155
|
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
124
156
|
|
|
@@ -126,8 +158,8 @@ describe('InitCommandHandler', () => {
|
|
|
126
158
|
const result = await handler.execute({ auto: true, force: true });
|
|
127
159
|
|
|
128
160
|
expect(result.ok).toBe(true);
|
|
129
|
-
expect(result.data.updated).toContain('agentic/orchestrator/policy.yaml');
|
|
130
|
-
expect(result.data.skipped).not.toContain('agentic/orchestrator/policy.yaml');
|
|
161
|
+
expect(result.data.updated).toContain('config/agentic/orchestrator/policy.yaml');
|
|
162
|
+
expect(result.data.skipped).not.toContain('config/agentic/orchestrator/policy.yaml');
|
|
131
163
|
|
|
132
164
|
// Verify file WAS overwritten with generated content (lean policy by default)
|
|
133
165
|
const content = await fs.readFile(path.join(orchestratorDir, 'policy.yaml'), 'utf8');
|
|
@@ -144,11 +176,14 @@ describe('InitCommandHandler', () => {
|
|
|
144
176
|
const result = await handler.execute({ auto: true });
|
|
145
177
|
|
|
146
178
|
expect(result.ok).toBe(true);
|
|
147
|
-
expect(result.data.created).toContain('agentic/orchestrator/policy.yaml');
|
|
179
|
+
expect(result.data.created).toContain('config/agentic/orchestrator/policy.yaml');
|
|
148
180
|
expect(result.data.validation_warnings).toHaveLength(0);
|
|
149
181
|
|
|
150
182
|
// Should default to main branch
|
|
151
|
-
const policyContent = await fs.readFile(
|
|
183
|
+
const policyContent = await fs.readFile(
|
|
184
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
185
|
+
'utf8',
|
|
186
|
+
);
|
|
152
187
|
expect(policyContent).toContain('base_branch: main');
|
|
153
188
|
});
|
|
154
189
|
|
|
@@ -156,7 +191,7 @@ describe('InitCommandHandler', () => {
|
|
|
156
191
|
await fs.writeFile(
|
|
157
192
|
path.join(cwd, 'package.json'),
|
|
158
193
|
JSON.stringify({ devDependencies: { jest: '^29.0.0' } }),
|
|
159
|
-
'utf8'
|
|
194
|
+
'utf8',
|
|
160
195
|
);
|
|
161
196
|
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
162
197
|
|
|
@@ -164,20 +199,30 @@ describe('InitCommandHandler', () => {
|
|
|
164
199
|
const result = await handler.execute({ auto: true });
|
|
165
200
|
|
|
166
201
|
expect(result.ok).toBe(true);
|
|
167
|
-
const gatesContent = await fs.readFile(
|
|
202
|
+
const gatesContent = await fs.readFile(
|
|
203
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'gates.yaml'),
|
|
204
|
+
'utf8',
|
|
205
|
+
);
|
|
168
206
|
expect(gatesContent).toContain('"npx"');
|
|
169
207
|
expect(gatesContent).toContain('"jest"');
|
|
170
208
|
});
|
|
171
209
|
|
|
172
210
|
it('GIVEN_pyproject_toml_WHEN_init_THEN_generates_pytest_gate_commands', async () => {
|
|
173
|
-
await fs.writeFile(
|
|
211
|
+
await fs.writeFile(
|
|
212
|
+
path.join(cwd, 'pyproject.toml'),
|
|
213
|
+
'[tool.poetry]\nname = "myproject"\n',
|
|
214
|
+
'utf8',
|
|
215
|
+
);
|
|
174
216
|
execFileMock.mockRejectedValue(new Error('not git'));
|
|
175
217
|
|
|
176
218
|
const handler = new InitCommandHandler(cwd);
|
|
177
219
|
const result = await handler.execute({ auto: true });
|
|
178
220
|
|
|
179
221
|
expect(result.ok).toBe(true);
|
|
180
|
-
const gatesContent = await fs.readFile(
|
|
222
|
+
const gatesContent = await fs.readFile(
|
|
223
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'gates.yaml'),
|
|
224
|
+
'utf8',
|
|
225
|
+
);
|
|
181
226
|
expect(gatesContent).toContain('"pytest"');
|
|
182
227
|
});
|
|
183
228
|
|
|
@@ -189,7 +234,10 @@ describe('InitCommandHandler', () => {
|
|
|
189
234
|
const result = await handler.execute({ auto: true });
|
|
190
235
|
|
|
191
236
|
expect(result.ok).toBe(true);
|
|
192
|
-
const gatesContent = await fs.readFile(
|
|
237
|
+
const gatesContent = await fs.readFile(
|
|
238
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'gates.yaml'),
|
|
239
|
+
'utf8',
|
|
240
|
+
);
|
|
193
241
|
expect(gatesContent).toContain('"mvn"');
|
|
194
242
|
});
|
|
195
243
|
|
|
@@ -201,7 +249,10 @@ describe('InitCommandHandler', () => {
|
|
|
201
249
|
const result = await handler.execute({ auto: true });
|
|
202
250
|
|
|
203
251
|
expect(result.ok).toBe(true);
|
|
204
|
-
const gatesContent = await fs.readFile(
|
|
252
|
+
const gatesContent = await fs.readFile(
|
|
253
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'gates.yaml'),
|
|
254
|
+
'utf8',
|
|
255
|
+
);
|
|
205
256
|
expect(gatesContent).toContain('"./gradlew"');
|
|
206
257
|
});
|
|
207
258
|
|
|
@@ -210,7 +261,7 @@ describe('InitCommandHandler', () => {
|
|
|
210
261
|
await fs.writeFile(
|
|
211
262
|
path.join(cwd, '.git', 'config'),
|
|
212
263
|
'[core]\n repositoryformatversion = 0\n',
|
|
213
|
-
'utf8'
|
|
264
|
+
'utf8',
|
|
214
265
|
);
|
|
215
266
|
execFileMock.mockResolvedValue({ stdout: 'origin/develop\n', stderr: '' });
|
|
216
267
|
|
|
@@ -218,7 +269,10 @@ describe('InitCommandHandler', () => {
|
|
|
218
269
|
const result = await handler.execute({ auto: true });
|
|
219
270
|
|
|
220
271
|
expect(result.ok).toBe(true);
|
|
221
|
-
const policyContent = await fs.readFile(
|
|
272
|
+
const policyContent = await fs.readFile(
|
|
273
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
274
|
+
'utf8',
|
|
275
|
+
);
|
|
222
276
|
expect(policyContent).toContain('base_branch: develop');
|
|
223
277
|
});
|
|
224
278
|
|
|
@@ -231,7 +285,10 @@ describe('InitCommandHandler', () => {
|
|
|
231
285
|
const result = await handler.execute({ auto: true });
|
|
232
286
|
|
|
233
287
|
expect(result.ok).toBe(true);
|
|
234
|
-
const policyContent = await fs.readFile(
|
|
288
|
+
const policyContent = await fs.readFile(
|
|
289
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
290
|
+
'utf8',
|
|
291
|
+
);
|
|
235
292
|
expect(policyContent).toContain('base_branch: master');
|
|
236
293
|
});
|
|
237
294
|
|
|
@@ -261,7 +318,7 @@ describe('InitCommandHandler', () => {
|
|
|
261
318
|
'4500',
|
|
262
319
|
'desktop,slack',
|
|
263
320
|
'jest',
|
|
264
|
-
'https://hooks.slack.example/webhook'
|
|
321
|
+
'https://hooks.slack.example/webhook',
|
|
265
322
|
]);
|
|
266
323
|
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
267
324
|
const result = await handler.execute({ auto: false });
|
|
@@ -270,7 +327,10 @@ describe('InitCommandHandler', () => {
|
|
|
270
327
|
expect(prompts.factory).toHaveBeenCalledTimes(1);
|
|
271
328
|
expect(prompts.close).toHaveBeenCalledTimes(1);
|
|
272
329
|
|
|
273
|
-
const policyContent = await fs.readFile(
|
|
330
|
+
const policyContent = await fs.readFile(
|
|
331
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
332
|
+
'utf8',
|
|
333
|
+
);
|
|
274
334
|
expect(policyContent).toContain('base_branch: release');
|
|
275
335
|
expect(policyContent).toContain('max_parallel_gate_runs: 4');
|
|
276
336
|
expect(policyContent).toContain('port: 4500');
|
|
@@ -278,18 +338,191 @@ describe('InitCommandHandler', () => {
|
|
|
278
338
|
expect(policyContent).toContain('enabled: true');
|
|
279
339
|
expect(policyContent).toContain('webhook: "https://hooks.slack.example/webhook"');
|
|
280
340
|
|
|
281
|
-
const gatesContent = await fs.readFile(
|
|
341
|
+
const gatesContent = await fs.readFile(
|
|
342
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'gates.yaml'),
|
|
343
|
+
'utf8',
|
|
344
|
+
);
|
|
282
345
|
expect(gatesContent).toContain('"npx"');
|
|
283
346
|
expect(gatesContent).toContain('"jest"');
|
|
284
347
|
|
|
285
|
-
const agentsContent = await fs.readFile(
|
|
348
|
+
const agentsContent = await fs.readFile(
|
|
349
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'agents.yaml'),
|
|
350
|
+
'utf8',
|
|
351
|
+
);
|
|
286
352
|
expect(agentsContent).toContain('default_provider: claude');
|
|
287
353
|
expect(agentsContent).toContain('default_model: sonnet-4.5');
|
|
354
|
+
expect(agentsContent).not.toContain('provider_config_env:');
|
|
288
355
|
|
|
289
|
-
const adaptersContent = await fs.readFile(
|
|
356
|
+
const adaptersContent = await fs.readFile(
|
|
357
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'adapters.yaml'),
|
|
358
|
+
'utf8',
|
|
359
|
+
);
|
|
290
360
|
expect(adaptersContent).toContain('activity-detector: claude-jsonl');
|
|
291
361
|
expect(adaptersContent).toContain('scm-provider: github');
|
|
292
362
|
});
|
|
363
|
+
|
|
364
|
+
it('GIVEN_interactive_local_cli_mode_WHEN_init_runs_THEN_provider_env_prompt_is_skipped_and_agents_yaml_omits_provider_config_env', async () => {
|
|
365
|
+
await fs.mkdir(path.join(cwd, '.git'), { recursive: true });
|
|
366
|
+
await fs.writeFile(path.join(cwd, '.git', 'config'), '[core]\n', 'utf8');
|
|
367
|
+
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
368
|
+
|
|
369
|
+
const prompts = makePromptFactory([
|
|
370
|
+
'main',
|
|
371
|
+
'codex',
|
|
372
|
+
'codex-default',
|
|
373
|
+
'github',
|
|
374
|
+
'3',
|
|
375
|
+
'3000',
|
|
376
|
+
'none',
|
|
377
|
+
'vitest',
|
|
378
|
+
'yes',
|
|
379
|
+
]);
|
|
380
|
+
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
381
|
+
const result = await handler.execute({ auto: false });
|
|
382
|
+
|
|
383
|
+
expect(result.ok).toBe(true);
|
|
384
|
+
expect(
|
|
385
|
+
prompts.question.mock.calls.some((call) =>
|
|
386
|
+
String(call[0]).includes('Provider config env var name'),
|
|
387
|
+
),
|
|
388
|
+
).toBe(false);
|
|
389
|
+
|
|
390
|
+
const agentsContent = await fs.readFile(
|
|
391
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'agents.yaml'),
|
|
392
|
+
'utf8',
|
|
393
|
+
);
|
|
394
|
+
expect(agentsContent).not.toContain('provider_config_env:');
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it('GIVEN_api_backed_mode_with_existing_env_var_WHEN_init_runs_THEN_agents_yaml_uses_that_env_var', async () => {
|
|
398
|
+
await fs.mkdir(path.join(cwd, '.git'), { recursive: true });
|
|
399
|
+
await fs.writeFile(path.join(cwd, '.git', 'config'), '[core]\n', 'utf8');
|
|
400
|
+
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
401
|
+
process.env.GEMINI_API_KEY = 'existing-key';
|
|
402
|
+
|
|
403
|
+
const prompts = makePromptFactory([
|
|
404
|
+
'main',
|
|
405
|
+
'gemini',
|
|
406
|
+
'gemini-default',
|
|
407
|
+
'github',
|
|
408
|
+
'3',
|
|
409
|
+
'3000',
|
|
410
|
+
'none',
|
|
411
|
+
'vitest',
|
|
412
|
+
'no',
|
|
413
|
+
'GEMINI_API_KEY',
|
|
414
|
+
]);
|
|
415
|
+
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
416
|
+
const result = await handler.execute({ auto: false }).finally(() => {
|
|
417
|
+
delete process.env.GEMINI_API_KEY;
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
expect(result.ok).toBe(true);
|
|
421
|
+
const agentsContent = await fs.readFile(
|
|
422
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'agents.yaml'),
|
|
423
|
+
'utf8',
|
|
424
|
+
);
|
|
425
|
+
expect(agentsContent).toContain('provider_config_env: GEMINI_API_KEY');
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('GIVEN_api_backed_mode_with_env_var_in_dotenv_WHEN_init_runs_THEN_agents_yaml_uses_that_env_var_without_bootstrap_prompt', async () => {
|
|
429
|
+
await fs.mkdir(path.join(cwd, '.git'), { recursive: true });
|
|
430
|
+
await fs.writeFile(path.join(cwd, '.git', 'config'), '[core]\n', 'utf8');
|
|
431
|
+
await fs.writeFile(path.join(cwd, '.env'), 'GEMINI_API_KEY=dotenv-key\n', 'utf8');
|
|
432
|
+
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
433
|
+
|
|
434
|
+
const prompts = makePromptFactory([
|
|
435
|
+
'main',
|
|
436
|
+
'gemini',
|
|
437
|
+
'gemini-default',
|
|
438
|
+
'github',
|
|
439
|
+
'3',
|
|
440
|
+
'3000',
|
|
441
|
+
'none',
|
|
442
|
+
'vitest',
|
|
443
|
+
'no',
|
|
444
|
+
'GEMINI_API_KEY',
|
|
445
|
+
]);
|
|
446
|
+
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
447
|
+
const result = await handler.execute({ auto: false });
|
|
448
|
+
|
|
449
|
+
expect(result.ok).toBe(true);
|
|
450
|
+
expect(
|
|
451
|
+
prompts.question.mock.calls.some((call) =>
|
|
452
|
+
String(call[0]).includes('Paste provider key to store in AOP_PROVIDER_CONFIG_ENV'),
|
|
453
|
+
),
|
|
454
|
+
).toBe(false);
|
|
455
|
+
const agentsContent = await fs.readFile(
|
|
456
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'agents.yaml'),
|
|
457
|
+
'utf8',
|
|
458
|
+
);
|
|
459
|
+
expect(agentsContent).toContain('provider_config_env: GEMINI_API_KEY');
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
it('GIVEN_api_backed_mode_with_missing_env_var_WHEN_init_runs_THEN_bootstraps_AOP_provider_env_in_dotenv', async () => {
|
|
463
|
+
await fs.mkdir(path.join(cwd, '.git'), { recursive: true });
|
|
464
|
+
await fs.writeFile(path.join(cwd, '.git', 'config'), '[core]\n', 'utf8');
|
|
465
|
+
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
466
|
+
|
|
467
|
+
const prompts = makePromptFactory([
|
|
468
|
+
'main',
|
|
469
|
+
'gemini',
|
|
470
|
+
'gemini-default',
|
|
471
|
+
'github',
|
|
472
|
+
'3',
|
|
473
|
+
'3000',
|
|
474
|
+
'none',
|
|
475
|
+
'vitest',
|
|
476
|
+
'no',
|
|
477
|
+
'GEMINI_API_KEY',
|
|
478
|
+
'bootstrap-secret',
|
|
479
|
+
]);
|
|
480
|
+
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
481
|
+
const result = await handler.execute({ auto: false });
|
|
482
|
+
|
|
483
|
+
expect(result.ok).toBe(true);
|
|
484
|
+
expect(result.data.next_steps).toContain(
|
|
485
|
+
'Stored provider credential in .env as AOP_PROVIDER_CONFIG_ENV.',
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
const agentsContent = await fs.readFile(
|
|
489
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'agents.yaml'),
|
|
490
|
+
'utf8',
|
|
491
|
+
);
|
|
492
|
+
expect(agentsContent).toContain('provider_config_env: AOP_PROVIDER_CONFIG_ENV');
|
|
493
|
+
|
|
494
|
+
const envContent = await fs.readFile(path.join(cwd, '.env'), 'utf8');
|
|
495
|
+
expect(envContent).toContain('AOP_PROVIDER_CONFIG_ENV=bootstrap-secret');
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it('GIVEN_existing_AOP_provider_env_in_dotenv_WHEN_init_bootstraps_again_THEN_replaces_existing_value_without_duplication', async () => {
|
|
499
|
+
await fs.mkdir(path.join(cwd, '.git'), { recursive: true });
|
|
500
|
+
await fs.writeFile(path.join(cwd, '.git', 'config'), '[core]\n', 'utf8');
|
|
501
|
+
await fs.writeFile(path.join(cwd, '.env'), 'FOO=bar\nAOP_PROVIDER_CONFIG_ENV=old\n', 'utf8');
|
|
502
|
+
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
503
|
+
|
|
504
|
+
const prompts = makePromptFactory([
|
|
505
|
+
'main',
|
|
506
|
+
'gemini',
|
|
507
|
+
'gemini-default',
|
|
508
|
+
'github',
|
|
509
|
+
'3',
|
|
510
|
+
'3000',
|
|
511
|
+
'none',
|
|
512
|
+
'vitest',
|
|
513
|
+
'no',
|
|
514
|
+
'MISSING_ENV_VAR',
|
|
515
|
+
'new-secret',
|
|
516
|
+
]);
|
|
517
|
+
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
518
|
+
const result = await handler.execute({ auto: false });
|
|
519
|
+
|
|
520
|
+
expect(result.ok).toBe(true);
|
|
521
|
+
const envContent = await fs.readFile(path.join(cwd, '.env'), 'utf8');
|
|
522
|
+
expect(envContent).toContain('FOO=bar');
|
|
523
|
+
expect(envContent).toContain('AOP_PROVIDER_CONFIG_ENV=new-secret');
|
|
524
|
+
expect((envContent.match(/AOP_PROVIDER_CONFIG_ENV=/g) ?? []).length).toBe(1);
|
|
525
|
+
});
|
|
293
526
|
});
|
|
294
527
|
|
|
295
528
|
describe('InitCommandHandler validation branches', () => {
|
|
@@ -306,7 +539,7 @@ describe('InitCommandHandler validation branches', () => {
|
|
|
306
539
|
});
|
|
307
540
|
|
|
308
541
|
it('GIVEN_skipped_file_WHEN_validation_loop_runs_THEN_skipped_rel_is_not_validated', async () => {
|
|
309
|
-
const orchestratorDir = path.join(cwd, 'agentic', 'orchestrator');
|
|
542
|
+
const orchestratorDir = path.join(cwd, 'config', 'agentic', 'orchestrator');
|
|
310
543
|
await fs.mkdir(orchestratorDir, { recursive: true });
|
|
311
544
|
// Pre-create policy.yaml so it gets skipped (no --force)
|
|
312
545
|
await fs.writeFile(path.join(orchestratorDir, 'policy.yaml'), '# existing\n', 'utf8');
|
|
@@ -317,7 +550,7 @@ describe('InitCommandHandler validation branches', () => {
|
|
|
317
550
|
|
|
318
551
|
expect(result.ok).toBe(true);
|
|
319
552
|
// policy.yaml was skipped, so the validation loop skipped it too (no error about it)
|
|
320
|
-
expect(result.data.skipped).toContain('agentic/orchestrator/policy.yaml');
|
|
553
|
+
expect(result.data.skipped).toContain('config/agentic/orchestrator/policy.yaml');
|
|
321
554
|
// Validation warnings should be empty (skipped file is not validated)
|
|
322
555
|
expect(result.data.validation_warnings).toHaveLength(0);
|
|
323
556
|
});
|
|
@@ -327,7 +560,7 @@ describe('InitCommandHandler validation branches', () => {
|
|
|
327
560
|
const { SchemaRegistry } = await import('../src/core/schemas.js');
|
|
328
561
|
const validateSpy = vi.spyOn(SchemaRegistry.prototype, 'validate').mockResolvedValue({
|
|
329
562
|
valid: false,
|
|
330
|
-
errors: [{ message: 'test-schema-error' } as any]
|
|
563
|
+
errors: [{ message: 'test-schema-error' } as any],
|
|
331
564
|
});
|
|
332
565
|
|
|
333
566
|
const handler = new InitCommandHandler(cwd);
|
|
@@ -342,9 +575,9 @@ describe('InitCommandHandler validation branches', () => {
|
|
|
342
575
|
it('GIVEN_schema_registry_throws_WHEN_init_runs_THEN_adds_catch_validation_warning', async () => {
|
|
343
576
|
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
344
577
|
const { SchemaRegistry } = await import('../src/core/schemas.js');
|
|
345
|
-
const validateSpy = vi
|
|
346
|
-
|
|
347
|
-
|
|
578
|
+
const validateSpy = vi
|
|
579
|
+
.spyOn(SchemaRegistry.prototype, 'validate')
|
|
580
|
+
.mockRejectedValue(new Error('schema-load-failure'));
|
|
348
581
|
|
|
349
582
|
const handler = new InitCommandHandler(cwd);
|
|
350
583
|
const result = await handler.execute({ auto: true });
|
|
@@ -356,19 +589,27 @@ describe('InitCommandHandler validation branches', () => {
|
|
|
356
589
|
});
|
|
357
590
|
|
|
358
591
|
it('GIVEN_skipped_non_policy_files_WHEN_validation_loop_runs_THEN_skipped_rels_are_not_validated', async () => {
|
|
359
|
-
const orchestratorDir = path.join(cwd, 'agentic', 'orchestrator');
|
|
592
|
+
const orchestratorDir = path.join(cwd, 'config', 'agentic', 'orchestrator');
|
|
360
593
|
await fs.mkdir(orchestratorDir, { recursive: true });
|
|
361
594
|
// Pre-create gates.yaml and agents.yaml so they get skipped (no --force)
|
|
362
|
-
await fs.writeFile(
|
|
363
|
-
|
|
595
|
+
await fs.writeFile(
|
|
596
|
+
path.join(orchestratorDir, 'gates.yaml'),
|
|
597
|
+
'version: 1\n# existing gates\n',
|
|
598
|
+
'utf8',
|
|
599
|
+
);
|
|
600
|
+
await fs.writeFile(
|
|
601
|
+
path.join(orchestratorDir, 'agents.yaml'),
|
|
602
|
+
'version: 1\n# existing agents\n',
|
|
603
|
+
'utf8',
|
|
604
|
+
);
|
|
364
605
|
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
365
606
|
|
|
366
607
|
const handler = new InitCommandHandler(cwd);
|
|
367
608
|
const result = await handler.execute({ auto: true });
|
|
368
609
|
|
|
369
610
|
expect(result.ok).toBe(true);
|
|
370
|
-
expect(result.data.skipped).toContain('agentic/orchestrator/gates.yaml');
|
|
371
|
-
expect(result.data.skipped).toContain('agentic/orchestrator/agents.yaml');
|
|
611
|
+
expect(result.data.skipped).toContain('config/agentic/orchestrator/gates.yaml');
|
|
612
|
+
expect(result.data.skipped).toContain('config/agentic/orchestrator/agents.yaml');
|
|
372
613
|
// Skipped files are not validated — no errors from their existing (partial) content
|
|
373
614
|
expect(result.data.validation_warnings).toHaveLength(0);
|
|
374
615
|
});
|
|
@@ -400,13 +641,16 @@ describe('InitCommandHandler codex activity detector branch', () => {
|
|
|
400
641
|
'3',
|
|
401
642
|
'3000',
|
|
402
643
|
'none',
|
|
403
|
-
'vitest'
|
|
644
|
+
'vitest',
|
|
404
645
|
]);
|
|
405
646
|
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
406
647
|
const result = await handler.execute({ auto: false });
|
|
407
648
|
|
|
408
649
|
expect(result.ok).toBe(true);
|
|
409
|
-
const adaptersContent = await fs.readFile(
|
|
650
|
+
const adaptersContent = await fs.readFile(
|
|
651
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'adapters.yaml'),
|
|
652
|
+
'utf8',
|
|
653
|
+
);
|
|
410
654
|
expect(adaptersContent).toContain('activity-detector: codex-rpc');
|
|
411
655
|
});
|
|
412
656
|
});
|
|
@@ -438,13 +682,16 @@ describe('InitCommandHandler webhook channel branch', () => {
|
|
|
438
682
|
'3000',
|
|
439
683
|
'webhook',
|
|
440
684
|
'jest',
|
|
441
|
-
'https://example.com/my-webhook'
|
|
685
|
+
'https://example.com/my-webhook',
|
|
442
686
|
]);
|
|
443
687
|
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
444
688
|
const result = await handler.execute({ auto: false });
|
|
445
689
|
|
|
446
690
|
expect(result.ok).toBe(true);
|
|
447
|
-
const policyContent = await fs.readFile(
|
|
691
|
+
const policyContent = await fs.readFile(
|
|
692
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
693
|
+
'utf8',
|
|
694
|
+
);
|
|
448
695
|
expect(policyContent).toContain('url: "https://example.com/my-webhook"');
|
|
449
696
|
});
|
|
450
697
|
});
|
|
@@ -475,13 +722,16 @@ describe('InitCommandHandler parseNotificationChannels none branch', () => {
|
|
|
475
722
|
'3',
|
|
476
723
|
'3000',
|
|
477
724
|
'none',
|
|
478
|
-
'jest'
|
|
725
|
+
'jest',
|
|
479
726
|
]);
|
|
480
727
|
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
481
728
|
const result = await handler.execute({ auto: false });
|
|
482
729
|
|
|
483
730
|
expect(result.ok).toBe(true);
|
|
484
|
-
const policyContent = await fs.readFile(
|
|
731
|
+
const policyContent = await fs.readFile(
|
|
732
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
733
|
+
'utf8',
|
|
734
|
+
);
|
|
485
735
|
expect(policyContent).toContain('notifications:');
|
|
486
736
|
});
|
|
487
737
|
});
|
|
@@ -505,8 +755,9 @@ describe('InitCommandHandler loadTemplateFiles non-file entry', () => {
|
|
|
505
755
|
execFileMock.mockResolvedValue({ stdout: 'origin/main\n', stderr: '' });
|
|
506
756
|
|
|
507
757
|
const readdirSpy = vi.spyOn(fs, 'readdir').mockImplementation(async (dirPath, opts) => {
|
|
508
|
-
const originalReaddir = (await vi.importActual<typeof FsPromises>('node:fs/promises'))
|
|
509
|
-
|
|
758
|
+
const originalReaddir = (await vi.importActual<typeof FsPromises>('node:fs/promises'))
|
|
759
|
+
.readdir;
|
|
760
|
+
const entries = await originalReaddir(dirPath, opts as never);
|
|
510
761
|
const fakeDir = {
|
|
511
762
|
name: 'subdir',
|
|
512
763
|
isFile: () => false,
|
|
@@ -517,7 +768,7 @@ describe('InitCommandHandler loadTemplateFiles non-file entry', () => {
|
|
|
517
768
|
isSocket: () => false,
|
|
518
769
|
isSymbolicLink: () => false,
|
|
519
770
|
parentPath: String(dirPath),
|
|
520
|
-
path: String(dirPath)
|
|
771
|
+
path: String(dirPath),
|
|
521
772
|
};
|
|
522
773
|
return [...entries, fakeDir] as never;
|
|
523
774
|
});
|
|
@@ -553,16 +804,19 @@ describe('InitCommandHandler parseInteger out-of-range and parseFramework fallba
|
|
|
553
804
|
'custom',
|
|
554
805
|
'local-default',
|
|
555
806
|
'github',
|
|
556
|
-
'0',
|
|
807
|
+
'0', // out of range (min=1) → parseInteger returns fallback 3
|
|
557
808
|
'3000',
|
|
558
809
|
'none',
|
|
559
|
-
'vitest'
|
|
810
|
+
'vitest',
|
|
560
811
|
]);
|
|
561
812
|
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
562
813
|
const result = await handler.execute({ auto: false });
|
|
563
814
|
|
|
564
815
|
expect(result.ok).toBe(true);
|
|
565
|
-
const policyContent = await fs.readFile(
|
|
816
|
+
const policyContent = await fs.readFile(
|
|
817
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
818
|
+
'utf8',
|
|
819
|
+
);
|
|
566
820
|
// Falls back to default 3
|
|
567
821
|
expect(policyContent).toContain('max_parallel_gate_runs: 3');
|
|
568
822
|
});
|
|
@@ -580,7 +834,7 @@ describe('InitCommandHandler parseInteger out-of-range and parseFramework fallba
|
|
|
580
834
|
'3',
|
|
581
835
|
'3000',
|
|
582
836
|
'none',
|
|
583
|
-
'unknown_framework'
|
|
837
|
+
'unknown_framework', // not vitest/jest/pytest/maven/gradle → parseFramework returns fallback
|
|
584
838
|
]);
|
|
585
839
|
const handler = new InitCommandHandler(cwd, prompts.factory);
|
|
586
840
|
const result = await handler.execute({ auto: false });
|
|
@@ -611,7 +865,10 @@ describe('InitCommandHandler lean vs advanced policy', () => {
|
|
|
611
865
|
expect(result.ok).toBe(true);
|
|
612
866
|
expect(result.data.validation_warnings).toHaveLength(0);
|
|
613
867
|
|
|
614
|
-
const policyContent = await fs.readFile(
|
|
868
|
+
const policyContent = await fs.readFile(
|
|
869
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
870
|
+
'utf8',
|
|
871
|
+
);
|
|
615
872
|
// Lean policy contains common controls
|
|
616
873
|
expect(policyContent).toContain('worktree:');
|
|
617
874
|
expect(policyContent).toContain('base_branch:');
|
|
@@ -638,7 +895,10 @@ describe('InitCommandHandler lean vs advanced policy', () => {
|
|
|
638
895
|
expect(result.ok).toBe(true);
|
|
639
896
|
expect(result.data.validation_warnings).toHaveLength(0);
|
|
640
897
|
|
|
641
|
-
const policyContent = await fs.readFile(
|
|
898
|
+
const policyContent = await fs.readFile(
|
|
899
|
+
path.join(cwd, 'config', 'agentic', 'orchestrator', 'policy.yaml'),
|
|
900
|
+
'utf8',
|
|
901
|
+
);
|
|
642
902
|
// Full policy contains advanced controls
|
|
643
903
|
expect(policyContent).toContain('commit_policy:');
|
|
644
904
|
expect(policyContent).toContain('patch_policy:');
|