smol-symphony 0.2.0 → 0.3.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/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/src/bin/symphony.js +30 -0
- package/dist/src/bin/symphony.js.map +1 -0
- package/dist/src/core/actions/context.js +109 -0
- package/dist/src/core/actions/context.js.map +1 -0
- package/dist/{actions/parsing.js → src/core/actions/parse.js} +33 -114
- package/dist/src/core/actions/parse.js.map +1 -0
- package/dist/src/core/actions/plan.js +197 -0
- package/dist/src/core/actions/plan.js.map +1 -0
- package/dist/src/core/actions/predicates.js +111 -0
- package/dist/src/core/actions/predicates.js.map +1 -0
- package/dist/src/core/actions/run-fold.js +248 -0
- package/dist/src/core/actions/run-fold.js.map +1 -0
- package/dist/src/core/actions/template.js +118 -0
- package/dist/src/core/actions/template.js.map +1 -0
- package/dist/src/core/cli/args.js +116 -0
- package/dist/src/core/cli/args.js.map +1 -0
- package/dist/src/core/coerce.js +75 -0
- package/dist/src/core/coerce.js.map +1 -0
- package/dist/src/core/credential/account-id.js +20 -0
- package/dist/src/core/credential/account-id.js.map +1 -0
- package/dist/src/core/credential/adapter-config.js +136 -0
- package/dist/src/core/credential/adapter-config.js.map +1 -0
- package/dist/src/core/credential/availability.js +98 -0
- package/dist/src/core/credential/availability.js.map +1 -0
- package/dist/src/core/credential/extract.js +228 -0
- package/dist/src/core/credential/extract.js.map +1 -0
- package/dist/src/core/credential/fake-creds.js +171 -0
- package/dist/src/core/credential/fake-creds.js.map +1 -0
- package/dist/src/core/credential/identity.js +125 -0
- package/dist/src/core/credential/identity.js.map +1 -0
- package/dist/src/core/credential/shape.js +230 -0
- package/dist/src/core/credential/shape.js.map +1 -0
- package/dist/src/core/credential/strings.js +15 -0
- package/dist/src/core/credential/strings.js.map +1 -0
- package/dist/src/core/doctor/checks.js +303 -0
- package/dist/src/core/doctor/checks.js.map +1 -0
- package/dist/src/core/git/result.js +107 -0
- package/dist/src/core/git/result.js.map +1 -0
- package/dist/src/core/http/decisions.js +225 -0
- package/dist/src/core/http/decisions.js.map +1 -0
- package/dist/{http.js → src/core/http/render.js} +472 -738
- package/dist/src/core/http/render.js.map +1 -0
- package/dist/{http-handlers.js → src/core/http/routes.js} +52 -87
- package/dist/src/core/http/routes.js.map +1 -0
- package/dist/src/core/http/views.js +181 -0
- package/dist/src/core/http/views.js.map +1 -0
- package/dist/src/core/image/managed-image.js +95 -0
- package/dist/src/core/image/managed-image.js.map +1 -0
- package/dist/src/core/issue/file.js +149 -0
- package/dist/src/core/issue/file.js.map +1 -0
- package/dist/src/core/issue/parse.js +210 -0
- package/dist/src/core/issue/parse.js.map +1 -0
- package/dist/src/core/mcp/dispatch.js +239 -0
- package/dist/src/core/mcp/dispatch.js.map +1 -0
- package/dist/src/core/mcp/post-move.js +92 -0
- package/dist/src/core/mcp/post-move.js.map +1 -0
- package/dist/src/core/mcp/protocol.js +293 -0
- package/dist/src/core/mcp/protocol.js.map +1 -0
- package/dist/src/core/mcp/url.js +162 -0
- package/dist/src/core/mcp/url.js.map +1 -0
- package/dist/src/core/path.js +63 -0
- package/dist/src/core/path.js.map +1 -0
- package/dist/src/core/reconcile/image-decide.js +48 -0
- package/dist/src/core/reconcile/image-decide.js.map +1 -0
- package/dist/src/core/reconcile/ledger.js +142 -0
- package/dist/src/core/reconcile/ledger.js.map +1 -0
- package/dist/src/core/reconcile/pr-classify.js +62 -0
- package/dist/src/core/reconcile/pr-classify.js.map +1 -0
- package/dist/{reconciler → src/core/reconcile}/pr-decide.js +25 -12
- package/dist/src/core/reconcile/pr-decide.js.map +1 -0
- package/dist/src/core/reconcile/pr-loop.js +161 -0
- package/dist/src/core/reconcile/pr-loop.js.map +1 -0
- package/dist/src/core/reconcile/pr-notes.js +35 -0
- package/dist/src/core/reconcile/pr-notes.js.map +1 -0
- package/dist/src/core/reconcile/vm-decide.js +70 -0
- package/dist/src/core/reconcile/vm-decide.js.map +1 -0
- package/dist/src/core/reconcile/vm-reap.js +207 -0
- package/dist/src/core/reconcile/vm-reap.js.map +1 -0
- package/dist/src/core/reconcile/workspace-decide.js +162 -0
- package/dist/src/core/reconcile/workspace-decide.js.map +1 -0
- package/dist/src/core/runlog/summary.js +231 -0
- package/dist/src/core/runlog/summary.js.map +1 -0
- package/dist/src/core/runner/dispatch-config.js +95 -0
- package/dist/src/core/runner/dispatch-config.js.map +1 -0
- package/dist/src/core/runner/injection.js +61 -0
- package/dist/src/core/runner/injection.js.map +1 -0
- package/dist/src/core/runner/mise.js +210 -0
- package/dist/src/core/runner/mise.js.map +1 -0
- package/dist/src/core/runner/prompt.js +720 -0
- package/dist/src/core/runner/prompt.js.map +1 -0
- package/dist/src/core/runner/turn.js +242 -0
- package/dist/src/core/runner/turn.js.map +1 -0
- package/dist/src/core/runner/vm-plan.js +390 -0
- package/dist/src/core/runner/vm-plan.js.map +1 -0
- package/dist/src/core/schedule/admission.js +123 -0
- package/dist/src/core/schedule/admission.js.map +1 -0
- package/dist/src/core/schedule/circuit-breaker.js +111 -0
- package/dist/src/core/schedule/circuit-breaker.js.map +1 -0
- package/dist/src/core/schedule/eligibility.js +83 -0
- package/dist/src/core/schedule/eligibility.js.map +1 -0
- package/dist/src/core/schedule/reconcile-issue.js +82 -0
- package/dist/src/core/schedule/reconcile-issue.js.map +1 -0
- package/dist/src/core/schedule/retry.js +96 -0
- package/dist/src/core/schedule/retry.js.map +1 -0
- package/dist/src/core/schedule/sleep-cycle.js +133 -0
- package/dist/src/core/schedule/sleep-cycle.js.map +1 -0
- package/dist/src/core/schedule/slots.js +124 -0
- package/dist/src/core/schedule/slots.js.map +1 -0
- package/dist/src/core/schedule/tick.js +553 -0
- package/dist/src/core/schedule/tick.js.map +1 -0
- package/dist/src/core/schedule/token-fold.js +181 -0
- package/dist/src/core/schedule/token-fold.js.map +1 -0
- package/dist/src/core/state-resolve.js +86 -0
- package/dist/src/core/state-resolve.js.map +1 -0
- package/dist/src/core/vm-guards.js +278 -0
- package/dist/src/core/vm-guards.js.map +1 -0
- package/dist/src/core/workflow/derive.js +107 -0
- package/dist/src/core/workflow/derive.js.map +1 -0
- package/dist/src/core/workflow/parse.js +687 -0
- package/dist/src/core/workflow/parse.js.map +1 -0
- package/dist/src/core/workflow/prompt-probe.js +78 -0
- package/dist/src/core/workflow/prompt-probe.js.map +1 -0
- package/dist/src/core/workflow/validate.js +189 -0
- package/dist/src/core/workflow/validate.js.map +1 -0
- package/dist/src/core/workspace-key.js +19 -0
- package/dist/src/core/workspace-key.js.map +1 -0
- package/dist/src/shell/actions-runner.js +356 -0
- package/dist/src/shell/actions-runner.js.map +1 -0
- package/dist/src/shell/adapter/adapter-registry.js +45 -0
- package/dist/src/shell/adapter/adapter-registry.js.map +1 -0
- package/dist/src/shell/adapter/clock-random.js +96 -0
- package/dist/src/shell/adapter/clock-random.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-dispatch-helpers.js +158 -0
- package/dist/src/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-dispatch.js +385 -0
- package/dist/src/shell/adapter/gondolin-dispatch.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-image-converter.js +233 -0
- package/dist/src/shell/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-image-fetch.js +180 -0
- package/dist/src/shell/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/src/shell/adapter/launcher-asset.js +57 -0
- package/dist/src/shell/adapter/launcher-asset.js.map +1 -0
- package/dist/src/shell/adapter/mise-config-asset.js +65 -0
- package/dist/src/shell/adapter/mise-config-asset.js.map +1 -0
- package/dist/src/shell/adapter/workflow-loader.js +304 -0
- package/dist/src/shell/adapter/workflow-loader.js.map +1 -0
- package/dist/src/shell/cli/doctor.js +268 -0
- package/dist/src/shell/cli/doctor.js.map +1 -0
- package/dist/src/shell/effect-interpreter-families.js +314 -0
- package/dist/src/shell/effect-interpreter-families.js.map +1 -0
- package/dist/src/shell/effect-interpreter.js +29 -0
- package/dist/src/shell/effect-interpreter.js.map +1 -0
- package/dist/src/shell/interp/acp-frame.js +137 -0
- package/dist/src/shell/interp/acp-frame.js.map +1 -0
- package/dist/src/shell/interp/acp-ws-conn.js +320 -0
- package/dist/src/shell/interp/acp-ws-conn.js.map +1 -0
- package/dist/src/shell/interp/acp-ws-frames.js +159 -0
- package/dist/src/shell/interp/acp-ws-frames.js.map +1 -0
- package/dist/src/shell/interp/acp-ws.js +197 -0
- package/dist/src/shell/interp/acp-ws.js.map +1 -0
- package/dist/src/shell/interp/acp.js +319 -0
- package/dist/src/shell/interp/acp.js.map +1 -0
- package/dist/src/shell/interp/credential-defaults.js +128 -0
- package/dist/src/shell/interp/credential-defaults.js.map +1 -0
- package/dist/src/shell/interp/credential-hooks.js +149 -0
- package/dist/src/shell/interp/credential-hooks.js.map +1 -0
- package/dist/src/shell/interp/credential-registry.js +226 -0
- package/dist/src/shell/interp/credential-registry.js.map +1 -0
- package/dist/src/shell/interp/credential.js +103 -0
- package/dist/src/shell/interp/credential.js.map +1 -0
- package/dist/src/shell/interp/gh.js +163 -0
- package/dist/src/shell/interp/gh.js.map +1 -0
- package/dist/src/shell/interp/git.js +28 -0
- package/dist/src/shell/interp/git.js.map +1 -0
- package/dist/src/shell/interp/log.js +213 -0
- package/dist/src/shell/interp/log.js.map +1 -0
- package/dist/src/shell/interp/process.js +178 -0
- package/dist/src/shell/interp/process.js.map +1 -0
- package/dist/src/shell/interp/runlog.js +193 -0
- package/dist/src/shell/interp/runlog.js.map +1 -0
- package/dist/src/shell/interp/timer.js +64 -0
- package/dist/src/shell/interp/timer.js.map +1 -0
- package/dist/src/shell/interp/tracker-disk.js +99 -0
- package/dist/src/shell/interp/tracker-disk.js.map +1 -0
- package/dist/src/shell/interp/tracker-parse.js +71 -0
- package/dist/src/shell/interp/tracker-parse.js.map +1 -0
- package/dist/src/shell/interp/tracker-scan.js +238 -0
- package/dist/src/shell/interp/tracker-scan.js.map +1 -0
- package/dist/src/shell/interp/tracker-write.js +91 -0
- package/dist/src/shell/interp/tracker-write.js.map +1 -0
- package/dist/src/shell/interp/tracker.js +41 -0
- package/dist/src/shell/interp/tracker.js.map +1 -0
- package/dist/src/shell/interp/tty.js +48 -0
- package/dist/src/shell/interp/tty.js.map +1 -0
- package/dist/src/shell/interp/vm.js +199 -0
- package/dist/src/shell/interp/vm.js.map +1 -0
- package/dist/src/shell/interp/workspace.js +310 -0
- package/dist/src/shell/interp/workspace.js.map +1 -0
- package/dist/src/shell/main-acp.js +78 -0
- package/dist/src/shell/main-acp.js.map +1 -0
- package/dist/src/shell/main-adapters.js +222 -0
- package/dist/src/shell/main-adapters.js.map +1 -0
- package/dist/src/shell/main-credential.js +122 -0
- package/dist/src/shell/main-credential.js.map +1 -0
- package/dist/src/shell/main-doctor.js +22 -0
- package/dist/src/shell/main-doctor.js.map +1 -0
- package/dist/src/shell/main-entry.js +46 -0
- package/dist/src/shell/main-entry.js.map +1 -0
- package/dist/src/shell/main-http-csrf.js +45 -0
- package/dist/src/shell/main-http-csrf.js.map +1 -0
- package/dist/src/shell/main-http-handler.js +389 -0
- package/dist/src/shell/main-http-handler.js.map +1 -0
- package/dist/src/shell/main-http-mcp.js +122 -0
- package/dist/src/shell/main-http-mcp.js.map +1 -0
- package/dist/src/shell/main-http-views.js +253 -0
- package/dist/src/shell/main-http-views.js.map +1 -0
- package/dist/src/shell/main-http.js +76 -0
- package/dist/src/shell/main-http.js.map +1 -0
- package/dist/src/shell/main-loops.js +130 -0
- package/dist/src/shell/main-loops.js.map +1 -0
- package/dist/src/shell/main-mcp.js +129 -0
- package/dist/src/shell/main-mcp.js.map +1 -0
- package/dist/src/shell/main-orchestrator.js +120 -0
- package/dist/src/shell/main-orchestrator.js.map +1 -0
- package/dist/src/shell/main-preflight.js +43 -0
- package/dist/src/shell/main-preflight.js.map +1 -0
- package/dist/src/shell/main-reconcilers-helpers.js +244 -0
- package/dist/src/shell/main-reconcilers-helpers.js.map +1 -0
- package/dist/src/shell/main-reconcilers-pr.js +148 -0
- package/dist/src/shell/main-reconcilers-pr.js.map +1 -0
- package/dist/src/shell/main-reconcilers.js +225 -0
- package/dist/src/shell/main-reconcilers.js.map +1 -0
- package/dist/src/shell/main-runner.js +355 -0
- package/dist/src/shell/main-runner.js.map +1 -0
- package/dist/src/shell/main-scaffold.js +116 -0
- package/dist/src/shell/main-scaffold.js.map +1 -0
- package/dist/src/shell/main-shutdown.js +115 -0
- package/dist/src/shell/main-shutdown.js.map +1 -0
- package/dist/src/shell/main-startup.js +48 -0
- package/dist/src/shell/main-startup.js.map +1 -0
- package/dist/src/shell/main-substrates.js +43 -0
- package/dist/src/shell/main-substrates.js.map +1 -0
- package/dist/src/shell/main.js +385 -0
- package/dist/src/shell/main.js.map +1 -0
- package/dist/src/shell/orchestrator-feedback.js +69 -0
- package/dist/src/shell/orchestrator-feedback.js.map +1 -0
- package/dist/src/shell/orchestrator-image.js +167 -0
- package/dist/src/shell/orchestrator-image.js.map +1 -0
- package/dist/src/shell/orchestrator-loop.js +468 -0
- package/dist/src/shell/orchestrator-loop.js.map +1 -0
- package/dist/src/shell/orchestrator-reconcile.js +36 -0
- package/dist/src/shell/orchestrator-reconcile.js.map +1 -0
- package/dist/src/shell/reconciler-loop.js +228 -0
- package/dist/src/shell/reconciler-loop.js.map +1 -0
- package/dist/src/shell/runner-loop-turn.js +301 -0
- package/dist/src/shell/runner-loop-turn.js.map +1 -0
- package/dist/src/shell/runner-loop.js +338 -0
- package/dist/src/shell/runner-loop.js.map +1 -0
- package/dist/src/shell/server/http.js +208 -0
- package/dist/src/shell/server/http.js.map +1 -0
- package/dist/src/shell/server/mcp-runtime-effects.js +237 -0
- package/dist/src/shell/server/mcp-runtime-effects.js.map +1 -0
- package/dist/src/shell/server/mcp-runtime.js +99 -0
- package/dist/src/shell/server/mcp-runtime.js.map +1 -0
- package/dist/src/shell/workspace-key.js +14 -0
- package/dist/src/shell/workspace-key.js.map +1 -0
- package/dist/src/types/acp.js +8 -0
- package/dist/src/types/acp.js.map +1 -0
- package/dist/src/types/actions/plan.js +6 -0
- package/dist/src/types/actions/plan.js.map +1 -0
- package/dist/src/types/actions/predicates.js +6 -0
- package/dist/src/types/actions/predicates.js.map +1 -0
- package/dist/src/types/actions/run-fold.js +8 -0
- package/dist/src/types/actions/run-fold.js.map +1 -0
- package/dist/src/types/actions.js +7 -0
- package/dist/src/types/actions.js.map +1 -0
- package/dist/src/types/adapter/clock-random.js +4 -0
- package/dist/src/types/adapter/clock-random.js.map +1 -0
- package/dist/src/types/adapter/gondolin-image-converter.js +5 -0
- package/dist/src/types/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/src/types/adapter/gondolin-image-fetch.js +5 -0
- package/dist/src/types/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/src/types/adapter/workflow-loader.js +4 -0
- package/dist/src/types/adapter/workflow-loader.js.map +1 -0
- package/dist/src/types/cli/args.js +8 -0
- package/dist/src/types/cli/args.js.map +1 -0
- package/dist/src/types/config.js +8 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/credential-interp.js +6 -0
- package/dist/src/types/credential-interp.js.map +1 -0
- package/dist/src/types/credentials.js +10 -0
- package/dist/src/types/credentials.js.map +1 -0
- package/dist/src/types/doctor.js +7 -0
- package/dist/src/types/doctor.js.map +1 -0
- package/dist/src/types/domain.js +7 -0
- package/dist/src/types/domain.js.map +1 -0
- package/dist/src/types/effect.js +15 -0
- package/dist/src/types/effect.js.map +1 -0
- package/dist/src/types/errors.js +39 -0
- package/dist/src/types/errors.js.map +1 -0
- package/dist/src/types/http/decisions.js +6 -0
- package/dist/src/types/http/decisions.js.map +1 -0
- package/dist/src/types/http/render.js +10 -0
- package/dist/src/types/http/render.js.map +1 -0
- package/dist/src/types/http/views.js +6 -0
- package/dist/src/types/http/views.js.map +1 -0
- package/dist/src/types/http.js +9 -0
- package/dist/src/types/http.js.map +1 -0
- package/dist/src/types/image/managed-image.js +7 -0
- package/dist/src/types/image/managed-image.js.map +1 -0
- package/dist/src/types/interp/effect-interpreter.js +8 -0
- package/dist/src/types/interp/effect-interpreter.js.map +1 -0
- package/dist/src/types/interp/tracker.js +7 -0
- package/dist/src/types/interp/tracker.js.map +1 -0
- package/dist/src/types/issue/file.js +6 -0
- package/dist/src/types/issue/file.js.map +1 -0
- package/dist/src/types/issue/parse.js +8 -0
- package/dist/src/types/issue/parse.js.map +1 -0
- package/dist/src/types/main-acp.js +13 -0
- package/dist/src/types/main-acp.js.map +1 -0
- package/dist/src/types/main-adapters.js +5 -0
- package/dist/src/types/main-adapters.js.map +1 -0
- package/dist/src/types/main-credential.js +21 -0
- package/dist/src/types/main-credential.js.map +1 -0
- package/dist/src/types/main-doctor.js +6 -0
- package/dist/src/types/main-doctor.js.map +1 -0
- package/dist/src/types/main-http-handler.js +12 -0
- package/dist/src/types/main-http-handler.js.map +1 -0
- package/dist/src/types/main-http.js +5 -0
- package/dist/src/types/main-http.js.map +1 -0
- package/dist/src/types/main-loops.js +5 -0
- package/dist/src/types/main-loops.js.map +1 -0
- package/dist/src/types/main-mcp.js +12 -0
- package/dist/src/types/main-mcp.js.map +1 -0
- package/dist/src/types/main-orchestrator.js +5 -0
- package/dist/src/types/main-orchestrator.js.map +1 -0
- package/dist/src/types/main-reconcilers.js +11 -0
- package/dist/src/types/main-reconcilers.js.map +1 -0
- package/dist/src/types/main-runner.js +13 -0
- package/dist/src/types/main-runner.js.map +1 -0
- package/dist/src/types/main-startup.js +5 -0
- package/dist/src/types/main-startup.js.map +1 -0
- package/dist/src/types/main-substrates.js +5 -0
- package/dist/src/types/main-substrates.js.map +1 -0
- package/dist/src/types/mcp/dispatch.js +4 -0
- package/dist/src/types/mcp/dispatch.js.map +1 -0
- package/dist/src/types/mcp/post-move.js +7 -0
- package/dist/src/types/mcp/post-move.js.map +1 -0
- package/dist/src/types/mcp.js +9 -0
- package/dist/src/types/mcp.js.map +1 -0
- package/dist/src/types/ports.js +12 -0
- package/dist/src/types/ports.js.map +1 -0
- package/dist/src/types/reconcile/image-decide.js +5 -0
- package/dist/src/types/reconcile/image-decide.js.map +1 -0
- package/dist/src/types/reconcile/ledger.js +7 -0
- package/dist/src/types/reconcile/ledger.js.map +1 -0
- package/dist/src/types/reconcile/pr-loop.js +8 -0
- package/dist/src/types/reconcile/pr-loop.js.map +1 -0
- package/dist/src/types/reconcile/vm-reap.js +8 -0
- package/dist/src/types/reconcile/vm-reap.js.map +1 -0
- package/dist/src/types/reconcile/workspace-decide.js +7 -0
- package/dist/src/types/reconcile/workspace-decide.js.map +1 -0
- package/dist/src/types/reconcile.js +9 -0
- package/dist/src/types/reconcile.js.map +1 -0
- package/dist/src/types/runlog.js +7 -0
- package/dist/src/types/runlog.js.map +1 -0
- package/dist/src/types/runner/actions-runner.js +12 -0
- package/dist/src/types/runner/actions-runner.js.map +1 -0
- package/dist/src/types/runner/gondolin-dispatch.js +5 -0
- package/dist/src/types/runner/gondolin-dispatch.js.map +1 -0
- package/dist/src/types/runner/injection.js +6 -0
- package/dist/src/types/runner/injection.js.map +1 -0
- package/dist/src/types/runner/runner-loop.js +5 -0
- package/dist/src/types/runner/runner-loop.js.map +1 -0
- package/dist/src/types/runner/turn.js +4 -0
- package/dist/src/types/runner/turn.js.map +1 -0
- package/dist/src/types/runner/vm-plan.js +4 -0
- package/dist/src/types/runner/vm-plan.js.map +1 -0
- package/dist/src/types/runtime.js +9 -0
- package/dist/src/types/runtime.js.map +1 -0
- package/dist/src/types/schedule/admission.js +7 -0
- package/dist/src/types/schedule/admission.js.map +1 -0
- package/dist/src/types/schedule/circuit-breaker.js +2 -0
- package/dist/src/types/schedule/circuit-breaker.js.map +1 -0
- package/dist/src/types/schedule/eligibility.js +9 -0
- package/dist/src/types/schedule/eligibility.js.map +1 -0
- package/dist/src/types/schedule/orchestrator-loop.js +10 -0
- package/dist/src/types/schedule/orchestrator-loop.js.map +1 -0
- package/dist/src/types/schedule/sleep-cycle.js +4 -0
- package/dist/src/types/schedule/sleep-cycle.js.map +1 -0
- package/dist/src/types/schedule/slots.js +8 -0
- package/dist/src/types/schedule/slots.js.map +1 -0
- package/dist/src/types/schedule/tick.js +9 -0
- package/dist/src/types/schedule/tick.js.map +1 -0
- package/dist/src/types/server/mcp-runtime.js +8 -0
- package/dist/src/types/server/mcp-runtime.js.map +1 -0
- package/dist/src/types/workflow/parse.js +4 -0
- package/dist/src/types/workflow/parse.js.map +1 -0
- package/dist/tests/core/account-id.test.js +35 -0
- package/dist/tests/core/account-id.test.js.map +1 -0
- package/dist/tests/core/actions-parse.test.js +176 -0
- package/dist/tests/core/actions-parse.test.js.map +1 -0
- package/dist/tests/core/adapter-config.test.js +133 -0
- package/dist/tests/core/adapter-config.test.js.map +1 -0
- package/dist/tests/core/admission.test.js +215 -0
- package/dist/tests/core/admission.test.js.map +1 -0
- package/dist/tests/core/args.test.js +132 -0
- package/dist/tests/core/args.test.js.map +1 -0
- package/dist/tests/core/availability.test.js +62 -0
- package/dist/tests/core/availability.test.js.map +1 -0
- package/dist/tests/core/checks.test.js +395 -0
- package/dist/tests/core/checks.test.js.map +1 -0
- package/dist/tests/core/circuit-breaker.test.js +172 -0
- package/dist/tests/core/circuit-breaker.test.js.map +1 -0
- package/dist/tests/core/coerce.test.js +87 -0
- package/dist/tests/core/coerce.test.js.map +1 -0
- package/dist/tests/core/context.test.js +228 -0
- package/dist/tests/core/context.test.js.map +1 -0
- package/dist/tests/core/decisions.test.js +310 -0
- package/dist/tests/core/decisions.test.js.map +1 -0
- package/dist/tests/core/derive.test.js +205 -0
- package/dist/tests/core/derive.test.js.map +1 -0
- package/dist/tests/core/dispatch-config.test.js +164 -0
- package/dist/tests/core/dispatch-config.test.js.map +1 -0
- package/dist/tests/core/dispatch.test.js +302 -0
- package/dist/tests/core/dispatch.test.js.map +1 -0
- package/dist/tests/core/eligibility.test.js +163 -0
- package/dist/tests/core/eligibility.test.js.map +1 -0
- package/dist/tests/core/extract.test.js +139 -0
- package/dist/tests/core/extract.test.js.map +1 -0
- package/dist/tests/core/fake-creds.test.js +134 -0
- package/dist/tests/core/fake-creds.test.js.map +1 -0
- package/dist/tests/core/file.test.js +197 -0
- package/dist/tests/core/file.test.js.map +1 -0
- package/dist/tests/core/git-result.test.js +113 -0
- package/dist/tests/core/git-result.test.js.map +1 -0
- package/dist/tests/core/identity.test.js +180 -0
- package/dist/tests/core/identity.test.js.map +1 -0
- package/dist/tests/core/image-decide.test.js +59 -0
- package/dist/tests/core/image-decide.test.js.map +1 -0
- package/dist/tests/core/injection.test.js +163 -0
- package/dist/tests/core/injection.test.js.map +1 -0
- package/dist/tests/core/ledger.test.js +218 -0
- package/dist/tests/core/ledger.test.js.map +1 -0
- package/dist/tests/core/managed-image.test.js +68 -0
- package/dist/tests/core/managed-image.test.js.map +1 -0
- package/dist/tests/core/mise.test.js +138 -0
- package/dist/tests/core/mise.test.js.map +1 -0
- package/dist/tests/core/parse.test.js +174 -0
- package/dist/tests/core/parse.test.js.map +1 -0
- package/dist/tests/core/path.test.js +50 -0
- package/dist/tests/core/path.test.js.map +1 -0
- package/dist/tests/core/plan.test.js +218 -0
- package/dist/tests/core/plan.test.js.map +1 -0
- package/dist/tests/core/post-move.test.js +162 -0
- package/dist/tests/core/post-move.test.js.map +1 -0
- package/dist/tests/core/pr-classify.test.js +117 -0
- package/dist/tests/core/pr-classify.test.js.map +1 -0
- package/dist/tests/core/pr-decide.test.js +298 -0
- package/dist/tests/core/pr-decide.test.js.map +1 -0
- package/dist/tests/core/pr-loop.test.js +301 -0
- package/dist/tests/core/pr-loop.test.js.map +1 -0
- package/dist/tests/core/pr-notes.test.js +165 -0
- package/dist/tests/core/pr-notes.test.js.map +1 -0
- package/dist/tests/core/predicates.test.js +154 -0
- package/dist/tests/core/predicates.test.js.map +1 -0
- package/dist/tests/core/prompt.test.js +189 -0
- package/dist/tests/core/prompt.test.js.map +1 -0
- package/dist/tests/core/protocol.test.js +195 -0
- package/dist/tests/core/protocol.test.js.map +1 -0
- package/dist/tests/core/reconcile-issue.test.js +116 -0
- package/dist/tests/core/reconcile-issue.test.js.map +1 -0
- package/dist/tests/core/render.test.js +549 -0
- package/dist/tests/core/render.test.js.map +1 -0
- package/dist/tests/core/retry.test.js +186 -0
- package/dist/tests/core/retry.test.js.map +1 -0
- package/dist/tests/core/routes.test.js +247 -0
- package/dist/tests/core/routes.test.js.map +1 -0
- package/dist/tests/core/run-fold.test.js +299 -0
- package/dist/tests/core/run-fold.test.js.map +1 -0
- package/dist/tests/core/shape.test.js +185 -0
- package/dist/tests/core/shape.test.js.map +1 -0
- package/dist/tests/core/sleep-cycle.test.js +150 -0
- package/dist/tests/core/sleep-cycle.test.js.map +1 -0
- package/dist/tests/core/slots.test.js +201 -0
- package/dist/tests/core/slots.test.js.map +1 -0
- package/dist/tests/core/state-resolve.test.js +80 -0
- package/dist/tests/core/state-resolve.test.js.map +1 -0
- package/dist/tests/core/summary.test.js +200 -0
- package/dist/tests/core/summary.test.js.map +1 -0
- package/dist/tests/core/template.test.js +116 -0
- package/dist/tests/core/template.test.js.map +1 -0
- package/dist/tests/core/tick.test.js +558 -0
- package/dist/tests/core/tick.test.js.map +1 -0
- package/dist/tests/core/token-fold.test.js +176 -0
- package/dist/tests/core/token-fold.test.js.map +1 -0
- package/dist/tests/core/turn.test.js +388 -0
- package/dist/tests/core/turn.test.js.map +1 -0
- package/dist/tests/core/url.test.js +118 -0
- package/dist/tests/core/url.test.js.map +1 -0
- package/dist/tests/core/validate.test.js +247 -0
- package/dist/tests/core/validate.test.js.map +1 -0
- package/dist/tests/core/views.test.js +252 -0
- package/dist/tests/core/views.test.js.map +1 -0
- package/dist/tests/core/vm-decide.test.js +110 -0
- package/dist/tests/core/vm-decide.test.js.map +1 -0
- package/dist/tests/core/vm-guards.test.js +153 -0
- package/dist/tests/core/vm-guards.test.js.map +1 -0
- package/dist/tests/core/vm-plan.test.js +332 -0
- package/dist/tests/core/vm-plan.test.js.map +1 -0
- package/dist/tests/core/vm-reap.test.js +196 -0
- package/dist/tests/core/vm-reap.test.js.map +1 -0
- package/dist/tests/core/workflow-parse.test.js +493 -0
- package/dist/tests/core/workflow-parse.test.js.map +1 -0
- package/dist/tests/core/workspace-decide.test.js +236 -0
- package/dist/tests/core/workspace-decide.test.js.map +1 -0
- package/dist/tests/helpers/fixtures.js +167 -0
- package/dist/tests/helpers/fixtures.js.map +1 -0
- package/dist/tests/shell/acp-substrate.test.js +101 -0
- package/dist/tests/shell/acp-substrate.test.js.map +1 -0
- package/dist/tests/shell/actions-runner-push.test.js +203 -0
- package/dist/tests/shell/actions-runner-push.test.js.map +1 -0
- package/dist/tests/shell/credential-hooks.test.js +36 -0
- package/dist/tests/shell/credential-hooks.test.js.map +1 -0
- package/dist/tests/shell/credential-registry.test.js +165 -0
- package/dist/tests/shell/credential-registry.test.js.map +1 -0
- package/dist/tests/shell/credential-substrate.test.js +179 -0
- package/dist/tests/shell/credential-substrate.test.js.map +1 -0
- package/dist/tests/shell/dockerfile-mise-pin.test.js +51 -0
- package/dist/tests/shell/dockerfile-mise-pin.test.js.map +1 -0
- package/dist/tests/shell/doctor.test.js +101 -0
- package/dist/tests/shell/doctor.test.js.map +1 -0
- package/dist/tests/shell/effect-vm-create.test.js +52 -0
- package/dist/tests/shell/effect-vm-create.test.js.map +1 -0
- package/dist/tests/shell/gh-port.test.js +63 -0
- package/dist/tests/shell/gh-port.test.js.map +1 -0
- package/dist/tests/shell/gondolin-dispatch-guard.test.js +144 -0
- package/dist/tests/shell/gondolin-dispatch-guard.test.js.map +1 -0
- package/dist/tests/shell/gondolin-dispatch-shquote.test.js +168 -0
- package/dist/tests/shell/gondolin-dispatch-shquote.test.js.map +1 -0
- package/dist/tests/shell/gondolin-image-converter.test.js +208 -0
- package/dist/tests/shell/gondolin-image-converter.test.js.map +1 -0
- package/dist/tests/shell/gondolin-image-fetch.test.js +93 -0
- package/dist/tests/shell/gondolin-image-fetch.test.js.map +1 -0
- package/dist/tests/shell/http-handler.test.js +608 -0
- package/dist/tests/shell/http-handler.test.js.map +1 -0
- package/dist/tests/shell/http-server.test.js +53 -0
- package/dist/tests/shell/http-server.test.js.map +1 -0
- package/dist/tests/shell/mcp-runtime.test.js +366 -0
- package/dist/tests/shell/mcp-runtime.test.js.map +1 -0
- package/dist/tests/shell/mise-config-asset.test.js +87 -0
- package/dist/tests/shell/mise-config-asset.test.js.map +1 -0
- package/dist/tests/shell/orchestrator-loop.test.js +583 -0
- package/dist/tests/shell/orchestrator-loop.test.js.map +1 -0
- package/dist/tests/shell/reconciler-passes.test.js +314 -0
- package/dist/tests/shell/reconciler-passes.test.js.map +1 -0
- package/dist/tests/shell/runner-loop-turn.test.js +97 -0
- package/dist/tests/shell/runner-loop-turn.test.js.map +1 -0
- package/dist/tests/shell/runner-slice.test.js +536 -0
- package/dist/tests/shell/runner-slice.test.js.map +1 -0
- package/dist/tests/shell/scaffold.test.js +65 -0
- package/dist/tests/shell/scaffold.test.js.map +1 -0
- package/dist/tests/shell/tick-config.test.js +83 -0
- package/dist/tests/shell/tick-config.test.js.map +1 -0
- package/dist/tests/shell/tracker-parse-dates.test.js +44 -0
- package/dist/tests/shell/tracker-parse-dates.test.js.map +1 -0
- package/dist/tests/shell/tracker-write-issue.test.js +154 -0
- package/dist/tests/shell/tracker-write-issue.test.js.map +1 -0
- package/dist/tests/shell/workflow-prompt-split.test.js +208 -0
- package/dist/tests/shell/workflow-prompt-split.test.js.map +1 -0
- package/dist/tests/shell/workspace-live-config.test.js +140 -0
- package/dist/tests/shell/workspace-live-config.test.js.map +1 -0
- package/package.json +21 -9
- 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/bin/symphony.js +0 -794
- package/dist/bin/symphony.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,158 @@
|
|
|
1
|
+
// FCIS rewrite — pure-ish bring-up helpers for the Gondolin dispatch adapter
|
|
2
|
+
// (split out of gondolin-dispatch.ts to keep that file under the shell line budget).
|
|
3
|
+
// Ports the reference src/agent/gondolin-dispatch.ts free functions verbatim. Shell
|
|
4
|
+
// rule: imports from src/types/** ONLY (plus the real Gondolin SDK type surface).
|
|
5
|
+
import { Buffer } from 'node:buffer';
|
|
6
|
+
import { readdir } from 'node:fs/promises';
|
|
7
|
+
/**
|
|
8
|
+
* Build the guest→host control-plane tunnel from the plan's tunnel decision. When the
|
|
9
|
+
* tcp.hosts entry is present, ACP (ws://symphony-mcp:7001/acp) and MCP HTTP share this
|
|
10
|
+
* ONE entry; synthetic per-host DNS resolves the mapped name. When empty (MCP disabled or
|
|
11
|
+
* reached via an explicit URL), no tunnel is added — the guest reaches the host directly.
|
|
12
|
+
*/
|
|
13
|
+
export function buildTunnel(plan) {
|
|
14
|
+
const entry = plan.tunnel.tcpHostEntry;
|
|
15
|
+
if (!entry || Object.keys(entry).length === 0)
|
|
16
|
+
return {};
|
|
17
|
+
return {
|
|
18
|
+
tcp: { hosts: entry },
|
|
19
|
+
dns: { mode: 'synthetic', syntheticHostMapping: 'per-host' },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* POSIX single-quote-safe shell quoter. Wraps the value in single quotes and escapes any
|
|
24
|
+
* embedded single quote with the canonical `'\''` close-escape-reopen trick. Use this for
|
|
25
|
+
* EVERY host-controlled value interpolated into a `/bin/sh -c '…'` script — a configured
|
|
26
|
+
* guest path (gondolin.guest_agent_path) or adapter name containing a `'` would otherwise
|
|
27
|
+
* break out of the quoting and inject arbitrary commands into the guest shell.
|
|
28
|
+
*/
|
|
29
|
+
export function shQuote(value) {
|
|
30
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The in-guest write command for one guest file. The content is base64-encoded host-side
|
|
34
|
+
* and decoded in-guest, so arbitrary JSON (quotes, newlines, `$`) can never break out of
|
|
35
|
+
* the shell — no heredoc/echo injection surface. `mkdir -p` the parent, decode into place,
|
|
36
|
+
* then chmod. POSIX-portable (/bin/sh, base64 -d). The guest path + dir are shell-quoted
|
|
37
|
+
* (shQuote) so a path containing a `'` cannot break out of the single quotes and inject.
|
|
38
|
+
*/
|
|
39
|
+
export function writeFileCommand(file) {
|
|
40
|
+
const b64 = Buffer.from(file.content, 'utf8').toString('base64');
|
|
41
|
+
const dir = posixDirname(file.guestPath);
|
|
42
|
+
const mode = file.mode.toString(8);
|
|
43
|
+
const script = `mkdir -p ${shQuote(dir)} && ` +
|
|
44
|
+
`printf %s '${b64}' | base64 -d > ${shQuote(file.guestPath)} && ` +
|
|
45
|
+
`chmod ${mode} ${shQuote(file.guestPath)}`;
|
|
46
|
+
return ['/bin/sh', '-c', script];
|
|
47
|
+
}
|
|
48
|
+
/** POSIX dirname for an absolute guest path (always `/`-separated). */
|
|
49
|
+
function posixDirname(p) {
|
|
50
|
+
const idx = p.lastIndexOf('/');
|
|
51
|
+
if (idx <= 0)
|
|
52
|
+
return '/';
|
|
53
|
+
return p.slice(0, idx);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Run a one-shot guest exec to completion, bounded by an OWN `kill()` timer, capturing
|
|
57
|
+
* stdout/stderr via non-blocking `'data'` taps and keying completion off `exec.exit` —
|
|
58
|
+
* NEVER on the streams reaching EOF. Load-bearing: the live VmHandle.exec does not honor
|
|
59
|
+
* `opts.timeoutMs`, so a probe that awaited stdout `'end'` would hang forever on a
|
|
60
|
+
* half-open guest pipe (the Node pipe-EOF gotcha). Taps attach BEFORE `stdin.end()` so no
|
|
61
|
+
* early chunk is missed.
|
|
62
|
+
*/
|
|
63
|
+
export async function runBoundedExec(exec, timeoutMs) {
|
|
64
|
+
const stdoutTap = tapStream(exec.stdout);
|
|
65
|
+
const stderrTap = tapStream(exec.stderr);
|
|
66
|
+
exec.stdin.end();
|
|
67
|
+
let timedOut = false;
|
|
68
|
+
const timer = setTimeout(() => {
|
|
69
|
+
timedOut = true;
|
|
70
|
+
try {
|
|
71
|
+
exec.kill();
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
/* idempotent — already aborted / process gone */
|
|
75
|
+
}
|
|
76
|
+
}, timeoutMs);
|
|
77
|
+
let code;
|
|
78
|
+
try {
|
|
79
|
+
({ code } = await exec.exit);
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
}
|
|
84
|
+
return { code, stdout: stdoutTap.read(), stderr: stderrTap.read(), timedOut };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Non-blocking accumulator for a guest exec's stdout/stderr. Attaches a `'data'` listener
|
|
88
|
+
* that appends each chunk to a buffer the caller reads AFTER `exec.exit` resolves — it
|
|
89
|
+
* NEVER awaits the stream reaching EOF (the Node pipe-EOF gotcha).
|
|
90
|
+
*/
|
|
91
|
+
function tapStream(stream) {
|
|
92
|
+
let out = '';
|
|
93
|
+
stream.setEncoding('utf8');
|
|
94
|
+
stream.on('data', (chunk) => {
|
|
95
|
+
out += chunk;
|
|
96
|
+
});
|
|
97
|
+
return { read: () => out };
|
|
98
|
+
}
|
|
99
|
+
// NOTE (§4a): the BYO-probe exit-code→message decision moved to core
|
|
100
|
+
// `vm-plan.ts:byoProbeFailureMessage` and is INJECTED into the GondolinDispatcher
|
|
101
|
+
// (the shell runs the probe exec, core maps the code to the operator message).
|
|
102
|
+
/**
|
|
103
|
+
* Run the in-guest `mise install` step (issue 209) — provision node + the agent CLIs
|
|
104
|
+
* (staged SYSTEM config) + any project toolchains (the workspace mise.toml), bounded
|
|
105
|
+
* by an OWN `kill()` timer. Best-effort reads the workspace dir and logs whether a
|
|
106
|
+
* project config was detected (via the injected pure `detectProjectConfig` decider) so
|
|
107
|
+
* the operator can see the project contributed toolchains. Returns the bounded result;
|
|
108
|
+
* the caller throws a typed ByoContractError on a non-zero exit.
|
|
109
|
+
*/
|
|
110
|
+
export async function runMiseInstall(vm, opts, detectProjectConfig, log, timeoutMs) {
|
|
111
|
+
let hasProject = false;
|
|
112
|
+
try {
|
|
113
|
+
hasProject = detectProjectConfig(await readdir(opts.workdir));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
/* best-effort: an unreadable workspace just logs no project config */
|
|
117
|
+
}
|
|
118
|
+
log.emit('info', 'gondolin-dispatch: mise install', { workdir: opts.workdir, project_config: hasProject });
|
|
119
|
+
return runBoundedExec(vm.exec({ command: opts.command, workdir: opts.workdir, env: opts.env, timeoutMs }), timeoutMs);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Idempotent, error-tolerant teardown: kill the exec, close the VM, deregister the secret
|
|
123
|
+
* manager. Each step is independently guarded so one failure does not strand the others.
|
|
124
|
+
* `exec` is null when teardown runs from a bring-up failure that aborted BEFORE the launch
|
|
125
|
+
* exec was created; `registered` is null when the secret manager never got registered —
|
|
126
|
+
* both are skipped so the partial-bring-up cleanup is safe at any failure point.
|
|
127
|
+
*/
|
|
128
|
+
export async function teardownDispatch(vm, exec, registered, log) {
|
|
129
|
+
if (exec) {
|
|
130
|
+
try {
|
|
131
|
+
exec.kill();
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
log.emit('warn', 'gondolin-dispatch: exec.kill threw during teardown', {
|
|
135
|
+
error: err.message,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
await vm.close();
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
log.emit('warn', 'gondolin-dispatch: vm.close threw during teardown', {
|
|
144
|
+
error: err.message,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (registered) {
|
|
148
|
+
try {
|
|
149
|
+
registered.deregister();
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
log.emit('warn', 'gondolin-dispatch: deregister threw during teardown', {
|
|
153
|
+
error: err.message,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=gondolin-dispatch-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gondolin-dispatch-helpers.js","sourceRoot":"","sources":["../../../../src/shell/adapter/gondolin-dispatch-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
// FCIS rewrite — per-dispatch Gondolin bring-up adapter (kind: adapter).
|
|
2
|
+
//
|
|
3
|
+
// The IMPERATIVE bring-up + teardown sequence for ONE dispatch, executing the
|
|
4
|
+
// pure `VmPlan` the core assembled (src/core/runner/vm-plan.ts: buildVmPlan):
|
|
5
|
+
// 1. the host hands in the per-dispatch { httpHooks, secretManager } it built from
|
|
6
|
+
// the ONE AdapterCredentialSpec (live-token-keyed: the codex chatgpt-backend
|
|
7
|
+
// route swap is active). The placeholder env is already baked into the plan's
|
|
8
|
+
// guestFiles + launchEnv by core; the host keeps the secretManager (→ registry)
|
|
9
|
+
// + httpHooks (→ createVm).
|
|
10
|
+
// 2. register the per-VM secretManager with the injected registry BEFORE the agent
|
|
11
|
+
// launches (the placeholder's real value must be present before the first egress).
|
|
12
|
+
// 3. createVm with the plan's mounts/env + the built httpHooks/tcp/dns (the
|
|
13
|
+
// control-plane tunnel) + allowWebSockets.
|
|
14
|
+
// 4. materialize the plan's guest file set (launcher + gitconfig + fake creds + effort
|
|
15
|
+
// files) via the base64-pipe write-exec, with a /tmp fallback for the launcher when
|
|
16
|
+
// a readonly-rootfs BYO image fails the primary write.
|
|
17
|
+
// 5. probe the BYO image (resolve absolute node + adapter paths, assert Node≥21 /
|
|
18
|
+
// global WebSocket, confirm the launcher materialized) — fail FAST with a typed
|
|
19
|
+
// ByoContractError instead of an opaque post-launch ENOENT.
|
|
20
|
+
// 6. exec the agent ([resolvedNode, launcherPath]) with the plan's launchEnv; stdin
|
|
21
|
+
// end()ed immediately (ACP rides the /acp WebSocket, not stdio); stderr tapped.
|
|
22
|
+
// 7. idempotent, error-tolerant teardown: kill the exec, close the VM, deregister.
|
|
23
|
+
//
|
|
24
|
+
// Ports the reference src/agent/gondolin-dispatch.ts + launcher-asset.ts (read-only).
|
|
25
|
+
// THIN by design: every routing/precedence/env/argv decision already lives in core
|
|
26
|
+
// (buildVmPlan); this file only EXECUTES. Shell rule: imports from src/types/** ONLY
|
|
27
|
+
// (plus the real Gondolin SDK). NodeNext ESM, .js extensions on relative imports.
|
|
28
|
+
import os from 'node:os';
|
|
29
|
+
import { buildTunnel, writeFileCommand, runBoundedExec, runMiseInstall, teardownDispatch, } from './gondolin-dispatch-helpers.js';
|
|
30
|
+
/**
|
|
31
|
+
* A bring-your-own-image contract violation surfaced by the pre-launch probe (missing
|
|
32
|
+
* node ≥21 / global WebSocket, missing adapter CLI, or the launcher failed to
|
|
33
|
+
* materialize). Thrown BEFORE the agent launch so the dispatch fails fast with a precise,
|
|
34
|
+
* operator-facing message instead of an opaque ENOENT / never-dials-back failure. A
|
|
35
|
+
* distinct type so the classifier/teardown can recognise it.
|
|
36
|
+
*/
|
|
37
|
+
class ByoContractError extends Error {
|
|
38
|
+
constructor(message) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = 'ByoContractError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// ─── Fixed constants (ported verbatim from the reference) ──────────────────────
|
|
44
|
+
/** Always-tmpfs fallback the launcher is re-staged under when the primary write fails. */
|
|
45
|
+
const VM_AGENT_TMP_FALLBACK_PATH = '/tmp/symphony/vm-agent.mjs';
|
|
46
|
+
// TODO(§4b): byte-identical twins of core `vm-plan.ts:VM_AGENT_LAUNCHER_MODE` /
|
|
47
|
+
// `GUEST_AGENT_PATH`. The shell may not import core, and the only seam here is the
|
|
48
|
+
// GondolinDispatcher constructor — threading two injected scalars for the /tmp
|
|
49
|
+
// FALLBACK re-stage + the probe PATH is more churn than the "low, don't force it"
|
|
50
|
+
// item warrants (the primary launcher already carries `mode` from the core plan).
|
|
51
|
+
// Left as a documented twin; inject via the dispatcher ctor when one of them changes.
|
|
52
|
+
/** Non-secret mode for the re-staged launcher under the /tmp fallback. */
|
|
53
|
+
const VM_AGENT_LAUNCHER_MODE = 0o644;
|
|
54
|
+
/**
|
|
55
|
+
* Launch/probe PATH. `vm.exec` runs WITHOUT a login shell, so the profile PATH does not
|
|
56
|
+
* apply. The mise shims dir leads (issue 209) so shim-resolved children pick up the
|
|
57
|
+
* project's tools; the `mise` binary + any baked node sit under /usr/local/bin. A
|
|
58
|
+
* non-existent shims dir (not yet installed) is harmlessly skipped.
|
|
59
|
+
* BYTE-IDENTICAL twin of core `vm-plan.ts:GUEST_AGENT_PATH` (the shell may not import core).
|
|
60
|
+
*/
|
|
61
|
+
const GUEST_AGENT_PATH = '/opt/symphony/mise-data/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';
|
|
62
|
+
/** Bound on each guest write-exec (a tiny mkdir+decode+chmod; never hangs). */
|
|
63
|
+
const STAGE_TIMEOUT_MS = 15_000;
|
|
64
|
+
/** Bound on the pre-launch BYO probe exec (a tiny `command -v` chain; never hangs). */
|
|
65
|
+
const PROBE_TIMEOUT_MS = 15_000;
|
|
66
|
+
/**
|
|
67
|
+
* Bound on the in-guest `mise install` exec (issue 209). Generous — a COLD cache
|
|
68
|
+
* downloads node + the agent CLIs + any project toolchains; the persistent download cache
|
|
69
|
+
* (issue 222) lets a warm install skip the re-download (the slow part), though the
|
|
70
|
+
* extract + chmod onto the ephemeral rootfs still runs each dispatch.
|
|
71
|
+
*/
|
|
72
|
+
const MISE_INSTALL_TIMEOUT_MS = 600_000;
|
|
73
|
+
// ─── The dispatcher ────────────────────────────────────────────────────────────
|
|
74
|
+
/**
|
|
75
|
+
* Orchestrates a single Gondolin dispatch — the ONE VM bring-up path. Inject the
|
|
76
|
+
* VM port, the host secret registry, the injected pure/IO deciders (the
|
|
77
|
+
* credential-mount guard, the symlink realpath resolver, the BYO-probe
|
|
78
|
+
* failure-message mapper), and a log sink; `dispatch()` executes the core-built
|
|
79
|
+
* plan (stage guest files incl. the launcher, BYO probe, launch the in-VM agent)
|
|
80
|
+
* with the per-dispatch live-token-keyed egress hooks the host hands in, and
|
|
81
|
+
* returns an idempotent teardown handle.
|
|
82
|
+
*/
|
|
83
|
+
export class GondolinDispatcher {
|
|
84
|
+
vmClient;
|
|
85
|
+
registry;
|
|
86
|
+
assertNoCredentialMounts;
|
|
87
|
+
resolveMountRealpath;
|
|
88
|
+
byoProbeFailureMessage;
|
|
89
|
+
byoProbeScript;
|
|
90
|
+
miseInstallFailureMessage;
|
|
91
|
+
hasProjectMiseConfig;
|
|
92
|
+
log;
|
|
93
|
+
constructor(vmClient, registry, assertNoCredentialMounts, resolveMountRealpath, byoProbeFailureMessage, byoProbeScript, miseInstallFailureMessage, hasProjectMiseConfig, log) {
|
|
94
|
+
this.vmClient = vmClient;
|
|
95
|
+
this.registry = registry;
|
|
96
|
+
this.assertNoCredentialMounts = assertNoCredentialMounts;
|
|
97
|
+
this.resolveMountRealpath = resolveMountRealpath;
|
|
98
|
+
this.byoProbeFailureMessage = byoProbeFailureMessage;
|
|
99
|
+
this.byoProbeScript = byoProbeScript;
|
|
100
|
+
this.miseInstallFailureMessage = miseInstallFailureMessage;
|
|
101
|
+
this.hasProjectMiseConfig = hasProjectMiseConfig;
|
|
102
|
+
this.log = log;
|
|
103
|
+
}
|
|
104
|
+
async dispatch(opts) {
|
|
105
|
+
// SECURITY (host-only-refresh invariant teeth): HARD-FAIL before createVm if
|
|
106
|
+
// any plan mount overlaps a credential directory or is the home-dir root. The
|
|
107
|
+
// pure denylist check is injected (core/vm-guards.ts:assertNoCredentialMounts);
|
|
108
|
+
// a throw aborts the dispatch before any VM exists. vm-plan.ts documents this
|
|
109
|
+
// guard as the shell's job — this is its sole runtime call site.
|
|
110
|
+
//
|
|
111
|
+
// The core guard is LEXICAL-only, so a symlink whose lexical path is benign but
|
|
112
|
+
// whose target overlaps a credential dir would slip past. We `realpath` every
|
|
113
|
+
// mount host path (IO) and feed BOTH the lexical AND the resolved form to the
|
|
114
|
+
// guard, closing the symlink bypass (codex HIGH).
|
|
115
|
+
await this.assertMountsAllowed(opts.plan.mounts);
|
|
116
|
+
// The per-dispatch egress hooks the host built from the ONE spec it threads
|
|
117
|
+
// everywhere (live-token-keyed so the codex chatgpt-backend route swap is
|
|
118
|
+
// active). httpHooks → createVm; secretManager → the registry. The placeholder
|
|
119
|
+
// bearer is already baked into the plan's guestFiles + launchEnv by core.
|
|
120
|
+
const { httpHooks, secretManager } = opts.egress;
|
|
121
|
+
const { tcp, dns } = buildTunnel(opts.plan);
|
|
122
|
+
const vm = await this.vmClient.createVm({
|
|
123
|
+
imagePath: opts.plan.imagePath,
|
|
124
|
+
cpus: opts.plan.cpus,
|
|
125
|
+
memMib: opts.plan.memMib,
|
|
126
|
+
// Grow the guest rootfs so the ephemeral mise install fits (issue 222).
|
|
127
|
+
rootfsSize: opts.plan.rootfsSize,
|
|
128
|
+
mounts: opts.plan.mounts,
|
|
129
|
+
env: opts.plan.env,
|
|
130
|
+
httpHooks,
|
|
131
|
+
tcp,
|
|
132
|
+
dns,
|
|
133
|
+
allowWebSockets: opts.plan.allowWebSockets,
|
|
134
|
+
sessionLabel: opts.plan.sessionLabel,
|
|
135
|
+
workdir: opts.workdir,
|
|
136
|
+
});
|
|
137
|
+
// The host registers the ACP dispatch context (vmId → issue/workspace + MCP
|
|
138
|
+
// servers) the moment the VM exists, BEFORE the agent dials back. Inside the
|
|
139
|
+
// try so a thrown hook still tears the VM down (it has not registered yet).
|
|
140
|
+
// Once the VM exists every later step can throw before the handle (the only
|
|
141
|
+
// teardown affordance) returns — guard the whole bring-up: on any failure close the
|
|
142
|
+
// VM + deregister (if registered), then rethrow.
|
|
143
|
+
return this.bringUpOrTeardown(vm, secretManager, opts);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Resolve the symlink-canonical form of every mount host path (IO) and run the
|
|
147
|
+
* injected core guard over BOTH the lexical AND the resolved mount set. A throw
|
|
148
|
+
* from either aborts the dispatch before any VM exists.
|
|
149
|
+
*/
|
|
150
|
+
async assertMountsAllowed(mounts) {
|
|
151
|
+
const homeDir = os.homedir();
|
|
152
|
+
const resolved = await Promise.all(mounts.map(async (m) => ({ ...m, host: await this.resolveMountRealpath(m.host) })));
|
|
153
|
+
// One guard call over lexical ∪ resolved so a symlinked credential mount is
|
|
154
|
+
// rejected even when its lexical path is benign. (The core guard is idempotent
|
|
155
|
+
// over duplicates — a non-symlink path appears in both lists identically.)
|
|
156
|
+
this.assertNoCredentialMounts([...mounts, ...resolved], { homeDir });
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Register the secret manager, stage the plan's guest files, probe, and launch —
|
|
160
|
+
* tearing the VM down (and deregistering) on any failure so a post-createVm throw can
|
|
161
|
+
* never leak the VM handle the caller never received.
|
|
162
|
+
*/
|
|
163
|
+
async bringUpOrTeardown(vm, secretManager, opts) {
|
|
164
|
+
let registered = null;
|
|
165
|
+
try {
|
|
166
|
+
// Register the ACP dispatch context (vmId → issue/workspace + MCP servers) the
|
|
167
|
+
// moment the VM exists, BEFORE the agent dials back the /acp WebSocket. Inside
|
|
168
|
+
// the try so a thrown registration still tears the VM down.
|
|
169
|
+
opts.onVmCreated?.(vm.id);
|
|
170
|
+
// Seed + register BEFORE launch so the placeholder's real value is present before
|
|
171
|
+
// the first egress. AWAIT it before exec.
|
|
172
|
+
registered = await this.registry.register({
|
|
173
|
+
manager: secretManager,
|
|
174
|
+
secretName: opts.egress.secretName,
|
|
175
|
+
adapterId: opts.egress.adapterId,
|
|
176
|
+
});
|
|
177
|
+
// Stage every plan guest file (launcher FIRST so its landed path drives the probe
|
|
178
|
+
// + the exec), with a /tmp fallback for the launcher on a readonly-rootfs image.
|
|
179
|
+
const launcherGuestPath = await this.stageGuestFiles(vm, opts);
|
|
180
|
+
// mise toolchain provisioning (issue 209/222): AFTER staging the SYSTEM config,
|
|
181
|
+
// BEFORE the probe resolves node + the adapter shim. First prep the persistent
|
|
182
|
+
// download cache (point mise's downloads at the bind mount), then install the merged
|
|
183
|
+
// SYSTEM (node + the agent CLIs) + project (the workspace mise.toml) tool set onto
|
|
184
|
+
// the chmod-capable guest rootfs.
|
|
185
|
+
await this.runMisePrepStep(vm, opts);
|
|
186
|
+
await this.runMiseInstallStep(vm, opts);
|
|
187
|
+
// Probe the BYO layout AFTER staging+install, BEFORE launch — fail fast with a typed error.
|
|
188
|
+
const probe = await this.probeGuest(vm, opts, launcherGuestPath);
|
|
189
|
+
// Launch with the absolute node + launcher paths the probe resolved.
|
|
190
|
+
const exec = this.launchAgent(vm, opts, probe, launcherGuestPath);
|
|
191
|
+
return this.buildHandle(vm, exec, registered);
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
await teardownDispatch(vm, null, registered, this.log);
|
|
195
|
+
throw err;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Materialize the plan's ordered guest file set via the base64-pipe write-exec,
|
|
200
|
+
* returning the guest path the launcher (plan.guestFiles[0]) actually landed at. The
|
|
201
|
+
* launcher rides a verify-after-write /tmp fallback (a readonly-rootfs BYO image fails
|
|
202
|
+
* the primary write); every other file is awaited so it exists before launch.
|
|
203
|
+
*/
|
|
204
|
+
async stageGuestFiles(vm, opts) {
|
|
205
|
+
const [launcher, ...rest] = opts.plan.guestFiles;
|
|
206
|
+
if (!launcher) {
|
|
207
|
+
throw new ByoContractError('VmPlan.guestFiles is empty: no in-VM launcher to stage.');
|
|
208
|
+
}
|
|
209
|
+
const launcherGuestPath = await this.stageLauncher(vm, launcher, opts.workdir);
|
|
210
|
+
for (const f of rest) {
|
|
211
|
+
await this.writeGuestFile(vm, f, opts.workdir);
|
|
212
|
+
}
|
|
213
|
+
return launcherGuestPath;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Stage the launcher with a verify-after-write /tmp fallback. Gondolin's default rootfs
|
|
217
|
+
* is `cow` (writable per-VM overlay) so the primary write normally lands; a BYO image
|
|
218
|
+
* with a readonly-rootfs manifest fails it — detected via the exec's non-zero exit —
|
|
219
|
+
* so we retry under the always-tmpfs /tmp and return THAT path, keeping the write
|
|
220
|
+
* target and the exec arg in lockstep.
|
|
221
|
+
*/
|
|
222
|
+
async stageLauncher(vm, launcher, workdir) {
|
|
223
|
+
const primary = await this.writeGuestFile(vm, launcher, workdir);
|
|
224
|
+
if (primary.code === 0)
|
|
225
|
+
return launcher.guestPath;
|
|
226
|
+
this.log.emit('warn', 'gondolin-dispatch: launcher write failed; retrying under /tmp fallback', {
|
|
227
|
+
primaryPath: launcher.guestPath,
|
|
228
|
+
code: primary.code,
|
|
229
|
+
fallbackPath: VM_AGENT_TMP_FALLBACK_PATH,
|
|
230
|
+
});
|
|
231
|
+
const fallback = await this.writeGuestFile(vm, { guestPath: VM_AGENT_TMP_FALLBACK_PATH, content: launcher.content, mode: VM_AGENT_LAUNCHER_MODE }, workdir);
|
|
232
|
+
if (fallback.code !== 0) {
|
|
233
|
+
throw new ByoContractError(`failed to stage the in-VM launcher: write to ${launcher.guestPath} exited ` +
|
|
234
|
+
`${primary.code} and the /tmp fallback (${VM_AGENT_TMP_FALLBACK_PATH}) exited ` +
|
|
235
|
+
`${fallback.code}. The BYO image must expose a writable rootfs overlay (Gondolin ` +
|
|
236
|
+
'default `cow`) or a writable /tmp tmpfs.');
|
|
237
|
+
}
|
|
238
|
+
return VM_AGENT_TMP_FALLBACK_PATH;
|
|
239
|
+
}
|
|
240
|
+
/** Write one guest file via the base64-pipe exec; resolve its exit status. */
|
|
241
|
+
async writeGuestFile(vm, file, workdir) {
|
|
242
|
+
const exec = vm.exec({ command: writeFileCommand(file), workdir, timeoutMs: STAGE_TIMEOUT_MS });
|
|
243
|
+
exec.stdin.end();
|
|
244
|
+
return exec.exit;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Run the in-guest mise pre-install prep (issue 222) — create the rootfs install dir +
|
|
248
|
+
* the persistent cache subdirs and symlink mise's tool-download dir onto the cache (the
|
|
249
|
+
* pure `prepCommand` from core `runner/mise.ts`), BEFORE `mise install`, so a cold
|
|
250
|
+
* install's downloads persist across dispatches while the executable installs stay on
|
|
251
|
+
* the chmod-capable rootfs. Best-effort: a non-zero exit / timeout only costs a
|
|
252
|
+
* re-download next time (the install still succeeds on the rootfs), so it is LOGGED,
|
|
253
|
+
* never thrown. Always runs — mise provisioning is unconditional (issue 233).
|
|
254
|
+
*/
|
|
255
|
+
async runMisePrepStep(vm, opts) {
|
|
256
|
+
const { code, stderr, timedOut } = await runBoundedExec(vm.exec({
|
|
257
|
+
command: opts.plan.mise.prepCommand,
|
|
258
|
+
workdir: opts.workdir,
|
|
259
|
+
env: { PATH: GUEST_AGENT_PATH, ...opts.plan.mise.env },
|
|
260
|
+
timeoutMs: STAGE_TIMEOUT_MS,
|
|
261
|
+
}), STAGE_TIMEOUT_MS);
|
|
262
|
+
if (timedOut || code !== 0) {
|
|
263
|
+
this.log.emit('warn', 'gondolin-dispatch: mise pre-install prep failed (continuing; downloads will not persist)', {
|
|
264
|
+
code,
|
|
265
|
+
timedOut,
|
|
266
|
+
stderr: stderr.trim().slice(0, 500),
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Run the in-guest `mise install` step (issue 209) — provision node + the agent CLIs
|
|
272
|
+
* (the staged SYSTEM config at /etc/mise/config.toml) + any project toolchains (the
|
|
273
|
+
* workspace mise.toml) onto the ephemeral guest rootfs (issue 222; downloads cached on
|
|
274
|
+
* the bind mount), with cwd = workspace so the merged tool set is picked up. The install
|
|
275
|
+
* command + env are pure (core `runner/mise.ts`); a non-zero exit / timeout throws a
|
|
276
|
+
* typed ByoContractError carrying the operator-facing message + the guest's stderr tail,
|
|
277
|
+
* so a provisioning failure surfaces here rather than as a later opaque ENOENT (no node /
|
|
278
|
+
* no adapter shim) from the probe. Always runs — mise provisioning is unconditional
|
|
279
|
+
* (issue 233).
|
|
280
|
+
*/
|
|
281
|
+
async runMiseInstallStep(vm, opts) {
|
|
282
|
+
const { code, stderr, timedOut } = await runMiseInstall(vm, {
|
|
283
|
+
workdir: opts.workdir,
|
|
284
|
+
command: opts.plan.mise.installCommand,
|
|
285
|
+
// The mise env (MISE_DATA_DIR + MISE_YES + npm_config_cache) rides this exec (not
|
|
286
|
+
// the boot env) so the install writes onto the rootfs, caches downloads on the bind
|
|
287
|
+
// mount, and answers mise's trust prompts.
|
|
288
|
+
env: { PATH: GUEST_AGENT_PATH, ...opts.plan.mise.env },
|
|
289
|
+
}, this.hasProjectMiseConfig, this.log, MISE_INSTALL_TIMEOUT_MS);
|
|
290
|
+
if (timedOut) {
|
|
291
|
+
throw new ByoContractError(this.miseInstallFailureMessage(null, `mise install timed out after ${MISE_INSTALL_TIMEOUT_MS} ms`));
|
|
292
|
+
}
|
|
293
|
+
if (code !== 0) {
|
|
294
|
+
throw new ByoContractError(this.miseInstallFailureMessage(code, stderr));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* One bounded probe run under the launch PATH, AFTER staging and BEFORE launch:
|
|
299
|
+
* resolve the ABSOLUTE node + adapter paths from PATH (so the launch exec stays
|
|
300
|
+
* PATH-independent), assert Node≥21 / global WebSocket, and confirm the launcher
|
|
301
|
+
* materialized at `launcherGuestPath`. A non-zero exit (or unresolved paths) throws a
|
|
302
|
+
* typed ByoContractError with a precise, operator-facing message.
|
|
303
|
+
*/
|
|
304
|
+
async probeGuest(vm, opts, launcherGuestPath) {
|
|
305
|
+
const adapterName = opts.adapterBin;
|
|
306
|
+
// The probe script (node-resolution decision + shell-injection-safe quoting) is
|
|
307
|
+
// an injected pure decider (core `runner/mise.ts:buildByoProbeScript`): it resolves
|
|
308
|
+
// the AGENT runtime node via `mise which node` run from `/` (system-scoped — a
|
|
309
|
+
// project mise.toml can't downgrade it). The exec carries the mise env (MISE_DATA_DIR)
|
|
310
|
+
// so the `mise which`/shim resolution sees the rootfs install dir the toolchain landed in.
|
|
311
|
+
const script = this.byoProbeScript(adapterName, launcherGuestPath);
|
|
312
|
+
const { code, stdout, stderr, timedOut } = await runBoundedExec(vm.exec({
|
|
313
|
+
command: ['/bin/sh', '-c', script],
|
|
314
|
+
workdir: opts.workdir,
|
|
315
|
+
env: { PATH: GUEST_AGENT_PATH, ...opts.plan.mise.env },
|
|
316
|
+
timeoutMs: PROBE_TIMEOUT_MS,
|
|
317
|
+
}), PROBE_TIMEOUT_MS);
|
|
318
|
+
if (timedOut) {
|
|
319
|
+
throw new ByoContractError(`BYO image probe timed out after ${PROBE_TIMEOUT_MS} ms before resolving node + ` +
|
|
320
|
+
`"${adapterName}" on PATH. Check that Node ≥ 21 and the adapter CLI are on PATH and ` +
|
|
321
|
+
'that /bin/sh works in the guest.');
|
|
322
|
+
}
|
|
323
|
+
if (code !== 0) {
|
|
324
|
+
throw new ByoContractError(this.byoProbeFailureMessage(code, adapterName, stderr, GUEST_AGENT_PATH));
|
|
325
|
+
}
|
|
326
|
+
const [resolvedNode, resolvedAdapter] = stdout
|
|
327
|
+
.split('\n')
|
|
328
|
+
.map((s) => s.trim())
|
|
329
|
+
.filter((s) => s.length > 0);
|
|
330
|
+
if (!resolvedNode || !resolvedAdapter) {
|
|
331
|
+
throw new ByoContractError(`BYO image probe succeeded but did not resolve absolute node + adapter paths ` +
|
|
332
|
+
`(node="${resolvedNode ?? ''}", adapter="${resolvedAdapter ?? ''}"). The image must ` +
|
|
333
|
+
`expose "node" and "${adapterName}" on PATH.`);
|
|
334
|
+
}
|
|
335
|
+
return { nodeBin: resolvedNode, adapterBin: resolvedAdapter };
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Launch the in-VM ACP agent. Stdin is end()ed immediately — ACP frames ride the /acp
|
|
339
|
+
* WebSocket, not the exec stdio; the exec channel is a process tether + diagnostic
|
|
340
|
+
* stderr pipe. Execs the ABSOLUTE node the probe resolved against the staged launcher
|
|
341
|
+
* path; SYMPHONY_ADAPTER_BIN in launchEnv is overridden with the probe's absolute
|
|
342
|
+
* adapter path so the adapter spawn is PATH-independent too.
|
|
343
|
+
*/
|
|
344
|
+
launchAgent(vm, opts, probe, launcherGuestPath) {
|
|
345
|
+
const exec = vm.exec({
|
|
346
|
+
command: [probe.nodeBin, launcherGuestPath],
|
|
347
|
+
workdir: opts.workdir,
|
|
348
|
+
env: { ...opts.launchEnv, SYMPHONY_ADAPTER_BIN: probe.adapterBin },
|
|
349
|
+
timeoutMs: null,
|
|
350
|
+
});
|
|
351
|
+
exec.stdin.end();
|
|
352
|
+
exec.stderr.setEncoding('utf8');
|
|
353
|
+
exec.stderr.on('data', (chunk) => {
|
|
354
|
+
try {
|
|
355
|
+
opts.onStderr(chunk);
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
this.log.emit('warn', 'gondolin-dispatch: stderr sink threw', { error: err.message });
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
// The exec is a fire-and-forget process tether: ACP drives the agent lifecycle over the
|
|
362
|
+
// /acp WebSocket and nothing awaits `exec.exit`. Observe it anyway so an in-VM agent that
|
|
363
|
+
// dies on its own (or the expected teardown kill, which the adapter resolves to a killed
|
|
364
|
+
// sentinel) is LOGGED rather than surfacing as an unhandled rejection that would crash the
|
|
365
|
+
// orchestrator. The adapter only re-rejects on genuine (non-kill) errors — log those.
|
|
366
|
+
void exec.exit.then(({ code, signal }) => this.log.emit('info', 'gondolin-dispatch: in-VM agent exec exited', { code, signal }), (err) => this.log.emit('warn', 'gondolin-dispatch: in-VM agent exec errored', { error: err.message }));
|
|
367
|
+
return exec;
|
|
368
|
+
}
|
|
369
|
+
/** Wrap the live VM + exec + registration into the idempotent teardown handle. */
|
|
370
|
+
buildHandle(vm, exec, registered) {
|
|
371
|
+
let torndown = false;
|
|
372
|
+
const log = this.log;
|
|
373
|
+
return {
|
|
374
|
+
vm,
|
|
375
|
+
exec,
|
|
376
|
+
teardown: async () => {
|
|
377
|
+
if (torndown)
|
|
378
|
+
return;
|
|
379
|
+
torndown = true;
|
|
380
|
+
await teardownDispatch(vm, exec, registered, log);
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=gondolin-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gondolin-dispatch.js","sourceRoot":"","sources":["../../../../src/shell/adapter/gondolin-dispatch.ts"],"names":[],"mappings":"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"}
|