@iowarp/clio-coder 0.3.4 → 0.3.7
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/CHANGELOG.md +65 -2
- package/CONTRIBUTING.md +6 -6
- package/README.md +16 -5
- package/dist/{acp-S5R4RR5B.js → acp-SK4MD6MM.js} +11 -11
- package/dist/{agents-P6DMMVZY.js → agents-2FN2K6ME.js} +33 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-2XCZLPKS.js → auth-QIYZWM5I.js} +15 -15
- package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
- package/dist/{chunk-VAWWTKDP.js → chunk-3HAPLH5M.js} +11 -11
- package/dist/{chunk-YCWGATWI.js → chunk-465YSENW.js} +3 -3
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-UZHIZC5S.js → chunk-4DWFMQDR.js} +61 -76
- package/dist/{chunk-ZWMF7253.js → chunk-5C3AQNDW.js} +328 -9
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-WPQLXFOZ.js → chunk-5FR74PWO.js} +3 -2
- package/dist/{chunk-35MKKU5R.js → chunk-5UJ6ECTS.js} +18 -10
- package/dist/{chunk-BRXQQJFP.js → chunk-6M7VS3J3.js} +571 -50
- package/dist/{chunk-QQK64KLB.js → chunk-6TUKSZVF.js} +141 -23
- package/dist/{chunk-N4CZJQRK.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-KRPY7NTG.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-ZYKPLLNQ.js → chunk-CEYBNUGC.js} +821 -83
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-BP4OYD6A.js → chunk-DMD2AGVS.js} +21 -2
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-3HZ5RWN2.js → chunk-EBEFWSGL.js} +9 -7
- package/dist/{chunk-EDRHSCIE.js → chunk-EELBMBT6.js} +128 -13
- package/dist/{chunk-HV5X7OR2.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-BPGS2WCQ.js → chunk-GEYXPTRF.js} +2 -1
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/{chunk-BEY543CS.js → chunk-GOXNB3AO.js} +5 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
- package/dist/chunk-HWUFFB6L.js +83 -0
- package/dist/{chunk-X6COSD2O.js → chunk-J7PIKKWC.js} +8 -436
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-K6WL7QZT.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-A2GZF7DC.js → chunk-LADCF22A.js} +13 -13
- package/dist/chunk-LCGCVYZ4.js +57 -0
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
- package/dist/{chunk-4JUF2NNX.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
- package/dist/{chunk-TTNYS3EA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-7RXG6QRZ.js → chunk-OBMAI2DP.js} +61 -840
- package/dist/{chunk-5M54SPOL.js → chunk-ODFEOB4F.js} +161 -5
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
- package/dist/{chunk-VMNQ6OZA.js → chunk-QCTRSGHQ.js} +963 -786
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-34475P3I.js → chunk-TSHXZTOQ.js} +5 -4
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QQL5RT5M.js → chunk-UUANF5CR.js} +2323 -2114
- package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-QWU7ZBO7.js → chunk-VQNODYQ4.js} +215 -56
- package/dist/chunk-VREKEFLL.js +37 -0
- package/dist/{chunk-2TZWSW76.js → chunk-WHGPSPT5.js} +2 -2
- package/dist/{chunk-TW3WDMVS.js → chunk-WHJYKASB.js} +2 -2
- package/dist/{chunk-MEQ45TQ4.js → chunk-WJHBC77E.js} +21 -7
- package/dist/{chunk-HXG4IURW.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
- package/dist/{chunk-2LZI5CAG.js → chunk-XEGB6BCN.js} +228 -36
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-4UUM6TEE.js → chunk-YTYFXUI3.js} +121 -372
- package/dist/{chunk-3JLKSKD7.js → chunk-ZGH7FGS5.js} +17 -7
- package/dist/{chunk-VSNATDE6.js → chunk-ZZMN5OM4.js} +2 -2
- package/dist/cli/index.js +34 -32
- package/dist/{clio-J5JIOIDS.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-AXCXSBHX.js → code-nav-FGGFIE7L.js} +7 -7
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-KELWS457.js → components-F7OEATSO.js} +5 -5
- package/dist/{config-OEBMIN2U.js → config-TRBL3RCF.js} +48 -41
- package/dist/{configure-PUQOSIXQ.js → configure-OLCVPHNM.js} +17 -17
- package/dist/{context-URSXPBCK.js → context-MJIJ6GOX.js} +12 -12
- package/dist/{context-EKDCKUUZ.js → context-WFPKQSM6.js} +26 -9
- package/dist/{context-MGSE4Z2T.js → context-XEWE3MOJ.js} +44 -37
- package/dist/{context-clear-KDAJRNUK.js → context-clear-KNOS2JPB.js} +44 -37
- package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
- package/dist/{context-working-set-SBKMPPI2.js → context-working-set-EUXAZI6N.js} +14 -13
- package/dist/{dispatch-runner-MSWN72NK.js → dispatch-runner-B7MTOVKL.js} +321 -60
- package/dist/{docs-2C2LTVT2.js → docs-FLJTIDSE.js} +5 -5
- package/dist/{doctor-7BSE27PJ.js → doctor-RN4YKO2X.js} +15 -15
- package/dist/{eval-IZGDOO4H.js → eval-RUBJVSNQ.js} +52 -236
- package/dist/{evidence-SR7WXB5B.js → evidence-JZNBUOQZ.js} +39 -33
- package/dist/{evolve-K7VE2CBX.js → evolve-FJVC4KKI.js} +39 -33
- package/dist/{extensions-QVDOHDGJ.js → extensions-IQL36S7K.js} +5 -5
- package/dist/{fleet-7XMJNQNF.js → fleet-BDKYJFCP.js} +243 -370
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/{fleet-preflight-AQNAH644.js → fleet-preflight-BHSNPBMH.js} +2 -2
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-JGNPAYXT.js → init-LQUB5COQ.js} +57 -48
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/memory-OG6HOYKM.js +472 -0
- package/dist/{models-ZMMLFJNN.js → models-5ZG5XY7J.js} +23 -22
- package/dist/{monitor-2F3T5KHP.js → monitor-TJ7AMTGB.js} +69 -35
- package/dist/{orchestrator-ORHT43JB.js → orchestrator-WZYB54DM.js} +4868 -1189
- package/dist/{paths-UXLN5YYZ.js → paths-XUC7GS6E.js} +5 -5
- package/dist/{reset-NXGTYNUO.js → reset-PXQT45IY.js} +8 -8
- package/dist/{run-RF4WJGMT.js → run-FQ74YF62.js} +82 -62
- package/dist/{share-UT3W6E4M.js → share-FW7SVCL3.js} +34 -10
- package/dist/{skills-PSACKC5Q.js → skills-7E7IRB3R.js} +25 -9
- package/dist/{skills-eval-WJSI55RZ.js → skills-eval-LI75W6OK.js} +43 -35
- package/dist/{targets-PIIRAOYS.js → targets-4CIFKCTW.js} +27 -24
- package/dist/{terminal-lease-ULWXWNVY.js → terminal-lease-WUZY7ZV5.js} +5 -4
- package/dist/{uninstall-FZCQCDKC.js → uninstall-7FV7IP4E.js} +5 -5
- package/dist/{upgrade-346TZ6AV.js → upgrade-K2HVIVMQ.js} +21 -20
- package/dist/{usage-6KKXR32N.js → usage-GTZELZQX.js} +159 -59
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-7STOCIFZ.js → wiki-generate-ASIFASCN.js} +58 -48
- package/dist/worker/entry.js +98 -84
- package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
- package/docs/README.md +4 -3
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-placement.md +1 -2
- package/docs/artifact-versions.md +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +90 -8
- package/docs/configuration-and-targets.md +90 -2
- package/docs/context-engine.md +4 -2
- package/docs/context-working-set.md +4 -4
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +4 -4
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +4 -45
- package/docs/evidence-and-memory.md +70 -10
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +224 -11
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +20 -2
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +55 -8
- package/docs/proactive-memory.md +26 -16
- package/docs/prompt-envelope-and-tools.md +4 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +83 -65
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +29 -7
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +38 -4
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +7 -4
- package/src/cli/agents.ts +2 -3
- package/src/cli/argv.ts +14 -1
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +121 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +188 -335
- package/src/cli/index.ts +4 -2
- package/src/cli/library.ts +190 -0
- package/src/cli/memory.ts +272 -10
- package/src/cli/modes/json-stream.ts +2 -2
- package/src/cli/modes/print.ts +12 -1
- package/src/cli/run.ts +22 -2
- package/src/cli/share.ts +13 -1
- package/src/cli/targets.ts +12 -3
- package/src/cli/usage.ts +160 -20
- package/src/core/bus-events.ts +7 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/core/response-model-id.ts +134 -0
- package/src/core/toml.ts +62 -0
- package/src/core/workspace-files.ts +0 -1
- package/src/domains/agents/builtins/architect.md +2 -1
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +18 -5
- package/src/domains/agents/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/recipe.ts +54 -14
- package/src/domains/agents/result-contract.ts +242 -5
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/context/bootstrap.ts +36 -27
- package/src/domains/context/project-metadata.ts +19 -63
- package/src/domains/context/prompt-context.ts +8 -0
- package/src/domains/context/working-set/policies/index.ts +3 -4
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/budget-envelope.ts +396 -0
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +36 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +339 -36
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +12 -4
- package/src/domains/dispatch/state.ts +37 -3
- package/src/domains/dispatch/types.ts +61 -9
- package/src/domains/dispatch/validation.ts +80 -6
- package/src/domains/dispatch/worker-spawn.ts +14 -3
- package/src/domains/eval/metrics/evidence.ts +0 -116
- package/src/domains/eval/metrics/invariants.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +1 -10
- package/src/domains/eval/runners/external-command.ts +2 -29
- package/src/domains/eval/schema/suite.ts +0 -7
- package/src/domains/eval/suites/run.ts +1 -7
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/memory/index.ts +22 -0
- package/src/domains/memory/operations.ts +58 -1
- package/src/domains/memory/promotion.ts +281 -0
- package/src/domains/memory/prompt-section.ts +25 -5
- package/src/domains/memory/proposal.ts +51 -7
- package/src/domains/memory/task-bank.ts +3 -2
- package/src/domains/memory/task-memory-handoff.ts +181 -24
- package/src/domains/memory/task-memory-policy.ts +3 -1
- package/src/domains/memory/types.ts +37 -0
- package/src/domains/memory/validate.ts +178 -0
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/memory-intervention.ts +35 -25
- package/src/domains/middleware/runtime.ts +6 -0
- package/src/domains/middleware/skills-reminder.ts +19 -4
- package/src/domains/middleware/stalled-turn.ts +43 -1
- package/src/domains/middleware/types.ts +10 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +9 -2
- package/src/domains/observability/cost.ts +31 -4
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/providers/index.ts +3 -0
- package/src/domains/providers/model-discovery.ts +9 -0
- package/src/domains/providers/runtime-resolution.ts +38 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
- package/src/domains/providers/types/context-window-slots.ts +18 -0
- package/src/domains/providers/types/runtime-descriptor.ts +3 -1
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/safety/call-target.ts +211 -14
- package/src/domains/safety/decision-presentation.ts +268 -0
- package/src/domains/safety/redaction.ts +73 -0
- package/src/domains/session/context-ledger.ts +10 -1
- package/src/domains/session/decision-board.ts +4 -0
- package/src/domains/session/entries.ts +3 -0
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/session/history.ts +68 -19
- package/src/domains/session/usage.ts +24 -7
- package/src/domains/share/archive.ts +67 -2
- package/src/engine/acp/event-mapper.ts +7 -0
- package/src/engine/acp/server.ts +29 -2
- package/src/engine/apis/lmstudio.ts +25 -4
- package/src/engine/apis/openai-completions.ts +147 -22
- package/src/engine/claude/sdk-runtime.ts +8 -2
- package/src/engine/claude/tool-safety.ts +13 -0
- package/src/engine/loop-guard.ts +27 -3
- package/src/engine/worker-events.ts +4 -3
- package/src/engine/worker-runtime.ts +59 -54
- package/src/entry/orchestrator.ts +55 -1
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop-messages.ts +22 -0
- package/src/interactive/chat-loop.ts +248 -1
- package/src/interactive/chat-renderer.ts +41 -3
- package/src/interactive/clio-editor.ts +44 -7
- package/src/interactive/context-overlay.ts +43 -5
- package/src/interactive/cost-overlay.ts +70 -11
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +471 -50
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +49 -2
- package/src/interactive/interactive-event-projection.ts +9 -1
- package/src/interactive/interactive-input-runtime.ts +11 -1
- package/src/interactive/interactive-presentation.ts +11 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/memory-overlay.ts +89 -4
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +7 -1
- package/src/interactive/overlay-frame.ts +5 -2
- package/src/interactive/overlay-general-openers.ts +230 -2
- package/src/interactive/overlay-key-routing.ts +58 -2
- package/src/interactive/overlay-lifecycle.ts +52 -5
- package/src/interactive/overlay-permission-lifecycle.ts +33 -8
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlay-transitions.ts +11 -0
- package/src/interactive/overlays/ask-user.ts +74 -30
- package/src/interactive/overlays/decisions.ts +3 -1
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +101 -4
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/permission-hint.ts +35 -0
- package/src/interactive/permission-overlay.ts +95 -45
- package/src/interactive/renderers/tool-execution.ts +19 -49
- package/src/interactive/session-last-turn.ts +8 -1
- package/src/interactive/session-usage-reseed.ts +36 -10
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +434 -7
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/status/summary.ts +5 -0
- package/src/interactive/status/types.ts +5 -0
- package/src/interactive/terminal-lease.ts +1 -0
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-context.ts +96 -23
- package/src/interactive/turn-middleware.ts +16 -1
- package/src/interactive/turn-runtime.ts +37 -8
- package/src/interactive/turn-state.ts +3 -0
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-progress.ts +440 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +58 -110
- package/src/tools/agent-tools.ts +28 -3
- package/src/tools/ask-user.ts +21 -1
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/context/index.ts +2 -2
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +65 -1
- package/src/tools/dispatch-event-text.ts +19 -0
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +96 -3
- package/src/tools/monitor.ts +31 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/registry.ts +15 -5
- package/src/tools/result-disposition.ts +156 -0
- package/src/tools/result-shaping.ts +59 -1
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +116 -55
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +21 -1
- package/src/worker/spec-contract.ts +44 -3
- package/dist/chunk-EFADSJET.js +0 -18
- package/dist/chunk-HC4CLZ2Y.js +0 -68
- package/dist/memory-4ALKDJ4Q.js +0 -246
- package/src/domains/eval/metrics/chaos-stream.ts +0 -93
|
@@ -15,6 +15,7 @@ import { basename, join } from "node:path";
|
|
|
15
15
|
import { Type } from "typebox";
|
|
16
16
|
import { Value } from "typebox/value";
|
|
17
17
|
import { resolvePackageRoot } from "../../core/package-root.js";
|
|
18
|
+
import { clioConfigDir } from "../../core/xdg.js";
|
|
18
19
|
import { type FleetCommandRegistry, loadFleetCommands } from "./fleet-commands.js";
|
|
19
20
|
import { parseFrontmatter } from "./frontmatter.js";
|
|
20
21
|
import { normalizeWriteBoundary, WRITE_BOUNDARY_MAX_ENTRIES } from "./write-boundary.js";
|
|
@@ -35,6 +36,7 @@ export type FleetOnFailure = "stop" | "continue";
|
|
|
35
36
|
* allowlist stated out loud.
|
|
36
37
|
*/
|
|
37
38
|
export const FLEET_WRITE_BOUNDARY_VERSION = 4;
|
|
39
|
+
export const FLEET_DYNAMIC_STEP_VERSION = 5;
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
42
|
* Upper bound on any declared loop. A loop is bounded in the contract, and the
|
|
@@ -63,6 +65,34 @@ export interface FleetContractAgentStep {
|
|
|
63
65
|
scope: FleetStepScope;
|
|
64
66
|
dependencies: ReadonlyArray<string>;
|
|
65
67
|
writes?: ReadonlyArray<string>;
|
|
68
|
+
target?: string;
|
|
69
|
+
profile?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface FleetContractGateStep {
|
|
73
|
+
kind: "gate";
|
|
74
|
+
id: string;
|
|
75
|
+
agent: string;
|
|
76
|
+
path: string;
|
|
77
|
+
run: string;
|
|
78
|
+
scope: "workspace";
|
|
79
|
+
dependencies: ReadonlyArray<string>;
|
|
80
|
+
target?: string;
|
|
81
|
+
profile?: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface FleetContractPlanStep {
|
|
85
|
+
kind: "plan";
|
|
86
|
+
id: string;
|
|
87
|
+
agent: string;
|
|
88
|
+
roster: ReadonlyArray<string>;
|
|
89
|
+
maxTasks: number;
|
|
90
|
+
proposals: boolean;
|
|
91
|
+
scope: FleetStepScope;
|
|
92
|
+
dependencies: ReadonlyArray<string>;
|
|
93
|
+
writes?: ReadonlyArray<string>;
|
|
94
|
+
target?: string;
|
|
95
|
+
profile?: string;
|
|
66
96
|
}
|
|
67
97
|
|
|
68
98
|
/**
|
|
@@ -89,7 +119,15 @@ export interface FleetContractCodeStep {
|
|
|
89
119
|
/** The verification half of a loop: the question that decides continuation. */
|
|
90
120
|
export type FleetContractLoopCheck =
|
|
91
121
|
| { kind: "code"; command: string; scope: FleetStepScope; writes?: ReadonlyArray<string> }
|
|
92
|
-
| {
|
|
122
|
+
| {
|
|
123
|
+
kind: "agent";
|
|
124
|
+
agent: string;
|
|
125
|
+
scope: FleetStepScope;
|
|
126
|
+
writes?: ReadonlyArray<string>;
|
|
127
|
+
target?: string;
|
|
128
|
+
profile?: string;
|
|
129
|
+
}
|
|
130
|
+
| { kind: "gate"; gate: string };
|
|
93
131
|
|
|
94
132
|
/** The repair half. Always an agent: a deterministic repair is just a check. */
|
|
95
133
|
export interface FleetContractLoopRepair {
|
|
@@ -97,6 +135,8 @@ export interface FleetContractLoopRepair {
|
|
|
97
135
|
agent: string;
|
|
98
136
|
scope: FleetStepScope;
|
|
99
137
|
writes?: ReadonlyArray<string>;
|
|
138
|
+
target?: string;
|
|
139
|
+
profile?: string;
|
|
100
140
|
}
|
|
101
141
|
|
|
102
142
|
/**
|
|
@@ -120,7 +160,12 @@ export interface FleetContractLoopStep {
|
|
|
120
160
|
repair: FleetContractLoopRepair;
|
|
121
161
|
}
|
|
122
162
|
|
|
123
|
-
export type FleetContractStep =
|
|
163
|
+
export type FleetContractStep =
|
|
164
|
+
| FleetContractAgentStep
|
|
165
|
+
| FleetContractCodeStep
|
|
166
|
+
| FleetContractLoopStep
|
|
167
|
+
| FleetContractGateStep
|
|
168
|
+
| FleetContractPlanStep;
|
|
124
169
|
|
|
125
170
|
/**
|
|
126
171
|
* Contract schema version.
|
|
@@ -137,7 +182,7 @@ export type FleetContractStep = FleetContractAgentStep | FleetContractCodeStep |
|
|
|
137
182
|
* A version literal gives that reader a clear refusal instead of an obscure
|
|
138
183
|
* unknown-property error deep in a step.
|
|
139
184
|
*/
|
|
140
|
-
export type FleetContractVersion = 1 | 2 | 3 | 4;
|
|
185
|
+
export type FleetContractVersion = 1 | 2 | 3 | 4 | 5;
|
|
141
186
|
|
|
142
187
|
export interface FleetContract {
|
|
143
188
|
version: FleetContractVersion;
|
|
@@ -147,12 +192,13 @@ export interface FleetContract {
|
|
|
147
192
|
maxWorkers: number;
|
|
148
193
|
budgetUsd: number | null;
|
|
149
194
|
onFailure: FleetOnFailure;
|
|
195
|
+
writers?: 1;
|
|
150
196
|
/** Prompt template body with unresolved {{var}} placeholders. */
|
|
151
197
|
body: string;
|
|
152
198
|
path: string;
|
|
153
199
|
}
|
|
154
200
|
|
|
155
|
-
export type FleetContractSource = "builtin" | "project";
|
|
201
|
+
export type FleetContractSource = "builtin" | "user" | "project";
|
|
156
202
|
|
|
157
203
|
export interface FleetContractListing {
|
|
158
204
|
name: string;
|
|
@@ -183,6 +229,12 @@ function writesSchema(version: FleetContractVersion) {
|
|
|
183
229
|
: {};
|
|
184
230
|
}
|
|
185
231
|
|
|
232
|
+
function routeSchema(version: FleetContractVersion) {
|
|
233
|
+
return version >= FLEET_DYNAMIC_STEP_VERSION
|
|
234
|
+
? { target: Type.Optional(Type.String({ minLength: 1 })), profile: Type.Optional(Type.String({ minLength: 1 })) }
|
|
235
|
+
: {};
|
|
236
|
+
}
|
|
237
|
+
|
|
186
238
|
function agentStepSchema(version: FleetContractVersion) {
|
|
187
239
|
return Type.Object(
|
|
188
240
|
{
|
|
@@ -192,6 +244,41 @@ function agentStepSchema(version: FleetContractVersion) {
|
|
|
192
244
|
scope: FleetScopeSchema,
|
|
193
245
|
dependencies: Type.Array(Type.String({ minLength: 1 })),
|
|
194
246
|
...writesSchema(version),
|
|
247
|
+
...routeSchema(version),
|
|
248
|
+
},
|
|
249
|
+
{ additionalProperties: false },
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function gateStepSchema() {
|
|
254
|
+
return Type.Object(
|
|
255
|
+
{
|
|
256
|
+
kind: Type.Literal("gate"),
|
|
257
|
+
id: Type.String({ minLength: 1 }),
|
|
258
|
+
agent: Type.String({ minLength: 1 }),
|
|
259
|
+
path: Type.String({ minLength: 1 }),
|
|
260
|
+
run: Type.String({ minLength: 1 }),
|
|
261
|
+
scope: Type.Optional(Type.Literal("workspace")),
|
|
262
|
+
dependencies: Type.Array(Type.String({ minLength: 1 })),
|
|
263
|
+
...routeSchema(5),
|
|
264
|
+
},
|
|
265
|
+
{ additionalProperties: false },
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function planStepSchema() {
|
|
270
|
+
return Type.Object(
|
|
271
|
+
{
|
|
272
|
+
kind: Type.Literal("plan"),
|
|
273
|
+
id: Type.String({ minLength: 1 }),
|
|
274
|
+
agent: Type.Optional(Type.String({ minLength: 1 })),
|
|
275
|
+
roster: Type.Array(Type.String({ minLength: 1 }), { minItems: 1, maxItems: 16 }),
|
|
276
|
+
maxTasks: Type.Integer({ minimum: 1, maximum: 16 }),
|
|
277
|
+
proposals: Type.Optional(Type.Boolean()),
|
|
278
|
+
scope: FleetScopeSchema,
|
|
279
|
+
dependencies: Type.Array(Type.String({ minLength: 1 })),
|
|
280
|
+
...writesSchema(5),
|
|
281
|
+
...routeSchema(5),
|
|
195
282
|
},
|
|
196
283
|
{ additionalProperties: false },
|
|
197
284
|
);
|
|
@@ -230,12 +317,21 @@ function loopStepSchema(version: FleetContractVersion) {
|
|
|
230
317
|
},
|
|
231
318
|
{ additionalProperties: false },
|
|
232
319
|
),
|
|
320
|
+
...(version >= FLEET_DYNAMIC_STEP_VERSION
|
|
321
|
+
? [
|
|
322
|
+
Type.Object(
|
|
323
|
+
{ kind: Type.Literal("gate"), gate: Type.String({ minLength: 1 }) },
|
|
324
|
+
{ additionalProperties: false },
|
|
325
|
+
),
|
|
326
|
+
]
|
|
327
|
+
: []),
|
|
233
328
|
Type.Object(
|
|
234
329
|
{
|
|
235
330
|
kind: Type.Literal("agent"),
|
|
236
331
|
agent: Type.String({ minLength: 1 }),
|
|
237
332
|
scope: FleetScopeSchema,
|
|
238
333
|
...writesSchema(version),
|
|
334
|
+
...routeSchema(version),
|
|
239
335
|
},
|
|
240
336
|
{ additionalProperties: false },
|
|
241
337
|
),
|
|
@@ -246,6 +342,7 @@ function loopStepSchema(version: FleetContractVersion) {
|
|
|
246
342
|
agent: Type.String({ minLength: 1 }),
|
|
247
343
|
scope: FleetScopeSchema,
|
|
248
344
|
...writesSchema(version),
|
|
345
|
+
...routeSchema(version),
|
|
249
346
|
},
|
|
250
347
|
{ additionalProperties: false },
|
|
251
348
|
),
|
|
@@ -257,6 +354,15 @@ function loopStepSchema(version: FleetContractVersion) {
|
|
|
257
354
|
function stepSchema(version: FleetContractVersion) {
|
|
258
355
|
if (version === 1) return agentStepSchema(1);
|
|
259
356
|
if (version === 2) return Type.Union([agentStepSchema(2), codeStepSchema(2)]);
|
|
357
|
+
if (version === 5) {
|
|
358
|
+
return Type.Union([
|
|
359
|
+
agentStepSchema(version),
|
|
360
|
+
codeStepSchema(version),
|
|
361
|
+
loopStepSchema(version),
|
|
362
|
+
gateStepSchema(),
|
|
363
|
+
planStepSchema(),
|
|
364
|
+
]);
|
|
365
|
+
}
|
|
260
366
|
return Type.Union([agentStepSchema(version), codeStepSchema(version), loopStepSchema(version)]);
|
|
261
367
|
}
|
|
262
368
|
|
|
@@ -270,6 +376,7 @@ function frontmatterSchema(version: FleetContractVersion) {
|
|
|
270
376
|
maxWorkers: Type.Integer({ minimum: 1 }),
|
|
271
377
|
budgetUsd: Type.Optional(Type.Number()),
|
|
272
378
|
onFailure: Type.Union([Type.Literal("stop"), Type.Literal("continue")]),
|
|
379
|
+
...(version >= FLEET_DYNAMIC_STEP_VERSION ? { writers: Type.Optional(Type.Literal(1)) } : {}),
|
|
273
380
|
},
|
|
274
381
|
{ additionalProperties: false },
|
|
275
382
|
);
|
|
@@ -280,11 +387,12 @@ const SCHEMAS: Readonly<Record<FleetContractVersion, ReturnType<typeof frontmatt
|
|
|
280
387
|
2: frontmatterSchema(2),
|
|
281
388
|
3: frontmatterSchema(3),
|
|
282
389
|
4: frontmatterSchema(4),
|
|
390
|
+
5: frontmatterSchema(5),
|
|
283
391
|
};
|
|
284
392
|
|
|
285
393
|
function contractVersion(frontmatter: Record<string, unknown>): FleetContractVersion | null {
|
|
286
394
|
const value = frontmatter.version;
|
|
287
|
-
return value === 1 || value === 2 || value === 3 || value === 4 ? value : null;
|
|
395
|
+
return value === 1 || value === 2 || value === 3 || value === 4 || value === 5 ? value : null;
|
|
288
396
|
}
|
|
289
397
|
|
|
290
398
|
function firstSchemaError(frontmatter: Record<string, unknown>, version: FleetContractVersion): string | null {
|
|
@@ -299,15 +407,38 @@ function fleetsDir(cwd: string): string {
|
|
|
299
407
|
}
|
|
300
408
|
|
|
301
409
|
type RawStep = {
|
|
302
|
-
kind?: "agent" | "code" | "loop";
|
|
410
|
+
kind?: "agent" | "code" | "loop" | "gate" | "plan";
|
|
303
411
|
id: string;
|
|
304
412
|
agent?: string;
|
|
305
413
|
command?: string;
|
|
306
414
|
commitFrom?: string[];
|
|
307
415
|
writes?: string[];
|
|
308
416
|
maxAttempts?: number;
|
|
309
|
-
check?: {
|
|
310
|
-
|
|
417
|
+
check?: {
|
|
418
|
+
kind: "code" | "agent" | "gate";
|
|
419
|
+
command?: string;
|
|
420
|
+
agent?: string;
|
|
421
|
+
gate?: string;
|
|
422
|
+
scope: FleetStepScope;
|
|
423
|
+
writes?: string[];
|
|
424
|
+
target?: string;
|
|
425
|
+
profile?: string;
|
|
426
|
+
};
|
|
427
|
+
repair?: {
|
|
428
|
+
kind?: "agent";
|
|
429
|
+
agent: string;
|
|
430
|
+
scope: FleetStepScope;
|
|
431
|
+
writes?: string[];
|
|
432
|
+
target?: string;
|
|
433
|
+
profile?: string;
|
|
434
|
+
};
|
|
435
|
+
target?: string;
|
|
436
|
+
profile?: string;
|
|
437
|
+
path?: string;
|
|
438
|
+
run?: string;
|
|
439
|
+
roster?: string[];
|
|
440
|
+
maxTasks?: number;
|
|
441
|
+
proposals?: boolean;
|
|
311
442
|
} & Pick<FleetContractAgentStep, "scope"> & { dependencies: string[] };
|
|
312
443
|
|
|
313
444
|
/** Normalized declaration, or nothing when this version declares no boundary. */
|
|
@@ -316,6 +447,36 @@ function normalizedWrites(writes: string[] | undefined): { writes?: ReadonlyArra
|
|
|
316
447
|
}
|
|
317
448
|
|
|
318
449
|
function normalizeStep(step: RawStep): FleetContractStep {
|
|
450
|
+
const route = (value: { target?: string; profile?: string }): { target?: string; profile?: string } => ({
|
|
451
|
+
...(value.target !== undefined ? { target: value.target } : {}),
|
|
452
|
+
...(value.profile !== undefined ? { profile: value.profile } : {}),
|
|
453
|
+
});
|
|
454
|
+
if (step.kind === "gate") {
|
|
455
|
+
return {
|
|
456
|
+
kind: "gate",
|
|
457
|
+
id: step.id,
|
|
458
|
+
agent: step.agent ?? "",
|
|
459
|
+
path: step.path ?? "",
|
|
460
|
+
run: step.run ?? "",
|
|
461
|
+
scope: "workspace",
|
|
462
|
+
dependencies: [...step.dependencies],
|
|
463
|
+
...route(step),
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
if (step.kind === "plan") {
|
|
467
|
+
return {
|
|
468
|
+
kind: "plan",
|
|
469
|
+
id: step.id,
|
|
470
|
+
agent: step.agent ?? "architect",
|
|
471
|
+
roster: [...(step.roster ?? [])],
|
|
472
|
+
maxTasks: step.maxTasks ?? 0,
|
|
473
|
+
proposals: step.proposals ?? false,
|
|
474
|
+
scope: step.scope,
|
|
475
|
+
dependencies: [...step.dependencies],
|
|
476
|
+
...normalizedWrites(step.writes),
|
|
477
|
+
...route(step),
|
|
478
|
+
};
|
|
479
|
+
}
|
|
319
480
|
if (step.kind === "loop") {
|
|
320
481
|
const check = step.check as NonNullable<RawStep["check"]>;
|
|
321
482
|
const repair = step.repair as NonNullable<RawStep["repair"]>;
|
|
@@ -327,8 +488,22 @@ function normalizeStep(step: RawStep): FleetContractStep {
|
|
|
327
488
|
check:
|
|
328
489
|
check.kind === "code"
|
|
329
490
|
? { kind: "code", command: check.command ?? "", scope: check.scope, ...normalizedWrites(check.writes) }
|
|
330
|
-
:
|
|
331
|
-
|
|
491
|
+
: check.kind === "gate"
|
|
492
|
+
? { kind: "gate", gate: check.gate ?? "" }
|
|
493
|
+
: {
|
|
494
|
+
kind: "agent",
|
|
495
|
+
agent: check.agent ?? "",
|
|
496
|
+
scope: check.scope,
|
|
497
|
+
...normalizedWrites(check.writes),
|
|
498
|
+
...route(check),
|
|
499
|
+
},
|
|
500
|
+
repair: {
|
|
501
|
+
kind: "agent",
|
|
502
|
+
agent: repair.agent,
|
|
503
|
+
scope: repair.scope,
|
|
504
|
+
...normalizedWrites(repair.writes),
|
|
505
|
+
...route(repair),
|
|
506
|
+
},
|
|
332
507
|
};
|
|
333
508
|
}
|
|
334
509
|
if (step.kind === "code") {
|
|
@@ -349,6 +524,7 @@ function normalizeStep(step: RawStep): FleetContractStep {
|
|
|
349
524
|
scope: step.scope,
|
|
350
525
|
dependencies: [...step.dependencies],
|
|
351
526
|
...normalizedWrites(step.writes),
|
|
527
|
+
...route(step),
|
|
352
528
|
};
|
|
353
529
|
}
|
|
354
530
|
|
|
@@ -406,6 +582,13 @@ export function validateFleetGraph(contract: Pick<FleetContract, "steps" | "path
|
|
|
406
582
|
}
|
|
407
583
|
}
|
|
408
584
|
for (const step of contract.steps) {
|
|
585
|
+
if (step.kind === "loop" && step.check.kind === "gate") {
|
|
586
|
+
const gateId = step.check.gate;
|
|
587
|
+
const gate = contract.steps.find((candidate) => candidate.id === gateId);
|
|
588
|
+
if (gate?.kind !== "gate") {
|
|
589
|
+
throw new Error(`fleet contract ${contract.path}: loop '${step.id}' names unknown gate '${gateId}'`);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
409
592
|
for (const dependency of step.dependencies) {
|
|
410
593
|
if (dependency === step.id) throw new Error(`fleet contract ${contract.path}: step '${step.id}' depends on itself`);
|
|
411
594
|
if (!declared.has(dependency)) {
|
|
@@ -484,10 +667,18 @@ export function fleetStepBoundaries(contract: Pick<FleetContract, "steps" | "ver
|
|
|
484
667
|
};
|
|
485
668
|
for (const step of contract.steps) {
|
|
486
669
|
if (step.kind === "loop") {
|
|
487
|
-
|
|
670
|
+
if (step.check.kind === "gate") {
|
|
671
|
+
const gateId = step.check.gate;
|
|
672
|
+
const gate = contract.steps.find((candidate) => candidate.id === gateId);
|
|
673
|
+
if (gate?.kind === "gate") add(`${step.id}.check`, "workspace", [gate.path]);
|
|
674
|
+
} else add(`${step.id}.check`, step.check.scope, step.check.writes);
|
|
488
675
|
add(`${step.id}.repair`, step.repair.scope, step.repair.writes);
|
|
489
676
|
continue;
|
|
490
677
|
}
|
|
678
|
+
if (step.kind === "gate") {
|
|
679
|
+
add(step.id, "workspace", [step.path]);
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
491
682
|
add(step.id, step.scope, step.writes);
|
|
492
683
|
}
|
|
493
684
|
return boundaries;
|
|
@@ -515,10 +706,14 @@ function validateWriteBoundaries(contract: Pick<FleetContract, "steps" | "versio
|
|
|
515
706
|
const declared: Array<{ id: string; scope: FleetStepScope; writes: ReadonlyArray<string> | undefined }> =
|
|
516
707
|
step.kind === "loop"
|
|
517
708
|
? [
|
|
518
|
-
|
|
709
|
+
...(step.check.kind === "gate"
|
|
710
|
+
? []
|
|
711
|
+
: [{ id: `${step.id}.check`, scope: step.check.scope, writes: step.check.writes }]),
|
|
519
712
|
{ id: `${step.id}.repair`, scope: step.repair.scope, writes: step.repair.writes },
|
|
520
713
|
]
|
|
521
|
-
:
|
|
714
|
+
: step.kind === "gate"
|
|
715
|
+
? []
|
|
716
|
+
: [{ id: step.id, scope: step.scope, writes: step.writes }];
|
|
522
717
|
for (const position of declared) {
|
|
523
718
|
if (position.scope === "readonly" && position.writes !== undefined) {
|
|
524
719
|
throw new Error(
|
|
@@ -559,11 +754,10 @@ export function parseFleetContract(raw: string, sourcePath: string): FleetContra
|
|
|
559
754
|
const { frontmatter, body } = parseFrontmatter(raw, sourcePath);
|
|
560
755
|
const version = contractVersion(frontmatter);
|
|
561
756
|
if (version === null) {
|
|
562
|
-
throw new Error(
|
|
563
|
-
`fleet contract ${sourcePath}: version must be 1 (agent steps), 2 (agent and code steps), 3 (adds bounded loops and commit steps), or 4 (adds enforced write boundaries)`,
|
|
564
|
-
);
|
|
757
|
+
throw new Error(`fleet contract ${sourcePath}: version must be 1, 2, 3, 4, or 5`);
|
|
565
758
|
}
|
|
566
759
|
if (version < FLEET_WRITE_BOUNDARY_VERSION) assertNoWritesBefore(frontmatter, sourcePath, version);
|
|
760
|
+
if (version < FLEET_DYNAMIC_STEP_VERSION) assertNoV5FieldsBefore(frontmatter, sourcePath, version);
|
|
567
761
|
const schemaError = firstSchemaError(frontmatter, version);
|
|
568
762
|
if (schemaError !== null) {
|
|
569
763
|
throw new Error(`fleet contract ${sourcePath}: ${schemaError}`);
|
|
@@ -576,6 +770,7 @@ export function parseFleetContract(raw: string, sourcePath: string): FleetContra
|
|
|
576
770
|
maxWorkers: number;
|
|
577
771
|
budgetUsd?: number;
|
|
578
772
|
onFailure: FleetOnFailure;
|
|
773
|
+
writers?: 1;
|
|
579
774
|
};
|
|
580
775
|
if (fm.budgetUsd !== undefined && !(fm.budgetUsd > 0)) {
|
|
581
776
|
throw new Error(`fleet contract ${sourcePath}: budgetUsd must be a positive number`);
|
|
@@ -592,14 +787,49 @@ export function parseFleetContract(raw: string, sourcePath: string): FleetContra
|
|
|
592
787
|
maxWorkers: fm.maxWorkers,
|
|
593
788
|
budgetUsd: fm.budgetUsd ?? null,
|
|
594
789
|
onFailure: fm.onFailure,
|
|
790
|
+
...(fm.writers === 1 ? { writers: 1 as const } : {}),
|
|
595
791
|
body: trimmedBody,
|
|
596
792
|
path: sourcePath,
|
|
597
793
|
};
|
|
598
794
|
validateFleetGraph(contract);
|
|
599
795
|
validateWriteBoundaries(contract);
|
|
796
|
+
validateV5Declarations(contract);
|
|
600
797
|
return contract;
|
|
601
798
|
}
|
|
602
799
|
|
|
800
|
+
function validateV5Declarations(contract: FleetContract): void {
|
|
801
|
+
if (contract.version < FLEET_DYNAMIC_STEP_VERSION) return;
|
|
802
|
+
const route = (id: string, value: { target?: string; profile?: string }): void => {
|
|
803
|
+
if (value.target !== undefined && value.profile !== undefined) {
|
|
804
|
+
throw new Error(`fleet contract ${contract.path}: step '${id}' may declare target or profile, never both`);
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
for (const step of contract.steps) {
|
|
808
|
+
if (step.kind === "agent" || step.kind === "plan" || step.kind === "gate") route(step.id, step);
|
|
809
|
+
if (step.kind === "plan" && new Set(step.roster).size !== step.roster.length) {
|
|
810
|
+
throw new Error(`fleet contract ${contract.path}: plan step '${step.id}' roster contains duplicate agents`);
|
|
811
|
+
}
|
|
812
|
+
if (step.kind === "gate") {
|
|
813
|
+
let normalized: ReadonlyArray<string>;
|
|
814
|
+
try {
|
|
815
|
+
normalized = normalizeWriteBoundary([step.path]);
|
|
816
|
+
} catch (error) {
|
|
817
|
+
throw new Error(
|
|
818
|
+
`fleet contract ${contract.path}: gate '${step.id}' path is invalid: ${error instanceof Error ? error.message : String(error)}`,
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
if (normalized[0] !== step.path.replaceAll("\\", "/")) {
|
|
822
|
+
throw new Error(
|
|
823
|
+
`fleet contract ${contract.path}: gate '${step.id}' path must be normalized and repository-relative`,
|
|
824
|
+
);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
if (step.kind !== "loop") continue;
|
|
828
|
+
if (step.check.kind === "agent") route(`${step.id}.check`, step.check);
|
|
829
|
+
route(`${step.id}.repair`, step.repair);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
603
833
|
/**
|
|
604
834
|
* A `writes` key under an older version is refused by name rather than as an
|
|
605
835
|
* unknown property, because the two readings are far apart: the author wrote a
|
|
@@ -619,6 +849,34 @@ function assertNoWritesBefore(frontmatter: Record<string, unknown>, sourcePath:
|
|
|
619
849
|
}
|
|
620
850
|
}
|
|
621
851
|
|
|
852
|
+
function assertNoV5FieldsBefore(frontmatter: Record<string, unknown>, sourcePath: string, version: number): void {
|
|
853
|
+
const forbidden = ["target", "profile"] as const;
|
|
854
|
+
if ("writers" in frontmatter) {
|
|
855
|
+
throw new Error(
|
|
856
|
+
`fleet contract ${sourcePath}: 'writers' requires contract version ${FLEET_DYNAMIC_STEP_VERSION}; this contract declares version ${version}`,
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
for (const value of Array.isArray(frontmatter.steps) ? frontmatter.steps : []) {
|
|
860
|
+
if (typeof value !== "object" || value === null) continue;
|
|
861
|
+
const step = value as Record<string, unknown>;
|
|
862
|
+
if (step.kind === "plan" || step.kind === "gate") {
|
|
863
|
+
throw new Error(
|
|
864
|
+
`fleet contract ${sourcePath}: kind '${String(step.kind)}' requires contract version ${FLEET_DYNAMIC_STEP_VERSION}; this contract declares version ${version}`,
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
for (const candidate of [step, step.check, step.repair]) {
|
|
868
|
+
if (typeof candidate !== "object" || candidate === null) continue;
|
|
869
|
+
for (const field of forbidden) {
|
|
870
|
+
if (field in candidate) {
|
|
871
|
+
throw new Error(
|
|
872
|
+
`fleet contract ${sourcePath}: '${field}' requires contract version ${FLEET_DYNAMIC_STEP_VERSION}; this contract declares version ${version}`,
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
622
880
|
/** Every loop in the contract, in declaration order. */
|
|
623
881
|
export function fleetLoopSteps(contract: FleetContract): FleetContractLoopStep[] {
|
|
624
882
|
return contract.steps.filter((step): step is FleetContractLoopStep => step.kind === "loop");
|
|
@@ -634,6 +892,7 @@ export function fleetCodeSteps(contract: FleetContract): Array<{ id: string; com
|
|
|
634
892
|
const steps: Array<{ id: string; command: string }> = [];
|
|
635
893
|
for (const step of contract.steps) {
|
|
636
894
|
if (step.kind === "code") steps.push({ id: step.id, command: step.command });
|
|
895
|
+
else if (step.kind === "gate") steps.push({ id: step.id, command: step.run });
|
|
637
896
|
else if (step.kind === "loop" && step.check.kind === "code") {
|
|
638
897
|
steps.push({ id: fleetLoopCheckStepId(step.id, 1), command: step.check.command });
|
|
639
898
|
}
|
|
@@ -702,6 +961,8 @@ function builtinFleetsDir(): string {
|
|
|
702
961
|
function fleetContractPath(cwd: string, name: string): { path: string; source: FleetContractSource } | null {
|
|
703
962
|
const projectPath = join(fleetsDir(cwd), `${name}.md`);
|
|
704
963
|
if (existsSync(projectPath)) return { path: projectPath, source: "project" };
|
|
964
|
+
const userPath = join(clioConfigDir(), "fleets", `${name}.md`);
|
|
965
|
+
if (existsSync(userPath)) return { path: userPath, source: "user" };
|
|
705
966
|
const builtinPath = join(builtinFleetsDir(), `${name}.md`);
|
|
706
967
|
if (existsSync(builtinPath)) return { path: builtinPath, source: "builtin" };
|
|
707
968
|
return null;
|
|
@@ -745,6 +1006,7 @@ export function listFleetContracts(cwd: string): FleetContractListing[] {
|
|
|
745
1006
|
const listings = new Map<string, FleetContractListing>();
|
|
746
1007
|
const sources: ReadonlyArray<{ dir: string; source: FleetContractSource }> = [
|
|
747
1008
|
{ dir: builtinFleetsDir(), source: "builtin" },
|
|
1009
|
+
{ dir: join(clioConfigDir(), "fleets"), source: "user" },
|
|
748
1010
|
{ dir: fleetsDir(cwd), source: "project" },
|
|
749
1011
|
];
|
|
750
1012
|
for (const { dir, source } of sources) {
|
|
@@ -20,10 +20,12 @@ export type {
|
|
|
20
20
|
FleetContract,
|
|
21
21
|
FleetContractAgentStep,
|
|
22
22
|
FleetContractCodeStep,
|
|
23
|
+
FleetContractGateStep,
|
|
23
24
|
FleetContractListing,
|
|
24
25
|
FleetContractLoopCheck,
|
|
25
26
|
FleetContractLoopRepair,
|
|
26
27
|
FleetContractLoopStep,
|
|
28
|
+
FleetContractPlanStep,
|
|
27
29
|
FleetContractSource,
|
|
28
30
|
FleetContractStep,
|
|
29
31
|
FleetContractVersion,
|
|
@@ -34,6 +36,7 @@ export type {
|
|
|
34
36
|
export {
|
|
35
37
|
FLEET_COMMANDS_REMEDY,
|
|
36
38
|
FLEET_COMMANDS_REPO_PATH,
|
|
39
|
+
FLEET_DYNAMIC_STEP_VERSION,
|
|
37
40
|
FLEET_LOOP_MAX_ATTEMPTS,
|
|
38
41
|
FLEET_WRITE_BOUNDARY_VERSION,
|
|
39
42
|
FleetCommandRegistryMissingError,
|
|
@@ -63,15 +66,26 @@ export { parseAgentBudget } from "./recipe.js";
|
|
|
63
66
|
export { parseAgentRecipeSchema, recipeSchemaFieldNames } from "./recipe-schema.js";
|
|
64
67
|
export type { AgentRecipeDiagnostic } from "./registry.js";
|
|
65
68
|
export type {
|
|
69
|
+
CouncilReport,
|
|
70
|
+
CouncilReportMember,
|
|
71
|
+
DelegationPlanResult,
|
|
72
|
+
DelegationPlanResultTask,
|
|
73
|
+
OracleResult,
|
|
66
74
|
ResultAuthorship,
|
|
67
75
|
ResultContract,
|
|
68
76
|
ResultContractQuality,
|
|
69
77
|
ResultContractValidation,
|
|
70
78
|
ScoutResult,
|
|
79
|
+
VerifierCheck,
|
|
80
|
+
VerifierResult,
|
|
71
81
|
} from "./result-contract.js";
|
|
72
82
|
export {
|
|
83
|
+
parseCouncilReport,
|
|
84
|
+
parseDelegationPlanResult,
|
|
85
|
+
parseOracleResult,
|
|
73
86
|
parseResultContract,
|
|
74
87
|
parseScoutResult,
|
|
88
|
+
parseVerifierResult,
|
|
75
89
|
resultContractAuthorship,
|
|
76
90
|
resultContractDigest,
|
|
77
91
|
validateRecipeResult,
|
|
@@ -9,33 +9,33 @@ import type {
|
|
|
9
9
|
AgentProjectContextTier,
|
|
10
10
|
} from "./spec.js";
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
export interface
|
|
12
|
+
/** One bounded worker-loop phase policy. */
|
|
13
|
+
export interface AgentBudgetPhase {
|
|
14
14
|
/** Admitted tool-call boundary before the final-response phase. */
|
|
15
15
|
toolCalls: number;
|
|
16
16
|
/** Tail of the admitted boundary reserved for canonical `read` calls. */
|
|
17
17
|
readReserve: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Authored worker-loop phase policy carried by an agent recipe. */
|
|
21
|
+
export interface AgentBudget extends AgentBudgetPhase {
|
|
18
22
|
/** Whether reaching the boundary transitions to text-only synthesis. */
|
|
19
23
|
synthesis: boolean;
|
|
24
|
+
/** Optional upper bound for invocation-level requests. Absence pins the default exactly. */
|
|
25
|
+
maximum?: AgentBudgetPhase;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
const AGENT_BUDGET_KEYS = ["toolCalls", "readReserve", "synthesis"] as const;
|
|
28
|
+
const AGENT_BUDGET_KEYS = ["toolCalls", "readReserve", "synthesis", "maximum"] as const;
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
export function parseAgentBudget(value: unknown, sourcePath: string): AgentBudget | undefined {
|
|
26
|
-
if (value === undefined) return undefined;
|
|
27
|
-
const prefix = `agent budget: ${sourcePath}: budget`;
|
|
30
|
+
function parseAgentBudgetPhase(value: unknown, prefix: string, relationTarget: string): AgentBudgetPhase {
|
|
28
31
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
29
32
|
throw new Error(`${prefix} must be a non-null YAML object`);
|
|
30
33
|
}
|
|
31
|
-
|
|
32
34
|
const record = value as Record<string, unknown>;
|
|
33
35
|
for (const key of Object.keys(record)) {
|
|
34
|
-
if (
|
|
35
|
-
throw new Error(`${prefix}.${key} is unknown`);
|
|
36
|
-
}
|
|
36
|
+
if (key !== "toolCalls" && key !== "readReserve") throw new Error(`${prefix}.${key} is unknown`);
|
|
37
37
|
}
|
|
38
|
-
for (const key of
|
|
38
|
+
for (const key of ["toolCalls", "readReserve"] as const) {
|
|
39
39
|
if (!Object.hasOwn(record, key)) throw new Error(`${prefix}.${key} is required`);
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -50,12 +50,52 @@ export function parseAgentBudget(value: unknown, sourcePath: string): AgentBudge
|
|
|
50
50
|
throw new Error(`${prefix}.readReserve must be a finite safe integer`);
|
|
51
51
|
}
|
|
52
52
|
if (readReserve < 0) throw new Error(`${prefix}.readReserve must be greater than or equal to 0`);
|
|
53
|
-
if (readReserve >= toolCalls) throw new Error(`${prefix}.readReserve must be less than
|
|
53
|
+
if (readReserve >= toolCalls) throw new Error(`${prefix}.readReserve must be less than ${relationTarget}`);
|
|
54
|
+
|
|
55
|
+
return { toolCalls, readReserve };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Strict parser shared by the one recipe schema and direct contract fixtures. */
|
|
59
|
+
export function parseAgentBudget(value: unknown, sourcePath: string): AgentBudget | undefined {
|
|
60
|
+
if (value === undefined) return undefined;
|
|
61
|
+
const prefix = `agent budget: ${sourcePath}: budget`;
|
|
62
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
63
|
+
throw new Error(`${prefix} must be a non-null YAML object`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const record = value as Record<string, unknown>;
|
|
67
|
+
for (const key of Object.keys(record)) {
|
|
68
|
+
if (!(AGENT_BUDGET_KEYS as ReadonlyArray<string>).includes(key)) {
|
|
69
|
+
throw new Error(`${prefix}.${key} is unknown`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const key of ["toolCalls", "readReserve", "synthesis"] as const) {
|
|
73
|
+
if (!Object.hasOwn(record, key)) throw new Error(`${prefix}.${key} is required`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const phase = parseAgentBudgetPhase(
|
|
77
|
+
{ toolCalls: record.toolCalls, readReserve: record.readReserve },
|
|
78
|
+
prefix,
|
|
79
|
+
"budget.toolCalls",
|
|
80
|
+
);
|
|
54
81
|
|
|
55
82
|
const synthesis = record.synthesis;
|
|
56
83
|
if (typeof synthesis !== "boolean") throw new Error(`${prefix}.synthesis must be a boolean`);
|
|
57
84
|
|
|
58
|
-
|
|
85
|
+
const maximum =
|
|
86
|
+
record.maximum === undefined
|
|
87
|
+
? undefined
|
|
88
|
+
: parseAgentBudgetPhase(record.maximum, `${prefix}.maximum`, "budget.maximum.toolCalls");
|
|
89
|
+
if (maximum !== undefined) {
|
|
90
|
+
if (maximum.toolCalls < phase.toolCalls) {
|
|
91
|
+
throw new Error(`${prefix}.maximum.toolCalls must be greater than or equal to budget.toolCalls`);
|
|
92
|
+
}
|
|
93
|
+
if (maximum.readReserve < phase.readReserve) {
|
|
94
|
+
throw new Error(`${prefix}.maximum.readReserve must be greater than or equal to budget.readReserve`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { ...phase, synthesis, ...(maximum === undefined ? {} : { maximum }) };
|
|
59
99
|
}
|
|
60
100
|
|
|
61
101
|
export interface AgentToolAnyOfRequirement {
|