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
package/dist/acp-bridge.js
DELETED
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
// ACP TCP bridge — host-side transport for the in-VM ACP adapter.
|
|
2
|
-
//
|
|
3
|
-
// Before this module, symphony spoke ACP to the in-VM adapter over the earlier
|
|
4
|
-
// in-VM-exec stdio channel directly. Two problems with that:
|
|
5
|
-
//
|
|
6
|
-
// 1. The in-VM-exec stdin pump does not reliably wake the in-VM reader for new
|
|
7
|
-
// event-loop iterations unless host-side stdin keeps writing — so once symphony
|
|
8
|
-
// stopped writing (after `session/prompt`), the adapter would freeze waiting for
|
|
9
|
-
// events that the kernel had already delivered. The previous workaround was a
|
|
10
|
-
// 1.5 s `\n` keepalive on the in-VM-exec stdin.
|
|
11
|
-
//
|
|
12
|
-
// 2. The in-VM-exec stdio path tightly coupled symphony to the exec channel. If we
|
|
13
|
-
// ever swap the sandbox out for another (firecracker, gvisor, Kubernetes job, …)
|
|
14
|
-
// we'd have to relearn the same per-sandbox-stdio quirks.
|
|
15
|
-
//
|
|
16
|
-
// This bridge replaces that path: symphony binds a TCP listener; the in-VM `vm-agent`
|
|
17
|
-
// dials back, authenticates with a per-dispatch bearer token, and from then on ACP
|
|
18
|
-
// JSON-RPC frames flow over a regular TCP socket. The in-VM exec is reduced to a process
|
|
19
|
-
// launcher — its stdio is used only for diagnostic stderr from the in-VM agent. Any
|
|
20
|
-
// sandbox that can (a) exec a process with env vars and (b) reach the host loopback
|
|
21
|
-
// can now run our agent stack.
|
|
22
|
-
//
|
|
23
|
-
// Lifecycle:
|
|
24
|
-
// 1. Orchestrator calls `bridge.register(issueId)` BEFORE launching the VM.
|
|
25
|
-
// Returns a `{ token, accepted }` pair; `token` goes into the launch env as
|
|
26
|
-
// SYMPHONY_ACP_TOKEN.
|
|
27
|
-
// 2. Launch command exec's `node /opt/symphony/vm-agent.mjs`, which dials
|
|
28
|
-
// `tcp://<bridge.host>:<bridge.port>` and writes `Bearer <token>\n` as its first
|
|
29
|
-
// line.
|
|
30
|
-
// 3. Bridge accepts the socket, parses the bearer line, looks up the registration,
|
|
31
|
-
// validates the token (constant time), and resolves the registration's
|
|
32
|
-
// `accepted` promise with the now-authenticated socket.
|
|
33
|
-
// 4. Caller hands the socket to AcpClient as its stdin/stdout.
|
|
34
|
-
// 5. On attempt teardown the caller closes the socket; vm-agent reacts by killing
|
|
35
|
-
// the adapter and exiting; the in-VM exec sees the in-VM agent exit; the orchestrator
|
|
36
|
-
// destroys the VM (per current lifecycle).
|
|
37
|
-
import { createServer } from 'node:net';
|
|
38
|
-
import { randomBytes, timingSafeEqual } from 'node:crypto';
|
|
39
|
-
import { log } from './logging.js';
|
|
40
|
-
/**
|
|
41
|
-
* Loopback host literals `start()` accepts under `loopbackOnly`. We match the exact
|
|
42
|
-
* IPv4 loopback `127.0.0.1`, the whole `127.0.0.0/8` range textually, the IPv6
|
|
43
|
-
* loopback `::1`, and the `localhost` name. A `0.0.0.0`/`::`/LAN-IP/hostname bind is
|
|
44
|
-
* rejected — those are wider than loopback.
|
|
45
|
-
*/
|
|
46
|
-
function isLoopbackHost(host) {
|
|
47
|
-
if (host === '::1' || host === 'localhost')
|
|
48
|
-
return true;
|
|
49
|
-
return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
50
|
-
}
|
|
51
|
-
export class AcpBridge {
|
|
52
|
-
server = null;
|
|
53
|
-
boundPort = null;
|
|
54
|
-
// Pending registrations keyed by token. Lookups are constant time because we walk and
|
|
55
|
-
// compare with `timingSafeEqual`; the map is just for fast membership filtering of
|
|
56
|
-
// expired entries during teardown.
|
|
57
|
-
pending = new Map();
|
|
58
|
-
// Live, post-auth sockets we've handed to callers. We track them so `stop()` can force
|
|
59
|
-
// them closed instead of waiting on `server.close()` to drain — without that, SIGTERM
|
|
60
|
-
// during an active attempt would block indefinitely while the adapter side fails to
|
|
61
|
-
// unwind. Added in response to a review finding that pointed out the shutdown hang.
|
|
62
|
-
liveSockets = new Set();
|
|
63
|
-
// Pre-auth sockets: connected but not yet authenticated (or failing auth). Tracked so
|
|
64
|
-
// stop() can destroy them too; otherwise `server.close()` waits for the 10s auth
|
|
65
|
-
// deadline to expire on each idle connection before SIGTERM completes.
|
|
66
|
-
preAuthSockets = new Set();
|
|
67
|
-
stopped = false;
|
|
68
|
-
authTimeoutMs;
|
|
69
|
-
loopbackOnly;
|
|
70
|
-
constructor(opts = {}) {
|
|
71
|
-
this.authTimeoutMs = opts.authTimeoutMs ?? 10_000;
|
|
72
|
-
this.loopbackOnly = opts.loopbackOnly ?? false;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Start listening on (host, port). Pass 0 for an ephemeral port; the actually-bound
|
|
76
|
-
* port is available via `port()` and is what the in-VM agent must dial. Throws on
|
|
77
|
-
* bind failure so the symphony bootstrap can surface the error early.
|
|
78
|
-
*/
|
|
79
|
-
async start(host, port) {
|
|
80
|
-
if (this.server)
|
|
81
|
-
return;
|
|
82
|
-
if (this.loopbackOnly && !isLoopbackHost(host)) {
|
|
83
|
-
throw new Error(`acp bridge: loopbackOnly is set but host ${JSON.stringify(host)} is not a ` +
|
|
84
|
-
`loopback address; refusing to bind a bearer-gated control channel wider than loopback`);
|
|
85
|
-
}
|
|
86
|
-
this.server = createServer((socket) => this.handleConnection(socket));
|
|
87
|
-
await new Promise((resolve, reject) => {
|
|
88
|
-
const onError = (err) => {
|
|
89
|
-
this.server?.removeListener('listening', onListening);
|
|
90
|
-
reject(err);
|
|
91
|
-
};
|
|
92
|
-
const onListening = () => {
|
|
93
|
-
this.server?.removeListener('error', onError);
|
|
94
|
-
resolve();
|
|
95
|
-
};
|
|
96
|
-
this.server.once('error', onError);
|
|
97
|
-
this.server.once('listening', onListening);
|
|
98
|
-
this.server.listen(port, host);
|
|
99
|
-
});
|
|
100
|
-
const addr = this.server.address();
|
|
101
|
-
if (typeof addr === 'object' && addr !== null) {
|
|
102
|
-
this.boundPort = addr.port;
|
|
103
|
-
}
|
|
104
|
-
// Re-attach a permanent error handler so post-bind runtime errors don't crash the
|
|
105
|
-
// process — they land in the log and the listener stays up.
|
|
106
|
-
this.server.on('error', (err) => log.warn('acp bridge runtime error', { error: err.message }));
|
|
107
|
-
log.info('acp bridge listening', { host, port: this.boundPort });
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Actually-bound port (differs from the requested port when 0 was passed). Returns
|
|
111
|
-
* `null` before `start()` has bound the listener.
|
|
112
|
-
*/
|
|
113
|
-
port() {
|
|
114
|
-
return this.boundPort;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Register a pending dispatch. Returns a token to inject into the in-VM agent's env
|
|
118
|
-
* and a promise that resolves when the agent connects + authenticates. The promise
|
|
119
|
-
* rejects if `cancel()` is called or if `stop()` runs before the agent connects.
|
|
120
|
-
*/
|
|
121
|
-
register(issueId, identifier) {
|
|
122
|
-
if (this.stopped) {
|
|
123
|
-
throw new Error('acp bridge is stopped');
|
|
124
|
-
}
|
|
125
|
-
if (!this.server) {
|
|
126
|
-
throw new Error('acp bridge is not listening; call start() first');
|
|
127
|
-
}
|
|
128
|
-
const token = randomBytes(24).toString('base64url');
|
|
129
|
-
let resolveFn;
|
|
130
|
-
let rejectFn;
|
|
131
|
-
const accepted = new Promise((res, rej) => {
|
|
132
|
-
resolveFn = res;
|
|
133
|
-
rejectFn = rej;
|
|
134
|
-
});
|
|
135
|
-
// Defensive: attach an internal noop catch so a `cancel()` that lands before the
|
|
136
|
-
// caller has wired up its own handler can't escalate into an unhandled-rejection
|
|
137
|
-
// crash. The caller's eventual `await accepted` / `.then()` still sees the rejection
|
|
138
|
-
// via its own handler chain — this `.catch` is a separate promise consumer and only
|
|
139
|
-
// exists to keep Node's unhandled-rejection tracking quiet.
|
|
140
|
-
accepted.catch(() => undefined);
|
|
141
|
-
const reg = {
|
|
142
|
-
issueId,
|
|
143
|
-
identifier,
|
|
144
|
-
token,
|
|
145
|
-
resolve: (s) => {
|
|
146
|
-
if (reg.settled)
|
|
147
|
-
return;
|
|
148
|
-
reg.settled = true;
|
|
149
|
-
this.pending.delete(token);
|
|
150
|
-
resolveFn(s);
|
|
151
|
-
},
|
|
152
|
-
reject: (err) => {
|
|
153
|
-
if (reg.settled)
|
|
154
|
-
return;
|
|
155
|
-
reg.settled = true;
|
|
156
|
-
this.pending.delete(token);
|
|
157
|
-
rejectFn(err);
|
|
158
|
-
},
|
|
159
|
-
settled: false,
|
|
160
|
-
};
|
|
161
|
-
this.pending.set(token, reg);
|
|
162
|
-
log.debug('acp bridge registered', { issue_id: issueId, issue_identifier: identifier });
|
|
163
|
-
return {
|
|
164
|
-
token,
|
|
165
|
-
accepted,
|
|
166
|
-
cancel: (reason) => reg.reject(new Error(`acp bridge cancel: ${reason}`)),
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Stop accepting new connections, reject all pending registrations, and force-close
|
|
171
|
-
* any live sockets. We deliberately tear down live sockets rather than waiting on
|
|
172
|
-
* them — `server.close()` blocks until every active connection ends, and an unhappy
|
|
173
|
-
* adapter / abruptly-killed VM can leave sockets half-open and stall SIGTERM
|
|
174
|
-
* indefinitely. The runner's cleanup path already destroys its end on attempt exit,
|
|
175
|
-
* so the only time this matters is symphony shutdown while an attempt is mid-flight.
|
|
176
|
-
*/
|
|
177
|
-
async stop() {
|
|
178
|
-
if (this.stopped)
|
|
179
|
-
return;
|
|
180
|
-
this.stopped = true;
|
|
181
|
-
for (const reg of [...this.pending.values()]) {
|
|
182
|
-
reg.reject(new Error('acp bridge stopped'));
|
|
183
|
-
}
|
|
184
|
-
this.pending.clear();
|
|
185
|
-
// Tear down BOTH pre-auth and live sockets. Pre-auth left to the 10s auth deadline
|
|
186
|
-
// would delay SIGTERM by exactly that long for every idle client (e.g. a port scan
|
|
187
|
-
// or a broken in-VM proxy that connects but never sends the bearer).
|
|
188
|
-
for (const s of [...this.preAuthSockets, ...this.liveSockets]) {
|
|
189
|
-
try {
|
|
190
|
-
s.destroy();
|
|
191
|
-
}
|
|
192
|
-
catch {
|
|
193
|
-
/* ignore */
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
this.preAuthSockets.clear();
|
|
197
|
-
this.liveSockets.clear();
|
|
198
|
-
const srv = this.server;
|
|
199
|
-
this.server = null;
|
|
200
|
-
if (!srv)
|
|
201
|
-
return;
|
|
202
|
-
await new Promise((resolve) => srv.close(() => resolve()));
|
|
203
|
-
log.info('acp bridge stopped');
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Per-connection handshake. We accumulate bytes on the socket until we see the first
|
|
207
|
-
* newline, parse `Bearer <token>` from that line, validate against a pending
|
|
208
|
-
* registration in constant time, and either hand the socket back to the awaiter
|
|
209
|
-
* (consuming any post-newline bytes that arrived in the same packet) or close.
|
|
210
|
-
*/
|
|
211
|
-
handleConnection(socket) {
|
|
212
|
-
socket.setNoDelay(true);
|
|
213
|
-
// Track every accepted connection (even pre-auth) so stop() can tear them down.
|
|
214
|
-
// Removed from preAuthSockets either when fail() destroys them or when the bearer
|
|
215
|
-
// handshake succeeds and they move into liveSockets.
|
|
216
|
-
this.preAuthSockets.add(socket);
|
|
217
|
-
socket.once('close', () => this.preAuthSockets.delete(socket));
|
|
218
|
-
let buf = Buffer.alloc(0);
|
|
219
|
-
let handled = false;
|
|
220
|
-
const fail = (reason) => {
|
|
221
|
-
if (handled)
|
|
222
|
-
return;
|
|
223
|
-
handled = true;
|
|
224
|
-
log.warn('acp bridge rejected connection', {
|
|
225
|
-
remote: `${socket.remoteAddress}:${socket.remotePort}`,
|
|
226
|
-
reason,
|
|
227
|
-
});
|
|
228
|
-
// Destroy (not just end) the socket. A misbehaving peer that ignores our half-close
|
|
229
|
-
// would otherwise keep the connection counted by `server.close()` and stall
|
|
230
|
-
// symphony shutdown indefinitely.
|
|
231
|
-
try {
|
|
232
|
-
socket.destroy();
|
|
233
|
-
}
|
|
234
|
-
catch {
|
|
235
|
-
/* ignore */
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
// Authentication deadline: if the in-VM agent doesn't send the bearer line within
|
|
239
|
-
// the configured window of connecting, the connection is almost certainly stuck or
|
|
240
|
-
// malformed. The dispatch's own timeout would also catch this; this is just a tighter
|
|
241
|
-
// guard.
|
|
242
|
-
const authDeadline = setTimeout(() => fail('auth timeout'), this.authTimeoutMs);
|
|
243
|
-
const onData = (chunk) => {
|
|
244
|
-
buf = Buffer.concat([buf, chunk]);
|
|
245
|
-
const nl = buf.indexOf(0x0a);
|
|
246
|
-
if (nl === -1) {
|
|
247
|
-
// Cap the unauthenticated buffer at 1 KiB so a misbehaving client can't grow
|
|
248
|
-
// memory before failing auth.
|
|
249
|
-
if (buf.length > 1024)
|
|
250
|
-
fail('auth header too large');
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
const headerLine = buf.subarray(0, nl).toString('utf8').trim();
|
|
254
|
-
const remainder = buf.subarray(nl + 1);
|
|
255
|
-
clearTimeout(authDeadline);
|
|
256
|
-
socket.removeListener('data', onData);
|
|
257
|
-
const matched = this.authenticate(socket, headerLine, fail);
|
|
258
|
-
if (!matched)
|
|
259
|
-
return;
|
|
260
|
-
handled = true;
|
|
261
|
-
this.promoteToLive(socket, remainder);
|
|
262
|
-
matched.resolve(socket);
|
|
263
|
-
};
|
|
264
|
-
socket.on('data', onData);
|
|
265
|
-
socket.on('error', (err) => {
|
|
266
|
-
// Connection errors before auth get swallowed; after auth the AcpClient owns the
|
|
267
|
-
// socket and will see the error itself.
|
|
268
|
-
if (!handled) {
|
|
269
|
-
clearTimeout(authDeadline);
|
|
270
|
-
fail(`socket error: ${err.message}`);
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
authenticate(socket, headerLine, fail) {
|
|
275
|
-
const match = /^Bearer\s+(\S+)$/.exec(headerLine);
|
|
276
|
-
if (!match) {
|
|
277
|
-
fail('malformed bearer line');
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
const matched = this.findPendingByToken(match[1]);
|
|
281
|
-
if (!matched) {
|
|
282
|
-
fail('invalid token');
|
|
283
|
-
return null;
|
|
284
|
-
}
|
|
285
|
-
log.info('acp bridge accepted', {
|
|
286
|
-
issue_id: matched.issueId,
|
|
287
|
-
issue_identifier: matched.identifier,
|
|
288
|
-
remote: `${socket.remoteAddress}:${socket.remotePort}`,
|
|
289
|
-
});
|
|
290
|
-
return matched;
|
|
291
|
-
}
|
|
292
|
-
// Constant-time compare against each pending token. With max_concurrent_agents = 1
|
|
293
|
-
// there's typically ONE pending entry, but loop anyway for correctness.
|
|
294
|
-
findPendingByToken(presented) {
|
|
295
|
-
const presentedBuf = Buffer.from(presented, 'utf8');
|
|
296
|
-
for (const reg of this.pending.values()) {
|
|
297
|
-
const expected = Buffer.from(reg.token, 'utf8');
|
|
298
|
-
if (expected.length !== presentedBuf.length)
|
|
299
|
-
continue;
|
|
300
|
-
if (timingSafeEqual(expected, presentedBuf))
|
|
301
|
-
return reg;
|
|
302
|
-
}
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
// CRITICAL: the temporary `data` listener in handleConnection put the socket in flowing
|
|
306
|
-
// mode. Removing that listener does NOT auto-pause it — any bytes already buffered in
|
|
307
|
-
// the kernel or arriving immediately after will be re-emitted in flowing mode and
|
|
308
|
-
// dropped if no listener is attached yet, which is exactly the window between
|
|
309
|
-
// `resolve(socket)` and AcpClient's microtask wiring up `ndJsonStream`. Pause
|
|
310
|
-
// explicitly so the next consumer is responsible for resuming. `unshift` puts the
|
|
311
|
-
// residual bytes (bearer + ACP-frame in one packet case) back in front of any
|
|
312
|
-
// subsequent kernel data.
|
|
313
|
-
promoteToLive(socket, remainder) {
|
|
314
|
-
socket.pause();
|
|
315
|
-
if (remainder.length > 0)
|
|
316
|
-
socket.unshift(remainder);
|
|
317
|
-
// Move from pre-auth tracking into live tracking. Both sets are tied into stop()
|
|
318
|
-
// for forced teardown on shutdown.
|
|
319
|
-
this.preAuthSockets.delete(socket);
|
|
320
|
-
this.liveSockets.add(socket);
|
|
321
|
-
socket.once('close', () => this.liveSockets.delete(socket));
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
//# sourceMappingURL=acp-bridge.js.map
|
package/dist/acp-bridge.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"acp-bridge.js","sourceRoot":"","sources":["../src/acp-bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/actions/cache.js
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
// Content-hash cache for run_in_vm actions (issue 36 AC4).
|
|
2
|
-
//
|
|
3
|
-
// Cache layout:
|
|
4
|
-
// <cacheRoot>/actions/run_in_vm/<name>/<sha256(workspace_tree ⊕ cmd ⊕ env)>/result.json
|
|
5
|
-
//
|
|
6
|
-
// The name is the first path segment so `symphony rerun --check=<name>` can
|
|
7
|
-
// drop an entire check's cache without recomputing the workspace-dependent
|
|
8
|
-
// hash (which the CLI doesn't know — it has no per-issue workspace). The
|
|
9
|
-
// per-execution path computes the hash against the actual per-issue
|
|
10
|
-
// workspace; the CLI just removes the namespace dir, and the next execution
|
|
11
|
-
// re-runs because no cached hash entry exists.
|
|
12
|
-
//
|
|
13
|
-
// `workspace_tree` hashes the live workspace contents the VM command will
|
|
14
|
-
// see: every file `git ls-files --cached --others --exclude-standard` would
|
|
15
|
-
// list (tracked, untracked-not-gitignored), read from the working tree (not
|
|
16
|
-
// from the index), so an uncommitted edit to a tracked file or a newly
|
|
17
|
-
// added untracked source file forces a cache miss. This is the whole point
|
|
18
|
-
// of `run_in_vm`: CI-style checks against the user's project as it exists
|
|
19
|
-
// in the per-issue workspace, post-agent-edits.
|
|
20
|
-
import { createHash } from 'node:crypto';
|
|
21
|
-
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
22
|
-
import path from 'node:path';
|
|
23
|
-
import { actionCacheDir, defaultCacheRoot } from '../reconciler/cache.js';
|
|
24
|
-
import { runProcess } from '../util/process.js';
|
|
25
|
-
export const RUN_IN_VM_CACHE_KIND = 'run_in_vm';
|
|
26
|
-
/**
|
|
27
|
-
* Hash the cache key. Order-stable over env keys so two callers with the
|
|
28
|
-
* same env (but different key insertion order) hit the same cache entry.
|
|
29
|
-
*/
|
|
30
|
-
export async function computeCacheHash(key) {
|
|
31
|
-
const h = createHash('sha256');
|
|
32
|
-
const tree = await workspaceTreeHash(key.workspacePath);
|
|
33
|
-
h.update('tree:');
|
|
34
|
-
h.update(tree);
|
|
35
|
-
h.update('\0cmd:');
|
|
36
|
-
for (const a of key.cmd) {
|
|
37
|
-
h.update(a);
|
|
38
|
-
h.update('\0');
|
|
39
|
-
}
|
|
40
|
-
h.update('env:');
|
|
41
|
-
const keys = Object.keys(key.env).sort();
|
|
42
|
-
for (const k of keys) {
|
|
43
|
-
h.update(k);
|
|
44
|
-
h.update('=');
|
|
45
|
-
h.update(key.env[k] ?? '');
|
|
46
|
-
h.update('\0');
|
|
47
|
-
}
|
|
48
|
-
return h.digest('hex');
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Hash of the workspace's live, .gitignore-aware contents — what the VM
|
|
52
|
-
* command will actually see. Uses `git ls-files --cached --others
|
|
53
|
-
* --exclude-standard -z` to enumerate (cheap, handles .gitignore correctly),
|
|
54
|
-
* then reads each file from the working tree (so uncommitted modifications
|
|
55
|
-
* are captured). Tracked-but-deleted-in-worktree paths are folded in as a
|
|
56
|
-
* deletion marker so removing a file still bumps the hash.
|
|
57
|
-
*
|
|
58
|
-
* Returns `'no-git'` when the workspace is not a git repo so the cache key
|
|
59
|
-
* still computes; the cmd/env contribution still differentiates calls.
|
|
60
|
-
*/
|
|
61
|
-
async function workspaceTreeHash(workspacePath) {
|
|
62
|
-
const lsZ = await runGitCapture(['ls-files', '-z', '--cached', '--others', '--exclude-standard'], workspacePath);
|
|
63
|
-
if (lsZ === null)
|
|
64
|
-
return 'no-git';
|
|
65
|
-
// -z output: NUL-separated paths, possibly with a trailing NUL.
|
|
66
|
-
const paths = lsZ.split('\0').filter((p) => p.length > 0);
|
|
67
|
-
// A path can appear in both --cached and --others (a freshly added but
|
|
68
|
-
// git-add'd file may show up in both lists depending on git's index
|
|
69
|
-
// state); dedupe and sort so the hash is order-stable.
|
|
70
|
-
const unique = Array.from(new Set(paths)).sort();
|
|
71
|
-
const h = createHash('sha256');
|
|
72
|
-
for (const rel of unique) {
|
|
73
|
-
await foldWorkspacePathIntoHash(h, workspacePath, rel);
|
|
74
|
-
}
|
|
75
|
-
return h.digest('hex');
|
|
76
|
-
}
|
|
77
|
-
// Read one workspace path and fold it (or its deletion / error marker) into
|
|
78
|
-
// `h`. Extracted from `workspaceTreeHash` to keep that function under the
|
|
79
|
-
// shell-statement budget; the per-path branching is the same as before.
|
|
80
|
-
async function foldWorkspacePathIntoHash(h, workspacePath, rel) {
|
|
81
|
-
const abs = path.join(workspacePath, rel);
|
|
82
|
-
let buf;
|
|
83
|
-
try {
|
|
84
|
-
buf = await readFile(abs);
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
const code = err.code;
|
|
88
|
-
// ENOENT: tracked file deleted in worktree; record deletion so the
|
|
89
|
-
// cache key differs from "file still present." EISDIR / other errors:
|
|
90
|
-
// record as an error marker so we don't silently bucket two
|
|
91
|
-
// distinguishable states together.
|
|
92
|
-
h.update(code === 'ENOENT' ? 'D\0' : 'E\0');
|
|
93
|
-
h.update(rel);
|
|
94
|
-
h.update('\0');
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
h.update('F\0');
|
|
98
|
-
h.update(rel);
|
|
99
|
-
h.update('\0');
|
|
100
|
-
h.update(buf.length.toString(10));
|
|
101
|
-
h.update('\0');
|
|
102
|
-
h.update(buf);
|
|
103
|
-
}
|
|
104
|
-
// Thin shape adapter: workspace-tree hashing wants `stdout | null` (null on
|
|
105
|
-
// any non-zero/error). The unified `runProcess` returns the full result; we
|
|
106
|
-
// throw away stderr (workspace-tree probes are quiet on the happy path) and
|
|
107
|
-
// project exit_code into the nullable signal. `maxBytes` is raised well above
|
|
108
|
-
// the unified default because `ls-files` output for a non-trivial workspace
|
|
109
|
-
// quickly exceeds 64 KiB; the cache hash MUST see the complete file list.
|
|
110
|
-
async function runGitCapture(args, cwd) {
|
|
111
|
-
const r = await runProcess('git', args, {
|
|
112
|
-
cwd,
|
|
113
|
-
maxBytes: 16 * 1024 * 1024,
|
|
114
|
-
appendErrorToStderr: false,
|
|
115
|
-
});
|
|
116
|
-
return r.exit_code === 0 ? r.stdout : null;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Sanitize an action name for use as a path segment. We validate at parse
|
|
120
|
-
* time (see parseActionsBlock for run_in_vm) but defensively encode here so
|
|
121
|
-
* a future relaxation of the parser rule can't silently make two names
|
|
122
|
-
* collide on the filesystem.
|
|
123
|
-
*/
|
|
124
|
-
function sanitizeNameSegment(name) {
|
|
125
|
-
// Map every char outside [A-Za-z0-9._-] to `_<hex>`; the underscore prefix
|
|
126
|
-
// guarantees the encoded form is unambiguous against a literal "_" because
|
|
127
|
-
// a literal underscore would not be followed by two hex chars... actually
|
|
128
|
-
// since `_` is in the safe set, `_AB` is a possible literal name. To keep
|
|
129
|
-
// collision-freedom we use `%` as the escape sentinel (which is unsafe and
|
|
130
|
-
// therefore always escaped if it appears literally).
|
|
131
|
-
let out = '';
|
|
132
|
-
for (const ch of name) {
|
|
133
|
-
if (/[A-Za-z0-9._-]/.test(ch)) {
|
|
134
|
-
out += ch;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
out += '%' + ch.charCodeAt(0).toString(16).padStart(2, '0');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return out.length > 0 ? out : '_';
|
|
141
|
-
}
|
|
142
|
-
function cacheNameDir(cacheRoot, name) {
|
|
143
|
-
return path.join(actionCacheDir(cacheRoot, RUN_IN_VM_CACHE_KIND), sanitizeNameSegment(name));
|
|
144
|
-
}
|
|
145
|
-
function cacheEntryDir(cacheRoot, name, hash) {
|
|
146
|
-
return path.join(cacheNameDir(cacheRoot, name), hash);
|
|
147
|
-
}
|
|
148
|
-
export async function readCache(cacheRoot, name, hash) {
|
|
149
|
-
const dir = cacheEntryDir(cacheRoot, name, hash);
|
|
150
|
-
try {
|
|
151
|
-
const buf = await readFile(path.join(dir, 'result.json'), 'utf8');
|
|
152
|
-
const parsed = JSON.parse(buf);
|
|
153
|
-
if (typeof parsed.exit_code !== 'number')
|
|
154
|
-
return null;
|
|
155
|
-
return parsed;
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
export async function writeCache(cacheRoot, name, hash, result) {
|
|
162
|
-
const dir = cacheEntryDir(cacheRoot, name, hash);
|
|
163
|
-
await mkdir(dir, { recursive: true });
|
|
164
|
-
await writeFile(path.join(dir, 'result.json'), JSON.stringify(result), 'utf8');
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Drop every cache entry for a named check. Used by `symphony rerun
|
|
168
|
-
* --check=<name>`: the operator names the check, not the workspace, and the
|
|
169
|
-
* orchestrator's next dispatch into the state hosting it re-executes
|
|
170
|
-
* because the namespace directory is empty.
|
|
171
|
-
*
|
|
172
|
-
* Per-name (rather than per-hash) invalidation is the cache-layout fix for
|
|
173
|
-
* the rerun CLI: the CLI has no per-issue workspace to hash against, so any
|
|
174
|
-
* hash-based invalidation would key off the wrong workspace and miss the
|
|
175
|
-
* entry the per-issue execution actually wrote. Dropping the namespace dir
|
|
176
|
-
* sidesteps the problem entirely.
|
|
177
|
-
*/
|
|
178
|
-
export async function invalidateCacheByName(cacheRoot, name) {
|
|
179
|
-
const dir = cacheNameDir(cacheRoot, name);
|
|
180
|
-
try {
|
|
181
|
-
await rm(dir, { recursive: true, force: true });
|
|
182
|
-
}
|
|
183
|
-
catch {
|
|
184
|
-
// Best-effort.
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
/** Default cache root mirrors the bake resource. */
|
|
188
|
-
export function runInVmCacheRoot() {
|
|
189
|
-
return defaultCacheRoot();
|
|
190
|
-
}
|
|
191
|
-
//# sourceMappingURL=cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/actions/cache.ts"],"names":[],"mappings":"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"}
|
package/dist/actions/effects.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// Effects-as-data foundation (issue 68): pure planner half of the
|
|
2
|
-
// planActions/runEffects split. Effects are plain data describing IO so the
|
|
3
|
-
// "decide what to do" half is unit-testable without spawning processes.
|
|
4
|
-
// Issues 69/70 build on the `Effect` union.
|
|
5
|
-
import { renderTree, TemplateError } from './templating.js';
|
|
6
|
-
const DEFAULT_RETRY_COUNT = 3, DEFAULT_RETRY_BACKOFF_MS = 1_000;
|
|
7
|
-
/** Pure planner — same inputs always produce the same `Effect[]`. */
|
|
8
|
-
export function planActions(actions, ctx) {
|
|
9
|
-
return actions.map((action, index) => {
|
|
10
|
-
const snapshotKey = actionSnapshotKey(action, index);
|
|
11
|
-
try {
|
|
12
|
-
const rendered = renderTree(action, ctx);
|
|
13
|
-
return {
|
|
14
|
-
kind: 'run',
|
|
15
|
-
snapshotKey,
|
|
16
|
-
rendered,
|
|
17
|
-
predicate: rendered.if ?? undefined,
|
|
18
|
-
policy: effectivePolicy(action.on_error),
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
catch (err) {
|
|
22
|
-
const error = err instanceof TemplateError ? err.message : err.message;
|
|
23
|
-
return { kind: 'render_failed', snapshotKey, error };
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
function effectivePolicy(p) {
|
|
28
|
-
return {
|
|
29
|
-
retry: {
|
|
30
|
-
count: p?.retry?.count ?? DEFAULT_RETRY_COUNT,
|
|
31
|
-
backoff_ms: p?.retry?.backoff_ms ?? DEFAULT_RETRY_BACKOFF_MS,
|
|
32
|
-
},
|
|
33
|
-
then: p?.then ?? 'abort',
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function actionSnapshotKey(action, idx) {
|
|
37
|
-
if (action.name && action.name.length > 0)
|
|
38
|
-
return `${action.kind}:${action.name}`;
|
|
39
|
-
return `${action.kind}:#${idx}`;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=effects.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"effects.js","sourceRoot":"","sources":["../../src/actions/effects.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,4EAA4E;AAC5E,wEAAwE;AACxE,4CAA4C;AAG5C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE5D,MAAM,mBAAmB,GAAG,CAAC,EAAE,wBAAwB,GAAG,KAAK,CAAC;AAqBhE,qEAAqE;AACrE,MAAM,UAAU,WAAW,CAAC,OAAkC,EAAE,GAAkB;IAChF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACnC,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACzC,OAAO;gBACL,IAAI,EAAE,KAAK;gBACX,WAAW;gBACX,QAAQ;gBACR,SAAS,EAAE,QAAQ,CAAC,EAAE,IAAI,SAAS;gBACnC,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC;aACzC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,GAAG,YAAY,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAE,GAAa,CAAC,OAAO,CAAC;YAClF,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QACvD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,CAAgC;IACvD,OAAO;QACL,KAAK,EAAE;YACL,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,mBAAmB;YAC7C,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,IAAI,wBAAwB;SAC7D;QACD,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,OAAO;KACzB,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAsB,EAAE,GAAW;IAC5D,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IAClF,OAAO,GAAG,MAAM,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;AAClC,CAAC"}
|