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
|
@@ -1,24 +1,47 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ensureDir,
|
|
5
|
+
pathExists,
|
|
6
|
+
readJson,
|
|
7
|
+
atomicWriteJson,
|
|
8
|
+
atomicWriteFile,
|
|
9
|
+
withFileLock,
|
|
10
|
+
nowIso,
|
|
11
|
+
stableHash,
|
|
12
|
+
} from './fs.js';
|
|
4
13
|
import { SchemaRegistry, loadAndValidateYaml } from './schemas.js';
|
|
5
14
|
import { normalizeRepoPath } from './path-rules.js';
|
|
6
15
|
import { parseFrontMatter, buildFrontMatter } from './frontmatter.js';
|
|
7
16
|
import { runGit, runCommand } from './git.js';
|
|
8
17
|
import { ERROR_CODES } from './error-codes.js';
|
|
9
18
|
import { ok, fail, withSuggestedActions, type ToolResponse } from './response.js';
|
|
10
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
ALLOWED_ACTORS,
|
|
21
|
+
DEFAULT_CLUSTER,
|
|
22
|
+
DEFAULT_ROLE_STATUS,
|
|
23
|
+
GATE_RESULT,
|
|
24
|
+
STATUS,
|
|
25
|
+
TOOLS,
|
|
26
|
+
} from './constants.js';
|
|
11
27
|
import { AopPathLayout, ensureAopRuntimeLayout } from './path-layout.js';
|
|
12
28
|
import {
|
|
13
29
|
applyWorktreeSymlinks,
|
|
14
30
|
formatWorkspaceHookWarning,
|
|
15
31
|
runWorktreePostCreate,
|
|
16
|
-
type WorkspaceHookWarning
|
|
32
|
+
type WorkspaceHookWarning,
|
|
17
33
|
} from './workspace-hooks.js';
|
|
18
34
|
import type { RuntimeSessionsSnapshot } from './runtime-sessions.js';
|
|
19
35
|
import { ToolRegistryLoader } from '../mcp/tool-registry-loader.js';
|
|
20
|
-
import {
|
|
21
|
-
|
|
36
|
+
import {
|
|
37
|
+
ToolHandlerRegistry,
|
|
38
|
+
ToolRouter,
|
|
39
|
+
type ToolHandlerContext,
|
|
40
|
+
} from '../application/tools/tool-router.js';
|
|
41
|
+
import {
|
|
42
|
+
RunLeaseService,
|
|
43
|
+
type AcquireRunLeaseInput,
|
|
44
|
+
} from '../application/services/run-lease-service.js';
|
|
22
45
|
import { LockService } from '../application/services/lock-service.js';
|
|
23
46
|
import { ReportingService } from '../application/services/reporting-service.js';
|
|
24
47
|
import { FeatureStateService } from '../application/services/feature-state-service.js';
|
|
@@ -29,15 +52,21 @@ import { GateService } from '../application/services/gate-service.js';
|
|
|
29
52
|
import { QaIndexService } from '../application/services/qa-index-service.js';
|
|
30
53
|
import { MergeService } from '../application/services/merge-service.js';
|
|
31
54
|
import { CollisionQueueService } from '../application/services/collision-queue-service.js';
|
|
32
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
FeatureDeletionService,
|
|
57
|
+
type FeatureDeleteResult,
|
|
58
|
+
} from '../application/services/feature-deletion-service.js';
|
|
33
59
|
import { CostTrackingService } from '../application/services/cost-tracking-service.js';
|
|
34
|
-
import {
|
|
60
|
+
import {
|
|
61
|
+
PerformanceAnalyticsService,
|
|
62
|
+
type FeatureOutcome,
|
|
63
|
+
} from '../application/services/performance-analytics-service.js';
|
|
35
64
|
import { loadComposedPolicy } from '../application/services/policy-loader-service.js';
|
|
36
65
|
import {
|
|
37
66
|
ACTIVITY_DETECTOR_SLOT,
|
|
38
67
|
NOTIFICATION_CHANNEL_SLOT,
|
|
39
68
|
SCM_PROVIDER_SLOT,
|
|
40
|
-
globalAdapterRegistry
|
|
69
|
+
globalAdapterRegistry,
|
|
41
70
|
} from '../application/adapters/adapter-registry.js';
|
|
42
71
|
import type { WorkerProvider } from '../providers/providers.js';
|
|
43
72
|
|
|
@@ -137,7 +166,11 @@ export class AopKernel {
|
|
|
137
166
|
private provider: WorkerProvider | null = null;
|
|
138
167
|
private readonly configOverrides: KernelConfigOverrides;
|
|
139
168
|
|
|
140
|
-
constructor(
|
|
169
|
+
constructor(
|
|
170
|
+
repoRoot: string,
|
|
171
|
+
instanceId = 'default',
|
|
172
|
+
configOverrides: KernelConfigOverrides = {},
|
|
173
|
+
) {
|
|
141
174
|
this.repoRoot = repoRoot;
|
|
142
175
|
this.instanceId = instanceId;
|
|
143
176
|
this.configOverrides = configOverrides;
|
|
@@ -169,9 +202,9 @@ export class AopKernel {
|
|
|
169
202
|
Promise.resolve(
|
|
170
203
|
fail(ERROR_CODES.INVALID_ARGUMENT, `Unknown tool ${toolName}`, {
|
|
171
204
|
retryable: false,
|
|
172
|
-
requires_human: true
|
|
173
|
-
})
|
|
174
|
-
)
|
|
205
|
+
requires_human: true,
|
|
206
|
+
}),
|
|
207
|
+
),
|
|
175
208
|
);
|
|
176
209
|
}
|
|
177
210
|
|
|
@@ -244,7 +277,7 @@ export class AopKernel {
|
|
|
244
277
|
last_heartbeat_at: at,
|
|
245
278
|
lease_expires_at: at,
|
|
246
279
|
orchestrator_epoch: 0,
|
|
247
|
-
feature_sessions: {}
|
|
280
|
+
feature_sessions: {},
|
|
248
281
|
};
|
|
249
282
|
}
|
|
250
283
|
|
|
@@ -267,7 +300,7 @@ export class AopKernel {
|
|
|
267
300
|
typeof typed.planner_session_id === 'string' ? typed.planner_session_id : 'unassigned',
|
|
268
301
|
builder_session_id:
|
|
269
302
|
typeof typed.builder_session_id === 'string' ? typed.builder_session_id : 'unassigned',
|
|
270
|
-
qa_session_id: typeof typed.qa_session_id === 'string' ? typed.qa_session_id : 'unassigned'
|
|
303
|
+
qa_session_id: typeof typed.qa_session_id === 'string' ? typed.qa_session_id : 'unassigned',
|
|
271
304
|
};
|
|
272
305
|
}
|
|
273
306
|
|
|
@@ -282,7 +315,10 @@ export class AopKernel {
|
|
|
282
315
|
typeof source.orchestrator_session_id === 'string' && source.orchestrator_session_id
|
|
283
316
|
? source.orchestrator_session_id
|
|
284
317
|
: fallback.orchestrator_session_id,
|
|
285
|
-
provider:
|
|
318
|
+
provider:
|
|
319
|
+
typeof source.provider === 'string' && source.provider
|
|
320
|
+
? source.provider
|
|
321
|
+
: fallback.provider,
|
|
286
322
|
model: typeof source.model === 'string' && source.model ? source.model : fallback.model,
|
|
287
323
|
provider_config_ref_hash:
|
|
288
324
|
typeof source.provider_config_ref_hash === 'string' && source.provider_config_ref_hash
|
|
@@ -292,8 +328,14 @@ export class AopKernel {
|
|
|
292
328
|
typeof source.owner_instance_id === 'string' && source.owner_instance_id
|
|
293
329
|
? source.owner_instance_id
|
|
294
330
|
: fallback.owner_instance_id,
|
|
295
|
-
lease_id:
|
|
296
|
-
|
|
331
|
+
lease_id:
|
|
332
|
+
typeof source.lease_id === 'string' && source.lease_id
|
|
333
|
+
? source.lease_id
|
|
334
|
+
: fallback.lease_id,
|
|
335
|
+
started_at:
|
|
336
|
+
typeof source.started_at === 'string' && source.started_at
|
|
337
|
+
? source.started_at
|
|
338
|
+
: fallback.started_at,
|
|
297
339
|
last_heartbeat_at:
|
|
298
340
|
typeof source.last_heartbeat_at === 'string' && source.last_heartbeat_at
|
|
299
341
|
? source.last_heartbeat_at
|
|
@@ -303,7 +345,7 @@ export class AopKernel {
|
|
|
303
345
|
? source.lease_expires_at
|
|
304
346
|
: fallback.lease_expires_at,
|
|
305
347
|
orchestrator_epoch: epoch,
|
|
306
|
-
feature_sessions: featureSessions
|
|
348
|
+
feature_sessions: featureSessions,
|
|
307
349
|
};
|
|
308
350
|
}
|
|
309
351
|
|
|
@@ -311,16 +353,29 @@ export class AopKernel {
|
|
|
311
353
|
const now = nowIso();
|
|
312
354
|
const source = value && typeof value === 'object' ? (value as Record<string, unknown>) : {};
|
|
313
355
|
return {
|
|
314
|
-
version:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
356
|
+
version:
|
|
357
|
+
typeof source.version === 'number' && Number.isFinite(source.version)
|
|
358
|
+
? Math.max(1, Math.floor(source.version))
|
|
359
|
+
: 1,
|
|
360
|
+
active: normalizeSet(
|
|
361
|
+
asArray<string>(source.active).filter((item) => typeof item === 'string'),
|
|
362
|
+
),
|
|
363
|
+
blocked: normalizeSet(
|
|
364
|
+
asArray<string>(source.blocked).filter((item) => typeof item === 'string'),
|
|
365
|
+
),
|
|
366
|
+
merged: normalizeSet(
|
|
367
|
+
asArray<string>(source.merged).filter((item) => typeof item === 'string'),
|
|
368
|
+
),
|
|
318
369
|
locks: source.locks && typeof source.locks === 'object' ? source.locks : {},
|
|
319
|
-
lock_leases:
|
|
320
|
-
|
|
370
|
+
lock_leases:
|
|
371
|
+
source.lock_leases && typeof source.lock_leases === 'object' ? source.lock_leases : {},
|
|
372
|
+
blocked_queue: asArray(source.blocked_queue).filter(
|
|
373
|
+
(item) => item && typeof item === 'object',
|
|
374
|
+
),
|
|
321
375
|
dep_blocked: asArray(source.dep_blocked).filter((item) => item && typeof item === 'object'),
|
|
322
|
-
updated_at:
|
|
323
|
-
|
|
376
|
+
updated_at:
|
|
377
|
+
typeof source.updated_at === 'string' && source.updated_at ? source.updated_at : now,
|
|
378
|
+
runtime_sessions: this.normalizeRuntimeSessions(source.runtime_sessions, now),
|
|
324
379
|
};
|
|
325
380
|
}
|
|
326
381
|
|
|
@@ -332,20 +387,40 @@ export class AopKernel {
|
|
|
332
387
|
return expiry > Date.now();
|
|
333
388
|
}
|
|
334
389
|
|
|
390
|
+
private async resolveDefaultConfigPath(fileName: string): Promise<string> {
|
|
391
|
+
const primary = path.join(this.pathLayout.orchestratorRoot, fileName);
|
|
392
|
+
if (await pathExists(primary)) {
|
|
393
|
+
return primary;
|
|
394
|
+
}
|
|
395
|
+
const legacy = path.join(this.pathLayout.legacyOrchestratorRoot, fileName);
|
|
396
|
+
if (await pathExists(legacy)) {
|
|
397
|
+
return legacy;
|
|
398
|
+
}
|
|
399
|
+
return primary;
|
|
400
|
+
}
|
|
401
|
+
|
|
335
402
|
async load() {
|
|
336
403
|
await ensureAopRuntimeLayout(this.pathLayout);
|
|
337
404
|
|
|
338
|
-
const gatesPath =
|
|
339
|
-
|
|
340
|
-
const
|
|
341
|
-
|
|
405
|
+
const gatesPath =
|
|
406
|
+
this.configOverrides.gatesPath ?? (await this.resolveDefaultConfigPath('gates.yaml'));
|
|
407
|
+
const policyPath =
|
|
408
|
+
this.configOverrides.policyPath ?? (await this.resolveDefaultConfigPath('policy.yaml'));
|
|
409
|
+
const agentsPath =
|
|
410
|
+
this.configOverrides.agentsPath ?? (await this.resolveDefaultConfigPath('agents.yaml'));
|
|
411
|
+
const adaptersPath =
|
|
412
|
+
this.configOverrides.adaptersPath ?? (await this.resolveDefaultConfigPath('adapters.yaml'));
|
|
342
413
|
|
|
343
414
|
const gates = await loadAndValidateYaml(this.schemaRegistry, 'gates.schema.json', gatesPath);
|
|
344
415
|
if (!gates.validation.valid) {
|
|
345
416
|
throw new Error(`invalid_gates_yaml:${JSON.stringify(gates.validation.errors)}`);
|
|
346
417
|
}
|
|
347
418
|
|
|
348
|
-
const { mergedPolicy } = await loadComposedPolicy(
|
|
419
|
+
const { mergedPolicy } = await loadComposedPolicy(
|
|
420
|
+
this.repoRoot,
|
|
421
|
+
policyPath,
|
|
422
|
+
this.schemaRegistry,
|
|
423
|
+
);
|
|
349
424
|
const parsedPolicy = mergedPolicy as PolicyConfigSnapshot;
|
|
350
425
|
const implementation = readObjectField(parsedPolicy, 'implementation');
|
|
351
426
|
const testing = readObjectField(parsedPolicy, 'testing');
|
|
@@ -369,7 +444,11 @@ export class AopKernel {
|
|
|
369
444
|
const adaptersExists = await pathExists(adaptersPath);
|
|
370
445
|
let adapters = { parsed: {}, validation: { valid: true, errors: [] as unknown[] } };
|
|
371
446
|
if (adaptersExists) {
|
|
372
|
-
adapters = await loadAndValidateYaml(
|
|
447
|
+
adapters = await loadAndValidateYaml(
|
|
448
|
+
this.schemaRegistry,
|
|
449
|
+
'adapters.schema.json',
|
|
450
|
+
adaptersPath,
|
|
451
|
+
);
|
|
373
452
|
if (!adapters.validation.valid) {
|
|
374
453
|
throw new Error(`invalid_adapters_yaml:${JSON.stringify(adapters.validation.errors)}`);
|
|
375
454
|
}
|
|
@@ -379,7 +458,9 @@ export class AopKernel {
|
|
|
379
458
|
try {
|
|
380
459
|
globalAdapterRegistry.resolve(NOTIFICATION_CHANNEL_SLOT, notificationChannel, {});
|
|
381
460
|
} catch {
|
|
382
|
-
throw new Error(
|
|
461
|
+
throw new Error(
|
|
462
|
+
`adapter_not_found:${NOTIFICATION_CHANNEL_SLOT.name}:${notificationChannel}`,
|
|
463
|
+
);
|
|
383
464
|
}
|
|
384
465
|
}
|
|
385
466
|
const activityDetector = readStringField(parsedAdapters, ACTIVITY_DETECTOR_SLOT.name);
|
|
@@ -427,7 +508,11 @@ export class AopKernel {
|
|
|
427
508
|
return allowedTools.includes(toolName);
|
|
428
509
|
}
|
|
429
510
|
|
|
430
|
-
async invoke(
|
|
511
|
+
async invoke(
|
|
512
|
+
toolName: string,
|
|
513
|
+
args: AnyRecord = {},
|
|
514
|
+
context: KernelContext = {},
|
|
515
|
+
): Promise<AnyRecord> {
|
|
431
516
|
await this.ensureLoaded();
|
|
432
517
|
const actorType = context.actor_type ?? 'system';
|
|
433
518
|
const actorId = context.actor_id ?? 'system';
|
|
@@ -436,7 +521,10 @@ export class AopKernel {
|
|
|
436
521
|
return fail(
|
|
437
522
|
ERROR_CODES.FORBIDDEN_TOOL_FOR_ROLE,
|
|
438
523
|
`Tool ${toolName} is not allowed for role ${actorType}`,
|
|
439
|
-
withSuggestedActions(
|
|
524
|
+
withSuggestedActions(
|
|
525
|
+
{ actor_type: actorType, tool_name: toolName, retryable: false, requires_human: true },
|
|
526
|
+
['Use orchestrator role for this operation'],
|
|
527
|
+
),
|
|
440
528
|
);
|
|
441
529
|
}
|
|
442
530
|
|
|
@@ -466,14 +554,14 @@ export class AopKernel {
|
|
|
466
554
|
if (text.startsWith('path_out_of_bounds')) {
|
|
467
555
|
return fail(ERROR_CODES.PATH_OUT_OF_BOUNDS, 'Path escapes repository root', {
|
|
468
556
|
retryable: false,
|
|
469
|
-
requires_human: true
|
|
557
|
+
requires_human: true,
|
|
470
558
|
});
|
|
471
559
|
}
|
|
472
560
|
|
|
473
561
|
if (text.startsWith('lock_timeout:')) {
|
|
474
562
|
return fail(ERROR_CODES.LOCK_CONFLICT, 'Timed out waiting for lock', {
|
|
475
563
|
retryable: true,
|
|
476
|
-
requires_human: false
|
|
564
|
+
requires_human: false,
|
|
477
565
|
});
|
|
478
566
|
}
|
|
479
567
|
|
|
@@ -481,7 +569,7 @@ export class AopKernel {
|
|
|
481
569
|
return fail(ERROR_CODES.UNKNOWN_GATE_PROFILE_OR_MODE, 'Unknown gate profile or mode', {
|
|
482
570
|
value: text.split(':')[1],
|
|
483
571
|
retryable: false,
|
|
484
|
-
requires_human: true
|
|
572
|
+
requires_human: true,
|
|
485
573
|
});
|
|
486
574
|
}
|
|
487
575
|
|
|
@@ -489,140 +577,234 @@ export class AopKernel {
|
|
|
489
577
|
return fail(ERROR_CODES.UNSUPPORTED_PARSER, 'Gate parser type is not supported', {
|
|
490
578
|
parser: text.split(':')[1],
|
|
491
579
|
retryable: false,
|
|
492
|
-
requires_human: true
|
|
580
|
+
requires_human: true,
|
|
493
581
|
});
|
|
494
582
|
}
|
|
495
583
|
|
|
496
584
|
if (text.includes('qa_index_version_conflict')) {
|
|
497
|
-
return fail(
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
585
|
+
return fail(
|
|
586
|
+
ERROR_CODES.QA_INDEX_VERSION_CONFLICT,
|
|
587
|
+
'QA index expected_version did not match current version',
|
|
588
|
+
{
|
|
589
|
+
retryable: true,
|
|
590
|
+
requires_human: false,
|
|
591
|
+
},
|
|
592
|
+
);
|
|
501
593
|
}
|
|
502
594
|
|
|
503
595
|
return fail(ERROR_CODES.INTERNAL_ERROR, text, {
|
|
504
596
|
retryable: false,
|
|
505
|
-
requires_human: true
|
|
597
|
+
requires_human: true,
|
|
506
598
|
});
|
|
507
599
|
}
|
|
508
600
|
|
|
509
|
-
async dispatchTool(
|
|
601
|
+
async dispatchTool(
|
|
602
|
+
toolName: string,
|
|
603
|
+
args: AnyRecord,
|
|
604
|
+
context: ToolHandlerContext,
|
|
605
|
+
): Promise<unknown> {
|
|
510
606
|
return await this.toolRouter.route(toolName, args, context);
|
|
511
607
|
}
|
|
512
608
|
|
|
513
609
|
private registerToolHandlers(): void {
|
|
514
|
-
this.toolHandlers.register(
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
await this.featureGetContext(readStringField(args, 'feature_id'))
|
|
610
|
+
this.toolHandlers.register(
|
|
611
|
+
TOOLS.FEATURE_DISCOVER_SPECS,
|
|
612
|
+
async () => await this.featureDiscoverSpecs(),
|
|
518
613
|
);
|
|
519
|
-
this.toolHandlers.register(
|
|
520
|
-
|
|
614
|
+
this.toolHandlers.register(
|
|
615
|
+
TOOLS.FEATURE_INIT,
|
|
616
|
+
async (args) => await this.featureInit(readStringField(args, 'feature_id')),
|
|
521
617
|
);
|
|
522
|
-
this.toolHandlers.register(
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
readNumberField(args, 'expected_version'),
|
|
526
|
-
args.patch
|
|
527
|
-
)
|
|
618
|
+
this.toolHandlers.register(
|
|
619
|
+
TOOLS.FEATURE_GET_CONTEXT,
|
|
620
|
+
async (args) => await this.featureGetContext(readStringField(args, 'feature_id')),
|
|
528
621
|
);
|
|
529
|
-
this.toolHandlers.register(
|
|
530
|
-
|
|
622
|
+
this.toolHandlers.register(
|
|
623
|
+
TOOLS.FEATURE_STATE_GET,
|
|
624
|
+
async (args) => await this.featureStateGet(readStringField(args, 'feature_id')),
|
|
531
625
|
);
|
|
532
|
-
this.toolHandlers.register(
|
|
533
|
-
|
|
626
|
+
this.toolHandlers.register(
|
|
627
|
+
TOOLS.FEATURE_STATE_PATCH,
|
|
628
|
+
async (args) =>
|
|
629
|
+
await this.featureStatePatch(
|
|
630
|
+
readStringField(args, 'feature_id'),
|
|
631
|
+
readNumberField(args, 'expected_version'),
|
|
632
|
+
args.patch,
|
|
633
|
+
),
|
|
534
634
|
);
|
|
535
|
-
this.toolHandlers.register(
|
|
536
|
-
|
|
537
|
-
|
|
635
|
+
this.toolHandlers.register(
|
|
636
|
+
TOOLS.FEATURE_LOG_APPEND,
|
|
637
|
+
async (args, context) =>
|
|
638
|
+
await this.featureLogAppend(
|
|
639
|
+
readStringField(args, 'feature_id'),
|
|
640
|
+
readStringField(args, 'note'),
|
|
641
|
+
context,
|
|
642
|
+
),
|
|
538
643
|
);
|
|
539
|
-
this.toolHandlers.register(
|
|
540
|
-
|
|
644
|
+
this.toolHandlers.register(
|
|
645
|
+
TOOLS.PLAN_SUBMIT,
|
|
646
|
+
async (args) =>
|
|
647
|
+
await this.planSubmit(
|
|
648
|
+
readStringField(args, 'feature_id'),
|
|
649
|
+
args.plan_json,
|
|
650
|
+
readNumberField(args, 'expected_version'),
|
|
651
|
+
),
|
|
541
652
|
);
|
|
542
|
-
this.toolHandlers.register(
|
|
543
|
-
|
|
653
|
+
this.toolHandlers.register(
|
|
654
|
+
TOOLS.PLAN_GET,
|
|
655
|
+
async (args) => await this.planGet(readStringField(args, 'feature_id')),
|
|
544
656
|
);
|
|
545
|
-
this.toolHandlers.register(
|
|
546
|
-
|
|
547
|
-
|
|
657
|
+
this.toolHandlers.register(
|
|
658
|
+
TOOLS.PLAN_UPDATE,
|
|
659
|
+
async (args) =>
|
|
660
|
+
await this.planUpdate(
|
|
661
|
+
readStringField(args, 'feature_id'),
|
|
662
|
+
readNumberField(args, 'expected_plan_version'),
|
|
663
|
+
args.plan_json,
|
|
664
|
+
),
|
|
548
665
|
);
|
|
549
|
-
this.toolHandlers.register(
|
|
550
|
-
|
|
666
|
+
this.toolHandlers.register(
|
|
667
|
+
TOOLS.REPO_ENSURE_WORKTREE,
|
|
668
|
+
async (args) => await this.repoEnsureWorktree(readStringField(args, 'feature_id')),
|
|
551
669
|
);
|
|
552
|
-
this.toolHandlers.register(
|
|
553
|
-
|
|
670
|
+
this.toolHandlers.register(
|
|
671
|
+
TOOLS.REPO_APPLY_PATCH,
|
|
672
|
+
async (args) =>
|
|
673
|
+
await this.repoApplyPatch(
|
|
674
|
+
readStringField(args, 'feature_id'),
|
|
675
|
+
readStringField(args, 'unified_diff'),
|
|
676
|
+
),
|
|
554
677
|
);
|
|
555
|
-
this.toolHandlers.register(
|
|
556
|
-
|
|
678
|
+
this.toolHandlers.register(
|
|
679
|
+
TOOLS.REPO_STATUS,
|
|
680
|
+
async (args) => await this.repoStatus(readStringField(args, 'feature_id')),
|
|
557
681
|
);
|
|
558
|
-
this.toolHandlers.register(
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
readStringField(args, '
|
|
562
|
-
readStringField(args, 'merge_strategy'),
|
|
563
|
-
readStringField(args, 'user_approval_token')
|
|
564
|
-
)
|
|
682
|
+
this.toolHandlers.register(
|
|
683
|
+
TOOLS.REPO_DIFF,
|
|
684
|
+
async (args) =>
|
|
685
|
+
await this.repoDiff(readStringField(args, 'feature_id'), asArray<string>(args.options)),
|
|
565
686
|
);
|
|
566
|
-
this.toolHandlers.register(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
readBooleanField(args, 'confirm'),
|
|
571
|
-
readBooleanField(args, 'remove_worktree'),
|
|
572
|
-
readStringField(args, 'remove_branch')
|
|
573
|
-
)
|
|
687
|
+
this.toolHandlers.register(
|
|
688
|
+
TOOLS.REPO_READ_FILE,
|
|
689
|
+
async (args) =>
|
|
690
|
+
await this.repoReadFile(readStringField(args, 'feature_id'), readStringField(args, 'path')),
|
|
574
691
|
);
|
|
575
|
-
this.toolHandlers.register(
|
|
576
|
-
|
|
577
|
-
|
|
692
|
+
this.toolHandlers.register(
|
|
693
|
+
TOOLS.REPO_SEARCH,
|
|
694
|
+
async (args) =>
|
|
695
|
+
await this.repoSearch(readStringField(args, 'feature_id'), readStringField(args, 'query')),
|
|
578
696
|
);
|
|
579
|
-
this.toolHandlers.register(
|
|
580
|
-
|
|
697
|
+
this.toolHandlers.register(
|
|
698
|
+
TOOLS.REPO_DIFF_BUNDLE,
|
|
699
|
+
async (args) => await this.repoDiffBundle(readStringField(args, 'feature_id')),
|
|
581
700
|
);
|
|
582
|
-
this.toolHandlers.register(
|
|
583
|
-
|
|
701
|
+
this.toolHandlers.register(
|
|
702
|
+
TOOLS.FEATURE_READY_TO_MERGE,
|
|
703
|
+
async (args) =>
|
|
704
|
+
await this.featureReadyToMerge(
|
|
705
|
+
readStringField(args, 'feature_id'),
|
|
706
|
+
readStringField(args, 'commit_message'),
|
|
707
|
+
readStringField(args, 'merge_strategy'),
|
|
708
|
+
readStringField(args, 'user_approval_token'),
|
|
709
|
+
),
|
|
584
710
|
);
|
|
585
|
-
this.toolHandlers.register(
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
711
|
+
this.toolHandlers.register(
|
|
712
|
+
TOOLS.FEATURE_DELETE,
|
|
713
|
+
async (args) =>
|
|
714
|
+
await this.featureDelete(
|
|
715
|
+
readStringField(args, 'feature_id'),
|
|
716
|
+
readBooleanField(args, 'dry_run'),
|
|
717
|
+
readBooleanField(args, 'confirm'),
|
|
718
|
+
readBooleanField(args, 'remove_worktree'),
|
|
719
|
+
readStringField(args, 'remove_branch'),
|
|
720
|
+
),
|
|
592
721
|
);
|
|
593
|
-
this.toolHandlers.register(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
readStringField(args, 'feature_id'),
|
|
597
|
-
readNumberField(args, 'wait_timeout_seconds')
|
|
598
|
-
)
|
|
722
|
+
this.toolHandlers.register(
|
|
723
|
+
TOOLS.GATES_LIST,
|
|
724
|
+
async (args) => await this.gatesList(readStringField(args, 'profile')),
|
|
599
725
|
);
|
|
600
|
-
this.toolHandlers.register(
|
|
601
|
-
|
|
726
|
+
this.toolHandlers.register(
|
|
727
|
+
TOOLS.GATES_RUN,
|
|
728
|
+
async (args) =>
|
|
729
|
+
await this.gatesRun(
|
|
730
|
+
readStringField(args, 'feature_id'),
|
|
731
|
+
readStringField(args, 'profile'),
|
|
732
|
+
readStringField(args, 'mode'),
|
|
733
|
+
),
|
|
734
|
+
);
|
|
735
|
+
this.toolHandlers.register(
|
|
736
|
+
TOOLS.EVIDENCE_LATEST,
|
|
737
|
+
async (args) => await this.evidenceLatest(readStringField(args, 'feature_id')),
|
|
738
|
+
);
|
|
739
|
+
this.toolHandlers.register(
|
|
740
|
+
TOOLS.QA_TEST_INDEX_GET,
|
|
741
|
+
async (args) => await this.qaTestIndexGet(readStringField(args, 'feature_id')),
|
|
742
|
+
);
|
|
743
|
+
this.toolHandlers.register(
|
|
744
|
+
TOOLS.QA_TEST_INDEX_UPDATE,
|
|
745
|
+
async (args) =>
|
|
746
|
+
await this.qaTestIndexUpdate(
|
|
747
|
+
readStringField(args, 'feature_id'),
|
|
748
|
+
readNumberField(args, 'expected_version'),
|
|
749
|
+
args.updates,
|
|
750
|
+
asArray(args.evidence_refs),
|
|
751
|
+
),
|
|
752
|
+
);
|
|
753
|
+
this.toolHandlers.register(
|
|
754
|
+
TOOLS.LOCKS_ACQUIRE,
|
|
755
|
+
async (args) =>
|
|
756
|
+
await this.locksAcquire(
|
|
757
|
+
readStringField(args, 'resource'),
|
|
758
|
+
readStringField(args, 'feature_id'),
|
|
759
|
+
readNumberField(args, 'wait_timeout_seconds'),
|
|
760
|
+
),
|
|
761
|
+
);
|
|
762
|
+
this.toolHandlers.register(
|
|
763
|
+
TOOLS.LOCKS_RELEASE,
|
|
764
|
+
async (args) =>
|
|
765
|
+
await this.locksRelease(
|
|
766
|
+
readStringField(args, 'resource'),
|
|
767
|
+
readStringField(args, 'feature_id'),
|
|
768
|
+
),
|
|
602
769
|
);
|
|
603
770
|
this.toolHandlers.register(TOOLS.COLLISIONS_SCAN, async () => await this.collisionsScan());
|
|
604
771
|
this.toolHandlers.register(TOOLS.REPORT_DASHBOARD, async () => await this.reportDashboard());
|
|
605
|
-
this.toolHandlers.register(
|
|
606
|
-
|
|
772
|
+
this.toolHandlers.register(
|
|
773
|
+
TOOLS.REPORT_FEATURE_SUMMARY,
|
|
774
|
+
async (args) => await this.reportFeatureSummary(readStringField(args, 'feature_id')),
|
|
607
775
|
);
|
|
608
|
-
this.toolHandlers.register(
|
|
609
|
-
|
|
776
|
+
this.toolHandlers.register(
|
|
777
|
+
TOOLS.FEATURE_SEND_MESSAGE,
|
|
778
|
+
async (args) =>
|
|
779
|
+
await this.featureSendMessage(
|
|
780
|
+
readStringField(args, 'feature_id'),
|
|
781
|
+
readStringField(args, 'message'),
|
|
782
|
+
),
|
|
610
783
|
);
|
|
611
|
-
this.toolHandlers.register(
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
784
|
+
this.toolHandlers.register(
|
|
785
|
+
TOOLS.COST_RECORD,
|
|
786
|
+
async (args) =>
|
|
787
|
+
await this.costRecord(
|
|
788
|
+
readStringField(args, 'feature_id'),
|
|
789
|
+
typeof args.tokens_used_delta === 'number' ? args.tokens_used_delta : 0,
|
|
790
|
+
typeof args.estimated_cost_usd_delta === 'number' ? args.estimated_cost_usd_delta : 0,
|
|
791
|
+
),
|
|
617
792
|
);
|
|
618
|
-
this.toolHandlers.register(
|
|
619
|
-
|
|
793
|
+
this.toolHandlers.register(
|
|
794
|
+
TOOLS.COST_GET,
|
|
795
|
+
async (args) => await this.costGet(readStringField(args, 'feature_id')),
|
|
620
796
|
);
|
|
621
|
-
this.toolHandlers.register(
|
|
622
|
-
|
|
797
|
+
this.toolHandlers.register(
|
|
798
|
+
TOOLS.PERFORMANCE_RECORD_OUTCOME,
|
|
799
|
+
async (args) => await this.performanceRecordOutcome(args),
|
|
623
800
|
);
|
|
624
|
-
this.toolHandlers.register(
|
|
625
|
-
|
|
801
|
+
this.toolHandlers.register(
|
|
802
|
+
TOOLS.PERFORMANCE_GET_ANALYTICS,
|
|
803
|
+
async (args) =>
|
|
804
|
+
await this.performanceGetAnalytics(
|
|
805
|
+
readStringField(args, 'provider'),
|
|
806
|
+
readStringField(args, 'model'),
|
|
807
|
+
),
|
|
626
808
|
);
|
|
627
809
|
}
|
|
628
810
|
|
|
@@ -697,30 +879,32 @@ export class AopKernel {
|
|
|
697
879
|
plan: GATE_RESULT.NA,
|
|
698
880
|
fast: GATE_RESULT.NA,
|
|
699
881
|
full: GATE_RESULT.NA,
|
|
700
|
-
merge: GATE_RESULT.NA
|
|
882
|
+
merge: GATE_RESULT.NA,
|
|
701
883
|
},
|
|
702
884
|
locks: {
|
|
703
|
-
held: []
|
|
885
|
+
held: [],
|
|
704
886
|
},
|
|
705
887
|
collisions: {
|
|
706
888
|
files: [],
|
|
707
889
|
areas: [],
|
|
708
|
-
contracts: []
|
|
890
|
+
contracts: [],
|
|
709
891
|
},
|
|
710
892
|
cluster: { ...DEFAULT_CLUSTER },
|
|
711
893
|
role_status: { ...DEFAULT_ROLE_STATUS },
|
|
712
|
-
last_updated: nowIso()
|
|
894
|
+
last_updated: nowIso(),
|
|
713
895
|
};
|
|
714
896
|
}
|
|
715
897
|
|
|
716
|
-
async readState(
|
|
898
|
+
async readState(
|
|
899
|
+
featureId: string,
|
|
900
|
+
): Promise<{ frontMatter: AnyRecord; body: string; raw: string }> {
|
|
717
901
|
const filePath = this.statePath(featureId);
|
|
718
902
|
const raw = await fs.readFile(filePath, 'utf8');
|
|
719
903
|
const parsed = parseFrontMatter(raw);
|
|
720
904
|
return {
|
|
721
905
|
frontMatter: parsed.frontMatter,
|
|
722
906
|
body: parsed.body,
|
|
723
|
-
raw
|
|
907
|
+
raw,
|
|
724
908
|
};
|
|
725
909
|
}
|
|
726
910
|
|
|
@@ -728,11 +912,15 @@ export class AopKernel {
|
|
|
728
912
|
const validation = await this.schemaRegistry.validate('state.schema.json', frontMatter);
|
|
729
913
|
if (!validation.valid) {
|
|
730
914
|
throw {
|
|
731
|
-
normalizedResponse: fail(
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
915
|
+
normalizedResponse: fail(
|
|
916
|
+
ERROR_CODES.STATE_VALIDATION_FAILED,
|
|
917
|
+
'state.md front matter failed schema validation',
|
|
918
|
+
{
|
|
919
|
+
errors: validation.errors,
|
|
920
|
+
retryable: false,
|
|
921
|
+
requires_human: true,
|
|
922
|
+
},
|
|
923
|
+
),
|
|
736
924
|
};
|
|
737
925
|
}
|
|
738
926
|
|
|
@@ -742,13 +930,13 @@ export class AopKernel {
|
|
|
742
930
|
|
|
743
931
|
async withFeatureLock<T>(featureId: string, operation: () => Promise<T>): Promise<T> {
|
|
744
932
|
return await withFileLock<T>(this.featureLockPath(featureId), operation, {
|
|
745
|
-
timeoutMs: 30_000
|
|
933
|
+
timeoutMs: 30_000,
|
|
746
934
|
});
|
|
747
935
|
}
|
|
748
936
|
|
|
749
937
|
async withIndexLock<T>(operation: () => Promise<T>): Promise<T> {
|
|
750
938
|
return await withFileLock<T>(this.indexLockPath, operation, {
|
|
751
|
-
timeoutMs: 30_000
|
|
939
|
+
timeoutMs: 30_000,
|
|
752
940
|
});
|
|
753
941
|
}
|
|
754
942
|
|
|
@@ -767,18 +955,25 @@ export class AopKernel {
|
|
|
767
955
|
const validation = await this.schemaRegistry.validate('index.schema.json', normalized);
|
|
768
956
|
if (!validation.valid) {
|
|
769
957
|
throw {
|
|
770
|
-
normalizedResponse: fail(
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
958
|
+
normalizedResponse: fail(
|
|
959
|
+
ERROR_CODES.INDEX_VALIDATION_FAILED,
|
|
960
|
+
'index.json failed schema validation',
|
|
961
|
+
{
|
|
962
|
+
errors: validation.errors,
|
|
963
|
+
retryable: false,
|
|
964
|
+
requires_human: true,
|
|
965
|
+
},
|
|
966
|
+
),
|
|
775
967
|
};
|
|
776
968
|
}
|
|
777
969
|
|
|
778
970
|
await atomicWriteJson(this.indexPath, normalized);
|
|
779
971
|
}
|
|
780
972
|
|
|
781
|
-
async validateSchema(
|
|
973
|
+
async validateSchema(
|
|
974
|
+
schemaName: string,
|
|
975
|
+
value: unknown,
|
|
976
|
+
): Promise<{ valid: boolean; errors?: unknown }> {
|
|
782
977
|
return await this.schemaRegistry.validate(schemaName, value);
|
|
783
978
|
}
|
|
784
979
|
|
|
@@ -806,15 +1001,27 @@ export class AopKernel {
|
|
|
806
1001
|
await atomicWriteJson(runLeasePath, data);
|
|
807
1002
|
}
|
|
808
1003
|
|
|
809
|
-
async acquireRunLease(input: AcquireRunLeaseInput): Promise<{
|
|
1004
|
+
async acquireRunLease(input: AcquireRunLeaseInput): Promise<{
|
|
1005
|
+
data: {
|
|
1006
|
+
runtime_sessions: RuntimeSessionsSnapshot;
|
|
1007
|
+
took_over_stale: boolean;
|
|
1008
|
+
reused_existing_owner: boolean;
|
|
1009
|
+
};
|
|
1010
|
+
}> {
|
|
810
1011
|
return await this.runLeaseService.acquireRunLease(input);
|
|
811
1012
|
}
|
|
812
1013
|
|
|
813
|
-
async renewRunLease(
|
|
1014
|
+
async renewRunLease(
|
|
1015
|
+
runId: string,
|
|
1016
|
+
ownerInstanceId: string,
|
|
1017
|
+
): Promise<{ data: { lease_expires_at: string } }> {
|
|
814
1018
|
return await this.runLeaseService.renewRunLease(runId, ownerInstanceId);
|
|
815
1019
|
}
|
|
816
1020
|
|
|
817
|
-
async releaseRunLease(
|
|
1021
|
+
async releaseRunLease(
|
|
1022
|
+
runId: string,
|
|
1023
|
+
ownerInstanceId: string,
|
|
1024
|
+
): Promise<{ data: { released: boolean } }> {
|
|
818
1025
|
return await this.runLeaseService.releaseRunLease(runId, ownerInstanceId);
|
|
819
1026
|
}
|
|
820
1027
|
|
|
@@ -849,7 +1056,10 @@ export class AopKernel {
|
|
|
849
1056
|
async updateState(
|
|
850
1057
|
featureId: string,
|
|
851
1058
|
expectedVersion: number | null,
|
|
852
|
-
updater: (
|
|
1059
|
+
updater: (
|
|
1060
|
+
frontMatter: AnyRecord,
|
|
1061
|
+
body: string,
|
|
1062
|
+
) => Promise<{ frontMatter?: AnyRecord; body?: string }>,
|
|
853
1063
|
) {
|
|
854
1064
|
return await this.featureStateService.updateState(featureId, expectedVersion, updater);
|
|
855
1065
|
}
|
|
@@ -925,8 +1135,8 @@ export class AopKernel {
|
|
|
925
1135
|
feature_id: featureId,
|
|
926
1136
|
branch,
|
|
927
1137
|
worktree_path_abs: worktree,
|
|
928
|
-
existed: true
|
|
929
|
-
}
|
|
1138
|
+
existed: true,
|
|
1139
|
+
},
|
|
930
1140
|
};
|
|
931
1141
|
}
|
|
932
1142
|
|
|
@@ -939,15 +1149,20 @@ export class AopKernel {
|
|
|
939
1149
|
const branchCreate = await runGit(this.repoRoot, ['branch', branch, baseRef]);
|
|
940
1150
|
if (branchCreate.code !== 0) {
|
|
941
1151
|
throw {
|
|
942
|
-
normalizedResponse: fail(
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1152
|
+
normalizedResponse: fail(
|
|
1153
|
+
ERROR_CODES.GIT_FAILURE,
|
|
1154
|
+
'Unable to create feature branch',
|
|
1155
|
+
{
|
|
1156
|
+
feature_id: featureId,
|
|
1157
|
+
stderr: branchCreate.stderr,
|
|
1158
|
+
retryable: false,
|
|
1159
|
+
requires_human: true,
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
command: ['git', 'branch', branch, baseRef],
|
|
1163
|
+
exit_code: branchCreate.code,
|
|
1164
|
+
},
|
|
1165
|
+
),
|
|
951
1166
|
};
|
|
952
1167
|
}
|
|
953
1168
|
}
|
|
@@ -955,30 +1170,42 @@ export class AopKernel {
|
|
|
955
1170
|
const addWorktree = await runGit(this.repoRoot, ['worktree', 'add', worktree, branch]);
|
|
956
1171
|
if (addWorktree.code !== 0) {
|
|
957
1172
|
throw {
|
|
958
|
-
normalizedResponse: fail(
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1173
|
+
normalizedResponse: fail(
|
|
1174
|
+
ERROR_CODES.GIT_FAILURE,
|
|
1175
|
+
'Unable to create git worktree',
|
|
1176
|
+
{
|
|
1177
|
+
feature_id: featureId,
|
|
1178
|
+
stderr: addWorktree.stderr,
|
|
1179
|
+
retryable: false,
|
|
1180
|
+
requires_human: true,
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
command: ['git', 'worktree', 'add', worktree, branch],
|
|
1184
|
+
exit_code: addWorktree.code,
|
|
1185
|
+
},
|
|
1186
|
+
),
|
|
967
1187
|
};
|
|
968
1188
|
}
|
|
969
1189
|
|
|
970
|
-
const worktreeConfig = this.policy.worktree as
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1190
|
+
const worktreeConfig = this.policy.worktree as
|
|
1191
|
+
| {
|
|
1192
|
+
base_branch: string;
|
|
1193
|
+
symlinks?: string[];
|
|
1194
|
+
post_create?: string[];
|
|
1195
|
+
}
|
|
1196
|
+
| undefined;
|
|
975
1197
|
const hookWarnings: WorkspaceHookWarning[] = [];
|
|
976
1198
|
const collectHookWarning = (warning: WorkspaceHookWarning) => {
|
|
977
1199
|
hookWarnings.push(warning);
|
|
978
1200
|
};
|
|
979
1201
|
|
|
980
1202
|
if (worktreeConfig?.symlinks?.length) {
|
|
981
|
-
await applyWorktreeSymlinks(
|
|
1203
|
+
await applyWorktreeSymlinks(
|
|
1204
|
+
this.repoRoot,
|
|
1205
|
+
worktree,
|
|
1206
|
+
worktreeConfig.symlinks,
|
|
1207
|
+
collectHookWarning,
|
|
1208
|
+
);
|
|
982
1209
|
}
|
|
983
1210
|
|
|
984
1211
|
if (worktreeConfig?.post_create?.length) {
|
|
@@ -995,8 +1222,8 @@ export class AopKernel {
|
|
|
995
1222
|
feature_id: featureId,
|
|
996
1223
|
branch,
|
|
997
1224
|
worktree_path_abs: worktree,
|
|
998
|
-
existed: false
|
|
999
|
-
}
|
|
1225
|
+
existed: false,
|
|
1226
|
+
},
|
|
1000
1227
|
};
|
|
1001
1228
|
}
|
|
1002
1229
|
|
|
@@ -1015,33 +1242,42 @@ export class AopKernel {
|
|
|
1015
1242
|
async repoStatus(featureId) {
|
|
1016
1243
|
const worktree = this.worktreePath(featureId);
|
|
1017
1244
|
const status = await runGit(this.repoRoot, ['status', '--porcelain'], { cwd: worktree });
|
|
1018
|
-
const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
1245
|
+
const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
1246
|
+
cwd: worktree,
|
|
1247
|
+
});
|
|
1019
1248
|
|
|
1020
1249
|
return {
|
|
1021
1250
|
data: {
|
|
1022
1251
|
feature_id: featureId,
|
|
1023
1252
|
branch: branch.stdout.trim(),
|
|
1024
|
-
status_porcelain: status.stdout.trim().split('\n').filter(Boolean)
|
|
1025
|
-
}
|
|
1253
|
+
status_porcelain: status.stdout.trim().split('\n').filter(Boolean),
|
|
1254
|
+
},
|
|
1026
1255
|
};
|
|
1027
1256
|
}
|
|
1028
1257
|
|
|
1029
1258
|
async repoDiff(featureId, options = []) {
|
|
1030
1259
|
const safeOptions = asArray<string>(options).filter(
|
|
1031
|
-
(option) => typeof option === 'string' && option.startsWith('--')
|
|
1260
|
+
(option) => typeof option === 'string' && option.startsWith('--'),
|
|
1032
1261
|
);
|
|
1033
|
-
const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], {
|
|
1262
|
+
const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], {
|
|
1263
|
+
cwd: this.worktreePath(featureId),
|
|
1264
|
+
});
|
|
1034
1265
|
return {
|
|
1035
1266
|
data: {
|
|
1036
1267
|
feature_id: featureId,
|
|
1037
|
-
diff: diff.stdout
|
|
1038
|
-
}
|
|
1268
|
+
diff: diff.stdout,
|
|
1269
|
+
},
|
|
1039
1270
|
};
|
|
1040
1271
|
}
|
|
1041
1272
|
|
|
1042
1273
|
async repoReadFile(featureId, filePath) {
|
|
1043
|
-
const normalized = await normalizeRepoPath(
|
|
1044
|
-
|
|
1274
|
+
const normalized = await normalizeRepoPath(
|
|
1275
|
+
this.repoRoot,
|
|
1276
|
+
path.join(this.worktreePath(featureId), filePath),
|
|
1277
|
+
this.policy.path_rules.allow_symlink_traversal,
|
|
1278
|
+
).then((relative) =>
|
|
1279
|
+
normalizeFromWorktree(this.worktreePath(featureId), this.repoRoot, relative),
|
|
1280
|
+
);
|
|
1045
1281
|
const absolute = path.join(this.repoRoot, normalized);
|
|
1046
1282
|
const exists = await pathExists(absolute);
|
|
1047
1283
|
if (!exists) {
|
|
@@ -1049,8 +1285,8 @@ export class AopKernel {
|
|
|
1049
1285
|
normalizedResponse: fail(ERROR_CODES.FILE_NOT_FOUND, 'File not found', {
|
|
1050
1286
|
path: normalized,
|
|
1051
1287
|
retryable: false,
|
|
1052
|
-
requires_human: false
|
|
1053
|
-
})
|
|
1288
|
+
requires_human: false,
|
|
1289
|
+
}),
|
|
1054
1290
|
};
|
|
1055
1291
|
}
|
|
1056
1292
|
const content = await fs.readFile(absolute, 'utf8');
|
|
@@ -1058,8 +1294,8 @@ export class AopKernel {
|
|
|
1058
1294
|
data: {
|
|
1059
1295
|
feature_id: featureId,
|
|
1060
1296
|
path: normalized,
|
|
1061
|
-
content
|
|
1062
|
-
}
|
|
1297
|
+
content,
|
|
1298
|
+
},
|
|
1063
1299
|
};
|
|
1064
1300
|
}
|
|
1065
1301
|
|
|
@@ -1067,16 +1303,20 @@ export class AopKernel {
|
|
|
1067
1303
|
const worktree = this.worktreePath(featureId);
|
|
1068
1304
|
const rgResult = await runCommand('rg', ['-n', '--no-heading', query, '.'], {
|
|
1069
1305
|
cwd: worktree,
|
|
1070
|
-
timeoutMs: 30_000
|
|
1306
|
+
timeoutMs: 30_000,
|
|
1071
1307
|
});
|
|
1072
1308
|
|
|
1073
1309
|
if (rgResult.code === 127) {
|
|
1074
1310
|
throw {
|
|
1075
|
-
normalizedResponse: fail(
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1311
|
+
normalizedResponse: fail(
|
|
1312
|
+
ERROR_CODES.GIT_FAILURE,
|
|
1313
|
+
'ripgrep (rg) not found - required for search functionality',
|
|
1314
|
+
{
|
|
1315
|
+
stderr: rgResult.stderr,
|
|
1316
|
+
retryable: false,
|
|
1317
|
+
requires_human: true,
|
|
1318
|
+
},
|
|
1319
|
+
),
|
|
1080
1320
|
};
|
|
1081
1321
|
}
|
|
1082
1322
|
|
|
@@ -1085,8 +1325,8 @@ export class AopKernel {
|
|
|
1085
1325
|
normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Search failed', {
|
|
1086
1326
|
stderr: rgResult.stderr,
|
|
1087
1327
|
retryable: true,
|
|
1088
|
-
requires_human: false
|
|
1089
|
-
})
|
|
1328
|
+
requires_human: false,
|
|
1329
|
+
}),
|
|
1090
1330
|
};
|
|
1091
1331
|
}
|
|
1092
1332
|
|
|
@@ -1103,7 +1343,7 @@ export class AopKernel {
|
|
|
1103
1343
|
return {
|
|
1104
1344
|
path: line.slice(0, firstColon),
|
|
1105
1345
|
line: Number(line.slice(firstColon + 1, secondColon)),
|
|
1106
|
-
snippet: line.slice(secondColon + 1)
|
|
1346
|
+
snippet: line.slice(secondColon + 1),
|
|
1107
1347
|
};
|
|
1108
1348
|
});
|
|
1109
1349
|
|
|
@@ -1111,15 +1351,19 @@ export class AopKernel {
|
|
|
1111
1351
|
data: {
|
|
1112
1352
|
feature_id: featureId,
|
|
1113
1353
|
query,
|
|
1114
|
-
matches
|
|
1115
|
-
}
|
|
1354
|
+
matches,
|
|
1355
|
+
},
|
|
1116
1356
|
};
|
|
1117
1357
|
}
|
|
1118
1358
|
|
|
1119
1359
|
async repoDiffBundle(featureId) {
|
|
1120
|
-
const stat = await runGit(this.repoRoot, ['diff', '--stat'], {
|
|
1360
|
+
const stat = await runGit(this.repoRoot, ['diff', '--stat'], {
|
|
1361
|
+
cwd: this.worktreePath(featureId),
|
|
1362
|
+
});
|
|
1121
1363
|
const full = await runGit(this.repoRoot, ['diff'], { cwd: this.worktreePath(featureId) });
|
|
1122
|
-
const names = await runGit(this.repoRoot, ['diff', '--name-only'], {
|
|
1364
|
+
const names = await runGit(this.repoRoot, ['diff', '--name-only'], {
|
|
1365
|
+
cwd: this.worktreePath(featureId),
|
|
1366
|
+
});
|
|
1123
1367
|
const latest = await this.evidenceLatest(featureId);
|
|
1124
1368
|
|
|
1125
1369
|
return {
|
|
@@ -1127,9 +1371,12 @@ export class AopKernel {
|
|
|
1127
1371
|
feature_id: featureId,
|
|
1128
1372
|
diff_stat: stat.stdout,
|
|
1129
1373
|
diff: full.stdout,
|
|
1130
|
-
touched_files: names.stdout
|
|
1131
|
-
|
|
1132
|
-
|
|
1374
|
+
touched_files: names.stdout
|
|
1375
|
+
.split('\n')
|
|
1376
|
+
.map((x) => x.trim())
|
|
1377
|
+
.filter(Boolean),
|
|
1378
|
+
last_gate_summary: latest.data?.latest ?? null,
|
|
1379
|
+
},
|
|
1133
1380
|
};
|
|
1134
1381
|
}
|
|
1135
1382
|
|
|
@@ -1154,7 +1401,12 @@ export class AopKernel {
|
|
|
1154
1401
|
}
|
|
1155
1402
|
|
|
1156
1403
|
async qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs) {
|
|
1157
|
-
return await this.qaIndexService.qaTestIndexUpdate(
|
|
1404
|
+
return await this.qaIndexService.qaTestIndexUpdate(
|
|
1405
|
+
featureId,
|
|
1406
|
+
expectedVersion,
|
|
1407
|
+
updates,
|
|
1408
|
+
evidenceRefs,
|
|
1409
|
+
);
|
|
1158
1410
|
}
|
|
1159
1411
|
|
|
1160
1412
|
async locksAcquire(resource, featureId, waitTimeoutSeconds = null) {
|
|
@@ -1178,7 +1430,12 @@ export class AopKernel {
|
|
|
1178
1430
|
}
|
|
1179
1431
|
|
|
1180
1432
|
async featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken) {
|
|
1181
|
-
return await this.mergeService.featureReadyToMerge(
|
|
1433
|
+
return await this.mergeService.featureReadyToMerge(
|
|
1434
|
+
featureId,
|
|
1435
|
+
commitMessage,
|
|
1436
|
+
mergeStrategy,
|
|
1437
|
+
userApprovalToken,
|
|
1438
|
+
);
|
|
1182
1439
|
}
|
|
1183
1440
|
|
|
1184
1441
|
async featureDelete(
|
|
@@ -1186,13 +1443,13 @@ export class AopKernel {
|
|
|
1186
1443
|
dryRun: boolean | null,
|
|
1187
1444
|
confirm: boolean | null,
|
|
1188
1445
|
removeWorktree: boolean | null,
|
|
1189
|
-
removeBranch: string | null
|
|
1446
|
+
removeBranch: string | null,
|
|
1190
1447
|
): Promise<FeatureDeleteResult> {
|
|
1191
1448
|
return await this.featureDeletionService.featureDelete(featureId, {
|
|
1192
1449
|
dryRun: dryRun ?? undefined,
|
|
1193
1450
|
confirm: confirm ?? undefined,
|
|
1194
1451
|
removeWorktree: removeWorktree ?? undefined,
|
|
1195
|
-
removeBranch: removeBranch ?? undefined
|
|
1452
|
+
removeBranch: removeBranch ?? undefined,
|
|
1196
1453
|
});
|
|
1197
1454
|
}
|
|
1198
1455
|
|
|
@@ -1224,21 +1481,34 @@ export class AopKernel {
|
|
|
1224
1481
|
}
|
|
1225
1482
|
}
|
|
1226
1483
|
|
|
1227
|
-
async featureSendMessage(
|
|
1228
|
-
featureId: string | null,
|
|
1229
|
-
message: string | null
|
|
1230
|
-
): Promise<unknown> {
|
|
1484
|
+
async featureSendMessage(featureId: string | null, message: string | null): Promise<unknown> {
|
|
1231
1485
|
if (!featureId) {
|
|
1232
|
-
throw {
|
|
1486
|
+
throw {
|
|
1487
|
+
normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'feature_id is required', {
|
|
1488
|
+
retryable: false,
|
|
1489
|
+
requires_human: false,
|
|
1490
|
+
}),
|
|
1491
|
+
};
|
|
1233
1492
|
}
|
|
1234
1493
|
if (!message) {
|
|
1235
|
-
throw {
|
|
1494
|
+
throw {
|
|
1495
|
+
normalizedResponse: fail(
|
|
1496
|
+
ERROR_CODES.INVALID_ARGUMENT,
|
|
1497
|
+
'message is required and must not be empty',
|
|
1498
|
+
{ retryable: false, requires_human: false },
|
|
1499
|
+
),
|
|
1500
|
+
};
|
|
1236
1501
|
}
|
|
1237
1502
|
|
|
1238
1503
|
const runtimeSessions = await this.getRuntimeSessions();
|
|
1239
1504
|
const featureSession = runtimeSessions.feature_sessions?.[featureId];
|
|
1240
1505
|
if (!featureSession) {
|
|
1241
|
-
throw {
|
|
1506
|
+
throw {
|
|
1507
|
+
normalizedResponse: {
|
|
1508
|
+
ok: false,
|
|
1509
|
+
error: { code: 'session_not_found', message: 'No active session cluster for feature' },
|
|
1510
|
+
},
|
|
1511
|
+
};
|
|
1242
1512
|
}
|
|
1243
1513
|
|
|
1244
1514
|
const state = await this.readState(featureId);
|
|
@@ -1275,7 +1545,12 @@ export class AopKernel {
|
|
|
1275
1545
|
}
|
|
1276
1546
|
|
|
1277
1547
|
if (!this.provider?.sendMessage) {
|
|
1278
|
-
throw {
|
|
1548
|
+
throw {
|
|
1549
|
+
normalizedResponse: {
|
|
1550
|
+
ok: false,
|
|
1551
|
+
error: { code: 'provider_unsupported', message: 'Provider does not support sendMessage' },
|
|
1552
|
+
},
|
|
1553
|
+
};
|
|
1279
1554
|
}
|
|
1280
1555
|
|
|
1281
1556
|
await this.waitForSessionToBecomeActive(targetSessionId);
|
|
@@ -1285,7 +1560,7 @@ export class AopKernel {
|
|
|
1285
1560
|
session_id: targetSessionId,
|
|
1286
1561
|
target_role: targetRole,
|
|
1287
1562
|
status,
|
|
1288
|
-
delivered: true
|
|
1563
|
+
delivered: true,
|
|
1289
1564
|
};
|
|
1290
1565
|
}
|
|
1291
1566
|
|
|
@@ -1313,7 +1588,7 @@ export class AopKernel {
|
|
|
1313
1588
|
retry_count: typeof args.retry_count === 'number' ? args.retry_count : 0,
|
|
1314
1589
|
duration_ms: typeof args.duration_ms === 'number' ? args.duration_ms : 0,
|
|
1315
1590
|
cost_usd: typeof args.cost_usd === 'number' ? args.cost_usd : 0,
|
|
1316
|
-
recorded_at: nowIso()
|
|
1591
|
+
recorded_at: nowIso(),
|
|
1317
1592
|
};
|
|
1318
1593
|
const snapshot = await this.performanceAnalyticsService.recordOutcome(outcome);
|
|
1319
1594
|
return { ok: true as const, data: { total_outcomes: snapshot.outcomes.length } };
|
|
@@ -1323,10 +1598,17 @@ export class AopKernel {
|
|
|
1323
1598
|
if (provider || model) {
|
|
1324
1599
|
const stats = await this.performanceAnalyticsService.getProviderStats(
|
|
1325
1600
|
provider ?? undefined,
|
|
1326
|
-
model ?? undefined
|
|
1601
|
+
model ?? undefined,
|
|
1327
1602
|
);
|
|
1328
1603
|
const snapshot = await this.performanceAnalyticsService.getAnalytics();
|
|
1329
|
-
return {
|
|
1604
|
+
return {
|
|
1605
|
+
ok: true as const,
|
|
1606
|
+
data: {
|
|
1607
|
+
outcomes: snapshot.outcomes,
|
|
1608
|
+
aggregates: stats,
|
|
1609
|
+
generated_at: snapshot.generated_at,
|
|
1610
|
+
},
|
|
1611
|
+
};
|
|
1330
1612
|
}
|
|
1331
1613
|
const snapshot = await this.performanceAnalyticsService.getAnalytics();
|
|
1332
1614
|
return { ok: true as const, data: snapshot };
|
|
@@ -1341,7 +1623,11 @@ function normalizeRepoPathForState(repoRoot: string, absolutePath: string) {
|
|
|
1341
1623
|
return relative;
|
|
1342
1624
|
}
|
|
1343
1625
|
|
|
1344
|
-
function normalizeFromWorktree(
|
|
1626
|
+
function normalizeFromWorktree(
|
|
1627
|
+
worktreePath: string,
|
|
1628
|
+
repoRoot: string,
|
|
1629
|
+
repoRelativeFromWorktree: string,
|
|
1630
|
+
) {
|
|
1345
1631
|
const absolute = path.resolve(repoRoot, repoRelativeFromWorktree);
|
|
1346
1632
|
const maybeRelativeToWorktree = path.relative(worktreePath, absolute).replaceAll('\\\\', '/');
|
|
1347
1633
|
if (!maybeRelativeToWorktree.startsWith('../')) {
|