smol-symphony 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +41 -22
- package/DESIGN.md +494 -273
- package/README.md +109 -57
- package/SPEC.md +33 -24
- package/WORKFLOW.minimal.yaml +34 -0
- package/{WORKFLOW.template.md → WORKFLOW.template.yaml} +409 -256
- package/WORKFLOW.yaml +487 -0
- package/assets/skills/symphony-issues/SKILL.md +136 -0
- package/assets/symphony-mise.system.toml +68 -0
- package/dist/bin/symphony.js +22 -786
- package/dist/bin/symphony.js.map +1 -1
- package/dist/core/actions/context.js +109 -0
- package/dist/core/actions/context.js.map +1 -0
- package/dist/{actions/parsing.js → core/actions/parse.js} +33 -114
- package/dist/core/actions/parse.js.map +1 -0
- package/dist/core/actions/plan.js +197 -0
- package/dist/core/actions/plan.js.map +1 -0
- package/dist/core/actions/predicates.js +111 -0
- package/dist/core/actions/predicates.js.map +1 -0
- package/dist/core/actions/run-fold.js +248 -0
- package/dist/core/actions/run-fold.js.map +1 -0
- package/dist/core/actions/template.js +118 -0
- package/dist/core/actions/template.js.map +1 -0
- package/dist/core/cli/args.js +116 -0
- package/dist/core/cli/args.js.map +1 -0
- package/dist/core/coerce.js +75 -0
- package/dist/core/coerce.js.map +1 -0
- package/dist/core/credential/account-id.js +20 -0
- package/dist/core/credential/account-id.js.map +1 -0
- package/dist/core/credential/adapter-config.js +136 -0
- package/dist/core/credential/adapter-config.js.map +1 -0
- package/dist/core/credential/availability.js +98 -0
- package/dist/core/credential/availability.js.map +1 -0
- package/dist/core/credential/extract.js +228 -0
- package/dist/core/credential/extract.js.map +1 -0
- package/dist/core/credential/fake-creds.js +171 -0
- package/dist/core/credential/fake-creds.js.map +1 -0
- package/dist/core/credential/identity.js +125 -0
- package/dist/core/credential/identity.js.map +1 -0
- package/dist/core/credential/shape.js +230 -0
- package/dist/core/credential/shape.js.map +1 -0
- package/dist/core/credential/strings.js +15 -0
- package/dist/core/credential/strings.js.map +1 -0
- package/dist/core/doctor/checks.js +303 -0
- package/dist/core/doctor/checks.js.map +1 -0
- package/dist/core/git/result.js +107 -0
- package/dist/core/git/result.js.map +1 -0
- package/dist/core/http/decisions.js +225 -0
- package/dist/core/http/decisions.js.map +1 -0
- package/dist/{http.js → core/http/render.js} +472 -738
- package/dist/core/http/render.js.map +1 -0
- package/dist/{http-handlers.js → core/http/routes.js} +52 -87
- package/dist/core/http/routes.js.map +1 -0
- package/dist/core/http/views.js +181 -0
- package/dist/core/http/views.js.map +1 -0
- package/dist/core/image/managed-image.js +95 -0
- package/dist/core/image/managed-image.js.map +1 -0
- package/dist/core/issue/file.js +149 -0
- package/dist/core/issue/file.js.map +1 -0
- package/dist/core/issue/parse.js +210 -0
- package/dist/core/issue/parse.js.map +1 -0
- package/dist/core/mcp/dispatch.js +239 -0
- package/dist/core/mcp/dispatch.js.map +1 -0
- package/dist/core/mcp/post-move.js +92 -0
- package/dist/core/mcp/post-move.js.map +1 -0
- package/dist/core/mcp/protocol.js +293 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/url.js +162 -0
- package/dist/core/mcp/url.js.map +1 -0
- package/dist/core/path.js +63 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/reconcile/image-decide.js +48 -0
- package/dist/core/reconcile/image-decide.js.map +1 -0
- package/dist/core/reconcile/ledger.js +142 -0
- package/dist/core/reconcile/ledger.js.map +1 -0
- package/dist/core/reconcile/pr-classify.js +62 -0
- package/dist/core/reconcile/pr-classify.js.map +1 -0
- package/dist/{reconciler → core/reconcile}/pr-decide.js +25 -12
- package/dist/core/reconcile/pr-decide.js.map +1 -0
- package/dist/core/reconcile/pr-loop.js +161 -0
- package/dist/core/reconcile/pr-loop.js.map +1 -0
- package/dist/core/reconcile/pr-notes.js +35 -0
- package/dist/core/reconcile/pr-notes.js.map +1 -0
- package/dist/core/reconcile/vm-decide.js +70 -0
- package/dist/core/reconcile/vm-decide.js.map +1 -0
- package/dist/core/reconcile/vm-reap.js +207 -0
- package/dist/core/reconcile/vm-reap.js.map +1 -0
- package/dist/core/reconcile/workspace-decide.js +162 -0
- package/dist/core/reconcile/workspace-decide.js.map +1 -0
- package/dist/core/runlog/summary.js +231 -0
- package/dist/core/runlog/summary.js.map +1 -0
- package/dist/core/runner/dispatch-config.js +95 -0
- package/dist/core/runner/dispatch-config.js.map +1 -0
- package/dist/core/runner/injection.js +61 -0
- package/dist/core/runner/injection.js.map +1 -0
- package/dist/core/runner/mise.js +210 -0
- package/dist/core/runner/mise.js.map +1 -0
- package/dist/core/runner/prompt.js +720 -0
- package/dist/core/runner/prompt.js.map +1 -0
- package/dist/core/runner/turn.js +242 -0
- package/dist/core/runner/turn.js.map +1 -0
- package/dist/core/runner/vm-plan.js +390 -0
- package/dist/core/runner/vm-plan.js.map +1 -0
- package/dist/core/schedule/admission.js +123 -0
- package/dist/core/schedule/admission.js.map +1 -0
- package/dist/core/schedule/circuit-breaker.js +111 -0
- package/dist/core/schedule/circuit-breaker.js.map +1 -0
- package/dist/core/schedule/eligibility.js +83 -0
- package/dist/core/schedule/eligibility.js.map +1 -0
- package/dist/core/schedule/reconcile-issue.js +82 -0
- package/dist/core/schedule/reconcile-issue.js.map +1 -0
- package/dist/core/schedule/retry.js +96 -0
- package/dist/core/schedule/retry.js.map +1 -0
- package/dist/core/schedule/sleep-cycle.js +133 -0
- package/dist/core/schedule/sleep-cycle.js.map +1 -0
- package/dist/core/schedule/slots.js +124 -0
- package/dist/core/schedule/slots.js.map +1 -0
- package/dist/core/schedule/tick.js +553 -0
- package/dist/core/schedule/tick.js.map +1 -0
- package/dist/core/schedule/token-fold.js +181 -0
- package/dist/core/schedule/token-fold.js.map +1 -0
- package/dist/core/state-resolve.js +86 -0
- package/dist/core/state-resolve.js.map +1 -0
- package/dist/core/vm-guards.js +278 -0
- package/dist/core/vm-guards.js.map +1 -0
- package/dist/core/workflow/derive.js +107 -0
- package/dist/core/workflow/derive.js.map +1 -0
- package/dist/core/workflow/parse.js +687 -0
- package/dist/core/workflow/parse.js.map +1 -0
- package/dist/core/workflow/prompt-probe.js +78 -0
- package/dist/core/workflow/prompt-probe.js.map +1 -0
- package/dist/core/workflow/validate.js +189 -0
- package/dist/core/workflow/validate.js.map +1 -0
- package/dist/core/workspace-key.js +19 -0
- package/dist/core/workspace-key.js.map +1 -0
- package/dist/shell/actions-runner.js +356 -0
- package/dist/shell/actions-runner.js.map +1 -0
- package/dist/shell/adapter/adapter-registry.js +45 -0
- package/dist/shell/adapter/adapter-registry.js.map +1 -0
- package/dist/shell/adapter/clock-random.js +96 -0
- package/dist/shell/adapter/clock-random.js.map +1 -0
- package/dist/shell/adapter/gondolin-dispatch-helpers.js +158 -0
- package/dist/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
- package/dist/shell/adapter/gondolin-dispatch.js +385 -0
- package/dist/shell/adapter/gondolin-dispatch.js.map +1 -0
- package/dist/shell/adapter/gondolin-image-converter.js +233 -0
- package/dist/shell/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/shell/adapter/gondolin-image-fetch.js +180 -0
- package/dist/shell/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/shell/adapter/launcher-asset.js +57 -0
- package/dist/shell/adapter/launcher-asset.js.map +1 -0
- package/dist/shell/adapter/mise-config-asset.js +65 -0
- package/dist/shell/adapter/mise-config-asset.js.map +1 -0
- package/dist/shell/adapter/workflow-loader.js +304 -0
- package/dist/shell/adapter/workflow-loader.js.map +1 -0
- package/dist/shell/cli/doctor.js +268 -0
- package/dist/shell/cli/doctor.js.map +1 -0
- package/dist/shell/effect-interpreter-families.js +314 -0
- package/dist/shell/effect-interpreter-families.js.map +1 -0
- package/dist/shell/effect-interpreter.js +29 -0
- package/dist/shell/effect-interpreter.js.map +1 -0
- package/dist/shell/interp/acp-frame.js +137 -0
- package/dist/shell/interp/acp-frame.js.map +1 -0
- package/dist/shell/interp/acp-ws-conn.js +320 -0
- package/dist/shell/interp/acp-ws-conn.js.map +1 -0
- package/dist/shell/interp/acp-ws-frames.js +159 -0
- package/dist/shell/interp/acp-ws-frames.js.map +1 -0
- package/dist/shell/interp/acp-ws.js +197 -0
- package/dist/shell/interp/acp-ws.js.map +1 -0
- package/dist/shell/interp/acp.js +319 -0
- package/dist/shell/interp/acp.js.map +1 -0
- package/dist/shell/interp/credential-defaults.js +128 -0
- package/dist/shell/interp/credential-defaults.js.map +1 -0
- package/dist/shell/interp/credential-hooks.js +149 -0
- package/dist/shell/interp/credential-hooks.js.map +1 -0
- package/dist/shell/interp/credential-registry.js +226 -0
- package/dist/shell/interp/credential-registry.js.map +1 -0
- package/dist/shell/interp/credential.js +103 -0
- package/dist/shell/interp/credential.js.map +1 -0
- package/dist/shell/interp/gh.js +163 -0
- package/dist/shell/interp/gh.js.map +1 -0
- package/dist/shell/interp/git.js +28 -0
- package/dist/shell/interp/git.js.map +1 -0
- package/dist/shell/interp/log.js +213 -0
- package/dist/shell/interp/log.js.map +1 -0
- package/dist/shell/interp/process.js +178 -0
- package/dist/shell/interp/process.js.map +1 -0
- package/dist/shell/interp/runlog.js +193 -0
- package/dist/shell/interp/runlog.js.map +1 -0
- package/dist/shell/interp/timer.js +64 -0
- package/dist/shell/interp/timer.js.map +1 -0
- package/dist/shell/interp/tracker-disk.js +99 -0
- package/dist/shell/interp/tracker-disk.js.map +1 -0
- package/dist/shell/interp/tracker-parse.js +71 -0
- package/dist/shell/interp/tracker-parse.js.map +1 -0
- package/dist/shell/interp/tracker-scan.js +238 -0
- package/dist/shell/interp/tracker-scan.js.map +1 -0
- package/dist/shell/interp/tracker-write.js +91 -0
- package/dist/shell/interp/tracker-write.js.map +1 -0
- package/dist/shell/interp/tracker.js +41 -0
- package/dist/shell/interp/tracker.js.map +1 -0
- package/dist/shell/interp/tty.js +48 -0
- package/dist/shell/interp/tty.js.map +1 -0
- package/dist/shell/interp/vm.js +199 -0
- package/dist/shell/interp/vm.js.map +1 -0
- package/dist/shell/interp/workspace.js +310 -0
- package/dist/shell/interp/workspace.js.map +1 -0
- package/dist/shell/main-acp.js +78 -0
- package/dist/shell/main-acp.js.map +1 -0
- package/dist/shell/main-adapters.js +222 -0
- package/dist/shell/main-adapters.js.map +1 -0
- package/dist/shell/main-credential.js +122 -0
- package/dist/shell/main-credential.js.map +1 -0
- package/dist/shell/main-doctor.js +22 -0
- package/dist/shell/main-doctor.js.map +1 -0
- package/dist/shell/main-entry.js +46 -0
- package/dist/shell/main-entry.js.map +1 -0
- package/dist/shell/main-http-csrf.js +45 -0
- package/dist/shell/main-http-csrf.js.map +1 -0
- package/dist/shell/main-http-handler.js +389 -0
- package/dist/shell/main-http-handler.js.map +1 -0
- package/dist/shell/main-http-mcp.js +122 -0
- package/dist/shell/main-http-mcp.js.map +1 -0
- package/dist/shell/main-http-views.js +253 -0
- package/dist/shell/main-http-views.js.map +1 -0
- package/dist/shell/main-http.js +76 -0
- package/dist/shell/main-http.js.map +1 -0
- package/dist/shell/main-loops.js +130 -0
- package/dist/shell/main-loops.js.map +1 -0
- package/dist/shell/main-mcp.js +129 -0
- package/dist/shell/main-mcp.js.map +1 -0
- package/dist/shell/main-orchestrator.js +120 -0
- package/dist/shell/main-orchestrator.js.map +1 -0
- package/dist/shell/main-preflight.js +43 -0
- package/dist/shell/main-preflight.js.map +1 -0
- package/dist/shell/main-reconcilers-helpers.js +244 -0
- package/dist/shell/main-reconcilers-helpers.js.map +1 -0
- package/dist/shell/main-reconcilers-pr.js +148 -0
- package/dist/shell/main-reconcilers-pr.js.map +1 -0
- package/dist/shell/main-reconcilers.js +225 -0
- package/dist/shell/main-reconcilers.js.map +1 -0
- package/dist/shell/main-runner.js +355 -0
- package/dist/shell/main-runner.js.map +1 -0
- package/dist/shell/main-scaffold.js +116 -0
- package/dist/shell/main-scaffold.js.map +1 -0
- package/dist/shell/main-shutdown.js +115 -0
- package/dist/shell/main-shutdown.js.map +1 -0
- package/dist/shell/main-startup.js +48 -0
- package/dist/shell/main-startup.js.map +1 -0
- package/dist/shell/main-substrates.js +43 -0
- package/dist/shell/main-substrates.js.map +1 -0
- package/dist/shell/main.js +385 -0
- package/dist/shell/main.js.map +1 -0
- package/dist/shell/orchestrator-feedback.js +69 -0
- package/dist/shell/orchestrator-feedback.js.map +1 -0
- package/dist/shell/orchestrator-image.js +167 -0
- package/dist/shell/orchestrator-image.js.map +1 -0
- package/dist/shell/orchestrator-loop.js +468 -0
- package/dist/shell/orchestrator-loop.js.map +1 -0
- package/dist/shell/orchestrator-reconcile.js +36 -0
- package/dist/shell/orchestrator-reconcile.js.map +1 -0
- package/dist/shell/reconciler-loop.js +228 -0
- package/dist/shell/reconciler-loop.js.map +1 -0
- package/dist/shell/runner-loop-turn.js +301 -0
- package/dist/shell/runner-loop-turn.js.map +1 -0
- package/dist/shell/runner-loop.js +338 -0
- package/dist/shell/runner-loop.js.map +1 -0
- package/dist/shell/server/http.js +208 -0
- package/dist/shell/server/http.js.map +1 -0
- package/dist/shell/server/mcp-runtime-effects.js +237 -0
- package/dist/shell/server/mcp-runtime-effects.js.map +1 -0
- package/dist/shell/server/mcp-runtime.js +99 -0
- package/dist/shell/server/mcp-runtime.js.map +1 -0
- package/dist/shell/workspace-key.js +14 -0
- package/dist/shell/workspace-key.js.map +1 -0
- package/dist/types/acp.js +8 -0
- package/dist/types/acp.js.map +1 -0
- package/dist/types/actions/plan.js +6 -0
- package/dist/types/actions/plan.js.map +1 -0
- package/dist/types/actions/predicates.js +6 -0
- package/dist/types/actions/predicates.js.map +1 -0
- package/dist/types/actions/run-fold.js +8 -0
- package/dist/types/actions/run-fold.js.map +1 -0
- package/dist/types/actions.js +7 -0
- package/dist/types/actions.js.map +1 -0
- package/dist/types/adapter/clock-random.js +4 -0
- package/dist/types/adapter/clock-random.js.map +1 -0
- package/dist/types/adapter/gondolin-image-converter.js +5 -0
- package/dist/types/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/types/adapter/gondolin-image-fetch.js +5 -0
- package/dist/types/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/types/adapter/workflow-loader.js +4 -0
- package/dist/types/adapter/workflow-loader.js.map +1 -0
- package/dist/types/cli/args.js +8 -0
- package/dist/types/cli/args.js.map +1 -0
- package/dist/types/config.js +8 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/credential-interp.js +6 -0
- package/dist/types/credential-interp.js.map +1 -0
- package/dist/types/credentials.js +10 -0
- package/dist/types/credentials.js.map +1 -0
- package/dist/types/doctor.js +7 -0
- package/dist/types/doctor.js.map +1 -0
- package/dist/types/domain.js +7 -0
- package/dist/types/domain.js.map +1 -0
- package/dist/types/effect.js +15 -0
- package/dist/types/effect.js.map +1 -0
- package/dist/types/errors.js +39 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/http/decisions.js +6 -0
- package/dist/types/http/decisions.js.map +1 -0
- package/dist/types/http/render.js +10 -0
- package/dist/types/http/render.js.map +1 -0
- package/dist/types/http/views.js +6 -0
- package/dist/types/http/views.js.map +1 -0
- package/dist/types/http.js +9 -0
- package/dist/types/http.js.map +1 -0
- package/dist/types/image/managed-image.js +7 -0
- package/dist/types/image/managed-image.js.map +1 -0
- package/dist/types/interp/effect-interpreter.js +8 -0
- package/dist/types/interp/effect-interpreter.js.map +1 -0
- package/dist/types/interp/tracker.js +7 -0
- package/dist/types/interp/tracker.js.map +1 -0
- package/dist/types/issue/file.js +6 -0
- package/dist/types/issue/file.js.map +1 -0
- package/dist/types/issue/parse.js +8 -0
- package/dist/types/issue/parse.js.map +1 -0
- package/dist/types/main-acp.js +13 -0
- package/dist/types/main-acp.js.map +1 -0
- package/dist/types/main-adapters.js +5 -0
- package/dist/types/main-adapters.js.map +1 -0
- package/dist/types/main-credential.js +21 -0
- package/dist/types/main-credential.js.map +1 -0
- package/dist/types/main-doctor.js +6 -0
- package/dist/types/main-doctor.js.map +1 -0
- package/dist/types/main-http-handler.js +12 -0
- package/dist/types/main-http-handler.js.map +1 -0
- package/dist/types/main-http.js +5 -0
- package/dist/types/main-http.js.map +1 -0
- package/dist/types/main-loops.js +5 -0
- package/dist/types/main-loops.js.map +1 -0
- package/dist/types/main-mcp.js +12 -0
- package/dist/types/main-mcp.js.map +1 -0
- package/dist/types/main-orchestrator.js +5 -0
- package/dist/types/main-orchestrator.js.map +1 -0
- package/dist/types/main-reconcilers.js +11 -0
- package/dist/types/main-reconcilers.js.map +1 -0
- package/dist/types/main-runner.js +13 -0
- package/dist/types/main-runner.js.map +1 -0
- package/dist/types/main-startup.js +5 -0
- package/dist/types/main-startup.js.map +1 -0
- package/dist/types/main-substrates.js +5 -0
- package/dist/types/main-substrates.js.map +1 -0
- package/dist/types/mcp/dispatch.js +4 -0
- package/dist/types/mcp/dispatch.js.map +1 -0
- package/dist/types/mcp/post-move.js +7 -0
- package/dist/types/mcp/post-move.js.map +1 -0
- package/dist/types/mcp.js +9 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/ports.js +12 -0
- package/dist/types/ports.js.map +1 -0
- package/dist/types/reconcile/image-decide.js +5 -0
- package/dist/types/reconcile/image-decide.js.map +1 -0
- package/dist/types/reconcile/ledger.js +7 -0
- package/dist/types/reconcile/ledger.js.map +1 -0
- package/dist/types/reconcile/pr-loop.js +8 -0
- package/dist/types/reconcile/pr-loop.js.map +1 -0
- package/dist/types/reconcile/vm-reap.js +8 -0
- package/dist/types/reconcile/vm-reap.js.map +1 -0
- package/dist/types/reconcile/workspace-decide.js +7 -0
- package/dist/types/reconcile/workspace-decide.js.map +1 -0
- package/dist/types/reconcile.js +9 -0
- package/dist/types/reconcile.js.map +1 -0
- package/dist/types/runlog.js +7 -0
- package/dist/types/runlog.js.map +1 -0
- package/dist/types/runner/actions-runner.js +12 -0
- package/dist/types/runner/actions-runner.js.map +1 -0
- package/dist/types/runner/gondolin-dispatch.js +5 -0
- package/dist/types/runner/gondolin-dispatch.js.map +1 -0
- package/dist/types/runner/injection.js +6 -0
- package/dist/types/runner/injection.js.map +1 -0
- package/dist/types/runner/runner-loop.js +5 -0
- package/dist/types/runner/runner-loop.js.map +1 -0
- package/dist/types/runner/turn.js +4 -0
- package/dist/types/runner/turn.js.map +1 -0
- package/dist/types/runner/vm-plan.js +4 -0
- package/dist/types/runner/vm-plan.js.map +1 -0
- package/dist/types/runtime.js +9 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/schedule/admission.js +7 -0
- package/dist/types/schedule/admission.js.map +1 -0
- package/dist/types/schedule/circuit-breaker.js +2 -0
- package/dist/types/schedule/circuit-breaker.js.map +1 -0
- package/dist/types/schedule/eligibility.js +9 -0
- package/dist/types/schedule/eligibility.js.map +1 -0
- package/dist/types/schedule/orchestrator-loop.js +10 -0
- package/dist/types/schedule/orchestrator-loop.js.map +1 -0
- package/dist/types/schedule/sleep-cycle.js +4 -0
- package/dist/types/schedule/sleep-cycle.js.map +1 -0
- package/dist/types/schedule/slots.js +8 -0
- package/dist/types/schedule/slots.js.map +1 -0
- package/dist/types/schedule/tick.js +9 -0
- package/dist/types/schedule/tick.js.map +1 -0
- package/dist/types/server/mcp-runtime.js +8 -0
- package/dist/types/server/mcp-runtime.js.map +1 -0
- package/dist/types/workflow/parse.js +4 -0
- package/dist/types/workflow/parse.js.map +1 -0
- package/package.json +22 -10
- package/patches/@earendil-works+gondolin+0.12.0.patch +173 -0
- package/prompts/Reflect.md +91 -0
- package/prompts/Review.md +97 -0
- package/prompts/Todo.md +96 -0
- package/prompts/_footer.md +41 -0
- package/prompts/_preamble.md +42 -0
- package/prompts-minimal/Todo.md +26 -0
- package/scripts/postinstall.mjs +63 -0
- package/scripts/vm-agent.mjs +312 -90
- package/WORKFLOW.md +0 -744
- package/dist/acp-bridge.js +0 -324
- package/dist/acp-bridge.js.map +0 -1
- package/dist/actions/cache.js +0 -191
- package/dist/actions/cache.js.map +0 -1
- package/dist/actions/effects.js +0 -41
- package/dist/actions/effects.js.map +0 -1
- package/dist/actions/executor.js +0 -570
- package/dist/actions/executor.js.map +0 -1
- package/dist/actions/index.js +0 -13
- package/dist/actions/index.js.map +0 -1
- package/dist/actions/parsing.js.map +0 -1
- package/dist/actions/predicate-env.js +0 -27
- package/dist/actions/predicate-env.js.map +0 -1
- package/dist/actions/predicates.js +0 -49
- package/dist/actions/predicates.js.map +0 -1
- package/dist/actions/templating.js +0 -66
- package/dist/actions/templating.js.map +0 -1
- package/dist/actions/types.js +0 -15
- package/dist/actions/types.js.map +0 -1
- package/dist/agent/acp.js +0 -473
- package/dist/agent/acp.js.map +0 -1
- package/dist/agent/adapter-names.js +0 -159
- package/dist/agent/adapter-names.js.map +0 -1
- package/dist/agent/adapters.js +0 -511
- package/dist/agent/adapters.js.map +0 -1
- package/dist/agent/credential-extractors.js +0 -342
- package/dist/agent/credential-extractors.js.map +0 -1
- package/dist/agent/credential-secrets.js +0 -628
- package/dist/agent/credential-secrets.js.map +0 -1
- package/dist/agent/credential-ticker.js +0 -57
- package/dist/agent/credential-ticker.js.map +0 -1
- package/dist/agent/gondolin-creds-staging.js +0 -356
- package/dist/agent/gondolin-creds-staging.js.map +0 -1
- package/dist/agent/gondolin-dispatch.js +0 -375
- package/dist/agent/gondolin-dispatch.js.map +0 -1
- package/dist/agent/gondolin.js +0 -124
- package/dist/agent/gondolin.js.map +0 -1
- package/dist/agent/runner-decisions.js +0 -134
- package/dist/agent/runner-decisions.js.map +0 -1
- package/dist/agent/runner.js +0 -1456
- package/dist/agent/runner.js.map +0 -1
- package/dist/agent/tool-call-summary.js +0 -102
- package/dist/agent/tool-call-summary.js.map +0 -1
- package/dist/agent/vm-acp-mapping.js +0 -73
- package/dist/agent/vm-acp-mapping.js.map +0 -1
- package/dist/agent/vm-guards.js +0 -262
- package/dist/agent/vm-guards.js.map +0 -1
- package/dist/agent/vm-port.js +0 -22
- package/dist/agent/vm-port.js.map +0 -1
- package/dist/agent/vm-process-registry.js +0 -79
- package/dist/agent/vm-process-registry.js.map +0 -1
- package/dist/bin/cli-args.js +0 -105
- package/dist/bin/cli-args.js.map +0 -1
- package/dist/errors.js +0 -15
- package/dist/errors.js.map +0 -1
- package/dist/http-disk.js +0 -135
- package/dist/http-disk.js.map +0 -1
- package/dist/http-handlers.js.map +0 -1
- package/dist/http.js.map +0 -1
- package/dist/issues.js +0 -178
- package/dist/issues.js.map +0 -1
- package/dist/logging.js +0 -203
- package/dist/logging.js.map +0 -1
- package/dist/mcp.js +0 -706
- package/dist/mcp.js.map +0 -1
- package/dist/memory.js +0 -85
- package/dist/memory.js.map +0 -1
- package/dist/orchestrator-decisions.js +0 -331
- package/dist/orchestrator-decisions.js.map +0 -1
- package/dist/orchestrator.js +0 -1569
- package/dist/orchestrator.js.map +0 -1
- package/dist/prompt.js +0 -65
- package/dist/prompt.js.map +0 -1
- package/dist/reconciler/cache.js +0 -65
- package/dist/reconciler/cache.js.map +0 -1
- package/dist/reconciler/index.js +0 -448
- package/dist/reconciler/index.js.map +0 -1
- package/dist/reconciler/ledger.js +0 -131
- package/dist/reconciler/ledger.js.map +0 -1
- package/dist/reconciler/pr-adapters.js +0 -174
- package/dist/reconciler/pr-adapters.js.map +0 -1
- package/dist/reconciler/pr-decide.js.map +0 -1
- package/dist/reconciler/pr.js +0 -422
- package/dist/reconciler/pr.js.map +0 -1
- package/dist/reconciler/types.js +0 -12
- package/dist/reconciler/types.js.map +0 -1
- package/dist/reconciler/vm.js +0 -243
- package/dist/reconciler/vm.js.map +0 -1
- package/dist/reconciler/workspace-defaults.js +0 -83
- package/dist/reconciler/workspace-defaults.js.map +0 -1
- package/dist/reconciler/workspace.js +0 -272
- package/dist/reconciler/workspace.js.map +0 -1
- package/dist/runlog.js +0 -403
- package/dist/runlog.js.map +0 -1
- package/dist/scaffold.js +0 -165
- package/dist/scaffold.js.map +0 -1
- package/dist/trackers/local.js +0 -445
- package/dist/trackers/local.js.map +0 -1
- package/dist/trackers/types.js +0 -10
- package/dist/trackers/types.js.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/util/clock.js +0 -12
- package/dist/util/clock.js.map +0 -1
- package/dist/util/crypto.js +0 -25
- package/dist/util/crypto.js.map +0 -1
- package/dist/util/frontmatter.js +0 -70
- package/dist/util/frontmatter.js.map +0 -1
- package/dist/util/fs-issues.js +0 -22
- package/dist/util/fs-issues.js.map +0 -1
- package/dist/util/process.js +0 -152
- package/dist/util/process.js.map +0 -1
- package/dist/util/workspace-key.js +0 -10
- package/dist/util/workspace-key.js.map +0 -1
- package/dist/workflow-loader.js +0 -147
- package/dist/workflow-loader.js.map +0 -1
- package/dist/workflow.js +0 -822
- package/dist/workflow.js.map +0 -1
- package/dist/workspace-types.js +0 -8
- package/dist/workspace-types.js.map +0 -1
- package/dist/workspace.js +0 -443
- package/dist/workspace.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm.js","sourceRoot":"","sources":["../../../src/shell/interp/vm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
// FCIS rewrite — WorkspaceEffect adapter (kind: adapter) implementing the
|
|
2
|
+
// `WorkspacePort` over the host filesystem + git/gh CLIs.
|
|
3
|
+
//
|
|
4
|
+
// Responsibility (ported from the read-only reference, NOT modified):
|
|
5
|
+
// • src/workspace.ts — ensureFor (per-identifier lock, assertContained
|
|
6
|
+
// guard, mkdir, canonical clone+branch+origin
|
|
7
|
+
// restore + restorePushedBranch on re-dispatch),
|
|
8
|
+
// fetchBaseInWorkspace, remove, workspacePathFor.
|
|
9
|
+
// • src/reconciler/workspace-defaults.ts — list (dirs under root) + inspect
|
|
10
|
+
// (HEAD / base-sha / dirty / commits-ahead).
|
|
11
|
+
//
|
|
12
|
+
// The central effect-interpreter routes the `workspace` family to this port
|
|
13
|
+
// (effect-interpreter.ts `workspace()`); ZERO decisions live here. Env-driven
|
|
14
|
+
// repo/base resolution (SYMPHONY_REPO / SYMPHONY_BASE_BRANCH / SYMPHONY_SOURCE_REPO)
|
|
15
|
+
// now lives in core — the port receives an ALREADY-RESOLVED `{ baseBranch,
|
|
16
|
+
// githubRepo }`, so this adapter only performs IO.
|
|
17
|
+
//
|
|
18
|
+
// Shell rule: imports from src/types/** ONLY. Git/gh spawn lifecycle is injected
|
|
19
|
+
// as a `ProcessRunner` port by the composition root, so this file stays a thin
|
|
20
|
+
// fs+verb mapper. NodeNext ESM with .js extensions on relative imports.
|
|
21
|
+
import { mkdir, rm, lstat, stat, readdir, writeFile, access } from 'node:fs/promises';
|
|
22
|
+
import path from 'node:path';
|
|
23
|
+
import { sanitizeWorkspaceKey } from '../workspace-key.js';
|
|
24
|
+
// Pinned commit identity for work the in-VM agent makes. Local-only so it never
|
|
25
|
+
// leaks into ~/.gitconfig. Mirrors workspace.ts resolveSetupOptions.
|
|
26
|
+
const GIT_IDENTITY = { name: 'symphony-agent', email: 'agent@symphony.local' };
|
|
27
|
+
// Network git verbs fail fast on a credential prompt rather than blocking
|
|
28
|
+
// (workspace.ts `noPrompt`).
|
|
29
|
+
const NO_PROMPT_ENV = { GIT_TERMINAL_PROMPT: '0' };
|
|
30
|
+
// Marker file (workspace-dir root) the runner drops when a terminal-state phase-8
|
|
31
|
+
// handoff push FAILED; the janitor stats it and RETAINS the dir so the only copy
|
|
32
|
+
// of the completed commit survives for manual push/recovery (issue 234). A dotfile
|
|
33
|
+
// at the clone root so an operator doing manual recovery sees it (and the reason)
|
|
34
|
+
// in a plain `ls -la`.
|
|
35
|
+
const HANDOFF_PENDING_MARKER = '.symphony-handoff-pending';
|
|
36
|
+
class WorkspaceError extends Error {
|
|
37
|
+
code;
|
|
38
|
+
constructor(code, message) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.code = code;
|
|
41
|
+
this.name = 'WorkspaceError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function workspacePathFor(root, identifier) {
|
|
45
|
+
const key = sanitizeWorkspaceKey(identifier);
|
|
46
|
+
if (key.length === 0) {
|
|
47
|
+
throw new WorkspaceError('invalid_workspace_key', `cannot sanitize identifier: ${identifier}`);
|
|
48
|
+
}
|
|
49
|
+
return path.join(root, key);
|
|
50
|
+
}
|
|
51
|
+
// git/gh runner pair bound to a single deps.process seam. `expect` throws on a
|
|
52
|
+
// non-zero exit; the bare runner returns the result for the caller to branch on.
|
|
53
|
+
function gitRunners(proc) {
|
|
54
|
+
const run = (argv, cwd, env) => proc.run(['git', ...argv], { cwd, env });
|
|
55
|
+
const expect = async (argv, cwd, env) => {
|
|
56
|
+
const r = await run(argv, cwd, env);
|
|
57
|
+
if (r.exit_code !== 0) {
|
|
58
|
+
throw new WorkspaceError('workspace_setup_git_failed', `git ${argv.join(' ')} exited ${r.exit_code}: ${(r.stderr.trim() || r.stdout.trim())}`);
|
|
59
|
+
}
|
|
60
|
+
return r;
|
|
61
|
+
};
|
|
62
|
+
return { run, expect };
|
|
63
|
+
}
|
|
64
|
+
// Restore an already-pushed agent/<id> branch into a fresh clone so a re-dispatch
|
|
65
|
+
// continues from pushed work. Returns false when there is no origin (local-only)
|
|
66
|
+
// or the remote branch genuinely doesn't exist yet (ls-remote exit 2 = first
|
|
67
|
+
// dispatch). Fails CLOSED on any other non-zero exit (128 transport/auth) so a
|
|
68
|
+
// later push can't force-with-lease over already-pushed work once origin recovers.
|
|
69
|
+
async function restorePushedBranch(git, wsPath, branch) {
|
|
70
|
+
const remoteCheck = await git.run(['remote', 'get-url', 'origin'], wsPath);
|
|
71
|
+
if (remoteCheck.exit_code !== 0)
|
|
72
|
+
return false;
|
|
73
|
+
// Probe the EXACT head ref (`refs/heads/<branch>`) — `ls-remote <branch>` does
|
|
74
|
+
// suffix matching and a colliding ref would false-positive.
|
|
75
|
+
const exists = await git.run(['ls-remote', '--exit-code', 'origin', `refs/heads/${branch}`], wsPath, NO_PROMPT_ENV);
|
|
76
|
+
if (exists.exit_code === 2)
|
|
77
|
+
return false; // reached remote, no such ref → cut fresh
|
|
78
|
+
if (exists.exit_code !== 0) {
|
|
79
|
+
throw new WorkspaceError('workspace_setup_origin_unreachable', `git ls-remote origin ${branch} failed (exit ${exists.exit_code}): ${(exists.stderr || exists.stdout).trim()}`);
|
|
80
|
+
}
|
|
81
|
+
// Fetch the EXACT head ref (a bare <branch> refspec could resolve a same-named tag).
|
|
82
|
+
const fetched = await git.run(['fetch', '--no-tags', 'origin', `refs/heads/${branch}`], wsPath, NO_PROMPT_ENV);
|
|
83
|
+
if (fetched.exit_code !== 0) {
|
|
84
|
+
throw new WorkspaceError('workspace_setup_branch_fetch_failed', `git fetch origin ${branch} failed (exit ${fetched.exit_code}): ${(fetched.stderr || fetched.stdout).trim()}`);
|
|
85
|
+
}
|
|
86
|
+
await git.expect(['checkout', '-b', branch, 'FETCH_HEAD'], wsPath);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
// Canonical per-issue clone+branch+remote setup (workspace.ts setupWorkspaceDir).
|
|
90
|
+
// `wsPath` exists and is empty; on failure the caller unwinds the dir.
|
|
91
|
+
async function setup(deps, git, wsPath, baseBranch, branch, githubRepo) {
|
|
92
|
+
// 1. Source repo must look like a git repo. Read the LIVE source repo so a
|
|
93
|
+
// reloaded workflow_dir is honoured.
|
|
94
|
+
const sourceRepo = deps.sourceRepo();
|
|
95
|
+
try {
|
|
96
|
+
const st = await stat(path.join(sourceRepo, '.git'));
|
|
97
|
+
if (!st.isDirectory() && !st.isFile())
|
|
98
|
+
throw new Error('not a git dir');
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
throw new WorkspaceError('workspace_setup_no_source_repo', `source repo ${sourceRepo} is not a git repository: ${err.message}`);
|
|
102
|
+
}
|
|
103
|
+
// 2. Hardlinked, narrow-refspec clone landing on base (`.` cwd = wsPath).
|
|
104
|
+
await git.expect(['clone', '--local', '--no-tags', '--branch', baseBranch, sourceRepo, '.'], wsPath);
|
|
105
|
+
// 3. Strip every remote the clone copied (network targets stay zero) + unset
|
|
106
|
+
// any inherited credential.helper (best-effort: empty config → exit 5).
|
|
107
|
+
const remotes = await git.expect(['remote'], wsPath);
|
|
108
|
+
for (const remote of remotes.stdout.split(/\r?\n/).map((r) => r.trim()).filter((r) => r.length > 0)) {
|
|
109
|
+
await git.expect(['remote', 'remove', remote], wsPath);
|
|
110
|
+
}
|
|
111
|
+
await git.run(['config', '--local', '--unset', 'credential.helper'], wsPath);
|
|
112
|
+
// 4. Conditional origin restore (PR mode): canonical HTTPS URL (no token; auth
|
|
113
|
+
// is the host's gh, never the VM). Deliberately NO origin fetch+reset — the
|
|
114
|
+
// source repo's local <base> is the canonical base ref (avoids drift false
|
|
115
|
+
// positives, see workspace.ts comment).
|
|
116
|
+
if (githubRepo && githubRepo.length > 0) {
|
|
117
|
+
await git.expect(['remote', 'add', 'origin', `https://github.com/${githubRepo}.git`], wsPath);
|
|
118
|
+
// gh auth setup-git best-effort: a host without gh still gets a usable origin.
|
|
119
|
+
await deps.process.run(['gh', 'auth', 'setup-git'], { cwd: wsPath });
|
|
120
|
+
}
|
|
121
|
+
// 5. Pin commit identity (local-only).
|
|
122
|
+
await git.expect(['config', '--local', 'user.name', GIT_IDENTITY.name], wsPath);
|
|
123
|
+
await git.expect(['config', '--local', 'user.email', GIT_IDENTITY.email], wsPath);
|
|
124
|
+
// 6. Land HEAD on the per-issue branch. On re-dispatch (origin/<branch> already
|
|
125
|
+
// pushed) restore it so the agent's pushed work is carried forward; else cut
|
|
126
|
+
// fresh. See restorePushedBranch for the non-converging loop this closes.
|
|
127
|
+
if (await restorePushedBranch(git, wsPath, branch))
|
|
128
|
+
return;
|
|
129
|
+
await git.expect(['checkout', '-b', branch], wsPath);
|
|
130
|
+
}
|
|
131
|
+
// Resolve (creating if missing) the workspace dir. Returns true when THIS call
|
|
132
|
+
// did the mkdir (gates one-time canonical setup). Rejects symlinks (containment
|
|
133
|
+
// risk) and non-directory entries.
|
|
134
|
+
async function ensureDirExists(wsPath) {
|
|
135
|
+
try {
|
|
136
|
+
// lstat (not stat): a symlink could redirect setup + the returned cwd
|
|
137
|
+
// outside the root, violating the §5.5 containment invariant.
|
|
138
|
+
const st = await lstat(wsPath);
|
|
139
|
+
if (st.isSymbolicLink()) {
|
|
140
|
+
throw new WorkspaceError('workspace_path_is_symlink', `workspace path ${wsPath} is a symlink; refusing to use`);
|
|
141
|
+
}
|
|
142
|
+
if (!st.isDirectory()) {
|
|
143
|
+
throw new WorkspaceError('workspace_path_not_directory', `expected directory at ${wsPath}, found a non-directory`);
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
if (err.code === 'ENOENT') {
|
|
149
|
+
await mkdir(wsPath, { recursive: true });
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function doEnsureFor(deps, git, identifier, opts) {
|
|
156
|
+
// Read the LIVE workspace root so a hot-reloaded workspace.root retargets here.
|
|
157
|
+
const root = deps.root();
|
|
158
|
+
await mkdir(root, { recursive: true });
|
|
159
|
+
const wsPath = workspacePathFor(root, identifier);
|
|
160
|
+
deps.assertContained(root, wsPath);
|
|
161
|
+
const createdNow = await ensureDirExists(wsPath);
|
|
162
|
+
if (createdNow) {
|
|
163
|
+
try {
|
|
164
|
+
await setup(deps, git, wsPath, opts.baseBranch, `agent/${identifier}`, opts.githubRepo);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
// Best-effort unwind so the next dispatch tick retries cleanly.
|
|
168
|
+
await rm(wsPath, { recursive: true, force: true }).catch(() => undefined);
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return { path: wsPath, created: createdNow };
|
|
173
|
+
}
|
|
174
|
+
// git inspection of one workspace for drift detection (workspace-defaults.ts
|
|
175
|
+
// defaultInspectWorkspace). HEAD-less / non-repo dirs return a null head so the
|
|
176
|
+
// janitor treats them as "don't touch". All git is workspace-local.
|
|
177
|
+
async function inspect(git, workspacePath, baseBranch) {
|
|
178
|
+
const head = await git.run(['rev-parse', 'HEAD'], workspacePath);
|
|
179
|
+
if (head.exit_code !== 0 || head.stdout.trim().length === 0) {
|
|
180
|
+
return { head: null, workspaceBaseSha: null, hasUncommitted: false, commitsAheadOfBase: 0 };
|
|
181
|
+
}
|
|
182
|
+
const headSha = head.stdout.trim();
|
|
183
|
+
const status = await git.run(['status', '--porcelain'], workspacePath);
|
|
184
|
+
const hasUncommitted = status.exit_code === 0 && status.stdout.length > 0;
|
|
185
|
+
const wsBase = await git.run(['rev-parse', baseBranch], workspacePath);
|
|
186
|
+
const workspaceBaseSha = wsBase.exit_code === 0 && wsBase.stdout.trim().length > 0 ? wsBase.stdout.trim() : null;
|
|
187
|
+
let aheadCount = 0;
|
|
188
|
+
if (workspaceBaseSha !== null) {
|
|
189
|
+
// `<base>..HEAD` walks only objects the workspace owns. Malformed-ref
|
|
190
|
+
// non-zero → 0 ahead rather than poisoning the snapshot.
|
|
191
|
+
const ahead = await git.run(['rev-list', '--count', `${workspaceBaseSha}..${headSha}`], workspacePath);
|
|
192
|
+
aheadCount = ahead.exit_code === 0 ? Number(ahead.stdout.trim()) || 0 : 0;
|
|
193
|
+
}
|
|
194
|
+
return { head: headSha, workspaceBaseSha, hasUncommitted, commitsAheadOfBase: aheadCount };
|
|
195
|
+
}
|
|
196
|
+
// Enumerate workspace dirs under root (workspace-defaults.ts
|
|
197
|
+
// defaultListWorkspaceDirs). Non-directories filtered out; ENOENT on root →
|
|
198
|
+
// empty (cold start). Other errors propagate (don't reap on a transient hiccup).
|
|
199
|
+
async function listDirs(root) {
|
|
200
|
+
let entries;
|
|
201
|
+
try {
|
|
202
|
+
entries = await readdir(root);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
if (err.code === 'ENOENT')
|
|
206
|
+
return [];
|
|
207
|
+
throw err;
|
|
208
|
+
}
|
|
209
|
+
const out = [];
|
|
210
|
+
for (const name of entries) {
|
|
211
|
+
const p = path.join(root, name);
|
|
212
|
+
try {
|
|
213
|
+
const st = await stat(p);
|
|
214
|
+
if (st.isDirectory())
|
|
215
|
+
out.push({ name, path: p });
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// Entry vanished mid-pass; next reconcile picks it up.
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Build the workspace adapter. Returns the {@link WorkspacePort} the central
|
|
225
|
+
* effect-interpreter drains the `workspace` family through. A per-identifier
|
|
226
|
+
* in-flight promise map coalesces concurrent `ensureFor` calls (dispatch runner
|
|
227
|
+
* + reconciler eager-create) into one `git clone --local` so they don't race on
|
|
228
|
+
* the same dir; the entry is removed in a `finally` so a re-dispatch re-enters.
|
|
229
|
+
*/
|
|
230
|
+
export function createWorkspaceAdapter(deps) {
|
|
231
|
+
const git = gitRunners(deps.process);
|
|
232
|
+
const ensureInFlight = new Map();
|
|
233
|
+
return {
|
|
234
|
+
workspacePathFor: (identifier) => workspacePathFor(deps.root(), identifier),
|
|
235
|
+
workspaceKeyFor: sanitizeWorkspaceKey,
|
|
236
|
+
// Coalesce concurrent ensureFor for the same identifier into one setup pass.
|
|
237
|
+
// Key by the LIVE root + sanitized identifier: a WORKFLOW.yaml hot-reload that
|
|
238
|
+
// moves workspace.root mid-clone must NOT let a fresh ensureFor(id) reuse the
|
|
239
|
+
// stale promise still cloning into the OLD root — that would return a path
|
|
240
|
+
// under the wrong root. Including the live root in the key starts a fresh
|
|
241
|
+
// in-flight entry whenever the root changes (and the finally-delete uses the
|
|
242
|
+
// same captured key so the right entry is cleared).
|
|
243
|
+
async ensureFor(identifier, opts) {
|
|
244
|
+
const key = `${deps.root()}\0${sanitizeWorkspaceKey(identifier)}`;
|
|
245
|
+
const existing = ensureInFlight.get(key);
|
|
246
|
+
if (existing)
|
|
247
|
+
return existing;
|
|
248
|
+
const p = doEnsureFor(deps, git, identifier, opts);
|
|
249
|
+
ensureInFlight.set(key, p);
|
|
250
|
+
try {
|
|
251
|
+
return await p;
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
ensureInFlight.delete(key);
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
// Per-dispatch fetch of the workspace's base ref so the in-VM `git rebase
|
|
258
|
+
// origin/<base>` sees a current ref (workspace.ts fetchBaseInWorkspace). No-op
|
|
259
|
+
// when there's no origin (local-only). Throws on a configured-origin fetch
|
|
260
|
+
// failure so the caller aborts rather than launching against a stale ref.
|
|
261
|
+
async fetchBaseInWorkspace(workspacePath, baseBranch) {
|
|
262
|
+
const remoteCheck = await git.run(['remote', 'get-url', 'origin'], workspacePath);
|
|
263
|
+
if (remoteCheck.exit_code !== 0)
|
|
264
|
+
return; // local-only: nothing to fetch
|
|
265
|
+
const fetched = await git.run(['fetch', '--no-tags', 'origin', baseBranch], workspacePath, NO_PROMPT_ENV);
|
|
266
|
+
if (fetched.exit_code !== 0) {
|
|
267
|
+
throw new WorkspaceError('workspace_fetch_base_failed', `git fetch origin ${baseBranch} failed (exit ${fetched.exit_code}): ${(fetched.stderr || fetched.stdout).trim()}`);
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
// Best-effort fs removal of the per-issue dir. A symlink/non-directory at the
|
|
271
|
+
// path is a no-op (containment safety). `reason` is carried for the run log.
|
|
272
|
+
async remove(identifier, _reason) {
|
|
273
|
+
const root = deps.root();
|
|
274
|
+
const wsPath = workspacePathFor(root, identifier);
|
|
275
|
+
deps.assertContained(root, wsPath);
|
|
276
|
+
try {
|
|
277
|
+
const st = await lstat(wsPath);
|
|
278
|
+
if (st.isSymbolicLink() || !st.isDirectory())
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return; // ENOENT etc. → already gone
|
|
283
|
+
}
|
|
284
|
+
await rm(wsPath, { recursive: true, force: true });
|
|
285
|
+
},
|
|
286
|
+
inspect: (workspacePath, baseBranch) => inspect(git, workspacePath, baseBranch),
|
|
287
|
+
list: () => listDirs(deps.root()),
|
|
288
|
+
// Drop the handoff-pending marker into the per-issue dir (issue 234). Resolved +
|
|
289
|
+
// containment-guarded like remove(); the reason is the body so manual recovery
|
|
290
|
+
// can read why the push failed. No-op if the dir vanished (best-effort).
|
|
291
|
+
async markHandoffPending(identifier, reason) {
|
|
292
|
+
const root = deps.root();
|
|
293
|
+
const wsPath = workspacePathFor(root, identifier);
|
|
294
|
+
deps.assertContained(root, wsPath);
|
|
295
|
+
await writeFile(path.join(wsPath, HANDOFF_PENDING_MARKER), `${reason}\n`, 'utf8');
|
|
296
|
+
},
|
|
297
|
+
// Stat the marker for the janitor's retention gate. Any access error (ENOENT,
|
|
298
|
+
// the dir gone) reads as "no marker" → the dir reaps as today.
|
|
299
|
+
async hasHandoffPendingMarker(workspacePath) {
|
|
300
|
+
try {
|
|
301
|
+
await access(path.join(workspacePath, HANDOFF_PENDING_MARKER));
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/shell/interp/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// FCIS rewrite — ACP-substrate construction for the composition root (kind: shell).
|
|
2
|
+
//
|
|
3
|
+
// Builds the REAL {@link AcpPort} (createAcpInterpreter, shell/interp/acp.ts) over
|
|
4
|
+
// the `/acp` WebSocket, replacing the placeholderAcp() stub. The interpreter binds
|
|
5
|
+
// to the SAME {@link AcpWsRegistry} the unified HTTP server exposes on the `/acp`
|
|
6
|
+
// Upgrade (passed in as `input.registry` = a.acpWs from buildConcreteAdapters), so
|
|
7
|
+
// a guest dial-back resolves the Duplex the host SDK drives.
|
|
8
|
+
//
|
|
9
|
+
// The interpreter resolves `vmId → dispatch context` through a small mutable
|
|
10
|
+
// DISPATCH-CONTEXT registry the runner slice populates at per-dispatch bring-up:
|
|
11
|
+
// constructed empty here (no dispatch active until the runner registers one) and
|
|
12
|
+
// returned alongside the port so the runner slice can wire it.
|
|
13
|
+
//
|
|
14
|
+
// Core-free: imports src/types + sibling shell only — the pure `toolCallLifecycle`
|
|
15
|
+
// decider arrives injected via `input.core` (only the composition root imports core).
|
|
16
|
+
import { createAcpInterpreter } from './interp/acp.js';
|
|
17
|
+
/** The mutable per-dispatch context registry (runner writes; ACP interpreter reads). */
|
|
18
|
+
function createDispatchContextRegistry() {
|
|
19
|
+
const byVm = new Map();
|
|
20
|
+
return {
|
|
21
|
+
register: (vmId, ctx) => {
|
|
22
|
+
byVm.set(vmId, ctx);
|
|
23
|
+
},
|
|
24
|
+
deregister: (vmId) => {
|
|
25
|
+
byVm.delete(vmId);
|
|
26
|
+
},
|
|
27
|
+
contextForVm: (vmId) => byVm.get(vmId),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Construct the real ACP substrate. The returned `port` is the live AcpPort wired
|
|
32
|
+
* into the EffectAdapters bundle; `context` is the registry the runner slice
|
|
33
|
+
* populates so `sessionNew(vmId)` can resolve the dispatch's issue / workspace /
|
|
34
|
+
* MCP-server set. The `mcpServersFor` seam reads the SAME registry the runner
|
|
35
|
+
* populated (per-dispatch MCP servers), defaulting to none when MCP is disabled.
|
|
36
|
+
*/
|
|
37
|
+
export function buildAcpSubstrate(input) {
|
|
38
|
+
const context = createDispatchContextRegistry();
|
|
39
|
+
const port = createAcpInterpreter({
|
|
40
|
+
toolCallLifecycle: input.core.toolCallLifecycle,
|
|
41
|
+
isTransportError: input.core.isTransportError,
|
|
42
|
+
selectPermissionOption: input.core.selectPermissionOption,
|
|
43
|
+
// vmId → the per-dispatch ACP context captured at bring-up (runner-populated):
|
|
44
|
+
// the issue/workspace identity AND the dial-back `accepted` stream of the WS
|
|
45
|
+
// registration the runner created BEFORE launch (token → launch env). The
|
|
46
|
+
// interpreter CONSUMES `accepted` in sessionNew — it never registers again.
|
|
47
|
+
contextForVm: (vmId) => {
|
|
48
|
+
const ctx = context.contextForVm(vmId);
|
|
49
|
+
return ctx
|
|
50
|
+
? {
|
|
51
|
+
issueId: ctx.issueId,
|
|
52
|
+
identifier: ctx.identifier,
|
|
53
|
+
workspacePath: ctx.workspacePath,
|
|
54
|
+
accepted: ctx.accepted,
|
|
55
|
+
cancelAccept: ctx.cancelAccept,
|
|
56
|
+
}
|
|
57
|
+
: undefined;
|
|
58
|
+
},
|
|
59
|
+
// The per-dispatch MCP server set (registered alongside the context); when the
|
|
60
|
+
// dispatch ran with mcp disabled OR no context is registered, expose none.
|
|
61
|
+
mcpServersFor: (vmId, opts) => {
|
|
62
|
+
if (!opts.mcpEnabled)
|
|
63
|
+
return [];
|
|
64
|
+
return context.contextForVm(vmId)?.mcpServers ?? [];
|
|
65
|
+
},
|
|
66
|
+
runlog: input.runlog,
|
|
67
|
+
readTimeoutMs: input.readTimeoutMs(),
|
|
68
|
+
promptTimeoutMs: input.promptTimeoutMs(),
|
|
69
|
+
connectTimeoutMs: input.connectTimeoutMs(),
|
|
70
|
+
iso: () => input.clock.iso(),
|
|
71
|
+
});
|
|
72
|
+
// Expose the host `/acp` WS registry so the runner slice can `register(issueId,
|
|
73
|
+
// identifier)` EARLY — before the agent launches — and thread the returned token
|
|
74
|
+
// into the launch env. (Was previously consumed only here for the late, racy
|
|
75
|
+
// in-sessionNew registration.)
|
|
76
|
+
return { port, context, registry: input.registry };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=main-acp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main-acp.js","sourceRoot":"","sources":["../../src/shell/main-acp.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,EAAE;AACF,mFAAmF;AACnF,mFAAmF;AACnF,kFAAkF;AAClF,mFAAmF;AACnF,6DAA6D;AAC7D,EAAE;AACF,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,+DAA+D;AAC/D,EAAE;AACF,mFAAmF;AACnF,sFAAsF;AAStF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,wFAAwF;AACxF,SAAS,6BAA6B;IACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAA8B,CAAC;IACnD,OAAO;QACL,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACtB,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtB,CAAC;QACD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;YACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;KACvC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAwB;IACxD,MAAM,OAAO,GAAG,6BAA6B,EAAE,CAAC;IAEhD,MAAM,IAAI,GAAG,oBAAoB,CAAC;QAChC,iBAAiB,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB;QAC/C,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB;QAC7C,sBAAsB,EAAE,KAAK,CAAC,IAAI,CAAC,sBAAsB;QACzD,+EAA+E;QAC/E,6EAA6E;QAC7E,0EAA0E;QAC1E,4EAA4E;QAC5E,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACvC,OAAO,GAAG;gBACR,CAAC,CAAC;oBACE,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,aAAa,EAAE,GAAG,CAAC,aAAa;oBAChC,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,YAAY,EAAE,GAAG,CAAC,YAAY;iBAC/B;gBACH,CAAC,CAAC,SAAS,CAAC;QAChB,CAAC;QACD,+EAA+E;QAC/E,2EAA2E;QAC3E,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAe,EAAE;YACzC,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,OAAO,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC;QACtD,CAAC;QACD,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;QACpC,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE;QACxC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE;QAC1C,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;KAC7B,CAAC,CAAC;IAEH,gFAAgF;IAChF,iFAAiF;IACjF,6EAA6E;IAC7E,+BAA+B;IAC/B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
// FCIS rewrite — adapter construction for the composition root (kind: shell).
|
|
2
|
+
//
|
|
3
|
+
// Sliced out of src/shell/main.ts so the root keeps only the core-wiring under
|
|
4
|
+
// the max-lines budget. This module constructs the resolvable adapters + the
|
|
5
|
+
// deterministic seams and folds them into the EffectAdapters bundle the central
|
|
6
|
+
// interpreter routes through. It imports NO core (only the root may) — every
|
|
7
|
+
// pure decider arrives already injected by the root.
|
|
8
|
+
//
|
|
9
|
+
// The real ACP client (main-acp.ts: createAcpInterpreter over the `/acp`
|
|
10
|
+
// WebSocket) + the host-only credential adapter (main-credential.ts:
|
|
11
|
+
// GondolinCredentialAdapter) are now LIVE: the root builds each substrate and
|
|
12
|
+
// injects the resolved port here. The remaining heavy / stateful sub-vocabularies
|
|
13
|
+
// (the live runner pipeline, PR autopilot, VM-reaper fold) are owned by their own
|
|
14
|
+
// shell slices and wired by the root once those slices stabilize; here they
|
|
15
|
+
// surface a clean `{ ok:false }` / honest fallback so the interpreter stays total
|
|
16
|
+
// and the scheduler reducer drains end-to-end while they land. The MCP runtime's
|
|
17
|
+
// `mcp_tool`-family applier (`applyMcpEffect`) IS wired now (main-mcp.ts); the
|
|
18
|
+
// root injects it so it shares the tracker move/write IO with the live runtime.
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
import process from 'node:process';
|
|
21
|
+
import { mkdir, readdir, rm, stat, writeFile, readFile, access } from 'node:fs/promises';
|
|
22
|
+
import { systemClock, tokenRandomSource, nodeCryptoEnv, nodeMemProbe } from './adapter/clock-random.js';
|
|
23
|
+
import { setLogFile } from './interp/log.js';
|
|
24
|
+
import { createProcessRunner, createProcessSignalPort } from './interp/process.js';
|
|
25
|
+
import { createTimerPort } from './interp/timer.js';
|
|
26
|
+
import { createGitAdapter } from './interp/git.js';
|
|
27
|
+
import { GhCliPort } from './interp/gh.js';
|
|
28
|
+
import { GondolinVmClient } from './interp/vm.js';
|
|
29
|
+
import { createTrackerAdapter } from './interp/tracker.js';
|
|
30
|
+
import { createWorkspaceAdapter } from './interp/workspace.js';
|
|
31
|
+
import { FsRunLogStore } from './interp/runlog.js';
|
|
32
|
+
import { AcpWsRegistry } from './interp/acp-ws.js';
|
|
33
|
+
/** Resolve the persistent log-file path: env override > <logs.root>/symphony.log. */
|
|
34
|
+
export function resolveLogFile(envLogFile, cfg) {
|
|
35
|
+
if (envLogFile === undefined)
|
|
36
|
+
return path.join(cfg.logs.root, 'symphony.log');
|
|
37
|
+
return envLogFile === '' ? null : envLogFile;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Point the persistent log sink at the resolved file for `cfg` and return a
|
|
41
|
+
* `retarget` closure for reloads. The startup banner names the file once; on a
|
|
42
|
+
* WORKFLOW.yaml edit the sink only moves when the resolved target actually
|
|
43
|
+
* changed (a `logs.root` edit with no SYMPHONY_LOG_FILE override — the override
|
|
44
|
+
* pins the path), and we print one short stdout line so the operator sees the new
|
|
45
|
+
* destination. Steady-state reloads stay silent.
|
|
46
|
+
*/
|
|
47
|
+
export function wireLogSink(envLogFile, cfg) {
|
|
48
|
+
let current = resolveLogFile(envLogFile, cfg);
|
|
49
|
+
setLogFile(current);
|
|
50
|
+
return (next) => {
|
|
51
|
+
const nextFile = resolveLogFile(envLogFile, next);
|
|
52
|
+
if (nextFile === current)
|
|
53
|
+
return;
|
|
54
|
+
current = nextFile;
|
|
55
|
+
setLogFile(nextFile);
|
|
56
|
+
if (nextFile !== null)
|
|
57
|
+
process.stdout.write(`reloaded; logs → ${nextFile}\n`);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Construct the resolvable adapters + the four deterministic seams. `getCfg` is
|
|
62
|
+
* read lazily so each adapter sees the live (reloaded) config; `log` is the
|
|
63
|
+
* already-built structured sink.
|
|
64
|
+
*/
|
|
65
|
+
export function buildConcreteAdapters(getCfg, log, resolveIssueMatch, core) {
|
|
66
|
+
const proc = createProcessRunner();
|
|
67
|
+
return {
|
|
68
|
+
clock: systemClock(),
|
|
69
|
+
random: tokenRandomSource(),
|
|
70
|
+
crypto: nodeCryptoEnv(),
|
|
71
|
+
mem: nodeMemProbe(core.parseMemAvailableMib),
|
|
72
|
+
process: proc,
|
|
73
|
+
signal: createProcessSignalPort(),
|
|
74
|
+
timer: createTimerPort(),
|
|
75
|
+
git: createGitAdapter({ process: proc }),
|
|
76
|
+
gh: new GhCliPort(proc, { repoSlug: () => getCfg().workspace.github_repo }),
|
|
77
|
+
vm: new GondolinVmClient(),
|
|
78
|
+
tracker: createTrackerAdapter({
|
|
79
|
+
config: () => getCfg().tracker,
|
|
80
|
+
log,
|
|
81
|
+
resolveMatch: resolveIssueMatch,
|
|
82
|
+
composeIssueFile: core.composeIssueFile,
|
|
83
|
+
pickNextNumericIdentifier: core.pickNextNumericIdentifier,
|
|
84
|
+
}),
|
|
85
|
+
workspace: createWorkspaceAdapter({
|
|
86
|
+
// LIVE closures (not boot snapshots) so a WORKFLOW.yaml hot-reload that moves
|
|
87
|
+
// workspace.root / workflow_dir retargets create/list/remove (finding #3).
|
|
88
|
+
// SYMPHONY_SOURCE_REPO still wins when set (a static env override).
|
|
89
|
+
root: () => getCfg().workspace.root,
|
|
90
|
+
sourceRepo: () => process.env.SYMPHONY_SOURCE_REPO ?? getCfg().workflow_dir,
|
|
91
|
+
process: proc,
|
|
92
|
+
assertContained: core.assertContained,
|
|
93
|
+
}),
|
|
94
|
+
runlog: new FsRunLogStore(log),
|
|
95
|
+
acpWs: new AcpWsRegistry({ log }),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Assemble the EffectAdapters bundle the central interpreter routes through. The
|
|
100
|
+
* resolvable adapters pass straight through; the remaining sub-vocabulary
|
|
101
|
+
* families are honest fallbacks (see file header) until their owning slice wires
|
|
102
|
+
* them through the root.
|
|
103
|
+
*/
|
|
104
|
+
export function buildEffectAdapters(deps) {
|
|
105
|
+
const diskTracker = {
|
|
106
|
+
listIssues: (root) => deps.tracker.listIssues(root),
|
|
107
|
+
readIssue: (root, identifier) => deps.tracker.readIssue(root, identifier),
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
tracker: deps.tracker,
|
|
111
|
+
diskTracker,
|
|
112
|
+
vm: deps.vm,
|
|
113
|
+
// The runner slice owns the live vmId→VmHandle table; no live attempts run
|
|
114
|
+
// through the root yet, so no handle resolves.
|
|
115
|
+
vmHandleFor: () => undefined,
|
|
116
|
+
// The REAL ACP port (over the `/acp` WebSocket) + host-only credential port,
|
|
117
|
+
// built in the main-acp / main-credential substrates and injected by the root.
|
|
118
|
+
acp: deps.acp,
|
|
119
|
+
git: deps.git,
|
|
120
|
+
gh: deps.gh,
|
|
121
|
+
classifyPushResult: deps.classifyPushResult,
|
|
122
|
+
parsePrNumberFromUrl: deps.parsePrNumberFromUrl,
|
|
123
|
+
fs: nodeIssueFs(),
|
|
124
|
+
workspace: deps.workspace,
|
|
125
|
+
credential: deps.credential,
|
|
126
|
+
log: deps.log,
|
|
127
|
+
runlog: deps.runlog,
|
|
128
|
+
timer: deps.timer,
|
|
129
|
+
signal: deps.signal,
|
|
130
|
+
process: deps.process,
|
|
131
|
+
// <logsRoot>/<identifier>.jsonl (REF sanitizeWorkspaceKey → file path).
|
|
132
|
+
runlogPathFor: (_issueId, identifier) => path.join(deps.logsRoot(), `${identifier}.jsonl`),
|
|
133
|
+
// PR autopilot + VM reaper appliers: the reconciler slice owns them (the PR
|
|
134
|
+
// pass + the SIGTERM→…→SIGKILL escalation drive the same instances). The root
|
|
135
|
+
// injects them here so a core-emitted `pr`/`reaper` Effect shares pass state;
|
|
136
|
+
// an honest fallback covers the (unwired) case so the interpreter stays total.
|
|
137
|
+
applyPrEffect: deps.applyPrEffect ?? (async () => ({ ok: false, error: 'pr autopilot not wired in composition root' })),
|
|
138
|
+
applyMcpEffect: deps.applyMcpEffect ?? (async () => ({ kind: 'move_failed', message: 'mcp runtime not wired in composition root' })),
|
|
139
|
+
// The `steering` family resolves/cancels the per-issue awaiter (the ONE live
|
|
140
|
+
// Promise); the root injects McpRuntime's so a steering Effect lands it.
|
|
141
|
+
steering: deps.steering,
|
|
142
|
+
// The `mcp` family activates/deactivates the per-dispatch active entry; the root
|
|
143
|
+
// injects the live McpRuntime so the runner's bracket effect mints/tears it down.
|
|
144
|
+
mcpLifecycle: deps.mcpLifecycle,
|
|
145
|
+
applyKillStep: deps.applyKillStep ?? (async () => ({ kind: 'gone' })),
|
|
146
|
+
ttyPromptLine: async (question) => {
|
|
147
|
+
const { promptLine } = await import('./interp/tty.js');
|
|
148
|
+
return promptLine(question);
|
|
149
|
+
},
|
|
150
|
+
ttyWrite: (text) => process.stdout.write(text),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Real node:fs/promises-backed IssueFs (issue files + predicate file_present
|
|
155
|
+
* probes + action body staging). The thin port the interpreter's fs family
|
|
156
|
+
* routes through; lives here rather than its own interp slice while that slice
|
|
157
|
+
* is unsliced.
|
|
158
|
+
*/
|
|
159
|
+
export function nodeIssueFs() {
|
|
160
|
+
return {
|
|
161
|
+
mkdir: async (p, opts) => {
|
|
162
|
+
await mkdir(p, { recursive: opts.recursive });
|
|
163
|
+
},
|
|
164
|
+
readdir: (p) => readdir(p),
|
|
165
|
+
stat: async (p) => {
|
|
166
|
+
const st = await stat(p);
|
|
167
|
+
return { isDirectory: () => st.isDirectory() };
|
|
168
|
+
},
|
|
169
|
+
writeFile: (p, data, encoding) => writeFile(p, data, encoding),
|
|
170
|
+
readFile: (p, encoding) => readFile(p, encoding),
|
|
171
|
+
rm: (p, opts) => rm(p, { recursive: opts.recursive, force: opts.force }),
|
|
172
|
+
access: (p) => access(p)
|
|
173
|
+
.then(() => true)
|
|
174
|
+
.catch(() => false),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Minimal real RunningEntry the loop fills in until the runner slice supplies the
|
|
179
|
+
* pinned one (workspace path, pinned dispatch config, …). Carries the live
|
|
180
|
+
* `cancel` closure + the `active_tool_calls` Set the loop driver mutates directly.
|
|
181
|
+
*/
|
|
182
|
+
export function buildPlaceholderEntry(plan, cancel) {
|
|
183
|
+
const issue = plan.issue;
|
|
184
|
+
return {
|
|
185
|
+
issue_id: issue.id,
|
|
186
|
+
identifier: issue.identifier,
|
|
187
|
+
issue,
|
|
188
|
+
session_id: null,
|
|
189
|
+
thread_id: null,
|
|
190
|
+
turn_id: null,
|
|
191
|
+
adapter_pid: null,
|
|
192
|
+
last_event: null,
|
|
193
|
+
last_event_at: null,
|
|
194
|
+
last_message: null,
|
|
195
|
+
input_tokens: 0,
|
|
196
|
+
output_tokens: 0,
|
|
197
|
+
total_tokens: 0,
|
|
198
|
+
last_reported_input_tokens: 0,
|
|
199
|
+
last_reported_output_tokens: 0,
|
|
200
|
+
last_reported_total_tokens: 0,
|
|
201
|
+
turn_count: 0,
|
|
202
|
+
retry_attempt: plan.attempt,
|
|
203
|
+
started_at: new Date().toISOString(),
|
|
204
|
+
workspace_path: '',
|
|
205
|
+
cancel,
|
|
206
|
+
recent_events: [],
|
|
207
|
+
last_error: null,
|
|
208
|
+
cleanup_workspace_on_exit: false,
|
|
209
|
+
mcp_token: null,
|
|
210
|
+
tracker_root_at_dispatch: plan.trackerRoot,
|
|
211
|
+
github_repo_at_dispatch: null,
|
|
212
|
+
base_branch_at_dispatch: '',
|
|
213
|
+
resolved_actor: '',
|
|
214
|
+
transitioned: false,
|
|
215
|
+
steering_requested: false,
|
|
216
|
+
steering_question: null,
|
|
217
|
+
steering_context: null,
|
|
218
|
+
active_tool_calls: new Set(),
|
|
219
|
+
last_transition: null,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=main-adapters.js.map
|