smol-symphony 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +41 -22
- package/DESIGN.md +494 -273
- package/README.md +109 -57
- package/SPEC.md +33 -24
- package/WORKFLOW.minimal.yaml +34 -0
- package/{WORKFLOW.template.md → WORKFLOW.template.yaml} +409 -256
- package/WORKFLOW.yaml +487 -0
- package/assets/skills/symphony-issues/SKILL.md +136 -0
- package/assets/symphony-mise.system.toml +68 -0
- package/dist/bin/symphony.js +22 -786
- package/dist/bin/symphony.js.map +1 -1
- package/dist/core/actions/context.js +109 -0
- package/dist/core/actions/context.js.map +1 -0
- package/dist/{actions/parsing.js → core/actions/parse.js} +33 -114
- package/dist/core/actions/parse.js.map +1 -0
- package/dist/core/actions/plan.js +197 -0
- package/dist/core/actions/plan.js.map +1 -0
- package/dist/core/actions/predicates.js +111 -0
- package/dist/core/actions/predicates.js.map +1 -0
- package/dist/core/actions/run-fold.js +248 -0
- package/dist/core/actions/run-fold.js.map +1 -0
- package/dist/core/actions/template.js +118 -0
- package/dist/core/actions/template.js.map +1 -0
- package/dist/core/cli/args.js +116 -0
- package/dist/core/cli/args.js.map +1 -0
- package/dist/core/coerce.js +75 -0
- package/dist/core/coerce.js.map +1 -0
- package/dist/core/credential/account-id.js +20 -0
- package/dist/core/credential/account-id.js.map +1 -0
- package/dist/core/credential/adapter-config.js +136 -0
- package/dist/core/credential/adapter-config.js.map +1 -0
- package/dist/core/credential/availability.js +98 -0
- package/dist/core/credential/availability.js.map +1 -0
- package/dist/core/credential/extract.js +228 -0
- package/dist/core/credential/extract.js.map +1 -0
- package/dist/core/credential/fake-creds.js +171 -0
- package/dist/core/credential/fake-creds.js.map +1 -0
- package/dist/core/credential/identity.js +125 -0
- package/dist/core/credential/identity.js.map +1 -0
- package/dist/core/credential/shape.js +230 -0
- package/dist/core/credential/shape.js.map +1 -0
- package/dist/core/credential/strings.js +15 -0
- package/dist/core/credential/strings.js.map +1 -0
- package/dist/core/doctor/checks.js +303 -0
- package/dist/core/doctor/checks.js.map +1 -0
- package/dist/core/git/result.js +107 -0
- package/dist/core/git/result.js.map +1 -0
- package/dist/core/http/decisions.js +225 -0
- package/dist/core/http/decisions.js.map +1 -0
- package/dist/{http.js → core/http/render.js} +472 -738
- package/dist/core/http/render.js.map +1 -0
- package/dist/{http-handlers.js → core/http/routes.js} +52 -87
- package/dist/core/http/routes.js.map +1 -0
- package/dist/core/http/views.js +181 -0
- package/dist/core/http/views.js.map +1 -0
- package/dist/core/image/managed-image.js +95 -0
- package/dist/core/image/managed-image.js.map +1 -0
- package/dist/core/issue/file.js +149 -0
- package/dist/core/issue/file.js.map +1 -0
- package/dist/core/issue/parse.js +210 -0
- package/dist/core/issue/parse.js.map +1 -0
- package/dist/core/mcp/dispatch.js +239 -0
- package/dist/core/mcp/dispatch.js.map +1 -0
- package/dist/core/mcp/post-move.js +92 -0
- package/dist/core/mcp/post-move.js.map +1 -0
- package/dist/core/mcp/protocol.js +293 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/url.js +162 -0
- package/dist/core/mcp/url.js.map +1 -0
- package/dist/core/path.js +63 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/reconcile/image-decide.js +48 -0
- package/dist/core/reconcile/image-decide.js.map +1 -0
- package/dist/core/reconcile/ledger.js +142 -0
- package/dist/core/reconcile/ledger.js.map +1 -0
- package/dist/core/reconcile/pr-classify.js +62 -0
- package/dist/core/reconcile/pr-classify.js.map +1 -0
- package/dist/{reconciler → core/reconcile}/pr-decide.js +25 -12
- package/dist/core/reconcile/pr-decide.js.map +1 -0
- package/dist/core/reconcile/pr-loop.js +161 -0
- package/dist/core/reconcile/pr-loop.js.map +1 -0
- package/dist/core/reconcile/pr-notes.js +35 -0
- package/dist/core/reconcile/pr-notes.js.map +1 -0
- package/dist/core/reconcile/vm-decide.js +70 -0
- package/dist/core/reconcile/vm-decide.js.map +1 -0
- package/dist/core/reconcile/vm-reap.js +207 -0
- package/dist/core/reconcile/vm-reap.js.map +1 -0
- package/dist/core/reconcile/workspace-decide.js +162 -0
- package/dist/core/reconcile/workspace-decide.js.map +1 -0
- package/dist/core/runlog/summary.js +231 -0
- package/dist/core/runlog/summary.js.map +1 -0
- package/dist/core/runner/dispatch-config.js +95 -0
- package/dist/core/runner/dispatch-config.js.map +1 -0
- package/dist/core/runner/injection.js +61 -0
- package/dist/core/runner/injection.js.map +1 -0
- package/dist/core/runner/mise.js +210 -0
- package/dist/core/runner/mise.js.map +1 -0
- package/dist/core/runner/prompt.js +720 -0
- package/dist/core/runner/prompt.js.map +1 -0
- package/dist/core/runner/turn.js +242 -0
- package/dist/core/runner/turn.js.map +1 -0
- package/dist/core/runner/vm-plan.js +390 -0
- package/dist/core/runner/vm-plan.js.map +1 -0
- package/dist/core/schedule/admission.js +123 -0
- package/dist/core/schedule/admission.js.map +1 -0
- package/dist/core/schedule/circuit-breaker.js +111 -0
- package/dist/core/schedule/circuit-breaker.js.map +1 -0
- package/dist/core/schedule/eligibility.js +83 -0
- package/dist/core/schedule/eligibility.js.map +1 -0
- package/dist/core/schedule/reconcile-issue.js +82 -0
- package/dist/core/schedule/reconcile-issue.js.map +1 -0
- package/dist/core/schedule/retry.js +96 -0
- package/dist/core/schedule/retry.js.map +1 -0
- package/dist/core/schedule/sleep-cycle.js +133 -0
- package/dist/core/schedule/sleep-cycle.js.map +1 -0
- package/dist/core/schedule/slots.js +124 -0
- package/dist/core/schedule/slots.js.map +1 -0
- package/dist/core/schedule/tick.js +553 -0
- package/dist/core/schedule/tick.js.map +1 -0
- package/dist/core/schedule/token-fold.js +181 -0
- package/dist/core/schedule/token-fold.js.map +1 -0
- package/dist/core/state-resolve.js +86 -0
- package/dist/core/state-resolve.js.map +1 -0
- package/dist/core/vm-guards.js +278 -0
- package/dist/core/vm-guards.js.map +1 -0
- package/dist/core/workflow/derive.js +107 -0
- package/dist/core/workflow/derive.js.map +1 -0
- package/dist/core/workflow/parse.js +687 -0
- package/dist/core/workflow/parse.js.map +1 -0
- package/dist/core/workflow/prompt-probe.js +78 -0
- package/dist/core/workflow/prompt-probe.js.map +1 -0
- package/dist/core/workflow/validate.js +189 -0
- package/dist/core/workflow/validate.js.map +1 -0
- package/dist/core/workspace-key.js +19 -0
- package/dist/core/workspace-key.js.map +1 -0
- package/dist/shell/actions-runner.js +356 -0
- package/dist/shell/actions-runner.js.map +1 -0
- package/dist/shell/adapter/adapter-registry.js +45 -0
- package/dist/shell/adapter/adapter-registry.js.map +1 -0
- package/dist/shell/adapter/clock-random.js +96 -0
- package/dist/shell/adapter/clock-random.js.map +1 -0
- package/dist/shell/adapter/gondolin-dispatch-helpers.js +158 -0
- package/dist/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
- package/dist/shell/adapter/gondolin-dispatch.js +385 -0
- package/dist/shell/adapter/gondolin-dispatch.js.map +1 -0
- package/dist/shell/adapter/gondolin-image-converter.js +233 -0
- package/dist/shell/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/shell/adapter/gondolin-image-fetch.js +180 -0
- package/dist/shell/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/shell/adapter/launcher-asset.js +57 -0
- package/dist/shell/adapter/launcher-asset.js.map +1 -0
- package/dist/shell/adapter/mise-config-asset.js +65 -0
- package/dist/shell/adapter/mise-config-asset.js.map +1 -0
- package/dist/shell/adapter/workflow-loader.js +304 -0
- package/dist/shell/adapter/workflow-loader.js.map +1 -0
- package/dist/shell/cli/doctor.js +268 -0
- package/dist/shell/cli/doctor.js.map +1 -0
- package/dist/shell/effect-interpreter-families.js +314 -0
- package/dist/shell/effect-interpreter-families.js.map +1 -0
- package/dist/shell/effect-interpreter.js +29 -0
- package/dist/shell/effect-interpreter.js.map +1 -0
- package/dist/shell/interp/acp-frame.js +137 -0
- package/dist/shell/interp/acp-frame.js.map +1 -0
- package/dist/shell/interp/acp-ws-conn.js +320 -0
- package/dist/shell/interp/acp-ws-conn.js.map +1 -0
- package/dist/shell/interp/acp-ws-frames.js +159 -0
- package/dist/shell/interp/acp-ws-frames.js.map +1 -0
- package/dist/shell/interp/acp-ws.js +197 -0
- package/dist/shell/interp/acp-ws.js.map +1 -0
- package/dist/shell/interp/acp.js +319 -0
- package/dist/shell/interp/acp.js.map +1 -0
- package/dist/shell/interp/credential-defaults.js +128 -0
- package/dist/shell/interp/credential-defaults.js.map +1 -0
- package/dist/shell/interp/credential-hooks.js +149 -0
- package/dist/shell/interp/credential-hooks.js.map +1 -0
- package/dist/shell/interp/credential-registry.js +226 -0
- package/dist/shell/interp/credential-registry.js.map +1 -0
- package/dist/shell/interp/credential.js +103 -0
- package/dist/shell/interp/credential.js.map +1 -0
- package/dist/shell/interp/gh.js +163 -0
- package/dist/shell/interp/gh.js.map +1 -0
- package/dist/shell/interp/git.js +28 -0
- package/dist/shell/interp/git.js.map +1 -0
- package/dist/shell/interp/log.js +213 -0
- package/dist/shell/interp/log.js.map +1 -0
- package/dist/shell/interp/process.js +178 -0
- package/dist/shell/interp/process.js.map +1 -0
- package/dist/shell/interp/runlog.js +193 -0
- package/dist/shell/interp/runlog.js.map +1 -0
- package/dist/shell/interp/timer.js +64 -0
- package/dist/shell/interp/timer.js.map +1 -0
- package/dist/shell/interp/tracker-disk.js +99 -0
- package/dist/shell/interp/tracker-disk.js.map +1 -0
- package/dist/shell/interp/tracker-parse.js +71 -0
- package/dist/shell/interp/tracker-parse.js.map +1 -0
- package/dist/shell/interp/tracker-scan.js +238 -0
- package/dist/shell/interp/tracker-scan.js.map +1 -0
- package/dist/shell/interp/tracker-write.js +91 -0
- package/dist/shell/interp/tracker-write.js.map +1 -0
- package/dist/shell/interp/tracker.js +41 -0
- package/dist/shell/interp/tracker.js.map +1 -0
- package/dist/shell/interp/tty.js +48 -0
- package/dist/shell/interp/tty.js.map +1 -0
- package/dist/shell/interp/vm.js +199 -0
- package/dist/shell/interp/vm.js.map +1 -0
- package/dist/shell/interp/workspace.js +310 -0
- package/dist/shell/interp/workspace.js.map +1 -0
- package/dist/shell/main-acp.js +78 -0
- package/dist/shell/main-acp.js.map +1 -0
- package/dist/shell/main-adapters.js +222 -0
- package/dist/shell/main-adapters.js.map +1 -0
- package/dist/shell/main-credential.js +122 -0
- package/dist/shell/main-credential.js.map +1 -0
- package/dist/shell/main-doctor.js +22 -0
- package/dist/shell/main-doctor.js.map +1 -0
- package/dist/shell/main-entry.js +46 -0
- package/dist/shell/main-entry.js.map +1 -0
- package/dist/shell/main-http-csrf.js +45 -0
- package/dist/shell/main-http-csrf.js.map +1 -0
- package/dist/shell/main-http-handler.js +389 -0
- package/dist/shell/main-http-handler.js.map +1 -0
- package/dist/shell/main-http-mcp.js +122 -0
- package/dist/shell/main-http-mcp.js.map +1 -0
- package/dist/shell/main-http-views.js +253 -0
- package/dist/shell/main-http-views.js.map +1 -0
- package/dist/shell/main-http.js +76 -0
- package/dist/shell/main-http.js.map +1 -0
- package/dist/shell/main-loops.js +130 -0
- package/dist/shell/main-loops.js.map +1 -0
- package/dist/shell/main-mcp.js +129 -0
- package/dist/shell/main-mcp.js.map +1 -0
- package/dist/shell/main-orchestrator.js +120 -0
- package/dist/shell/main-orchestrator.js.map +1 -0
- package/dist/shell/main-preflight.js +43 -0
- package/dist/shell/main-preflight.js.map +1 -0
- package/dist/shell/main-reconcilers-helpers.js +244 -0
- package/dist/shell/main-reconcilers-helpers.js.map +1 -0
- package/dist/shell/main-reconcilers-pr.js +148 -0
- package/dist/shell/main-reconcilers-pr.js.map +1 -0
- package/dist/shell/main-reconcilers.js +225 -0
- package/dist/shell/main-reconcilers.js.map +1 -0
- package/dist/shell/main-runner.js +355 -0
- package/dist/shell/main-runner.js.map +1 -0
- package/dist/shell/main-scaffold.js +116 -0
- package/dist/shell/main-scaffold.js.map +1 -0
- package/dist/shell/main-shutdown.js +115 -0
- package/dist/shell/main-shutdown.js.map +1 -0
- package/dist/shell/main-startup.js +48 -0
- package/dist/shell/main-startup.js.map +1 -0
- package/dist/shell/main-substrates.js +43 -0
- package/dist/shell/main-substrates.js.map +1 -0
- package/dist/shell/main.js +385 -0
- package/dist/shell/main.js.map +1 -0
- package/dist/shell/orchestrator-feedback.js +69 -0
- package/dist/shell/orchestrator-feedback.js.map +1 -0
- package/dist/shell/orchestrator-image.js +167 -0
- package/dist/shell/orchestrator-image.js.map +1 -0
- package/dist/shell/orchestrator-loop.js +468 -0
- package/dist/shell/orchestrator-loop.js.map +1 -0
- package/dist/shell/orchestrator-reconcile.js +36 -0
- package/dist/shell/orchestrator-reconcile.js.map +1 -0
- package/dist/shell/reconciler-loop.js +228 -0
- package/dist/shell/reconciler-loop.js.map +1 -0
- package/dist/shell/runner-loop-turn.js +301 -0
- package/dist/shell/runner-loop-turn.js.map +1 -0
- package/dist/shell/runner-loop.js +338 -0
- package/dist/shell/runner-loop.js.map +1 -0
- package/dist/shell/server/http.js +208 -0
- package/dist/shell/server/http.js.map +1 -0
- package/dist/shell/server/mcp-runtime-effects.js +237 -0
- package/dist/shell/server/mcp-runtime-effects.js.map +1 -0
- package/dist/shell/server/mcp-runtime.js +99 -0
- package/dist/shell/server/mcp-runtime.js.map +1 -0
- package/dist/shell/workspace-key.js +14 -0
- package/dist/shell/workspace-key.js.map +1 -0
- package/dist/types/acp.js +8 -0
- package/dist/types/acp.js.map +1 -0
- package/dist/types/actions/plan.js +6 -0
- package/dist/types/actions/plan.js.map +1 -0
- package/dist/types/actions/predicates.js +6 -0
- package/dist/types/actions/predicates.js.map +1 -0
- package/dist/types/actions/run-fold.js +8 -0
- package/dist/types/actions/run-fold.js.map +1 -0
- package/dist/types/actions.js +7 -0
- package/dist/types/actions.js.map +1 -0
- package/dist/types/adapter/clock-random.js +4 -0
- package/dist/types/adapter/clock-random.js.map +1 -0
- package/dist/types/adapter/gondolin-image-converter.js +5 -0
- package/dist/types/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/types/adapter/gondolin-image-fetch.js +5 -0
- package/dist/types/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/types/adapter/workflow-loader.js +4 -0
- package/dist/types/adapter/workflow-loader.js.map +1 -0
- package/dist/types/cli/args.js +8 -0
- package/dist/types/cli/args.js.map +1 -0
- package/dist/types/config.js +8 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/credential-interp.js +6 -0
- package/dist/types/credential-interp.js.map +1 -0
- package/dist/types/credentials.js +10 -0
- package/dist/types/credentials.js.map +1 -0
- package/dist/types/doctor.js +7 -0
- package/dist/types/doctor.js.map +1 -0
- package/dist/types/domain.js +7 -0
- package/dist/types/domain.js.map +1 -0
- package/dist/types/effect.js +15 -0
- package/dist/types/effect.js.map +1 -0
- package/dist/types/errors.js +39 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/http/decisions.js +6 -0
- package/dist/types/http/decisions.js.map +1 -0
- package/dist/types/http/render.js +10 -0
- package/dist/types/http/render.js.map +1 -0
- package/dist/types/http/views.js +6 -0
- package/dist/types/http/views.js.map +1 -0
- package/dist/types/http.js +9 -0
- package/dist/types/http.js.map +1 -0
- package/dist/types/image/managed-image.js +7 -0
- package/dist/types/image/managed-image.js.map +1 -0
- package/dist/types/interp/effect-interpreter.js +8 -0
- package/dist/types/interp/effect-interpreter.js.map +1 -0
- package/dist/types/interp/tracker.js +7 -0
- package/dist/types/interp/tracker.js.map +1 -0
- package/dist/types/issue/file.js +6 -0
- package/dist/types/issue/file.js.map +1 -0
- package/dist/types/issue/parse.js +8 -0
- package/dist/types/issue/parse.js.map +1 -0
- package/dist/types/main-acp.js +13 -0
- package/dist/types/main-acp.js.map +1 -0
- package/dist/types/main-adapters.js +5 -0
- package/dist/types/main-adapters.js.map +1 -0
- package/dist/types/main-credential.js +21 -0
- package/dist/types/main-credential.js.map +1 -0
- package/dist/types/main-doctor.js +6 -0
- package/dist/types/main-doctor.js.map +1 -0
- package/dist/types/main-http-handler.js +12 -0
- package/dist/types/main-http-handler.js.map +1 -0
- package/dist/types/main-http.js +5 -0
- package/dist/types/main-http.js.map +1 -0
- package/dist/types/main-loops.js +5 -0
- package/dist/types/main-loops.js.map +1 -0
- package/dist/types/main-mcp.js +12 -0
- package/dist/types/main-mcp.js.map +1 -0
- package/dist/types/main-orchestrator.js +5 -0
- package/dist/types/main-orchestrator.js.map +1 -0
- package/dist/types/main-reconcilers.js +11 -0
- package/dist/types/main-reconcilers.js.map +1 -0
- package/dist/types/main-runner.js +13 -0
- package/dist/types/main-runner.js.map +1 -0
- package/dist/types/main-startup.js +5 -0
- package/dist/types/main-startup.js.map +1 -0
- package/dist/types/main-substrates.js +5 -0
- package/dist/types/main-substrates.js.map +1 -0
- package/dist/types/mcp/dispatch.js +4 -0
- package/dist/types/mcp/dispatch.js.map +1 -0
- package/dist/types/mcp/post-move.js +7 -0
- package/dist/types/mcp/post-move.js.map +1 -0
- package/dist/types/mcp.js +9 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/ports.js +12 -0
- package/dist/types/ports.js.map +1 -0
- package/dist/types/reconcile/image-decide.js +5 -0
- package/dist/types/reconcile/image-decide.js.map +1 -0
- package/dist/types/reconcile/ledger.js +7 -0
- package/dist/types/reconcile/ledger.js.map +1 -0
- package/dist/types/reconcile/pr-loop.js +8 -0
- package/dist/types/reconcile/pr-loop.js.map +1 -0
- package/dist/types/reconcile/vm-reap.js +8 -0
- package/dist/types/reconcile/vm-reap.js.map +1 -0
- package/dist/types/reconcile/workspace-decide.js +7 -0
- package/dist/types/reconcile/workspace-decide.js.map +1 -0
- package/dist/types/reconcile.js +9 -0
- package/dist/types/reconcile.js.map +1 -0
- package/dist/types/runlog.js +7 -0
- package/dist/types/runlog.js.map +1 -0
- package/dist/types/runner/actions-runner.js +12 -0
- package/dist/types/runner/actions-runner.js.map +1 -0
- package/dist/types/runner/gondolin-dispatch.js +5 -0
- package/dist/types/runner/gondolin-dispatch.js.map +1 -0
- package/dist/types/runner/injection.js +6 -0
- package/dist/types/runner/injection.js.map +1 -0
- package/dist/types/runner/runner-loop.js +5 -0
- package/dist/types/runner/runner-loop.js.map +1 -0
- package/dist/types/runner/turn.js +4 -0
- package/dist/types/runner/turn.js.map +1 -0
- package/dist/types/runner/vm-plan.js +4 -0
- package/dist/types/runner/vm-plan.js.map +1 -0
- package/dist/types/runtime.js +9 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/schedule/admission.js +7 -0
- package/dist/types/schedule/admission.js.map +1 -0
- package/dist/types/schedule/circuit-breaker.js +2 -0
- package/dist/types/schedule/circuit-breaker.js.map +1 -0
- package/dist/types/schedule/eligibility.js +9 -0
- package/dist/types/schedule/eligibility.js.map +1 -0
- package/dist/types/schedule/orchestrator-loop.js +10 -0
- package/dist/types/schedule/orchestrator-loop.js.map +1 -0
- package/dist/types/schedule/sleep-cycle.js +4 -0
- package/dist/types/schedule/sleep-cycle.js.map +1 -0
- package/dist/types/schedule/slots.js +8 -0
- package/dist/types/schedule/slots.js.map +1 -0
- package/dist/types/schedule/tick.js +9 -0
- package/dist/types/schedule/tick.js.map +1 -0
- package/dist/types/server/mcp-runtime.js +8 -0
- package/dist/types/server/mcp-runtime.js.map +1 -0
- package/dist/types/workflow/parse.js +4 -0
- package/dist/types/workflow/parse.js.map +1 -0
- package/package.json +22 -10
- package/patches/@earendil-works+gondolin+0.12.0.patch +173 -0
- package/prompts/Reflect.md +91 -0
- package/prompts/Review.md +97 -0
- package/prompts/Todo.md +96 -0
- package/prompts/_footer.md +41 -0
- package/prompts/_preamble.md +42 -0
- package/prompts-minimal/Todo.md +26 -0
- package/scripts/postinstall.mjs +63 -0
- package/scripts/vm-agent.mjs +312 -90
- package/WORKFLOW.md +0 -744
- package/dist/acp-bridge.js +0 -324
- package/dist/acp-bridge.js.map +0 -1
- package/dist/actions/cache.js +0 -191
- package/dist/actions/cache.js.map +0 -1
- package/dist/actions/effects.js +0 -41
- package/dist/actions/effects.js.map +0 -1
- package/dist/actions/executor.js +0 -570
- package/dist/actions/executor.js.map +0 -1
- package/dist/actions/index.js +0 -13
- package/dist/actions/index.js.map +0 -1
- package/dist/actions/parsing.js.map +0 -1
- package/dist/actions/predicate-env.js +0 -27
- package/dist/actions/predicate-env.js.map +0 -1
- package/dist/actions/predicates.js +0 -49
- package/dist/actions/predicates.js.map +0 -1
- package/dist/actions/templating.js +0 -66
- package/dist/actions/templating.js.map +0 -1
- package/dist/actions/types.js +0 -15
- package/dist/actions/types.js.map +0 -1
- package/dist/agent/acp.js +0 -473
- package/dist/agent/acp.js.map +0 -1
- package/dist/agent/adapter-names.js +0 -159
- package/dist/agent/adapter-names.js.map +0 -1
- package/dist/agent/adapters.js +0 -511
- package/dist/agent/adapters.js.map +0 -1
- package/dist/agent/credential-extractors.js +0 -342
- package/dist/agent/credential-extractors.js.map +0 -1
- package/dist/agent/credential-secrets.js +0 -628
- package/dist/agent/credential-secrets.js.map +0 -1
- package/dist/agent/credential-ticker.js +0 -57
- package/dist/agent/credential-ticker.js.map +0 -1
- package/dist/agent/gondolin-creds-staging.js +0 -356
- package/dist/agent/gondolin-creds-staging.js.map +0 -1
- package/dist/agent/gondolin-dispatch.js +0 -375
- package/dist/agent/gondolin-dispatch.js.map +0 -1
- package/dist/agent/gondolin.js +0 -124
- package/dist/agent/gondolin.js.map +0 -1
- package/dist/agent/runner-decisions.js +0 -134
- package/dist/agent/runner-decisions.js.map +0 -1
- package/dist/agent/runner.js +0 -1456
- package/dist/agent/runner.js.map +0 -1
- package/dist/agent/tool-call-summary.js +0 -102
- package/dist/agent/tool-call-summary.js.map +0 -1
- package/dist/agent/vm-acp-mapping.js +0 -73
- package/dist/agent/vm-acp-mapping.js.map +0 -1
- package/dist/agent/vm-guards.js +0 -262
- package/dist/agent/vm-guards.js.map +0 -1
- package/dist/agent/vm-port.js +0 -22
- package/dist/agent/vm-port.js.map +0 -1
- package/dist/agent/vm-process-registry.js +0 -79
- package/dist/agent/vm-process-registry.js.map +0 -1
- package/dist/bin/cli-args.js +0 -105
- package/dist/bin/cli-args.js.map +0 -1
- package/dist/errors.js +0 -15
- package/dist/errors.js.map +0 -1
- package/dist/http-disk.js +0 -135
- package/dist/http-disk.js.map +0 -1
- package/dist/http-handlers.js.map +0 -1
- package/dist/http.js.map +0 -1
- package/dist/issues.js +0 -178
- package/dist/issues.js.map +0 -1
- package/dist/logging.js +0 -203
- package/dist/logging.js.map +0 -1
- package/dist/mcp.js +0 -706
- package/dist/mcp.js.map +0 -1
- package/dist/memory.js +0 -85
- package/dist/memory.js.map +0 -1
- package/dist/orchestrator-decisions.js +0 -331
- package/dist/orchestrator-decisions.js.map +0 -1
- package/dist/orchestrator.js +0 -1569
- package/dist/orchestrator.js.map +0 -1
- package/dist/prompt.js +0 -65
- package/dist/prompt.js.map +0 -1
- package/dist/reconciler/cache.js +0 -65
- package/dist/reconciler/cache.js.map +0 -1
- package/dist/reconciler/index.js +0 -448
- package/dist/reconciler/index.js.map +0 -1
- package/dist/reconciler/ledger.js +0 -131
- package/dist/reconciler/ledger.js.map +0 -1
- package/dist/reconciler/pr-adapters.js +0 -174
- package/dist/reconciler/pr-adapters.js.map +0 -1
- package/dist/reconciler/pr-decide.js.map +0 -1
- package/dist/reconciler/pr.js +0 -422
- package/dist/reconciler/pr.js.map +0 -1
- package/dist/reconciler/types.js +0 -12
- package/dist/reconciler/types.js.map +0 -1
- package/dist/reconciler/vm.js +0 -243
- package/dist/reconciler/vm.js.map +0 -1
- package/dist/reconciler/workspace-defaults.js +0 -83
- package/dist/reconciler/workspace-defaults.js.map +0 -1
- package/dist/reconciler/workspace.js +0 -272
- package/dist/reconciler/workspace.js.map +0 -1
- package/dist/runlog.js +0 -403
- package/dist/runlog.js.map +0 -1
- package/dist/scaffold.js +0 -165
- package/dist/scaffold.js.map +0 -1
- package/dist/trackers/local.js +0 -445
- package/dist/trackers/local.js.map +0 -1
- package/dist/trackers/types.js +0 -10
- package/dist/trackers/types.js.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/util/clock.js +0 -12
- package/dist/util/clock.js.map +0 -1
- package/dist/util/crypto.js +0 -25
- package/dist/util/crypto.js.map +0 -1
- package/dist/util/frontmatter.js +0 -70
- package/dist/util/frontmatter.js.map +0 -1
- package/dist/util/fs-issues.js +0 -22
- package/dist/util/fs-issues.js.map +0 -1
- package/dist/util/process.js +0 -152
- package/dist/util/process.js.map +0 -1
- package/dist/util/workspace-key.js +0 -10
- package/dist/util/workspace-key.js.map +0 -1
- package/dist/workflow-loader.js +0 -147
- package/dist/workflow-loader.js.map +0 -1
- package/dist/workflow.js +0 -822
- package/dist/workflow.js.map +0 -1
- package/dist/workspace-types.js +0 -8
- package/dist/workspace-types.js.map +0 -1
- package/dist/workspace.js +0 -443
- package/dist/workspace.js.map +0 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// FCIS rewrite — pure issue-file serialization.
|
|
2
|
+
//
|
|
3
|
+
// Functional-core port of the original `src/issues.ts:writeIssueFile`. The
|
|
4
|
+
// original was async and performed real fs IO: it mkdir'd the state dir,
|
|
5
|
+
// `readdir`'d every state directory to discover taken numeric identifiers
|
|
6
|
+
// (collision avoidance), `stat`'d an explicit identifier's target path to
|
|
7
|
+
// reject duplicates, and finally `writeFile`'d the rendered Markdown.
|
|
8
|
+
//
|
|
9
|
+
// In the FCIS layout all of that IO moves OUT of this module:
|
|
10
|
+
// - The existing-identifier discovery (a `readdir` walk) is performed by the
|
|
11
|
+
// shell and the resulting SET is SUPPLIED here as plain data
|
|
12
|
+
// (`existingIdentifiers`). This module only DECIDES which id to take.
|
|
13
|
+
// - The wall-clock `created_at` / `updated_at` stamp is injected as a plain
|
|
14
|
+
// ISO string (`nowIso`) — no `Date.now()` / clock read inside core.
|
|
15
|
+
// - The actual file write becomes a `tracker.write_issue` Effect the caller
|
|
16
|
+
// executes; this module ALSO returns the fully-rendered file `content` and
|
|
17
|
+
// the composed `path` so a shell that prefers a raw `fs.write_file` (or
|
|
18
|
+
// wants to surface the content in a dashboard) needn't re-derive them.
|
|
19
|
+
//
|
|
20
|
+
// Pure + synchronous: (data) -> data + Effect[]. Imports ONLY from src/types.
|
|
21
|
+
import { sanitizeWorkspaceKey } from '../workspace-key.js';
|
|
22
|
+
// Identifier sanitizer (SPEC §5.5 Invariant 3) is the canonical core util.
|
|
23
|
+
const sanitizeIdentifier = sanitizeWorkspaceKey;
|
|
24
|
+
// POSIX-style path join. Core may not import `node:path`; the tracker root is
|
|
25
|
+
// always a real on-disk path and the segments here never contain `..`, so a
|
|
26
|
+
// simple single-slash join is faithful. Strips a trailing slash per segment so
|
|
27
|
+
// `root/` + `state` doesn't produce `root//state`, and keeps an absolute root's
|
|
28
|
+
// leading slash.
|
|
29
|
+
function joinPath(...segments) {
|
|
30
|
+
const lead = segments[0]?.startsWith('/') ? '/' : '';
|
|
31
|
+
const parts = segments.map((s) => s.replace(/^\/+|\/+$/g, '')).filter((s) => s.length > 0);
|
|
32
|
+
return lead + parts.join('/');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Render a YAML scalar/array value the way the original serializer did:
|
|
36
|
+
* - arrays → `[<json>, <json>, …]`
|
|
37
|
+
* - strings → JSON-quoted (escapes + always double-quoted)
|
|
38
|
+
* - other → `String(v)` (numbers, booleans)
|
|
39
|
+
*/
|
|
40
|
+
function renderYamlValue(v) {
|
|
41
|
+
if (Array.isArray(v)) {
|
|
42
|
+
return `[${v.map((x) => JSON.stringify(x)).join(', ')}]`;
|
|
43
|
+
}
|
|
44
|
+
if (typeof v === 'string') {
|
|
45
|
+
return JSON.stringify(v);
|
|
46
|
+
}
|
|
47
|
+
return String(v);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Pure issue-file serializer. Decides the identifier (sanitize an explicit one
|
|
51
|
+
* or pick the next free numeric over `existingIdentifiers`), renders the YAML
|
|
52
|
+
* front matter + body, composes the path, and returns a `tracker.write_issue`
|
|
53
|
+
* Effect for the shell to execute. Never throws: refusals come back as a
|
|
54
|
+
* `{ error }` result the caller maps to a structured rejection.
|
|
55
|
+
*
|
|
56
|
+
* Mirrors the original `writeIssueFile` decision branches exactly:
|
|
57
|
+
* - explicit identifier → sanitize; reject empty; reject collision
|
|
58
|
+
* - no identifier → count up from 1 to the first id not in the set
|
|
59
|
+
*/
|
|
60
|
+
export function composeIssueFile(input) {
|
|
61
|
+
const stateDir = joinPath(input.trackerRoot, input.state);
|
|
62
|
+
let identifier;
|
|
63
|
+
const explicit = (input.identifier ?? '').trim();
|
|
64
|
+
if (explicit.length > 0) {
|
|
65
|
+
identifier = sanitizeIdentifier(explicit);
|
|
66
|
+
if (identifier.length === 0) {
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
error: {
|
|
70
|
+
code: 'empty_identifier',
|
|
71
|
+
message: 'identifier must contain at least one allowed character',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const filePath = joinPath(stateDir, `${identifier}.md`);
|
|
76
|
+
if (input.existingIdentifiers.has(identifier)) {
|
|
77
|
+
return {
|
|
78
|
+
ok: false,
|
|
79
|
+
error: {
|
|
80
|
+
code: 'identifier_exists',
|
|
81
|
+
message: `issue ${identifier} already exists at ${filePath}`,
|
|
82
|
+
identifier,
|
|
83
|
+
path: filePath,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// No identifier supplied → pick the next free numeric identifier by counting
|
|
90
|
+
// up from 1. Title-slug files from prior cycles are inert: only numeric
|
|
91
|
+
// basenames consume IDs (legacy `add-changelog.md` never claims a slot).
|
|
92
|
+
let n = 1;
|
|
93
|
+
while (input.existingIdentifiers.has(String(n)))
|
|
94
|
+
n += 1;
|
|
95
|
+
identifier = String(n);
|
|
96
|
+
}
|
|
97
|
+
const filePath = joinPath(stateDir, `${identifier}.md`);
|
|
98
|
+
// Standard front matter, in the original's declaration order, then the
|
|
99
|
+
// caller's extras (which may override — preserving the original's merge).
|
|
100
|
+
const fm = {
|
|
101
|
+
id: identifier,
|
|
102
|
+
identifier,
|
|
103
|
+
title: input.title,
|
|
104
|
+
created_at: input.nowIso,
|
|
105
|
+
updated_at: input.nowIso,
|
|
106
|
+
};
|
|
107
|
+
if (typeof input.priority === 'number')
|
|
108
|
+
fm.priority = input.priority;
|
|
109
|
+
if (input.labels && input.labels.length > 0)
|
|
110
|
+
fm.labels = input.labels;
|
|
111
|
+
if (input.blocked_by && input.blocked_by.length > 0)
|
|
112
|
+
fm.blocked_by = input.blocked_by;
|
|
113
|
+
if (input.extra_front_matter) {
|
|
114
|
+
for (const [k, v] of Object.entries(input.extra_front_matter)) {
|
|
115
|
+
fm[k] = v;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const yamlLines = ['---'];
|
|
119
|
+
for (const [k, v] of Object.entries(fm)) {
|
|
120
|
+
yamlLines.push(`${k}: ${renderYamlValue(v)}`);
|
|
121
|
+
}
|
|
122
|
+
yamlLines.push('---', '');
|
|
123
|
+
const body = (input.description ?? '').trim();
|
|
124
|
+
const content = yamlLines.join('\n') + (body.length > 0 ? body + '\n' : '');
|
|
125
|
+
const writeEffect = {
|
|
126
|
+
family: 'tracker',
|
|
127
|
+
kind: 'write_issue',
|
|
128
|
+
trackerRoot: input.trackerRoot,
|
|
129
|
+
identifier,
|
|
130
|
+
state: input.state,
|
|
131
|
+
title: input.title,
|
|
132
|
+
...(input.description !== undefined ? { description: input.description } : {}),
|
|
133
|
+
...(input.priority !== undefined ? { priority: input.priority } : {}),
|
|
134
|
+
...(input.labels !== undefined ? { labels: input.labels } : {}),
|
|
135
|
+
...(input.blocked_by !== undefined ? { blocked_by: input.blocked_by } : {}),
|
|
136
|
+
...(input.extra_front_matter !== undefined ? { extraFrontMatter: input.extra_front_matter } : {}),
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
ok: true,
|
|
140
|
+
result: {
|
|
141
|
+
path: filePath,
|
|
142
|
+
identifier,
|
|
143
|
+
state: input.state,
|
|
144
|
+
content,
|
|
145
|
+
effects: [writeEffect],
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/core/issue/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// FCIS rewrite — pure issue parsing & selection core (SPEC §3.2).
|
|
2
|
+
//
|
|
3
|
+
// Ports the *decision* half of the original `src/trackers/local.ts` (parse +
|
|
4
|
+
// normalize + active-candidate filter + multi-match disambiguation) and the
|
|
5
|
+
// pure collision-pick from `src/issues.ts` (`writeIssueFile`'s next-free-id
|
|
6
|
+
// loop), with the impureCoreRisk removed: the existing-identifier SET is
|
|
7
|
+
// supplied by the shell (which owns the readdir), NOT scanned here.
|
|
8
|
+
//
|
|
9
|
+
// HARD CONSTRAINTS (gate-enforced):
|
|
10
|
+
// - 100% SYNCHRONOUS. No async/await/Promise anywhere.
|
|
11
|
+
// - No IO, no node: imports, no process/fetch, no wall clock, no randomness.
|
|
12
|
+
// - Imports ONLY from src/types/**.
|
|
13
|
+
//
|
|
14
|
+
// The YAML decode itself lives in the shell tracker adapter (it needs the
|
|
15
|
+
// `yaml` userland lib, which core may not import). The shell hands us the
|
|
16
|
+
// already-decoded front-matter map + body + state-from-dir + filename; this
|
|
17
|
+
// module turns that into a normalized `Issue` and makes every selection
|
|
18
|
+
// decision as pure data-in / data-out.
|
|
19
|
+
import { TrackerError, NoHoldingStateError } from '../../types/errors.js';
|
|
20
|
+
import { asString, asStringList, asInt, asTimestamp } from '../coerce.js';
|
|
21
|
+
// Front-matter coercers (asString/asStringList/asInt/asTimestamp) are the
|
|
22
|
+
// canonical ones from core/coerce.ts. NOTE(drift resolved): the old local copy
|
|
23
|
+
// of `asInt` here used `Number.isInteger` (rejecting a fractional priority);
|
|
24
|
+
// the canonical `asInt` truncates (isFinite + Math.trunc), matching the rest
|
|
25
|
+
// of the codebase. See core/coerce.ts header + tests/core/coerce.test.ts.
|
|
26
|
+
// ─── id derivation ───────────────────────────────────────────────────────────
|
|
27
|
+
/**
|
|
28
|
+
* Canonical id of a raw file: front-matter `id` when non-blank, else the
|
|
29
|
+
* filename stem. Exported because the shell's transition path resolves the
|
|
30
|
+
* caller-supplied issueId against this same key.
|
|
31
|
+
*/
|
|
32
|
+
export function idOf(raw) {
|
|
33
|
+
const fmId = asString(raw.frontMatter['id']);
|
|
34
|
+
return fmId && fmId.trim().length > 0 ? fmId : raw.identifier;
|
|
35
|
+
}
|
|
36
|
+
// ─── normalize (build Issue objects, resolving blocker states) ───────────────
|
|
37
|
+
/**
|
|
38
|
+
* Build a blocker lookup keyed by every alias a `blocked_by` entry might use:
|
|
39
|
+
* the front-matter `identifier`, the canonical `id`, and the filename stem.
|
|
40
|
+
* Pure: derived solely from `all`. Last-write-wins mirrors the original.
|
|
41
|
+
*/
|
|
42
|
+
function buildBlockerIndex(all) {
|
|
43
|
+
const byKey = new Map();
|
|
44
|
+
for (const r of all) {
|
|
45
|
+
const ident = asString(r.frontMatter['identifier']) ?? r.identifier;
|
|
46
|
+
byKey.set(ident, r);
|
|
47
|
+
byKey.set(idOf(r), r);
|
|
48
|
+
byKey.set(r.identifier, r);
|
|
49
|
+
}
|
|
50
|
+
return byKey;
|
|
51
|
+
}
|
|
52
|
+
function toIssue(raw, byKey) {
|
|
53
|
+
const fm = raw.frontMatter;
|
|
54
|
+
const id = idOf(raw);
|
|
55
|
+
const identifier = asString(fm['identifier']) ?? raw.identifier;
|
|
56
|
+
const title = asString(fm['title']) ?? identifier;
|
|
57
|
+
const priority = asInt(fm['priority']);
|
|
58
|
+
const labels = asStringList(fm['labels']).map((s) => s.toLowerCase());
|
|
59
|
+
const branch_name = asString(fm['branch_name']);
|
|
60
|
+
const url = asString(fm['url']);
|
|
61
|
+
const created_at = asTimestamp(fm['created_at']);
|
|
62
|
+
const updated_at = asTimestamp(fm['updated_at']);
|
|
63
|
+
const description = raw.description.length > 0 ? raw.description : null;
|
|
64
|
+
const blockerIdents = asStringList(fm['blocked_by']);
|
|
65
|
+
const blocked_by = blockerIdents.map((ident) => {
|
|
66
|
+
const found = byKey.get(ident);
|
|
67
|
+
if (found) {
|
|
68
|
+
const foundIdent = asString(found.frontMatter['identifier']) ?? found.identifier;
|
|
69
|
+
return {
|
|
70
|
+
id: idOf(found),
|
|
71
|
+
identifier: foundIdent,
|
|
72
|
+
state: found.state,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { id: null, identifier: ident, state: null };
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
id,
|
|
79
|
+
identifier,
|
|
80
|
+
title,
|
|
81
|
+
description,
|
|
82
|
+
priority,
|
|
83
|
+
state: raw.state,
|
|
84
|
+
branch_name,
|
|
85
|
+
url,
|
|
86
|
+
labels,
|
|
87
|
+
blocked_by,
|
|
88
|
+
created_at,
|
|
89
|
+
updated_at,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Normalize `target` raw files into `Issue`s, resolving blocker states against
|
|
94
|
+
* the full `all` view. The original passed both sets so a candidate's
|
|
95
|
+
* `blocked_by` could reference an issue outside the candidate window.
|
|
96
|
+
*/
|
|
97
|
+
export function normalizeIssues(target, all) {
|
|
98
|
+
const byKey = buildBlockerIndex(all);
|
|
99
|
+
return target.map((r) => toIssue(r, byKey));
|
|
100
|
+
}
|
|
101
|
+
/** Parse a single raw file into an `Issue` (blockers resolved only against the file itself). */
|
|
102
|
+
export function parseIssue(raw) {
|
|
103
|
+
return toIssue(raw, buildBlockerIndex([raw]));
|
|
104
|
+
}
|
|
105
|
+
// ─── state-role helpers (ported from src/issues.ts) ──────────────────────────
|
|
106
|
+
/** Names of every state with `role`, in declaration order. */
|
|
107
|
+
function statesWithRole(states, role) {
|
|
108
|
+
return Object.entries(states).filter(([, cfg]) => cfg.role === role).map(([name]) => name);
|
|
109
|
+
}
|
|
110
|
+
/** Names of every `role: active` state, in declaration order. */
|
|
111
|
+
export function activeStateNames(states) {
|
|
112
|
+
return statesWithRole(states, 'active');
|
|
113
|
+
}
|
|
114
|
+
/** Names of every `role: terminal` state, in declaration order. */
|
|
115
|
+
export function terminalStateNames(states) {
|
|
116
|
+
return statesWithRole(states, 'terminal');
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* First declared `role: holding` state in declaration order (where triage /
|
|
120
|
+
* agent-proposed issues land). Throws `NoHoldingStateError` when none is
|
|
121
|
+
* declared — callers that surface this to agents should map it to a structured
|
|
122
|
+
* `no_holding_state` error.
|
|
123
|
+
*/
|
|
124
|
+
export function pickHoldingState(states) {
|
|
125
|
+
for (const [name, cfg] of Object.entries(states)) {
|
|
126
|
+
if (cfg.role === 'holding')
|
|
127
|
+
return name;
|
|
128
|
+
}
|
|
129
|
+
throw new NoHoldingStateError('no holding state declared in workflow');
|
|
130
|
+
}
|
|
131
|
+
// ─── active-candidate filtering ──────────────────────────────────────────────
|
|
132
|
+
/**
|
|
133
|
+
* Select the active-but-not-terminal candidates and normalize them. Mirrors
|
|
134
|
+
* the original `fetchCandidateIssues`: state comparison is case-insensitive
|
|
135
|
+
* (SPEC §3.2 "Normalized Issue State"), and a state that is BOTH active and
|
|
136
|
+
* terminal (a malformed config) is excluded — the `!terminal` guard wins.
|
|
137
|
+
*/
|
|
138
|
+
export function selectCandidateIssues(all, states) {
|
|
139
|
+
const active = new Set(activeStateNames(states).map((s) => s.toLowerCase()));
|
|
140
|
+
const terminal = new Set(terminalStateNames(states).map((s) => s.toLowerCase()));
|
|
141
|
+
const filtered = all.filter((raw) => {
|
|
142
|
+
const s = raw.state.toLowerCase();
|
|
143
|
+
return active.has(s) && !terminal.has(s);
|
|
144
|
+
});
|
|
145
|
+
return normalizeIssues(filtered, all);
|
|
146
|
+
}
|
|
147
|
+
/** Select & normalize every file whose state is in `stateNames` (case-insensitive). */
|
|
148
|
+
export function selectIssuesByStates(all, stateNames) {
|
|
149
|
+
if (stateNames.length === 0)
|
|
150
|
+
return [];
|
|
151
|
+
const want = new Set(stateNames.map((s) => s.toLowerCase()));
|
|
152
|
+
const filtered = all.filter((raw) => want.has(raw.state.toLowerCase()));
|
|
153
|
+
return normalizeIssues(filtered, all);
|
|
154
|
+
}
|
|
155
|
+
/** Select & normalize every file whose canonical id is in `issueIds`. */
|
|
156
|
+
export function selectIssuesByIds(all, issueIds) {
|
|
157
|
+
if (issueIds.length === 0)
|
|
158
|
+
return [];
|
|
159
|
+
const want = new Set(issueIds);
|
|
160
|
+
const filtered = all.filter((raw) => want.has(idOf(raw)));
|
|
161
|
+
return normalizeIssues(filtered, all);
|
|
162
|
+
}
|
|
163
|
+
// ─── multi-match disambiguation (ported from resolveMatch) ───────────────────
|
|
164
|
+
/**
|
|
165
|
+
* Resolve the single raw file that matches `issueId`. Multiple files can share
|
|
166
|
+
* an id when a stale terminal copy survives alongside a live active copy;
|
|
167
|
+
* `readdir` ordering is filesystem-dependent, so we refuse to guess. When more
|
|
168
|
+
* than one candidate matches, prefer the copy whose state equals the
|
|
169
|
+
* caller-supplied `fromState`; if that still doesn't resolve to exactly one,
|
|
170
|
+
* throw `TrackerError('local_issue_ambiguous')`.
|
|
171
|
+
*
|
|
172
|
+
* `candidates` is the pre-filtered set (state in: all files with `idOf === issueId`).
|
|
173
|
+
* Throws `TrackerError('local_issue_not_found')` when empty.
|
|
174
|
+
*/
|
|
175
|
+
export function resolveMatch(candidates, issueId, fromState) {
|
|
176
|
+
if (candidates.length === 0) {
|
|
177
|
+
throw new TrackerError('local_issue_not_found', `no issue file matches id ${issueId}`);
|
|
178
|
+
}
|
|
179
|
+
if (candidates.length === 1)
|
|
180
|
+
return candidates[0];
|
|
181
|
+
const preferred = fromState
|
|
182
|
+
? candidates.filter((raw) => raw.state.toLowerCase() === fromState.toLowerCase())
|
|
183
|
+
: [];
|
|
184
|
+
if (preferred.length === 1)
|
|
185
|
+
return preferred[0];
|
|
186
|
+
const statesStr = candidates.map((raw) => raw.state).join(', ');
|
|
187
|
+
throw new TrackerError('local_issue_ambiguous', `multiple issue files match id ${issueId} across states [${statesStr}]; pass fromState to disambiguate`);
|
|
188
|
+
}
|
|
189
|
+
/** All raw files whose canonical id equals `issueId` (the input `resolveMatch` expects). */
|
|
190
|
+
export function matchingCandidates(all, issueId) {
|
|
191
|
+
return all.filter((raw) => idOf(raw) === issueId);
|
|
192
|
+
}
|
|
193
|
+
// ─── next-free-identifier collision pick (pure half of writeIssueFile) ───────
|
|
194
|
+
/**
|
|
195
|
+
* Pick the next free numeric identifier given the existing-identifier SET (the
|
|
196
|
+
* shell's readdir supplies it — impureCoreRisk fix: NO scan here). Counts up
|
|
197
|
+
* from 1 until it finds a basename not present in `existing`. Title-slug files
|
|
198
|
+
* from prior cycles are inert: only numeric basenames consume IDs.
|
|
199
|
+
*
|
|
200
|
+
* `existing` should be the union of identifiers across ALL state directories,
|
|
201
|
+
* so a `Done/3.md` can't silently shadow a freshly created `Todo/3.md` once it
|
|
202
|
+
* moves out of Todo (faithful to `collectExistingIdentifiers`).
|
|
203
|
+
*/
|
|
204
|
+
export function pickNextNumericIdentifier(existing) {
|
|
205
|
+
let n = 1;
|
|
206
|
+
while (existing.has(String(n)))
|
|
207
|
+
n += 1;
|
|
208
|
+
return String(n);
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/core/issue/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// FCIS rewrite — pure MCP tools/call PRE-move decider (ported from src/mcp.ts:
|
|
2
|
+
// callTransition / callRequestHumanSteering / callProposeIssue). `decideToolCall`
|
|
3
|
+
// is a pure synchronous (data) -> {response, effects} function: it does no IO,
|
|
4
|
+
// reads no clock, holds no Promise.
|
|
5
|
+
//
|
|
6
|
+
// The keystone of the FCIS split — what is and is NOT decided here:
|
|
7
|
+
// * VALIDATION (data-only) IS decided here: declared-state + `allowed_transitions`
|
|
8
|
+
// gate, the non-empty/single-line arg checks, and the "steering already
|
|
9
|
+
// pending" guard. A rejection is the synchronous tool-result (`isError: true`,
|
|
10
|
+
// plus a structured payload for the transition rejections), with NO effects.
|
|
11
|
+
// * The MOVE is an EFFECT: a valid transition emits `move_state` +
|
|
12
|
+
// `set_transitioned`; the shell runs the move, folds the resolved
|
|
13
|
+
// {fromState,toState}, builds the success response, and decides `defer_cleanup`
|
|
14
|
+
// (the post-move cleanup gate lives in the core/mcp fold, not here).
|
|
15
|
+
// * The steering AWAITER Promise is never held here (desync fix, issue 151):
|
|
16
|
+
// we emit `stash_steering` + `await_steering`; the shell parks the awaiter and
|
|
17
|
+
// flips `steering_requested` only once it is live.
|
|
18
|
+
// * `propose_issue` emits `write_issue` with validated fields only; the shell
|
|
19
|
+
// stamps `proposed_at` from its injected Clock (orig: `isoFromClock(this.now)`).
|
|
20
|
+
import { resolveDeclaredName, isInFlowTransition } from '../state-resolve.js';
|
|
21
|
+
import { makeError } from './protocol.js';
|
|
22
|
+
// ─── Top-level dispatch ─────────────────────────────────────────────────────
|
|
23
|
+
/**
|
|
24
|
+
* Decide a single `tools/call`. Returns the synchronous response and/or the
|
|
25
|
+
* effects to perform. Unknown tool names produce a JSON-RPC method-not-found
|
|
26
|
+
* error (matching the original `unknown tool: <name>` branch).
|
|
27
|
+
*/
|
|
28
|
+
export function decideToolCall(id, toolName, args, view, states) {
|
|
29
|
+
switch (toolName) {
|
|
30
|
+
case 'transition':
|
|
31
|
+
return decideTransition(id, args, view, states);
|
|
32
|
+
case 'request_human_steering':
|
|
33
|
+
return decideRequestHumanSteering(id, args, view);
|
|
34
|
+
case 'propose_issue':
|
|
35
|
+
return decideProposeIssue(id, args, view, states);
|
|
36
|
+
default:
|
|
37
|
+
return { response: makeError(id, -32601, `unknown tool: ${toolName}`), effects: [] };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// ─── transition ─────────────────────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* `transition({ to_state, notes? })`. Validate the target against the declared
|
|
43
|
+
* states + the current state's `allowed_transitions`, then emit the move.
|
|
44
|
+
*
|
|
45
|
+
* Validation rejections return a tool-result error (the structured ones for
|
|
46
|
+
* `unknown_state` / `transition_not_allowed` carry the machine-readable payload
|
|
47
|
+
* the agent reads to pick a valid target next call). On success, `response` is
|
|
48
|
+
* null and `effects` carries `move_state` + `set_transitioned`.
|
|
49
|
+
*/
|
|
50
|
+
export function decideTransition(id, args, view, states) {
|
|
51
|
+
const toStateRaw = typeof args.to_state === 'string' ? args.to_state.trim() : '';
|
|
52
|
+
const notes = typeof args.notes === 'string' ? args.notes : '';
|
|
53
|
+
if (!toStateRaw) {
|
|
54
|
+
return rejectText(id, 'to_state is required and must be a non-empty string');
|
|
55
|
+
}
|
|
56
|
+
if (!view.trackerSupportsMove) {
|
|
57
|
+
return rejectText(id, 'this tracker does not support state transitions');
|
|
58
|
+
}
|
|
59
|
+
const declaredNames = states.order;
|
|
60
|
+
const canonicalTarget = canonicalStateName(states, toStateRaw);
|
|
61
|
+
if (canonicalTarget === null) {
|
|
62
|
+
const text = `state "${toStateRaw}" is not declared. declared: ${declaredNames.length > 0 ? declaredNames.join(', ') : '<none>'}`;
|
|
63
|
+
return rejectStructured(id, text, {
|
|
64
|
+
error: 'unknown_state',
|
|
65
|
+
declared_states: declaredNames,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// `allowed_transitions: null | undefined` ⇒ any declared state reachable; a
|
|
69
|
+
// present array restricts (empty array ⇒ no transitions out). Validate only
|
|
70
|
+
// when the CURRENT state canonicalizes to a declared state with a list. The
|
|
71
|
+
// in-flow test is the ONE predicate shared with the operator's soft-warning
|
|
72
|
+
// move endpoint (isInFlowTransition, src/core/state-resolve.ts) — the agent
|
|
73
|
+
// path HARD-rejects exactly what the operator path only warns on (issue 126).
|
|
74
|
+
// A self-transition is always in-flow (the predicate short-circuits it).
|
|
75
|
+
const canonicalFrom = canonicalStateName(states, view.fromState);
|
|
76
|
+
if (canonicalFrom !== null) {
|
|
77
|
+
const allowed = states.views[canonicalFrom].allowed_transitions;
|
|
78
|
+
if (allowed && !isInFlowTransition(allowed, canonicalFrom, canonicalTarget)) {
|
|
79
|
+
const text = `transition to "${canonicalTarget}" is not allowed from "${canonicalFrom}". allowed: ${allowed.length > 0 ? allowed.join(', ') : '<none>'}`;
|
|
80
|
+
return rejectStructured(id, text, {
|
|
81
|
+
error: 'transition_not_allowed',
|
|
82
|
+
from_state: canonicalFrom,
|
|
83
|
+
requested_to_state: canonicalTarget,
|
|
84
|
+
allowed_transitions: allowed,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Valid. Emit the move (the shell runs the tracker file-move and folds the
|
|
89
|
+
// resolved {fromState,toState} back to build the success response + decide
|
|
90
|
+
// cleanup). `set_transitioned` flips the post-turn exit flag. The decider
|
|
91
|
+
// does NOT build the success response (it depends on the resolved tracker
|
|
92
|
+
// result) → response: null.
|
|
93
|
+
const effects = [
|
|
94
|
+
{
|
|
95
|
+
kind: 'move_state',
|
|
96
|
+
issueId: view.issueId,
|
|
97
|
+
toState: canonicalTarget,
|
|
98
|
+
fromRoot: view.trackerRootSnapshot,
|
|
99
|
+
fromState: view.fromState,
|
|
100
|
+
notes,
|
|
101
|
+
actor: view.actor,
|
|
102
|
+
},
|
|
103
|
+
{ kind: 'set_transitioned' },
|
|
104
|
+
];
|
|
105
|
+
return { response: null, effects };
|
|
106
|
+
}
|
|
107
|
+
// ─── request_human_steering ───────────────────────────────────────────────
|
|
108
|
+
/**
|
|
109
|
+
* `request_human_steering({ question, context? })`. Validate the question and
|
|
110
|
+
* the "already pending" guard, then emit `stash_steering` + `await_steering`.
|
|
111
|
+
*
|
|
112
|
+
* The decider returns a READY ack response (the original returned the ack
|
|
113
|
+
* synchronously — the question is merely queued; the turn ends and the human
|
|
114
|
+
* reply arrives as the next turn's prompt). The awaiter Promise + the
|
|
115
|
+
* `steering_requested` flag flip both live in the shell (issue 151).
|
|
116
|
+
*/
|
|
117
|
+
export function decideRequestHumanSteering(id, args, view) {
|
|
118
|
+
const question = typeof args.question === 'string' ? args.question.trim() : '';
|
|
119
|
+
const context = typeof args.context === 'string' ? args.context.trim() : '';
|
|
120
|
+
if (!question) {
|
|
121
|
+
return rejectText(id, 'question is required and must be a non-empty string');
|
|
122
|
+
}
|
|
123
|
+
// Guard on the stashed question (awaiter-liveness desync fix, issue 151): a
|
|
124
|
+
// non-null pending question means an unanswered request is already out.
|
|
125
|
+
if (view.steeringPending) {
|
|
126
|
+
return rejectText(id, 'a steering request is already pending for this issue; end the turn and wait for the response');
|
|
127
|
+
}
|
|
128
|
+
const effects = [
|
|
129
|
+
{ kind: 'stash_steering', question, context: context.length > 0 ? context : null },
|
|
130
|
+
{ kind: 'await_steering' },
|
|
131
|
+
];
|
|
132
|
+
const ack = 'Question queued. End this turn now. The human response will arrive as the prompt for your next turn.';
|
|
133
|
+
return { response: toolResult(id, ack, false), effects };
|
|
134
|
+
}
|
|
135
|
+
// ─── propose_issue ──────────────────────────────────────────────────────────
|
|
136
|
+
/**
|
|
137
|
+
* `propose_issue({ title, description?, labels?, priority? })`. Validate the
|
|
138
|
+
* title (non-empty single line), resolve the landing holding state, then emit
|
|
139
|
+
* the `write_issue` effect. The shell stamps `proposed_at` from its Clock and
|
|
140
|
+
* builds the success response from the written {identifier,state,path}; on a
|
|
141
|
+
* valid propose this decider returns `response: null` (the identifier isn't
|
|
142
|
+
* known until the file is written).
|
|
143
|
+
*
|
|
144
|
+
* Two rejections are decided here purely:
|
|
145
|
+
* - missing/multiline title (text tool-error)
|
|
146
|
+
* - unresolvable tracker root (text tool-error)
|
|
147
|
+
* - no declared holding state (structured `no_holding_state` tool-error)
|
|
148
|
+
*/
|
|
149
|
+
export function decideProposeIssue(id, args, view, states) {
|
|
150
|
+
const titleRaw = typeof args.title === 'string' ? args.title.trim() : '';
|
|
151
|
+
const description = typeof args.description === 'string' ? args.description : '';
|
|
152
|
+
if (!titleRaw) {
|
|
153
|
+
return rejectText(id, 'title is required and must be a non-empty string');
|
|
154
|
+
}
|
|
155
|
+
if (titleRaw.includes('\n')) {
|
|
156
|
+
return rejectText(id, 'title must be a single line (no embedded newlines)');
|
|
157
|
+
}
|
|
158
|
+
const labels = Array.isArray(args.labels)
|
|
159
|
+
? args.labels.filter((x) => typeof x === 'string')
|
|
160
|
+
: [];
|
|
161
|
+
const priority = typeof args.priority === 'number' && Number.isFinite(args.priority) ? args.priority : null;
|
|
162
|
+
// Original resolved root := dispatch snapshot ?? tracker.currentRoot(); the
|
|
163
|
+
// shell projects that already-resolved value into `trackerRootSnapshot`, so a
|
|
164
|
+
// null here is the genuine "no resolvable root" case.
|
|
165
|
+
if (view.trackerRootSnapshot === null) {
|
|
166
|
+
return rejectText(id, 'tracker root is not available; cannot create issue files (is this a non-local tracker?)');
|
|
167
|
+
}
|
|
168
|
+
// Landing state must exist (first declared `holding` state). Core resolves the
|
|
169
|
+
// actual landing name HERE (strict, declaration-order) and carries it on the
|
|
170
|
+
// effect so the shell writer never re-resolves it with a divergent fallback.
|
|
171
|
+
const landingState = pickHoldingState(states);
|
|
172
|
+
if (landingState === null) {
|
|
173
|
+
return rejectStructured(id, 'cannot propose issue: workflow has no holding-role state declared', {
|
|
174
|
+
error: 'no_holding_state',
|
|
175
|
+
declared_states: states.order,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const effects = [
|
|
179
|
+
{
|
|
180
|
+
kind: 'write_issue',
|
|
181
|
+
title: titleRaw,
|
|
182
|
+
description: description.length > 0 ? description : null,
|
|
183
|
+
labels,
|
|
184
|
+
priority,
|
|
185
|
+
proposedBy: view.identifier,
|
|
186
|
+
landingState,
|
|
187
|
+
},
|
|
188
|
+
];
|
|
189
|
+
return { response: null, effects };
|
|
190
|
+
}
|
|
191
|
+
// ─── Pure helpers ───────────────────────────────────────────────────────────
|
|
192
|
+
/**
|
|
193
|
+
* Canonical declared name for `name` (exact match wins, else a case-insensitive
|
|
194
|
+
* scan in declaration order). Thin adapter over the canonical
|
|
195
|
+
* {@link resolveDeclaredName} (core/state-resolve.ts) keyed by the MCP states
|
|
196
|
+
* view's declared-name `order`. Returns null when no declared state matches.
|
|
197
|
+
*/
|
|
198
|
+
export function canonicalStateName(states, name) {
|
|
199
|
+
return resolveDeclaredName(states.order, name);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* First declared `holding` state in declaration order, or null when none is
|
|
203
|
+
* declared. Pure mirror of core/states.pickHoldingState, but returns null (the
|
|
204
|
+
* caller turns that into the structured `no_holding_state` rejection) rather
|
|
205
|
+
* than a NoHoldingStateError value, since the original surfaced it as a tool
|
|
206
|
+
* error to the agent rather than throwing.
|
|
207
|
+
*/
|
|
208
|
+
function pickHoldingState(states) {
|
|
209
|
+
for (const name of states.order) {
|
|
210
|
+
const v = states.views[name];
|
|
211
|
+
if (v && v.role === 'holding')
|
|
212
|
+
return name;
|
|
213
|
+
}
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
// ─── Response constructors (pure value objects) ───────────────────────────────
|
|
217
|
+
// `makeError` (the JSON-RPC error envelope) is imported from ./protocol.js — the
|
|
218
|
+
// canonical home — rather than re-inlined here (it was byte-identical).
|
|
219
|
+
/**
|
|
220
|
+
* MCP convention: tool results (success OR error) are a `result`, not a JSON-RPC
|
|
221
|
+
* error. `isError` marks a tool failure; the optional `structuredContent` slot
|
|
222
|
+
* carries the machine-readable recovery payload (transition + no_holding_state
|
|
223
|
+
* rejections) the agent reads to pick a valid next call.
|
|
224
|
+
*/
|
|
225
|
+
function toolResult(id, text, isError, structuredContent) {
|
|
226
|
+
const result = { content: [{ type: 'text', text }], isError };
|
|
227
|
+
if (structuredContent)
|
|
228
|
+
result.structuredContent = structuredContent;
|
|
229
|
+
return { jsonrpc: '2.0', id, result };
|
|
230
|
+
}
|
|
231
|
+
/** Plain-text tool-error decision with no effects. */
|
|
232
|
+
function rejectText(id, message) {
|
|
233
|
+
return { response: toolResult(id, message, true), effects: [] };
|
|
234
|
+
}
|
|
235
|
+
/** Structured tool-error decision (text + machine-readable payload), no effects. */
|
|
236
|
+
function rejectStructured(id, text, json) {
|
|
237
|
+
return { response: toolResult(id, text, true, json), effects: [] };
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../../src/core/mcp/dispatch.ts"],"names":[],"mappings":"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"}
|