@iowarp/clio-coder 0.3.8 → 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 +102 -0
- package/NOTICE +33 -0
- package/README.md +12 -3
- package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
- package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
- package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
- package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
- package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
- package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
- package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
- package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
- package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
- package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
- package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
- package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
- package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
- package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
- package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
- package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
- package/dist/chunk-BKFM6EJV.js +462 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
- package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/chunk-C2LTL2W6.js +2447 -0
- package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
- package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
- package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
- package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
- package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
- package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
- package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/chunk-GKF55TAZ.js +391 -0
- package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
- package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
- package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
- package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
- package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
- package/dist/chunk-HZHHCK24.js +1631 -0
- package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
- package/dist/chunk-IBEBSCYA.js +564 -0
- package/dist/chunk-IQ7KR472.js +362 -0
- package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
- package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
- package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
- package/dist/chunk-KMVISBZR.js +132 -0
- package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
- package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
- package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
- package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
- package/dist/chunk-NHLBIGRH.js +1506 -0
- package/dist/chunk-NQQH3YT7.js +302 -0
- package/dist/chunk-NYS75XW5.js +15 -0
- package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
- package/dist/{chunk-EMYUUSFG.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-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
- package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
- package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
- package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
- package/dist/chunk-SUCTJL45.js +45 -0
- package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
- package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
- package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
- package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
- package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
- package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
- package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
- package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
- package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
- package/dist/chunk-VO67MWHC.js +75 -0
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
- package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
- package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
- package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
- package/dist/chunk-X75E3D2N.js +686 -0
- package/dist/{chunk-VAWNZU7Z.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-Z2RR6MAK.js +127 -0
- package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
- package/dist/cli/index.js +47 -36
- package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
- package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
- 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-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
- package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
- package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
- package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
- package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
- package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
- package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
- package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
- package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
- package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
- package/dist/doctor-QOA5FNY5.js +313 -0
- package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
- package/dist/eval-inventory-SXH7PDKX.js +316 -0
- package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
- package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
- package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
- package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
- package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
- package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
- package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
- package/dist/fleet-inspect-VLY4S7QM.js +442 -0
- package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
- package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
- package/dist/fleet-verify-JFEL2L3H.js +175 -0
- package/dist/fleet-view-ZCON35AG.js +102 -0
- package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
- package/dist/install-XGLBQY5E.js +13 -0
- package/dist/interop-OZBKXAYL.js +114 -0
- package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
- package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
- package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
- package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
- package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
- 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-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
- package/dist/resources-BB3MVJMD.js +111 -0
- package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
- package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
- package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
- package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
- package/dist/skills-inventory-S4MXPJFV.js +126 -0
- package/dist/slash-commands-ZSGASKJC.js +77 -0
- package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
- package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
- package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
- package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
- package/dist/tools-DAF3DI3C.js +27 -0
- package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
- package/dist/tui-primitives-2AKXQNZK.js +13 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
- package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
- package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
- package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
- package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
- package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
- package/dist/with-panes-MKB46MPQ.js +782 -0
- package/dist/worker/entry.js +106 -75
- 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 +9 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +62 -3
- package/docs/commands-and-modes.md +31 -2
- package/docs/configuration-and-targets.md +69 -12
- package/docs/context-engine.md +63 -4
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +5 -5
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +3 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +12 -11
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +27 -1
- package/docs/fleet-dispatch.md +25 -4
- 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 +55 -4
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +19 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +19 -3
- 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 +88 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +5 -2
- package/src/cli/acp.ts +6 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +25 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +23 -21
- package/src/cli/doctor-panes.ts +124 -0
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor-toolchain.ts +57 -0
- package/src/cli/doctor.ts +22 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +93 -16
- 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/extensions.ts +5 -1
- 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 +179 -39
- 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/targets.ts +44 -13
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +85 -5
- package/src/cli/usage.ts +63 -14
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/core/bus-events.ts +33 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/config.ts +67 -0
- package/src/core/defaults.ts +124 -8
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +80 -6
- 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 +6 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +52 -14
- package/src/domains/dispatch/capacity-lease.ts +118 -9
- package/src/domains/dispatch/contract.ts +11 -0
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/extension.ts +378 -82
- 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 +87 -4
- 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/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +22 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/reservation-store.ts +139 -11
- 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 +49 -1
- package/src/domains/dispatch/types.ts +13 -0
- package/src/domains/dispatch/validation.ts +33 -8
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
- package/src/domains/dispatch/write-boundary.ts +62 -1
- package/src/domains/eval/artifacts/store.ts +62 -0
- package/src/domains/eval/compare/behavioral.ts +224 -0
- package/src/domains/eval/compare/compare.ts +342 -2
- package/src/domains/eval/compare/envelope.ts +128 -0
- package/src/domains/eval/compare/gates.ts +24 -6
- package/src/domains/eval/compare/thresholds.ts +30 -3
- package/src/domains/eval/execution-provenance.ts +240 -0
- package/src/domains/eval/inventory.ts +113 -0
- package/src/domains/eval/metrics/aggregate.ts +136 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
- package/src/domains/eval/metrics/tracked.ts +413 -0
- package/src/domains/eval/provenance.ts +117 -0
- package/src/domains/eval/reports/comparison.ts +128 -0
- package/src/domains/eval/reports/junit.ts +17 -3
- package/src/domains/eval/reports/markdown.ts +3 -3
- package/src/domains/eval/reports/text.ts +14 -0
- package/src/domains/eval/run-compare.ts +20 -0
- package/src/domains/eval/runners/clio-run.ts +127 -0
- package/src/domains/eval/runners/external-command.ts +28 -3
- package/src/domains/eval/schema/adapter.ts +111 -0
- package/src/domains/eval/schema/artifact.ts +20 -0
- package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
- package/src/domains/eval/schema/behavioral.ts +520 -0
- package/src/domains/eval/schema/execution-envelope.ts +194 -0
- package/src/domains/eval/schema/serving.ts +105 -0
- package/src/domains/eval/schema/suite.ts +38 -8
- package/src/domains/eval/schema/validate.ts +58 -3
- package/src/domains/eval/schema/verdict.ts +237 -0
- package/src/domains/eval/suites/resolve.ts +2 -0
- package/src/domains/eval/suites/run.ts +264 -33
- package/src/domains/eval/verifiers/command.ts +2 -1
- package/src/domains/eval/workspaces/temp-copy.ts +145 -13
- package/src/domains/evidence/build.ts +2 -13
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/store.ts +6 -0
- package/src/domains/evidence/trust-projection.ts +2 -2
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +38 -3
- package/src/domains/extensions/resources.ts +1 -1
- package/src/domains/extensions/state.ts +12 -3
- package/src/domains/extensions/types.ts +2 -0
- package/src/domains/lifecycle/doctor.ts +69 -1
- package/src/domains/memory/index.ts +14 -1
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +82 -17
- package/src/domains/memory/task-memory-spend.ts +131 -0
- package/src/domains/memory/task-memory-status.ts +7 -0
- package/src/domains/memory/task-memory-telemetry.ts +3 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +97 -21
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- 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/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +22 -1
- package/src/domains/observability/index.ts +9 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +234 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/providers/endpoint-capacity.ts +228 -0
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +20 -3
- package/src/domains/providers/index.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +32 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
- package/src/domains/providers/runtime-resolution.ts +8 -1
- package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
- 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/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +95 -33
- package/src/domains/resources/skills/loader.ts +33 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/run-effects.ts +35 -4
- package/src/domains/session/context-accounting.ts +52 -1
- package/src/domains/session/context-ledger.ts +37 -13
- package/src/domains/session/index.ts +6 -0
- package/src/domains/session/prompt-cache.ts +140 -0
- package/src/domains/session/prompt-manifest.ts +42 -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/adapter.ts +18 -3
- package/src/engine/acp/server.ts +413 -70
- package/src/engine/acp/types.ts +19 -1
- package/src/engine/ai.ts +35 -0
- package/src/engine/apis/llamacpp-residency.ts +55 -3
- package/src/engine/apis/lmstudio.ts +25 -5
- package/src/engine/apis/ollama-native.ts +2 -1
- package/src/engine/apis/openai-completions.ts +80 -17
- package/src/engine/apis/residency-lock.ts +3 -1
- package/src/engine/apis/residency.ts +34 -1
- package/src/engine/claude/sdk-module.ts +98 -0
- package/src/engine/claude/sdk-runtime.ts +19 -11
- package/src/engine/provider-payload.ts +29 -1
- 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 +279 -35
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- package/src/interactive/chat-loop-messages.ts +26 -7
- package/src/interactive/chat-loop.ts +318 -41
- package/src/interactive/chat-panel.ts +62 -8
- package/src/interactive/clio-editor.ts +45 -8
- package/src/interactive/context-activity.ts +5 -1
- package/src/interactive/context-meter.ts +1 -1
- package/src/interactive/context-overlay.ts +41 -10
- package/src/interactive/cost-overlay.ts +66 -6
- package/src/interactive/council-grid.ts +1 -3
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +102 -20
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +177 -7
- package/src/interactive/interactive-input-runtime.ts +15 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +63 -10
- package/src/interactive/memory-overlay.ts +9 -0
- package/src/interactive/modal-marker.ts +170 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +58 -2
- package/src/interactive/overlay-general-openers.ts +17 -0
- package/src/interactive/overlay-key-routing.ts +52 -3
- package/src/interactive/overlay-lifecycle.ts +56 -7
- package/src/interactive/overlay-model-selectors.ts +40 -3
- package/src/interactive/overlay-permission-lifecycle.ts +112 -24
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +1 -0
- package/src/interactive/overlays/ask-user.ts +227 -49
- 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 +6 -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 +12 -1
- package/src/interactive/overlays/session-selector.ts +1 -0
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +614 -45
- 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/permission-hint.ts +34 -2
- package/src/interactive/permission-overlay.ts +159 -9
- package/src/interactive/prewarm.ts +197 -0
- package/src/interactive/render-trace.ts +162 -15
- package/src/interactive/renderers/compaction-summary.ts +29 -0
- package/src/interactive/renderers/tool-execution.ts +4 -0
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +251 -15
- package/src/interactive/status/controller.ts +11 -0
- package/src/interactive/status/state-machine.ts +54 -2
- package/src/interactive/status/types.ts +7 -0
- package/src/interactive/tasks-overlay.ts +1 -0
- package/src/interactive/terminal-lease.ts +2 -0
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +346 -33
- package/src/interactive/turn-persistence.ts +14 -4
- package/src/interactive/turn-prewarm.ts +364 -0
- package/src/interactive/turn-queues.ts +7 -4
- package/src/interactive/turn-runtime.ts +8 -1
- package/src/interactive/turn-state.ts +23 -0
- package/src/interactive/view/artifacts.ts +109 -1
- package/src/interactive/view/view-overlay.ts +29 -3
- 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/ask-user.ts +43 -2
- 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-plan.ts +17 -9
- package/src/tools/dispatch-run-events.ts +134 -19
- package/src/tools/dispatch-runner.ts +29 -7
- package/src/tools/dispatch-scout.ts +1 -1
- 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/src/tools/registry.ts +16 -0
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HLE42MG7.js +0 -37
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-JOZYP4GM.js +0 -279
- package/dist/doctor-M7YEDGAE.js +0 -91
|
@@ -18,7 +18,13 @@ import {
|
|
|
18
18
|
} from "../../engine/tui.js";
|
|
19
19
|
import type { AskUserAnswer, AskUserQuestion, AskUserResult } from "../../tools/ask-user.js";
|
|
20
20
|
import { ASK_USER_OTHER_LABEL, cancelledAskUserResult } from "../../tools/ask-user.js";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
buildHint,
|
|
23
|
+
DEFAULT_SELECT_THEME,
|
|
24
|
+
type HintEntry,
|
|
25
|
+
type OverlayEscVerb,
|
|
26
|
+
showClioOverlayFrame,
|
|
27
|
+
} from "../overlay-frame.js";
|
|
22
28
|
import { type ClioToken, clioTheme, dotSep, GLYPH, screenTitle } from "../theme/index.js";
|
|
23
29
|
import { nextContentScrollOffset, type ViewScrollAction } from "../view/view-overlay.js";
|
|
24
30
|
|
|
@@ -91,6 +97,8 @@ const MIN_VISIBLE_OPTIONS = 3;
|
|
|
91
97
|
/** Interview rows spent on chrome before an option row: strip, header, blanks, status, one question row. */
|
|
92
98
|
const INTERVIEW_CHROME_ROWS = 7;
|
|
93
99
|
const MAX_VISIBLE_OPTIONS = 12;
|
|
100
|
+
/** Below this the second column is too narrow to wrap a sentence into. */
|
|
101
|
+
const MIN_DESCRIPTION_COLUMN = 28;
|
|
94
102
|
const ELLIPSIS = "…";
|
|
95
103
|
|
|
96
104
|
/**
|
|
@@ -129,6 +137,14 @@ interface QuestionState {
|
|
|
129
137
|
customAnswer: string;
|
|
130
138
|
inputValue: string;
|
|
131
139
|
answer: string;
|
|
140
|
+
/**
|
|
141
|
+
* The operator's typed text exactly as submitted, empty when they typed
|
|
142
|
+
* nothing. `answer` is the one-line rendering of the whole decision and gets
|
|
143
|
+
* trimmed and joined; this is the record of what they actually typed, and
|
|
144
|
+
* losing it is what made an interview re-ask for the same figures three times
|
|
145
|
+
* (issue #228).
|
|
146
|
+
*/
|
|
147
|
+
rawValue: string;
|
|
132
148
|
focusedValue?: string;
|
|
133
149
|
}
|
|
134
150
|
|
|
@@ -154,6 +170,7 @@ function createQuestionState(question: AskUserQuestion): QuestionState {
|
|
|
154
170
|
customAnswer: "",
|
|
155
171
|
inputValue: "",
|
|
156
172
|
answer: "",
|
|
173
|
+
rawValue: "",
|
|
157
174
|
};
|
|
158
175
|
}
|
|
159
176
|
|
|
@@ -205,12 +222,18 @@ function optionIndexFromValue(value: string): number | null {
|
|
|
205
222
|
return Number.isInteger(index) && index >= 0 ? index : null;
|
|
206
223
|
}
|
|
207
224
|
|
|
208
|
-
|
|
209
|
-
|
|
225
|
+
/** The labels the operator chose, in list order. */
|
|
226
|
+
function selectedOptionLabels(question: AskUserQuestion, selected: ReadonlySet<number>): string[] {
|
|
227
|
+
const labels: string[] = [];
|
|
210
228
|
for (const index of [...selected].sort((a, b) => a - b)) {
|
|
211
229
|
const label = question.options?.[index]?.label;
|
|
212
|
-
if (label)
|
|
230
|
+
if (label) labels.push(label);
|
|
213
231
|
}
|
|
232
|
+
return labels;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function answerText(question: AskUserQuestion, selected: ReadonlySet<number>, customAnswer: string): string {
|
|
236
|
+
const parts = selectedOptionLabels(question, selected);
|
|
214
237
|
const custom = customAnswer.trim();
|
|
215
238
|
if (custom.length > 0) parts.push(custom);
|
|
216
239
|
return parts.join("; ");
|
|
@@ -348,6 +371,10 @@ class AskUserOverlayView implements Component {
|
|
|
348
371
|
this.commitMultiSelectOrOpenOther(state);
|
|
349
372
|
return;
|
|
350
373
|
}
|
|
374
|
+
if (this.isAddTextKey(data)) {
|
|
375
|
+
this.chooseFocusedAndOpenText(question, state);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
351
378
|
this.list?.handleInput(data);
|
|
352
379
|
}
|
|
353
380
|
|
|
@@ -492,34 +519,40 @@ class AskUserOverlayView implements Component {
|
|
|
492
519
|
this.presentation.requiredActions.find((action) => action.id === "record-answer")?.label.toLowerCase() ??
|
|
493
520
|
"record answer";
|
|
494
521
|
if (state.mode === "text") {
|
|
522
|
+
// Esc means two different things depending on what is behind the field.
|
|
523
|
+
// A question with options has a list to fall back to, so the key goes
|
|
524
|
+
// back; a question without one has nothing behind it and the key still
|
|
525
|
+
// leaves the interview. The footer says which one this is.
|
|
526
|
+
const escapeVerb: OverlayEscVerb = questionHasOptions(question) ? "back" : "close";
|
|
495
527
|
return this.questions.length > 1
|
|
496
|
-
? this.withScrollHint(
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
528
|
+
? this.withScrollHint(
|
|
529
|
+
[
|
|
530
|
+
{ key: "Enter", verb: recordAnswer },
|
|
531
|
+
{ key: "Alt+Left/Right", verb: "question" },
|
|
532
|
+
],
|
|
533
|
+
escapeVerb,
|
|
534
|
+
)
|
|
535
|
+
: this.withScrollHint([{ key: "Enter", verb: recordAnswer }], escapeVerb);
|
|
501
536
|
}
|
|
502
537
|
// The classified action label distinguishes recording an answer from
|
|
503
|
-
// granting authority. Esc
|
|
504
|
-
//
|
|
538
|
+
// granting authority. Esc on the option list is the way out of the whole
|
|
539
|
+
// interview, which is the one place the product spells `close`.
|
|
540
|
+
// `t` is on every select footer because the operator cannot tell from a
|
|
541
|
+
// label whether the option needs a figure attached until they read it.
|
|
542
|
+
const addText: HintEntry = { key: "t", verb: "add text", short: "text" };
|
|
505
543
|
if (question.multi_select === true) {
|
|
506
544
|
return this.questions.length > 1
|
|
507
545
|
? this.withScrollHint([
|
|
508
546
|
{ key: "Left/Right", verb: "question" },
|
|
509
547
|
{ key: "Space", verb: "toggle" },
|
|
548
|
+
addText,
|
|
510
549
|
{ key: "Enter", verb: recordAnswer },
|
|
511
550
|
])
|
|
512
|
-
: this.withScrollHint([
|
|
513
|
-
{ key: "Space", verb: "toggle" },
|
|
514
|
-
{ key: "Enter", verb: recordAnswer },
|
|
515
|
-
]);
|
|
551
|
+
: this.withScrollHint([{ key: "Space", verb: "toggle" }, addText, { key: "Enter", verb: recordAnswer }]);
|
|
516
552
|
}
|
|
517
553
|
return this.questions.length > 1
|
|
518
|
-
? this.withScrollHint([
|
|
519
|
-
|
|
520
|
-
{ key: "Enter", verb: recordAnswer },
|
|
521
|
-
])
|
|
522
|
-
: this.withScrollHint([{ key: "Enter", verb: recordAnswer }]);
|
|
554
|
+
? this.withScrollHint([{ key: "Left/Right", verb: "question" }, addText, { key: "Enter", verb: recordAnswer }])
|
|
555
|
+
: this.withScrollHint([addText, { key: "Enter", verb: recordAnswer }]);
|
|
523
556
|
}
|
|
524
557
|
|
|
525
558
|
private renderDecisionContext(width: number): string[] {
|
|
@@ -541,9 +574,9 @@ class AskUserOverlayView implements Component {
|
|
|
541
574
|
* scroll. A footer that always advertised PgUp would be advertising a key that
|
|
542
575
|
* does nothing on most rounds.
|
|
543
576
|
*/
|
|
544
|
-
private withScrollHint(entries: ReadonlyArray<HintEntry
|
|
545
|
-
if (this.surface !== "interview" || !this.contentOverflows) return buildHint(entries);
|
|
546
|
-
return buildHint([...entries, { key: "PgUp/PgDn", verb: "scroll" }]);
|
|
577
|
+
private withScrollHint(entries: ReadonlyArray<HintEntry>, esc: OverlayEscVerb = "close"): string {
|
|
578
|
+
if (this.surface !== "interview" || !this.contentOverflows) return buildHint(entries, esc);
|
|
579
|
+
return buildHint([...entries, { key: "PgUp/PgDn", verb: "scroll" }], esc);
|
|
547
580
|
}
|
|
548
581
|
|
|
549
582
|
private setSurface(next: AskUserSurface): void {
|
|
@@ -644,6 +677,34 @@ class AskUserOverlayView implements Component {
|
|
|
644
677
|
return this.questions.length > 1 && (matchesKey(data, "alt+right") || matchesKey(data, "ctrl+right"));
|
|
645
678
|
}
|
|
646
679
|
|
|
680
|
+
/**
|
|
681
|
+
* The key that adds typed text to the option under the cursor.
|
|
682
|
+
*
|
|
683
|
+
* Choosing an option used to be the whole answer, so a model that offered
|
|
684
|
+
* "Exact number - I'll type it" gave the operator a label and nowhere to put
|
|
685
|
+
* the number; the interview then spent two of its four rounds asking for the
|
|
686
|
+
* figures again (issue #228). The list itself only reads the arrows, Enter,
|
|
687
|
+
* and Esc, so a letter is free here.
|
|
688
|
+
*/
|
|
689
|
+
private isAddTextKey(data: string): boolean {
|
|
690
|
+
return matchesKey(data, "t");
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Take the focused option and open the text field for it, without committing.
|
|
695
|
+
* Submitting the text records the label and the text together.
|
|
696
|
+
*/
|
|
697
|
+
private chooseFocusedAndOpenText(question: AskUserQuestion, state: QuestionState): void {
|
|
698
|
+
const current = this.list?.getSelectedItem();
|
|
699
|
+
const optionIndex = current && current.value !== "other" ? optionIndexFromValue(current.value) : null;
|
|
700
|
+
if (optionIndex !== null) {
|
|
701
|
+
if (question.multi_select === true) state.selected.add(optionIndex);
|
|
702
|
+
else state.selected = new Set<number>([optionIndex]);
|
|
703
|
+
state.focusedValue = `option:${optionIndex}`;
|
|
704
|
+
}
|
|
705
|
+
this.openTextInput(state.selected.size > 0 ? "Add your answer to the chosen option" : "Other answer");
|
|
706
|
+
}
|
|
707
|
+
|
|
647
708
|
/**
|
|
648
709
|
* The row above the question, or nothing.
|
|
649
710
|
*
|
|
@@ -739,17 +800,29 @@ class AskUserOverlayView implements Component {
|
|
|
739
800
|
0,
|
|
740
801
|
items.findIndex((item) => item.value === selectedItem.value),
|
|
741
802
|
);
|
|
742
|
-
const
|
|
803
|
+
const primaryColumnWidth = this.primaryColumnWidth(items, width);
|
|
804
|
+
const acceptKey = question.multi_select === true ? "Space" : "Enter";
|
|
805
|
+
// The focused option's description wraps in full, so the rows it needs come
|
|
806
|
+
// out of the list rather than out of the sentence. Options the operator
|
|
807
|
+
// cannot currently read are what a windowed list is for, and one arrow key
|
|
808
|
+
// brings any of them back; a cut explanation has no such recovery.
|
|
809
|
+
const focusedRows = this.renderOptionRow(
|
|
810
|
+
items[selectedIndex] as SelectItem,
|
|
811
|
+
true,
|
|
812
|
+
width,
|
|
813
|
+
primaryColumnWidth,
|
|
814
|
+
acceptKey,
|
|
815
|
+
).length;
|
|
816
|
+
const budget = Math.max(1, this.maxVisibleOptions() - (focusedRows - 1));
|
|
817
|
+
const visibleCount = Math.min(budget, Math.max(1, items.length));
|
|
743
818
|
const start = Math.max(0, Math.min(selectedIndex - Math.floor(visibleCount / 2), items.length - visibleCount));
|
|
744
819
|
const end = Math.min(items.length, start + visibleCount);
|
|
745
|
-
const primaryColumnWidth = this.primaryColumnWidth(items, width);
|
|
746
820
|
const lines: string[] = [];
|
|
747
821
|
|
|
748
|
-
const acceptKey = question.multi_select === true ? "Space" : "Enter";
|
|
749
822
|
for (let index = start; index < end; index += 1) {
|
|
750
823
|
const item = items[index];
|
|
751
824
|
if (!item) continue;
|
|
752
|
-
lines.push(this.renderOptionRow(item, index === selectedIndex, width, primaryColumnWidth, acceptKey));
|
|
825
|
+
lines.push(...this.renderOptionRow(item, index === selectedIndex, width, primaryColumnWidth, acceptKey));
|
|
753
826
|
}
|
|
754
827
|
|
|
755
828
|
if (start > 0 || end < items.length) {
|
|
@@ -764,13 +837,22 @@ class AskUserOverlayView implements Component {
|
|
|
764
837
|
return Math.max(1, Math.min(bounded, Math.max(1, width - 4)));
|
|
765
838
|
}
|
|
766
839
|
|
|
840
|
+
/**
|
|
841
|
+
* One option, as the rows it needs.
|
|
842
|
+
*
|
|
843
|
+
* The focused option's description wraps under its own column and is never
|
|
844
|
+
* cut: a description is what the operator is choosing between, and half of
|
|
845
|
+
* one reads as the whole thing. An unfocused row stays a one-line table cell
|
|
846
|
+
* whose ellipsis says there is more, which the operator reads by moving to
|
|
847
|
+
* it.
|
|
848
|
+
*/
|
|
767
849
|
private renderOptionRow(
|
|
768
850
|
item: SelectItem,
|
|
769
851
|
selected: boolean,
|
|
770
852
|
width: number,
|
|
771
853
|
primaryColumnWidth: number,
|
|
772
854
|
acceptKey: string,
|
|
773
|
-
): string {
|
|
855
|
+
): string[] {
|
|
774
856
|
const theme = clioTheme();
|
|
775
857
|
const prefix = selected ? theme.fg("accent", `${GLYPH.cursor} `) : " ";
|
|
776
858
|
// The key that answers rides on the focused row. An operator whose eyes are
|
|
@@ -780,22 +862,40 @@ class AskUserOverlayView implements Component {
|
|
|
780
862
|
const available = Math.max(1, width - 2 - visibleWidth(affordance));
|
|
781
863
|
const description = item.description?.replace(/[\r\n]+/g, " ").trim();
|
|
782
864
|
|
|
783
|
-
|
|
784
|
-
if (description && width > 40) {
|
|
785
|
-
const labelWidth = Math.max(1, Math.min(primaryColumnWidth - 2, available - 4));
|
|
786
|
-
const label = truncateToWidth(item.label, labelWidth, ELLIPSIS, false);
|
|
787
|
-
const spacing = " ".repeat(Math.max(1, primaryColumnWidth - visibleWidth(label)));
|
|
788
|
-
const descriptionWidth = Math.max(1, available - visibleWidth(label) - visibleWidth(spacing));
|
|
789
|
-
const desc = truncateToWidth(description, descriptionWidth, ELLIPSIS, false);
|
|
790
|
-
body = selected
|
|
791
|
-
? theme.style("accent", `${label}${spacing}${desc}`, { bold: true })
|
|
792
|
-
: `${label}${theme.fg("muted", `${spacing}${desc}`)}`;
|
|
793
|
-
} else {
|
|
865
|
+
if (!description || width <= 40) {
|
|
794
866
|
const label = truncateToWidth(item.label, available, ELLIPSIS, false);
|
|
795
|
-
body = selected ? theme.style("accent", label, { bold: true }) : label;
|
|
867
|
+
const body = selected ? theme.style("accent", label, { bold: true }) : label;
|
|
868
|
+
return [fitLine(`${prefix}${body}${affordance}`, width)];
|
|
796
869
|
}
|
|
797
870
|
|
|
798
|
-
|
|
871
|
+
const labelWidth = Math.max(1, Math.min(primaryColumnWidth - 2, available - 4));
|
|
872
|
+
const label = truncateToWidth(item.label, labelWidth, ELLIPSIS, false);
|
|
873
|
+
const spacing = " ".repeat(Math.max(1, primaryColumnWidth - visibleWidth(label)));
|
|
874
|
+
const descriptionWidth = Math.max(1, available - visibleWidth(label) - visibleWidth(spacing));
|
|
875
|
+
if (!selected) {
|
|
876
|
+
const desc = truncateToWidth(description, descriptionWidth, ELLIPSIS, false);
|
|
877
|
+
return [fitLine(`${prefix}${label}${theme.fg("muted", `${spacing}${desc}`)}`, width)];
|
|
878
|
+
}
|
|
879
|
+
// A gutter this narrow wraps a sentence into slivers and breaks words, so
|
|
880
|
+
// below the floor the description drops to its own full-width lines under
|
|
881
|
+
// the label instead of squeezing into the second column.
|
|
882
|
+
if (descriptionWidth < MIN_DESCRIPTION_COLUMN) {
|
|
883
|
+
const indent = " ";
|
|
884
|
+
const body = theme.style("accent", label, { bold: true });
|
|
885
|
+
return [
|
|
886
|
+
fitLine(`${prefix}${body}${affordance}`, width),
|
|
887
|
+
...wrapTextWithAnsi(description, Math.max(1, width - indent.length)).map((line) =>
|
|
888
|
+
fitLine(`${indent}${theme.style("accent", line, { bold: true })}`, width),
|
|
889
|
+
),
|
|
890
|
+
];
|
|
891
|
+
}
|
|
892
|
+
const wrapped = wrapTextWithAnsi(description, descriptionWidth);
|
|
893
|
+
const head = wrapped[0] ?? "";
|
|
894
|
+
const indent = " ".repeat(visibleWidth(prefix) + visibleWidth(label) + visibleWidth(spacing));
|
|
895
|
+
return [
|
|
896
|
+
fitLine(`${prefix}${theme.style("accent", `${label}${spacing}${head}`, { bold: true })}${affordance}`, width),
|
|
897
|
+
...wrapped.slice(1).map((line) => fitLine(`${indent}${theme.style("accent", line, { bold: true })}`, width)),
|
|
898
|
+
];
|
|
799
899
|
}
|
|
800
900
|
|
|
801
901
|
private ensureControl(): void {
|
|
@@ -829,16 +929,22 @@ class AskUserOverlayView implements Component {
|
|
|
829
929
|
return;
|
|
830
930
|
}
|
|
831
931
|
state.inputValue = answer;
|
|
932
|
+
// Verbatim, before any joining or trimming the display line does. The
|
|
933
|
+
// typed text is the answer; the one-line `answer` is a rendering of it.
|
|
934
|
+
state.rawValue = value;
|
|
832
935
|
if (questionHasOptions(question) && question.multi_select === true) {
|
|
833
936
|
state.customAnswer = answer;
|
|
834
937
|
this.commitCurrentAnswer();
|
|
835
|
-
|
|
836
|
-
state.customAnswer = questionHasOptions(question) ? answer : "";
|
|
837
|
-
state.answer = answer;
|
|
838
|
-
this.finishIfCompleteOrAdvance();
|
|
938
|
+
return;
|
|
839
939
|
}
|
|
940
|
+
state.customAnswer = questionHasOptions(question) ? answer : "";
|
|
941
|
+
// The chosen labels and the typed text compose, so a question answered
|
|
942
|
+
// with an option that says "I will type it" keeps both. With nothing
|
|
943
|
+
// selected, which is the implicit Other path, this is the text alone.
|
|
944
|
+
state.answer = questionHasOptions(question) ? answerText(question, state.selected, state.customAnswer) : answer;
|
|
945
|
+
this.finishIfCompleteOrAdvance();
|
|
840
946
|
};
|
|
841
|
-
activeInput.onEscape = () => this.
|
|
947
|
+
activeInput.onEscape = () => this.escapeFromTextInput(question, state);
|
|
842
948
|
this.input = activeInput;
|
|
843
949
|
this.list = null;
|
|
844
950
|
}
|
|
@@ -866,7 +972,14 @@ class AskUserOverlayView implements Component {
|
|
|
866
972
|
return;
|
|
867
973
|
}
|
|
868
974
|
state.selected = new Set<number>([optionIndex]);
|
|
869
|
-
|
|
975
|
+
// Choosing a plain option is a label-only answer, so the typed text
|
|
976
|
+
// clears with the choice: it was given for a label the operator has
|
|
977
|
+
// just moved off, and the composed answer runs through the same
|
|
978
|
+
// `answerText` every other path uses.
|
|
979
|
+
state.customAnswer = "";
|
|
980
|
+
state.rawValue = "";
|
|
981
|
+
state.inputValue = "";
|
|
982
|
+
state.answer = answerText(question, state.selected, state.customAnswer) || item.label;
|
|
870
983
|
state.focusedValue = item.value;
|
|
871
984
|
this.status = "";
|
|
872
985
|
this.finishIfCompleteOrAdvance();
|
|
@@ -902,6 +1015,53 @@ class AskUserOverlayView implements Component {
|
|
|
902
1015
|
return 0;
|
|
903
1016
|
}
|
|
904
1017
|
|
|
1018
|
+
/**
|
|
1019
|
+
* Esc in the text field.
|
|
1020
|
+
*
|
|
1021
|
+
* The field used to resolve the whole round as cancelled, which made a typed
|
|
1022
|
+
* draft unrecoverable: a single-question round had no other question to answer
|
|
1023
|
+
* first, so the only way off `t` was to abandon the interview (issue #260). A
|
|
1024
|
+
* question with options has a surface behind the field, so Esc goes back to it
|
|
1025
|
+
* and drops the draft. A question with no options has nothing behind it, so Esc
|
|
1026
|
+
* keeps its old meaning and leaves the interview; the footer says which.
|
|
1027
|
+
*
|
|
1028
|
+
* The draft is dropped rather than parked because Esc is the discard gesture.
|
|
1029
|
+
* It never reached `answer`, `options`, or `value` in the first place, since
|
|
1030
|
+
* only a submit writes those, so #228's clearing rule holds either way.
|
|
1031
|
+
*/
|
|
1032
|
+
private escapeFromTextInput(question: AskUserQuestion, state: QuestionState): void {
|
|
1033
|
+
if (!questionHasOptions(question)) {
|
|
1034
|
+
this.cancel();
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
state.inputValue = "";
|
|
1038
|
+
state.mode = "select";
|
|
1039
|
+
this.status = "";
|
|
1040
|
+
this.rebuildSelectList(question, state);
|
|
1041
|
+
this.deps.requestRender();
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* Leave a question the operator is walking away from on its option list.
|
|
1046
|
+
*
|
|
1047
|
+
* The mode used to belong to the question for the rest of the round, so a
|
|
1048
|
+
* question opened with `t` came back as a prefilled field however the operator
|
|
1049
|
+
* returned to it, and the option list was gone for good. Navigating away is not
|
|
1050
|
+
* the discard gesture, so the draft stays in `inputValue` and `t` finds it
|
|
1051
|
+
* again; what does not survive is the field being the thing that greets them.
|
|
1052
|
+
*
|
|
1053
|
+
* A question whose value was actually submitted keeps its field, because
|
|
1054
|
+
* coming back to a recorded figure is how it gets revised (issue #228).
|
|
1055
|
+
*/
|
|
1056
|
+
private parkTextMode(): void {
|
|
1057
|
+
const question = this.currentQuestion();
|
|
1058
|
+
const state = this.currentState();
|
|
1059
|
+
if (!question || !state) return;
|
|
1060
|
+
if (state.mode !== "text" || !questionHasOptions(question)) return;
|
|
1061
|
+
if (state.rawValue.length > 0) return;
|
|
1062
|
+
state.mode = "select";
|
|
1063
|
+
}
|
|
1064
|
+
|
|
905
1065
|
private openTextInput(nextStatus: string): void {
|
|
906
1066
|
const state = this.currentState();
|
|
907
1067
|
const question = this.currentQuestion();
|
|
@@ -992,12 +1152,26 @@ class AskUserOverlayView implements Component {
|
|
|
992
1152
|
return this.states.length > 0 && this.states.every((state) => state.answer.trim().length > 0);
|
|
993
1153
|
}
|
|
994
1154
|
|
|
1155
|
+
/**
|
|
1156
|
+
* What the round captured, as three separable facts per question: the one-line
|
|
1157
|
+
* answer, the labels chosen, and the text typed. A reader tells a label-only
|
|
1158
|
+
* answer from a label-plus-value one by whether `value` is there, which the
|
|
1159
|
+
* joined string alone could never say.
|
|
1160
|
+
*/
|
|
995
1161
|
private answers(): AskUserResult["answers"] {
|
|
996
1162
|
const answers: AskUserResult["answers"] = [];
|
|
997
1163
|
for (let index = 0; index < this.questions.length; index += 1) {
|
|
998
1164
|
const question = this.questions[index];
|
|
999
|
-
const
|
|
1000
|
-
|
|
1165
|
+
const state = this.states[index];
|
|
1166
|
+
const answer = state?.answer.trim();
|
|
1167
|
+
if (!question || !state || !answer || answer.length === 0) continue;
|
|
1168
|
+
const options = selectedOptionLabels(question, state.selected);
|
|
1169
|
+
answers.push({
|
|
1170
|
+
question: question.question,
|
|
1171
|
+
answer,
|
|
1172
|
+
...(options.length > 0 ? { options } : {}),
|
|
1173
|
+
...(state.rawValue.length > 0 ? { value: state.rawValue } : {}),
|
|
1174
|
+
});
|
|
1001
1175
|
}
|
|
1002
1176
|
return answers;
|
|
1003
1177
|
}
|
|
@@ -1005,6 +1179,7 @@ class AskUserOverlayView implements Component {
|
|
|
1005
1179
|
private goToRelativeQuestion(delta: -1 | 1): void {
|
|
1006
1180
|
if (this.questions.length <= 1) return;
|
|
1007
1181
|
this.syncActiveControl();
|
|
1182
|
+
this.parkTextMode();
|
|
1008
1183
|
this.index = (this.index + delta + this.questions.length) % this.questions.length;
|
|
1009
1184
|
this.status = "";
|
|
1010
1185
|
this.resetContentScroll();
|
|
@@ -1056,6 +1231,9 @@ export function openAskUserOverlay(tui: TUI, deps: OpenAskUserOverlayDeps): AskU
|
|
|
1056
1231
|
// the terminal has left after the margins.
|
|
1057
1232
|
...(geometry.maxInnerRows > 0 ? { maxHeight: geometry.maxInnerRows + ASK_USER_FRAME_ROWS } : {}),
|
|
1058
1233
|
margin: geometry.margin,
|
|
1234
|
+
// Not derived from the title: this modal swaps between a waiting title
|
|
1235
|
+
// and a classified decision title without ever changing hands.
|
|
1236
|
+
markerId: "ask-user",
|
|
1059
1237
|
title: () => (view.isDecisionPending() ? view.decisionTitle() : ASK_USER_WAITING_TITLE),
|
|
1060
1238
|
tone: () => (view.isDecisionPending() ? view.decisionTone() : undefined),
|
|
1061
1239
|
footerHint: () => view.footerHint(),
|
|
@@ -211,6 +211,7 @@ export function openAuthDialog(tui: TUI, title: string, onCancel: () => void): A
|
|
|
211
211
|
const handle = showClioOverlayFrame(tui, box, {
|
|
212
212
|
anchor: "center",
|
|
213
213
|
width: AUTH_DIALOG_WIDTH,
|
|
214
|
+
markerId: "auth",
|
|
214
215
|
title: "Authentication",
|
|
215
216
|
footerHint: getHint,
|
|
216
217
|
});
|
|
@@ -102,6 +102,7 @@ export function openContextResetOverlay(tui: TUI, deps: OpenContextResetOverlayD
|
|
|
102
102
|
return showClioOverlayFrame(tui, new FocusBox(list), {
|
|
103
103
|
anchor: "center",
|
|
104
104
|
width: CONTEXT_RESET_OVERLAY_WIDTH,
|
|
105
|
+
markerId: "context-reset",
|
|
105
106
|
title: "Reset Project Context",
|
|
106
107
|
footerHint: buildHint([{ key: "Enter", verb: "select" }]),
|
|
107
108
|
});
|
|
@@ -135,6 +135,7 @@ export function openCwdFallbackOverlay(tui: TUI, deps: OpenCwdFallbackOverlayDep
|
|
|
135
135
|
return showClioOverlayFrame(tui, box, {
|
|
136
136
|
anchor: "center",
|
|
137
137
|
width: CWD_FALLBACK_OVERLAY_WIDTH,
|
|
138
|
+
markerId: "cwd-fallback",
|
|
138
139
|
title: "Session Working Directory",
|
|
139
140
|
footerHint: buildHint([{ key: "Enter", verb: "select" }]),
|
|
140
141
|
});
|
|
@@ -94,22 +94,21 @@ function decisionLines(decision: DecisionRecord, selected: boolean, expanded: bo
|
|
|
94
94
|
const label = decision.status === "superseded" ? theme.fg("dim", labelText) : theme.fg("muted", labelText);
|
|
95
95
|
const value = decision.status === "superseded" ? theme.fg("dim", decision.value) : decision.value;
|
|
96
96
|
const lines = [fitLine(`${cursor} ${status} ${label}${theme.fg("dim", ":")} ${value}`, width)];
|
|
97
|
+
// The indent belongs to the container, so this text wraps inside what is left
|
|
98
|
+
// of the row. Wrapping to the full width and then indenting cost every line
|
|
99
|
+
// its last six columns to a cut that landed mid-sentence.
|
|
100
|
+
const indent = " ";
|
|
101
|
+
const indented = Math.max(1, width - indent.length);
|
|
102
|
+
const wrapIndented = (text: string): string[] =>
|
|
103
|
+
wrapTextWithAnsi(text, indented).map((line) => fitLine(`${indent}${line}`, width));
|
|
97
104
|
if (decision.status === "superseded" && decision.correction) {
|
|
98
|
-
lines.push(
|
|
105
|
+
lines.push(...wrapIndented(`${theme.fg("dim", "correction")} ${theme.fg("muted", decision.correction)}`));
|
|
99
106
|
}
|
|
100
107
|
if (selected && expanded) {
|
|
101
108
|
if (decision.source_question) {
|
|
102
|
-
lines.push(
|
|
103
|
-
...wrapTextWithAnsi(`${theme.fg("dim", "question")} ${theme.fg("muted", decision.source_question)}`, width).map(
|
|
104
|
-
(line) => fitLine(` ${line}`, width),
|
|
105
|
-
),
|
|
106
|
-
);
|
|
109
|
+
lines.push(...wrapIndented(`${theme.fg("dim", "question")} ${theme.fg("muted", decision.source_question)}`));
|
|
107
110
|
}
|
|
108
|
-
lines.push(
|
|
109
|
-
...wrapTextWithAnsi(`${theme.fg("dim", "answer")} ${theme.fg("muted", decision.value)}`, width).map((line) =>
|
|
110
|
-
fitLine(` ${line}`, width),
|
|
111
|
-
),
|
|
112
|
-
);
|
|
111
|
+
lines.push(...wrapIndented(`${theme.fg("dim", "answer")} ${theme.fg("muted", decision.value)}`));
|
|
113
112
|
}
|
|
114
113
|
return lines;
|
|
115
114
|
}
|
|
@@ -296,6 +295,7 @@ export function openDecisionsOverlay(
|
|
|
296
295
|
return showClioOverlayFrame(tui, body, {
|
|
297
296
|
anchor: "center",
|
|
298
297
|
width: DECISIONS_OVERLAY_WIDTH,
|
|
298
|
+
markerId: "decisions",
|
|
299
299
|
title: () => "Decisions",
|
|
300
300
|
footerHint: () => body.footerHint(),
|
|
301
301
|
});
|
|
@@ -191,6 +191,7 @@ export function openFleetRunApprovalOverlay(tui: TUI, options: OpenFleetRunAppro
|
|
|
191
191
|
const handle = showClioOverlayFrame(tui, focus, {
|
|
192
192
|
anchor: "center",
|
|
193
193
|
width: fleetRunApprovalOverlayWidth(options.columns),
|
|
194
|
+
markerId: "fleet-run-approval",
|
|
194
195
|
title: FLEET_RUN_APPROVAL_OVERLAY_TITLE,
|
|
195
196
|
footerHint: buildResponsiveHint(
|
|
196
197
|
[...(acceptable ? [{ key: "Enter", verb: "dispatch" }] : []), { key: "↑↓", verb: "scroll" }],
|
|
@@ -163,6 +163,7 @@ export function openHandoffReviewOverlay(
|
|
|
163
163
|
const handle = showClioOverlayFrame(tui, focus, {
|
|
164
164
|
anchor: "center",
|
|
165
165
|
width: handoffReviewOverlayWidth(options.columns),
|
|
166
|
+
markerId: "handoff-review",
|
|
166
167
|
title: HANDOFF_REVIEW_OVERLAY_TITLE,
|
|
167
168
|
footerHint: buildResponsiveHint(
|
|
168
169
|
[
|
|
@@ -94,6 +94,7 @@ export function openHelpOverlay(
|
|
|
94
94
|
detail: () => [
|
|
95
95
|
"# Fleet runs & steering",
|
|
96
96
|
"**Fleet Runs board**: open it with the configured Dispatch Board key (Alt+W by default). Use Up/Down or `j`/`k` to select a live or recent run.",
|
|
97
|
+
"**Enter**: on a live run in a `--with-panes` session, Enter opens (or retargets) the watch pane beside Clio, rendering that run's stream; the arrow keys then move it between runs. On a finished run, or without panes, Enter toggles the inline worker-progress detail instead.",
|
|
97
98
|
"**Steer**: press `s` on a live native run to close the board and prefill `@<runId> `. Add guidance and submit it normally. The first notice means queued; a received notice confirms worker delivery.",
|
|
98
99
|
"**Cancel**: press `x` on a running, stale, queued, or retry-waiting run. The row changes to cancelling while the worker or retry is being stopped.",
|
|
99
100
|
"**Capabilities**: ACP delegation runs cannot accept live steering. The board footer only advertises actions supported by the selected row.",
|
|
@@ -129,6 +130,10 @@ export function openHelpOverlay(
|
|
|
129
130
|
"auto-edit parks unrecognized commands, and full-auto runs them.",
|
|
130
131
|
"**Approvals**: a parked call waits for a one-shot operator decision; approving resumes only that call. " +
|
|
131
132
|
"Workers resolve asks per `workers.onPermission` (Approvals Routing); headless runs auto-deny.",
|
|
133
|
+
"**Inspecting a mutation**: a parked `write` or `edit` card carries the target, the byte count, and a `sha256` digest of the exact call arguments. " +
|
|
134
|
+
"Press `v` to read the complete proposed content, or the complete effective diff against the file on disk, and `v` again to put it away; ↑/↓ and PageUp/PageDown scroll it. " +
|
|
135
|
+
"Enter still allows, `s` still stops, and Esc still denies while it is open. The mutation text is shown locally and never enters the transcript, a notice, a desktop notification, or the render trace. " +
|
|
136
|
+
"A worker escalation has no preview because the call's arguments never leave the worker, and its card says so.",
|
|
132
137
|
],
|
|
133
138
|
},
|
|
134
139
|
];
|
|
@@ -136,6 +141,7 @@ export function openHelpOverlay(
|
|
|
136
141
|
const items = [...commands, ...keys, ...topics];
|
|
137
142
|
|
|
138
143
|
return openListOverlay(tui, {
|
|
144
|
+
markerId: "help",
|
|
139
145
|
title: "Help Center",
|
|
140
146
|
items,
|
|
141
147
|
filterable: true,
|
|
@@ -137,6 +137,7 @@ export function openLibraryInstallConfirmOverlay(
|
|
|
137
137
|
const handle = showClioOverlayFrame(tui, focus, {
|
|
138
138
|
anchor: "center",
|
|
139
139
|
width: confirmOverlayWidth(options.columns),
|
|
140
|
+
markerId: "library-install",
|
|
140
141
|
title: LIBRARY_INSTALL_CONFIRM_TITLE,
|
|
141
142
|
footerHint: buildResponsiveHint([{ key: "Enter", verb: "install" }], { key: "Esc", verb: "cancel" }),
|
|
142
143
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Skills Hub's tab table.
|
|
3
|
+
*
|
|
4
|
+
* It sits in its own module rather than inside `skills-hub.ts` because the slash
|
|
5
|
+
* registry parses `/library <kind>` against it, and the registry has to stay off
|
|
6
|
+
* the render module graph. Pulling the whole hub overlay in for four ids made
|
|
7
|
+
* `src/cli/run.ts` a second, disjoint reacher of the interactive theme and
|
|
8
|
+
* `src/engine/tui.ts`, which splits the merged chunk the Stage 0 instant shell
|
|
9
|
+
* depends on. See `tests/contracts/instant-shell-import-graph.test.ts`.
|
|
10
|
+
*
|
|
11
|
+
* Pure data plus its membership test: no rendering, no overlay state.
|
|
12
|
+
* `skills-hub.ts` re-exports both symbols, so every existing importer keeps the
|
|
13
|
+
* path it had.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type { LibraryEntryKind } from "../../domains/resources/index.js";
|
|
17
|
+
|
|
18
|
+
/** The hub's tabs, in the order ←/→ walks them. `skill` is the original view. */
|
|
19
|
+
export const LIBRARY_TABS: ReadonlyArray<{ id: LibraryEntryKind; label: string }> = [
|
|
20
|
+
{ id: "skill", label: "Skills" },
|
|
21
|
+
{ id: "agent", label: "Agents" },
|
|
22
|
+
{ id: "prompt", label: "Prompts" },
|
|
23
|
+
{ id: "fleet", label: "Fleets" },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export function isLibraryTab(value: string): value is LibraryEntryKind {
|
|
27
|
+
return LIBRARY_TABS.some((tab) => tab.id === value);
|
|
28
|
+
}
|
|
@@ -742,11 +742,20 @@ export interface ListOverlayHandle extends OverlayHandle {
|
|
|
742
742
|
activeTabId(): string;
|
|
743
743
|
}
|
|
744
744
|
|
|
745
|
-
|
|
745
|
+
/**
|
|
746
|
+
* The marker id rides on the opener rather than on `ListOverlayOptions` because
|
|
747
|
+
* it belongs to the mounted modal, not to the view: the view renders the same
|
|
748
|
+
* rows whether it is a modal or a body inside something else. It is named by
|
|
749
|
+
* the surface rather than derived from `title`, because a tabbed overlay's
|
|
750
|
+
* rendered title names the active tab while the modal holding the keyboard has
|
|
751
|
+
* not changed hands.
|
|
752
|
+
*/
|
|
753
|
+
export function openListOverlay(tui: TUI, options: ListOverlayOptions & { markerId: string }): ListOverlayHandle {
|
|
746
754
|
const view = new ListOverlayView(options, () => tui.requestRender());
|
|
747
755
|
const handle = showClioOverlayFrame(tui, view, {
|
|
748
756
|
anchor: "center",
|
|
749
757
|
width: 100,
|
|
758
|
+
markerId: options.markerId,
|
|
750
759
|
// A function, not the string: on a tabbed overlay the title names the tab
|
|
751
760
|
// and must be re-read after every switch.
|
|
752
761
|
title: () => view.title(),
|
|
@@ -149,6 +149,7 @@ export function openMessagePickerOverlay(tui: TUI, deps: OpenMessagePickerOverla
|
|
|
149
149
|
return showClioOverlayFrame(tui, box, {
|
|
150
150
|
anchor: "center",
|
|
151
151
|
width: MESSAGE_PICKER_OVERLAY_WIDTH,
|
|
152
|
+
markerId: "message-picker",
|
|
152
153
|
title: "Fork",
|
|
153
154
|
footerHint: rows.length > 0 ? buildHint([{ key: "Enter", verb: "select" }]) : buildHint([]),
|
|
154
155
|
});
|