@iowarp/clio-coder 0.3.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/NOTICE +33 -0
- package/README.md +7 -2
- package/dist/{acp-7LOELQFP.js → acp-G5WJBNCT.js} +13 -12
- package/dist/{agents-FIBG2SHA.js → agents-FMV2Q5G4.js} +39 -36
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-OI4LIH2I.js → auth-3IDSJEIK.js} +16 -15
- package/dist/{builtins-AD25UL3C.js → builtins-XCZWXSC7.js} +3 -3
- package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
- package/dist/{chunk-56KB5IJP.js → chunk-2OQE55CK.js} +3 -3
- package/dist/{chunk-N3PBVRTZ.js → chunk-32KWKNSF.js} +9 -7
- package/dist/{chunk-VKBMFOYV.js → chunk-36EJLSQQ.js} +23 -27
- package/dist/{chunk-465CC7FK.js → chunk-3BT2XMV4.js} +16 -13
- package/dist/{chunk-NQ6UCCOD.js → chunk-3URVFKWK.js} +7 -7
- package/dist/{chunk-WIE7ZOSW.js → chunk-3XML7CDN.js} +2 -2
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
- package/dist/{chunk-HAY4ZE2P.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-JEQQR47K.js → chunk-6DB53AJS.js} +168 -9
- package/dist/{chunk-KV2AOLDF.js → chunk-76ONBSIA.js} +5 -25
- package/dist/{chunk-FALJGAWU.js → chunk-7MCTRUCE.js} +2 -2
- package/dist/{chunk-5T7RBWN2.js → chunk-AB44T6BB.js} +5 -5
- package/dist/chunk-B7OBL7PK.js +1405 -0
- package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
- package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
- package/dist/{chunk-O6I4CIEU.js → chunk-BKFJHQCA.js} +6 -6
- package/dist/chunk-BKFM6EJV.js +462 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-MV2VUEJC.js → chunk-BPKCPIL7.js} +2 -2
- package/dist/{chunk-TEO2TLVN.js → chunk-BUMFYQFY.js} +964 -1120
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/chunk-C2LTL2W6.js +2447 -0
- package/dist/{chunk-EBOC7MT3.js → chunk-CODPRO7Q.js} +8 -8
- package/dist/{chunk-HPCTNZM2.js → chunk-CTJ4RNAA.js} +4 -4
- package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
- package/dist/{chunk-MIX5N5AC.js → chunk-DQITNCXG.js} +394 -154
- package/dist/{chunk-S4COXYBG.js → chunk-DYJP44XW.js} +129 -106
- package/dist/{chunk-N5XKWMDW.js → chunk-F4CKPOEQ.js} +6 -6
- package/dist/{chunk-AMKHQW3C.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/{chunk-7C6RYZGQ.js → chunk-GKF55TAZ.js} +3 -3
- package/dist/{chunk-B5XRQOLB.js → chunk-GR5G2PVF.js} +9 -8
- package/dist/{chunk-XDOQXGFO.js → chunk-GXNLGKAB.js} +64 -8
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/{chunk-774ILSRL.js → chunk-HI63TFOG.js} +4 -3
- package/dist/{chunk-R7LNVMCS.js → chunk-HJJTYUHX.js} +64 -72
- package/dist/{chunk-RKRLDWD3.js → chunk-HLW2MRKE.js} +1 -1
- package/dist/{chunk-CA42X6KT.js → chunk-HWHKMHUA.js} +6 -6
- package/dist/chunk-HZHHCK24.js +1631 -0
- package/dist/{chunk-HJB5IUKP.js → chunk-I5VEOC6I.js} +12 -12
- package/dist/chunk-IBEBSCYA.js +564 -0
- package/dist/chunk-IQ7KR472.js +362 -0
- package/dist/{chunk-4H6ULJ3H.js → chunk-J4W7KFM7.js} +921 -990
- package/dist/{chunk-4LJX2PUC.js → chunk-JDG2WCRO.js} +5 -5
- package/dist/{chunk-NZU6YDNV.js → chunk-K5C3NCBD.js} +4 -4
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-NNNWO6F2.js → chunk-KFZI4NIL.js} +93 -3
- package/dist/chunk-KMVISBZR.js +132 -0
- package/dist/{chunk-BVDVID7E.js → chunk-LDQ2ZF2M.js} +2 -2
- package/dist/{chunk-OEDBCISO.js → chunk-LQ3DZAMX.js} +2 -2
- package/dist/{chunk-PZ4I4JE2.js → chunk-LY4S7GJC.js} +124 -116
- package/dist/{chunk-3DUR4WUA.js → chunk-MLKNTWH2.js} +19 -19
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-5DQRIYDZ.js → chunk-NHCZP4K7.js} +2 -2
- package/dist/chunk-NHLBIGRH.js +1506 -0
- package/dist/chunk-NQQH3YT7.js +302 -0
- package/dist/chunk-NYS75XW5.js +15 -0
- package/dist/{chunk-TD7UE2L5.js → chunk-O4XIVISU.js} +7 -7
- package/dist/{chunk-WXCJ7VME.js → chunk-O6TL7WWY.js} +6 -6
- package/dist/chunk-OQBA45DZ.js +97 -0
- package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
- package/dist/chunk-PMZCIOCJ.js +25 -0
- package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
- package/dist/{chunk-HKO36JWF.js → chunk-QBJA7R7N.js} +31 -3
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-5HFBWUMU.js → chunk-QLFS5GO2.js} +4 -4
- package/dist/{chunk-GAYUJ7LE.js → chunk-QLL7ILRG.js} +41 -32
- package/dist/{chunk-LXPJXFM5.js → chunk-QREDIESB.js} +7 -7
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/chunk-R346GLFC.js +31 -0
- package/dist/{chunk-VPTUJU4P.js → chunk-SJ5ZKQ4S.js} +2 -2
- package/dist/{chunk-QQ7EKM72.js → chunk-SP2RXXYO.js} +6 -54
- package/dist/chunk-SUCTJL45.js +45 -0
- package/dist/{chunk-5QKCQQ3E.js → chunk-SUW5DORT.js} +2 -2
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/{chunk-IHKBWSXF.js → chunk-TZ3SGWZZ.js} +2 -2
- package/dist/{chunk-ECUO3KDP.js → chunk-U77AMWDL.js} +47 -7
- package/dist/{chunk-3UUY7R3Z.js → chunk-ULC6OTWO.js} +7 -7
- package/dist/{chunk-AEYBF3TB.js → chunk-UM7N4G5A.js} +2 -2
- package/dist/{chunk-3V5AYSEQ.js → chunk-UXMFQ54G.js} +43 -36
- package/dist/{chunk-YW7UVM5V.js → chunk-V5DHCITQ.js} +34 -1
- package/dist/{chunk-47CMYGET.js → chunk-VAZSBTKF.js} +2 -2
- package/dist/{chunk-3MRC2YSQ.js → chunk-VEO4AP2K.js} +2 -2
- package/dist/{chunk-PNY46YEY.js → chunk-VFA6GDY5.js} +47 -3
- package/dist/chunk-VO67MWHC.js +75 -0
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-AD7Y7STJ.js → chunk-VYMXRQI6.js} +36 -22
- package/dist/{chunk-T3Z6VAAF.js → chunk-W5VSYASO.js} +19 -17
- package/dist/{chunk-5PVQ4SRS.js → chunk-WZR7K7ZX.js} +7 -123
- package/dist/{chunk-DG4M6ZUE.js → chunk-X3YGUTOB.js} +4 -4
- package/dist/chunk-X75E3D2N.js +686 -0
- package/dist/{chunk-P3JGPQFL.js → chunk-YDFRH54B.js} +4 -4
- package/dist/chunk-YJX4SHTD.js +40 -0
- package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
- package/dist/{chunk-YSEHGPCT.js → chunk-Z2RR6MAK.js} +3 -3
- package/dist/{chunk-HCBCAYZU.js → chunk-Z4TXYIEG.js} +5 -5
- package/dist/cli/index.js +47 -36
- package/dist/{clio-LT5V7SSZ.js → clio-2JXHBBY5.js} +7 -7
- package/dist/{code-nav-LMW275PA.js → code-nav-3YYRMYNF.js} +6 -6
- package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
- package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
- package/dist/{config-RXS5T3JT.js → config-QZPCMYSO.js} +58 -50
- package/dist/{configure-2WYWSCSD.js → configure-TEGEBYCA.js} +21 -19
- package/dist/{context-I3BTOTCS.js → context-AV7OEZ4D.js} +11 -11
- package/dist/{context-MVOORGMF.js → context-E6H5RNMC.js} +49 -41
- package/dist/{context-PALKKQYL.js → context-GSXUE4CT.js} +25 -23
- package/dist/{context-clear-N2WOYZ2K.js → context-clear-SHIBYK6T.js} +48 -40
- package/dist/{context-working-set-MIEVECVZ.js → context-working-set-5ZGKPGZQ.js} +11 -10
- package/dist/{dispatch-runner-VVA4SRRH.js → dispatch-runner-EFMJT4LD.js} +88 -60
- package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
- package/dist/doctor-QOA5FNY5.js +313 -0
- package/dist/{eval-IJ5VEZDJ.js → eval-TFBYQH4H.js} +66 -64
- package/dist/eval-inventory-SXH7PDKX.js +316 -0
- package/dist/{evidence-L5APPXNV.js → evidence-ERGESKGN.js} +198 -44
- package/dist/{evolve-RGNKFJ52.js → evolve-VDXTSYCJ.js} +46 -38
- package/dist/{extensions-7WYWUX5A.js → extensions-7BGBHN57.js} +6 -6
- package/dist/{fleet-6CNVBZZP.js → fleet-2RRVDF2V.js} +189 -101
- package/dist/{fleet-commands-L2SXSYEI.js → fleet-commands-VJ726XIA.js} +10 -10
- package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
- package/dist/{fleet-graph-2J3OOIPO.js → fleet-graph-JF5QOATM.js} +16 -15
- package/dist/fleet-inspect-VLY4S7QM.js +442 -0
- package/dist/{fleet-preflight-CZRJ4JP5.js → fleet-preflight-AIZUEJOY.js} +6 -5
- package/dist/{fleet-validate-C5RI6DP7.js → fleet-validate-AJRPDMDV.js} +20 -18
- package/dist/fleet-verify-JFEL2L3H.js +175 -0
- package/dist/fleet-view-ZCON35AG.js +102 -0
- package/dist/{init-VBN2ACVA.js → init-DN2WWLFE.js} +64 -56
- package/dist/install-XGLBQY5E.js +13 -0
- package/dist/interop-OZBKXAYL.js +114 -0
- package/dist/{library-JHGUMLY2.js → library-YWZG7IMW.js} +19 -18
- package/dist/{memory-K4OQIYWG.js → memory-I4C4HMLW.js} +48 -40
- package/dist/{models-2NCZUWDD.js → models-CEYXJBO6.js} +30 -28
- package/dist/{monitor-MMVTJABD.js → monitor-NZ6GCI3P.js} +53 -47
- package/dist/{orchestrator-ZKBPCHW6.js → orchestrator-GCGQ4N5I.js} +6311 -7145
- package/dist/panes-HMABYVO4.js +58 -0
- package/dist/panes-KY6W3V2E.js +103 -0
- package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
- package/dist/{reset-DD5JGOY3.js → reset-DQ6FGCSH.js} +13 -11
- package/dist/resources-BB3MVJMD.js +111 -0
- package/dist/{run-QEGNX7FL.js → run-H2GQDUER.js} +113 -82
- package/dist/{share-JKD3BQMW.js → share-GTJN6A5O.js} +18 -17
- package/dist/{skills-LMQIKDOZ.js → skills-L55TEW6R.js} +31 -24
- package/dist/{skills-eval-I7X2774U.js → skills-eval-XVXPH2JI.js} +61 -52
- package/dist/skills-inventory-S4MXPJFV.js +126 -0
- package/dist/slash-commands-ZSGASKJC.js +77 -0
- package/dist/{steer-CF5TDANS.js → steer-RZGSCY4R.js} +3 -3
- package/dist/{support-I7LOJLIF.js → support-PKEUNNQL.js} +4 -4
- package/dist/{targets-RUSR6B5Z.js → targets-NCPZ644J.js} +31 -29
- package/dist/{terminal-lease-QYVORFR4.js → terminal-lease-44SV3YCN.js} +4 -4
- package/dist/tools-DAF3DI3C.js +27 -0
- package/dist/{trace-ODOQIVIW.js → trace-FYVW2MQA.js} +149 -7
- package/dist/tui-primitives-2AKXQNZK.js +13 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
- package/dist/{upgrade-XANW3FXB.js → upgrade-3XPP6OQL.js} +26 -24
- package/dist/{usage-4H7ZRXQT.js → usage-3NLHGTU2.js} +57 -49
- package/dist/{verifiers-UZXNBZEB.js → verifiers-SSQONKRT.js} +171 -12
- package/dist/{verify-BVKWTNDL.js → verify-3U6J7FZI.js} +9 -9
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
- package/dist/{wiki-generate-MY7WV2QI.js → wiki-generate-CEHYGPGQ.js} +67 -59
- package/dist/with-panes-MKB46MPQ.js +782 -0
- package/dist/worker/entry.js +101 -66
- package/docs/README.md +3 -2
- package/docs/acp.md +24 -3
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +4 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +43 -5
- package/docs/commands-and-modes.md +31 -2
- package/docs/configuration-and-targets.md +40 -10
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +1 -0
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +2 -2
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +25 -1
- package/docs/fleet-dispatch.md +22 -1
- package/docs/installation-and-lifecycle.md +15 -2
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +10 -1
- package/docs/observability.md +3 -3
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +1 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +18 -8
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +4 -2
- package/src/cli/acp.ts +6 -2
- package/src/cli/argv.ts +25 -0
- package/src/cli/configure.ts +23 -21
- package/src/cli/doctor-panes.ts +124 -0
- package/src/cli/doctor-toolchain.ts +57 -0
- package/src/cli/doctor.ts +20 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +13 -0
- package/src/cli/evidence-detail.ts +88 -0
- package/src/cli/evidence-inventory.ts +183 -0
- package/src/cli/evidence.ts +30 -5
- package/src/cli/fleet-decisions.ts +69 -0
- package/src/cli/fleet-inspect.ts +334 -0
- package/src/cli/fleet-verify.ts +133 -0
- package/src/cli/fleet-view.ts +810 -0
- package/src/cli/fleet.ts +148 -37
- package/src/cli/index.ts +14 -2
- package/src/cli/interop-inspect.ts +128 -0
- package/src/cli/interop.ts +34 -0
- package/src/cli/panes.ts +35 -0
- package/src/cli/reset.ts +5 -2
- package/src/cli/run.ts +58 -0
- package/src/cli/skills-inventory.ts +185 -0
- package/src/cli/skills.ts +16 -13
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +23 -2
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/core/bus-events.ts +4 -0
- package/src/core/config.ts +49 -0
- package/src/core/defaults.ts +93 -7
- package/src/core/response-schema.ts +44 -4
- package/src/core/theme-token-hex.ts +43 -0
- package/src/core/tool-names.ts +2 -1
- package/src/core/xdg.ts +1 -1
- package/src/domains/agents/fleets/build-review.md +0 -3
- package/src/domains/agents/fleets/build-test.md +0 -3
- package/src/domains/agents/result-contract-filesystem.ts +32 -0
- package/src/domains/agents/result-contract.ts +164 -35
- package/src/domains/config/classify.ts +3 -0
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +22 -21
- package/src/domains/dispatch/capacity-lease.ts +21 -1
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/extension.ts +222 -50
- package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
- package/src/domains/dispatch/fleet-plan.ts +7 -2
- package/src/domains/dispatch/fleet-run.ts +64 -1
- package/src/domains/dispatch/gate-decisions.ts +11 -1
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/gate-topology.ts +289 -0
- package/src/domains/dispatch/index.ts +19 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/reservation-store.ts +24 -4
- package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
- package/src/domains/dispatch/run-event-journal.ts +598 -0
- package/src/domains/dispatch/state.ts +45 -1
- package/src/domains/dispatch/types.ts +13 -0
- package/src/domains/dispatch/validation.ts +33 -8
- package/src/domains/eval/compare/compare.ts +3 -16
- package/src/domains/eval/inventory.ts +113 -0
- package/src/domains/eval/schema/serving.ts +31 -0
- package/src/domains/evidence/store.ts +6 -0
- package/src/domains/memory/index.ts +0 -1
- package/src/domains/memory/task-memory-policy.ts +6 -10
- package/src/domains/memory/task-memory-telemetry.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +33 -21
- package/src/domains/mux/contract.ts +434 -0
- package/src/domains/mux/detect.ts +158 -0
- package/src/domains/mux/extension.ts +47 -0
- package/src/domains/mux/index.ts +96 -0
- package/src/domains/mux/manifest.ts +6 -0
- package/src/domains/mux/operations.ts +164 -0
- package/src/domains/mux/pane-registry.ts +90 -0
- package/src/domains/mux/protocol.ts +49 -0
- package/src/domains/mux/socket-client.ts +816 -0
- package/src/domains/mux/types.ts +222 -0
- package/src/domains/mux/viewer-command.ts +59 -0
- package/src/domains/mux/yazi/assets/init.lua +2 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
- package/src/domains/mux/yazi/assets/yazi.toml +17 -0
- package/src/domains/mux/yazi/event-stream.ts +180 -0
- package/src/domains/mux/yazi/profile.ts +299 -0
- package/src/domains/mux/yazi/session.ts +228 -0
- package/src/domains/mux/yazi/theme.ts +30 -0
- package/src/domains/observability/cost.ts +21 -0
- package/src/domains/observability/index.ts +2 -0
- package/src/domains/observability/trace-store.ts +42 -0
- package/src/domains/providers/endpoint-capacity.ts +154 -22
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +20 -3
- package/src/domains/providers/index.ts +22 -0
- package/src/domains/providers/model-runtime-capabilities.ts +32 -0
- package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
- package/src/domains/providers/support.ts +1 -0
- package/src/domains/providers/target-model-cache.ts +124 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/skills/loader.ts +33 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- package/src/domains/toolchain/archive.ts +175 -0
- package/src/domains/toolchain/contract.ts +28 -0
- package/src/domains/toolchain/extension.ts +47 -0
- package/src/domains/toolchain/index.ts +39 -0
- package/src/domains/toolchain/install.ts +327 -0
- package/src/domains/toolchain/manifest.ts +8 -0
- package/src/domains/toolchain/paths.ts +34 -0
- package/src/domains/toolchain/registry.ts +265 -0
- package/src/domains/toolchain/remove.ts +218 -0
- package/src/domains/toolchain/resolve.ts +182 -0
- package/src/domains/toolchain/types.ts +113 -0
- package/src/domains/toolchain/version.ts +88 -0
- package/src/engine/acp/server.ts +413 -70
- package/src/engine/acp/types.ts +19 -1
- package/src/engine/claude/sdk-module.ts +98 -0
- package/src/engine/claude/sdk-runtime.ts +19 -11
- package/src/engine/tui-primitives.ts +21 -0
- package/src/engine/tui.ts +1 -0
- package/src/engine/worker-runtime.ts +2 -13
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +103 -5
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- package/src/interactive/context-overlay.ts +1 -0
- package/src/interactive/cost-overlay.ts +2 -0
- package/src/interactive/council-grid.ts +1 -3
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +26 -16
- package/src/interactive/interactive-application.ts +153 -6
- package/src/interactive/interactive-input-runtime.ts +7 -0
- package/src/interactive/interactive-slash-runtime.ts +36 -6
- package/src/interactive/memory-overlay.ts +1 -0
- package/src/interactive/modal-marker.ts +170 -0
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +58 -2
- package/src/interactive/overlay-general-openers.ts +1 -0
- package/src/interactive/overlay-key-routing.ts +14 -3
- package/src/interactive/overlay-lifecycle.ts +19 -3
- package/src/interactive/overlay-model-selectors.ts +40 -3
- package/src/interactive/overlay-permission-lifecycle.ts +90 -22
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +1 -0
- package/src/interactive/overlays/ask-user.ts +136 -30
- package/src/interactive/overlays/auth-dialog.ts +1 -0
- package/src/interactive/overlays/context-reset.ts +1 -0
- package/src/interactive/overlays/cwd-fallback.ts +1 -0
- package/src/interactive/overlays/decisions.ts +11 -11
- package/src/interactive/overlays/extensions.ts +1 -0
- package/src/interactive/overlays/fleet-run-approval.ts +1 -0
- package/src/interactive/overlays/handoff-review.ts +1 -0
- package/src/interactive/overlays/help-reference.ts +2 -0
- package/src/interactive/overlays/interop.ts +1 -0
- package/src/interactive/overlays/library-install-confirm.ts +1 -0
- package/src/interactive/overlays/library-tabs.ts +28 -0
- package/src/interactive/overlays/list-overlay.ts +10 -1
- package/src/interactive/overlays/message-picker.ts +1 -0
- package/src/interactive/overlays/model-scope.ts +86 -0
- package/src/interactive/overlays/model-selector.ts +1 -0
- package/src/interactive/overlays/prompts.ts +1 -0
- package/src/interactive/overlays/session-selector.ts +1 -0
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +579 -44
- package/src/interactive/overlays/side-question.ts +1 -0
- package/src/interactive/overlays/skills-hub.ts +3 -11
- package/src/interactive/overlays/tree-selector.ts +1 -0
- package/src/interactive/pane-policy.ts +46 -0
- package/src/interactive/panes-runtime.ts +292 -0
- package/src/interactive/renderers/compaction-summary.ts +29 -0
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/slash-commands.ts +251 -15
- package/src/interactive/tasks-overlay.ts +1 -0
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +47 -2
- package/src/interactive/view/artifacts.ts +109 -1
- package/src/interactive/view/view-overlay.ts +1 -0
- package/src/interactive/watch-pane.ts +152 -0
- package/src/interactive/worker-progress.ts +7 -1
- package/src/interactive/worker-receipts.ts +19 -1
- package/src/interactive/worker-stream.ts +5 -0
- package/src/interactive/yazi-bridge.ts +444 -0
- package/src/tools/bootstrap.ts +26 -2
- package/src/tools/builtin-tool-catalog.ts +15 -0
- package/src/tools/compete-worktrees.ts +83 -2
- package/src/tools/core-bootstrap.ts +2 -1
- package/src/tools/dispatch-admission.ts +14 -3
- package/src/tools/dispatch-arguments.ts +20 -20
- package/src/tools/dispatch-run-events.ts +134 -19
- package/src/tools/dispatch-runner.ts +29 -7
- package/src/tools/dispatch-types.ts +15 -3
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/executables.ts +17 -14
- package/src/tools/observation.ts +54 -4
- package/src/tools/panes-surface.ts +38 -0
- package/src/tools/panes.ts +112 -0
- package/src/tools/policy.ts +10 -1
- package/src/tools/presentation.ts +1 -0
- package/dist/chunk-D73KXYPF.js +0 -37
- package/dist/chunk-MLOK6ZOS.js +0 -2888
- package/dist/chunk-YKOFT37S.js +0 -279
- package/dist/doctor-TWBWFK5V.js +0 -165
|
@@ -41,13 +41,8 @@ import { type CostProvenance, foregroundStreamUsage } from "../domains/providers
|
|
|
41
41
|
import { sanitizeCallTargetText } from "../domains/safety/call-target.js";
|
|
42
42
|
import { type Component, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "../engine/tui.js";
|
|
43
43
|
import { formatWorkerContextMeter } from "./context-meter.js";
|
|
44
|
-
import {
|
|
45
|
-
|
|
46
|
-
type CouncilGroupView,
|
|
47
|
-
type CouncilMemberView,
|
|
48
|
-
councilGroupBody,
|
|
49
|
-
councilIslandLines,
|
|
50
|
-
} from "./council-grid.js";
|
|
44
|
+
import { COUNCIL_SYNTHESIS_LABEL } from "./council.js";
|
|
45
|
+
import { type CouncilGroupView, type CouncilMemberView, councilGroupBody, councilIslandLines } from "./council-grid.js";
|
|
51
46
|
import { formatFooterTokens } from "./footer-panel.js";
|
|
52
47
|
import {
|
|
53
48
|
type ClioTheme,
|
|
@@ -631,9 +626,15 @@ export function renderDispatchCard(
|
|
|
631
626
|
row: DispatchBoardRow,
|
|
632
627
|
width: number,
|
|
633
628
|
evidence?: RunEvidencePresentation,
|
|
634
|
-
options: {
|
|
629
|
+
options: {
|
|
630
|
+
selected?: boolean;
|
|
631
|
+
expanded?: boolean;
|
|
632
|
+
endpointActive?: number;
|
|
633
|
+
endpointQueued?: number;
|
|
634
|
+
theme?: ClioTheme;
|
|
635
|
+
} = {},
|
|
635
636
|
): string[] {
|
|
636
|
-
const theme = clioTheme();
|
|
637
|
+
const theme = options.theme ?? clioTheme();
|
|
637
638
|
const contentWidth = Math.max(0, width - 4);
|
|
638
639
|
const agentLabel = agentDisplayLabel(row);
|
|
639
640
|
const elapsed = formatCompactMs(row.elapsedMs);
|
|
@@ -683,7 +684,12 @@ export function renderDispatchCard(
|
|
|
683
684
|
statusStr,
|
|
684
685
|
theme.fg("muted", `node ${row.node ?? "local"}`),
|
|
685
686
|
...(row.endpoint !== undefined
|
|
686
|
-
? [
|
|
687
|
+
? [
|
|
688
|
+
theme.fg(
|
|
689
|
+
"info",
|
|
690
|
+
`slots ${options.endpointActive ?? 0}/${row.endpoint.limit}${(options.endpointQueued ?? 0) > 0 ? ` +${options.endpointQueued} queued` : ""} ${row.endpoint.label}`,
|
|
691
|
+
),
|
|
692
|
+
]
|
|
687
693
|
: []),
|
|
688
694
|
...(row.gate !== undefined ? [theme.fg("info", `gate ${row.gate.role} c${row.gate.cycle}`)] : []),
|
|
689
695
|
...(row.rerouteCount !== undefined && row.rerouteCount > 0
|
|
@@ -1003,13 +1009,12 @@ export function formatDispatchBoardLines(
|
|
|
1003
1009
|
}
|
|
1004
1010
|
|
|
1005
1011
|
const endpointActive: Record<string, number> = { ...foregroundStreamUsage() };
|
|
1012
|
+
const endpointQueued: Record<string, number> = {};
|
|
1006
1013
|
for (const row of rows) {
|
|
1007
|
-
if (
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
) {
|
|
1014
|
+
if (row.endpoint === undefined) continue;
|
|
1015
|
+
if (row.status === "enqueued") endpointQueued[row.endpoint.key] = (endpointQueued[row.endpoint.key] ?? 0) + 1;
|
|
1016
|
+
else if (row.status === "running" || row.status === "stale" || row.status === "cancelling")
|
|
1011
1017
|
endpointActive[row.endpoint.key] = (endpointActive[row.endpoint.key] ?? 0) + 1;
|
|
1012
|
-
}
|
|
1013
1018
|
}
|
|
1014
1019
|
|
|
1015
1020
|
// A council is one question asked of several members, so its rows render as
|
|
@@ -1020,7 +1025,12 @@ export function formatDispatchBoardLines(
|
|
|
1020
1025
|
: renderDispatchCard(item.row, width, deriveRunEvidenceState(observability, item.row.runId), {
|
|
1021
1026
|
selected: item.row.runId === selectedRunId,
|
|
1022
1027
|
expanded: detailExpanded && item.row.runId === selectedRunId,
|
|
1023
|
-
...(item.row.endpoint !== undefined
|
|
1028
|
+
...(item.row.endpoint !== undefined
|
|
1029
|
+
? {
|
|
1030
|
+
endpointActive: endpointActive[item.row.endpoint.key] ?? 0,
|
|
1031
|
+
endpointQueued: endpointQueued[item.row.endpoint.key] ?? 0,
|
|
1032
|
+
}
|
|
1033
|
+
: {}),
|
|
1024
1034
|
}),
|
|
1025
1035
|
);
|
|
1026
1036
|
const body: string[] = [];
|
|
@@ -12,6 +12,8 @@ import type { ExtensionsContract } from "../domains/extensions/index.js";
|
|
|
12
12
|
import type { InteropContract } from "../domains/interop/index.js";
|
|
13
13
|
import type { TaskMemoryOperatorStatus } from "../domains/memory/index.js";
|
|
14
14
|
import { openDetachedBatchViews } from "../domains/middleware/index.js";
|
|
15
|
+
import type { MuxContract } from "../domains/mux/index.js";
|
|
16
|
+
import type { PanesOperations, PanesWatchController } from "../domains/mux/operations.js";
|
|
15
17
|
import type { ObservabilityContract } from "../domains/observability/index.js";
|
|
16
18
|
import type { ProvidersContract, ThinkingLevel } from "../domains/providers/index.js";
|
|
17
19
|
import type { ResourcesContract } from "../domains/resources/index.js";
|
|
@@ -40,8 +42,10 @@ import { createProcessInteractiveShell, getActiveRenderTrace } from "./interacti
|
|
|
40
42
|
import { createInteractiveSlashRuntime, resolveAvailableThinkingLevels } from "./interactive-slash-runtime.js";
|
|
41
43
|
import { createInteractiveSubscriptions } from "./interactive-subscriptions.js";
|
|
42
44
|
import { createInteractiveTickers } from "./interactive-tickers.js";
|
|
45
|
+
import type { createMuxBridge } from "./mux-bridge.js";
|
|
43
46
|
import { createOverlayLifecycle, type OverlayLifecycleController, type OverlayState } from "./overlay-lifecycle.js";
|
|
44
47
|
import { interopOverlaySurface } from "./overlays/interop.js";
|
|
48
|
+
import { paneWatchDecision } from "./pane-policy.js";
|
|
45
49
|
import { writeInputWedgeDump } from "./render-trace.js";
|
|
46
50
|
import { settleChatBeforeSessionSwitch } from "./session-switch-settlement.js";
|
|
47
51
|
import { createSessionTranscript } from "./session-transcript.js";
|
|
@@ -53,7 +57,9 @@ import type {
|
|
|
53
57
|
} from "./slash-commands.js";
|
|
54
58
|
import { processAutoPacingAllowed, resolveSmoothStreamingMode } from "./stream-pacing-policy.js";
|
|
55
59
|
import type { TerminalLease } from "./terminal-lease.js";
|
|
60
|
+
import type { createWatchPaneController } from "./watch-pane.js";
|
|
56
61
|
import { createWorkspaceFacts } from "./workspace-facts.js";
|
|
62
|
+
import type { createYaziBridge, YaziBridge } from "./yazi-bridge.js";
|
|
57
63
|
|
|
58
64
|
export {
|
|
59
65
|
IDLE_LEADER_STATE,
|
|
@@ -130,6 +136,36 @@ export interface InteractiveDeps {
|
|
|
130
136
|
extensions?: ExtensionsContract;
|
|
131
137
|
interop?: InteropContract;
|
|
132
138
|
share?: ShareContract;
|
|
139
|
+
/**
|
|
140
|
+
* Pane layer. A `none` contract still reaches the interactive surface so the
|
|
141
|
+
* files preset can use its terminal chooser; every mux operation remains
|
|
142
|
+
* best-effort and never reaches a dispatch or a turn.
|
|
143
|
+
*/
|
|
144
|
+
mux?: MuxContract;
|
|
145
|
+
/**
|
|
146
|
+
* Pane-layer operations behind `/panes` and the `panes` tool. Built by the
|
|
147
|
+
* composition root so the tool registry and this surface drive one instance.
|
|
148
|
+
*/
|
|
149
|
+
panes?: PanesOperations;
|
|
150
|
+
/**
|
|
151
|
+
* Factory seam for the dispatch-to-pane bridge, so a contract test can drive
|
|
152
|
+
* it without a TUI. Production leaves it unset and gets `createMuxBridge`.
|
|
153
|
+
*/
|
|
154
|
+
createMuxBridge?: typeof createMuxBridge;
|
|
155
|
+
/** Bind the file-pane return path after the composer and TUI exist. */
|
|
156
|
+
attachYaziBridge?: (bridge: YaziBridge) => () => void;
|
|
157
|
+
/**
|
|
158
|
+
* Watch-pane factory from the `--with-panes` composition root; absent on a
|
|
159
|
+
* plain boot. The controller it builds backs Enter in the workers view.
|
|
160
|
+
*/
|
|
161
|
+
createWatchPane?: typeof createWatchPaneController;
|
|
162
|
+
/** Bind the watch controller into the shared PanesOperations for `/panes show`. */
|
|
163
|
+
attachWatchPane?: (controller: PanesWatchController) => () => void;
|
|
164
|
+
/**
|
|
165
|
+
* File-pane factory. Supplied by the `--with-panes` composition root (or a
|
|
166
|
+
* contract test); absent on a plain boot, which therefore loads no yazi code.
|
|
167
|
+
*/
|
|
168
|
+
createYaziBridge?: typeof createYaziBridge;
|
|
133
169
|
/**
|
|
134
170
|
* Shared tool registry. When wired, the permission overlay opens automatically
|
|
135
171
|
* whenever a tool call is parked waiting for operator confirmation, and the
|
|
@@ -173,12 +209,19 @@ export interface InteractiveDeps {
|
|
|
173
209
|
registerAskUserHandler?: (handler: AskUserHandler) => () => void;
|
|
174
210
|
/** Live CLIO-CODER.md and memory state for the footer Context quadrant. */
|
|
175
211
|
getContextState?: (cwd?: string) => ContextState;
|
|
176
|
-
/**
|
|
177
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Persist a thinking level set by `/thinking <level>` or `/model <pattern>:<level>`.
|
|
214
|
+
* Scope "session" leaves settings.yaml alone; omitted means the historical
|
|
215
|
+
* write-through, which is what the Shift+Tab cycle and `/thinking` still want.
|
|
216
|
+
*/
|
|
217
|
+
onSetThinkingLevel?: (level: ThinkingLevel, scope?: "session" | "global") => void;
|
|
178
218
|
/** Persist the next thinking level when Shift+Tab is pressed. */
|
|
179
219
|
onCycleThinking?: () => void;
|
|
180
|
-
/**
|
|
181
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Apply the orchestrator target selected in /model at the scope the operator
|
|
222
|
+
* chose. "session" routes this session only and never touches settings.yaml.
|
|
223
|
+
*/
|
|
224
|
+
onSelectModel?: (ref: { target: string; model: string }, scope: "session" | "global") => void;
|
|
182
225
|
/** Write handler the /settings overlay uses to persist cycled values. */
|
|
183
226
|
writeSettings?: (next: ClioSettings) => void;
|
|
184
227
|
/**
|
|
@@ -567,6 +610,31 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
567
610
|
chatRenderer,
|
|
568
611
|
io,
|
|
569
612
|
} = presentation;
|
|
613
|
+
// The factory arrives only from an active `--with-panes` boot (or a test); a
|
|
614
|
+
// plain session has no deps.panes and no factory, and loads no yazi code.
|
|
615
|
+
const yaziBridge =
|
|
616
|
+
deps.panes && deps.createYaziBridge
|
|
617
|
+
? deps.createYaziBridge({
|
|
618
|
+
...(deps.mux ? { mux: deps.mux } : {}),
|
|
619
|
+
getDraft: () => editor.getText(),
|
|
620
|
+
setDraft: (text) => editor.setText(text),
|
|
621
|
+
requestRender: () => tui.requestRender(),
|
|
622
|
+
notice: (level, text) => notify(level, text, `yazi:${level}`),
|
|
623
|
+
getCwd: () => process.cwd(),
|
|
624
|
+
getSettings: () =>
|
|
625
|
+
deps.getSettings?.().panes.yazi ?? {
|
|
626
|
+
mode: "companion",
|
|
627
|
+
profile: "managed",
|
|
628
|
+
followCwd: true,
|
|
629
|
+
},
|
|
630
|
+
stopUi: () => tui.stop(),
|
|
631
|
+
startUi: () => {
|
|
632
|
+
tui.start();
|
|
633
|
+
tui.requestRender(true);
|
|
634
|
+
},
|
|
635
|
+
})
|
|
636
|
+
: null;
|
|
637
|
+
const detachYaziBridge = yaziBridge ? deps.attachYaziBridge?.(yaziBridge) : undefined;
|
|
570
638
|
refreshPresentationFooter = () => footer.refresh();
|
|
571
639
|
const agentProgress = createAgentProgress(terminal);
|
|
572
640
|
// Desktop notifications are a protocol write on the terminal owner, issued
|
|
@@ -681,7 +749,9 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
681
749
|
openMemory: () => openMemoryOverlayState(),
|
|
682
750
|
...(deps.seedTaskMemory ? { seedTaskMemory: deps.seedTaskMemory } : {}),
|
|
683
751
|
openView: (filter) => openViewOverlayState(filter),
|
|
752
|
+
...(deps.panes ? { panes: deps.panes } : {}),
|
|
684
753
|
openModel: () => openModelOverlayState(),
|
|
754
|
+
openModelScope: (ref) => openModelScopeState(ref),
|
|
685
755
|
openSettings: (section, rowId) => openSettingsOverlayState(section, rowId),
|
|
686
756
|
openResume: () => openResumeOverlayState(),
|
|
687
757
|
startNewSession: () => startNewSession(),
|
|
@@ -789,6 +859,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
789
859
|
openMemoryOverlayState,
|
|
790
860
|
openViewOverlayState,
|
|
791
861
|
openModelOverlayState,
|
|
862
|
+
openModelScopeState,
|
|
792
863
|
openSettingsOverlayState,
|
|
793
864
|
openResumeOverlayState,
|
|
794
865
|
openTreeOverlayState,
|
|
@@ -866,6 +937,64 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
866
937
|
};
|
|
867
938
|
notify(outcome.ok ? "success" : "info", outcome.message, "dispatch:background");
|
|
868
939
|
};
|
|
940
|
+
// Built only when a pane host answered detection, so a session with no
|
|
941
|
+
// panes subscribes to nothing and the bus handlers do not exist at all.
|
|
942
|
+
// The factories arrive from the `--with-panes` composition root (or a
|
|
943
|
+
// test); a plain session loads none of the bridge code.
|
|
944
|
+
const mux = deps.mux;
|
|
945
|
+
const muxBridge =
|
|
946
|
+
mux && mux.mode !== "none" && deps.createMuxBridge
|
|
947
|
+
? deps.createMuxBridge({
|
|
948
|
+
bus: deps.bus,
|
|
949
|
+
mux,
|
|
950
|
+
notificationsPolicy: () => deps.getSettings?.().panes.notifications ?? "failures",
|
|
951
|
+
log: (level, message) => {
|
|
952
|
+
if (level === "warning") notify("warning", message, "mux:bridge");
|
|
953
|
+
},
|
|
954
|
+
notice: (level, text) => appendNotice(level, text, busNoticeSink),
|
|
955
|
+
})
|
|
956
|
+
: null;
|
|
957
|
+
// The workers-view watch pane: opened on Enter over a live run, retargeted
|
|
958
|
+
// by arrow keys through its selection file. `/panes show` and the panes
|
|
959
|
+
// tool drive the same controller through the shared operations object.
|
|
960
|
+
const watchPane =
|
|
961
|
+
mux && mux.mode !== "none" && deps.createWatchPane
|
|
962
|
+
? deps.createWatchPane({ mux, getCwd: () => process.cwd() })
|
|
963
|
+
: null;
|
|
964
|
+
const detachWatchPane = watchPane ? deps.attachWatchPane?.(watchPane) : undefined;
|
|
965
|
+
const selectedWatchableRun = (): { runId: string; agentId: string } | null => {
|
|
966
|
+
if (!watchPane) return null;
|
|
967
|
+
const row = dispatchBoard.selectedRow();
|
|
968
|
+
if (!row) return null;
|
|
969
|
+
const decision = paneWatchDecision({ source: "workers-view", runStatus: row.status });
|
|
970
|
+
return decision.open ? { runId: row.runId, agentId: row.agentId } : null;
|
|
971
|
+
};
|
|
972
|
+
/**
|
|
973
|
+
* Enter in the workers view. True means the watch pane took the key; false
|
|
974
|
+
* (panes off, nothing watchable under the policy) falls back to the inline
|
|
975
|
+
* worker-progress detail, so a terminal run's Enter still expands its card.
|
|
976
|
+
*/
|
|
977
|
+
const watchSelectedDispatch = (): boolean => {
|
|
978
|
+
const selected = selectedWatchableRun();
|
|
979
|
+
if (!watchPane || !selected) return false;
|
|
980
|
+
void watchPane.watch(selected.runId).then((result) => {
|
|
981
|
+
if (result.status === "watching") {
|
|
982
|
+
if (result.opened) {
|
|
983
|
+
notify("success", `watching ${selected.agentId} (${selected.runId}) in a pane`, "panes:watch");
|
|
984
|
+
}
|
|
985
|
+
} else {
|
|
986
|
+
notify("warning", result.reason, "panes:watch");
|
|
987
|
+
}
|
|
988
|
+
tui.requestRender();
|
|
989
|
+
});
|
|
990
|
+
return true;
|
|
991
|
+
};
|
|
992
|
+
/** Arrow keys: the watch pane follows the cursor, but only once it exists. */
|
|
993
|
+
const followBoardSelection = (): void => {
|
|
994
|
+
if (!watchPane?.isOpen()) return;
|
|
995
|
+
const selected = selectedWatchableRun();
|
|
996
|
+
if (selected) watchPane.follow(selected.runId);
|
|
997
|
+
};
|
|
869
998
|
const interactiveSubscriptions = createInteractiveSubscriptions({
|
|
870
999
|
bus: deps.bus,
|
|
871
1000
|
refreshFooter: () => footer.refresh(),
|
|
@@ -916,7 +1045,18 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
916
1045
|
onShutdownArmedChange: (armed) => {
|
|
917
1046
|
shutdownArmed = armed;
|
|
918
1047
|
},
|
|
919
|
-
dispatchBoard
|
|
1048
|
+
dispatchBoard: {
|
|
1049
|
+
selectPrevious: () => {
|
|
1050
|
+
dispatchBoard.selectPrevious();
|
|
1051
|
+
followBoardSelection();
|
|
1052
|
+
},
|
|
1053
|
+
selectNext: () => {
|
|
1054
|
+
dispatchBoard.selectNext();
|
|
1055
|
+
followBoardSelection();
|
|
1056
|
+
},
|
|
1057
|
+
toggleDetail: () => dispatchBoard.toggleDetail(),
|
|
1058
|
+
},
|
|
1059
|
+
watchSelectedDispatch,
|
|
920
1060
|
steerSelectedDispatch,
|
|
921
1061
|
cancelSelectedDispatch,
|
|
922
1062
|
cancelActiveEditorBash: () => editorSubmit.cancelActiveEditorBash(),
|
|
@@ -955,7 +1095,14 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
955
1095
|
disposeOverlay: overlayLifecycle.dispose,
|
|
956
1096
|
stopAgentProgress: agentProgress.stop,
|
|
957
1097
|
disposeChat: () => deps.chat.dispose(),
|
|
958
|
-
disposeSubscriptions:
|
|
1098
|
+
disposeSubscriptions: () => {
|
|
1099
|
+
detachYaziBridge?.();
|
|
1100
|
+
yaziBridge?.dispose();
|
|
1101
|
+
detachWatchPane?.();
|
|
1102
|
+
watchPane?.dispose();
|
|
1103
|
+
muxBridge?.dispose();
|
|
1104
|
+
interactiveSubscriptions.dispose();
|
|
1105
|
+
},
|
|
959
1106
|
},
|
|
960
1107
|
beforeStopUi: (() => {
|
|
961
1108
|
let settlement: Promise<void> | null = null;
|
|
@@ -82,6 +82,8 @@ export interface InteractiveInputRuntimeDeps {
|
|
|
82
82
|
selectNext(): void;
|
|
83
83
|
toggleDetail(): void;
|
|
84
84
|
};
|
|
85
|
+
/** Enter in the workers view; false falls through to the detail toggle. */
|
|
86
|
+
watchSelectedDispatch: () => boolean;
|
|
85
87
|
steerSelectedDispatch: () => void;
|
|
86
88
|
cancelSelectedDispatch: () => void;
|
|
87
89
|
cancelActiveEditorBash: () => boolean;
|
|
@@ -238,6 +240,11 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
238
240
|
deps.dispatchBoard.toggleDetail();
|
|
239
241
|
deps.requestRender();
|
|
240
242
|
},
|
|
243
|
+
watchSelectedDispatch: () => {
|
|
244
|
+
const handled = deps.watchSelectedDispatch();
|
|
245
|
+
if (handled) deps.requestRender();
|
|
246
|
+
return handled;
|
|
247
|
+
},
|
|
241
248
|
steerSelectedDispatch: deps.steerSelectedDispatch,
|
|
242
249
|
cancelSelectedDispatch: deps.cancelSelectedDispatch,
|
|
243
250
|
cancelAskUser: () => deps.overlay.cancelAskUser(),
|
|
@@ -9,6 +9,7 @@ import type { AgentsContract } from "../domains/agents/contract.js";
|
|
|
9
9
|
import type { DispatchContract } from "../domains/dispatch/contract.js";
|
|
10
10
|
import { agentRoleFactsResolver } from "../domains/dispatch/execution-role.js";
|
|
11
11
|
import type { ExtensionsContract } from "../domains/extensions/index.js";
|
|
12
|
+
import type { PanesOperations } from "../domains/mux/operations.js";
|
|
12
13
|
import {
|
|
13
14
|
type ProvidersContract,
|
|
14
15
|
type ResolvedThinkingCapability,
|
|
@@ -36,6 +37,7 @@ import { runOperatorRecall } from "./context-recall-command.js";
|
|
|
36
37
|
import { renderSessionHtml } from "./export-html/index.js";
|
|
37
38
|
import { dateLocal } from "./format-time.js";
|
|
38
39
|
import type { OracleDigestSources } from "./oracle.js";
|
|
40
|
+
import type { PendingModelScope } from "./overlays/model-scope.js";
|
|
39
41
|
import type { SettingsCenterRowId, SettingsSectionId } from "./overlays/settings.js";
|
|
40
42
|
import {
|
|
41
43
|
type ContextClearCommandOptions,
|
|
@@ -48,7 +50,7 @@ import {
|
|
|
48
50
|
type SlashCommandDispatchResult,
|
|
49
51
|
type TaskMemorySeedCommandResult,
|
|
50
52
|
} from "./slash-commands.js";
|
|
51
|
-
import {
|
|
53
|
+
import { verifyReceiptFileReport } from "./view/artifacts.js";
|
|
52
54
|
import type { WorkerEntryState } from "./worker-stream.js";
|
|
53
55
|
|
|
54
56
|
const EXPORT_RENDER_WIDTH = 100;
|
|
@@ -89,8 +91,8 @@ export interface InteractiveSlashRuntimeDeps {
|
|
|
89
91
|
* making a value permanent stays the Settings overlay's explicit choice.
|
|
90
92
|
*/
|
|
91
93
|
commitSetting?: (id: string, next: ClioSettings, scope: "session" | "global") => void;
|
|
92
|
-
onSelectModel?: (ref: { target: string; model: string }) => void;
|
|
93
|
-
onSetThinkingLevel?: (level: ThinkingLevel) => void;
|
|
94
|
+
onSelectModel?: (ref: { target: string; model: string }, scope: "session" | "global") => void;
|
|
95
|
+
onSetThinkingLevel?: (level: ThinkingLevel, scope?: "session" | "global") => void;
|
|
94
96
|
onCompact?: (instructions: string | undefined) => Promise<void>;
|
|
95
97
|
onInit?: (options: InitCommandOptions, io?: RunIo) => Promise<void>;
|
|
96
98
|
onContextClear?: (options: ContextClearCommandOptions) => Promise<void>;
|
|
@@ -135,7 +137,14 @@ export interface InteractiveSlashRuntimeDeps {
|
|
|
135
137
|
openMemory: () => void;
|
|
136
138
|
seedTaskMemory?: () => TaskMemorySeedCommandResult;
|
|
137
139
|
openView: (filter?: string) => void;
|
|
140
|
+
/** Pane-layer operations behind `/panes`. Absent when the mux resolved to `none`. */
|
|
141
|
+
panes?: PanesOperations;
|
|
138
142
|
openModel: () => void;
|
|
143
|
+
/**
|
|
144
|
+
* Ask where a resolved `/model <pattern>` swap lands before anything applies.
|
|
145
|
+
* Absent on a host with no overlay layer, where the swap stays session-scoped.
|
|
146
|
+
*/
|
|
147
|
+
openModelScope?: (ref: PendingModelScope) => void;
|
|
139
148
|
openSettings: (section?: SettingsSectionId, rowId?: SettingsCenterRowId) => void;
|
|
140
149
|
openResume: () => void;
|
|
141
150
|
startNewSession: () => void;
|
|
@@ -200,6 +209,7 @@ export function resolveAvailableThinkingLevels(
|
|
|
200
209
|
export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps): InteractiveSlashRuntime {
|
|
201
210
|
let activeContextInit = false;
|
|
202
211
|
let latestAdmission: Promise<void> = Promise.resolve();
|
|
212
|
+
let latestLocalOperation: Promise<void> = Promise.resolve();
|
|
203
213
|
let activeAdmissionSignal: AbortSignal | undefined;
|
|
204
214
|
const cwd = (): string => deps.getCwd?.() ?? process.cwd();
|
|
205
215
|
const resources = deps.resources;
|
|
@@ -436,6 +446,7 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
436
446
|
return result;
|
|
437
447
|
},
|
|
438
448
|
openView: deps.openView,
|
|
449
|
+
...(deps.panes ? { panes: deps.panes } : {}),
|
|
439
450
|
setThinkingLevel: (level) => {
|
|
440
451
|
const settings = deps.getSettings?.();
|
|
441
452
|
if (!settings || !deps.onSetThinkingLevel) return { status: "unavailable" };
|
|
@@ -485,9 +496,20 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
485
496
|
openModel: deps.openModel,
|
|
486
497
|
providers: deps.providers,
|
|
487
498
|
applyModelRef: (ref) => {
|
|
488
|
-
|
|
489
|
-
|
|
499
|
+
// A mid-conversation swap used to rewrite the orchestrator role in
|
|
500
|
+
// settings.yaml with no prompt, so the next launch could come up on a
|
|
501
|
+
// dead endpoint (smoke pass 2, G3). The scope dialog owns the commit
|
|
502
|
+
// now, and it applies nothing until the operator answers.
|
|
503
|
+
if (deps.openModelScope) {
|
|
504
|
+
deps.openModelScope(ref);
|
|
505
|
+
return "pending";
|
|
506
|
+
}
|
|
507
|
+
// No overlay layer to ask with: session scope is the answer that cannot
|
|
508
|
+
// outlive the session that chose it.
|
|
509
|
+
deps.onSelectModel?.({ target: ref.target, model: ref.model }, "session");
|
|
510
|
+
if (ref.thinkingLevel) deps.onSetThinkingLevel?.(ref.thinkingLevel, "session");
|
|
490
511
|
deps.requestRender();
|
|
512
|
+
return "applied";
|
|
491
513
|
},
|
|
492
514
|
openSettings: deps.openSettings,
|
|
493
515
|
openResume: deps.openResume,
|
|
@@ -634,7 +656,7 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
634
656
|
})
|
|
635
657
|
.finally(deps.requestRender);
|
|
636
658
|
},
|
|
637
|
-
verifyReceipt: (runId) =>
|
|
659
|
+
verifyReceipt: (runId) => verifyReceiptFileReport(deps.stateDir, runId),
|
|
638
660
|
...(deps.listWorkerRuns ? { listWorkerRuns: deps.listWorkerRuns } : {}),
|
|
639
661
|
// The user-turn path, minus expansion. A worker's answer is literal text:
|
|
640
662
|
// running it through the prompt, skill, and @file expanders would let a
|
|
@@ -644,6 +666,9 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
644
666
|
latestAdmission = admitChat(text, activeAdmissionSignal);
|
|
645
667
|
void latestAdmission;
|
|
646
668
|
},
|
|
669
|
+
runLocalOperation: (operation) => {
|
|
670
|
+
latestLocalOperation = latestLocalOperation.catch(() => undefined).then(operation);
|
|
671
|
+
},
|
|
647
672
|
render: deps.requestRender,
|
|
648
673
|
};
|
|
649
674
|
|
|
@@ -653,8 +678,12 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
653
678
|
dispatchCommand: (text) => dispatchSlashCommand(parseSlashCommand(text), context),
|
|
654
679
|
admitCommand: async (text, signal) => {
|
|
655
680
|
signal?.throwIfAborted();
|
|
681
|
+
// Pane opens and focus changes mutate a remote registry. A following
|
|
682
|
+
// slash read must observe their settled state, just as the tool path does.
|
|
683
|
+
await latestLocalOperation;
|
|
656
684
|
const command = parseSlashCommand(text);
|
|
657
685
|
const before = latestAdmission;
|
|
686
|
+
const localBefore = latestLocalOperation;
|
|
658
687
|
const previousSignal = activeAdmissionSignal;
|
|
659
688
|
activeAdmissionSignal = signal;
|
|
660
689
|
try {
|
|
@@ -663,6 +692,7 @@ export function createInteractiveSlashRuntime(deps: InteractiveSlashRuntimeDeps)
|
|
|
663
692
|
activeAdmissionSignal = previousSignal;
|
|
664
693
|
}
|
|
665
694
|
if (latestAdmission !== before) await latestAdmission;
|
|
695
|
+
if (latestLocalOperation !== localBefore) await latestLocalOperation;
|
|
666
696
|
},
|
|
667
697
|
};
|
|
668
698
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The outward signal that a modal overlay owns the keyboard.
|
|
3
|
+
*
|
|
4
|
+
* Every framed Clio overlay captures input for as long as it is up, and until
|
|
5
|
+
* now it announced that only by being on screen. An external driver feeding
|
|
6
|
+
* keys into the pane, and herdr deciding whether the pane is idle, working, or
|
|
7
|
+
* blocked, had to infer modality from whatever the overlay happened to draw:
|
|
8
|
+
* its box title, its hint row, a footer pill. Those are per-overlay strings
|
|
9
|
+
* that move on every reskin, and the tall modals cover the very rows a screen
|
|
10
|
+
* scraper reads, so the signal is weakest exactly when a modal is largest.
|
|
11
|
+
*
|
|
12
|
+
* The marker publishes the fact out of band instead, as an OSC 0 terminal
|
|
13
|
+
* title. Three properties make the title the reliable channel here:
|
|
14
|
+
*
|
|
15
|
+
* 1. It is not screen content. No overlay can composite over it, no
|
|
16
|
+
* transcript line can counterfeit it, and no terminal height changes
|
|
17
|
+
* whether it is readable.
|
|
18
|
+
* 2. herdr already consumes it. `region = "osc_title"` is a first-class
|
|
19
|
+
* detection region (herdr `src/detect/manifest.rs`), fed from the pane's
|
|
20
|
+
* own emulator, and its rules outrank every screen rule.
|
|
21
|
+
* 3. Clio has never written a title, so the channel carries exactly one
|
|
22
|
+
* meaning and nothing else contends for it.
|
|
23
|
+
*
|
|
24
|
+
* The grammar is fixed and machine-first:
|
|
25
|
+
*
|
|
26
|
+
* clio no modal owns the keys
|
|
27
|
+
* clio [modal:permission-confirm] one modal, named
|
|
28
|
+
* clio [modal:library-install+2] top modal named, two more beneath it
|
|
29
|
+
*
|
|
30
|
+
* Nothing is written until the first modal opens, so a Clio that never opens
|
|
31
|
+
* an overlay leaves the pane's inherited title alone. From the first modal
|
|
32
|
+
* onward the title toggles between the marker and the bare base, which is what
|
|
33
|
+
* makes the absence of a marker a positive statement rather than an unknown.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/** The write side of a terminal title. `ProcessTerminal` satisfies it structurally. */
|
|
37
|
+
export interface ModalMarkerSink {
|
|
38
|
+
setTitle(title: string): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** What the title reads when nothing modal owns the keyboard. */
|
|
42
|
+
export const MODAL_MARKER_BASE_TITLE = "clio";
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The one regular expression an external reader needs. Exported so Clio's own
|
|
46
|
+
* contract test and herdr's manifest rule are written against the same shape
|
|
47
|
+
* rather than two hand-copied spellings of it.
|
|
48
|
+
*/
|
|
49
|
+
export const MODAL_MARKER_TITLE_PATTERN = /^clio \[modal:([a-z0-9][a-z0-9-]*)(?:\+([1-9]\d*))?\]$/u;
|
|
50
|
+
|
|
51
|
+
/** Render the title for a modal stack, outermost first. */
|
|
52
|
+
export function formatModalMarkerTitle(stack: readonly string[]): string {
|
|
53
|
+
const top = stack.at(-1);
|
|
54
|
+
if (top === undefined) return MODAL_MARKER_BASE_TITLE;
|
|
55
|
+
const beneath = stack.length - 1;
|
|
56
|
+
return `${MODAL_MARKER_BASE_TITLE} [modal:${top}${beneath > 0 ? `+${beneath}` : ""}]`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Read a marker title back. Returns null for the base title and for anything else. */
|
|
60
|
+
export function parseModalMarkerTitle(title: string): { id: string; depth: number } | null {
|
|
61
|
+
const match = MODAL_MARKER_TITLE_PATTERN.exec(title);
|
|
62
|
+
const id = match?.[1];
|
|
63
|
+
if (id === undefined) return null;
|
|
64
|
+
const beneath = match?.[2];
|
|
65
|
+
return { id, depth: beneath === undefined ? 1 : 1 + Number.parseInt(beneath, 10) };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** One modal's claim on the keyboard, released when the overlay goes away. */
|
|
69
|
+
export interface ModalMarkerHandle {
|
|
70
|
+
/** Drop this modal from the stack. Idempotent; a second call is inert. */
|
|
71
|
+
release(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Whether this modal currently owns keys. The engine's `setHidden` takes a
|
|
74
|
+
* visible overlay out of the focus order without destroying it, which is how
|
|
75
|
+
* a surface that shells out to a child process gets off the screen, so a
|
|
76
|
+
* hidden modal must stop claiming the keyboard without leaving the stack.
|
|
77
|
+
*/
|
|
78
|
+
setActive(active: boolean): void;
|
|
79
|
+
/** Bring this modal back to the top of the stack, as `handle.focus()` does on screen. */
|
|
80
|
+
raise(): void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface ModalMarkerRegistry {
|
|
84
|
+
/**
|
|
85
|
+
* Push a modal. The sink is taken from the caller rather than installed at
|
|
86
|
+
* startup so the marker has no lifecycle of its own: it exists exactly when
|
|
87
|
+
* an overlay exists, and a stub terminal with no `setTitle` makes the whole
|
|
88
|
+
* mechanism inert instead of throwing.
|
|
89
|
+
*/
|
|
90
|
+
enter(id: string, sink?: ModalMarkerSink | null): ModalMarkerHandle;
|
|
91
|
+
/** The ids that currently own keys, outermost first. */
|
|
92
|
+
stack(): readonly string[];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
interface ModalMarkerEntry {
|
|
96
|
+
readonly id: string;
|
|
97
|
+
active: boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function createModalMarkerRegistry(): ModalMarkerRegistry {
|
|
101
|
+
const entries: ModalMarkerEntry[] = [];
|
|
102
|
+
let sink: ModalMarkerSink | null = null;
|
|
103
|
+
let published: string | null = null;
|
|
104
|
+
|
|
105
|
+
function activeIds(): string[] {
|
|
106
|
+
return entries.filter((entry) => entry.active).map((entry) => entry.id);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function publish(): void {
|
|
110
|
+
if (sink === null) return;
|
|
111
|
+
const title = formatModalMarkerTitle(activeIds());
|
|
112
|
+
// Before the first marker there is no stale claim to clear, so the pane
|
|
113
|
+
// keeps whatever title the shell or the multiplexer gave it.
|
|
114
|
+
if (published === null && title === MODAL_MARKER_BASE_TITLE) return;
|
|
115
|
+
if (title === published) return;
|
|
116
|
+
published = title;
|
|
117
|
+
sink.setTitle(title);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function enter(id: string, nextSink?: ModalMarkerSink | null): ModalMarkerHandle {
|
|
121
|
+
if (nextSink) sink = nextSink;
|
|
122
|
+
const entry: ModalMarkerEntry = { id, active: true };
|
|
123
|
+
entries.push(entry);
|
|
124
|
+
publish();
|
|
125
|
+
let released = false;
|
|
126
|
+
return {
|
|
127
|
+
release(): void {
|
|
128
|
+
if (released) return;
|
|
129
|
+
released = true;
|
|
130
|
+
const index = entries.indexOf(entry);
|
|
131
|
+
if (index !== -1) entries.splice(index, 1);
|
|
132
|
+
publish();
|
|
133
|
+
},
|
|
134
|
+
setActive(active: boolean): void {
|
|
135
|
+
if (released || entry.active === active) return;
|
|
136
|
+
entry.active = active;
|
|
137
|
+
publish();
|
|
138
|
+
},
|
|
139
|
+
raise(): void {
|
|
140
|
+
if (released) return;
|
|
141
|
+
entry.active = true;
|
|
142
|
+
const index = entries.indexOf(entry);
|
|
143
|
+
if (index !== -1 && index !== entries.length - 1) {
|
|
144
|
+
entries.splice(index, 1);
|
|
145
|
+
entries.push(entry);
|
|
146
|
+
}
|
|
147
|
+
publish();
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { enter, stack: (): readonly string[] => activeIds() };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let registry = createModalMarkerRegistry();
|
|
156
|
+
|
|
157
|
+
/** Push a modal onto the process-wide stack. See {@link ModalMarkerRegistry.enter}. */
|
|
158
|
+
export function enterModal(id: string, sink?: ModalMarkerSink | null): ModalMarkerHandle {
|
|
159
|
+
return registry.enter(id, sink);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** The ids that currently own keys, outermost first. */
|
|
163
|
+
export function modalMarkerStack(): readonly string[] {
|
|
164
|
+
return registry.stack();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Drop every claim and forget the sink. Tests use it to isolate; nothing in the app does. */
|
|
168
|
+
export function resetModalMarker(): void {
|
|
169
|
+
registry = createModalMarkerRegistry();
|
|
170
|
+
}
|