agentic-orchestrator 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +10 -0
- package/.prettierrc.json +24 -0
- package/CLAUDE.md +3 -2
- package/README.md +47 -46
- 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 +4 -21
- 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/help-command-handler.ts +61 -32
- package/apps/control-plane/src/cli/init-command-handler.ts +110 -54
- 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 +515 -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 +69 -32
- 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 +72 -48
- 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 +162 -67
- 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 +133 -102
- 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/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/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 +44 -33
- 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 +31 -20
- 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 +1 -1
- package/dist/apps/control-plane/providers/providers.js +31 -34
- 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 +187 -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_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,29 @@ export class AopKernel {
|
|
|
806
1001
|
await atomicWriteJson(runLeasePath, data);
|
|
807
1002
|
}
|
|
808
1003
|
|
|
809
|
-
async acquireRunLease(
|
|
1004
|
+
async acquireRunLease(
|
|
1005
|
+
input: AcquireRunLeaseInput,
|
|
1006
|
+
): Promise<{
|
|
1007
|
+
data: {
|
|
1008
|
+
runtime_sessions: RuntimeSessionsSnapshot;
|
|
1009
|
+
took_over_stale: boolean;
|
|
1010
|
+
reused_existing_owner: boolean;
|
|
1011
|
+
};
|
|
1012
|
+
}> {
|
|
810
1013
|
return await this.runLeaseService.acquireRunLease(input);
|
|
811
1014
|
}
|
|
812
1015
|
|
|
813
|
-
async renewRunLease(
|
|
1016
|
+
async renewRunLease(
|
|
1017
|
+
runId: string,
|
|
1018
|
+
ownerInstanceId: string,
|
|
1019
|
+
): Promise<{ data: { lease_expires_at: string } }> {
|
|
814
1020
|
return await this.runLeaseService.renewRunLease(runId, ownerInstanceId);
|
|
815
1021
|
}
|
|
816
1022
|
|
|
817
|
-
async releaseRunLease(
|
|
1023
|
+
async releaseRunLease(
|
|
1024
|
+
runId: string,
|
|
1025
|
+
ownerInstanceId: string,
|
|
1026
|
+
): Promise<{ data: { released: boolean } }> {
|
|
818
1027
|
return await this.runLeaseService.releaseRunLease(runId, ownerInstanceId);
|
|
819
1028
|
}
|
|
820
1029
|
|
|
@@ -849,7 +1058,10 @@ export class AopKernel {
|
|
|
849
1058
|
async updateState(
|
|
850
1059
|
featureId: string,
|
|
851
1060
|
expectedVersion: number | null,
|
|
852
|
-
updater: (
|
|
1061
|
+
updater: (
|
|
1062
|
+
frontMatter: AnyRecord,
|
|
1063
|
+
body: string,
|
|
1064
|
+
) => Promise<{ frontMatter?: AnyRecord; body?: string }>,
|
|
853
1065
|
) {
|
|
854
1066
|
return await this.featureStateService.updateState(featureId, expectedVersion, updater);
|
|
855
1067
|
}
|
|
@@ -925,8 +1137,8 @@ export class AopKernel {
|
|
|
925
1137
|
feature_id: featureId,
|
|
926
1138
|
branch,
|
|
927
1139
|
worktree_path_abs: worktree,
|
|
928
|
-
existed: true
|
|
929
|
-
}
|
|
1140
|
+
existed: true,
|
|
1141
|
+
},
|
|
930
1142
|
};
|
|
931
1143
|
}
|
|
932
1144
|
|
|
@@ -939,15 +1151,20 @@ export class AopKernel {
|
|
|
939
1151
|
const branchCreate = await runGit(this.repoRoot, ['branch', branch, baseRef]);
|
|
940
1152
|
if (branchCreate.code !== 0) {
|
|
941
1153
|
throw {
|
|
942
|
-
normalizedResponse: fail(
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1154
|
+
normalizedResponse: fail(
|
|
1155
|
+
ERROR_CODES.GIT_FAILURE,
|
|
1156
|
+
'Unable to create feature branch',
|
|
1157
|
+
{
|
|
1158
|
+
feature_id: featureId,
|
|
1159
|
+
stderr: branchCreate.stderr,
|
|
1160
|
+
retryable: false,
|
|
1161
|
+
requires_human: true,
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
command: ['git', 'branch', branch, baseRef],
|
|
1165
|
+
exit_code: branchCreate.code,
|
|
1166
|
+
},
|
|
1167
|
+
),
|
|
951
1168
|
};
|
|
952
1169
|
}
|
|
953
1170
|
}
|
|
@@ -955,30 +1172,42 @@ export class AopKernel {
|
|
|
955
1172
|
const addWorktree = await runGit(this.repoRoot, ['worktree', 'add', worktree, branch]);
|
|
956
1173
|
if (addWorktree.code !== 0) {
|
|
957
1174
|
throw {
|
|
958
|
-
normalizedResponse: fail(
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1175
|
+
normalizedResponse: fail(
|
|
1176
|
+
ERROR_CODES.GIT_FAILURE,
|
|
1177
|
+
'Unable to create git worktree',
|
|
1178
|
+
{
|
|
1179
|
+
feature_id: featureId,
|
|
1180
|
+
stderr: addWorktree.stderr,
|
|
1181
|
+
retryable: false,
|
|
1182
|
+
requires_human: true,
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
command: ['git', 'worktree', 'add', worktree, branch],
|
|
1186
|
+
exit_code: addWorktree.code,
|
|
1187
|
+
},
|
|
1188
|
+
),
|
|
967
1189
|
};
|
|
968
1190
|
}
|
|
969
1191
|
|
|
970
|
-
const worktreeConfig = this.policy.worktree as
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1192
|
+
const worktreeConfig = this.policy.worktree as
|
|
1193
|
+
| {
|
|
1194
|
+
base_branch: string;
|
|
1195
|
+
symlinks?: string[];
|
|
1196
|
+
post_create?: string[];
|
|
1197
|
+
}
|
|
1198
|
+
| undefined;
|
|
975
1199
|
const hookWarnings: WorkspaceHookWarning[] = [];
|
|
976
1200
|
const collectHookWarning = (warning: WorkspaceHookWarning) => {
|
|
977
1201
|
hookWarnings.push(warning);
|
|
978
1202
|
};
|
|
979
1203
|
|
|
980
1204
|
if (worktreeConfig?.symlinks?.length) {
|
|
981
|
-
await applyWorktreeSymlinks(
|
|
1205
|
+
await applyWorktreeSymlinks(
|
|
1206
|
+
this.repoRoot,
|
|
1207
|
+
worktree,
|
|
1208
|
+
worktreeConfig.symlinks,
|
|
1209
|
+
collectHookWarning,
|
|
1210
|
+
);
|
|
982
1211
|
}
|
|
983
1212
|
|
|
984
1213
|
if (worktreeConfig?.post_create?.length) {
|
|
@@ -995,8 +1224,8 @@ export class AopKernel {
|
|
|
995
1224
|
feature_id: featureId,
|
|
996
1225
|
branch,
|
|
997
1226
|
worktree_path_abs: worktree,
|
|
998
|
-
existed: false
|
|
999
|
-
}
|
|
1227
|
+
existed: false,
|
|
1228
|
+
},
|
|
1000
1229
|
};
|
|
1001
1230
|
}
|
|
1002
1231
|
|
|
@@ -1015,33 +1244,42 @@ export class AopKernel {
|
|
|
1015
1244
|
async repoStatus(featureId) {
|
|
1016
1245
|
const worktree = this.worktreePath(featureId);
|
|
1017
1246
|
const status = await runGit(this.repoRoot, ['status', '--porcelain'], { cwd: worktree });
|
|
1018
|
-
const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
1247
|
+
const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
1248
|
+
cwd: worktree,
|
|
1249
|
+
});
|
|
1019
1250
|
|
|
1020
1251
|
return {
|
|
1021
1252
|
data: {
|
|
1022
1253
|
feature_id: featureId,
|
|
1023
1254
|
branch: branch.stdout.trim(),
|
|
1024
|
-
status_porcelain: status.stdout.trim().split('\n').filter(Boolean)
|
|
1025
|
-
}
|
|
1255
|
+
status_porcelain: status.stdout.trim().split('\n').filter(Boolean),
|
|
1256
|
+
},
|
|
1026
1257
|
};
|
|
1027
1258
|
}
|
|
1028
1259
|
|
|
1029
1260
|
async repoDiff(featureId, options = []) {
|
|
1030
1261
|
const safeOptions = asArray<string>(options).filter(
|
|
1031
|
-
(option) => typeof option === 'string' && option.startsWith('--')
|
|
1262
|
+
(option) => typeof option === 'string' && option.startsWith('--'),
|
|
1032
1263
|
);
|
|
1033
|
-
const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], {
|
|
1264
|
+
const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], {
|
|
1265
|
+
cwd: this.worktreePath(featureId),
|
|
1266
|
+
});
|
|
1034
1267
|
return {
|
|
1035
1268
|
data: {
|
|
1036
1269
|
feature_id: featureId,
|
|
1037
|
-
diff: diff.stdout
|
|
1038
|
-
}
|
|
1270
|
+
diff: diff.stdout,
|
|
1271
|
+
},
|
|
1039
1272
|
};
|
|
1040
1273
|
}
|
|
1041
1274
|
|
|
1042
1275
|
async repoReadFile(featureId, filePath) {
|
|
1043
|
-
const normalized = await normalizeRepoPath(
|
|
1044
|
-
|
|
1276
|
+
const normalized = await normalizeRepoPath(
|
|
1277
|
+
this.repoRoot,
|
|
1278
|
+
path.join(this.worktreePath(featureId), filePath),
|
|
1279
|
+
this.policy.path_rules.allow_symlink_traversal,
|
|
1280
|
+
).then((relative) =>
|
|
1281
|
+
normalizeFromWorktree(this.worktreePath(featureId), this.repoRoot, relative),
|
|
1282
|
+
);
|
|
1045
1283
|
const absolute = path.join(this.repoRoot, normalized);
|
|
1046
1284
|
const exists = await pathExists(absolute);
|
|
1047
1285
|
if (!exists) {
|
|
@@ -1049,8 +1287,8 @@ export class AopKernel {
|
|
|
1049
1287
|
normalizedResponse: fail(ERROR_CODES.FILE_NOT_FOUND, 'File not found', {
|
|
1050
1288
|
path: normalized,
|
|
1051
1289
|
retryable: false,
|
|
1052
|
-
requires_human: false
|
|
1053
|
-
})
|
|
1290
|
+
requires_human: false,
|
|
1291
|
+
}),
|
|
1054
1292
|
};
|
|
1055
1293
|
}
|
|
1056
1294
|
const content = await fs.readFile(absolute, 'utf8');
|
|
@@ -1058,8 +1296,8 @@ export class AopKernel {
|
|
|
1058
1296
|
data: {
|
|
1059
1297
|
feature_id: featureId,
|
|
1060
1298
|
path: normalized,
|
|
1061
|
-
content
|
|
1062
|
-
}
|
|
1299
|
+
content,
|
|
1300
|
+
},
|
|
1063
1301
|
};
|
|
1064
1302
|
}
|
|
1065
1303
|
|
|
@@ -1067,16 +1305,20 @@ export class AopKernel {
|
|
|
1067
1305
|
const worktree = this.worktreePath(featureId);
|
|
1068
1306
|
const rgResult = await runCommand('rg', ['-n', '--no-heading', query, '.'], {
|
|
1069
1307
|
cwd: worktree,
|
|
1070
|
-
timeoutMs: 30_000
|
|
1308
|
+
timeoutMs: 30_000,
|
|
1071
1309
|
});
|
|
1072
1310
|
|
|
1073
1311
|
if (rgResult.code === 127) {
|
|
1074
1312
|
throw {
|
|
1075
|
-
normalizedResponse: fail(
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1313
|
+
normalizedResponse: fail(
|
|
1314
|
+
ERROR_CODES.GIT_FAILURE,
|
|
1315
|
+
'ripgrep (rg) not found - required for search functionality',
|
|
1316
|
+
{
|
|
1317
|
+
stderr: rgResult.stderr,
|
|
1318
|
+
retryable: false,
|
|
1319
|
+
requires_human: true,
|
|
1320
|
+
},
|
|
1321
|
+
),
|
|
1080
1322
|
};
|
|
1081
1323
|
}
|
|
1082
1324
|
|
|
@@ -1085,8 +1327,8 @@ export class AopKernel {
|
|
|
1085
1327
|
normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Search failed', {
|
|
1086
1328
|
stderr: rgResult.stderr,
|
|
1087
1329
|
retryable: true,
|
|
1088
|
-
requires_human: false
|
|
1089
|
-
})
|
|
1330
|
+
requires_human: false,
|
|
1331
|
+
}),
|
|
1090
1332
|
};
|
|
1091
1333
|
}
|
|
1092
1334
|
|
|
@@ -1103,7 +1345,7 @@ export class AopKernel {
|
|
|
1103
1345
|
return {
|
|
1104
1346
|
path: line.slice(0, firstColon),
|
|
1105
1347
|
line: Number(line.slice(firstColon + 1, secondColon)),
|
|
1106
|
-
snippet: line.slice(secondColon + 1)
|
|
1348
|
+
snippet: line.slice(secondColon + 1),
|
|
1107
1349
|
};
|
|
1108
1350
|
});
|
|
1109
1351
|
|
|
@@ -1111,15 +1353,19 @@ export class AopKernel {
|
|
|
1111
1353
|
data: {
|
|
1112
1354
|
feature_id: featureId,
|
|
1113
1355
|
query,
|
|
1114
|
-
matches
|
|
1115
|
-
}
|
|
1356
|
+
matches,
|
|
1357
|
+
},
|
|
1116
1358
|
};
|
|
1117
1359
|
}
|
|
1118
1360
|
|
|
1119
1361
|
async repoDiffBundle(featureId) {
|
|
1120
|
-
const stat = await runGit(this.repoRoot, ['diff', '--stat'], {
|
|
1362
|
+
const stat = await runGit(this.repoRoot, ['diff', '--stat'], {
|
|
1363
|
+
cwd: this.worktreePath(featureId),
|
|
1364
|
+
});
|
|
1121
1365
|
const full = await runGit(this.repoRoot, ['diff'], { cwd: this.worktreePath(featureId) });
|
|
1122
|
-
const names = await runGit(this.repoRoot, ['diff', '--name-only'], {
|
|
1366
|
+
const names = await runGit(this.repoRoot, ['diff', '--name-only'], {
|
|
1367
|
+
cwd: this.worktreePath(featureId),
|
|
1368
|
+
});
|
|
1123
1369
|
const latest = await this.evidenceLatest(featureId);
|
|
1124
1370
|
|
|
1125
1371
|
return {
|
|
@@ -1127,9 +1373,12 @@ export class AopKernel {
|
|
|
1127
1373
|
feature_id: featureId,
|
|
1128
1374
|
diff_stat: stat.stdout,
|
|
1129
1375
|
diff: full.stdout,
|
|
1130
|
-
touched_files: names.stdout
|
|
1131
|
-
|
|
1132
|
-
|
|
1376
|
+
touched_files: names.stdout
|
|
1377
|
+
.split('\n')
|
|
1378
|
+
.map((x) => x.trim())
|
|
1379
|
+
.filter(Boolean),
|
|
1380
|
+
last_gate_summary: latest.data?.latest ?? null,
|
|
1381
|
+
},
|
|
1133
1382
|
};
|
|
1134
1383
|
}
|
|
1135
1384
|
|
|
@@ -1154,7 +1403,12 @@ export class AopKernel {
|
|
|
1154
1403
|
}
|
|
1155
1404
|
|
|
1156
1405
|
async qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs) {
|
|
1157
|
-
return await this.qaIndexService.qaTestIndexUpdate(
|
|
1406
|
+
return await this.qaIndexService.qaTestIndexUpdate(
|
|
1407
|
+
featureId,
|
|
1408
|
+
expectedVersion,
|
|
1409
|
+
updates,
|
|
1410
|
+
evidenceRefs,
|
|
1411
|
+
);
|
|
1158
1412
|
}
|
|
1159
1413
|
|
|
1160
1414
|
async locksAcquire(resource, featureId, waitTimeoutSeconds = null) {
|
|
@@ -1178,7 +1432,12 @@ export class AopKernel {
|
|
|
1178
1432
|
}
|
|
1179
1433
|
|
|
1180
1434
|
async featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken) {
|
|
1181
|
-
return await this.mergeService.featureReadyToMerge(
|
|
1435
|
+
return await this.mergeService.featureReadyToMerge(
|
|
1436
|
+
featureId,
|
|
1437
|
+
commitMessage,
|
|
1438
|
+
mergeStrategy,
|
|
1439
|
+
userApprovalToken,
|
|
1440
|
+
);
|
|
1182
1441
|
}
|
|
1183
1442
|
|
|
1184
1443
|
async featureDelete(
|
|
@@ -1186,13 +1445,13 @@ export class AopKernel {
|
|
|
1186
1445
|
dryRun: boolean | null,
|
|
1187
1446
|
confirm: boolean | null,
|
|
1188
1447
|
removeWorktree: boolean | null,
|
|
1189
|
-
removeBranch: string | null
|
|
1448
|
+
removeBranch: string | null,
|
|
1190
1449
|
): Promise<FeatureDeleteResult> {
|
|
1191
1450
|
return await this.featureDeletionService.featureDelete(featureId, {
|
|
1192
1451
|
dryRun: dryRun ?? undefined,
|
|
1193
1452
|
confirm: confirm ?? undefined,
|
|
1194
1453
|
removeWorktree: removeWorktree ?? undefined,
|
|
1195
|
-
removeBranch: removeBranch ?? undefined
|
|
1454
|
+
removeBranch: removeBranch ?? undefined,
|
|
1196
1455
|
});
|
|
1197
1456
|
}
|
|
1198
1457
|
|
|
@@ -1224,21 +1483,34 @@ export class AopKernel {
|
|
|
1224
1483
|
}
|
|
1225
1484
|
}
|
|
1226
1485
|
|
|
1227
|
-
async featureSendMessage(
|
|
1228
|
-
featureId: string | null,
|
|
1229
|
-
message: string | null
|
|
1230
|
-
): Promise<unknown> {
|
|
1486
|
+
async featureSendMessage(featureId: string | null, message: string | null): Promise<unknown> {
|
|
1231
1487
|
if (!featureId) {
|
|
1232
|
-
throw {
|
|
1488
|
+
throw {
|
|
1489
|
+
normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'feature_id is required', {
|
|
1490
|
+
retryable: false,
|
|
1491
|
+
requires_human: false,
|
|
1492
|
+
}),
|
|
1493
|
+
};
|
|
1233
1494
|
}
|
|
1234
1495
|
if (!message) {
|
|
1235
|
-
throw {
|
|
1496
|
+
throw {
|
|
1497
|
+
normalizedResponse: fail(
|
|
1498
|
+
ERROR_CODES.INVALID_ARGUMENT,
|
|
1499
|
+
'message is required and must not be empty',
|
|
1500
|
+
{ retryable: false, requires_human: false },
|
|
1501
|
+
),
|
|
1502
|
+
};
|
|
1236
1503
|
}
|
|
1237
1504
|
|
|
1238
1505
|
const runtimeSessions = await this.getRuntimeSessions();
|
|
1239
1506
|
const featureSession = runtimeSessions.feature_sessions?.[featureId];
|
|
1240
1507
|
if (!featureSession) {
|
|
1241
|
-
throw {
|
|
1508
|
+
throw {
|
|
1509
|
+
normalizedResponse: {
|
|
1510
|
+
ok: false,
|
|
1511
|
+
error: { code: 'session_not_found', message: 'No active session cluster for feature' },
|
|
1512
|
+
},
|
|
1513
|
+
};
|
|
1242
1514
|
}
|
|
1243
1515
|
|
|
1244
1516
|
const state = await this.readState(featureId);
|
|
@@ -1275,7 +1547,12 @@ export class AopKernel {
|
|
|
1275
1547
|
}
|
|
1276
1548
|
|
|
1277
1549
|
if (!this.provider?.sendMessage) {
|
|
1278
|
-
throw {
|
|
1550
|
+
throw {
|
|
1551
|
+
normalizedResponse: {
|
|
1552
|
+
ok: false,
|
|
1553
|
+
error: { code: 'provider_unsupported', message: 'Provider does not support sendMessage' },
|
|
1554
|
+
},
|
|
1555
|
+
};
|
|
1279
1556
|
}
|
|
1280
1557
|
|
|
1281
1558
|
await this.waitForSessionToBecomeActive(targetSessionId);
|
|
@@ -1285,7 +1562,7 @@ export class AopKernel {
|
|
|
1285
1562
|
session_id: targetSessionId,
|
|
1286
1563
|
target_role: targetRole,
|
|
1287
1564
|
status,
|
|
1288
|
-
delivered: true
|
|
1565
|
+
delivered: true,
|
|
1289
1566
|
};
|
|
1290
1567
|
}
|
|
1291
1568
|
|
|
@@ -1313,7 +1590,7 @@ export class AopKernel {
|
|
|
1313
1590
|
retry_count: typeof args.retry_count === 'number' ? args.retry_count : 0,
|
|
1314
1591
|
duration_ms: typeof args.duration_ms === 'number' ? args.duration_ms : 0,
|
|
1315
1592
|
cost_usd: typeof args.cost_usd === 'number' ? args.cost_usd : 0,
|
|
1316
|
-
recorded_at: nowIso()
|
|
1593
|
+
recorded_at: nowIso(),
|
|
1317
1594
|
};
|
|
1318
1595
|
const snapshot = await this.performanceAnalyticsService.recordOutcome(outcome);
|
|
1319
1596
|
return { ok: true as const, data: { total_outcomes: snapshot.outcomes.length } };
|
|
@@ -1323,10 +1600,17 @@ export class AopKernel {
|
|
|
1323
1600
|
if (provider || model) {
|
|
1324
1601
|
const stats = await this.performanceAnalyticsService.getProviderStats(
|
|
1325
1602
|
provider ?? undefined,
|
|
1326
|
-
model ?? undefined
|
|
1603
|
+
model ?? undefined,
|
|
1327
1604
|
);
|
|
1328
1605
|
const snapshot = await this.performanceAnalyticsService.getAnalytics();
|
|
1329
|
-
return {
|
|
1606
|
+
return {
|
|
1607
|
+
ok: true as const,
|
|
1608
|
+
data: {
|
|
1609
|
+
outcomes: snapshot.outcomes,
|
|
1610
|
+
aggregates: stats,
|
|
1611
|
+
generated_at: snapshot.generated_at,
|
|
1612
|
+
},
|
|
1613
|
+
};
|
|
1330
1614
|
}
|
|
1331
1615
|
const snapshot = await this.performanceAnalyticsService.getAnalytics();
|
|
1332
1616
|
return { ok: true as const, data: snapshot };
|
|
@@ -1341,7 +1625,11 @@ function normalizeRepoPathForState(repoRoot: string, absolutePath: string) {
|
|
|
1341
1625
|
return relative;
|
|
1342
1626
|
}
|
|
1343
1627
|
|
|
1344
|
-
function normalizeFromWorktree(
|
|
1628
|
+
function normalizeFromWorktree(
|
|
1629
|
+
worktreePath: string,
|
|
1630
|
+
repoRoot: string,
|
|
1631
|
+
repoRelativeFromWorktree: string,
|
|
1632
|
+
) {
|
|
1345
1633
|
const absolute = path.resolve(repoRoot, repoRelativeFromWorktree);
|
|
1346
1634
|
const maybeRelativeToWorktree = path.relative(worktreePath, absolute).replaceAll('\\\\', '/');
|
|
1347
1635
|
if (!maybeRelativeToWorktree.startsWith('../')) {
|