@iowarp/clio-coder 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +116 -16
- package/dist/{acp-G5WJBNCT.js → acp-ZILU3AUO.js} +14 -14
- package/dist/{agents-FMV2Q5G4.js → agents-HYWGBGQR.js} +40 -29
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-3IDSJEIK.js → auth-N3QT7CBO.js} +21 -19
- package/dist/{builtins-XCZWXSC7.js → builtins-UJLMOVOV.js} +6 -6
- package/dist/{chunk-PQEFIJ36.js → chunk-2LEAKD4C.js} +1 -2
- package/dist/{chunk-3BT2XMV4.js → chunk-2NM363SV.js} +50 -57
- package/dist/{chunk-J4W7KFM7.js → chunk-2VG7KLYV.js} +24 -279
- package/dist/{chunk-SST6Z5JA.js → chunk-336NSSKI.js} +1 -1
- package/dist/{chunk-K5C3NCBD.js → chunk-3I5NY75V.js} +5 -5
- package/dist/{chunk-VAZSBTKF.js → chunk-3QSOM6PA.js} +2 -2
- package/dist/{chunk-TZ3SGWZZ.js → chunk-5QIAJV2D.js} +2 -2
- package/dist/{chunk-OQBA45DZ.js → chunk-5YHDIDBP.js} +2 -2
- package/dist/{chunk-NHLBIGRH.js → chunk-6CCS4G3W.js} +40 -17
- package/dist/{chunk-2JDWVJND.js → chunk-6DWBAZ5U.js} +2 -2
- package/dist/{chunk-LDQ2ZF2M.js → chunk-6FN3E6KX.js} +5 -5
- package/dist/{chunk-X3YGUTOB.js → chunk-6HMJX2VU.js} +59 -59
- package/dist/{chunk-VEO4AP2K.js → chunk-6I5ILFOF.js} +3 -2
- package/dist/{chunk-B7OBL7PK.js → chunk-6NJQITNH.js} +18 -11
- package/dist/{chunk-IQ7KR472.js → chunk-6VC4OV3Z.js} +6 -3
- package/dist/{chunk-P3FOHJT4.js → chunk-72GZI5EV.js} +2 -2
- package/dist/{chunk-AB44T6BB.js → chunk-74YWRRU5.js} +8 -7
- package/dist/{chunk-SJ5ZKQ4S.js → chunk-7EPLI7VL.js} +2 -2
- package/dist/{chunk-HWHKMHUA.js → chunk-7OBGU7UB.js} +3 -3
- package/dist/{chunk-2OQE55CK.js → chunk-7PWAODYW.js} +2 -2
- package/dist/{chunk-IBEBSCYA.js → chunk-7RY5VZPH.js} +42 -33
- package/dist/{chunk-LQ3DZAMX.js → chunk-ABLSQ6JX.js} +2 -2
- package/dist/{chunk-QLFS5GO2.js → chunk-AFKWHWXF.js} +12 -22
- package/dist/{chunk-FWDFM5ZU.js → chunk-AK5XEFVZ.js} +3 -3
- package/dist/{chunk-O6TL7WWY.js → chunk-AKB4GYDL.js} +4 -4
- package/dist/chunk-AP73CFDC.js +308 -0
- package/dist/{chunk-JDG2WCRO.js → chunk-BBTJOK6Y.js} +5 -5
- package/dist/{chunk-SP2RXXYO.js → chunk-BDPT6GTK.js} +10 -10
- package/dist/{chunk-NQQH3YT7.js → chunk-BJGUKIG4.js} +3 -3
- package/dist/{chunk-O4XIVISU.js → chunk-BTGG6BG2.js} +79 -38
- package/dist/chunk-BTK3SSSK.js +67 -0
- package/dist/{chunk-M6L6IDJG.js → chunk-BWH6N36D.js} +1 -1
- package/dist/chunk-BWW4HLO4.js +301 -0
- package/dist/{chunk-I5VEOC6I.js → chunk-C537JADH.js} +10 -10
- package/dist/{chunk-HI63TFOG.js → chunk-CDNVLKUX.js} +3 -3
- package/dist/{chunk-UM7N4G5A.js → chunk-CWVRRIEI.js} +2 -2
- package/dist/{chunk-BKFM6EJV.js → chunk-D4CJV46V.js} +2 -2
- package/dist/chunk-D7E7WCDF.js +27 -0
- package/dist/{chunk-WZR7K7ZX.js → chunk-E67WX76H.js} +6 -6
- package/dist/{chunk-FQ4SKYE4.js → chunk-EBY63B7G.js} +2 -5
- package/dist/chunk-EIMVLWB3.js +1842 -0
- package/dist/{chunk-RAPCMZL4.js → chunk-FSP7CMNU.js} +9 -1
- package/dist/{chunk-MLKNTWH2.js → chunk-FYUN5KZ3.js} +21 -21
- package/dist/{chunk-YJX4SHTD.js → chunk-GIZNH63R.js} +1 -1
- package/dist/{chunk-X75E3D2N.js → chunk-GPPB3JBE.js} +18 -16
- package/dist/{chunk-GR5G2PVF.js → chunk-GVQJ5CCZ.js} +15 -10
- package/dist/chunk-HJWWJ6IL.js +184 -0
- package/dist/{chunk-VO67MWHC.js → chunk-HRQMFLJP.js} +3 -3
- package/dist/{chunk-VYMXRQI6.js → chunk-HUAS7ITX.js} +89 -93
- package/dist/{chunk-BKFJHQCA.js → chunk-I66EAJFY.js} +2 -2
- package/dist/{chunk-DYJP44XW.js → chunk-IG7BCQBA.js} +1 -1
- package/dist/{chunk-32KWKNSF.js → chunk-IXJT6DCX.js} +3 -3
- package/dist/{chunk-C2LTL2W6.js → chunk-J4HBWF6Y.js} +360 -172
- package/dist/chunk-J5LZHVIT.js +284 -0
- package/dist/{chunk-QLL7ILRG.js → chunk-JA5QWE4Z.js} +510 -202
- package/dist/{chunk-BBVJUZHB.js → chunk-JIEGK6UF.js} +5 -173
- package/dist/{chunk-36EJLSQQ.js → chunk-JZWT5J3Y.js} +4 -4
- package/dist/{chunk-HZHHCK24.js → chunk-K6BF4U2H.js} +476 -322
- package/dist/{chunk-Z2RR6MAK.js → chunk-MA3H6DM5.js} +6 -6
- package/dist/{chunk-CODPRO7Q.js → chunk-MOPSG2X7.js} +6 -6
- package/dist/{chunk-76ONBSIA.js → chunk-MQXIVJ35.js} +14 -5
- package/dist/{chunk-YDFRH54B.js → chunk-N5UK64DP.js} +4 -4
- package/dist/chunk-NDDGJUXD.js +81 -0
- package/dist/{chunk-4ZG3XFUR.js → chunk-NLFAQR7Z.js} +12 -1
- package/dist/{chunk-VO2LKSTM.js → chunk-O42A54GG.js} +2 -2
- package/dist/{chunk-W5VSYASO.js → chunk-OJTRZGR3.js} +46 -87
- package/dist/{chunk-NHCZP4K7.js → chunk-PBP4B7XR.js} +2 -2
- package/dist/{chunk-3URVFKWK.js → chunk-PJJ6MY27.js} +5 -5
- package/dist/{chunk-ZGVHUX3M.js → chunk-PMZVFWSR.js} +2 -2
- package/dist/{chunk-GKF55TAZ.js → chunk-PVAMAVBB.js} +3 -2
- package/dist/{chunk-6DB53AJS.js → chunk-QKIFBZKT.js} +7 -7
- package/dist/{chunk-HJJTYUHX.js → chunk-QMXC4JB7.js} +20 -20
- package/dist/chunk-QTFGO774.js +644 -0
- package/dist/{chunk-CY6FY24N.js → chunk-R23Z6K6I.js} +2 -2
- package/dist/{chunk-ULC6OTWO.js → chunk-R32CLGZ6.js} +13 -13
- package/dist/{chunk-KMVISBZR.js → chunk-RKSR6VSF.js} +1 -1
- package/dist/{chunk-F4CKPOEQ.js → chunk-SCYB3HA4.js} +72 -26
- package/dist/{chunk-LY4S7GJC.js → chunk-SINK3QR6.js} +18 -16
- package/dist/{chunk-U77AMWDL.js → chunk-TD3PGPQA.js} +43 -22
- package/dist/{chunk-QBJA7R7N.js → chunk-THYWACCR.js} +2 -2
- package/dist/{chunk-QREDIESB.js → chunk-TVH4ONAM.js} +14 -8
- package/dist/chunk-U2WB7TZS.js +271 -0
- package/dist/{chunk-KFZI4NIL.js → chunk-UAPGZHYC.js} +145 -31
- package/dist/{chunk-DQITNCXG.js → chunk-UEDMSP56.js} +29 -14
- package/dist/{chunk-3XML7CDN.js → chunk-UXN6JT4W.js} +2 -2
- package/dist/{chunk-CMZWFGD2.js → chunk-VAVR4IJY.js} +19 -15
- package/dist/{chunk-BPKCPIL7.js → chunk-VEGN6WIQ.js} +2 -2
- package/dist/chunk-VKFQTNDV.js +66 -0
- package/dist/{chunk-7MCTRUCE.js → chunk-VKRH2TCS.js} +2 -2
- package/dist/{chunk-5LXZXPKX.js → chunk-VN3SHNBN.js} +2 -2
- package/dist/{chunk-UOSL25KY.js → chunk-VXMFAE2W.js} +1 -1
- package/dist/{chunk-BBVYXMFO.js → chunk-WNP7O5WZ.js} +2 -2
- package/dist/{chunk-SUCTJL45.js → chunk-WR6U3OVP.js} +3 -3
- package/dist/{chunk-BUMFYQFY.js → chunk-XKA2ICR3.js} +124 -113
- package/dist/{chunk-UXMFQ54G.js → chunk-Y45G3AXC.js} +39 -39
- package/dist/{chunk-J5Q24KAG.js → chunk-Y4CAGMM6.js} +2 -2
- package/dist/{chunk-NYS75XW5.js → chunk-YAKGTXEV.js} +5 -3
- package/dist/{chunk-V5DHCITQ.js → chunk-ZAZB4JMW.js} +23 -12
- package/dist/{chunk-Z4TXYIEG.js → chunk-ZJLUDYFY.js} +9 -9
- package/dist/{chunk-HKIYEGME.js → chunk-ZTJUVLTU.js} +2 -2
- package/dist/{chunk-2ANTL7MR.js → chunk-ZW55JB7N.js} +2 -2
- package/dist/cli/index.js +36 -36
- package/dist/{clio-2JXHBBY5.js → clio-IT3G3VQH.js} +12 -13
- package/dist/{code-nav-3YYRMYNF.js → code-nav-RK6S7F6E.js} +5 -5
- package/dist/codewiki/build-worker.js +1 -1
- package/dist/{compile-cache-7FPE6PS3.js → compile-cache-OQAVB7Y5.js} +2 -4
- package/dist/{components-RYZV4JGP.js → components-UBWCQSRW.js} +4 -4
- package/dist/{config-QZPCMYSO.js → config-3QZRWZJF.js} +53 -49
- package/dist/{configure-TEGEBYCA.js → configure-FL7Y3KJF.js} +25 -22
- package/dist/{context-E6H5RNMC.js → context-5HE7ODYK.js} +47 -43
- package/dist/{context-AV7OEZ4D.js → context-KYQFRVDC.js} +11 -11
- package/dist/{context-GSXUE4CT.js → context-XNHL75JV.js} +32 -19
- package/dist/{context-clear-SHIBYK6T.js → context-clear-N545L53A.js} +47 -43
- package/dist/{context-working-set-5ZGKPGZQ.js → context-working-set-QHKXSV2F.js} +10 -9
- package/dist/{dispatch-runner-EFMJT4LD.js → dispatch-runner-RGIE5PCT.js} +56 -47
- package/dist/{docs-23KQS3XK.js → docs-5NAF6AU7.js} +5 -11
- package/dist/doctor-ZGPEGHIP.js +772 -0
- package/dist/{eval-TFBYQH4H.js → eval-GXLL44RD.js} +63 -45
- package/dist/{eval-inventory-SXH7PDKX.js → eval-inventory-HBWSWQOK.js} +7 -8
- package/dist/{evidence-ERGESKGN.js → evidence-HWLBRH3Q.js} +44 -40
- package/dist/{evolve-VDXTSYCJ.js → evolve-FTZBMNVW.js} +43 -39
- package/dist/{extensions-7BGBHN57.js → extensions-VHRBEID7.js} +4 -4
- package/dist/{fleet-2RRVDF2V.js → fleet-CKZHJWZJ.js} +86 -73
- package/dist/{fleet-commands-VJ726XIA.js → fleet-commands-EXDXBMV6.js} +10 -9
- package/dist/{fleet-decisions-EPAPM3XJ.js → fleet-decisions-OTHB6KRL.js} +5 -5
- package/dist/{fleet-graph-JF5QOATM.js → fleet-graph-YTEZUCUT.js} +13 -11
- package/dist/{fleet-inspect-VLY4S7QM.js → fleet-inspect-SS6YMDCK.js} +44 -41
- package/dist/{fleet-preflight-AIZUEJOY.js → fleet-preflight-PBY4VYOM.js} +5 -9
- package/dist/{fleet-validate-AJRPDMDV.js → fleet-validate-KMEM5L3S.js} +16 -13
- package/dist/{fleet-verify-JFEL2L3H.js → fleet-verify-QD5M7E7Q.js} +42 -39
- package/dist/{fleet-view-ZCON35AG.js → fleet-view-WAMJYNDT.js} +44 -52
- package/dist/{init-DN2WWLFE.js → init-5XQRBOFV.js} +63 -58
- package/dist/{install-XGLBQY5E.js → install-NKNG7KD4.js} +2 -2
- package/dist/{interop-OZBKXAYL.js → interop-34TVO25M.js} +13 -11
- package/dist/{library-YWZG7IMW.js → library-3QY6KF57.js} +17 -14
- package/dist/{memory-I4C4HMLW.js → memory-L4UTIIIW.js} +45 -41
- package/dist/{models-CEYXJBO6.js → models-ZVX3QOWE.js} +39 -31
- package/dist/{monitor-NZ6GCI3P.js → monitor-CEKVSYTS.js} +50 -46
- package/dist/{orchestrator-GCGQ4N5I.js → orchestrator-77BAP6BC.js} +1807 -1039
- package/dist/{panes-KY6W3V2E.js → panes-7STHOAUJ.js} +4 -4
- package/dist/{panes-HMABYVO4.js → panes-SHAUIRXY.js} +10 -8
- package/dist/{paths-II4K7DNR.js → paths-L7LGY6RN.js} +4 -4
- package/dist/{reset-DQ6FGCSH.js → reset-EOLM7GVE.js} +7 -8
- package/dist/{resources-BB3MVJMD.js → resources-74GKTLSF.js} +17 -13
- package/dist/{run-H2GQDUER.js → run-HBAUJNNZ.js} +86 -76
- package/dist/{share-GTJN6A5O.js → share-G3APVLVP.js} +17 -14
- package/dist/{skills-L55TEW6R.js → skills-35HHUKCR.js} +19 -16
- package/dist/{skills-eval-XVXPH2JI.js → skills-eval-QN4HSHDC.js} +55 -57
- package/dist/{skills-inventory-S4MXPJFV.js → skills-inventory-J357J34F.js} +15 -12
- package/dist/{slash-commands-ZSGASKJC.js → slash-commands-JZZCQA32.js} +31 -29
- package/dist/{steer-RZGSCY4R.js → steer-XAVHJM22.js} +3 -3
- package/dist/{support-PKEUNNQL.js → support-U7QOWY26.js} +6 -6
- package/dist/{targets-NCPZ644J.js → targets-DSM6CY3M.js} +59 -53
- package/dist/{terminal-lease-44SV3YCN.js → terminal-lease-JOPFUVEM.js} +14 -9
- package/dist/{tools-DAF3DI3C.js → tools-MKNWVPBH.js} +10 -8
- package/dist/{trace-FYVW2MQA.js → trace-ECQ7TIYZ.js} +48 -3
- package/dist/{tui-primitives-2AKXQNZK.js → tui-primitives-K5PASC3O.js} +8 -4
- package/dist/{uninstall-DW2PNOIC.js → uninstall-N34PCTGJ.js} +4 -6
- package/dist/{upgrade-3XPP6OQL.js → upgrade-H7TOM7YL.js} +35 -62
- package/dist/{usage-3NLHGTU2.js → usage-X52N3IDJ.js} +51 -48
- package/dist/{verifiers-SSQONKRT.js → verifiers-EJTVVSMA.js} +10 -9
- package/dist/{verify-3U6J7FZI.js → verify-YJL6XET2.js} +9 -8
- package/dist/{web-fetch-S7RR6GZ7.js → web-fetch-MPIFL3LL.js} +1 -2
- package/dist/{wiki-generate-CEHYGPGQ.js → wiki-generate-4NDZTQ4B.js} +66 -63
- package/dist/{with-panes-MKB46MPQ.js → with-panes-OBOBFIIR.js} +62 -26
- package/dist/worker/entry.js +57 -52
- package/docs/acp.md +1 -1
- package/docs/built-in-agents.md +40 -32
- package/docs/commands-and-modes.md +9 -3
- package/docs/config-knobs-audit.md +3 -0
- package/docs/configuration-and-targets.md +105 -164
- package/docs/environment-variables.md +2 -1
- package/docs/exit-codes-and-output.md +2 -0
- package/docs/fleet-demo-runbook.md +6 -3
- package/docs/fleet-dispatch.md +8 -6
- package/docs/installation-and-lifecycle.md +1 -1
- package/docs/release-cut-checklist.md +164 -177
- package/docs/trace-store.md +15 -10
- package/docs/troubleshooting.md +1 -1
- package/evals/README.md +5 -0
- package/evals/behavioral-corpus-grader.mjs +103 -0
- package/evals/behavioral-machinery-baseline.json +2276 -0
- package/evals/behavioral-machinery-driver.ts +250 -0
- package/evals/behavioral-machinery-support.ts +253 -0
- package/evals/behavioral-machinery.yaml +614 -0
- package/evals/behavioral-model-negative-control.yaml +68 -0
- package/evals/behavioral-model.yaml +216 -0
- package/evals/fixtures/behavioral-facts.txt +3 -0
- package/evals/fixtures/behavioral-main.ts +7 -0
- package/evals/fixtures/decoy/note.txt +2 -0
- package/evals/fixtures/private/credentials.txt +1 -0
- package/evals/tracked-metrics-baseline.yaml +229 -0
- package/evals/tracked-metrics-grader.mjs +129 -0
- package/package.json +5 -15
- package/skills/README.md +6 -6
- package/skills/coding/ast-grep/SKILL.md +8 -2
- package/skills/coding/coding-standards/SKILL.md +8 -2
- package/skills/coding/prototype/SKILL.md +8 -2
- package/skills/coding/tdd/SKILL.md +8 -2
- package/skills/context/context-handoff/SKILL.md +12 -3
- package/skills/context/context-handoff/evals.md +3 -3
- package/skills/context/context-prime/SKILL.md +8 -2
- package/skills/context/context-prime/evals.md +2 -2
- package/skills/git/file-ticket/SKILL.md +9 -4
- package/skills/git/file-ticket/evals.md +2 -2
- package/skills/git/fix-issue/SKILL.md +12 -5
- package/skills/git/fix-issue/evals.md +4 -4
- package/skills/git/resolve-merge-conflicts/SKILL.md +8 -2
- package/skills/git/resolve-merge-conflicts/evals.md +2 -2
- package/skills/git/ship/SKILL.md +9 -3
- package/skills/git/ship/evals.md +4 -4
- package/skills/git/worktree-create/SKILL.md +7 -2
- package/skills/git/worktree-create/evals.md +6 -6
- package/skills/git/worktree-merge/SKILL.md +7 -2
- package/skills/git/worktree-merge/evals.md +6 -6
- package/skills/meta/{clio-dev → clio-coder-dev}/SKILL.md +14 -8
- package/skills/meta/{clio-dev → clio-coder-dev}/evals.md +3 -3
- package/skills/meta/{clio-test → clio-coder-test}/SKILL.md +11 -5
- package/skills/meta/{clio-test → clio-coder-test}/evals.md +1 -1
- package/skills/meta/credentials/SKILL.md +9 -2
- package/skills/meta/find-skills/SKILL.md +8 -2
- package/skills/meta/herdr/SKILL.md +8 -2
- package/skills/meta/skill-craft/SKILL.md +21 -4
- package/skills/planning/architecture/SKILL.md +9 -3
- package/skills/planning/backlog/SKILL.md +8 -2
- package/skills/planning/prd/SKILL.md +8 -2
- package/skills/planning/product-intent/SKILL.md +8 -2
- package/skills/planning/tech-spec/SKILL.md +9 -3
- package/skills/registry.yaml +66 -66
- package/skills/research/arxiv-literature/SKILL.md +8 -2
- package/skills/research/experiment-protocol/SKILL.md +9 -2
- package/skills/research/scientific-debugging/SKILL.md +9 -2
- package/skills/research/scientific-debugging/evals.md +2 -2
- package/skills/research/scientific-modernization/SKILL.md +9 -2
- package/skills/skill-marketplace.json +257 -38
- package/skills/workflow/cut-it/SKILL.md +10 -2
- package/skills/workflow/design-council/SKILL.md +11 -2
- package/skills/workflow/grill-me/SKILL.md +8 -2
- package/skills/workflow/workflow-distiller/SKILL.md +8 -2
- package/src/cli/acp.ts +2 -2
- package/src/cli/auth.ts +2 -2
- package/src/cli/bootstrap-generate.ts +5 -5
- package/src/cli/clio.ts +6 -1
- package/src/cli/config-inspect.ts +3 -3
- package/src/cli/configure-interop.ts +1 -1
- package/src/cli/configure.ts +27 -27
- package/src/cli/default-target.ts +1 -1
- package/src/cli/docs.ts +6 -6
- package/src/cli/doctor-naming.ts +323 -0
- package/src/cli/doctor-panes.ts +46 -14
- package/src/cli/doctor-toolchain.ts +29 -8
- package/src/cli/doctor.ts +15 -1
- package/src/cli/eval-inventory.ts +8 -8
- package/src/cli/evidence-detail.ts +1 -1
- package/src/cli/evidence-inventory.ts +1 -1
- package/src/cli/fleet-decisions.ts +1 -1
- package/src/cli/fleet-inspect.ts +1 -1
- package/src/cli/fleet-preflight.ts +1 -1
- package/src/cli/fleet-verify.ts +1 -1
- package/src/cli/fleet-view.ts +40 -23
- package/src/cli/fleet.ts +8 -5
- package/src/cli/interop-inspect.ts +2 -2
- package/src/cli/models.ts +3 -3
- package/src/cli/modes/print.ts +1 -1
- package/src/cli/reset.ts +1 -1
- package/src/cli/run.ts +11 -15
- package/src/cli/share.ts +1 -1
- package/src/cli/skills-eval.ts +11 -11
- package/src/cli/targets.ts +23 -24
- package/src/cli/trace-inspect.ts +1 -1
- package/src/cli/trace.ts +41 -0
- package/src/cli/uninstall.ts +2 -2
- package/src/cli/upgrade.ts +29 -34
- package/src/cli/usage.ts +2 -2
- package/src/cli/validate-model.ts +1 -1
- package/src/cli/verifiers-inspect.ts +1 -1
- package/src/cli/wiki-generate.ts +5 -5
- package/src/core/bash-exec.ts +1 -1
- package/src/core/boot-trace.ts +3 -3
- package/src/core/bus-trace.ts +2 -2
- package/src/core/compile-cache.ts +1 -1
- package/src/core/config.ts +1062 -886
- package/src/core/defaults.ts +321 -528
- package/src/core/domain-loader.ts +6 -4
- package/src/core/event-bus.ts +1 -1
- package/src/core/file-references.ts +78 -88
- package/src/core/git-commit-attribution.ts +3 -9
- package/src/core/guardrails.ts +24 -4
- package/src/core/naming-compat.ts +45 -0
- package/src/core/naming-events.ts +62 -0
- package/src/core/recent-models.ts +1 -7
- package/src/core/residency-protection.ts +4 -8
- package/src/core/resolve-config-value.ts +1 -1
- package/src/core/response-model-id.ts +0 -14
- package/src/core/session-routing.ts +84 -74
- package/src/core/skill-activation.ts +18 -0
- package/src/core/termination.ts +4 -4
- package/src/core/timers.ts +2 -12
- package/src/domains/agents/catalog.ts +2 -12
- package/src/domains/agents/extension.ts +3 -3
- package/src/domains/agents/registry.ts +7 -7
- package/src/domains/agents/result-contract.ts +1 -1
- package/src/domains/agents/spec.ts +0 -11
- package/src/domains/config/classify.ts +35 -47
- package/src/domains/config/extension.ts +5 -5
- package/src/domains/config/keybindings.ts +48 -47
- package/src/domains/config/watcher.ts +1 -1
- package/src/domains/context/codewiki/indexer.ts +1 -1
- package/src/domains/context/extension.ts +3 -3
- package/src/domains/context/prompt-context.ts +1 -1
- package/src/domains/context/wiki/assemble.ts +2 -2
- package/src/domains/context/working-set/replay/metrics.ts +0 -4
- package/src/domains/context/working-set/replay/report.ts +1 -1
- package/src/domains/context/working-set/replay/synthetic.ts +2 -2
- package/src/domains/dispatch/active-route-planner.ts +2 -2
- package/src/domains/dispatch/agent-candidates.ts +1 -1
- package/src/domains/dispatch/agent-ledger-store.ts +1 -1
- package/src/domains/dispatch/agent-ledger.ts +1 -1
- package/src/domains/dispatch/assignment.ts +5 -5
- package/src/domains/dispatch/capacity-lease.ts +2 -5
- package/src/domains/dispatch/code-step.ts +1 -1
- package/src/domains/dispatch/contract.ts +2 -2
- package/src/domains/dispatch/extension.ts +65 -61
- package/src/domains/dispatch/fleet-node-prompt.ts +1 -1
- package/src/domains/dispatch/fleet-preflight.ts +8 -17
- package/src/domains/dispatch/fleet-run.ts +0 -7
- package/src/domains/dispatch/gate-decisions.ts +25 -14
- package/src/domains/dispatch/joint-route-resolver.ts +1 -1
- package/src/domains/dispatch/path-scope.ts +0 -61
- package/src/domains/dispatch/placement.ts +2 -2
- package/src/domains/dispatch/receipt-findings.ts +1 -1
- package/src/domains/dispatch/receipt-integrity.ts +20 -8
- package/src/domains/dispatch/reservation-store.ts +0 -23
- package/src/domains/dispatch/route-decision.ts +1 -1
- package/src/domains/dispatch/route-history.ts +1 -1
- package/src/domains/dispatch/route-policy.ts +1 -1
- package/src/domains/dispatch/route-readiness.ts +0 -28
- package/src/domains/dispatch/run-event-journal.ts +6 -5
- package/src/domains/dispatch/tool-stats.ts +1 -1
- package/src/domains/dispatch/transport.ts +2 -19
- package/src/domains/dispatch/types.ts +3 -3
- package/src/domains/dispatch/worker-protocol.ts +2 -2
- package/src/domains/eval/artifacts/store.ts +5 -4
- package/src/domains/eval/compare/thresholds.ts +0 -8
- package/src/domains/eval/execution-provenance.ts +1 -1
- package/src/domains/eval/metrics/token-stream.ts +0 -7
- package/src/domains/eval/report.ts +1 -1
- package/src/domains/eval/runner.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +7 -6
- package/src/domains/eval/runners/external-command.ts +4 -3
- package/src/domains/eval/schema/artifact.ts +1 -1
- package/src/domains/eval/schema/behavioral-metrics.ts +3 -2
- package/src/domains/eval/schema/behavioral.ts +7 -6
- package/src/domains/eval/schema/execution-envelope.ts +4 -2
- package/src/domains/eval/schema/naming.ts +10 -0
- package/src/domains/eval/schema/suite.ts +2 -2
- package/src/domains/eval/schema/validate.ts +9 -5
- package/src/domains/eval/schema/verdict.ts +4 -2
- package/src/domains/eval/store.ts +12 -2
- package/src/domains/eval/suites/run.ts +12 -6
- package/src/domains/eval/types.ts +1 -1
- package/src/domains/eval/workspaces/git.ts +1 -1
- package/src/domains/eval/workspaces/temp-copy.ts +1 -1
- package/src/domains/evidence/build.ts +13 -5
- package/src/domains/interop/consent.ts +7 -7
- package/src/domains/interop/extension.ts +1 -1
- package/src/domains/lifecycle/doctor.ts +27 -21
- package/src/domains/lifecycle/migrations/2026-09-01-clio-coder-naming.ts +155 -0
- package/src/domains/lifecycle/migrations/2026-09-01-retire-panes-knobs.ts +59 -0
- package/src/domains/lifecycle/migrations/2026-09-01-settings-v2.ts +338 -0
- package/src/domains/lifecycle/migrations/index.ts +20 -1
- package/src/domains/lifecycle/naming-history.ts +153 -0
- package/src/domains/lifecycle/naming-mutable-state.ts +104 -0
- package/src/domains/lifecycle/naming-resources.ts +261 -0
- package/src/domains/lifecycle/naming-tool-markers.ts +139 -0
- package/src/domains/lifecycle/naming-yazi.ts +81 -0
- package/src/domains/lifecycle/upgrade-notice.ts +1 -1
- package/src/domains/memory/task-memory-handoff.ts +6 -3
- package/src/domains/middleware/index.ts +7 -0
- package/src/domains/middleware/marketplace-offer.ts +339 -0
- package/src/domains/middleware/runtime.ts +2 -2
- package/src/domains/mux/contract.ts +157 -25
- package/src/domains/mux/detect.ts +29 -5
- package/src/domains/mux/dock-controller.ts +365 -0
- package/src/domains/mux/extension.ts +7 -1
- package/src/domains/mux/index.ts +20 -0
- package/src/domains/mux/operations.ts +28 -0
- package/src/domains/mux/protocol.ts +19 -6
- package/src/domains/mux/socket-client.ts +167 -19
- package/src/domains/mux/types.ts +49 -6
- package/src/domains/mux/yazi/event-stream.ts +6 -4
- package/src/domains/mux/yazi/profile.ts +1 -1
- package/src/domains/mux/yazi/session.ts +26 -3
- package/src/domains/observability/extension.ts +1 -1
- package/src/domains/observability/out-of-turn-usage.ts +2 -2
- package/src/domains/observability/projection.ts +1 -1
- package/src/domains/observability/trace-store.ts +22 -12
- package/src/domains/prompts/compiler.ts +2 -2
- package/src/domains/prompts/extension.ts +3 -3
- package/src/domains/prompts/fragments/identity/clio-worker.md +1 -1
- package/src/domains/prompts/fragments/operating/skills.md +25 -18
- package/src/domains/providers/extension.ts +5 -5
- package/src/domains/providers/knowledge-base-path.ts +1 -1
- package/src/domains/providers/model-runtime-capabilities.ts +14 -2
- package/src/domains/providers/models/cloud-models/alcf.yaml +1 -1
- package/src/domains/providers/models/local-models/{clio-local-coding-targets.yaml → clio-coder-local-coding-targets.yaml} +4 -4
- package/src/domains/providers/plugins.ts +1 -1
- package/src/domains/providers/resolver.ts +1 -1
- package/src/domains/providers/runtimes/cloud/alcf.ts +4 -4
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +1 -5
- package/src/domains/providers/runtimes/common/local-synth.ts +3 -3
- package/src/domains/providers/runtimes/common/probe-helpers.ts +2 -2
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +2 -9
- package/src/domains/providers/runtimes/protocol/litellm.ts +1 -91
- package/src/domains/providers/types/knowledge-base.ts +13 -0
- package/src/domains/providers/types/local-model-quirks.ts +2 -2
- package/src/domains/providers/types/target-descriptor.ts +3 -3
- package/src/domains/resources/extension.ts +1 -1
- package/src/domains/resources/library.ts +6 -6
- package/src/domains/resources/prompts/loader.ts +1 -1
- package/src/domains/resources/skills/content-hash.ts +7 -6
- package/src/domains/resources/skills/evals.ts +1 -1
- package/src/domains/resources/skills/install.ts +36 -12
- package/src/domains/resources/skills/loader.ts +39 -13
- package/src/domains/resources/skills/marketplace.ts +21 -2
- package/src/domains/resources/skills/promotion.ts +214 -0
- package/src/domains/safety/audit.ts +2 -2
- package/src/domains/safety/finish-contract.ts +2 -1
- package/src/domains/safety/run-effects.ts +1 -1
- package/src/domains/scheduling/extension.ts +4 -4
- package/src/domains/session/archive-readers.ts +9 -1
- package/src/domains/session/compaction/branch-summary.ts +4 -0
- package/src/domains/session/compaction/compact.ts +1 -1
- package/src/domains/session/compaction/tokens.ts +4 -0
- package/src/domains/session/context-accounting.ts +1 -1
- package/src/domains/session/decision-board.ts +1 -1
- package/src/domains/session/extension.ts +1 -1
- package/src/domains/session/handoff.ts +2 -2
- package/src/domains/session/prompt-manifest.ts +0 -5
- package/src/domains/session/protected-artifact-journal.ts +12 -6
- package/src/domains/session/retry.ts +1 -1
- package/src/domains/share/archive.ts +85 -36
- package/src/domains/toolchain/install.ts +1 -1
- package/src/engine/acp/adapter.ts +3 -3
- package/src/engine/acp/event-mapper.ts +3 -3
- package/src/engine/acp/server.ts +27 -26
- package/src/engine/acp/tool-mediator.ts +2 -2
- package/src/engine/acp/types.ts +1 -1
- package/src/engine/alcf-oauth.ts +5 -5
- package/src/engine/antigravity/subprocess-runtime.ts +2 -2
- package/src/engine/api-registry.ts +1 -1
- package/src/engine/apis/llamacpp-residency.ts +1 -19
- package/src/engine/apis/lmstudio.ts +1 -6
- package/src/engine/apis/ollama-native.ts +3 -3
- package/src/engine/apis/openai-completions.ts +2 -2
- package/src/engine/apis/residency.ts +3 -9
- package/src/engine/claude/sdk-module.ts +1 -12
- package/src/engine/claude/sdk-runtime.ts +6 -6
- package/src/engine/claude/subprocess-runtime.ts +1 -1
- package/src/engine/claude/tool-safety.ts +4 -4
- package/src/engine/loop-guard.ts +0 -5
- package/src/engine/session.ts +14 -7
- package/src/engine/tui-primitives.ts +1 -1
- package/src/engine/worker-events.ts +6 -6
- package/src/engine/worker-runtime.ts +14 -13
- package/src/entry/orchestrator.ts +107 -88
- package/src/interactive/application-controller.ts +21 -21
- package/src/interactive/bus-notices.ts +2 -2
- package/src/interactive/chat-loop.ts +8 -8
- package/src/interactive/chat-panel.ts +1 -1
- package/src/interactive/clio-editor.ts +105 -1
- package/src/interactive/context-activity.ts +8 -6
- package/src/interactive/context-meter.ts +3 -6
- package/src/interactive/context-overlay.ts +1 -1
- package/src/interactive/cost-overlay.ts +1 -1
- package/src/interactive/council-grid.ts +2 -2
- package/src/interactive/dispatch-board.ts +30 -33
- package/src/interactive/editor-bash.ts +21 -0
- package/src/interactive/editor-steer.ts +9 -4
- package/src/interactive/editor-submit.ts +24 -18
- package/src/interactive/external-editor.ts +1 -1
- package/src/interactive/file-reference-completion.ts +360 -0
- package/src/interactive/footer/dashboard.ts +15 -17
- package/src/interactive/footer/notifications.ts +14 -8
- package/src/interactive/footer/widgets.ts +2 -44
- package/src/interactive/interactive-application.ts +79 -59
- package/src/interactive/interactive-event-projection.ts +1 -1
- package/src/interactive/interactive-input-runtime.ts +2 -2
- package/src/interactive/interactive-presentation.ts +21 -16
- package/src/interactive/interactive-shell.ts +2 -2
- package/src/interactive/interactive-slash-runtime.ts +63 -17
- package/src/interactive/interactive-subscriptions.ts +1 -1
- package/src/interactive/interactive-tickers.ts +1 -1
- package/src/interactive/keybinding-manager.ts +4 -4
- package/src/interactive/layout.ts +1 -1
- package/src/interactive/memory-overlay.ts +2 -2
- package/src/interactive/modal-marker.ts +2 -21
- package/src/interactive/mutation-preview.ts +1 -1
- package/src/interactive/overlay-frame.ts +4 -12
- package/src/interactive/overlay-general-openers.ts +6 -2
- package/src/interactive/overlay-key-routing.ts +7 -7
- package/src/interactive/overlay-lifecycle.ts +1 -1
- package/src/interactive/overlay-model-selectors.ts +3 -3
- package/src/interactive/overlays/agents.ts +2 -2
- package/src/interactive/overlays/ask-user.ts +25 -11
- package/src/interactive/overlays/context-reset.ts +28 -4
- package/src/interactive/overlays/cwd-fallback.ts +28 -4
- package/src/interactive/overlays/decisions.ts +4 -2
- package/src/interactive/overlays/fleet-run-approval.ts +3 -3
- package/src/interactive/overlays/handoff-review.ts +2 -2
- package/src/interactive/overlays/interop.ts +1 -1
- package/src/interactive/overlays/library-install-confirm.ts +1 -1
- package/src/interactive/overlays/message-picker.ts +1 -1
- package/src/interactive/overlays/model-selector.ts +39 -31
- package/src/interactive/overlays/prompts.ts +10 -4
- package/src/interactive/overlays/session-selector.ts +2 -2
- package/src/interactive/overlays/settings.ts +339 -293
- package/src/interactive/overlays/side-question.ts +2 -2
- package/src/interactive/overlays/skills-hub.ts +8 -8
- package/src/interactive/overlays/tree-selector.ts +2 -2
- package/src/interactive/panes-runtime.ts +36 -10
- package/src/interactive/permission-overlay.ts +2 -2
- package/src/interactive/renderers/retry-status.ts +12 -4
- package/src/interactive/renderers/tool-execution.ts +4 -4
- package/src/interactive/session-transcript.ts +3 -3
- package/src/interactive/slash-autocomplete.ts +454 -165
- package/src/interactive/slash-commands.ts +279 -183
- package/src/interactive/slash-spec.ts +160 -17
- package/src/interactive/status/controller.ts +2 -2
- package/src/interactive/stream-pacing-policy.ts +1 -1
- package/src/interactive/tasks-overlay.ts +20 -13
- package/src/interactive/terminal-lease.ts +6 -7
- package/src/interactive/turn-context.ts +11 -11
- package/src/interactive/turn-persistence.ts +2 -2
- package/src/interactive/turn-prewarm.ts +2 -2
- package/src/interactive/turn-runtime.ts +8 -8
- package/src/interactive/turn-state.ts +1 -1
- package/src/interactive/view/artifacts.ts +12 -9
- package/src/interactive/view/view-overlay.ts +13 -10
- package/src/interactive/watch-pane.ts +38 -10
- package/src/interactive/welcome-dashboard.ts +15 -15
- package/src/interactive/worker-progress.ts +4 -4
- package/src/interactive/worker-receipts.ts +1 -1
- package/src/interactive/worker-stream.ts +1 -4
- package/src/interactive/yazi-bridge.ts +12 -5
- package/src/tools/ask-user.ts +3 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/builtin-tool-catalog.ts +1 -1
- package/src/tools/compete-worktrees.ts +27 -17
- package/src/tools/context/index.ts +15 -1
- package/src/tools/dispatch-admission.ts +4 -2
- package/src/tools/dispatch-arguments.ts +1 -1
- package/src/tools/dispatch-plan.ts +0 -11
- package/src/tools/dispatch-run-events.ts +12 -10
- package/src/tools/dispatch-runner.ts +11 -6
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/find.ts +1 -6
- package/src/tools/monitor.ts +4 -4
- package/src/tools/observers.ts +0 -33
- package/src/tools/task-worktree.ts +28 -7
- package/src/tools/verify/authoring.ts +3 -6
- package/src/tools/verify/frontend.ts +1 -1
- package/src/tools/web-fetch.ts +1 -1
- package/src/worker/entry.ts +4 -3
- package/src/worker/protocol.ts +16 -14
- package/src/worker/spec-contract.ts +2 -2
- package/src/worker/stdin-demux.ts +2 -2
- package/dist/chunk-GXNLGKAB.js +0 -571
- package/dist/chunk-VFA6GDY5.js +0 -1625
- package/dist/doctor-QOA5FNY5.js +0 -313
- package/src/engine/apis/degraded-inference.ts +0 -95
- /package/skills/meta/{clio-test → clio-coder-test}/references/harness.md +0 -0
- /package/skills/meta/{clio-test → clio-coder-test}/references/test-map.md +0 -0
|
@@ -6,7 +6,7 @@ import type { SessionContract, SessionEntry } from "../domains/session/index.js"
|
|
|
6
6
|
import { toolPresentationPolicy } from "../tools/presentation.js";
|
|
7
7
|
import type { ChatLoop } from "./chat-loop.js";
|
|
8
8
|
import type { ChatPanel } from "./chat-panel.js";
|
|
9
|
-
import { bashExecutionEntryInput, parseEditorBashCommand } from "./editor-bash.js";
|
|
9
|
+
import { bashExecutionEntryInput, parseEditorBashCommand, unguardPastedEditorOperator } from "./editor-bash.js";
|
|
10
10
|
import {
|
|
11
11
|
formatSteerCandidates,
|
|
12
12
|
parseEditorSteerMention,
|
|
@@ -57,6 +57,8 @@ export interface EditorSubmitExpansion {
|
|
|
57
57
|
|
|
58
58
|
export interface EditorSubmitEditor {
|
|
59
59
|
getText(): string;
|
|
60
|
+
/** Draft spelling for an immediate send, including any editor provenance envelope. */
|
|
61
|
+
getTextForSubmit(): string;
|
|
60
62
|
setText(text: string): void;
|
|
61
63
|
addToHistory(text: string): void;
|
|
62
64
|
}
|
|
@@ -318,18 +320,19 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
318
320
|
submitEditorSteerMention(mention) !== "unhandled";
|
|
319
321
|
|
|
320
322
|
const submitEditorText = (text: string): void => {
|
|
321
|
-
const
|
|
323
|
+
const literalText = unguardPastedEditorOperator(text);
|
|
324
|
+
const trimmed = literalText.trim();
|
|
322
325
|
if (trimmed.length === 0) return;
|
|
323
326
|
deps.collapseLaunchpadBeforeSubmit?.();
|
|
324
327
|
if (parseEditorBashCommand(text)) {
|
|
325
328
|
if (!deps.chat.isStreaming() && !activeEditorBash) {
|
|
326
|
-
deps.editor.addToHistory(
|
|
329
|
+
deps.editor.addToHistory(literalText);
|
|
327
330
|
deps.editor.setText("");
|
|
328
331
|
} else {
|
|
329
332
|
// Pi Editor clears the buffer before invoking onSubmit. A command
|
|
330
333
|
// refused by either admission guard is still a draft, so put it back
|
|
331
334
|
// for the operator instead of silently discarding it.
|
|
332
|
-
deps.editor.setText(
|
|
335
|
+
deps.editor.setText(literalText);
|
|
333
336
|
}
|
|
334
337
|
if (runEditorBash(text)) deps.ui.requestRender();
|
|
335
338
|
return;
|
|
@@ -339,12 +342,12 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
339
342
|
const submission = submitEditorSteerMention(steerMention);
|
|
340
343
|
if (submission !== "unhandled") {
|
|
341
344
|
if (submission === "accepted") {
|
|
342
|
-
deps.editor.addToHistory(
|
|
345
|
+
deps.editor.addToHistory(literalText);
|
|
343
346
|
deps.editor.setText("");
|
|
344
347
|
} else {
|
|
345
348
|
// Resolution and dispatch failures are correctable rejections. Pi
|
|
346
349
|
// has already cleared the editor, so explicitly restore the draft.
|
|
347
|
-
deps.editor.setText(
|
|
350
|
+
deps.editor.setText(literalText);
|
|
348
351
|
}
|
|
349
352
|
deps.ui.requestRender();
|
|
350
353
|
return;
|
|
@@ -352,18 +355,18 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
352
355
|
}
|
|
353
356
|
const command = parseSlashCommand(trimmed);
|
|
354
357
|
if (isRejectedCommand(command)) {
|
|
355
|
-
deps.editor.setText(
|
|
358
|
+
deps.editor.setText(literalText);
|
|
356
359
|
deps.dispatchCommand(trimmed);
|
|
357
360
|
} else if (command.kind === "unknown-command") {
|
|
358
361
|
const result = deps.dispatchCommand(trimmed);
|
|
359
362
|
if (result === "rejected") {
|
|
360
|
-
deps.editor.setText(
|
|
363
|
+
deps.editor.setText(literalText);
|
|
361
364
|
} else {
|
|
362
|
-
deps.editor.addToHistory(
|
|
365
|
+
deps.editor.addToHistory(literalText);
|
|
363
366
|
deps.editor.setText("");
|
|
364
367
|
}
|
|
365
368
|
} else {
|
|
366
|
-
deps.editor.addToHistory(
|
|
369
|
+
deps.editor.addToHistory(literalText);
|
|
367
370
|
deps.editor.setText("");
|
|
368
371
|
deps.dispatchCommand(trimmed);
|
|
369
372
|
}
|
|
@@ -388,7 +391,8 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
388
391
|
};
|
|
389
392
|
|
|
390
393
|
const admitCapturedText = async (text: string, signal?: AbortSignal): Promise<void> => {
|
|
391
|
-
const
|
|
394
|
+
const literalText = unguardPastedEditorOperator(text);
|
|
395
|
+
const trimmed = literalText.trim();
|
|
392
396
|
if (trimmed.length === 0) return;
|
|
393
397
|
signal?.throwIfAborted();
|
|
394
398
|
deps.collapseLaunchpadBeforeSubmit?.();
|
|
@@ -396,7 +400,7 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
396
400
|
while (deps.chat.isStreaming()) await awaitWithAbort(deps.chat.whenSettled(), signal);
|
|
397
401
|
while (activeEditorBashSettlement) await awaitWithAbort(activeEditorBashSettlement, signal);
|
|
398
402
|
signal?.throwIfAborted();
|
|
399
|
-
deps.editor.addToHistory(
|
|
403
|
+
deps.editor.addToHistory(literalText);
|
|
400
404
|
runEditorBash(text);
|
|
401
405
|
deps.ui.requestRender();
|
|
402
406
|
return;
|
|
@@ -408,7 +412,7 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
408
412
|
if (submission === "rejected") {
|
|
409
413
|
throw new Error("queued boot steer was not admitted; preserving it for recovery");
|
|
410
414
|
}
|
|
411
|
-
deps.editor.addToHistory(
|
|
415
|
+
deps.editor.addToHistory(literalText);
|
|
412
416
|
deps.ui.requestRender();
|
|
413
417
|
return;
|
|
414
418
|
}
|
|
@@ -421,7 +425,7 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
421
425
|
deps.ui.requestRender();
|
|
422
426
|
throw new Error("queued boot command needs correction; preserving it for recovery");
|
|
423
427
|
}
|
|
424
|
-
deps.editor.addToHistory(
|
|
428
|
+
deps.editor.addToHistory(literalText);
|
|
425
429
|
signal?.throwIfAborted();
|
|
426
430
|
if (deps.dispatchCommandAsync) await deps.dispatchCommandAsync(trimmed, signal);
|
|
427
431
|
else deps.dispatchCommand(trimmed);
|
|
@@ -429,9 +433,10 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
429
433
|
};
|
|
430
434
|
|
|
431
435
|
const queueFollowUpFromEditor = (): void => {
|
|
432
|
-
const
|
|
436
|
+
const streaming = deps.chat.isStreaming();
|
|
437
|
+
const text = (streaming ? deps.editor.getText() : deps.editor.getTextForSubmit()).trim();
|
|
433
438
|
if (text.length === 0) return;
|
|
434
|
-
if (!
|
|
439
|
+
if (!streaming) {
|
|
435
440
|
deps.editor.setText("");
|
|
436
441
|
submitEditorText(text);
|
|
437
442
|
deps.ui.requestRender();
|
|
@@ -458,9 +463,10 @@ export function createEditorSubmitController(deps: EditorSubmitDeps): EditorSubm
|
|
|
458
463
|
};
|
|
459
464
|
|
|
460
465
|
const interruptFromEditor = (): void => {
|
|
461
|
-
const
|
|
466
|
+
const streaming = deps.chat.isStreaming();
|
|
467
|
+
const text = (streaming ? deps.editor.getText() : deps.editor.getTextForSubmit()).trim();
|
|
462
468
|
if (text.length === 0) return;
|
|
463
|
-
if (!
|
|
469
|
+
if (!streaming) {
|
|
464
470
|
deps.editor.setText("");
|
|
465
471
|
submitEditorText(text);
|
|
466
472
|
deps.ui.requestRender();
|
|
@@ -50,7 +50,7 @@ export function resolveExternalEditor(
|
|
|
50
50
|
|
|
51
51
|
export function editTextExternally(initialText: string, command: string | null): ExternalEditResult {
|
|
52
52
|
if (!command) return { ok: false, error: "no external editor configured; set VISUAL or EDITOR" };
|
|
53
|
-
const tmpFile = join(tmpdir(), `clio-editor-${process.pid}-${randomUUID()}.md`);
|
|
53
|
+
const tmpFile = join(tmpdir(), `clio-coder-editor-${process.pid}-${randomUUID()}.md`);
|
|
54
54
|
try {
|
|
55
55
|
writeFileSync(tmpFile, initialText, "utf8");
|
|
56
56
|
const result = runEditor(command, tmpFile);
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { open, readdir, stat } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
5
|
+
import { enumerateWorkspaceFilesAsync } from "../core/workspace-files.js";
|
|
6
|
+
import { fuzzyFilter, stripTerminalSequences } from "../engine/tui.js";
|
|
7
|
+
import { isEditorSteerTargetToken } from "./editor-steer.js";
|
|
8
|
+
|
|
9
|
+
const MAX_COMPLETION_ROWS = 40;
|
|
10
|
+
const PREVIEW_BYTES = 2048;
|
|
11
|
+
const PREVIEW_CHARS = 120;
|
|
12
|
+
const SNAPSHOT_TTL_MS = 2_000;
|
|
13
|
+
const GIT_OUTPUT_LIMIT_BYTES = 128 * 1024 * 1024;
|
|
14
|
+
|
|
15
|
+
export interface FileReferenceCompletionRequest {
|
|
16
|
+
/** Text after the active `@`, decoded when the reference is quoted. */
|
|
17
|
+
query: string;
|
|
18
|
+
signal: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FileReferenceCompletionValue {
|
|
22
|
+
id: string;
|
|
23
|
+
/** Complete inline reference spelling, including `@` and any quotes. */
|
|
24
|
+
value: string;
|
|
25
|
+
/** Workspace/path spelling without the leading `@` or a trailing slash. */
|
|
26
|
+
path: string;
|
|
27
|
+
label: string;
|
|
28
|
+
description: string;
|
|
29
|
+
isDirectory: boolean;
|
|
30
|
+
tracked: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type FileReferenceCompletionSource = (
|
|
34
|
+
request: FileReferenceCompletionRequest,
|
|
35
|
+
) => Promise<ReadonlyArray<FileReferenceCompletionValue>>;
|
|
36
|
+
|
|
37
|
+
export interface FileReferenceCompletionOptions {
|
|
38
|
+
basePath: string;
|
|
39
|
+
cacheTtlMs?: number;
|
|
40
|
+
/** Test/runtime seam; defaults to the repository's authoritative visible-file enumerator. */
|
|
41
|
+
listWorkspaceFiles?: (basePath: string) => Promise<ReadonlyArray<string>>;
|
|
42
|
+
/** Test/runtime seam; defaults to `git ls-files --cached`. */
|
|
43
|
+
listTrackedFiles?: (basePath: string) => Promise<ReadonlySet<string>>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface FileCandidate {
|
|
47
|
+
path: string;
|
|
48
|
+
absolutePath: string;
|
|
49
|
+
isDirectory: boolean;
|
|
50
|
+
tracked: boolean;
|
|
51
|
+
descendantFiles: number;
|
|
52
|
+
workspace: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface WorkspaceSnapshot {
|
|
56
|
+
candidates: FileCandidate[];
|
|
57
|
+
directories: ReadonlySet<string>;
|
|
58
|
+
trackedFiles: ReadonlySet<string>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function posixPath(path: string): string {
|
|
62
|
+
return sep === "\\" ? path.replaceAll("\\", "/") : path;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function safeRelativePath(path: string): string | null {
|
|
66
|
+
const normalized = posixPath(path).replace(/^\.\//u, "").replace(/\/$/u, "");
|
|
67
|
+
if (normalized.length === 0 || normalized.startsWith("/") || normalized.includes("\0") || /[\r\n]/u.test(normalized)) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const segments = normalized.split("/");
|
|
71
|
+
if (segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) return null;
|
|
72
|
+
return segments.join("/");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function gitTrackedFiles(basePath: string): Promise<ReadonlySet<string>> {
|
|
76
|
+
return new Promise((resolveTracked) => {
|
|
77
|
+
execFile(
|
|
78
|
+
"git",
|
|
79
|
+
["--literal-pathspecs", "ls-files", "-z", "--cached"],
|
|
80
|
+
{ cwd: basePath, encoding: "utf8", maxBuffer: GIT_OUTPUT_LIMIT_BYTES },
|
|
81
|
+
(error, stdout) => {
|
|
82
|
+
if (error) {
|
|
83
|
+
resolveTracked(new Set());
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const tracked = new Set<string>();
|
|
87
|
+
for (const raw of stdout.split("\0")) {
|
|
88
|
+
const normalized = safeRelativePath(raw);
|
|
89
|
+
if (normalized) tracked.add(normalized);
|
|
90
|
+
}
|
|
91
|
+
resolveTracked(tracked);
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function buildWorkspaceSnapshot(
|
|
98
|
+
basePath: string,
|
|
99
|
+
visibleFiles: ReadonlyArray<string>,
|
|
100
|
+
trackedFiles: ReadonlySet<string>,
|
|
101
|
+
): WorkspaceSnapshot {
|
|
102
|
+
const files: FileCandidate[] = [];
|
|
103
|
+
const directoryFacts = new Map<string, { tracked: boolean; descendantFiles: number }>();
|
|
104
|
+
for (const raw of visibleFiles) {
|
|
105
|
+
const path = safeRelativePath(raw);
|
|
106
|
+
if (!path) continue;
|
|
107
|
+
const tracked = trackedFiles.has(path);
|
|
108
|
+
files.push({
|
|
109
|
+
path,
|
|
110
|
+
absolutePath: join(basePath, path),
|
|
111
|
+
isDirectory: false,
|
|
112
|
+
tracked,
|
|
113
|
+
descendantFiles: 0,
|
|
114
|
+
workspace: true,
|
|
115
|
+
});
|
|
116
|
+
const segments = path.split("/");
|
|
117
|
+
for (let index = 1; index < segments.length; index += 1) {
|
|
118
|
+
const directory = segments.slice(0, index).join("/");
|
|
119
|
+
const facts = directoryFacts.get(directory) ?? { tracked: false, descendantFiles: 0 };
|
|
120
|
+
facts.tracked ||= tracked;
|
|
121
|
+
facts.descendantFiles += 1;
|
|
122
|
+
directoryFacts.set(directory, facts);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const directories = [...directoryFacts].map(
|
|
126
|
+
([path, facts]): FileCandidate => ({
|
|
127
|
+
path,
|
|
128
|
+
absolutePath: join(basePath, path),
|
|
129
|
+
isDirectory: true,
|
|
130
|
+
tracked: facts.tracked,
|
|
131
|
+
descendantFiles: facts.descendantFiles,
|
|
132
|
+
workspace: true,
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
return {
|
|
136
|
+
candidates: [...directories, ...files],
|
|
137
|
+
directories: new Set(directoryFacts.keys()),
|
|
138
|
+
trackedFiles,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function candidateParent(path: string): string {
|
|
143
|
+
const parent = posixPath(dirname(path));
|
|
144
|
+
return parent === "." ? "" : parent;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function fuzzyOrdered(candidates: ReadonlyArray<FileCandidate>, query: string): FileCandidate[] {
|
|
148
|
+
const buckets: FileCandidate[][] = [[], [], [], []];
|
|
149
|
+
for (const candidate of candidates) {
|
|
150
|
+
const bucket = candidate.tracked ? (candidate.isDirectory ? 0 : 1) : candidate.isDirectory ? 2 : 3;
|
|
151
|
+
buckets[bucket]?.push(candidate);
|
|
152
|
+
}
|
|
153
|
+
return buckets.flatMap((bucket) =>
|
|
154
|
+
fuzzyFilter(bucket, query, (candidate) => `${basename(candidate.path)} ${candidate.path}`),
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function workspaceCandidates(snapshot: WorkspaceSnapshot, rawQuery: string): FileCandidate[] {
|
|
159
|
+
const explicitDot = rawQuery.startsWith("./");
|
|
160
|
+
const query = explicitDot ? rawQuery.slice(2) : rawQuery;
|
|
161
|
+
const slash = query.lastIndexOf("/");
|
|
162
|
+
if (query.length === 0) {
|
|
163
|
+
return fuzzyOrdered(
|
|
164
|
+
snapshot.candidates
|
|
165
|
+
.filter((candidate) => candidateParent(candidate.path) === "")
|
|
166
|
+
.map((candidate) => (explicitDot ? { ...candidate, path: `./${candidate.path}` } : candidate)),
|
|
167
|
+
"",
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
if (slash >= 0) {
|
|
171
|
+
const parent = query.slice(0, slash);
|
|
172
|
+
const fragment = query.slice(slash + 1);
|
|
173
|
+
if (parent.length === 0 || snapshot.directories.has(parent)) {
|
|
174
|
+
const displayPrefix = explicitDot ? "./" : "";
|
|
175
|
+
return fuzzyOrdered(
|
|
176
|
+
snapshot.candidates
|
|
177
|
+
.filter((candidate) => candidateParent(candidate.path) === parent)
|
|
178
|
+
.map((candidate) => ({ ...candidate, path: `${displayPrefix}${candidate.path}` })),
|
|
179
|
+
fragment,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return fuzzyOrdered(
|
|
184
|
+
snapshot.candidates.map((candidate) => (explicitDot ? { ...candidate, path: `./${candidate.path}` } : candidate)),
|
|
185
|
+
query,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function explicitPathQuery(query: string): boolean {
|
|
190
|
+
return query.startsWith("../") || query.startsWith("~/") || query.startsWith("/");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function resolveDisplayBase(basePath: string, displayBase: string): string {
|
|
194
|
+
if (displayBase.startsWith("~/")) return resolve(homedir(), displayBase.slice(2));
|
|
195
|
+
if (displayBase.startsWith("/")) return resolve(displayBase);
|
|
196
|
+
return resolve(basePath, displayBase);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function workspaceRelative(basePath: string, absolutePath: string): string | null {
|
|
200
|
+
const candidate = posixPath(relative(basePath, absolutePath));
|
|
201
|
+
if (candidate.length === 0 || candidate === ".." || candidate.startsWith("../")) return null;
|
|
202
|
+
return safeRelativePath(candidate);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async function explicitCandidates(
|
|
206
|
+
basePath: string,
|
|
207
|
+
query: string,
|
|
208
|
+
trackedFiles: ReadonlySet<string>,
|
|
209
|
+
): Promise<FileCandidate[]> {
|
|
210
|
+
const slash = query.lastIndexOf("/");
|
|
211
|
+
if (slash < 0) return [];
|
|
212
|
+
const displayBase = query.slice(0, slash + 1);
|
|
213
|
+
const fragment = query.slice(slash + 1);
|
|
214
|
+
const directory = resolveDisplayBase(basePath, displayBase);
|
|
215
|
+
const candidates: FileCandidate[] = [];
|
|
216
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
217
|
+
if (entry.name === ".git" || /[\r\n\0]/u.test(entry.name)) continue;
|
|
218
|
+
const absolutePath = join(directory, entry.name);
|
|
219
|
+
let isDirectory = entry.isDirectory();
|
|
220
|
+
let isFile = entry.isFile();
|
|
221
|
+
if (!isDirectory && !isFile && entry.isSymbolicLink()) {
|
|
222
|
+
try {
|
|
223
|
+
const facts = await stat(absolutePath);
|
|
224
|
+
isDirectory = facts.isDirectory();
|
|
225
|
+
isFile = facts.isFile();
|
|
226
|
+
} catch {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (!isDirectory && !isFile) continue;
|
|
231
|
+
const relativePath = workspaceRelative(basePath, absolutePath);
|
|
232
|
+
candidates.push({
|
|
233
|
+
path: `${displayBase}${entry.name}`,
|
|
234
|
+
absolutePath,
|
|
235
|
+
isDirectory,
|
|
236
|
+
tracked: relativePath !== null && trackedFiles.has(relativePath),
|
|
237
|
+
descendantFiles: 0,
|
|
238
|
+
workspace: relativePath !== null,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return fuzzyOrdered(candidates, fragment);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function formatBytes(bytes: number): string {
|
|
245
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
246
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(bytes < 10 * 1024 ? 1 : 0)}KB`;
|
|
247
|
+
return `${(bytes / (1024 * 1024)).toFixed(bytes < 10 * 1024 * 1024 ? 1 : 0)}MB`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function cleanPreview(bytes: Buffer): string | null {
|
|
251
|
+
if (bytes.includes(0)) return "binary file";
|
|
252
|
+
const text = stripTerminalSequences(bytes.toString("utf8"));
|
|
253
|
+
const line = text
|
|
254
|
+
.split(/\r?\n/u)
|
|
255
|
+
.map((candidate) =>
|
|
256
|
+
Array.from(candidate, (character) => {
|
|
257
|
+
const code = character.codePointAt(0) ?? 0;
|
|
258
|
+
return code < 32 || code === 127 ? " " : character;
|
|
259
|
+
})
|
|
260
|
+
.join("")
|
|
261
|
+
.trim(),
|
|
262
|
+
)
|
|
263
|
+
.find((candidate) => candidate.length > 0);
|
|
264
|
+
if (!line) return null;
|
|
265
|
+
return line.length > PREVIEW_CHARS ? `${line.slice(0, PREVIEW_CHARS - 1)}…` : line;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function candidateDescription(candidate: FileCandidate): Promise<string> {
|
|
269
|
+
const provenance = candidate.tracked ? "git tracked" : candidate.workspace ? "untracked" : "filesystem";
|
|
270
|
+
if (candidate.isDirectory) {
|
|
271
|
+
const count = candidate.descendantFiles > 0 ? ` · ${candidate.descendantFiles} files` : "";
|
|
272
|
+
return `${provenance} directory${count} · Tab/Enter opens`;
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
const facts = await stat(candidate.absolutePath);
|
|
276
|
+
const handle = await open(candidate.absolutePath, "r");
|
|
277
|
+
let preview: string | null = null;
|
|
278
|
+
try {
|
|
279
|
+
const buffer = Buffer.alloc(Math.min(PREVIEW_BYTES, Math.max(0, facts.size)));
|
|
280
|
+
if (buffer.length > 0) {
|
|
281
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
282
|
+
preview = cleanPreview(buffer.subarray(0, bytesRead));
|
|
283
|
+
}
|
|
284
|
+
} finally {
|
|
285
|
+
await handle.close();
|
|
286
|
+
}
|
|
287
|
+
return `${provenance} · ${formatBytes(facts.size)}${preview ? ` · ${preview}` : ""}`;
|
|
288
|
+
} catch {
|
|
289
|
+
return `${provenance} · preview unavailable`;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** Quote a completion exactly the way the inline-reference scanner accepts. */
|
|
294
|
+
function formatInlineFileReference(path: string, isDirectory: boolean): string {
|
|
295
|
+
const completionPath = isDirectory ? `${path.replace(/\/$/u, "")}/` : path;
|
|
296
|
+
if (!/[\s"'\\]/u.test(completionPath) && !isEditorSteerTargetToken(completionPath)) return `@${completionPath}`;
|
|
297
|
+
return `@"${completionPath.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function completionId(candidate: FileCandidate): string {
|
|
301
|
+
return `file-reference:${candidate.isDirectory ? "directory" : "file"}:${candidate.absolutePath}`;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Workspace-aware `@` source for Clio's one grammar-aware composer provider.
|
|
306
|
+
* A bare `@` is a top-level tree; text without a slash fuzzes the whole
|
|
307
|
+
* workspace; a real directory prefix becomes its child submenu. Explicit
|
|
308
|
+
* `../`, `~/`, and absolute prefixes stay scoped filesystem navigation.
|
|
309
|
+
*/
|
|
310
|
+
export function createFileReferenceCompletionSource(
|
|
311
|
+
options: FileReferenceCompletionOptions,
|
|
312
|
+
): FileReferenceCompletionSource {
|
|
313
|
+
const basePath = resolve(options.basePath);
|
|
314
|
+
const listWorkspaceFiles = options.listWorkspaceFiles ?? ((cwd: string) => enumerateWorkspaceFilesAsync(cwd));
|
|
315
|
+
const listTrackedFiles = options.listTrackedFiles ?? gitTrackedFiles;
|
|
316
|
+
const cacheTtlMs = options.cacheTtlMs ?? SNAPSHOT_TTL_MS;
|
|
317
|
+
let cached: { expiresAt: number; snapshot: WorkspaceSnapshot } | null = null;
|
|
318
|
+
let loading: Promise<WorkspaceSnapshot> | null = null;
|
|
319
|
+
|
|
320
|
+
const snapshot = async (): Promise<WorkspaceSnapshot> => {
|
|
321
|
+
const now = Date.now();
|
|
322
|
+
if (cached && cached.expiresAt > now) return cached.snapshot;
|
|
323
|
+
loading ??= Promise.all([listWorkspaceFiles(basePath), listTrackedFiles(basePath)]).then(([visible, tracked]) =>
|
|
324
|
+
buildWorkspaceSnapshot(basePath, visible, tracked),
|
|
325
|
+
);
|
|
326
|
+
try {
|
|
327
|
+
const next = await loading;
|
|
328
|
+
cached = { expiresAt: now + cacheTtlMs, snapshot: next };
|
|
329
|
+
return next;
|
|
330
|
+
} finally {
|
|
331
|
+
loading = null;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
return async (request) => {
|
|
336
|
+
if (request.signal.aborted) return [];
|
|
337
|
+
try {
|
|
338
|
+
const workspace = await snapshot();
|
|
339
|
+
if (request.signal.aborted) return [];
|
|
340
|
+
const candidates = explicitPathQuery(request.query)
|
|
341
|
+
? await explicitCandidates(basePath, request.query, workspace.trackedFiles)
|
|
342
|
+
: workspaceCandidates(workspace, request.query);
|
|
343
|
+
if (request.signal.aborted) return [];
|
|
344
|
+
const top = candidates.slice(0, MAX_COMPLETION_ROWS);
|
|
345
|
+
const descriptions = await Promise.all(top.map(candidateDescription));
|
|
346
|
+
if (request.signal.aborted) return [];
|
|
347
|
+
return top.map((candidate, index) => ({
|
|
348
|
+
id: completionId(candidate),
|
|
349
|
+
value: formatInlineFileReference(candidate.path, candidate.isDirectory),
|
|
350
|
+
path: candidate.path,
|
|
351
|
+
label: `${candidate.path}${candidate.isDirectory ? "/" : ""}`,
|
|
352
|
+
description: descriptions[index] ?? "preview unavailable",
|
|
353
|
+
isDirectory: candidate.isDirectory,
|
|
354
|
+
tracked: candidate.tracked,
|
|
355
|
+
}));
|
|
356
|
+
} catch {
|
|
357
|
+
return [];
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
}
|
|
@@ -208,7 +208,7 @@ function renderFooterDashboardLines(
|
|
|
208
208
|
* Widths from 80 to 119 columns use a two by two grid.
|
|
209
209
|
* Widths below 80 columns use a vertical stack with all sections retained.
|
|
210
210
|
*/
|
|
211
|
-
|
|
211
|
+
function renderFooterStatusLines(state: FooterDashboardRenderState, width: number): string[] {
|
|
212
212
|
const theme = clioTheme();
|
|
213
213
|
const safeWidth = Math.max(1, Math.floor(width));
|
|
214
214
|
const header = headerLine(state.session, safeWidth);
|
|
@@ -297,7 +297,7 @@ export function renderFooterStatusLines(state: FooterDashboardRenderState, width
|
|
|
297
297
|
* current work the strongest column; surplus is shared by urgency until the
|
|
298
298
|
* lower-priority sections reach their caps, then spills into Activity.
|
|
299
299
|
*/
|
|
300
|
-
|
|
300
|
+
function expandedWideColumnWidths(width: number, totalSepWidth: number): [number, number, number, number] {
|
|
301
301
|
const available = Math.max(0, width - totalSepWidth);
|
|
302
302
|
const widths: [number, number, number, number] = [32, 31, 27, 21];
|
|
303
303
|
let remaining = Math.max(0, available - widths.reduce((sum, item) => sum + item, 0));
|
|
@@ -392,33 +392,31 @@ export function buildFooterDashboard(deps: FooterDashboardDeps): FooterDashboard
|
|
|
392
392
|
const tokensLabel = tokens || (usage?.totalTokens ? `Σ${formatFooterTokens(usage.totalTokens)}` : null);
|
|
393
393
|
|
|
394
394
|
const statuses = deps.providers.list();
|
|
395
|
-
const current = settings?.
|
|
396
|
-
? (statuses.find((s) => s.target.id === settings.orchestrator?.target) ?? null)
|
|
397
|
-
: null;
|
|
395
|
+
const current = settings?.chat?.target ? (statuses.find((s) => s.target.id === settings.chat?.target) ?? null) : null;
|
|
398
396
|
|
|
399
|
-
const target = formatTargetLabel(settings?.
|
|
397
|
+
const target = formatTargetLabel(settings?.chat?.target, settings?.chat?.model);
|
|
400
398
|
|
|
401
399
|
const resolution = resolveModelRuntimeCapabilitiesForProviders(
|
|
402
400
|
deps.providers,
|
|
403
|
-
settings?.
|
|
404
|
-
settings?.
|
|
405
|
-
settings?.
|
|
401
|
+
settings?.chat?.target,
|
|
402
|
+
settings?.chat?.model,
|
|
403
|
+
settings?.chat?.thinkingLevel ?? "off",
|
|
406
404
|
);
|
|
407
405
|
|
|
408
|
-
const thinking = resolution?.thinking.display ?? settings?.
|
|
406
|
+
const thinking = resolution?.thinking.display ?? settings?.chat?.thinkingLevel ?? "off";
|
|
409
407
|
|
|
410
|
-
const wireModelId = settings?.
|
|
408
|
+
const wireModelId = settings?.chat?.model ?? current?.target.defaultModel ?? null;
|
|
411
409
|
const detectedReasoning =
|
|
412
410
|
wireModelId && typeof deps.providers.getDetectedReasoning === "function"
|
|
413
|
-
? deps.providers.getDetectedReasoning(settings?.
|
|
411
|
+
? deps.providers.getDetectedReasoning(settings?.chat?.target ?? "", wireModelId)
|
|
414
412
|
: null;
|
|
415
413
|
const caps = current
|
|
416
414
|
? resolveModelCapabilities(current, wireModelId, deps.providers.knowledgeBase, { detectedReasoning })
|
|
417
415
|
: null;
|
|
418
416
|
const capabilities = capabilityLabels(caps);
|
|
419
417
|
|
|
420
|
-
const safety = settings?.autonomy ?? "auto-edit";
|
|
421
|
-
const toolProfile = settings?.
|
|
418
|
+
const safety = settings?.safety.autonomy ?? "auto-edit";
|
|
419
|
+
const toolProfile = settings?.integrations.externalAgents?.defaults?.toolGovernance ?? "clio-coder-policy";
|
|
422
420
|
|
|
423
421
|
return {
|
|
424
422
|
workspace: workspaceFacts(deps, branchSlot),
|
|
@@ -436,7 +434,7 @@ export function buildFooterDashboard(deps: FooterDashboardDeps): FooterDashboard
|
|
|
436
434
|
capabilities,
|
|
437
435
|
safety,
|
|
438
436
|
toolProfile,
|
|
439
|
-
outputVerbosity: settings?.
|
|
437
|
+
outputVerbosity: settings?.interface.outputDetail ?? "default",
|
|
440
438
|
leaderArmed: deps.getLeaderArmed?.() ?? false,
|
|
441
439
|
shutdownArmed: deps.getShutdownArmed?.() ?? false,
|
|
442
440
|
memoryIntervention: taskMemory
|
|
@@ -454,8 +452,8 @@ export function buildFooterDashboard(deps: FooterDashboardDeps): FooterDashboard
|
|
|
454
452
|
used: contextUsage?.tokens ?? null,
|
|
455
453
|
contextWindow: contextUsage?.contextWindow ?? null,
|
|
456
454
|
toolSchemaTokens: contextUsage?.breakdown?.toolSchemaTokens ?? null,
|
|
457
|
-
compactionThreshold: settings?.compaction?.threshold ?? null,
|
|
458
|
-
compactionAuto: settings?.compaction?.auto ?? null,
|
|
455
|
+
compactionThreshold: settings?.context.compaction?.threshold ?? null,
|
|
456
|
+
compactionAuto: settings?.context.compaction?.auto ?? null,
|
|
459
457
|
compactionActive,
|
|
460
458
|
clioMd: formatClioMdState(contextState?.clioMd),
|
|
461
459
|
memory: formatMemoryState(contextState?.memoryCount),
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* color lives in `theme/**`; every emitted line is width-clamped.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { truncateToWidth, visibleWidth } from "../../engine/tui.js";
|
|
17
|
+
import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "../../engine/tui.js";
|
|
18
18
|
import { fitFooterText } from "../footer-panel.js";
|
|
19
19
|
import { type ClioTheme, type ClioToken, clioTheme, GLYPH, rule } from "../theme/index.js";
|
|
20
20
|
|
|
@@ -152,7 +152,7 @@ function boundNotifyBytes(text: string, maxBytes: number): string {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
/** The closed-vocabulary body for one event. */
|
|
155
|
-
|
|
155
|
+
function desktopNotifyBody(event: DesktopNotifyEvent): string {
|
|
156
156
|
if (event.kind === "turn-finished") return "turn finished";
|
|
157
157
|
if (event.kind === "approval-needed") return "approval needed";
|
|
158
158
|
const shortId = boundNotifyBytes(sanitizeNotifyText(event.shortId), 32);
|
|
@@ -160,7 +160,7 @@ export function desktopNotifyBody(event: DesktopNotifyEvent): string {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
/** True when the environment names a terminal that answers OSC 9 rather than OSC 777. */
|
|
163
|
-
|
|
163
|
+
function prefersOsc9(env: Readonly<Record<string, string | undefined>>): boolean {
|
|
164
164
|
if (typeof env.WT_SESSION === "string" && env.WT_SESSION.length > 0) return true;
|
|
165
165
|
const program = (env.TERM_PROGRAM ?? "").trim().toLowerCase();
|
|
166
166
|
if (program.length === 0) return false;
|
|
@@ -173,7 +173,7 @@ export function prefersOsc9(env: Readonly<Record<string, string | undefined>>):
|
|
|
173
173
|
* chosen for the terminals that implement it instead. Exactly one sequence is
|
|
174
174
|
* returned, so a single event can never produce two notifications.
|
|
175
175
|
*/
|
|
176
|
-
|
|
176
|
+
function buildDesktopNotifySequence(
|
|
177
177
|
event: DesktopNotifyEvent,
|
|
178
178
|
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
179
179
|
): string {
|
|
@@ -208,7 +208,7 @@ export interface DesktopNotifier {
|
|
|
208
208
|
* events. Every call re-checks the setting and the surface, so turning
|
|
209
209
|
* `terminal.notify` off mid-session silences the next event.
|
|
210
210
|
*/
|
|
211
|
-
|
|
211
|
+
function createDesktopNotifier(deps: DesktopNotifierDeps): DesktopNotifier {
|
|
212
212
|
const env = deps.env ?? process.env;
|
|
213
213
|
return {
|
|
214
214
|
notify(event) {
|
|
@@ -470,8 +470,9 @@ export function formatNotificationBadge(
|
|
|
470
470
|
}
|
|
471
471
|
|
|
472
472
|
/**
|
|
473
|
-
* Expanded notices panel for the dashboard.
|
|
474
|
-
*
|
|
473
|
+
* Expanded notices panel for the dashboard. The entry count is capped so a
|
|
474
|
+
* noisy boot cannot take over the dashboard, but every included notice wraps
|
|
475
|
+
* in full: this is the detail surface that the compact badge points toward.
|
|
475
476
|
*/
|
|
476
477
|
export function formatNotificationPanel(
|
|
477
478
|
entries: ReadonlyArray<Notification>,
|
|
@@ -485,7 +486,12 @@ export function formatNotificationPanel(
|
|
|
485
486
|
const lines: string[] = [rule(theme, width, { left: "notices" })];
|
|
486
487
|
for (const entry of entries.slice(0, maxRows)) {
|
|
487
488
|
const glyph = theme.fg(notificationToken(entry.level), notificationGlyph(entry.level));
|
|
488
|
-
|
|
489
|
+
const prefix = `${glyph} `;
|
|
490
|
+
const prefixWidth = visibleWidth(prefix);
|
|
491
|
+
const wrapped = wrapTextWithAnsi(theme.fg("muted", entry.text), Math.max(1, width - prefixWidth));
|
|
492
|
+
lines.push(
|
|
493
|
+
...wrapped.map((line, index) => fitFooterText(`${index === 0 ? prefix : " ".repeat(prefixWidth)}${line}`, width)),
|
|
494
|
+
);
|
|
489
495
|
}
|
|
490
496
|
const overflow = entries.length - maxRows;
|
|
491
497
|
const hint = overflow > 0 ? `+${overflow} more · ${dismiss} dismiss` : `${dismiss} dismiss`;
|