agentic-orchestrator 0.1.28 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +46 -1
- package/.cortexrc +28 -0
- package/.github/agents/copilot-instructions.md +29 -0
- package/.github/copilot-instructions.md +93 -0
- package/.vscode/settings.json +13 -0
- package/.vscode/tms.code-snippets +223 -0
- package/AGENTS.md +72 -1
- package/Agentic-Orchestrator.iml +12 -11
- package/CLAUDE.md +72 -1
- package/CONSTITUTION.md +504 -0
- package/FUTURE-ENHANCEMENTS.md +85 -0
- package/NEXT-TASKS.md +25 -0
- package/PROMPTS.md +161 -0
- package/README.md +126 -29
- package/agentic/orchestrator/agents.yaml +4 -3
- package/agentic/orchestrator/defaults/policy.defaults.yaml +39 -3
- package/agentic/orchestrator/gates.yaml +15 -3
- package/agentic/orchestrator/policy.yaml +47 -3
- package/agentic/orchestrator/prompts/builder.system.md +69 -20
- package/agentic/orchestrator/prompts/planner-intake.system.md +149 -0
- package/agentic/orchestrator/prompts/planner.system.md +113 -40
- package/agentic/orchestrator/prompts/qa.system.md +73 -18
- package/agentic/orchestrator/prompts/reconciler.system.md +119 -0
- package/agentic/orchestrator/schemas/agents.schema.json +89 -1
- package/agentic/orchestrator/schemas/execution-control.schema.json +242 -0
- package/agentic/orchestrator/schemas/index.schema.json +234 -0
- package/agentic/orchestrator/schemas/intake.review.schema.json +82 -0
- package/agentic/orchestrator/schemas/organizer-ordering-artifact.schema.json +75 -0
- package/agentic/orchestrator/schemas/plan.schema.json +44 -0
- package/agentic/orchestrator/schemas/policy.schema.json +238 -9
- package/agentic/orchestrator/schemas/policy.user.schema.json +129 -1
- package/agentic/orchestrator/schemas/spec.manifest.bootstrap.schema.json +101 -0
- package/agentic/orchestrator/schemas/spec.manifest.verified.schema.json +80 -0
- package/agentic/orchestrator/schemas/state.schema.json +298 -3
- package/agentic/orchestrator/tools/catalog.json +145 -15
- package/agentic/orchestrator/tools/schemas/input/doctor.run.input.schema.json +18 -0
- package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +4 -0
- package/agentic/orchestrator/tools/schemas/input/evidence.verify_chain.input.schema.json +13 -0
- package/agentic/orchestrator/tools/schemas/input/feature.intake_submit.input.schema.json +11 -0
- package/agentic/orchestrator/tools/schemas/input/feature.question_answer.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/feature.question_create.input.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/input/feature.question_list.input.schema.json +13 -0
- package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +5 -0
- package/agentic/orchestrator/tools/schemas/input/feature.send_message.input.schema.json +1 -1
- package/agentic/orchestrator/tools/schemas/input/replay.timeline_get.input.schema.json +32 -0
- package/agentic/orchestrator/tools/schemas/input/repo.conflict_abort.input.schema.json +16 -0
- package/agentic/orchestrator/tools/schemas/input/repo.conflict_files.input.schema.json +16 -0
- package/agentic/orchestrator/tools/schemas/input/repo.reconcile_mainline.input.schema.json +37 -0
- package/agentic/orchestrator/tools/schemas/input/repo.resolve_conflict.input.schema.json +40 -0
- package/agentic/orchestrator/tools/schemas/input/runtime.execution_request_list.input.schema.json +7 -0
- package/agentic/orchestrator/tools/schemas/input/runtime.execution_request_submit.input.schema.json +25 -0
- package/agentic/orchestrator/tools/schemas/output/doctor.run.output.schema.json +34 -0
- package/agentic/orchestrator/tools/schemas/output/evidence.verify_chain.output.schema.json +23 -0
- package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +62 -2
- package/agentic/orchestrator/tools/schemas/output/feature.intake_submit.output.schema.json +24 -0
- package/agentic/orchestrator/tools/schemas/output/feature.question_answer.output.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/output/feature.question_create.output.schema.json +12 -0
- package/agentic/orchestrator/tools/schemas/output/feature.question_list.output.schema.json +14 -0
- package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +31 -0
- package/agentic/orchestrator/tools/schemas/output/feature.send_message.output.schema.json +8 -18
- package/agentic/orchestrator/tools/schemas/output/replay.timeline_get.output.schema.json +64 -0
- package/agentic/orchestrator/tools/schemas/output/repo.conflict_abort.output.schema.json +16 -0
- package/agentic/orchestrator/tools/schemas/output/repo.conflict_files.output.schema.json +22 -0
- package/agentic/orchestrator/tools/schemas/output/repo.reconcile_mainline.output.schema.json +61 -0
- package/agentic/orchestrator/tools/schemas/output/repo.resolve_conflict.output.schema.json +19 -0
- package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +26 -0
- package/agentic/orchestrator/tools/schemas/output/runtime.execution_request_list.output.schema.json +17 -0
- package/agentic/orchestrator/tools/schemas/output/runtime.execution_request_submit.output.schema.json +24 -0
- package/agentic/orchestrator/tools.md +13 -0
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +1 -1
- package/apps/control-plane/src/application/kernel-tool-wiring.ts +140 -2
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +44 -1
- package/apps/control-plane/src/application/services/bootstrap-manifest-generator-service.ts +251 -0
- package/apps/control-plane/src/application/services/checkpoint-service.ts +87 -27
- package/apps/control-plane/src/application/services/collision-override-service.ts +906 -0
- package/apps/control-plane/src/application/services/collision-queue-service.ts +129 -38
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +94 -0
- package/apps/control-plane/src/application/services/execution-control-service.ts +599 -0
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +37 -1
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +182 -4
- package/apps/control-plane/src/application/services/feature-send-message-service.ts +17 -8
- package/apps/control-plane/src/application/services/feature-state-service.ts +191 -6
- package/apps/control-plane/src/application/services/gate-service.ts +121 -2
- package/apps/control-plane/src/application/services/git-reconciliation-service.ts +1591 -0
- package/apps/control-plane/src/application/services/intake-service.ts +1468 -0
- package/apps/control-plane/src/application/services/merge-service.ts +308 -17
- package/apps/control-plane/src/application/services/notifier-service.ts +3 -1
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +75 -0
- package/apps/control-plane/src/application/services/plan-service.ts +336 -20
- package/apps/control-plane/src/application/services/question-service.ts +693 -0
- package/apps/control-plane/src/application/services/reactions-service.ts +73 -17
- package/apps/control-plane/src/application/services/replay-timeline-service.ts +295 -0
- package/apps/control-plane/src/application/services/reporting-service.ts +194 -10
- package/apps/control-plane/src/application/services/run-lease-service.ts +121 -5
- package/apps/control-plane/src/application/services/worktree-watchdog-service.ts +95 -8
- package/apps/control-plane/src/application/tools/tool-metadata.ts +7 -0
- package/apps/control-plane/src/application/usage-types.ts +138 -0
- package/apps/control-plane/src/cli/add-command-handler.ts +162 -0
- package/apps/control-plane/src/cli/answer-command-handler.ts +113 -0
- package/apps/control-plane/src/cli/attach-command-handler.ts +12 -3
- package/apps/control-plane/src/cli/cli-argument-parser.ts +133 -11
- package/apps/control-plane/src/cli/collision-command-handler.ts +113 -0
- package/apps/control-plane/src/cli/command-catalog.ts +479 -0
- package/apps/control-plane/src/cli/complete-command-handler.ts +23 -0
- package/apps/control-plane/src/cli/completion-command-handler.ts +25 -0
- package/apps/control-plane/src/cli/completion-resolver.ts +319 -0
- package/apps/control-plane/src/cli/completion-shell-renderer.ts +58 -0
- package/apps/control-plane/src/cli/dashboard-command-handler.ts +110 -1
- package/apps/control-plane/src/cli/dashboard-runtime-runner.ts +1036 -0
- package/apps/control-plane/src/cli/dashboard-runtime.ts +31 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +17 -185
- package/apps/control-plane/src/cli/init-command-handler.ts +51 -6
- package/apps/control-plane/src/cli/merge-command-handler.ts +200 -0
- package/apps/control-plane/src/cli/questions-command-handler.ts +70 -0
- package/apps/control-plane/src/cli/replay-command-handler.ts +98 -0
- package/apps/control-plane/src/cli/resume-command-handler.ts +231 -16
- package/apps/control-plane/src/cli/retry-command-handler.ts +229 -17
- package/apps/control-plane/src/cli/retry-resume-decision.ts +75 -0
- package/apps/control-plane/src/cli/rollback-command-handler.ts +4 -2
- package/apps/control-plane/src/cli/run-command-handler.ts +35 -1
- package/apps/control-plane/src/cli/spec-ingestion-service.ts +45 -55
- package/apps/control-plane/src/cli/spec-preparation.ts +114 -0
- package/apps/control-plane/src/cli/spec-utils.ts +90 -11
- package/apps/control-plane/src/cli/status-command-handler.ts +122 -0
- package/apps/control-plane/src/cli/types.ts +41 -3
- package/apps/control-plane/src/core/collisions.ts +150 -31
- package/apps/control-plane/src/core/constants.ts +18 -1
- package/apps/control-plane/src/core/error-codes.ts +39 -0
- package/apps/control-plane/src/core/execution-control.ts +56 -0
- package/apps/control-plane/src/core/feature-resume-phase.ts +118 -0
- package/apps/control-plane/src/core/gate-freshness.ts +359 -0
- package/apps/control-plane/src/core/gate-log-extractor.ts +97 -0
- package/apps/control-plane/src/core/gates.ts +90 -1
- package/apps/control-plane/src/core/intake-artifacts.ts +295 -0
- package/apps/control-plane/src/core/kernel-types.ts +11 -0
- package/apps/control-plane/src/core/kernel.ts +604 -16
- package/apps/control-plane/src/core/mainline-conflict.ts +22 -0
- package/apps/control-plane/src/core/merge-repair.ts +149 -0
- package/apps/control-plane/src/core/path-layout.ts +46 -2
- package/apps/control-plane/src/core/path-rules.ts +11 -3
- package/apps/control-plane/src/core/plan-submit-recovery.ts +130 -0
- package/apps/control-plane/src/core/questions.ts +49 -0
- package/apps/control-plane/src/core/runtime-sessions.ts +4 -0
- package/apps/control-plane/src/core/schemas.ts +40 -1
- package/apps/control-plane/src/core/tool-caller.ts +25 -1
- package/apps/control-plane/src/core/utils/index-normalizer.ts +25 -4
- package/apps/control-plane/src/core/worktree-diff.ts +66 -0
- package/apps/control-plane/src/index.ts +29 -1
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +300 -6
- package/apps/control-plane/src/mcp/kernel-tool-executor.ts +17 -0
- package/apps/control-plane/src/mcp/tool-runtime.ts +63 -4
- package/apps/control-plane/src/providers/api-worker-provider.ts +62 -15
- package/apps/control-plane/src/providers/cli-worker-provider.ts +1037 -61
- package/apps/control-plane/src/providers/output-parsers/generic-output-parser.ts +99 -1
- package/apps/control-plane/src/providers/output-parsers/types.ts +2 -0
- package/apps/control-plane/src/providers/provider-defaults.ts +116 -7
- package/apps/control-plane/src/providers/providers.ts +225 -21
- package/apps/control-plane/src/providers/worker-provider-factory.ts +26 -2
- package/apps/control-plane/src/supervisor/artifact-stager.ts +52 -0
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +477 -166
- package/apps/control-plane/src/supervisor/execution-enrollment-service.ts +408 -0
- package/apps/control-plane/src/supervisor/organizer-enrollment-scheduler.ts +117 -0
- package/apps/control-plane/src/supervisor/organizer-sidecar-service.ts +394 -0
- package/apps/control-plane/src/supervisor/plan-conformance-scorer.ts +2 -5
- package/apps/control-plane/src/supervisor/planner-phase.ts +85 -0
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +993 -64
- package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +20 -1
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +384 -177
- package/apps/control-plane/src/supervisor/run-coordinator.ts +723 -20
- package/apps/control-plane/src/supervisor/runtime.ts +485 -9
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +220 -1
- package/apps/control-plane/src/supervisor/types.ts +152 -1
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +1030 -92
- package/apps/control-plane/test/activity-monitor.spec.ts +76 -0
- package/apps/control-plane/test/add-command-handler.spec.ts +189 -0
- package/apps/control-plane/test/application/services/feature-state-service.spec.ts +208 -0
- package/apps/control-plane/test/artifact-stager.spec.ts +93 -0
- package/apps/control-plane/test/batch-operations.spec.ts +58 -0
- package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +50 -2
- package/apps/control-plane/test/bootstrap-manifest-generator-service.spec.ts +99 -0
- package/apps/control-plane/test/bootstrap.spec.ts +177 -4
- package/apps/control-plane/test/checkpoint-service.spec.ts +977 -29
- package/apps/control-plane/test/cli-argument-parser.spec.ts +119 -0
- package/apps/control-plane/test/cli-helpers.spec.ts +1202 -12
- package/apps/control-plane/test/cli.unit.spec.ts +797 -16
- package/apps/control-plane/test/collision-command-handler.spec.ts +182 -0
- package/apps/control-plane/test/collision-override-service.spec.ts +878 -0
- package/apps/control-plane/test/collision-queue.spec.ts +430 -2
- package/apps/control-plane/test/collisions.spec.ts +209 -1
- package/apps/control-plane/test/core-utils.spec.ts +61 -0
- package/apps/control-plane/test/cost-tracking.spec.ts +224 -0
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +185 -5
- package/apps/control-plane/test/dashboard-client.spec.ts +948 -0
- package/apps/control-plane/test/dashboard-command.spec.ts +138 -6
- package/apps/control-plane/test/dashboard-runtime-runner.spec.ts +1550 -0
- package/apps/control-plane/test/dashboard-runtime.spec.ts +138 -0
- package/apps/control-plane/test/dashboard-ui-utils.spec.ts +56 -12
- package/apps/control-plane/test/dependency-scheduler.spec.ts +7 -1
- package/apps/control-plane/test/env-file.spec.ts +76 -0
- package/apps/control-plane/test/execution-control-service.spec.ts +535 -0
- package/apps/control-plane/test/execution-enrollment-service.spec.ts +648 -0
- package/apps/control-plane/test/feature-lifecycle.spec.ts +126 -0
- package/apps/control-plane/test/feature-resume-phase.spec.ts +164 -0
- package/apps/control-plane/test/feature-send-message-service.spec.ts +161 -0
- package/apps/control-plane/test/feature-state-service.spec.ts +295 -0
- package/apps/control-plane/test/fs.spec.ts +80 -0
- package/apps/control-plane/test/gate-freshness.spec.ts +590 -0
- package/apps/control-plane/test/gate-log-extractor.spec.ts +170 -0
- package/apps/control-plane/test/gates.spec.ts +108 -0
- package/apps/control-plane/test/git-reconciliation-service.spec.ts +2307 -0
- package/apps/control-plane/test/helpers.ts +65 -0
- package/apps/control-plane/test/incremental-gates.spec.ts +271 -0
- package/apps/control-plane/test/index-normalizer.spec.ts +98 -0
- package/apps/control-plane/test/init-wizard.spec.ts +17 -0
- package/apps/control-plane/test/intake-artifacts.spec.ts +203 -0
- package/apps/control-plane/test/intake-service.spec.ts +3176 -0
- package/apps/control-plane/test/kernel-collision-replay.spec.ts +3 -2
- package/apps/control-plane/test/kernel-tool-executor.spec.ts +77 -0
- package/apps/control-plane/test/kernel-tool-wiring.spec.ts +279 -0
- package/apps/control-plane/test/kernel.branches.spec.ts +15 -2
- package/apps/control-plane/test/kernel.coverage.spec.ts +7 -3
- package/apps/control-plane/test/kernel.coverage2.spec.ts +731 -2
- package/apps/control-plane/test/kernel.spec.ts +464 -2
- package/apps/control-plane/test/mainline-conflict.spec.ts +66 -0
- package/apps/control-plane/test/mcp-helpers.spec.ts +79 -0
- package/apps/control-plane/test/mcp.spec.ts +177 -13
- package/apps/control-plane/test/merge-command-handler.spec.ts +531 -0
- package/apps/control-plane/test/merge-service.spec.ts +570 -4
- package/apps/control-plane/test/notifier-service.spec.ts +26 -0
- package/apps/control-plane/test/organizer-enrollment-scheduler.spec.ts +340 -0
- package/apps/control-plane/test/organizer-ordering-artifact.spec.ts +95 -0
- package/apps/control-plane/test/organizer-sidecar-service.spec.ts +468 -0
- package/apps/control-plane/test/output-loop-detector.spec.ts +6 -0
- package/apps/control-plane/test/path-layout.spec.ts +70 -0
- package/apps/control-plane/test/performance-analytics.spec.ts +124 -0
- package/apps/control-plane/test/plan-conformance-scorer.spec.ts +53 -0
- package/apps/control-plane/test/plan-service.spec.ts +686 -4
- package/apps/control-plane/test/planning-wave-executor.spec.ts +3272 -86
- package/apps/control-plane/test/policy-loader-service.spec.ts +5 -0
- package/apps/control-plane/test/prompt-overlay.spec.ts +65 -0
- package/apps/control-plane/test/provider-command-runner-epipe.spec.ts +64 -0
- package/apps/control-plane/test/providers/api-worker-provider.spec.ts +129 -0
- package/apps/control-plane/test/providers/cli-worker-provider.spec.ts +148 -0
- package/apps/control-plane/test/providers/usage-types.spec.ts +98 -0
- package/apps/control-plane/test/providers.spec.ts +293 -16
- package/apps/control-plane/test/question-command-handlers.spec.ts +156 -0
- package/apps/control-plane/test/question-service.spec.ts +1119 -0
- package/apps/control-plane/test/reactions.spec.ts +114 -0
- package/apps/control-plane/test/replay-command-handler.spec.ts +144 -0
- package/apps/control-plane/test/replay-timeline-service.spec.ts +459 -0
- package/apps/control-plane/test/response.spec.ts +31 -0
- package/apps/control-plane/test/resume-command.spec.ts +757 -9
- package/apps/control-plane/test/retry-resume-decision.spec.ts +133 -0
- package/apps/control-plane/test/rollback-command-handler.spec.ts +334 -0
- package/apps/control-plane/test/rollback-command.spec.ts +120 -0
- package/apps/control-plane/test/run-coordinator.spec.ts +3062 -404
- package/apps/control-plane/test/schemas/state.schema.spec.ts +71 -0
- package/apps/control-plane/test/service-retry-paths.spec.ts +112 -0
- package/apps/control-plane/test/services.spec.ts +472 -2
- package/apps/control-plane/test/session-management.spec.ts +346 -1
- package/apps/control-plane/test/spec-ingestion.spec.ts +102 -28
- package/apps/control-plane/test/spec-preparation.spec.ts +182 -0
- package/apps/control-plane/test/supervisor-collaborators.spec.ts +191 -3
- package/apps/control-plane/test/supervisor.calltool.spec.ts +198 -0
- package/apps/control-plane/test/supervisor.spec.ts +95 -16
- package/apps/control-plane/test/supervisor.unit.spec.ts +385 -18
- package/apps/control-plane/test/tool-runtime.spec.ts +122 -0
- package/apps/control-plane/test/worker-decision-loop.spec.ts +3479 -476
- package/apps/control-plane/test/worker-execution-policy.spec.ts +1416 -6
- package/apps/control-plane/test/worker-provider-adapters.spec.ts +1894 -37
- package/apps/control-plane/test/worker-provider-factory.spec.ts +81 -0
- package/apps/control-plane/test/worktree-watchdog-service.spec.ts +125 -0
- package/apps/control-plane/vitest.config.ts +5 -0
- package/config/agentic/orchestrator/agents.yaml +22 -1
- package/config/agentic/orchestrator/gates.yaml +24 -7
- package/config/agentic/orchestrator/policy.yaml +23 -1
- package/config/agentic/orchestrator/prompts/builder.system.md +69 -20
- package/config/agentic/orchestrator/prompts/organizer.system.md +85 -0
- package/config/agentic/orchestrator/prompts/overrides/builder.claude.md +28 -0
- package/config/agentic/orchestrator/prompts/overrides/builder.codex.md +28 -0
- package/config/agentic/orchestrator/prompts/overrides/planner.claude.md +20 -0
- package/config/agentic/orchestrator/prompts/overrides/planner.codex.md +20 -0
- package/config/agentic/orchestrator/prompts/planner-intake.system.md +149 -0
- package/config/agentic/orchestrator/prompts/planner.system.md +113 -40
- package/config/agentic/orchestrator/prompts/qa.system.md +75 -18
- package/config/agentic/orchestrator/prompts/reconciler.system.md +119 -0
- package/dist/apps/control-plane/application/kernel-tool-wiring.d.ts +26 -2
- package/dist/apps/control-plane/application/kernel-tool-wiring.js +40 -2
- package/dist/apps/control-plane/application/kernel-tool-wiring.js.map +1 -1
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +37 -1
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.d.ts +4 -0
- package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.js +188 -0
- package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/checkpoint-service.d.ts +5 -0
- package/dist/apps/control-plane/application/services/checkpoint-service.js +69 -24
- package/dist/apps/control-plane/application/services/checkpoint-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/collision-override-service.d.ts +139 -0
- package/dist/apps/control-plane/application/services/collision-override-service.js +568 -0
- package/dist/apps/control-plane/application/services/collision-override-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +15 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js +92 -33
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +11 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +75 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/execution-control-service.d.ts +75 -0
- package/dist/apps/control-plane/application/services/execution-control-service.js +421 -0
- package/dist/apps/control-plane/application/services/execution-control-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +1 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +23 -1
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +24 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +132 -3
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-send-message-service.js +16 -8
- package/dist/apps/control-plane/application/services/feature-send-message-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-state-service.d.ts +36 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js +163 -6
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-service.d.ts +2 -1
- package/dist/apps/control-plane/application/services/gate-service.js +95 -5
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/git-reconciliation-service.d.ts +92 -0
- package/dist/apps/control-plane/application/services/git-reconciliation-service.js +1097 -0
- package/dist/apps/control-plane/application/services/git-reconciliation-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/intake-service.d.ts +63 -0
- package/dist/apps/control-plane/application/services/intake-service.js +1050 -0
- package/dist/apps/control-plane/application/services/intake-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/merge-service.d.ts +5 -1
- package/dist/apps/control-plane/application/services/merge-service.js +233 -18
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.d.ts +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.js +1 -0
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +11 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +59 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/plan-service.d.ts +5 -0
- package/dist/apps/control-plane/application/services/plan-service.js +254 -15
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/question-service.d.ts +72 -0
- package/dist/apps/control-plane/application/services/question-service.js +507 -0
- package/dist/apps/control-plane/application/services/question-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/reactions-service.d.ts +2 -0
- package/dist/apps/control-plane/application/services/reactions-service.js +60 -17
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/replay-timeline-service.d.ts +39 -0
- package/dist/apps/control-plane/application/services/replay-timeline-service.js +205 -0
- package/dist/apps/control-plane/application/services/replay-timeline-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/reporting-service.d.ts +59 -0
- package/dist/apps/control-plane/application/services/reporting-service.js +121 -9
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.d.ts +20 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js +81 -4
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.d.ts +10 -0
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.js +65 -8
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-metadata.js +7 -0
- package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -1
- package/dist/apps/control-plane/application/usage-types.d.ts +65 -0
- package/dist/apps/control-plane/application/usage-types.js +75 -0
- package/dist/apps/control-plane/application/usage-types.js.map +1 -0
- package/dist/apps/control-plane/cli/add-command-handler.d.ts +18 -0
- package/dist/apps/control-plane/cli/add-command-handler.js +110 -0
- package/dist/apps/control-plane/cli/add-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/answer-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/answer-command-handler.js +96 -0
- package/dist/apps/control-plane/cli/answer-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/attach-command-handler.js +8 -3
- package/dist/apps/control-plane/cli/attach-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/cli-argument-parser.js +131 -11
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/collision-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/collision-command-handler.js +90 -0
- package/dist/apps/control-plane/cli/collision-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/command-catalog.d.ts +21 -0
- package/dist/apps/control-plane/cli/command-catalog.js +416 -0
- package/dist/apps/control-plane/cli/command-catalog.js.map +1 -0
- package/dist/apps/control-plane/cli/complete-command-handler.d.ts +15 -0
- package/dist/apps/control-plane/cli/complete-command-handler.js +26 -0
- package/dist/apps/control-plane/cli/complete-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/completion-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/completion-command-handler.js +20 -0
- package/dist/apps/control-plane/cli/completion-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/completion-resolver.d.ts +1 -0
- package/dist/apps/control-plane/cli/completion-resolver.js +250 -0
- package/dist/apps/control-plane/cli/completion-resolver.js.map +1 -0
- package/dist/apps/control-plane/cli/completion-shell-renderer.d.ts +3 -0
- package/dist/apps/control-plane/cli/completion-shell-renderer.js +53 -0
- package/dist/apps/control-plane/cli/completion-shell-renderer.js.map +1 -0
- package/dist/apps/control-plane/cli/dashboard-command-handler.d.ts +1 -0
- package/dist/apps/control-plane/cli/dashboard-command-handler.js +83 -1
- package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/dashboard-runtime-runner.d.ts +81 -0
- package/dist/apps/control-plane/cli/dashboard-runtime-runner.js +724 -0
- package/dist/apps/control-plane/cli/dashboard-runtime-runner.js.map +1 -0
- package/dist/apps/control-plane/cli/dashboard-runtime.d.ts +1 -0
- package/dist/apps/control-plane/cli/dashboard-runtime.js +26 -0
- package/dist/apps/control-plane/cli/dashboard-runtime.js.map +1 -0
- package/dist/apps/control-plane/cli/help-command-handler.js +13 -172
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.js +51 -6
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/merge-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/merge-command-handler.js +139 -0
- package/dist/apps/control-plane/cli/merge-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/questions-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/questions-command-handler.js +59 -0
- package/dist/apps/control-plane/cli/questions-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/replay-command-handler.d.ts +15 -0
- package/dist/apps/control-plane/cli/replay-command-handler.js +55 -0
- package/dist/apps/control-plane/cli/replay-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/resume-command-handler.d.ts +2 -0
- package/dist/apps/control-plane/cli/resume-command-handler.js +180 -17
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-command-handler.js +202 -16
- package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-resume-decision.d.ts +26 -0
- package/dist/apps/control-plane/cli/retry-resume-decision.js +61 -0
- package/dist/apps/control-plane/cli/retry-resume-decision.js.map +1 -0
- package/dist/apps/control-plane/cli/rollback-command-handler.js +3 -2
- package/dist/apps/control-plane/cli/rollback-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/run-command-handler.js +26 -2
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-ingestion-service.d.ts +2 -0
- package/dist/apps/control-plane/cli/spec-ingestion-service.js +37 -48
- package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-preparation.d.ts +14 -0
- package/dist/apps/control-plane/cli/spec-preparation.js +81 -0
- package/dist/apps/control-plane/cli/spec-preparation.js.map +1 -0
- package/dist/apps/control-plane/cli/spec-utils.d.ts +4 -0
- package/dist/apps/control-plane/cli/spec-utils.js +70 -11
- package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
- package/dist/apps/control-plane/cli/status-command-handler.js +69 -0
- package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/types.d.ts +41 -4
- package/dist/apps/control-plane/cli/types.js +9 -1
- package/dist/apps/control-plane/cli/types.js.map +1 -1
- package/dist/apps/control-plane/core/collisions.d.ts +37 -19
- package/dist/apps/control-plane/core/collisions.js +87 -12
- package/dist/apps/control-plane/core/collisions.js.map +1 -1
- package/dist/apps/control-plane/core/constants.d.ts +17 -1
- package/dist/apps/control-plane/core/constants.js +18 -1
- package/dist/apps/control-plane/core/constants.js.map +1 -1
- package/dist/apps/control-plane/core/error-codes.d.ts +39 -0
- package/dist/apps/control-plane/core/error-codes.js +39 -0
- package/dist/apps/control-plane/core/error-codes.js.map +1 -1
- package/dist/apps/control-plane/core/execution-control.d.ts +45 -0
- package/dist/apps/control-plane/core/execution-control.js +2 -0
- package/dist/apps/control-plane/core/execution-control.js.map +1 -0
- package/dist/apps/control-plane/core/feature-resume-phase.d.ts +3 -0
- package/dist/apps/control-plane/core/feature-resume-phase.js +88 -0
- package/dist/apps/control-plane/core/feature-resume-phase.js.map +1 -0
- package/dist/apps/control-plane/core/gate-freshness.d.ts +48 -0
- package/dist/apps/control-plane/core/gate-freshness.js +267 -0
- package/dist/apps/control-plane/core/gate-freshness.js.map +1 -0
- package/dist/apps/control-plane/core/gate-log-extractor.d.ts +22 -0
- package/dist/apps/control-plane/core/gate-log-extractor.js +66 -0
- package/dist/apps/control-plane/core/gate-log-extractor.js.map +1 -0
- package/dist/apps/control-plane/core/gates.d.ts +11 -2
- package/dist/apps/control-plane/core/gates.js +67 -3
- package/dist/apps/control-plane/core/gates.js.map +1 -1
- package/dist/apps/control-plane/core/intake-artifacts.d.ts +109 -0
- package/dist/apps/control-plane/core/intake-artifacts.js +143 -0
- package/dist/apps/control-plane/core/intake-artifacts.js.map +1 -0
- package/dist/apps/control-plane/core/kernel-types.d.ts +8 -0
- package/dist/apps/control-plane/core/kernel.d.ts +256 -8
- package/dist/apps/control-plane/core/kernel.js +400 -14
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/mainline-conflict.d.ts +7 -0
- package/dist/apps/control-plane/core/mainline-conflict.js +20 -0
- package/dist/apps/control-plane/core/mainline-conflict.js.map +1 -0
- package/dist/apps/control-plane/core/merge-repair.d.ts +35 -0
- package/dist/apps/control-plane/core/merge-repair.js +99 -0
- package/dist/apps/control-plane/core/merge-repair.js.map +1 -0
- package/dist/apps/control-plane/core/path-layout.d.ts +10 -0
- package/dist/apps/control-plane/core/path-layout.js +32 -2
- package/dist/apps/control-plane/core/path-layout.js.map +1 -1
- package/dist/apps/control-plane/core/path-rules.js +9 -3
- package/dist/apps/control-plane/core/path-rules.js.map +1 -1
- package/dist/apps/control-plane/core/plan-submit-recovery.d.ts +22 -0
- package/dist/apps/control-plane/core/plan-submit-recovery.js +78 -0
- package/dist/apps/control-plane/core/plan-submit-recovery.js.map +1 -0
- package/dist/apps/control-plane/core/questions.d.ts +40 -0
- package/dist/apps/control-plane/core/questions.js +2 -0
- package/dist/apps/control-plane/core/questions.js.map +1 -0
- package/dist/apps/control-plane/core/runtime-sessions.d.ts +4 -0
- package/dist/apps/control-plane/core/schemas.d.ts +2 -0
- package/dist/apps/control-plane/core/schemas.js +31 -1
- package/dist/apps/control-plane/core/schemas.js.map +1 -1
- package/dist/apps/control-plane/core/tool-caller.d.ts +18 -1
- package/dist/apps/control-plane/core/utils/index-normalizer.js +17 -4
- package/dist/apps/control-plane/core/utils/index-normalizer.js.map +1 -1
- package/dist/apps/control-plane/core/worktree-diff.d.ts +4 -0
- package/dist/apps/control-plane/core/worktree-diff.js +52 -0
- package/dist/apps/control-plane/core/worktree-diff.js.map +1 -0
- package/dist/apps/control-plane/index.d.ts +10 -2
- package/dist/apps/control-plane/index.js +9 -2
- package/dist/apps/control-plane/index.js.map +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +236 -6
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js +16 -0
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-runtime.d.ts +5 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js +40 -5
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
- package/dist/apps/control-plane/providers/api-worker-provider.d.ts +2 -2
- package/dist/apps/control-plane/providers/api-worker-provider.js +40 -9
- package/dist/apps/control-plane/providers/api-worker-provider.js.map +1 -1
- package/dist/apps/control-plane/providers/cli-worker-provider.d.ts +59 -3
- package/dist/apps/control-plane/providers/cli-worker-provider.js +758 -46
- package/dist/apps/control-plane/providers/cli-worker-provider.js.map +1 -1
- package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js +91 -1
- package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js.map +1 -1
- package/dist/apps/control-plane/providers/output-parsers/types.d.ts +2 -0
- package/dist/apps/control-plane/providers/provider-defaults.d.ts +12 -0
- package/dist/apps/control-plane/providers/provider-defaults.js +103 -7
- package/dist/apps/control-plane/providers/provider-defaults.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +50 -4
- package/dist/apps/control-plane/providers/providers.js +145 -14
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +2 -0
- package/dist/apps/control-plane/providers/worker-provider-factory.js +8 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
- package/dist/apps/control-plane/supervisor/artifact-stager.d.ts +5 -0
- package/dist/apps/control-plane/supervisor/artifact-stager.js +45 -0
- package/dist/apps/control-plane/supervisor/artifact-stager.js.map +1 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +24 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +362 -150
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/execution-enrollment-service.d.ts +41 -0
- package/dist/apps/control-plane/supervisor/execution-enrollment-service.js +311 -0
- package/dist/apps/control-plane/supervisor/execution-enrollment-service.js.map +1 -0
- package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.d.ts +15 -0
- package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.js +93 -0
- package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.js.map +1 -0
- package/dist/apps/control-plane/supervisor/organizer-sidecar-service.d.ts +44 -0
- package/dist/apps/control-plane/supervisor/organizer-sidecar-service.js +311 -0
- package/dist/apps/control-plane/supervisor/organizer-sidecar-service.js.map +1 -0
- package/dist/apps/control-plane/supervisor/plan-conformance-scorer.js +2 -5
- package/dist/apps/control-plane/supervisor/plan-conformance-scorer.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planner-phase.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/planner-phase.js +70 -0
- package/dist/apps/control-plane/supervisor/planner-phase.js.map +1 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +42 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +753 -55
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +19 -1
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js.map +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +21 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +287 -156
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +30 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.js +561 -17
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.d.ts +84 -0
- package/dist/apps/control-plane/supervisor/runtime.js +393 -3
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +54 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +176 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/types.d.ts +142 -1
- package/dist/apps/control-plane/supervisor/types.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +68 -2
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +723 -89
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/docs/core/ARCHITECTURE.md +227 -0
- package/docs/core/DECISIONS.md +94 -0
- package/docs/core/DOMAIN-LOGIC.md +60 -0
- package/docs/core/PATTERNS.md +201 -0
- package/docs/core/TROUBLESHOOTING.md +347 -0
- package/docs/core/intentgraph-dependencies.json +39860 -0
- package/docs/core/intentgraph.index.json +46580 -0
- package/docs/plans/2026-03-10-gate-failure-targeted-repair-design.md +224 -0
- package/docs/plans/2026-03-10-gate-failure-targeted-repair.md +1032 -0
- package/docs/superpowers/plans/2026-03-16-provider-cli-config.md +743 -0
- package/docs/superpowers/plans/2026-03-23-reconcile-divergence-fix.md +777 -0
- package/docs/superpowers/plans/2026-03-28-ordering-agent-implementation.md +1754 -0
- package/docs/superpowers/plans/2026-03-29-drop-zone-and-provider-optimization.md +1108 -0
- package/docs/superpowers/plans/2026-03-29-merge-target-feature-branch.md +685 -0
- package/docs/superpowers/plans/2026-03-29-organizer-sidecar-runtime-loop.md +1289 -0
- package/docs/superpowers/specs/2026-03-23-reconcile-divergence-fix-design.md +118 -0
- package/docs/superpowers/specs/2026-03-28-ordering-agent-spec-audit-design.md +50 -0
- package/docs/superpowers/specs/2026-03-29-drop-zone-and-provider-optimization-design.md +254 -0
- package/docs/superpowers/specs/2026-03-29-merge-target-feature-branch-design.md +152 -0
- package/docs/superpowers/specs/2026-03-29-organizer-sidecar-runtime-loop-design.md +225 -0
- package/package.json +3 -2
- package/packages/web-dashboard/package.json +2 -1
- package/packages/web-dashboard/src/app/analytics/page.tsx +36 -2
- package/packages/web-dashboard/src/app/api/actions/route.ts +274 -63
- package/packages/web-dashboard/src/app/api/actions/status/route.ts +35 -0
- package/packages/web-dashboard/src/app/api/analytics/provider/route.ts +18 -0
- package/packages/web-dashboard/src/app/api/collisions/approve/route.ts +58 -0
- package/packages/web-dashboard/src/app/api/features/[id]/checkpoint-diff/route.ts +36 -0
- package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/route.ts +29 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/abort/route.ts +29 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/files/route.ts +30 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/resolve/route.ts +51 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/route.ts +75 -0
- package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +16 -2
- package/packages/web-dashboard/src/app/api/features/[id]/files/route.ts +26 -0
- package/packages/web-dashboard/src/app/api/features/[id]/gate-history/route.ts +27 -0
- package/packages/web-dashboard/src/app/api/features/[id]/genealogy/route.ts +26 -0
- package/packages/web-dashboard/src/app/api/features/[id]/history/run/[runId]/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/history/runs/route.ts +34 -0
- package/packages/web-dashboard/src/app/api/features/[id]/intake-workspace/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/live-output/route.ts +74 -0
- package/packages/web-dashboard/src/app/api/features/[id]/plan/amend/route.ts +21 -0
- package/packages/web-dashboard/src/app/api/features/[id]/plan-progress/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/planner-artifacts/[artifact]/route.ts +78 -0
- package/packages/web-dashboard/src/app/api/features/[id]/planner-lifecycle/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/planning-workspace/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/questions/[questionId]/answer/route.ts +27 -0
- package/packages/web-dashboard/src/app/api/features/[id]/questions/route.ts +18 -0
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +14 -7
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +57 -2
- package/packages/web-dashboard/src/app/api/features/[id]/spec/route.ts +30 -0
- package/packages/web-dashboard/src/app/api/features/[id]/triage/route.ts +83 -0
- package/packages/web-dashboard/src/app/api/features/[id]/worker-events/route.ts +40 -0
- package/packages/web-dashboard/src/app/api/launch/preview/route.ts +86 -0
- package/packages/web-dashboard/src/app/api/launch/submit/route.ts +180 -0
- package/packages/web-dashboard/src/app/api/mainline/status/route.ts +74 -0
- package/packages/web-dashboard/src/app/api/merge-queue/route.ts +13 -0
- package/packages/web-dashboard/src/app/api/policy/budget/route.ts +14 -0
- package/packages/web-dashboard/src/app/api/projects/route.ts +11 -7
- package/packages/web-dashboard/src/app/api/reconciler/queue/route.ts +47 -0
- package/packages/web-dashboard/src/app/api/run/route.ts +26 -2
- package/packages/web-dashboard/src/app/api/runtime/events/route.ts +227 -0
- package/packages/web-dashboard/src/app/api/runtime/operations/route.ts +269 -0
- package/packages/web-dashboard/src/app/api/runtime/questions/route.ts +11 -0
- package/packages/web-dashboard/src/app/api/runtime/runs/route.ts +80 -0
- package/packages/web-dashboard/src/app/api/status/route.ts +4 -2
- package/packages/web-dashboard/src/app/feature/[id]/page.tsx +32 -42
- package/packages/web-dashboard/src/app/globals.css +34 -3
- package/packages/web-dashboard/src/app/launch/page.tsx +357 -0
- package/packages/web-dashboard/src/app/layout.tsx +23 -1
- package/packages/web-dashboard/src/app/page.tsx +263 -272
- package/packages/web-dashboard/src/components/dashboard/attention-strip.tsx +52 -0
- package/packages/web-dashboard/src/components/dashboard/collision-approval-drawer.tsx +185 -0
- package/packages/web-dashboard/src/components/dashboard/command-center-header.tsx +102 -0
- package/packages/web-dashboard/src/components/dashboard/mainline-status-banner.tsx +84 -0
- package/packages/web-dashboard/src/components/dashboard/merged-archive.tsx +36 -0
- package/packages/web-dashboard/src/components/dashboard/prioritized-queues.tsx +98 -0
- package/packages/web-dashboard/src/components/dashboard/reconciler-queue-card.tsx +115 -0
- package/packages/web-dashboard/src/components/dashboard/secondary-diagnostics-rail.tsx +48 -0
- package/packages/web-dashboard/src/components/dashboard/task-filter-bar.tsx +74 -0
- package/packages/web-dashboard/src/components/dashboard/triage-drawer.tsx +455 -0
- package/packages/web-dashboard/src/components/diff-viewer.tsx +19 -3
- package/packages/web-dashboard/src/components/evidence-viewer.tsx +65 -51
- package/packages/web-dashboard/src/components/feature-card.tsx +90 -7
- package/packages/web-dashboard/src/components/feature-cost-panel.tsx +112 -11
- package/packages/web-dashboard/src/components/feature-list-view.tsx +25 -4
- package/packages/web-dashboard/src/components/features/runtime-inspector/EventsTimelineView.tsx +260 -0
- package/packages/web-dashboard/src/components/features/runtime-inspector/OperationsListView.tsx +172 -0
- package/packages/web-dashboard/src/components/features/runtime-inspector/RuntimeInspectorPanel.tsx +896 -0
- package/packages/web-dashboard/src/components/filter-bar.tsx +7 -39
- package/packages/web-dashboard/src/components/focus/ActionableRiskList.tsx +46 -0
- package/packages/web-dashboard/src/components/focus/AgentRolePerformanceCard.tsx +200 -0
- package/packages/web-dashboard/src/components/focus/BlockedGuidanceBanner.tsx +149 -0
- package/packages/web-dashboard/src/components/focus/CheckpointInspector.tsx +123 -0
- package/packages/web-dashboard/src/components/focus/CheckpointRail.tsx +118 -0
- package/packages/web-dashboard/src/components/focus/CheckpointScrubber.tsx +249 -0
- package/packages/web-dashboard/src/components/focus/CollisionApprovalBanner.tsx +192 -0
- package/packages/web-dashboard/src/components/focus/CollisionRadar.tsx +136 -0
- package/packages/web-dashboard/src/components/focus/ConflictStatusCard.tsx +52 -0
- package/packages/web-dashboard/src/components/focus/ContextSidebar.tsx +108 -0
- package/packages/web-dashboard/src/components/focus/DiagnosisPanel.tsx +68 -0
- package/packages/web-dashboard/src/components/focus/FeatureDecisionBanner.tsx +68 -0
- package/packages/web-dashboard/src/components/focus/FeatureQuestionAnswerPanel.tsx +167 -0
- package/packages/web-dashboard/src/components/focus/FocusHeader.tsx +54 -0
- package/packages/web-dashboard/src/components/focus/FocusLayout.tsx +283 -0
- package/packages/web-dashboard/src/components/focus/GateFlakinessSummary.tsx +144 -0
- package/packages/web-dashboard/src/components/focus/GenealogyTree.tsx +34 -0
- package/packages/web-dashboard/src/components/focus/HeroBlock.tsx +67 -0
- package/packages/web-dashboard/src/components/focus/LiveAgentConsole.tsx +277 -0
- package/packages/web-dashboard/src/components/focus/MergeQueueCard.tsx +78 -0
- package/packages/web-dashboard/src/components/focus/OperationalSummaryCard.tsx +227 -0
- package/packages/web-dashboard/src/components/focus/PinnedActions.tsx +96 -0
- package/packages/web-dashboard/src/components/focus/PlanAmendmentPanel.tsx +250 -0
- package/packages/web-dashboard/src/components/focus/PlanProgressPanel.tsx +133 -0
- package/packages/web-dashboard/src/components/focus/PlannerArtifactViewer.tsx +158 -0
- package/packages/web-dashboard/src/components/focus/PlannerLifecycleHeader.tsx +141 -0
- package/packages/web-dashboard/src/components/focus/ProgressSnapshotCard.tsx +113 -0
- package/packages/web-dashboard/src/components/focus/RecentMaterialChanges.tsx +69 -0
- package/packages/web-dashboard/src/components/focus/RoleLogViewer.tsx +436 -0
- package/packages/web-dashboard/src/components/focus/RunHistoryBrowser.tsx +62 -0
- package/packages/web-dashboard/src/components/focus/SpecViewer.tsx +172 -0
- package/packages/web-dashboard/src/components/focus/TabBar.tsx +33 -0
- package/packages/web-dashboard/src/components/focus/UsageBurnChart.tsx +212 -0
- package/packages/web-dashboard/src/components/focus/VerificationSummaryCard.tsx +122 -0
- package/packages/web-dashboard/src/components/focus/tabs/ChangesTab.tsx +325 -0
- package/packages/web-dashboard/src/components/focus/tabs/ConflictsTab.tsx +395 -0
- package/packages/web-dashboard/src/components/focus/tabs/GatesQaTab.tsx +38 -0
- package/packages/web-dashboard/src/components/focus/tabs/HistoryTab.tsx +213 -0
- package/packages/web-dashboard/src/components/focus/tabs/IntakeTab.tsx +429 -0
- package/packages/web-dashboard/src/components/focus/tabs/OverviewTab.tsx +217 -0
- package/packages/web-dashboard/src/components/focus/tabs/PlanningTab.tsx +390 -0
- package/packages/web-dashboard/src/components/focus/tabs/ReviewTab.tsx +497 -0
- package/packages/web-dashboard/src/components/focus/tabs/RuntimeTab.tsx +213 -0
- package/packages/web-dashboard/src/components/focus/tabs/TranscriptTab.tsx +315 -0
- package/packages/web-dashboard/src/components/gate-results.tsx +2 -2
- package/packages/web-dashboard/src/components/human-input-panel.tsx +33 -57
- package/packages/web-dashboard/src/components/kanban-board.tsx +4 -0
- package/packages/web-dashboard/src/components/launch/launch-draft-card.tsx +131 -0
- package/packages/web-dashboard/src/components/plan-viewer.tsx +147 -69
- package/packages/web-dashboard/src/components/quick-launch-panel.tsx +20 -47
- package/packages/web-dashboard/src/components/summary-bar.tsx +30 -76
- package/packages/web-dashboard/src/lib/aop-client.ts +2484 -36
- package/packages/web-dashboard/src/lib/blocked-state-guidance.ts +475 -0
- package/packages/web-dashboard/src/lib/collision-radar.ts +136 -0
- package/packages/web-dashboard/src/lib/dashboard-action-states.ts +204 -0
- package/packages/web-dashboard/src/lib/dashboard-runtime-client.ts +439 -0
- package/packages/web-dashboard/src/lib/dashboard-utils.ts +179 -18
- package/packages/web-dashboard/src/lib/drop-zone-utils.ts +92 -0
- package/packages/web-dashboard/src/lib/focus-detail-derivations.ts +958 -0
- package/packages/web-dashboard/src/lib/focus-view.ts +300 -0
- package/packages/web-dashboard/src/lib/health-diagnosis.ts +356 -0
- package/packages/web-dashboard/src/lib/launch-contracts.ts +77 -0
- package/packages/web-dashboard/src/lib/launch-markdown.ts +107 -0
- package/packages/web-dashboard/src/lib/launch-page-preview.ts +89 -0
- package/packages/web-dashboard/src/lib/live-feed.ts +1 -1
- package/packages/web-dashboard/src/lib/multi-project-config.ts +33 -0
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +845 -59
- package/packages/web-dashboard/src/lib/planner-workspace.ts +1285 -0
- package/packages/web-dashboard/src/lib/review-contracts.ts +5 -3
- package/packages/web-dashboard/src/lib/runtime-files.ts +285 -0
- package/packages/web-dashboard/src/lib/tool-catalog.ts +51 -0
- package/packages/web-dashboard/src/lib/types.ts +731 -3
- package/packages/web-dashboard/src/lib/usage-burn.ts +175 -0
- package/packages/web-dashboard/src/lib/worktree-diff.ts +128 -0
- package/packages/web-dashboard/src/styles/dashboard.module.css +1742 -459
- package/packages/web-dashboard/test/api/actions/route.spec.ts +675 -0
- package/packages/web-dashboard/test/api/features/diff.route.spec.ts +57 -0
- package/packages/web-dashboard/test/api/features/feature.route.spec.ts +99 -0
- package/packages/web-dashboard/test/api/features/live-output.route.spec.ts +123 -0
- package/packages/web-dashboard/test/api/features/plan-amend.route.spec.ts +95 -0
- package/packages/web-dashboard/test/api/features/planner-workspaces.route.spec.ts +162 -0
- package/packages/web-dashboard/test/api/features/question-answer.route.spec.ts +99 -0
- package/packages/web-dashboard/test/api/features/triage.route.spec.ts +195 -0
- package/packages/web-dashboard/test/api/launch/preview.route.spec.ts +149 -0
- package/packages/web-dashboard/test/api/launch/submit.route.spec.ts +382 -0
- package/packages/web-dashboard/test/api/runtime/events/route.spec.ts +164 -0
- package/packages/web-dashboard/test/api/runtime/operations/route.spec.ts +156 -0
- package/packages/web-dashboard/test/api/runtime/runs/route.spec.ts +112 -0
- package/packages/web-dashboard/test/components/changes-tab.spec.tsx +76 -0
- package/packages/web-dashboard/test/components/command-center-root.spec.tsx +87 -0
- package/packages/web-dashboard/test/components/diagnosis-panel.spec.tsx +59 -0
- package/packages/web-dashboard/test/components/feature-card.spec.tsx +45 -0
- package/packages/web-dashboard/test/components/focus-layout.spec.tsx +299 -0
- package/packages/web-dashboard/test/components/gate-results.spec.tsx +39 -0
- package/packages/web-dashboard/test/components/gates-qa-tab.spec.tsx +118 -0
- package/packages/web-dashboard/test/components/human-input-panel.spec.tsx +54 -0
- package/packages/web-dashboard/test/components/intake-tab.spec.tsx +210 -0
- package/packages/web-dashboard/test/components/kanban-board.spec.tsx +35 -0
- package/packages/web-dashboard/test/components/launch-draft-card.spec.tsx +54 -0
- package/packages/web-dashboard/test/components/launch-page.spec.tsx +79 -0
- package/packages/web-dashboard/test/components/overview-tab.spec.tsx +236 -0
- package/packages/web-dashboard/test/components/planning-tab.spec.tsx +202 -0
- package/packages/web-dashboard/test/components/review-tab.spec.tsx +169 -0
- package/packages/web-dashboard/test/components/role-log-viewer.spec.ts +42 -0
- package/packages/web-dashboard/test/components/runtime-inspector.spec.tsx +22 -0
- package/packages/web-dashboard/test/components/runtime-tab.spec.tsx +133 -0
- package/packages/web-dashboard/test/components/transcript-tab.spec.tsx +46 -0
- package/packages/web-dashboard/test/components/triage-drawer.spec.tsx +159 -0
- package/packages/web-dashboard/test/lib/aop-client.spec.ts +235 -0
- package/packages/web-dashboard/test/lib/dashboard-runtime-client.spec.ts +144 -0
- package/packages/web-dashboard/test/lib/focus-detail-derivations.spec.ts +314 -0
- package/packages/web-dashboard/test/lib/focus-view.spec.ts +248 -0
- package/packages/web-dashboard/test/lib/health-diagnosis.spec.ts +277 -0
- package/packages/web-dashboard/test/lib/launch-markdown.spec.ts +36 -0
- package/packages/web-dashboard/test/lib/multi-project-config.spec.ts +54 -0
- package/packages/web-dashboard/test/lib/orchestrator-tools.spec.ts +352 -0
- package/packages/web-dashboard/test/lib/planner-workspace.spec.ts +289 -0
- package/packages/web-dashboard/test/lib/worktree-diff.spec.ts +119 -0
- package/packages/web-dashboard/vitest.config.ts +2 -0
- package/spec-files/completed/agentic_orchestrator_add_feature_to_active_execution_spec.md +557 -0
- package/spec-files/completed/agentic_orchestrator_dashboard_command_center_redesign_spec.md +1147 -0
- package/spec-files/completed/agentic_orchestrator_execution_mode_spec.md +18 -16
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_a_spec.md +672 -0
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_b_spec.md +794 -0
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_c_decision_centric_remediation_spec.md +1037 -0
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_ux_redesign_spec.md +1432 -0
- package/spec-files/completed/agentic_orchestrator_focus_plan_tab_intake_planning_workspace_spec.md +921 -0
- package/spec-files/completed/agentic_orchestrator_intentional_collision_override_spec.md +584 -0
- package/spec-files/completed/agentic_orchestrator_interactive_planning_intake_and_requirements_verification_spec.md +1185 -0
- package/spec-files/completed/agentic_orchestrator_reactive_execution_enrollment_spec.md +864 -0
- package/spec-files/{outstanding → completed}/agentic_orchestrator_runtime_inspection_spec.md +92 -19
- package/spec-files/completed/agentic_orchestrator_scope_aware_run_lease_spec.md +408 -0
- package/spec-files/completed/git-reconciliation-engine.md +827 -0
- package/spec-files/outstanding/agentic_orchestrator_dashboard_quick_launch_and_control_surface_spec.md +331 -0
- package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +16 -6
- package/spec-files/outstanding/agentic_orchestrator_evidence_integrity_doctor_spec.md +60 -9
- package/spec-files/outstanding/agentic_orchestrator_focus_plan_tab_execution_contract_workspace_spec.md +616 -0
- package/spec-files/outstanding/agentic_orchestrator_headless_standby_dashboard_runtime_spec.md +310 -0
- package/spec-files/outstanding/agentic_orchestrator_human_input_interaction_protocol_spec.md +175 -72
- package/spec-files/outstanding/agentic_orchestrator_interactive_rename_cleanup_spec.md +197 -0
- package/spec-files/outstanding/agentic_orchestrator_interactive_resume_and_reconciliation_disposition_spec.md +412 -0
- package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +166 -137
- package/spec-files/outstanding/agentic_orchestrator_observability_replay_spec.md +3 -3
- package/spec-files/outstanding/agentic_orchestrator_phase_specific_agent_profiles_and_token_telemetry_spec.md +303 -0
- package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +18 -5
- package/spec-files/outstanding/agentic_orchestrator_policy_stratification_spec.md +225 -0
- package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +77 -50
- package/spec-files/outstanding/agentic_orchestrator_ready_to_merge_branch_handoff_spec.md +724 -0
- package/spec-files/outstanding/agentic_orchestrator_remove_deterministic_mode_spec.md +263 -0
- package/spec-files/outstanding/agentic_orchestrator_request_more_context_and_dashboard_human_input_spec.md +456 -0
- package/spec-files/outstanding/agentic_orchestrator_spec_coverage_and_reconciliation_enforcement_spec.md +1411 -0
- package/spec-files/outstanding/agentic_orchestrator_spec_ordering_agent_spec.md +370 -0
- package/spec-files/outstanding/shadow_workspace_implementation_spec.md +1 -1
- package/spec-files/progress.md +2026 -120
- package/specs/001-runtime-inspection/checklists/requirements.md +35 -0
- package/specs/001-runtime-inspection/design.md +338 -0
- package/specs/001-runtime-inspection/spec.md +95 -0
- package/specs/002-scope-aware-lease/checklists/requirements.md +35 -0
- package/specs/002-scope-aware-lease/contracts/lease-registry.schema.json +101 -0
- package/specs/002-scope-aware-lease/data-model.md +236 -0
- package/specs/002-scope-aware-lease/plan.md +766 -0
- package/specs/002-scope-aware-lease/quickstart.md +150 -0
- package/specs/002-scope-aware-lease/research.md +135 -0
- package/specs/002-scope-aware-lease/spec.md +128 -0
- package/specs/002-scope-aware-lease/tasks.md +767 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +28 -0
- package/ARCHITECTURE_ADHERENCE_ANALYSIS.md +0 -871
- package/packages/web-dashboard/next-env.d.ts +0 -6
- package/packages/web-dashboard/src/components/detail-panel.tsx +0 -1124
- package/packages/web-dashboard/src/components/review-workspace.tsx +0 -1162
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_artifact_database_publishing_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_cli_shell_tab_completion_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_dashboard_diff_and_agent_console_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_performance_improvements_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_persistent_worker_runtime_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_provider_auth_bootstrap_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_real_worker_provider_execution_spec.md +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { ERROR_CODES } from '../core/error-codes.js';
|
|
5
6
|
import { NodeProviderCommandRunner, } from './providers.js';
|
|
7
|
+
import { unavailableUsage } from '../application/usage-types.js';
|
|
6
8
|
import { PROVIDER_CLI_DEFAULTS } from './provider-defaults.js';
|
|
7
9
|
import { WorkerWatchdog } from './worker-watchdog.js';
|
|
8
10
|
const CLAUDE_MIN_EFFECTIVE_TIMEOUT_MS = 300_000;
|
|
@@ -19,15 +21,117 @@ const CLI_PROVIDER_CAPABILITIES = {
|
|
|
19
21
|
supportsMessagePassing: true,
|
|
20
22
|
supportsAcknowledgment: false,
|
|
21
23
|
};
|
|
22
|
-
function
|
|
24
|
+
function buildDeterministicWorkerPrompt(payload, systemPrompt) {
|
|
23
25
|
const lines = [];
|
|
24
26
|
if (systemPrompt) {
|
|
25
27
|
lines.push(systemPrompt);
|
|
26
28
|
lines.push('---');
|
|
27
29
|
}
|
|
28
|
-
lines.push('Return exactly one JSON object and nothing else.', 'Allowed output object forms:', '{"type":"PLAN_SUBMISSION|PATCH|NOTE|REQUEST", ...}', '{"outputs":[{"type":"PLAN_SUBMISSION|PATCH|NOTE|REQUEST", ...}], ...}', 'Do not wrap JSON in markdown code fences.', 'Worker input payload:', JSON.stringify(payload));
|
|
30
|
+
lines.push('Return exactly one JSON object and nothing else.', 'Allowed output object forms:', '{"type":"PLAN_SUBMISSION|INTAKE_SUBMISSION|PATCH|NOTE|REQUEST", ...}', '{"outputs":[{"type":"PLAN_SUBMISSION|INTAKE_SUBMISSION|PATCH|NOTE|REQUEST", ...}], ...}', 'Do not wrap JSON in markdown code fences.', 'Worker input payload:', JSON.stringify(payload));
|
|
29
31
|
return lines.join('\n');
|
|
30
32
|
}
|
|
33
|
+
function buildInteractiveWorkerPrompt(payload, systemPrompt) {
|
|
34
|
+
const lines = [];
|
|
35
|
+
if (systemPrompt) {
|
|
36
|
+
lines.push(systemPrompt);
|
|
37
|
+
lines.push('---');
|
|
38
|
+
}
|
|
39
|
+
const featureId = typeof payload['feature_id'] === 'string' ? payload['feature_id'] : '';
|
|
40
|
+
const repoRoot = typeof payload['repo_root'] === 'string' ? payload['repo_root'] : null;
|
|
41
|
+
const role = typeof payload['role'] === 'string' ? payload['role'] : '';
|
|
42
|
+
const workingDir = typeof payload['working_directory'] === 'string' ? payload['working_directory'] : null;
|
|
43
|
+
const instructions = typeof payload['instructions'] === 'string' ? payload['instructions'].trim() : '';
|
|
44
|
+
const lastToolResults = Array.isArray(payload['last_tool_results'])
|
|
45
|
+
? payload['last_tool_results']
|
|
46
|
+
: [];
|
|
47
|
+
const projectedContext = projectInteractiveContext(payload['context_bundle']);
|
|
48
|
+
const stateStatus = typeof projectedContext?.state === 'object' &&
|
|
49
|
+
projectedContext.state &&
|
|
50
|
+
typeof projectedContext.state.status === 'string'
|
|
51
|
+
? projectedContext.state.status
|
|
52
|
+
: null;
|
|
53
|
+
const plannerPhase = typeof payload['planner_phase'] === 'string'
|
|
54
|
+
? payload['planner_phase']
|
|
55
|
+
: stateStatus === 'intake'
|
|
56
|
+
? 'intake'
|
|
57
|
+
: 'planning';
|
|
58
|
+
lines.push(`You are the ${role} agent running in interactive mode.`);
|
|
59
|
+
lines.push(`Feature: ${featureId}`);
|
|
60
|
+
if (workingDir) {
|
|
61
|
+
lines.push(`Working directory (edit files here): ${workingDir}`);
|
|
62
|
+
}
|
|
63
|
+
if (repoRoot) {
|
|
64
|
+
const featureDir = `${repoRoot}/.aop/features/${featureId}`;
|
|
65
|
+
if (role === 'planner') {
|
|
66
|
+
if (plannerPhase === 'intake') {
|
|
67
|
+
lines.push('', 'Intake artifacts are on disk — use these files as the requirements workspace:', ` ${featureDir}/spec.md — feature specification`, ` ${featureDir}/spec.manifest.bootstrap.json — bootstrap requirements proposal`, ` ${featureDir}/spec.manifest.verified.json — current verified requirements contract`, ` ${featureDir}/intake.review.json — intake review and ambiguity status`, ` ${featureDir}/questions.json — persisted intake clarification questions and answers`, ` ${featureDir}/state.md — current status and front matter`, ` ${featureDir}/decisions.md — decision history`);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
lines.push('', 'Planning artifacts are on disk — use these files as the execution-planning baseline:', ` ${featureDir}/spec.md — feature specification`, ` ${featureDir}/spec.manifest.verified.json — verified requirements contract`, ` ${featureDir}/state.md — current status and front matter`, ` ${featureDir}/plan.md — canonical step-by-step planning artifact`, ` ${featureDir}/plan.json — schema-valid planning definition`, ` ${featureDir}/qa_test_index.json — QA coverage and pending items`, ` ${featureDir}/evidence/ — gate run results`, ` ${featureDir}/decisions.md — decision history`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (role === 'builder') {
|
|
74
|
+
if (workingDir) {
|
|
75
|
+
const contextDir = `${workingDir}/.aop/context`;
|
|
76
|
+
lines.push('', 'Staged artifacts (read these first for context):', ` ${contextDir}/spec.md — original feature specification`, ` ${contextDir}/plan.md — human-readable implementation plan`, ` ${contextDir}/plan.json — structured plan with tasks and acceptance criteria`, ` ${contextDir}/qa_test_index.json — test expectations (if available)`);
|
|
77
|
+
}
|
|
78
|
+
lines.push('', 'Runtime artifacts:', ` ${featureDir}/state.md — current status and front matter`, ` ${featureDir}/evidence/ — gate run results`, ` ${featureDir}/decisions.md — decision history`);
|
|
79
|
+
}
|
|
80
|
+
else if (role === 'qa') {
|
|
81
|
+
lines.push('', 'QA artifacts are on disk — use these files as the verification baseline:', ` ${featureDir}/state.md — current status and front matter`, ` ${featureDir}/plan.md — accepted planning baseline`, ` ${featureDir}/plan.json — machine-readable plan`, ` ${featureDir}/qa_test_index.json — QA coverage and pending items`, ` ${featureDir}/evidence/ — latest gate evidence`, ` ${featureDir}/decisions.md — decision history`);
|
|
82
|
+
}
|
|
83
|
+
else if (role === 'reconciler') {
|
|
84
|
+
lines.push('', 'Reconciliation artifacts are on disk — use these files as the merge-resolution baseline:', ` ${featureDir}/state.md — conflict status and front matter`, ` ${featureDir}/spec.md — feature intent`, ` ${featureDir}/plan.md — accepted planning baseline`, ` ${featureDir}/plan.json — machine-readable plan`, ` ${featureDir}/decisions.md — decision history`, ` ${featureDir}/evidence/ — latest gate evidence`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (instructions.length > 0) {
|
|
88
|
+
lines.push('', 'Instructions:', instructions);
|
|
89
|
+
}
|
|
90
|
+
if (projectedContext) {
|
|
91
|
+
lines.push('', 'Execution context summary:', JSON.stringify(projectedContext, null, 2));
|
|
92
|
+
}
|
|
93
|
+
if (lastToolResults.length > 0) {
|
|
94
|
+
lines.push('', 'Recent tool results:', JSON.stringify(lastToolResults));
|
|
95
|
+
}
|
|
96
|
+
if (role === 'planner') {
|
|
97
|
+
const featureDir = repoRoot ? `${repoRoot}/.aop/features/${featureId}` : null;
|
|
98
|
+
if (plannerPhase === 'intake') {
|
|
99
|
+
lines.push('', 'Update the intake artifacts directly in the working directory.', 'Return exactly one JSON object and nothing else:', '{"type":"INTAKE_SUBMISSION","intake_submission":{"verified_manifest":{...},"open_ambiguities":[...],"resolved_ambiguities":[...],"requires_user_input":false}}', 'or {"type":"REQUEST","request":{"action":"ask_user_input","question_type":"clarification","prompt":"<blocking intake question>","details":{"ambiguity_id":"AMB-001","obligation_ids":["OBL-001"]},"expected_answer":{"kind":"free_text"},"blocking":true}}', 'or {"type":"NOTE","content":"<why intake remains unchanged and what intake state was observed>"}', 'Do not emit PLAN_SUBMISSION while operating in the intake planner phase.', 'If you emit REQUEST.action=ask_user_input, stop there for the turn. Do not also emit INTAKE_SUBMISSION or resolve the ambiguity yourself.', 'Do not claim verification_basis=human_review_confirmed unless the context already contains an answered manifest-review confirmation question.', 'Do not wrap JSON in markdown code fences.');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
lines.push('', 'Update the planning artifacts directly in the working directory.', featureDir
|
|
103
|
+
? `Keep ${featureDir}/plan.md aligned with the planning state and any plan_json you return.`
|
|
104
|
+
: 'Keep plan.md aligned with the planning state and any plan_json you return.', 'Return exactly one JSON object and nothing else:', '{"type":"PLAN_SUBMISSION","plan_json":{...}}', 'or {"type":"REQUEST","request":{"action":"amend_plan","plan_json":{...},"expected_plan_version":<n>}}', 'or {"type":"NOTE","content":"<why the accepted plan remains unchanged and what state was observed>"}', 'Do not emit INTAKE_SUBMISSION while operating in the execution-planning phase.', 'Do not wrap JSON in markdown code fences.');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (role === 'builder') {
|
|
108
|
+
lines.push('', 'Edit files directly in the working directory. Do not emit PATCH/unified diff output.', 'Use the accepted plan as your execution contract and keep changes inside planned paths.', 'Return NOTE only after making planned file changes.', 'Return REQUEST.action=more_context when the safe fix surface exceeds the accepted plan or the context is stale.', 'Return REQUEST.action=ask_user_input only for genuine human decisions, approvals, or policy exceptions you cannot resolve from the plan and repo.', 'After completing your edits, return exactly one JSON object:', '{"type":"NOTE","content":"<summary of completed edits, tests updated, and remaining risks>"}', 'or {"type":"REQUEST","request":{"action":"more_context"}}', 'or {"type":"REQUEST","request":{"action":"ask_user_input","question_type":"clarification","prompt":"<question>","details":{},"expected_answer":{"kind":"free_text"},"blocking":true}}', 'Do not wrap JSON in markdown code fences.');
|
|
109
|
+
}
|
|
110
|
+
else if (role === 'qa') {
|
|
111
|
+
lines.push('', 'Edit files directly in the working directory. Do not emit PATCH/unified diff output.', 'Use plan.json, qa_test_index.json, and the latest evidence as your verification contract.', 'Return NOTE only after making file changes that address a reproduced failure or verification gap.', 'Return REQUEST.action=more_context when evidence is stale or the accepted plan does not authorize the safe fix surface.', 'Return REQUEST.action=ask_user_input only for genuine operator decisions, approvals, or risk acknowledgements.', 'After completing your edits, return exactly one JSON object:', '{"type":"NOTE","content":"<summary of reproduced failures, fixes applied, tests run, and remaining risks>"}', 'or {"type":"REQUEST","request":{"action":"more_context"}}', 'or {"type":"REQUEST","request":{"action":"ask_user_input","question_type":"risk_ack","prompt":"<question>","details":{},"expected_answer":{"kind":"free_text"},"blocking":true}}', 'Do not wrap JSON in markdown code fences.');
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
lines.push('', 'Edit files directly in the conflicted worktree. Do not emit PATCH/unified diff output.', 'Use spec.md, state.md, plan.json, and approved collision context as your reconciliation contract.', 'Return NOTE only after resolving conflicted files and performing proportionate verification.', 'Return REQUEST.action=more_context when the conflict snapshot or surrounding repo state is stale.', 'Return REQUEST.action=ask_user_input only when preserving mainline semantics and feature intent requires an operator choice.', 'After completing your edits, return exactly one JSON object:', '{"type":"NOTE","content":"<summary of conflicts resolved, verification run, plan impacts, and residual risks>"}', 'or {"type":"REQUEST","request":{"action":"more_context"}}', 'or {"type":"REQUEST","request":{"action":"ask_user_input","question_type":"clarification","prompt":"<question>","details":{},"expected_answer":{"kind":"free_text"},"blocking":true}}', 'Do not wrap JSON in markdown code fences.');
|
|
115
|
+
}
|
|
116
|
+
return lines.join('\n');
|
|
117
|
+
}
|
|
118
|
+
function buildWorkerPrompt(payload, systemPrompt, executionMode) {
|
|
119
|
+
if (executionMode === 'interactive') {
|
|
120
|
+
return buildInteractiveWorkerPrompt(payload, systemPrompt);
|
|
121
|
+
}
|
|
122
|
+
return buildDeterministicWorkerPrompt(payload, systemPrompt);
|
|
123
|
+
}
|
|
124
|
+
export async function resolvePromptOverlay(overlayDir, role, provider) {
|
|
125
|
+
const filename = `${role}.${provider}.md`;
|
|
126
|
+
const overlayPath = path.join(overlayDir, filename);
|
|
127
|
+
try {
|
|
128
|
+
const content = await fs.readFile(overlayPath, 'utf8');
|
|
129
|
+
return content.trim().length > 0 ? content : null;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
31
135
|
function isRecord(value) {
|
|
32
136
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
33
137
|
}
|
|
@@ -45,6 +149,96 @@ function asNonEmptyString(value) {
|
|
|
45
149
|
const trimmed = value.trim();
|
|
46
150
|
return trimmed.length > 0 ? trimmed : null;
|
|
47
151
|
}
|
|
152
|
+
function projectInteractiveContext(contextBundle) {
|
|
153
|
+
if (!isRecord(contextBundle)) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
const projected = {};
|
|
157
|
+
const state = isRecord(contextBundle['state']) ? contextBundle['state'] : null;
|
|
158
|
+
const frontMatter = isRecord(state?.['front_matter']) ? state['front_matter'] : null;
|
|
159
|
+
if (frontMatter) {
|
|
160
|
+
projected['state'] = {
|
|
161
|
+
status: frontMatter['status'] ?? null,
|
|
162
|
+
status_reason: frontMatter['status_reason'] ?? null,
|
|
163
|
+
gate_profile: frontMatter['gate_profile'] ?? null,
|
|
164
|
+
gates: isRecord(frontMatter['gates']) ? frontMatter['gates'] : null,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const plan = isRecord(contextBundle['plan']) ? contextBundle['plan'] : null;
|
|
168
|
+
if (plan) {
|
|
169
|
+
projected['accepted_plan'] = {
|
|
170
|
+
summary: plan['summary'] ?? null,
|
|
171
|
+
allowed_areas: Array.isArray(plan['allowed_areas']) ? plan['allowed_areas'] : [],
|
|
172
|
+
forbidden_areas: Array.isArray(plan['forbidden_areas']) ? plan['forbidden_areas'] : [],
|
|
173
|
+
files: isRecord(plan['files']) ? plan['files'] : null,
|
|
174
|
+
acceptance_criteria: Array.isArray(plan['acceptance_criteria'])
|
|
175
|
+
? plan['acceptance_criteria']
|
|
176
|
+
: [],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const latestEvidence = isRecord(contextBundle['latest_evidence'])
|
|
180
|
+
? contextBundle['latest_evidence']
|
|
181
|
+
: null;
|
|
182
|
+
if (latestEvidence) {
|
|
183
|
+
projected['latest_evidence'] = {
|
|
184
|
+
overall: latestEvidence['overall'] ?? null,
|
|
185
|
+
mode: latestEvidence['mode'] ?? null,
|
|
186
|
+
status_reason: latestEvidence['status_reason'] ?? null,
|
|
187
|
+
failed_steps: Array.isArray(latestEvidence['failed_steps'])
|
|
188
|
+
? latestEvidence['failed_steps']
|
|
189
|
+
: [],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const qaIndex = isRecord(contextBundle['qa_test_index']) ? contextBundle['qa_test_index'] : null;
|
|
193
|
+
if (qaIndex) {
|
|
194
|
+
projected['qa_test_index'] = qaIndex;
|
|
195
|
+
}
|
|
196
|
+
const intake = isRecord(contextBundle['intake']) ? contextBundle['intake'] : null;
|
|
197
|
+
if (intake) {
|
|
198
|
+
const review = isRecord(intake['review']) ? intake['review'] : null;
|
|
199
|
+
const openAmbiguities = Array.isArray(review?.['ambiguities'])
|
|
200
|
+
? review?.['ambiguities']
|
|
201
|
+
.map((item) => (isRecord(item) ? item : null))
|
|
202
|
+
.filter((item) => item !== null && asNonEmptyString(item['status']) === 'open')
|
|
203
|
+
.map((item) => ({
|
|
204
|
+
id: item['id'] ?? null,
|
|
205
|
+
summary: item['summary'] ?? null,
|
|
206
|
+
obligation_ids: Array.isArray(item['obligation_ids']) ? item['obligation_ids'] : [],
|
|
207
|
+
}))
|
|
208
|
+
: [];
|
|
209
|
+
const clarificationAnswers = Array.isArray(review?.['clarification_answers'])
|
|
210
|
+
? review?.['clarification_answers']
|
|
211
|
+
.map((item) => (isRecord(item) ? item : null))
|
|
212
|
+
.filter((item) => item !== null)
|
|
213
|
+
.map((item) => ({
|
|
214
|
+
question_id: item['question_id'] ?? null,
|
|
215
|
+
ambiguity_ids: Array.isArray(item['ambiguity_ids']) ? item['ambiguity_ids'] : [],
|
|
216
|
+
answer: item['answer'] ?? null,
|
|
217
|
+
answered_at: item['answered_at'] ?? null,
|
|
218
|
+
resolution_status: item['resolution_status'] ?? null,
|
|
219
|
+
}))
|
|
220
|
+
: [];
|
|
221
|
+
projected['intake'] = {
|
|
222
|
+
summary: isRecord(intake['summary']) ? intake['summary'] : null,
|
|
223
|
+
bootstrap_manifest_version: isRecord(intake['bootstrap_manifest'])
|
|
224
|
+
? (intake['bootstrap_manifest']['manifest_version'] ?? null)
|
|
225
|
+
: null,
|
|
226
|
+
verified_manifest_version: isRecord(intake['verified_manifest'])
|
|
227
|
+
? (intake['verified_manifest']['manifest_version'] ?? null)
|
|
228
|
+
: null,
|
|
229
|
+
review: review
|
|
230
|
+
? {
|
|
231
|
+
status: review['status'] ?? null,
|
|
232
|
+
questions_open: review['questions_open'] ?? null,
|
|
233
|
+
questions_resolved: review['questions_resolved'] ?? null,
|
|
234
|
+
open_ambiguities: openAmbiguities,
|
|
235
|
+
clarification_answers: clarificationAnswers,
|
|
236
|
+
}
|
|
237
|
+
: null,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return Object.keys(projected).length > 0 ? projected : null;
|
|
241
|
+
}
|
|
48
242
|
function templateFromConfig(config, kind, fallback) {
|
|
49
243
|
const nested = isRecord(config?.[kind]) ? config?.[kind] : null;
|
|
50
244
|
const nestedCommand = asNonEmptyString(nested?.command);
|
|
@@ -58,17 +252,28 @@ function templateFromConfig(config, kind, fallback) {
|
|
|
58
252
|
}
|
|
59
253
|
return { command, args };
|
|
60
254
|
}
|
|
61
|
-
function
|
|
255
|
+
function appendExtraArgs(template, extraArgs) {
|
|
256
|
+
if (!template || !extraArgs?.length) {
|
|
257
|
+
return template;
|
|
258
|
+
}
|
|
259
|
+
return { command: template.command, args: [...template.args, ...extraArgs] };
|
|
260
|
+
}
|
|
261
|
+
function resolveRunTemplate(selection, resumeSession) {
|
|
62
262
|
const topLevelCommand = asNonEmptyString(selection.agent_config?.command);
|
|
63
263
|
const topLevelArgs = readStringArray(selection.agent_config?.args);
|
|
64
264
|
const topLevelTemplate = topLevelCommand && topLevelArgs ? { command: topLevelCommand, args: topLevelArgs } : undefined;
|
|
65
|
-
|
|
265
|
+
const defaults = PROVIDER_CLI_DEFAULTS[selection.provider];
|
|
266
|
+
const kind = resumeSession ? 'run_resume' : 'run';
|
|
267
|
+
const template = templateFromConfig(selection.agent_config, kind, topLevelTemplate ?? (resumeSession ? defaults?.run_resume : undefined) ?? defaults?.run);
|
|
268
|
+
return appendExtraArgs(template, selection.cli_extra_args);
|
|
66
269
|
}
|
|
67
270
|
function resolveAttachTemplate(selection) {
|
|
68
|
-
|
|
271
|
+
const template = templateFromConfig(selection.agent_config, 'attach', PROVIDER_CLI_DEFAULTS[selection.provider]?.attach);
|
|
272
|
+
return appendExtraArgs(template, selection.cli_extra_args);
|
|
69
273
|
}
|
|
70
274
|
function resolveSendTemplate(selection) {
|
|
71
|
-
|
|
275
|
+
const template = templateFromConfig(selection.agent_config, 'send', PROVIDER_CLI_DEFAULTS[selection.provider]?.send);
|
|
276
|
+
return appendExtraArgs(template, selection.cli_extra_args);
|
|
72
277
|
}
|
|
73
278
|
function applyTemplateArgs(args, values) {
|
|
74
279
|
return args.map((arg) => {
|
|
@@ -87,6 +292,12 @@ function applyTemplateArgs(args, values) {
|
|
|
87
292
|
if (arg === '{message}') {
|
|
88
293
|
return values.message ?? '';
|
|
89
294
|
}
|
|
295
|
+
if (arg === '{output_last_message_path}') {
|
|
296
|
+
return values.outputLastMessagePath ?? '';
|
|
297
|
+
}
|
|
298
|
+
if (arg === '{model}') {
|
|
299
|
+
return values.model ?? '';
|
|
300
|
+
}
|
|
90
301
|
return arg;
|
|
91
302
|
});
|
|
92
303
|
}
|
|
@@ -101,6 +312,12 @@ function buildRunCommandEnv(selection) {
|
|
|
101
312
|
if (selection.provider_config_env && selection.provider_config_ref) {
|
|
102
313
|
env[selection.provider_config_env] = selection.provider_config_ref;
|
|
103
314
|
}
|
|
315
|
+
if (selection.provider === 'claude') {
|
|
316
|
+
// Claude Code refuses to spawn inside an active Claude Code session.
|
|
317
|
+
// Both CLAUDECODE and CLAUDE_CODE_ENTRYPOINT must be absent to bypass the nested-session guard.
|
|
318
|
+
delete env['CLAUDECODE'];
|
|
319
|
+
delete env['CLAUDE_CODE_ENTRYPOINT'];
|
|
320
|
+
}
|
|
104
321
|
return env;
|
|
105
322
|
}
|
|
106
323
|
function asPositiveInteger(value, fallback) {
|
|
@@ -121,6 +338,174 @@ function resolveCliWorkerCapabilities(selection) {
|
|
|
121
338
|
supportsSpawnDetection: true,
|
|
122
339
|
};
|
|
123
340
|
}
|
|
341
|
+
function isRawLogRole(role) {
|
|
342
|
+
return role === 'planner' || role === 'builder' || role === 'qa';
|
|
343
|
+
}
|
|
344
|
+
function sanitizeClaudeProjectKey(value) {
|
|
345
|
+
return value.replace(/[^A-Za-z0-9]/g, '-');
|
|
346
|
+
}
|
|
347
|
+
function resolveClaudeTranscriptPath(workingDirectory, sessionId) {
|
|
348
|
+
return path.join(os.homedir(), '.claude', 'projects', sanitizeClaudeProjectKey(workingDirectory), `${sessionId}.jsonl`);
|
|
349
|
+
}
|
|
350
|
+
function asNonEmptyStringOrNull(value) {
|
|
351
|
+
return typeof value === 'string' && value.trim().length > 0 ? value : null;
|
|
352
|
+
}
|
|
353
|
+
function collectClaudeTranscriptTextBlocks(value) {
|
|
354
|
+
if (!Array.isArray(value)) {
|
|
355
|
+
return [];
|
|
356
|
+
}
|
|
357
|
+
const blocks = [];
|
|
358
|
+
for (const entry of value) {
|
|
359
|
+
if (!isRecord(entry) || entry.type !== 'text') {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
const text = asNonEmptyStringOrNull(entry.text);
|
|
363
|
+
if (text) {
|
|
364
|
+
blocks.push(text);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return blocks;
|
|
368
|
+
}
|
|
369
|
+
function summarizeClaudeToolInput(input) {
|
|
370
|
+
const description = asNonEmptyStringOrNull(input.description);
|
|
371
|
+
if (description) {
|
|
372
|
+
return description;
|
|
373
|
+
}
|
|
374
|
+
const command = asNonEmptyStringOrNull(input.command);
|
|
375
|
+
if (command) {
|
|
376
|
+
return command;
|
|
377
|
+
}
|
|
378
|
+
const filePath = asNonEmptyStringOrNull(input.file_path);
|
|
379
|
+
if (filePath) {
|
|
380
|
+
return filePath;
|
|
381
|
+
}
|
|
382
|
+
const pattern = asNonEmptyStringOrNull(input.pattern);
|
|
383
|
+
const searchPath = asNonEmptyStringOrNull(input.path);
|
|
384
|
+
if (pattern && searchPath) {
|
|
385
|
+
return `${pattern} @ ${searchPath}`;
|
|
386
|
+
}
|
|
387
|
+
if (pattern) {
|
|
388
|
+
return pattern;
|
|
389
|
+
}
|
|
390
|
+
const specs = input.specs;
|
|
391
|
+
if (Array.isArray(specs)) {
|
|
392
|
+
const renderedSpecs = specs.filter((value) => typeof value === 'string');
|
|
393
|
+
if (renderedSpecs.length > 0) {
|
|
394
|
+
return renderedSpecs.join(', ');
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
function renderClaudeTranscriptEntry(record) {
|
|
400
|
+
const type = asNonEmptyStringOrNull(record.type);
|
|
401
|
+
if (!type) {
|
|
402
|
+
return [];
|
|
403
|
+
}
|
|
404
|
+
if (type === 'progress') {
|
|
405
|
+
const data = isRecord(record.data) ? record.data : null;
|
|
406
|
+
if (data?.type === 'hook_progress') {
|
|
407
|
+
const hookEvent = asNonEmptyStringOrNull(data.hookEvent);
|
|
408
|
+
const hookName = asNonEmptyStringOrNull(data.hookName);
|
|
409
|
+
const label = [hookEvent, hookName].filter(Boolean).join(' · ');
|
|
410
|
+
return label.length > 0 ? [`[progress] ${label}`] : [];
|
|
411
|
+
}
|
|
412
|
+
const progressType = asNonEmptyStringOrNull(data?.type);
|
|
413
|
+
return progressType ? [`[progress] ${progressType}`] : [];
|
|
414
|
+
}
|
|
415
|
+
const message = isRecord(record.message) ? record.message : null;
|
|
416
|
+
if (!message) {
|
|
417
|
+
return [];
|
|
418
|
+
}
|
|
419
|
+
if (type === 'assistant') {
|
|
420
|
+
const content = Array.isArray(message.content) ? message.content : [];
|
|
421
|
+
const rendered = [];
|
|
422
|
+
for (const entry of content) {
|
|
423
|
+
if (!isRecord(entry)) {
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
if (entry.type === 'text') {
|
|
427
|
+
const text = asNonEmptyStringOrNull(entry.text);
|
|
428
|
+
if (text) {
|
|
429
|
+
rendered.push(text);
|
|
430
|
+
}
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
if (entry.type === 'tool_use') {
|
|
434
|
+
const name = asNonEmptyStringOrNull(entry.name) ?? 'tool';
|
|
435
|
+
const input = isRecord(entry.input) ? entry.input : {};
|
|
436
|
+
const summary = summarizeClaudeToolInput(input);
|
|
437
|
+
rendered.push(summary ? `[tool] ${name}: ${summary}` : `[tool] ${name}`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return rendered;
|
|
441
|
+
}
|
|
442
|
+
if (type === 'user') {
|
|
443
|
+
const content = Array.isArray(message.content) ? message.content : [];
|
|
444
|
+
const rendered = [];
|
|
445
|
+
for (const entry of content) {
|
|
446
|
+
if (!isRecord(entry) || entry.type !== 'tool_result') {
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
const textBlocks = collectClaudeTranscriptTextBlocks(entry.content);
|
|
450
|
+
if (textBlocks.length > 0) {
|
|
451
|
+
rendered.push(...textBlocks);
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
const text = asNonEmptyStringOrNull(entry.content);
|
|
455
|
+
if (text) {
|
|
456
|
+
rendered.push(text);
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
if (isRecord(record.toolUseResult)) {
|
|
460
|
+
const stdout = asNonEmptyStringOrNull(record.toolUseResult.stdout);
|
|
461
|
+
const stderr = asNonEmptyStringOrNull(record.toolUseResult.stderr);
|
|
462
|
+
if (stdout) {
|
|
463
|
+
rendered.push(stdout);
|
|
464
|
+
}
|
|
465
|
+
if (stderr) {
|
|
466
|
+
rendered.push(stderr);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return rendered;
|
|
471
|
+
}
|
|
472
|
+
return [];
|
|
473
|
+
}
|
|
474
|
+
function renderClaudeTranscript(raw) {
|
|
475
|
+
const rendered = [];
|
|
476
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
477
|
+
const trimmed = line.trim();
|
|
478
|
+
if (trimmed.length === 0) {
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
try {
|
|
482
|
+
const parsed = JSON.parse(trimmed);
|
|
483
|
+
if (isRecord(parsed)) {
|
|
484
|
+
rendered.push(...renderClaudeTranscriptEntry(parsed));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
catch {
|
|
488
|
+
// Ignore malformed partial lines while the transcript is still being written.
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return rendered.join('\n\n');
|
|
492
|
+
}
|
|
493
|
+
export const cliWorkerProviderTestExports = {
|
|
494
|
+
buildInteractiveWorkerPrompt,
|
|
495
|
+
projectInteractiveContext,
|
|
496
|
+
resolveRunTemplate,
|
|
497
|
+
resolveAttachTemplate,
|
|
498
|
+
resolveSendTemplate,
|
|
499
|
+
applyTemplateArgs,
|
|
500
|
+
buildRunCommandEnv,
|
|
501
|
+
resolveCliWorkerCapabilities,
|
|
502
|
+
sanitizeClaudeProjectKey,
|
|
503
|
+
resolveClaudeTranscriptPath,
|
|
504
|
+
collectClaudeTranscriptTextBlocks,
|
|
505
|
+
summarizeClaudeToolInput,
|
|
506
|
+
renderClaudeTranscriptEntry,
|
|
507
|
+
renderClaudeTranscript,
|
|
508
|
+
};
|
|
124
509
|
export class CliWorkerProvider {
|
|
125
510
|
mode = 'live';
|
|
126
511
|
selection;
|
|
@@ -135,14 +520,57 @@ export class CliWorkerProvider {
|
|
|
135
520
|
workerWatchdogPollIntervalMs;
|
|
136
521
|
workerKillGracePeriodMs;
|
|
137
522
|
repoRoot;
|
|
523
|
+
overlayDir;
|
|
138
524
|
rawAgentLogsEnabled;
|
|
139
525
|
rawAgentLogsRetentionDays;
|
|
140
526
|
workerCapabilities;
|
|
141
|
-
runTemplate;
|
|
142
527
|
attachTemplate;
|
|
143
528
|
sendTemplate;
|
|
144
529
|
sessionsByRoleFeature = new Map();
|
|
145
530
|
systemPromptsBySession = new Map();
|
|
531
|
+
bootstrappedSessionIds = new Set();
|
|
532
|
+
overlayCache = new Map();
|
|
533
|
+
isMissingClaudeConversation(result) {
|
|
534
|
+
if (this.selection.provider !== 'claude') {
|
|
535
|
+
return false;
|
|
536
|
+
}
|
|
537
|
+
const stderr = typeof result.stderr === 'string' ? result.stderr : '';
|
|
538
|
+
const stdout = typeof result.stdout === 'string' ? result.stdout : '';
|
|
539
|
+
return (stderr.includes('No conversation found with session ID') ||
|
|
540
|
+
stdout.includes('No conversation found with session ID'));
|
|
541
|
+
}
|
|
542
|
+
buildBootstrapControlPrompt(sessionId, message) {
|
|
543
|
+
const systemPrompt = this.systemPromptsBySession.get(sessionId) ?? null;
|
|
544
|
+
return systemPrompt ? `${systemPrompt}\n---\n${message}` : message;
|
|
545
|
+
}
|
|
546
|
+
async bootstrapMissingClaudeControlSession(sessionId, message) {
|
|
547
|
+
if (this.selection.provider !== 'claude' || message.trim().length === 0) {
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
const runTemplate = resolveRunTemplate(this.selection, false);
|
|
551
|
+
if (!runTemplate) {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
const prompt = this.buildBootstrapControlPrompt(sessionId, message);
|
|
555
|
+
const args = applyTemplateArgs(runTemplate.args, {
|
|
556
|
+
sessionId,
|
|
557
|
+
prompt,
|
|
558
|
+
featureId: 'global',
|
|
559
|
+
role: 'reconciler',
|
|
560
|
+
message,
|
|
561
|
+
model: this.selection.model,
|
|
562
|
+
});
|
|
563
|
+
const result = await this.commandRunner.run(runTemplate.command, args, {
|
|
564
|
+
stdin: prompt,
|
|
565
|
+
timeoutMs: 15_000,
|
|
566
|
+
env: buildRunCommandEnv(this.selection),
|
|
567
|
+
});
|
|
568
|
+
if (result.exitCode !== 0) {
|
|
569
|
+
return false;
|
|
570
|
+
}
|
|
571
|
+
this.markSessionBootstrapped(this.selection.provider, sessionId);
|
|
572
|
+
return true;
|
|
573
|
+
}
|
|
146
574
|
constructor(selection, options) {
|
|
147
575
|
this.selection = selection;
|
|
148
576
|
this.outputParser = options.outputParser;
|
|
@@ -154,10 +582,10 @@ export class CliWorkerProvider {
|
|
|
154
582
|
this.workerKillGracePeriodMs = asPositiveInteger(options.workerKillGracePeriodMs, DEFAULT_KILL_GRACE_PERIOD_MS);
|
|
155
583
|
this.repoRoot =
|
|
156
584
|
typeof options.repoRoot === 'string' && options.repoRoot.length > 0 ? options.repoRoot : null;
|
|
585
|
+
this.overlayDir = options.overlayDir ?? null;
|
|
157
586
|
this.rawAgentLogsEnabled = options.rawAgentLogsEnabled === true;
|
|
158
587
|
this.rawAgentLogsRetentionDays = asPositiveInteger(options.rawAgentLogsRetentionDays, DEFAULT_RAW_LOG_RETENTION_DAYS);
|
|
159
588
|
this.workerCapabilities = resolveCliWorkerCapabilities(selection);
|
|
160
|
-
this.runTemplate = resolveRunTemplate(selection);
|
|
161
589
|
this.attachTemplate = resolveAttachTemplate(selection);
|
|
162
590
|
this.sendTemplate = resolveSendTemplate(selection);
|
|
163
591
|
if (this.attachTemplate) {
|
|
@@ -176,7 +604,7 @@ export class CliWorkerProvider {
|
|
|
176
604
|
}
|
|
177
605
|
}
|
|
178
606
|
createSession(role, featureId, systemPrompt) {
|
|
179
|
-
const sessionId =
|
|
607
|
+
const sessionId = crypto.randomUUID();
|
|
180
608
|
this.sessionsByRoleFeature.set(this.sessionKey(role, featureId), sessionId);
|
|
181
609
|
this.systemPromptsBySession.set(sessionId, systemPrompt);
|
|
182
610
|
return Promise.resolve({
|
|
@@ -203,34 +631,75 @@ export class CliWorkerProvider {
|
|
|
203
631
|
this.sessionsByRoleFeature.delete(key);
|
|
204
632
|
}
|
|
205
633
|
}
|
|
634
|
+
this.bootstrappedSessionIds.delete(sessionId);
|
|
206
635
|
this.systemPromptsBySession.delete(sessionId);
|
|
207
636
|
return Promise.resolve({ closed: true });
|
|
208
637
|
}
|
|
209
638
|
async runWorker(input) {
|
|
210
|
-
|
|
639
|
+
const effectiveSelection = this.resolveEffectiveSelection(input.runtime_selection ?? null);
|
|
640
|
+
const sessionId = this.resolveOrCreateSessionId(input.role, input.feature_id);
|
|
641
|
+
const workingDirectory = input.working_directory ?? this.repoRoot ?? process.cwd();
|
|
642
|
+
const resumeSession = await this.shouldResumeSession(effectiveSelection.provider, sessionId, workingDirectory);
|
|
643
|
+
const runTemplate = resolveRunTemplate(effectiveSelection, resumeSession);
|
|
644
|
+
if (!runTemplate) {
|
|
211
645
|
throw providerError(ERROR_CODES.PROVIDER_RUNTIME_UNAVAILABLE, 'Live worker provider is missing run command configuration', {
|
|
212
|
-
provider:
|
|
646
|
+
provider: effectiveSelection.provider,
|
|
213
647
|
reason: 'missing_run_command_template',
|
|
648
|
+
resume_session: resumeSession,
|
|
214
649
|
});
|
|
215
650
|
}
|
|
216
|
-
const
|
|
217
|
-
`${input.role}-${input.feature_id}-unassigned`;
|
|
651
|
+
const executionMode = input.execution_mode ?? 'deterministic';
|
|
218
652
|
const promptPayload = {
|
|
219
653
|
role: input.role,
|
|
220
654
|
feature_id: input.feature_id,
|
|
221
|
-
|
|
655
|
+
...(typeof input.planner_phase === 'string' ? { planner_phase: input.planner_phase } : {}),
|
|
656
|
+
...(executionMode === 'interactive'
|
|
657
|
+
? {
|
|
658
|
+
repo_root: this.repoRoot ?? null,
|
|
659
|
+
context_bundle: input.context_bundle ?? {},
|
|
660
|
+
}
|
|
661
|
+
: { context_bundle: input.context_bundle ?? {} }),
|
|
222
662
|
instructions: input.instructions ?? '',
|
|
223
663
|
last_tool_results: input.last_tool_results ?? [],
|
|
224
664
|
runtime_selection: input.runtime_selection ?? null,
|
|
225
665
|
session_id: sessionId,
|
|
666
|
+
execution_mode: executionMode,
|
|
667
|
+
working_directory: input.working_directory ?? null,
|
|
226
668
|
};
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
669
|
+
const baseSystemPrompt = this.systemPromptsBySession.get(sessionId) ?? null;
|
|
670
|
+
let systemPrompt = baseSystemPrompt;
|
|
671
|
+
if (baseSystemPrompt && this.overlayDir) {
|
|
672
|
+
const cacheKey = `${input.role}.${effectiveSelection.provider}`;
|
|
673
|
+
let overlay;
|
|
674
|
+
if (this.overlayCache.has(cacheKey)) {
|
|
675
|
+
overlay = this.overlayCache.get(cacheKey) ?? null;
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
overlay = await resolvePromptOverlay(this.overlayDir, input.role, effectiveSelection.provider);
|
|
679
|
+
this.overlayCache.set(cacheKey, overlay);
|
|
680
|
+
}
|
|
681
|
+
if (overlay) {
|
|
682
|
+
systemPrompt = `${baseSystemPrompt}\n\n---\n\n## Provider-Specific Instructions\n\n${overlay}`;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
const prompt = buildWorkerPrompt(promptPayload, systemPrompt, executionMode);
|
|
686
|
+
const outputCapture = await this.createOutputCapture(runTemplate.args);
|
|
687
|
+
const args = applyTemplateArgs(runTemplate.args, {
|
|
230
688
|
sessionId,
|
|
231
689
|
prompt,
|
|
232
690
|
featureId: input.feature_id,
|
|
233
691
|
role: input.role,
|
|
692
|
+
model: effectiveSelection.model,
|
|
693
|
+
outputLastMessagePath: outputCapture.lastMessagePath ?? undefined,
|
|
694
|
+
});
|
|
695
|
+
const liveAgentConsole = await this.createLiveAgentConsoleCapture({
|
|
696
|
+
featureId: input.feature_id,
|
|
697
|
+
role: input.role,
|
|
698
|
+
sessionId,
|
|
699
|
+
provider: effectiveSelection.provider,
|
|
700
|
+
model: effectiveSelection.model,
|
|
701
|
+
executionMode,
|
|
702
|
+
workingDirectory,
|
|
234
703
|
});
|
|
235
704
|
const effectiveTimeoutMs = this.resolveRunTimeoutMs();
|
|
236
705
|
const runnerBackstopTimeoutMs = this.resolveRunnerBackstopTimeoutMs(effectiveTimeoutMs);
|
|
@@ -256,40 +725,63 @@ export class CliWorkerProvider {
|
|
|
256
725
|
watchdog.recordActivity(event.type);
|
|
257
726
|
};
|
|
258
727
|
watchdog.start();
|
|
259
|
-
let runResult;
|
|
260
728
|
try {
|
|
261
|
-
runResult
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
729
|
+
let runResult;
|
|
730
|
+
try {
|
|
731
|
+
runResult = await this.commandRunner.run(runTemplate.command, args, {
|
|
732
|
+
stdin: prompt,
|
|
733
|
+
cwd: input.working_directory,
|
|
734
|
+
timeoutMs: runnerBackstopTimeoutMs,
|
|
735
|
+
env: buildRunCommandEnv(effectiveSelection),
|
|
736
|
+
onLifecycleEvent: (event) => {
|
|
737
|
+
workerHandle.onLifecycleEvent?.(event);
|
|
738
|
+
},
|
|
739
|
+
registerKill: (kill) => {
|
|
740
|
+
killRunner = kill;
|
|
741
|
+
},
|
|
742
|
+
onOutputChunk: (chunk) => {
|
|
743
|
+
liveAgentConsole?.appendChunk(chunk.text);
|
|
744
|
+
},
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
catch (error) {
|
|
748
|
+
watchdog.stop({
|
|
749
|
+
signal: null,
|
|
750
|
+
});
|
|
751
|
+
await liveAgentConsole?.finalize('failed');
|
|
752
|
+
throw error;
|
|
753
|
+
}
|
|
754
|
+
const watchdogOutcome = watchdog.stop({
|
|
755
|
+
signal: runResult.signal,
|
|
756
|
+
timedOut: runResult.timedOut ?? false,
|
|
757
|
+
});
|
|
758
|
+
if (runResult.exitCode !== 0) {
|
|
759
|
+
this.refreshSessionForRoleFeature(input.role, input.feature_id);
|
|
760
|
+
}
|
|
761
|
+
this.ensureRunSucceeded(runResult, runTemplate.command, args, effectiveTimeoutMs, watchdogOutcome);
|
|
762
|
+
this.markSessionBootstrapped(effectiveSelection.provider, sessionId);
|
|
763
|
+
const preferredOutput = await this.resolvePreferredWorkerOutput(runResult.stdout ?? '', outputCapture.lastMessagePath);
|
|
764
|
+
await liveAgentConsole?.finalize('completed', preferredOutput);
|
|
765
|
+
await this.persistRawAgentOutput(input.feature_id, input.role, preferredOutput);
|
|
766
|
+
const parsed = this.outputParser.parse(preferredOutput, {
|
|
767
|
+
sessionId,
|
|
768
|
+
role: input.role,
|
|
769
|
+
featureId: input.feature_id,
|
|
770
|
+
provider: this.selection.provider,
|
|
771
|
+
model: this.selection.model,
|
|
772
|
+
executionMode: input.execution_mode,
|
|
272
773
|
});
|
|
774
|
+
// CLI providers do not expose token usage; return unavailable status.
|
|
775
|
+
parsed.usage = unavailableUsage(effectiveSelection.provider, effectiveSelection.model, input.role);
|
|
776
|
+
return parsed;
|
|
273
777
|
}
|
|
274
778
|
catch (error) {
|
|
275
|
-
|
|
276
|
-
signal: null,
|
|
277
|
-
});
|
|
779
|
+
await liveAgentConsole?.finalize('failed');
|
|
278
780
|
throw error;
|
|
279
781
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
});
|
|
284
|
-
this.ensureRunSucceeded(runResult, this.runTemplate.command, args, effectiveTimeoutMs, watchdogOutcome);
|
|
285
|
-
await this.persistRawAgentOutput(input.feature_id, input.role, runResult.stdout ?? '');
|
|
286
|
-
return this.outputParser.parse(runResult.stdout ?? '', {
|
|
287
|
-
sessionId,
|
|
288
|
-
role: input.role,
|
|
289
|
-
featureId: input.feature_id,
|
|
290
|
-
provider: this.selection.provider,
|
|
291
|
-
model: this.selection.model,
|
|
292
|
-
});
|
|
782
|
+
finally {
|
|
783
|
+
await this.cleanupOutputCapture(outputCapture.captureDir);
|
|
784
|
+
}
|
|
293
785
|
}
|
|
294
786
|
getCapabilities() {
|
|
295
787
|
return CLI_PROVIDER_CAPABILITIES;
|
|
@@ -297,6 +789,72 @@ export class CliWorkerProvider {
|
|
|
297
789
|
sessionKey(role, featureId) {
|
|
298
790
|
return `${role}::${featureId}`;
|
|
299
791
|
}
|
|
792
|
+
resolveOrCreateSessionId(role, featureId) {
|
|
793
|
+
const key = this.sessionKey(role, featureId);
|
|
794
|
+
const existingSessionId = this.sessionsByRoleFeature.get(key);
|
|
795
|
+
if (existingSessionId) {
|
|
796
|
+
return existingSessionId;
|
|
797
|
+
}
|
|
798
|
+
const sessionId = crypto.randomUUID();
|
|
799
|
+
this.sessionsByRoleFeature.set(key, sessionId);
|
|
800
|
+
this.systemPromptsBySession.set(sessionId, null);
|
|
801
|
+
return sessionId;
|
|
802
|
+
}
|
|
803
|
+
refreshSessionForRoleFeature(role, featureId) {
|
|
804
|
+
const key = this.sessionKey(role, featureId);
|
|
805
|
+
const oldSessionId = this.sessionsByRoleFeature.get(key);
|
|
806
|
+
if (!oldSessionId) {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
const systemPrompt = this.systemPromptsBySession.get(oldSessionId) ?? null;
|
|
810
|
+
const newSessionId = crypto.randomUUID();
|
|
811
|
+
this.sessionsByRoleFeature.set(key, newSessionId);
|
|
812
|
+
this.bootstrappedSessionIds.delete(oldSessionId);
|
|
813
|
+
this.systemPromptsBySession.delete(oldSessionId);
|
|
814
|
+
this.systemPromptsBySession.set(newSessionId, systemPrompt);
|
|
815
|
+
}
|
|
816
|
+
async shouldResumeSession(provider, sessionId, workingDirectory) {
|
|
817
|
+
if (provider !== 'claude') {
|
|
818
|
+
return false;
|
|
819
|
+
}
|
|
820
|
+
if (this.bootstrappedSessionIds.has(sessionId)) {
|
|
821
|
+
return true;
|
|
822
|
+
}
|
|
823
|
+
try {
|
|
824
|
+
await fs.access(resolveClaudeTranscriptPath(workingDirectory, sessionId));
|
|
825
|
+
this.bootstrappedSessionIds.add(sessionId);
|
|
826
|
+
return true;
|
|
827
|
+
}
|
|
828
|
+
catch {
|
|
829
|
+
return false;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
markSessionBootstrapped(provider, sessionId) {
|
|
833
|
+
if (provider === 'claude') {
|
|
834
|
+
this.bootstrappedSessionIds.add(sessionId);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
resolveEffectiveSelection(runtimeSelection) {
|
|
838
|
+
if (!runtimeSelection) {
|
|
839
|
+
return this.selection;
|
|
840
|
+
}
|
|
841
|
+
if (runtimeSelection.provider !== this.selection.provider) {
|
|
842
|
+
throw providerError(ERROR_CODES.INVALID_ARGUMENT, 'Runtime selection provider override is not supported for this worker provider', {
|
|
843
|
+
provider: this.selection.provider,
|
|
844
|
+
runtime_provider: runtimeSelection.provider,
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
return {
|
|
848
|
+
...this.selection,
|
|
849
|
+
provider: runtimeSelection.provider,
|
|
850
|
+
model: runtimeSelection.model,
|
|
851
|
+
provider_config_env: runtimeSelection.provider_config_env ?? null,
|
|
852
|
+
provider_config_ref: runtimeSelection.provider_config_ref,
|
|
853
|
+
agent_config: isRecord(runtimeSelection.agent_config)
|
|
854
|
+
? runtimeSelection.agent_config
|
|
855
|
+
: this.selection.agent_config,
|
|
856
|
+
};
|
|
857
|
+
}
|
|
300
858
|
ensureRunSucceeded(result, command, args, timeoutMs, watchdogOutcome) {
|
|
301
859
|
if (result.exitCode === 0) {
|
|
302
860
|
return;
|
|
@@ -317,6 +875,7 @@ export class CliWorkerProvider {
|
|
|
317
875
|
idle_for_ms: watchdogOutcome.idleForMs,
|
|
318
876
|
elapsed_ms: watchdogOutcome.elapsedMs,
|
|
319
877
|
stderr: result.stderr,
|
|
878
|
+
stdout: result.stdout ? result.stdout.slice(0, 500) : undefined,
|
|
320
879
|
});
|
|
321
880
|
}
|
|
322
881
|
classifyRunFailureErrorCode(result, watchdogOutcome) {
|
|
@@ -359,6 +918,7 @@ export class CliWorkerProvider {
|
|
|
359
918
|
featureId: 'global',
|
|
360
919
|
role: 'orchestrator',
|
|
361
920
|
message,
|
|
921
|
+
model: this.selection.model,
|
|
362
922
|
});
|
|
363
923
|
const result = await this.commandRunner.run(template.command, args, {
|
|
364
924
|
interactive: kind === 'attach',
|
|
@@ -368,6 +928,12 @@ export class CliWorkerProvider {
|
|
|
368
928
|
if (result.exitCode === 0) {
|
|
369
929
|
return;
|
|
370
930
|
}
|
|
931
|
+
if (kind === 'send' &&
|
|
932
|
+
typeof message === 'string' &&
|
|
933
|
+
this.isMissingClaudeConversation(result) &&
|
|
934
|
+
(await this.bootstrapMissingClaudeControlSession(sessionId, message))) {
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
371
937
|
throw providerError(result.exitCode === 127 || result.errorCode === 'ENOENT'
|
|
372
938
|
? ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER
|
|
373
939
|
: ERROR_CODES.INTERNAL_ERROR, `Provider ${kind} command failed`, {
|
|
@@ -378,8 +944,124 @@ export class CliWorkerProvider {
|
|
|
378
944
|
exit_code: result.exitCode,
|
|
379
945
|
signal: result.signal,
|
|
380
946
|
error_code: result.errorCode,
|
|
947
|
+
timed_out: result.timedOut ?? false,
|
|
948
|
+
stdout: result.stdout,
|
|
949
|
+
stderr: result.stderr,
|
|
381
950
|
});
|
|
382
951
|
}
|
|
952
|
+
async createLiveAgentConsoleCapture(input) {
|
|
953
|
+
if (!this.rawAgentLogsEnabled || !this.repoRoot || !isRawLogRole(input.role)) {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
const liveDir = path.join(this.repoRoot, '.aop', 'features', input.featureId, 'logs', 'live');
|
|
957
|
+
const contentPath = path.join(liveDir, `${input.role}.txt`);
|
|
958
|
+
const metadataPath = path.join(liveDir, `${input.role}.json`);
|
|
959
|
+
const startedAt = new Date().toISOString();
|
|
960
|
+
let writeChain = Promise.resolve();
|
|
961
|
+
let hasLiveContent = false;
|
|
962
|
+
let finalized = false;
|
|
963
|
+
let transcriptInterval = null;
|
|
964
|
+
let lastTranscriptMtimeMs = -1;
|
|
965
|
+
let lastRenderedTranscript = '';
|
|
966
|
+
const transcriptPath = input.provider === 'claude'
|
|
967
|
+
? resolveClaudeTranscriptPath(input.workingDirectory, input.sessionId)
|
|
968
|
+
: null;
|
|
969
|
+
const enqueue = (task) => {
|
|
970
|
+
writeChain = writeChain.then(task).catch(() => undefined);
|
|
971
|
+
};
|
|
972
|
+
const syncClaudeTranscript = () => {
|
|
973
|
+
if (!transcriptPath || finalized) {
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
976
|
+
enqueue(async () => {
|
|
977
|
+
try {
|
|
978
|
+
const stats = await fs.stat(transcriptPath);
|
|
979
|
+
if (stats.mtimeMs <= lastTranscriptMtimeMs) {
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
const raw = await fs.readFile(transcriptPath, 'utf8');
|
|
983
|
+
const rendered = renderClaudeTranscript(raw);
|
|
984
|
+
lastTranscriptMtimeMs = stats.mtimeMs;
|
|
985
|
+
if (rendered === lastRenderedTranscript) {
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
lastRenderedTranscript = rendered;
|
|
989
|
+
hasLiveContent = rendered.trim().length > 0;
|
|
990
|
+
await fs.writeFile(contentPath, rendered, 'utf8');
|
|
991
|
+
}
|
|
992
|
+
catch {
|
|
993
|
+
// Claude transcript mirroring is best-effort.
|
|
994
|
+
}
|
|
995
|
+
});
|
|
996
|
+
};
|
|
997
|
+
try {
|
|
998
|
+
await fs.mkdir(liveDir, { recursive: true });
|
|
999
|
+
await fs.writeFile(contentPath, '', 'utf8');
|
|
1000
|
+
await fs.writeFile(metadataPath, JSON.stringify({
|
|
1001
|
+
feature_id: input.featureId,
|
|
1002
|
+
role: input.role,
|
|
1003
|
+
session_id: input.sessionId,
|
|
1004
|
+
provider: input.provider,
|
|
1005
|
+
model: input.model,
|
|
1006
|
+
execution_mode: input.executionMode,
|
|
1007
|
+
status: 'running',
|
|
1008
|
+
started_at: startedAt,
|
|
1009
|
+
ended_at: null,
|
|
1010
|
+
}, null, 2), 'utf8');
|
|
1011
|
+
}
|
|
1012
|
+
catch {
|
|
1013
|
+
return null;
|
|
1014
|
+
}
|
|
1015
|
+
if (transcriptPath) {
|
|
1016
|
+
syncClaudeTranscript();
|
|
1017
|
+
transcriptInterval = setInterval(() => {
|
|
1018
|
+
syncClaudeTranscript();
|
|
1019
|
+
}, 500);
|
|
1020
|
+
}
|
|
1021
|
+
return {
|
|
1022
|
+
appendChunk: (chunk) => {
|
|
1023
|
+
if (finalized || chunk.length === 0 || transcriptPath) {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
hasLiveContent = true;
|
|
1027
|
+
enqueue(async () => {
|
|
1028
|
+
await fs.appendFile(contentPath, chunk, 'utf8');
|
|
1029
|
+
});
|
|
1030
|
+
},
|
|
1031
|
+
finalize: async (status, fallbackContent) => {
|
|
1032
|
+
if (finalized) {
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
finalized = true;
|
|
1036
|
+
if (transcriptInterval) {
|
|
1037
|
+
clearInterval(transcriptInterval);
|
|
1038
|
+
transcriptInterval = null;
|
|
1039
|
+
}
|
|
1040
|
+
if (transcriptPath) {
|
|
1041
|
+
syncClaudeTranscript();
|
|
1042
|
+
}
|
|
1043
|
+
if (!hasLiveContent && typeof fallbackContent === 'string' && fallbackContent.length > 0) {
|
|
1044
|
+
enqueue(async () => {
|
|
1045
|
+
await fs.writeFile(contentPath, fallbackContent, 'utf8');
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
await writeChain;
|
|
1049
|
+
await fs
|
|
1050
|
+
.writeFile(metadataPath, JSON.stringify({
|
|
1051
|
+
feature_id: input.featureId,
|
|
1052
|
+
role: input.role,
|
|
1053
|
+
session_id: input.sessionId,
|
|
1054
|
+
provider: input.provider,
|
|
1055
|
+
model: input.model,
|
|
1056
|
+
execution_mode: input.executionMode,
|
|
1057
|
+
status,
|
|
1058
|
+
started_at: startedAt,
|
|
1059
|
+
ended_at: new Date().toISOString(),
|
|
1060
|
+
}, null, 2), 'utf8')
|
|
1061
|
+
.catch(() => undefined);
|
|
1062
|
+
},
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
383
1065
|
async persistRawAgentOutput(featureId, role, stdout) {
|
|
384
1066
|
if (!this.rawAgentLogsEnabled || !this.repoRoot) {
|
|
385
1067
|
return;
|
|
@@ -387,7 +1069,7 @@ export class CliWorkerProvider {
|
|
|
387
1069
|
if (stdout.trim().length === 0) {
|
|
388
1070
|
return;
|
|
389
1071
|
}
|
|
390
|
-
if (role
|
|
1072
|
+
if (!isRawLogRole(role)) {
|
|
391
1073
|
return;
|
|
392
1074
|
}
|
|
393
1075
|
const logsDir = path.join(this.repoRoot, '.aop', 'features', featureId, 'logs');
|
|
@@ -402,6 +1084,36 @@ export class CliWorkerProvider {
|
|
|
402
1084
|
// Raw log persistence must not fail orchestration flow.
|
|
403
1085
|
}
|
|
404
1086
|
}
|
|
1087
|
+
async createOutputCapture(args) {
|
|
1088
|
+
if (!args.includes('{output_last_message_path}')) {
|
|
1089
|
+
return { captureDir: null, lastMessagePath: null };
|
|
1090
|
+
}
|
|
1091
|
+
const captureDir = await fs.mkdtemp(path.join(os.tmpdir(), 'aop-provider-output-'));
|
|
1092
|
+
return {
|
|
1093
|
+
captureDir,
|
|
1094
|
+
lastMessagePath: path.join(captureDir, 'last-message.txt'),
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
async resolvePreferredWorkerOutput(stdout, lastMessagePath) {
|
|
1098
|
+
if (lastMessagePath) {
|
|
1099
|
+
try {
|
|
1100
|
+
const lastMessage = await fs.readFile(lastMessagePath, 'utf8');
|
|
1101
|
+
if (lastMessage.trim().length > 0) {
|
|
1102
|
+
return lastMessage;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
catch {
|
|
1106
|
+
// Fall back to stdout when the provider does not materialize the capture file.
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
return stdout;
|
|
1110
|
+
}
|
|
1111
|
+
async cleanupOutputCapture(captureDir) {
|
|
1112
|
+
if (!captureDir) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
await fs.rm(captureDir, { recursive: true, force: true }).catch(() => undefined);
|
|
1116
|
+
}
|
|
405
1117
|
async cleanupExpiredRawAgentLogs(logsDir) {
|
|
406
1118
|
const cutoffMs = Date.now() - this.rawAgentLogsRetentionDays * 24 * 60 * 60 * 1000;
|
|
407
1119
|
try {
|