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,75 @@
|
|
|
1
|
+
// FCIS rewrite — canonical scalar coercers for YAML/JSON-decoded front-matter
|
|
2
|
+
// and config values. Pure + synchronous; imports nothing (src/types not even
|
|
3
|
+
// needed). This is the ONE home for the `asString`/`asInt`/`asStringList`/
|
|
4
|
+
// `asNumber`/`asTimestamp` family that had drifted across ~5 core modules.
|
|
5
|
+
//
|
|
6
|
+
// 100% PURE + SYNCHRONOUS. No IO, no node: imports, no clock/randomness.
|
|
7
|
+
//
|
|
8
|
+
// ─── Resolved drift (the reason this module exists) ──────────────────────────
|
|
9
|
+
// • asInt: the issue parser used `Number.isInteger` (rejects a fractional
|
|
10
|
+
// `2.5` → null) while the actions/workflow parsers used `Number.isFinite`
|
|
11
|
+
// + `Math.trunc` (accepts `2.5` → 2). The workflow-config path (20+ call
|
|
12
|
+
// sites: timeouts, counts) is the dominant consumer and relies on the
|
|
13
|
+
// truncating form, so `isFinite + Math.trunc` is canonical. Pinned by
|
|
14
|
+
// tests/core/coerce.test.ts.
|
|
15
|
+
// • asString: the http renderer carried a `&& v.length > 0` length-guard the
|
|
16
|
+
// three parse copies did not. The canonical (no length-guard) matches the
|
|
17
|
+
// issue-parsing contract; emptiness is the CALLER's concern (most sites
|
|
18
|
+
// already truthiness-check the result). Pinned by tests/core/coerce.test.ts.
|
|
19
|
+
/** A string value, or null. No length guard — an empty string passes through. */
|
|
20
|
+
export function asString(v) {
|
|
21
|
+
return typeof v === 'string' ? v : null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* An integer, or null. Accepts a finite number (truncated toward zero) or a
|
|
25
|
+
* decimal-digit string; everything else → null. `isFinite + Math.trunc` (NOT
|
|
26
|
+
* `Number.isInteger`) is canonical: a fractional `2.5` truncates to `2`.
|
|
27
|
+
*/
|
|
28
|
+
export function asInt(v) {
|
|
29
|
+
if (typeof v === 'number' && Number.isFinite(v))
|
|
30
|
+
return Math.trunc(v);
|
|
31
|
+
if (typeof v === 'string' && /^-?\d+$/.test(v))
|
|
32
|
+
return parseInt(v, 10);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Like {@link asInt} but with a `fallback` for when the value is absent or
|
|
37
|
+
* un-coercible (the workflow-config form — every config knob has a default).
|
|
38
|
+
*/
|
|
39
|
+
export function asIntOr(v, fallback) {
|
|
40
|
+
return asInt(v) ?? fallback;
|
|
41
|
+
}
|
|
42
|
+
/** The string elements of an array, or `[]`. Non-string elements are dropped. */
|
|
43
|
+
export function asStringList(v) {
|
|
44
|
+
if (Array.isArray(v))
|
|
45
|
+
return v.filter((x) => typeof x === 'string');
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
/** Like {@link asStringList} but returns `fallback` when `v` is not an array. */
|
|
49
|
+
export function asStringListOr(v, fallback) {
|
|
50
|
+
if (Array.isArray(v))
|
|
51
|
+
return v.filter((x) => typeof x === 'string');
|
|
52
|
+
return fallback;
|
|
53
|
+
}
|
|
54
|
+
/** A finite number, or null. (No truncation — fractional values pass through.) */
|
|
55
|
+
export function asNumber(v) {
|
|
56
|
+
if (typeof v === 'number' && Number.isFinite(v))
|
|
57
|
+
return v;
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A timestamp as a string. A non-empty string passes through; everything else →
|
|
62
|
+
* null. The empty string is NOT a timestamp (folds the old `formatTimestamp`
|
|
63
|
+
* length-guard in, which the bare `asTimestamp` lacked).
|
|
64
|
+
*
|
|
65
|
+
* Core coercers operate over PLAIN DATA only, so this NEVER sees a `Date`: the
|
|
66
|
+
* `yaml` lib auto-decodes ISO timestamps to `Date`, but the shell front-matter
|
|
67
|
+
* decode (shell/interp/tracker-parse.ts:normalizeDates) renders any decoded `Date`
|
|
68
|
+
* back to its ISO string at the boundary before core consumes the map.
|
|
69
|
+
*/
|
|
70
|
+
export function asTimestamp(v) {
|
|
71
|
+
if (typeof v === 'string')
|
|
72
|
+
return v.length > 0 ? v : null;
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=coerce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coerce.js","sourceRoot":"","sources":["../../../src/core/coerce.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,EAAE;AACF,yEAAyE;AACzE,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,0EAA0E;AAC1E,0EAA0E;AAC1E,iCAAiC;AACjC,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,iFAAiF;AAEjF,iFAAiF;AACjF,MAAM,UAAU,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,CAAU;IAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtE,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,CAAU,EAAE,QAAgB;IAClD,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC;AAC9B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;IACjF,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,CAAU,EAAE,QAAkB;IAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;IACjF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CAAC,CAAU;IACjC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,CAAU;IACpC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// FCIS rewrite — the ONE shared account-id guard (codex review HIGH).
|
|
2
|
+
//
|
|
3
|
+
// `validAccountId` + its `UUID_RE` were inlined BYTE-IDENTICAL across three
|
|
4
|
+
// credential modules (identity.ts / fake-creds.ts / shape.ts), each commenting
|
|
5
|
+
// "SHARED" / "codex review HIGH". This is the single canonical home; those three
|
|
6
|
+
// modules import and re-export it so every existing importer keeps its specifier.
|
|
7
|
+
//
|
|
8
|
+
// 100% PURE + SYNCHRONOUS. No IO, no node: imports, no clock/randomness.
|
|
9
|
+
/** Canonical RFC-4122-shaped UUID (any case). */
|
|
10
|
+
export const UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
11
|
+
/**
|
|
12
|
+
* Defense-in-depth guard for a credential `account_id`: returns the value iff it
|
|
13
|
+
* is a UUID, else null. A hostile/malformed `account_id` (a token, a JWT, a path
|
|
14
|
+
* fragment) must NOT flow into the placeholder/identity machinery — it is dropped
|
|
15
|
+
* to null rather than trusted.
|
|
16
|
+
*/
|
|
17
|
+
export function validAccountId(v) {
|
|
18
|
+
return v !== null && UUID_RE.test(v) ? v : null;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=account-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-id.js","sourceRoot":"","sources":["../../../../src/core/credential/account-id.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,iFAAiF;AACjF,kFAAkF;AAClF,EAAE;AACF,yEAAyE;AAEzE,iDAAiD;AACjD,MAAM,CAAC,MAAM,OAAO,GAClB,+EAA+E,CAAC;AAElF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,CAAgB;IAC7C,OAAO,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// FCIS rewrite — pure per-adapter staged-config generation.
|
|
2
|
+
//
|
|
3
|
+
// Ported faithfully from the reference `src/agent/adapters.ts`:
|
|
4
|
+
// • stageClaudeIdentity — the claude settings.json effortLevel file + the
|
|
5
|
+
// non-secret identity file content.
|
|
6
|
+
// • stageCodexPlaceholderAuth — the fake codex auth.json placeholder shape.
|
|
7
|
+
//
|
|
8
|
+
// In the reference these were `async` because they also did host IO (read
|
|
9
|
+
// `~/.claude.json`, write the file 0600 with symlink-race defenses, resolve the
|
|
10
|
+
// `.git/` vs `.symphony-runtime/` staging root). That IO is the SHELL's job in
|
|
11
|
+
// the FCIS split. What this module owns — and the "critic gap" the synthesis
|
|
12
|
+
// called out — is the PURE content/path decision: given the chosen model /
|
|
13
|
+
// effort / already-extracted host identity, return the `StagedFileSpec[]` that
|
|
14
|
+
// describe what file must land where in the guest, with what bytes. Zero IO, no
|
|
15
|
+
// node builtins, no clock/random — every input is plain data supplied by the
|
|
16
|
+
// caller (the shell reads `~/.claude.json` via `HostIdentityReaders` and passes
|
|
17
|
+
// the extracted `ClaudeIdentity` in; this module never touches the filesystem).
|
|
18
|
+
//
|
|
19
|
+
// A `StagedFileSpec` is `{ stagedName, content, guestPath }` (src/types/credentials):
|
|
20
|
+
// • stagedName — the name inside the workspace runtime staging dir; the shell
|
|
21
|
+
// composes the actual on-host path (`.git/symphony-runtime/...`
|
|
22
|
+
// or `.symphony-runtime/...`) — that resolution stays in the shell.
|
|
23
|
+
// • content — the exact UTF-8 bytes to write.
|
|
24
|
+
// • guestPath — the absolute path inside the VM the dispatcher materializes to.
|
|
25
|
+
//
|
|
26
|
+
// Faithful semantics preserved from the reference:
|
|
27
|
+
// • claude settings.json: `{ "effortLevel": <effort> }`, compact JSON, copied
|
|
28
|
+
// to /root/.claude/settings.json (matches the reference effortInjection).
|
|
29
|
+
// • claude identity: ONLY `{ oauthAccount: { accountUuid, organizationUuid } }`
|
|
30
|
+
// — no token strings, no device/session ids, no local config. Skipped
|
|
31
|
+
// (null) when no identity was extracted (reference returned null).
|
|
32
|
+
// • codex placeholder auth.json: `{ OPENAI_API_KEY: <placeholder>, auth_mode:
|
|
33
|
+
// 'apikey' }`, NO real credential, NO OAuth tokens block.
|
|
34
|
+
// ── claude settings.json (effortLevel) + non-secret identity ───────────────
|
|
35
|
+
/** Absolute guest path the claude settings.json (effortLevel) lands at. */
|
|
36
|
+
export const CLAUDE_SETTINGS_GUEST_PATH = '/root/.claude/settings.json';
|
|
37
|
+
/** Absolute guest path the non-secret claude identity file lands at. */
|
|
38
|
+
export const CLAUDE_IDENTITY_GUEST_PATH = '/root/.claude.json';
|
|
39
|
+
/**
|
|
40
|
+
* The claude `effortLevel` settings.json spec. Mirrors the reference
|
|
41
|
+
* `ADAPTERS.claude.effortInjection`: a compact `{ "effortLevel": <effort> }`
|
|
42
|
+
* copied to /root/.claude/settings.json before the adapter starts. Valid values
|
|
43
|
+
* (`low|medium|high|xhigh|max`) are gated per-model by claude-agent-acp; symphony
|
|
44
|
+
* lets the adapter reject invalid choices rather than mirroring the gate, so we
|
|
45
|
+
* emit whatever non-empty string the caller supplies.
|
|
46
|
+
*/
|
|
47
|
+
export function claudeEffortSpec(effort) {
|
|
48
|
+
return {
|
|
49
|
+
stagedName: 'claude-settings.json',
|
|
50
|
+
content: JSON.stringify({ effortLevel: effort }),
|
|
51
|
+
guestPath: CLAUDE_SETTINGS_GUEST_PATH,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The non-secret claude identity staged-file spec (pure replacement for the
|
|
56
|
+
* reference `stageClaudeIdentity`, minus the host `~/.claude.json` read — that
|
|
57
|
+
* read + the `oauthAccount` extraction is the shell's `HostIdentityReaders` job;
|
|
58
|
+
* this module receives the already-extracted identity).
|
|
59
|
+
*
|
|
60
|
+
* Defensive shape (faithful): ONLY `{ oauthAccount: { accountUuid,
|
|
61
|
+
* organizationUuid } }` — NO token strings, NO device/session ids, NO local
|
|
62
|
+
* config. Returns `null` when no identity is available, exactly as the reference
|
|
63
|
+
* returned null when `~/.claude.json` was missing or had no `oauthAccount`
|
|
64
|
+
* (staging the identity is defense in depth, not a hard gate on dispatch).
|
|
65
|
+
*/
|
|
66
|
+
export function claudeIdentitySpec(identity) {
|
|
67
|
+
if (!identity)
|
|
68
|
+
return null;
|
|
69
|
+
return {
|
|
70
|
+
stagedName: 'claude.json',
|
|
71
|
+
content: JSON.stringify({
|
|
72
|
+
oauthAccount: {
|
|
73
|
+
accountUuid: identity.accountUuid,
|
|
74
|
+
organizationUuid: identity.organizationUuid,
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
guestPath: CLAUDE_IDENTITY_GUEST_PATH,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// ── codex placeholder auth.json ────────────────────────────────────────────
|
|
81
|
+
/** Absolute guest path the fake codex auth.json lands at. */
|
|
82
|
+
export const CODEX_AUTH_GUEST_PATH = '/root/.codex/auth.json';
|
|
83
|
+
/** Placeholder bearer staged into the fake codex auth.json (NOT a real token). */
|
|
84
|
+
export const CODEX_PLACEHOLDER_API_KEY = 'sk-symphony-placeholder';
|
|
85
|
+
/**
|
|
86
|
+
* The fake codex `~/.codex/auth.json` placeholder spec (pure replacement for the
|
|
87
|
+
* reference `stageCodexPlaceholderAuth`, minus the host write). It exists PURELY
|
|
88
|
+
* to satisfy codex-acp's session-init credential check; it contains NO real
|
|
89
|
+
* credential — `OPENAI_API_KEY` is a token-shaped placeholder and there is no
|
|
90
|
+
* OAuth `tokens` block — so codex falls through to the env `OPENAI_API_KEY`
|
|
91
|
+
* placeholder as its request bearer and Gondolin substitutes the real token at
|
|
92
|
+
* egress. `auth_mode: 'apikey'` forces the API-key path, never an OAuth
|
|
93
|
+
* handshake; `last_refresh` is omitted (no OAuth tokens to age).
|
|
94
|
+
*/
|
|
95
|
+
export function codexPlaceholderAuthSpec() {
|
|
96
|
+
return {
|
|
97
|
+
stagedName: 'auth.json',
|
|
98
|
+
content: JSON.stringify({
|
|
99
|
+
OPENAI_API_KEY: CODEX_PLACEHOLDER_API_KEY,
|
|
100
|
+
auth_mode: 'apikey',
|
|
101
|
+
}),
|
|
102
|
+
guestPath: CODEX_AUTH_GUEST_PATH,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Aggregate every staged-file spec one adapter dispatch needs into a single
|
|
107
|
+
* `StagedFileSpec[]`, in a stable order (identity/config first, then the
|
|
108
|
+
* effort/model overlays). Pure: the shell materializes each spec into the
|
|
109
|
+
* workspace runtime tree + the guest. No spec is ever a secret — the only
|
|
110
|
+
* credential bytes are token-shaped placeholders.
|
|
111
|
+
*
|
|
112
|
+
* Per-adapter (faithful to the reference staging in `runner.stageAdapterExtras`):
|
|
113
|
+
* • claude — optional non-secret identity (when extracted) + optional
|
|
114
|
+
* effortLevel settings.json (when effort is set).
|
|
115
|
+
* • codex — the fake placeholder auth.json (always; the init check needs it).
|
|
116
|
+
*/
|
|
117
|
+
export function buildStagedConfigs(input) {
|
|
118
|
+
const specs = [];
|
|
119
|
+
switch (input.adapter) {
|
|
120
|
+
case 'claude': {
|
|
121
|
+
const identity = claudeIdentitySpec(input.claudeIdentity);
|
|
122
|
+
if (identity)
|
|
123
|
+
specs.push(identity);
|
|
124
|
+
if (input.effort && input.effort.length > 0) {
|
|
125
|
+
specs.push(claudeEffortSpec(input.effort));
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case 'codex': {
|
|
130
|
+
specs.push(codexPlaceholderAuthSpec());
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return specs;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=adapter-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-config.js","sourceRoot":"","sources":["../../../../src/core/credential/adapter-config.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,gEAAgE;AAChE,mFAAmF;AACnF,qEAAqE;AACrE,+EAA+E;AAC/E,EAAE;AACF,0EAA0E;AAC1E,gFAAgF;AAChF,+EAA+E;AAC/E,6EAA6E;AAC7E,2EAA2E;AAC3E,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,gFAAgF;AAChF,gFAAgF;AAChF,EAAE;AACF,sFAAsF;AACtF,gFAAgF;AAChF,iFAAiF;AACjF,qFAAqF;AACrF,mDAAmD;AACnD,mFAAmF;AACnF,EAAE;AACF,mDAAmD;AACnD,gFAAgF;AAChF,8EAA8E;AAC9E,kFAAkF;AAClF,0EAA0E;AAC1E,uEAAuE;AACvE,gFAAgF;AAChF,8DAA8D;AAS9D,8EAA8E;AAE9E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,0BAA0B,GAAG,6BAA6B,CAAC;AAExE,wEAAwE;AACxE,MAAM,CAAC,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO;QACL,UAAU,EAAE,sBAAsB;QAClC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QAChD,SAAS,EAAE,0BAA0B;KACtC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAA+B;IAChE,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO;QACL,UAAU,EAAE,aAAa;QACzB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;YACtB,YAAY,EAAE;gBACZ,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;aAC5C;SACF,CAAC;QACF,SAAS,EAAE,0BAA0B;KACtC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAE9E,6DAA6D;AAC7D,MAAM,CAAC,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAE9D,kFAAkF;AAClF,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAyB,CAAC;AAEnE;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO;QACL,UAAU,EAAE,WAAW;QACvB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;YACtB,cAAc,EAAE,yBAAyB;YACzC,SAAS,EAAE,QAAQ;SACpB,CAAC;QACF,SAAS,EAAE,qBAAqB;KACjC,CAAC;AACJ,CAAC;AAeD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwB;IACzD,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,QAAQ,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAC1D,IAAI,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5C,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7C,CAAC;YACD,MAAM;QACR,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC;YACvC,MAAM;QACR,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// FCIS rewrite — PURE credential availability classification.
|
|
2
|
+
//
|
|
3
|
+
// Ports the pure half of the original `src/agent/adapter-names.ts`:
|
|
4
|
+
// codexCredentialAvailable, codexMissingCredentialMessage,
|
|
5
|
+
// host{Claude,Codex}CredentialPath, isKnownAdapter / KNOWN_ADAPTER_IDS.
|
|
6
|
+
//
|
|
7
|
+
// Critic gap this closes: availability classification is shared by BOTH the
|
|
8
|
+
// doctor check and the startup probe, so it must live in the core (one source of
|
|
9
|
+
// truth) rather than being re-implemented per call site.
|
|
10
|
+
//
|
|
11
|
+
// 100% synchronous, zero IO, imports ONLY from src/types.
|
|
12
|
+
//
|
|
13
|
+
// How the original's impure dependencies are made pure here:
|
|
14
|
+
// * `os.homedir()` (used to build the host credential paths) is replaced
|
|
15
|
+
// by an INJECTED `homeDir: string`. The shell derives it once (os.homedir())
|
|
16
|
+
// and threads it in; the core reads no real environment. This mirrors the
|
|
17
|
+
// homeDir(env) convention already used in src/core/workflow/parse.ts.
|
|
18
|
+
// * `node:path.join` is replaced by a tiny pure POSIX join (joinPath). The
|
|
19
|
+
// orchestrator targets Linux/macOS hosts, so POSIX semantics are faithful.
|
|
20
|
+
// * `NodeJS.ProcessEnv` becomes `WorkflowEnv` (Record<string, string|undefined>),
|
|
21
|
+
// the type already used across the core for injected environments.
|
|
22
|
+
//
|
|
23
|
+
// The actual file reads stay in the shell: the shell reads the credential file
|
|
24
|
+
// (passing its text, or `null` when absent/unreadable) and the env in here, so
|
|
25
|
+
// these functions mirror the host's egress read path EXACTLY — the startup probe
|
|
26
|
+
// accepts a dispatch iff a real dispatch would resolve a credential.
|
|
27
|
+
import { joinPosixParts } from '../path.js';
|
|
28
|
+
import { nonEmptyString } from './strings.js';
|
|
29
|
+
// ─── known-adapter registry ──────────────────────────────────────────────────
|
|
30
|
+
//
|
|
31
|
+
// The seam between the config layer and the IO adapter layer: both sides agree
|
|
32
|
+
// on which adapter ids exist. The full adapter *profile* lives elsewhere
|
|
33
|
+
// (AdapterProfile / the shell's adapter registry); this is only the id set.
|
|
34
|
+
export const KNOWN_ADAPTER_IDS = ['claude', 'codex'];
|
|
35
|
+
export function isKnownAdapter(id) {
|
|
36
|
+
return KNOWN_ADAPTER_IDS.includes(id);
|
|
37
|
+
}
|
|
38
|
+
// Host credential paths use the canonical variadic `joinPosixParts` from
|
|
39
|
+
// core/path.ts (the old local `joinPath` was byte-identical to it).
|
|
40
|
+
const joinPath = joinPosixParts;
|
|
41
|
+
// ─── host credential paths ───────────────────────────────────────────────────
|
|
42
|
+
//
|
|
43
|
+
// Absolute paths to the host's credential files. The host reads these to
|
|
44
|
+
// substitute the live access token into the outbound request at Gondolin egress
|
|
45
|
+
// (the guest only ever holds a token-shaped placeholder); the startup probe
|
|
46
|
+
// reads them once so a completely missing credential fails fast with a clear
|
|
47
|
+
// message instead of an opaque mid-dispatch error.
|
|
48
|
+
/** Absolute path to the host's claude OAuth credential file (`~/.claude/.credentials.json`). */
|
|
49
|
+
export function hostClaudeCredentialPath(homeDir) {
|
|
50
|
+
return joinPath(homeDir, '.claude', '.credentials.json');
|
|
51
|
+
}
|
|
52
|
+
/** Absolute path to the host's codex credential file (`~/.codex/auth.json`). */
|
|
53
|
+
export function hostCodexCredentialPath(homeDir) {
|
|
54
|
+
return joinPath(homeDir, '.codex', 'auth.json');
|
|
55
|
+
}
|
|
56
|
+
// ─── codex credential resolution ─────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* Pure: does codex have a resolvable credential from either valid source? The
|
|
59
|
+
* host reads two — the `~/.codex/auth.json` token (a ChatGPT-OAuth
|
|
60
|
+
* `tokens.access_token` or a top-level `OPENAI_API_KEY`) or an `OPENAI_API_KEY`
|
|
61
|
+
* env var. The shell reads the file (passing `null` when absent/unreadable) and
|
|
62
|
+
* its env in; this mirrors the host's `extractCodexToken` + env fallback so the
|
|
63
|
+
* startup probe accepts exactly when a dispatch would.
|
|
64
|
+
*/
|
|
65
|
+
export function codexCredentialAvailable(authFileText, env) {
|
|
66
|
+
if (nonEmptyString(env['OPENAI_API_KEY']))
|
|
67
|
+
return true;
|
|
68
|
+
if (authFileText === null)
|
|
69
|
+
return false;
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(authFileText);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return codexAuthFileHasToken(parsed);
|
|
78
|
+
}
|
|
79
|
+
/** Human-readable explanation of which codex credential sources were checked. */
|
|
80
|
+
export function codexMissingCredentialMessage(homeDir) {
|
|
81
|
+
return `adapter "codex" requires a host credential, but none is available: neither a token in ${hostCodexCredentialPath(homeDir)} (ChatGPT-OAuth tokens.access_token or OPENAI_API_KEY) nor an OPENAI_API_KEY environment variable is present`;
|
|
82
|
+
}
|
|
83
|
+
function codexAuthFileHasToken(parsed) {
|
|
84
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
85
|
+
return false;
|
|
86
|
+
const root = parsed;
|
|
87
|
+
const tokens = root['tokens'];
|
|
88
|
+
if (tokens && typeof tokens === 'object' && !Array.isArray(tokens)) {
|
|
89
|
+
if (nonEmptyString(tokens['access_token']))
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
return nonEmptyString(root['OPENAI_API_KEY']) !== null;
|
|
93
|
+
}
|
|
94
|
+
// nonEmptyString (string-valued) is the shared credential helper from
|
|
95
|
+
// ./strings.js — imported at the top. The boolean-returning local copy that
|
|
96
|
+
// used to live here was the §3a divergence; call sites that need a boolean use
|
|
97
|
+
// `nonEmptyString(...) !== null`, the rest rely on the truthy string/null.
|
|
98
|
+
//# sourceMappingURL=availability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"availability.js","sourceRoot":"","sources":["../../../../src/core/credential/availability.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,oEAAoE;AACpE,6DAA6D;AAC7D,0EAA0E;AAC1E,EAAE;AACF,4EAA4E;AAC5E,iFAAiF;AACjF,yDAAyD;AACzD,EAAE;AACF,0DAA0D;AAC1D,EAAE;AACF,6DAA6D;AAC7D,2EAA2E;AAC3E,iFAAiF;AACjF,8EAA8E;AAC9E,0EAA0E;AAC1E,6EAA6E;AAC7E,+EAA+E;AAC/E,oFAAoF;AACpF,uEAAuE;AACvE,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,iFAAiF;AACjF,qEAAqE;AAIrE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,gFAAgF;AAChF,EAAE;AACF,+EAA+E;AAC/E,yEAAyE;AACzE,4EAA4E;AAE5E,MAAM,CAAC,MAAM,iBAAiB,GAA4B,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAE9E,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,OAAQ,iBAAuC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,yEAAyE;AACzE,oEAAoE;AACpE,MAAM,QAAQ,GAAG,cAAc,CAAC;AAEhC,gFAAgF;AAChF,EAAE;AACF,yEAAyE;AACzE,gFAAgF;AAChF,4EAA4E;AAC5E,6EAA6E;AAC7E,mDAAmD;AAEnD,gGAAgG;AAChG,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,OAAO,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;AAC3D,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,OAAO,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AAClD,CAAC;AAED,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CACtC,YAA2B,EAC3B,GAAgB;IAEhB,IAAI,cAAc,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,6BAA6B,CAAC,OAAe;IAC3D,OAAO,yFAAyF,uBAAuB,CACrH,OAAO,CACR,8GAA8G,CAAC;AAClH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAe;IAC5C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACjF,MAAM,IAAI,GAAG,MAAiC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnE,IAAI,cAAc,CAAE,MAAkC,CAAC,cAAc,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACvF,CAAC;IACD,OAAO,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,IAAI,CAAC;AACzD,CAAC;AAED,sEAAsE;AACtE,4EAA4E;AAC5E,+EAA+E;AAC/E,2EAA2E"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
// FCIS rewrite — PURE token/JWT extraction over ALREADY-PARSED JSON.
|
|
2
|
+
//
|
|
3
|
+
// Functional core: every export here is a pure, synchronous (data) -> data
|
|
4
|
+
// function. No IO, no clock, no randomness, no node: imports, no process/env
|
|
5
|
+
// read. Imports ONLY from src/types.
|
|
6
|
+
//
|
|
7
|
+
// SECURITY-LOAD-BEARING. This is the "impureCoreRisk fix" half of the original
|
|
8
|
+
// src/agent/credential-extractors.ts + src/agent/adapter-names.ts: the original
|
|
9
|
+
// extractors mixed pure parsing with host IO (file reads, https requests, flock,
|
|
10
|
+
// refresher spawns, `process.env`). Here we keep ONLY the pure decisions:
|
|
11
|
+
// - extractClaudeToken — pull accessToken+expiry out of parsed claude creds
|
|
12
|
+
// - extractCodexToken — prefer ChatGPT-OAuth tokens.access_token (NEVER
|
|
13
|
+
// reads refresh_token), else OPENAI_API_KEY; sets
|
|
14
|
+
// chatgptOAuth + JWT-derived expiry
|
|
15
|
+
// - decodeJwtExpMs — read a JWT `exp` claim (ms), signature unverified
|
|
16
|
+
// - coerceExpiresAtMs — number | numeric-string | date-string -> ms|null
|
|
17
|
+
// - codexEnvFallback — OPENAI_API_KEY env fallback as a codex credential
|
|
18
|
+
//
|
|
19
|
+
// The host invariant ("only the host refreshes; the guest never sees a refresh
|
|
20
|
+
// token") is preserved at the extraction boundary: extractCodexToken NEVER reads
|
|
21
|
+
// `tokens.refresh_token`. All host file/env reads that previously lived here are
|
|
22
|
+
// now `credential.probe` Effects performed by the shell; the SHELL parses the
|
|
23
|
+
// JSON and the host environment, then hands the already-parsed values to these
|
|
24
|
+
// functions.
|
|
25
|
+
import { nonEmptyString } from './strings.js';
|
|
26
|
+
// ── claude ────────────────────────────────────────────────────────────────────
|
|
27
|
+
/**
|
|
28
|
+
* Pull `accessToken` and `expiresAt` out of the already-parsed claude
|
|
29
|
+
* credentials JSON. The shape `claude` writes is
|
|
30
|
+
* `{ claudeAiOauth: { accessToken, expiresAt, ... } }`, but we tolerate flat
|
|
31
|
+
* top-level fields too for forward compatibility. Returns null when no non-empty
|
|
32
|
+
* access token is present.
|
|
33
|
+
*/
|
|
34
|
+
export function extractClaudeToken(parsed) {
|
|
35
|
+
if (!parsed || typeof parsed !== 'object')
|
|
36
|
+
return null;
|
|
37
|
+
const root = parsed;
|
|
38
|
+
const oauth = root['claudeAiOauth'];
|
|
39
|
+
const candidate = oauth && typeof oauth === 'object' && !Array.isArray(oauth)
|
|
40
|
+
? oauth
|
|
41
|
+
: root;
|
|
42
|
+
const accessToken = candidate['accessToken'];
|
|
43
|
+
if (typeof accessToken !== 'string' || accessToken.length === 0)
|
|
44
|
+
return null;
|
|
45
|
+
const expiresAtMs = coerceExpiresAtMs(candidate['expiresAt']);
|
|
46
|
+
return { accessToken, expiresAtMs };
|
|
47
|
+
}
|
|
48
|
+
// ── codex ─────────────────────────────────────────────────────────────────────
|
|
49
|
+
/**
|
|
50
|
+
* Pull the access token out of the already-parsed codex `~/.codex/auth.json`.
|
|
51
|
+
* Two flavours live there: a ChatGPT-OAuth `tokens.access_token` and an API-key
|
|
52
|
+
* `OPENAI_API_KEY`. We prefer the OAuth access token, then fall back to the API
|
|
53
|
+
* key. The `tokens.refresh_token` is NEVER read — it stays host-side so an in-VM
|
|
54
|
+
* agent cannot rotate (and thereby invalidate) the host's credential.
|
|
55
|
+
*
|
|
56
|
+
* For the ChatGPT-OAuth token, `expiresAtMs` is decoded from the access-token
|
|
57
|
+
* JWT `exp` claim so the proactive pre-expiry refresh tick can fire; a non-JWT /
|
|
58
|
+
* malformed token decodes to null (safe degradation to on-demand re-read). The
|
|
59
|
+
* API-key fallback keeps `expiresAtMs: null` (API keys do not expire/refresh).
|
|
60
|
+
*/
|
|
61
|
+
export function extractCodexToken(parsed) {
|
|
62
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
63
|
+
return null;
|
|
64
|
+
const root = parsed;
|
|
65
|
+
const tokens = codexTokensObject(root);
|
|
66
|
+
if (tokens !== null) {
|
|
67
|
+
const oauth = nonEmptyString(tokens['access_token']);
|
|
68
|
+
if (oauth !== null) {
|
|
69
|
+
// ChatGPT-OAuth subscription credential → ChatGPT-backend route. The
|
|
70
|
+
// account id (when present) becomes the `chatgpt-account-id` header, but
|
|
71
|
+
// routing keys on `chatgptOAuth`: this token is ALWAYS rejected by the
|
|
72
|
+
// platform API, with or without the account id.
|
|
73
|
+
return {
|
|
74
|
+
accessToken: oauth,
|
|
75
|
+
expiresAtMs: decodeJwtExpMs(oauth),
|
|
76
|
+
chatgptOAuth: true,
|
|
77
|
+
chatgptAccountId: nonEmptyString(tokens['account_id']),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// API-key credential: forward to the platform API (api.openai.com/v1) unchanged.
|
|
82
|
+
const apiKey = nonEmptyString(root['OPENAI_API_KEY']);
|
|
83
|
+
return apiKey === null ? null : { accessToken: apiKey, expiresAtMs: null };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Pure: read `OPENAI_API_KEY` from a host-environment snapshot as a codex
|
|
87
|
+
* credential fallback. The shell passes the env in (a `credential.probe`-adjacent
|
|
88
|
+
* env read); core never touches `process.env`.
|
|
89
|
+
*/
|
|
90
|
+
export function codexEnvFallback(env) {
|
|
91
|
+
const key = nonEmptyString(env['OPENAI_API_KEY']);
|
|
92
|
+
return key === null ? null : { accessToken: key, expiresAtMs: null };
|
|
93
|
+
}
|
|
94
|
+
// ── JWT / expiry coercion ───────────────────────────────────────────────────────
|
|
95
|
+
/**
|
|
96
|
+
* Decode a JWT's `exp` claim (seconds since epoch) and return it as ms since
|
|
97
|
+
* epoch, or null when `token` is not a well-formed three-segment JWT or carries
|
|
98
|
+
* no finite numeric `exp`. The signature is NEVER verified — codex's own client
|
|
99
|
+
* owns verification; we read only the public `exp` claim to schedule a refresh.
|
|
100
|
+
*/
|
|
101
|
+
export function decodeJwtExpMs(token) {
|
|
102
|
+
const segments = token.split('.');
|
|
103
|
+
if (segments.length !== 3)
|
|
104
|
+
return null;
|
|
105
|
+
const payloadSeg = segments[1];
|
|
106
|
+
if (payloadSeg === undefined || payloadSeg.length === 0)
|
|
107
|
+
return null;
|
|
108
|
+
const json = decodeBase64UrlUtf8(payloadSeg);
|
|
109
|
+
if (json === null)
|
|
110
|
+
return null;
|
|
111
|
+
let payload;
|
|
112
|
+
try {
|
|
113
|
+
payload = JSON.parse(json);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
if (!payload || typeof payload !== 'object' || Array.isArray(payload))
|
|
119
|
+
return null;
|
|
120
|
+
const exp = payload['exp'];
|
|
121
|
+
if (typeof exp !== 'number' || !Number.isFinite(exp))
|
|
122
|
+
return null;
|
|
123
|
+
return exp * 1000;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Coerce an `expiresAt`-shaped value into ms since epoch: a finite number is
|
|
127
|
+
* taken verbatim; a numeric string is parsed as a number; otherwise a string is
|
|
128
|
+
* tried as a parseable date. Anything else → null.
|
|
129
|
+
*/
|
|
130
|
+
export function coerceExpiresAtMs(value) {
|
|
131
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
132
|
+
return value;
|
|
133
|
+
if (typeof value === 'string') {
|
|
134
|
+
const n = Number(value);
|
|
135
|
+
if (Number.isFinite(n))
|
|
136
|
+
return n;
|
|
137
|
+
const parsedDate = Date.parse(value);
|
|
138
|
+
if (Number.isFinite(parsedDate))
|
|
139
|
+
return parsedDate;
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
// ── internal helpers ─────────────────────────────────────────────────────────
|
|
144
|
+
/** The ChatGPT-OAuth `tokens` bundle from auth.json, or null when absent/malformed. */
|
|
145
|
+
function codexTokensObject(root) {
|
|
146
|
+
const tokens = root['tokens'];
|
|
147
|
+
if (!tokens || typeof tokens !== 'object' || Array.isArray(tokens))
|
|
148
|
+
return null;
|
|
149
|
+
return tokens;
|
|
150
|
+
}
|
|
151
|
+
// Standard base64 alphabet → 6-bit value (and -1 for non-alphabet chars).
|
|
152
|
+
const BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
153
|
+
/**
|
|
154
|
+
* Decode a base64url segment to a UTF-8 string, or null on malformed input.
|
|
155
|
+
*
|
|
156
|
+
* The original used `Buffer.from(seg, 'base64url').toString('utf8')`; core may
|
|
157
|
+
* not import `node:buffer` (and must not depend on an ambient `atob` global that
|
|
158
|
+
* the project's `lib` config does not surface), so this is a self-contained pure
|
|
159
|
+
* decoder: base64url→bytes, then a manual UTF-8 → string decode. Any malformed
|
|
160
|
+
* input (bad char, bad length, invalid UTF-8) → null, matching the original's
|
|
161
|
+
* try/catch → null degradation (JSON.parse then fails on null and yields null).
|
|
162
|
+
*/
|
|
163
|
+
function decodeBase64UrlUtf8(seg) {
|
|
164
|
+
const bytes = base64UrlToBytes(seg);
|
|
165
|
+
if (bytes === null)
|
|
166
|
+
return null;
|
|
167
|
+
return utf8BytesToString(bytes);
|
|
168
|
+
}
|
|
169
|
+
/** base64url string → byte values (0–255), or null on a malformed segment. */
|
|
170
|
+
function base64UrlToBytes(seg) {
|
|
171
|
+
// base64url → base64: '-'→'+', '_'→'/'. (Padding is recomputed below.)
|
|
172
|
+
const b64 = seg.replace(/-/g, '+').replace(/_/g, '/').replace(/=+$/, '');
|
|
173
|
+
if (b64.length % 4 === 1)
|
|
174
|
+
return null; // an invalid base64 length
|
|
175
|
+
const out = [];
|
|
176
|
+
let acc = 0;
|
|
177
|
+
let bits = 0;
|
|
178
|
+
for (const ch of b64) {
|
|
179
|
+
const v = BASE64_ALPHABET.indexOf(ch);
|
|
180
|
+
if (v === -1)
|
|
181
|
+
return null; // non-alphabet character
|
|
182
|
+
acc = (acc << 6) | v;
|
|
183
|
+
bits += 6;
|
|
184
|
+
if (bits >= 8) {
|
|
185
|
+
bits -= 8;
|
|
186
|
+
out.push((acc >> bits) & 0xff);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
/** Decode a UTF-8 byte sequence into a string, or null on invalid UTF-8. */
|
|
192
|
+
function utf8BytesToString(bytes) {
|
|
193
|
+
let result = '';
|
|
194
|
+
let i = 0;
|
|
195
|
+
while (i < bytes.length) {
|
|
196
|
+
const b0 = bytes[i++];
|
|
197
|
+
if (b0 < 0x80) {
|
|
198
|
+
result += String.fromCharCode(b0);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
let needed;
|
|
202
|
+
let cp;
|
|
203
|
+
if ((b0 & 0xe0) === 0xc0) {
|
|
204
|
+
needed = 1;
|
|
205
|
+
cp = b0 & 0x1f;
|
|
206
|
+
}
|
|
207
|
+
else if ((b0 & 0xf0) === 0xe0) {
|
|
208
|
+
needed = 2;
|
|
209
|
+
cp = b0 & 0x0f;
|
|
210
|
+
}
|
|
211
|
+
else if ((b0 & 0xf8) === 0xf0) {
|
|
212
|
+
needed = 3;
|
|
213
|
+
cp = b0 & 0x07;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
return null; // invalid leading byte
|
|
217
|
+
}
|
|
218
|
+
for (let k = 0; k < needed; k++) {
|
|
219
|
+
const cb = bytes[i++];
|
|
220
|
+
if (cb === undefined || (cb & 0xc0) !== 0x80)
|
|
221
|
+
return null; // bad continuation
|
|
222
|
+
cp = (cp << 6) | (cb & 0x3f);
|
|
223
|
+
}
|
|
224
|
+
result += String.fromCodePoint(cp);
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../../../src/core/credential/extract.ts"],"names":[],"mappings":"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"}
|