@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
|
@@ -10,10 +10,12 @@ import type { DispatchContract } from "../domains/dispatch/contract.js";
|
|
|
10
10
|
import type { ExtensionsContract } from "../domains/extensions/index.js";
|
|
11
11
|
import type { InteropContract } from "../domains/interop/index.js";
|
|
12
12
|
import type { TaskMemoryOperatorStatus } from "../domains/memory/index.js";
|
|
13
|
+
import { openDetachedBatchViews } from "../domains/middleware/index.js";
|
|
13
14
|
import type { ObservabilityContract } from "../domains/observability/index.js";
|
|
14
15
|
import type { ProvidersContract, ThinkingLevel } from "../domains/providers/index.js";
|
|
15
16
|
import type { ResourcesContract } from "../domains/resources/index.js";
|
|
16
17
|
import type { FleetNodeSnapshot } from "../domains/scheduling/cluster.js";
|
|
18
|
+
import type { SchedulingContract } from "../domains/scheduling/contract.js";
|
|
17
19
|
import type { DecisionLedgerEntry } from "../domains/session/entries.js";
|
|
18
20
|
import type { SessionContract, SessionEntry, TaskBoardSnapshot } from "../domains/session/index.js";
|
|
19
21
|
import type { ShareContract } from "../domains/share/index.js";
|
|
@@ -26,8 +28,10 @@ import { APPLICATION_DOUBLE_TAP_MS, type ApplicationController } from "./applica
|
|
|
26
28
|
import type { ChatLoop, ChatLoopEvent } from "./chat-loop.js";
|
|
27
29
|
import { emitCommandNotice } from "./command-fallbacks.js";
|
|
28
30
|
import { appendNotice } from "./command-output.js";
|
|
31
|
+
import { dispatchCouncilThroughRegistry } from "./council-dispatch.js";
|
|
29
32
|
import { createDispatchSteering } from "./dispatch-steering.js";
|
|
30
33
|
import { createEditorSubmitController } from "./editor-submit.js";
|
|
34
|
+
import { createInteractiveDesktopNotifications } from "./footer/notifications.js";
|
|
31
35
|
import { createInteractiveEventProjection } from "./interactive-event-projection.js";
|
|
32
36
|
import { createInteractiveInputRuntime } from "./interactive-input-runtime.js";
|
|
33
37
|
import { createInteractivePresentation } from "./interactive-presentation.js";
|
|
@@ -108,6 +112,8 @@ export interface InteractiveDeps {
|
|
|
108
112
|
providers: ProvidersContract;
|
|
109
113
|
dispatch: DispatchContract;
|
|
110
114
|
agents?: AgentsContract;
|
|
115
|
+
/** Session budget state `/fleet run` shows as the ceiling a plan is admitted under. */
|
|
116
|
+
scheduling?: SchedulingContract;
|
|
111
117
|
observability: ObservabilityContract;
|
|
112
118
|
chat: ChatLoop;
|
|
113
119
|
/** Fired once after the first real TUI render transaction issued all of its terminal writes. */
|
|
@@ -482,10 +488,16 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
482
488
|
* here for the same reason as the leader flag above.
|
|
483
489
|
*/
|
|
484
490
|
let shutdownArmed = false;
|
|
491
|
+
/**
|
|
492
|
+
* Assigned after the presentation because it renders into it. The composer
|
|
493
|
+
* rail reads it through the optional chain before then as "no prompt".
|
|
494
|
+
*/
|
|
495
|
+
let overlayLifecycle: OverlayLifecycleController;
|
|
485
496
|
const presentation = createInteractivePresentation({
|
|
486
497
|
bus: deps.bus,
|
|
487
498
|
getLeaderArmed: () => leaderArmed,
|
|
488
499
|
getShutdownArmed: () => shutdownArmed,
|
|
500
|
+
isAwaitingApproval: () => overlayLifecycle?.getState() === "permission-confirm",
|
|
489
501
|
resolveVisibleEventSequence: (event) => visibleEventIngress.get(event)?.traceSequence ?? null,
|
|
490
502
|
resolveStreamIngress: (event) => visibleEventIngress.get(event) ?? null,
|
|
491
503
|
commitFrame: (reason) => shell.commitCurrentFrame(reason === "teardown" ? 300 : 30_000),
|
|
@@ -535,6 +547,16 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
535
547
|
} = presentation;
|
|
536
548
|
refreshPresentationFooter = () => footer.refresh();
|
|
537
549
|
const agentProgress = createAgentProgress(terminal);
|
|
550
|
+
// Desktop notifications are a protocol write on the terminal owner, issued
|
|
551
|
+
// outside any render transaction, so the sequence carries frameId null and
|
|
552
|
+
// never lands inside a frame. A non-TTY process never emits one even when
|
|
553
|
+
// `CLIO_CODER_INTERACTIVE=1` forced the interactive surface on.
|
|
554
|
+
const desktopNotifications = createInteractiveDesktopNotifications({
|
|
555
|
+
write: (data) => terminal.write(data),
|
|
556
|
+
enabled: () => deps.getSettings?.().terminal.notify ?? false,
|
|
557
|
+
interactiveTty: () => process.stdout.isTTY === true,
|
|
558
|
+
getOpenBatches: () => openDetachedBatchViews(deps.dispatch),
|
|
559
|
+
});
|
|
538
560
|
const busNoticeSink = {
|
|
539
561
|
appendReplayBlock: (renderBlock: Parameters<typeof chatPanel.appendReplayBlock>[0]) =>
|
|
540
562
|
chatRenderer.mutate(() => chatPanel.appendReplayBlock(renderBlock), "bus-notice"),
|
|
@@ -564,6 +586,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
564
586
|
setLastTurnSummary: (summary) => presentation.setLastTurnSummary(summary),
|
|
565
587
|
startTerminalProgress: () => agentProgress.start(),
|
|
566
588
|
stopTerminalProgress: () => agentProgress.stop(),
|
|
589
|
+
onTurnEnded: () => desktopNotifications.turnEnded(),
|
|
567
590
|
refreshLiveWorkspaceGit,
|
|
568
591
|
refreshFooter: () => footer.refresh(),
|
|
569
592
|
requestRender: () => tui.requestRender(),
|
|
@@ -581,6 +604,10 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
581
604
|
// The overlay reads the report this process already produced at boot; it
|
|
582
605
|
// never probes on a keystroke.
|
|
583
606
|
const interop = deps.interop;
|
|
607
|
+
// `/council` reaches execution only through the tool registry, so the
|
|
608
|
+
// approval overlay this application already installs on it is the same one an
|
|
609
|
+
// operator-typed council parks.
|
|
610
|
+
const toolRegistry = deps.toolRegistry;
|
|
584
611
|
const interopSurface = interop ? interopOverlaySurface(interop, (level, text) => notify(level, text)) : null;
|
|
585
612
|
const slashRuntime = createInteractiveSlashRuntime({
|
|
586
613
|
io,
|
|
@@ -620,8 +647,12 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
620
647
|
readStructuredEntries,
|
|
621
648
|
expandSubmit: (text) => expandInteractiveSubmitAsync(text, deps.resources),
|
|
622
649
|
openAskUser: (questions, options) => openAskUserOverlayState(questions, options),
|
|
623
|
-
openSkillsHub: () => openSkillsHubState(),
|
|
650
|
+
openSkillsHub: (tab) => openSkillsHubState(tab),
|
|
624
651
|
openCost: () => openCostOverlayState(),
|
|
652
|
+
openSideQuestion: (question) => openSideQuestionOverlayState(question),
|
|
653
|
+
startHandoff: (goal) => startHandoffState(goal),
|
|
654
|
+
startFleetRun: (name, vars) => startFleetRunState(name, vars),
|
|
655
|
+
...(toolRegistry ? { runCouncilDispatch: (args) => dispatchCouncilThroughRegistry(toolRegistry, args) } : {}),
|
|
625
656
|
openContextView: () => openContextViewOverlayState(),
|
|
626
657
|
openTasks: () => openTasksOverlayState(),
|
|
627
658
|
openDecisions: () => openDecisionsOverlayState(),
|
|
@@ -668,7 +699,6 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
668
699
|
});
|
|
669
700
|
editor.onSubmit = editorSubmit.submitEditorText;
|
|
670
701
|
|
|
671
|
-
let overlayLifecycle: OverlayLifecycleController;
|
|
672
702
|
const interactiveTickers = createInteractiveTickers({
|
|
673
703
|
tui,
|
|
674
704
|
dispatchBoardStore,
|
|
@@ -700,6 +730,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
700
730
|
notify,
|
|
701
731
|
terminal,
|
|
702
732
|
dispatchBoard,
|
|
733
|
+
setFleetRunPhase: (runId, phase) => dispatchBoardStore.setFleetPhase(runId, phase),
|
|
703
734
|
chatPanel,
|
|
704
735
|
resetTranscript,
|
|
705
736
|
io,
|
|
@@ -709,11 +740,26 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
709
740
|
keybindings,
|
|
710
741
|
editor,
|
|
711
742
|
getSlashContext: () => slashRuntime.context,
|
|
743
|
+
// One terminal owner, so the external editor a handoff review opens gets
|
|
744
|
+
// the screen the same way the composer's own `$EDITOR` opener does.
|
|
745
|
+
suspendTerminal: (run) => {
|
|
746
|
+
try {
|
|
747
|
+
tui.stop();
|
|
748
|
+
return run();
|
|
749
|
+
} finally {
|
|
750
|
+
tui.start();
|
|
751
|
+
tui.requestRender(true);
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
onOperatorParked: () => desktopNotifications.approvalParked(),
|
|
712
755
|
});
|
|
713
756
|
const {
|
|
714
757
|
closeOverlay,
|
|
715
758
|
openAskUserOverlayState,
|
|
716
759
|
openCostOverlayState,
|
|
760
|
+
openSideQuestionOverlayState,
|
|
761
|
+
startHandoffState,
|
|
762
|
+
startFleetRunState,
|
|
717
763
|
openContextViewOverlayState,
|
|
718
764
|
openContextResetOverlayState,
|
|
719
765
|
openTasksOverlayState,
|
|
@@ -805,6 +851,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
805
851
|
renderContextIsland: interactiveTickers.renderContextIsland,
|
|
806
852
|
requestRender: () => tui.requestRender(),
|
|
807
853
|
notify,
|
|
854
|
+
onDispatchSettled: () => desktopNotifications.dispatchSettled(),
|
|
808
855
|
// The reducer mutates one state object per assignment, so the panel is
|
|
809
856
|
// handed that object rather than a copy: a streamed delta reaches the
|
|
810
857
|
// screen by invalidating a cached render, not by rebuilding the entry.
|
|
@@ -77,6 +77,11 @@ export interface InteractiveEventProjectionDeps {
|
|
|
77
77
|
setLastTurnSummary: (summary: TurnSummary) => void;
|
|
78
78
|
startTerminalProgress: () => void;
|
|
79
79
|
stopTerminalProgress: () => void;
|
|
80
|
+
/**
|
|
81
|
+
* One model turn reached its end. Wired to the desktop notification; absent
|
|
82
|
+
* on hosts that do not own a terminal to notify through.
|
|
83
|
+
*/
|
|
84
|
+
onTurnEnded?: () => void;
|
|
80
85
|
refreshLiveWorkspaceGit: (force: boolean) => void;
|
|
81
86
|
refreshFooter: () => void;
|
|
82
87
|
requestRender: () => void;
|
|
@@ -214,7 +219,10 @@ export function createInteractiveEventProjection(deps: InteractiveEventProjectio
|
|
|
214
219
|
deps.chat.onEvent((event) => {
|
|
215
220
|
const showProgress = deps.getSettings?.().terminal.showTerminalProgress ?? false;
|
|
216
221
|
if (event.type === "agent_start" && showProgress) deps.startTerminalProgress();
|
|
217
|
-
else if (event.type === "agent_end")
|
|
222
|
+
else if (event.type === "agent_end") {
|
|
223
|
+
deps.stopTerminalProgress();
|
|
224
|
+
deps.onTurnEnded?.();
|
|
225
|
+
}
|
|
218
226
|
}),
|
|
219
227
|
deps.bus.on(BusChannels.RunAborted, () => {
|
|
220
228
|
deps.stopTerminalProgress();
|
|
@@ -76,13 +76,14 @@ export interface InteractiveInputRuntimeDeps {
|
|
|
76
76
|
dispatchBoard: {
|
|
77
77
|
selectPrevious(): void;
|
|
78
78
|
selectNext(): void;
|
|
79
|
+
toggleDetail(): void;
|
|
79
80
|
};
|
|
80
81
|
steerSelectedDispatch: () => void;
|
|
81
82
|
cancelSelectedDispatch: () => void;
|
|
82
83
|
cancelActiveEditorBash: () => boolean;
|
|
83
84
|
isStreaming: () => boolean;
|
|
84
85
|
cancelActiveRun: () => void;
|
|
85
|
-
editor: { getText(): string; setText(text: string): void };
|
|
86
|
+
editor: { getText(): string; setText(text: string): void; handleInput?(data: string): void };
|
|
86
87
|
editorSubmit: {
|
|
87
88
|
openExternalEditorForInput(): void;
|
|
88
89
|
queueFollowUpFromEditor(): void;
|
|
@@ -211,6 +212,11 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
211
212
|
cancelPermission: () => deps.overlay.closeOverlay(),
|
|
212
213
|
confirmPermission: () => deps.overlay.confirmPermission(),
|
|
213
214
|
stopTurnFromPermission: () => deps.overlay.stopTurnFromPermission(),
|
|
215
|
+
composerHasDraft: () => deps.editor.getText().length > 0,
|
|
216
|
+
editDraft: (data) => {
|
|
217
|
+
deps.editor.handleInput?.(data);
|
|
218
|
+
deps.requestRender();
|
|
219
|
+
},
|
|
214
220
|
closeOverlay: () => deps.overlay.closeOverlay(),
|
|
215
221
|
selectPreviousDispatch: () => {
|
|
216
222
|
deps.dispatchBoard.selectPrevious();
|
|
@@ -220,6 +226,10 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
220
226
|
deps.dispatchBoard.selectNext();
|
|
221
227
|
deps.requestRender();
|
|
222
228
|
},
|
|
229
|
+
toggleSelectedDispatchDetail: () => {
|
|
230
|
+
deps.dispatchBoard.toggleDetail();
|
|
231
|
+
deps.requestRender();
|
|
232
|
+
},
|
|
223
233
|
steerSelectedDispatch: deps.steerSelectedDispatch,
|
|
224
234
|
cancelSelectedDispatch: deps.cancelSelectedDispatch,
|
|
225
235
|
cancelAskUser: () => deps.overlay.cancelAskUser(),
|
|
@@ -39,6 +39,7 @@ import type { SmoothStreamingMode } from "./stream-pacer.js";
|
|
|
39
39
|
import { processAutoPacingAllowed, resolveSmoothStreamingMode } from "./stream-pacing-policy.js";
|
|
40
40
|
import { formatTargetLabel } from "./theme/index.js";
|
|
41
41
|
import { createWelcomeDashboard, type WelcomeDashboardComponent } from "./welcome-dashboard.js";
|
|
42
|
+
import { readWorkerReceiptFacts } from "./worker-receipts.js";
|
|
42
43
|
import type { WorkspaceFacts } from "./workspace-facts.js";
|
|
43
44
|
|
|
44
45
|
export interface PresentationTickerHandle {
|
|
@@ -96,6 +97,8 @@ export interface InteractivePresentationDeps {
|
|
|
96
97
|
getLeaderArmed?: () => boolean;
|
|
97
98
|
/** Whether a Ctrl+C armed the double tap and its window is still open. */
|
|
98
99
|
getShutdownArmed?: () => boolean;
|
|
100
|
+
/** Whether a permission prompt owns the keyboard, for the composer's CONFIRM rail. */
|
|
101
|
+
isAwaitingApproval?: () => boolean;
|
|
99
102
|
getCwd?: () => string;
|
|
100
103
|
resolveVisibleEventSequence?: (event: ChatLoopEvent) => number | null;
|
|
101
104
|
resolveStreamIngress?: (
|
|
@@ -242,7 +245,13 @@ export function createInteractivePresentation(deps: InteractivePresentationDeps)
|
|
|
242
245
|
bus: deps.bus,
|
|
243
246
|
...(deps.getSettings ? { getSettings: deps.getSettings } : {}),
|
|
244
247
|
});
|
|
245
|
-
|
|
248
|
+
// The board settles a finished run on the same sealed receipt the transcript
|
|
249
|
+
// block reads, so the two surfaces agree on a worker's terminal answer.
|
|
250
|
+
const dispatchBoardStore = factories.createDispatchBoardStore(
|
|
251
|
+
deps.bus,
|
|
252
|
+
() => deps.dispatch.snapshot(),
|
|
253
|
+
(runId) => readWorkerReceiptFacts(runId),
|
|
254
|
+
);
|
|
246
255
|
const contextActivityStore = factories.createContextActivityStore(deps.bus);
|
|
247
256
|
|
|
248
257
|
const footerToolCounts = new Map<string, number>();
|
|
@@ -408,6 +417,7 @@ export function createInteractivePresentation(deps: InteractivePresentationDeps)
|
|
|
408
417
|
);
|
|
409
418
|
},
|
|
410
419
|
isStreaming: () => deps.chat.isStreaming(),
|
|
420
|
+
...(deps.isAwaitingApproval ? { isAwaitingApproval: deps.isAwaitingApproval } : {}),
|
|
411
421
|
willEnterSteer: (text) => willEnterSteerActiveWork(deps, text),
|
|
412
422
|
getSubmitKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.submit")[0], "Enter"),
|
|
413
423
|
getNewlineKeyLabel: () => formatKeyLabel(keybindings.getKeys("tui.input.newLine")[0], "Shift+Enter"),
|
|
@@ -16,9 +16,12 @@ import {
|
|
|
16
16
|
type ThinkingLevel,
|
|
17
17
|
thinkingLevelChoiceLabel,
|
|
18
18
|
} from "../domains/providers/index.js";
|
|
19
|
-
import type { ResourcesContract } from "../domains/resources/index.js";
|
|
19
|
+
import type { LibraryEntryKind, ResourcesContract } from "../domains/resources/index.js";
|
|
20
20
|
import { installSkill } from "../domains/resources/skills/marketplace.js";
|
|
21
|
+
import { foldDecisionBoard } from "../domains/session/decision-board.js";
|
|
21
22
|
import type { SessionContract, SessionEntry } from "../domains/session/index.js";
|
|
23
|
+
import { foldTaskBoard } from "../domains/session/task-board.js";
|
|
24
|
+
import { filterEntriesToActivePath } from "../domains/session/tree/active-path.js";
|
|
22
25
|
import type { ShareContract } from "../domains/share/index.js";
|
|
23
26
|
import type { UserTasksStore } from "../domains/user-tasks/store.js";
|
|
24
27
|
import { stripTerminalSequences } from "../engine/tui.js";
|
|
@@ -32,9 +35,11 @@ import { appendNotice, appendOperatorCommand } from "./command-output.js";
|
|
|
32
35
|
import { runOperatorRecall } from "./context-recall-command.js";
|
|
33
36
|
import { renderSessionHtml } from "./export-html/index.js";
|
|
34
37
|
import { dateLocal } from "./format-time.js";
|
|
38
|
+
import type { OracleDigestSources } from "./oracle.js";
|
|
35
39
|
import type { SettingsCenterRowId, SettingsSectionId } from "./overlays/settings.js";
|
|
36
40
|
import {
|
|
37
41
|
type ContextClearCommandOptions,
|
|
42
|
+
type CouncilDispatchOutcome,
|
|
38
43
|
dispatchSlashCommand,
|
|
39
44
|
type InitCommandOptions,
|
|
40
45
|
parseSlashCommand,
|
|
@@ -108,8 +113,21 @@ export interface InteractiveSlashRuntimeDeps {
|
|
|
108
113
|
session?: Pick<SessionContract, "tree" | "current" | "appendEntry">;
|
|
109
114
|
expandSubmit: (text: string) => Promise<InteractiveSlashSubmitExpansion>;
|
|
110
115
|
openAskUser: AskUserHandler;
|
|
111
|
-
openSkillsHub: () => void;
|
|
116
|
+
openSkillsHub: (tab?: LibraryEntryKind) => void;
|
|
112
117
|
openCost: () => void;
|
|
118
|
+
/** Run one `/btw` side question in its own overlay. */
|
|
119
|
+
openSideQuestion: (question: string) => void;
|
|
120
|
+
/** Run one `/handoff <goal>`: extract, review, and seed a successor session. */
|
|
121
|
+
startHandoff: (goal: string) => void;
|
|
122
|
+
/** Run one `/fleet run <name>`: approval preview first, dispatch only on accept. */
|
|
123
|
+
startFleetRun?: (name: string, vars: Readonly<Record<string, string>>) => void;
|
|
124
|
+
/**
|
|
125
|
+
* Run one `/council <task>`: the prepared dispatch-tool arguments go through
|
|
126
|
+
* the ordinary tool-admission path, so supervised autonomy parks the call and
|
|
127
|
+
* the approval overlay opens before any member runs. Absent on a host with no
|
|
128
|
+
* tool registry, in which case `/council` says so.
|
|
129
|
+
*/
|
|
130
|
+
runCouncilDispatch?: (args: Readonly<Record<string, unknown>>) => Promise<CouncilDispatchOutcome>;
|
|
113
131
|
openContextView: () => void;
|
|
114
132
|
openTasks: () => void;
|
|
115
133
|
openDecisions: () => void;
|
|
@@ -186,6 +204,29 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
186
204
|
const resources = deps.resources;
|
|
187
205
|
const userTasks = deps.userTasks;
|
|
188
206
|
|
|
207
|
+
/**
|
|
208
|
+
* The record `/oracle` briefs its advisor on. Entries are filtered to the
|
|
209
|
+
* active branch first, the same way the task board, compaction, and the
|
|
210
|
+
* finish contract read them (issue #94): after a `/tree` switch the raw file
|
|
211
|
+
* still holds the abandoned turns, and an unscoped fold would brief the
|
|
212
|
+
* advisor on decisions the operator walked away from.
|
|
213
|
+
*/
|
|
214
|
+
const oracleBriefingSources = (): Omit<OracleDigestSources, "question"> => {
|
|
215
|
+
const sessionId = deps.chat.getSessionId();
|
|
216
|
+
if (sessionId === null) return { decisions: [], tasks: [], compactionSummary: null };
|
|
217
|
+
const leafTurnId = deps.session?.tree(sessionId).leafId ?? undefined;
|
|
218
|
+
const entries = filterEntriesToActivePath(deps.readStructuredEntries(sessionId), leafTurnId);
|
|
219
|
+
let compactionSummary: string | null = null;
|
|
220
|
+
for (const entry of entries) {
|
|
221
|
+
if (entry.kind === "compactionSummary") compactionSummary = entry.summary;
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
decisions: foldDecisionBoard(entries),
|
|
225
|
+
tasks: foldTaskBoard(entries)?.tasks ?? [],
|
|
226
|
+
compactionSummary,
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
|
|
189
230
|
const appendCommandNotice: SlashCommandContext["notice"] = (level, text) => {
|
|
190
231
|
appendNotice(level, text, {
|
|
191
232
|
appendReplayBlock: (renderBlock) => deps.chatPanel.appendReplayBlock(renderBlock),
|
|
@@ -342,6 +383,15 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
342
383
|
: deps.share.importArchive(resolve(archivePath), importOptions);
|
|
343
384
|
},
|
|
344
385
|
openCost: deps.openCost,
|
|
386
|
+
openSideQuestion: deps.openSideQuestion,
|
|
387
|
+
// `/oracle` is refused, never queued, while a turn streams: the digest it
|
|
388
|
+
// packs describes the record as it stands.
|
|
389
|
+
isTurnInFlight: () => deps.chat.isStreaming(),
|
|
390
|
+
oracleBriefing: oracleBriefingSources,
|
|
391
|
+
startHandoff: deps.startHandoff,
|
|
392
|
+
...(deps.startFleetRun ? { startFleetRun: deps.startFleetRun } : {}),
|
|
393
|
+
...(deps.getSettings ? { getWorkerRosters: () => deps.getSettings?.().workers.rosters ?? {} } : {}),
|
|
394
|
+
...(deps.runCouncilDispatch ? { runCouncilDispatch: deps.runCouncilDispatch } : {}),
|
|
345
395
|
openContextView: deps.openContextView,
|
|
346
396
|
openTasks: deps.openTasks,
|
|
347
397
|
openDecisions: deps.openDecisions,
|
|
@@ -37,6 +37,12 @@ export interface InteractiveSubscriptionsDeps {
|
|
|
37
37
|
recordWorkerRun?: (fields: WorkerRunEntryFields) => void;
|
|
38
38
|
/** Sealed-receipt reader, injected by tests. Defaults to `<state>/receipts/<runId>.json`. */
|
|
39
39
|
readWorkerReceipt?: WorkerReceiptReader;
|
|
40
|
+
/**
|
|
41
|
+
* A dispatch run reached a terminal state. The desktop notification uses it
|
|
42
|
+
* to look for a detached batch that settled with this run; nothing else
|
|
43
|
+
* derives state from it.
|
|
44
|
+
*/
|
|
45
|
+
onDispatchSettled?: () => void;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
export interface InteractiveSubscriptions {
|
|
@@ -89,8 +95,14 @@ export function createInteractiveSubscriptions(deps: InteractiveSubscriptionsDep
|
|
|
89
95
|
}),
|
|
90
96
|
),
|
|
91
97
|
deps.bus.on(BusChannels.RunAborted, folded(workers.aborted)),
|
|
92
|
-
deps.bus.on(BusChannels.DispatchCompleted,
|
|
93
|
-
|
|
98
|
+
deps.bus.on(BusChannels.DispatchCompleted, (payload) => {
|
|
99
|
+
folded(workers.completed)(payload);
|
|
100
|
+
deps.onDispatchSettled?.();
|
|
101
|
+
}),
|
|
102
|
+
deps.bus.on(BusChannels.DispatchFailed, (payload) => {
|
|
103
|
+
folded(workers.failed)(payload);
|
|
104
|
+
deps.onDispatchSettled?.();
|
|
105
|
+
}),
|
|
94
106
|
deps.bus.on(BusChannels.ContextActivity, () => {
|
|
95
107
|
deps.refreshFooter();
|
|
96
108
|
deps.renderContextIsland();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
describeTaskMemoryActivity,
|
|
3
|
+
type MemoryProposalResult,
|
|
3
4
|
type MemoryRecord,
|
|
4
5
|
type TaskMemoryActivityEvent,
|
|
5
6
|
type TaskMemoryEntry,
|
|
@@ -182,6 +183,7 @@ function memorySignature(status: TaskMemoryOperatorStatus, records: ReadonlyArra
|
|
|
182
183
|
|
|
183
184
|
interface OpenMemoryOverlayOptions {
|
|
184
185
|
onClose?: () => void;
|
|
186
|
+
onPromote?: (entry: TaskMemoryEntry, scope: "repo" | "global") => Promise<MemoryProposalResult>;
|
|
185
187
|
}
|
|
186
188
|
|
|
187
189
|
/** Master-detail memory view: status header, grouped list, scrollable detail pane. */
|
|
@@ -189,12 +191,18 @@ export class MemoryOverlayView implements Component {
|
|
|
189
191
|
private readonly list: ListOverlayView;
|
|
190
192
|
private signature: string | null = null;
|
|
191
193
|
private renderMemo: { width: number; status: string; listLines: string[]; lines: string[] } | null = null;
|
|
194
|
+
private pendingGlobalEntryId: string | null = null;
|
|
195
|
+
private promotionMessage: { token: "muted" | "warning" | "success" | "error"; text: string } | null = null;
|
|
196
|
+
private promotionInFlight = false;
|
|
192
197
|
|
|
193
198
|
constructor(
|
|
194
199
|
private readonly getStatus: () => TaskMemoryOperatorStatus,
|
|
195
200
|
private readonly getRecords: () => ReadonlyArray<MemoryRecord>,
|
|
196
201
|
onClose: () => void,
|
|
197
202
|
onChange: () => void,
|
|
203
|
+
private readonly promotion?: {
|
|
204
|
+
onPromote: (entry: TaskMemoryEntry, scope: "repo" | "global") => Promise<MemoryProposalResult>;
|
|
205
|
+
},
|
|
198
206
|
) {
|
|
199
207
|
this.list = new ListOverlayView(
|
|
200
208
|
{
|
|
@@ -203,6 +211,18 @@ export class MemoryOverlayView implements Component {
|
|
|
203
211
|
filterable: true,
|
|
204
212
|
layout: "split",
|
|
205
213
|
emptyMessage: EMPTY_MESSAGE,
|
|
214
|
+
...(promotion
|
|
215
|
+
? {
|
|
216
|
+
hints: [
|
|
217
|
+
{ key: "p", verb: "propose repo" },
|
|
218
|
+
{ key: "g", verb: "propose global" },
|
|
219
|
+
],
|
|
220
|
+
actions: {
|
|
221
|
+
p: (item: ListOverlayItem) => this.promote(item, "repo", onChange),
|
|
222
|
+
g: (item: ListOverlayItem) => this.promote(item, "global", onChange),
|
|
223
|
+
},
|
|
224
|
+
}
|
|
225
|
+
: {}),
|
|
206
226
|
onClose,
|
|
207
227
|
},
|
|
208
228
|
onChange,
|
|
@@ -217,11 +237,21 @@ export class MemoryOverlayView implements Component {
|
|
|
217
237
|
render(width: number): string[] {
|
|
218
238
|
const status = this.sync();
|
|
219
239
|
const statusLine = formatMemoryStatusLine(status, width);
|
|
240
|
+
const promotionLine =
|
|
241
|
+
this.promotionMessage === null
|
|
242
|
+
? null
|
|
243
|
+
: fitUnits(clioTheme(), "", [clioTheme().fg(this.promotionMessage.token, this.promotionMessage.text)], width);
|
|
244
|
+
const statusKey = promotionLine === null ? statusLine : `${statusLine}\n${promotionLine}`;
|
|
220
245
|
const listLines = this.list.render(width);
|
|
221
246
|
const memo = this.renderMemo;
|
|
222
|
-
if (memo && memo.width === width && memo.status ===
|
|
223
|
-
const lines = [
|
|
224
|
-
|
|
247
|
+
if (memo && memo.width === width && memo.status === statusKey && memo.listLines === listLines) return memo.lines;
|
|
248
|
+
const lines = [
|
|
249
|
+
statusLine,
|
|
250
|
+
...(promotionLine === null ? [] : [promotionLine]),
|
|
251
|
+
rule(clioTheme(), width),
|
|
252
|
+
...listLines,
|
|
253
|
+
];
|
|
254
|
+
this.renderMemo = { width, status: statusKey, listLines, lines };
|
|
225
255
|
return lines;
|
|
226
256
|
}
|
|
227
257
|
|
|
@@ -247,9 +277,63 @@ export class MemoryOverlayView implements Component {
|
|
|
247
277
|
}
|
|
248
278
|
return status;
|
|
249
279
|
}
|
|
280
|
+
|
|
281
|
+
private promote(item: ListOverlayItem, scope: "repo" | "global", onChange: () => void): void {
|
|
282
|
+
if (this.promotion === undefined || this.promotionInFlight) return;
|
|
283
|
+
const entry = this.selectedBankEntry(item);
|
|
284
|
+
if (entry === null) {
|
|
285
|
+
this.pendingGlobalEntryId = null;
|
|
286
|
+
this.promotionMessage = { token: "warning", text: "select a knowledge or procedural task-bank entry" };
|
|
287
|
+
this.invalidate();
|
|
288
|
+
onChange();
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (scope === "global" && this.pendingGlobalEntryId !== entry.id) {
|
|
292
|
+
this.pendingGlobalEntryId = entry.id;
|
|
293
|
+
this.promotionMessage = {
|
|
294
|
+
token: "warning",
|
|
295
|
+
text: `global scope broadens applicability for ${entry.id}; press g again to acknowledge`,
|
|
296
|
+
};
|
|
297
|
+
this.invalidate();
|
|
298
|
+
onChange();
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
this.pendingGlobalEntryId = null;
|
|
302
|
+
this.promotionInFlight = true;
|
|
303
|
+
this.promotionMessage = { token: "muted", text: `proposing ${entry.id} with ${scope} scope` };
|
|
304
|
+
this.invalidate();
|
|
305
|
+
onChange();
|
|
306
|
+
void this.promotion
|
|
307
|
+
.onPromote(entry, scope)
|
|
308
|
+
.then((result) => {
|
|
309
|
+
this.promotionMessage = {
|
|
310
|
+
token: "success",
|
|
311
|
+
text: `${result.created ? "proposed" : "found existing"} ${result.record.id}; review, then run clio-coder memory approve ${result.record.id}`,
|
|
312
|
+
};
|
|
313
|
+
})
|
|
314
|
+
.catch((error: unknown) => {
|
|
315
|
+
this.promotionMessage = {
|
|
316
|
+
token: "error",
|
|
317
|
+
text: `promotion failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
318
|
+
};
|
|
319
|
+
})
|
|
320
|
+
.finally(() => {
|
|
321
|
+
this.promotionInFlight = false;
|
|
322
|
+
this.invalidate();
|
|
323
|
+
onChange();
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private selectedBankEntry(item: ListOverlayItem): TaskMemoryEntry | null {
|
|
328
|
+
if (!item.id.startsWith("bank:")) return null;
|
|
329
|
+
const entryId = item.id.slice("bank:".length);
|
|
330
|
+
const entry = bankEntries(this.getStatus().bank).find((candidate) => candidate.id === entryId);
|
|
331
|
+
if (entry === undefined || entry.kind === "status") return null;
|
|
332
|
+
return entry;
|
|
333
|
+
}
|
|
250
334
|
}
|
|
251
335
|
|
|
252
|
-
/** Mount
|
|
336
|
+
/** Mount durable lessons and the live task bank with reviewed promotion actions. */
|
|
253
337
|
export function openMemoryOverlay(
|
|
254
338
|
tui: TUI,
|
|
255
339
|
getStatus: () => TaskMemoryOperatorStatus,
|
|
@@ -261,6 +345,7 @@ export function openMemoryOverlay(
|
|
|
261
345
|
getRecords,
|
|
262
346
|
() => options.onClose?.(),
|
|
263
347
|
() => tui.requestRender(),
|
|
348
|
+
options.onPromote ? { onPromote: options.onPromote } : undefined,
|
|
264
349
|
);
|
|
265
350
|
const handle = showClioOverlayFrame(tui, view, {
|
|
266
351
|
anchor: "center",
|