@iowarp/clio-coder 0.3.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/NOTICE +33 -0
- package/README.md +7 -2
- package/dist/{acp-7LOELQFP.js → acp-G5WJBNCT.js} +13 -12
- package/dist/{agents-FIBG2SHA.js → agents-FMV2Q5G4.js} +39 -36
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-OI4LIH2I.js → auth-3IDSJEIK.js} +16 -15
- package/dist/{builtins-AD25UL3C.js → builtins-XCZWXSC7.js} +3 -3
- package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
- package/dist/{chunk-56KB5IJP.js → chunk-2OQE55CK.js} +3 -3
- package/dist/{chunk-N3PBVRTZ.js → chunk-32KWKNSF.js} +9 -7
- package/dist/{chunk-VKBMFOYV.js → chunk-36EJLSQQ.js} +23 -27
- package/dist/{chunk-465CC7FK.js → chunk-3BT2XMV4.js} +16 -13
- package/dist/{chunk-NQ6UCCOD.js → chunk-3URVFKWK.js} +7 -7
- package/dist/{chunk-WIE7ZOSW.js → chunk-3XML7CDN.js} +2 -2
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
- package/dist/{chunk-HAY4ZE2P.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-JEQQR47K.js → chunk-6DB53AJS.js} +168 -9
- package/dist/{chunk-KV2AOLDF.js → chunk-76ONBSIA.js} +5 -25
- package/dist/{chunk-FALJGAWU.js → chunk-7MCTRUCE.js} +2 -2
- package/dist/{chunk-5T7RBWN2.js → chunk-AB44T6BB.js} +5 -5
- package/dist/chunk-B7OBL7PK.js +1405 -0
- package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
- package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
- package/dist/{chunk-O6I4CIEU.js → chunk-BKFJHQCA.js} +6 -6
- package/dist/chunk-BKFM6EJV.js +462 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-MV2VUEJC.js → chunk-BPKCPIL7.js} +2 -2
- package/dist/{chunk-TEO2TLVN.js → chunk-BUMFYQFY.js} +964 -1120
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/chunk-C2LTL2W6.js +2447 -0
- package/dist/{chunk-EBOC7MT3.js → chunk-CODPRO7Q.js} +8 -8
- package/dist/{chunk-HPCTNZM2.js → chunk-CTJ4RNAA.js} +4 -4
- package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
- package/dist/{chunk-MIX5N5AC.js → chunk-DQITNCXG.js} +394 -154
- package/dist/{chunk-S4COXYBG.js → chunk-DYJP44XW.js} +129 -106
- package/dist/{chunk-N5XKWMDW.js → chunk-F4CKPOEQ.js} +6 -6
- package/dist/{chunk-AMKHQW3C.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/{chunk-7C6RYZGQ.js → chunk-GKF55TAZ.js} +3 -3
- package/dist/{chunk-B5XRQOLB.js → chunk-GR5G2PVF.js} +9 -8
- package/dist/{chunk-XDOQXGFO.js → chunk-GXNLGKAB.js} +64 -8
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/{chunk-774ILSRL.js → chunk-HI63TFOG.js} +4 -3
- package/dist/{chunk-R7LNVMCS.js → chunk-HJJTYUHX.js} +64 -72
- package/dist/{chunk-RKRLDWD3.js → chunk-HLW2MRKE.js} +1 -1
- package/dist/{chunk-CA42X6KT.js → chunk-HWHKMHUA.js} +6 -6
- package/dist/chunk-HZHHCK24.js +1631 -0
- package/dist/{chunk-HJB5IUKP.js → chunk-I5VEOC6I.js} +12 -12
- package/dist/chunk-IBEBSCYA.js +564 -0
- package/dist/chunk-IQ7KR472.js +362 -0
- package/dist/{chunk-4H6ULJ3H.js → chunk-J4W7KFM7.js} +921 -990
- package/dist/{chunk-4LJX2PUC.js → chunk-JDG2WCRO.js} +5 -5
- package/dist/{chunk-NZU6YDNV.js → chunk-K5C3NCBD.js} +4 -4
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-NNNWO6F2.js → chunk-KFZI4NIL.js} +93 -3
- package/dist/chunk-KMVISBZR.js +132 -0
- package/dist/{chunk-BVDVID7E.js → chunk-LDQ2ZF2M.js} +2 -2
- package/dist/{chunk-OEDBCISO.js → chunk-LQ3DZAMX.js} +2 -2
- package/dist/{chunk-PZ4I4JE2.js → chunk-LY4S7GJC.js} +124 -116
- package/dist/{chunk-3DUR4WUA.js → chunk-MLKNTWH2.js} +19 -19
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-5DQRIYDZ.js → chunk-NHCZP4K7.js} +2 -2
- package/dist/chunk-NHLBIGRH.js +1506 -0
- package/dist/chunk-NQQH3YT7.js +302 -0
- package/dist/chunk-NYS75XW5.js +15 -0
- package/dist/{chunk-TD7UE2L5.js → chunk-O4XIVISU.js} +7 -7
- package/dist/{chunk-WXCJ7VME.js → chunk-O6TL7WWY.js} +6 -6
- package/dist/chunk-OQBA45DZ.js +97 -0
- package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
- package/dist/chunk-PMZCIOCJ.js +25 -0
- package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
- package/dist/{chunk-HKO36JWF.js → chunk-QBJA7R7N.js} +31 -3
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-5HFBWUMU.js → chunk-QLFS5GO2.js} +4 -4
- package/dist/{chunk-GAYUJ7LE.js → chunk-QLL7ILRG.js} +41 -32
- package/dist/{chunk-LXPJXFM5.js → chunk-QREDIESB.js} +7 -7
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/chunk-R346GLFC.js +31 -0
- package/dist/{chunk-VPTUJU4P.js → chunk-SJ5ZKQ4S.js} +2 -2
- package/dist/{chunk-QQ7EKM72.js → chunk-SP2RXXYO.js} +6 -54
- package/dist/chunk-SUCTJL45.js +45 -0
- package/dist/{chunk-5QKCQQ3E.js → chunk-SUW5DORT.js} +2 -2
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/{chunk-IHKBWSXF.js → chunk-TZ3SGWZZ.js} +2 -2
- package/dist/{chunk-ECUO3KDP.js → chunk-U77AMWDL.js} +47 -7
- package/dist/{chunk-3UUY7R3Z.js → chunk-ULC6OTWO.js} +7 -7
- package/dist/{chunk-AEYBF3TB.js → chunk-UM7N4G5A.js} +2 -2
- package/dist/{chunk-3V5AYSEQ.js → chunk-UXMFQ54G.js} +43 -36
- package/dist/{chunk-YW7UVM5V.js → chunk-V5DHCITQ.js} +34 -1
- package/dist/{chunk-47CMYGET.js → chunk-VAZSBTKF.js} +2 -2
- package/dist/{chunk-3MRC2YSQ.js → chunk-VEO4AP2K.js} +2 -2
- package/dist/{chunk-PNY46YEY.js → chunk-VFA6GDY5.js} +47 -3
- package/dist/chunk-VO67MWHC.js +75 -0
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-AD7Y7STJ.js → chunk-VYMXRQI6.js} +36 -22
- package/dist/{chunk-T3Z6VAAF.js → chunk-W5VSYASO.js} +19 -17
- package/dist/{chunk-5PVQ4SRS.js → chunk-WZR7K7ZX.js} +7 -123
- package/dist/{chunk-DG4M6ZUE.js → chunk-X3YGUTOB.js} +4 -4
- package/dist/chunk-X75E3D2N.js +686 -0
- package/dist/{chunk-P3JGPQFL.js → chunk-YDFRH54B.js} +4 -4
- package/dist/chunk-YJX4SHTD.js +40 -0
- package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
- package/dist/{chunk-YSEHGPCT.js → chunk-Z2RR6MAK.js} +3 -3
- package/dist/{chunk-HCBCAYZU.js → chunk-Z4TXYIEG.js} +5 -5
- package/dist/cli/index.js +47 -36
- package/dist/{clio-LT5V7SSZ.js → clio-2JXHBBY5.js} +7 -7
- package/dist/{code-nav-LMW275PA.js → code-nav-3YYRMYNF.js} +6 -6
- package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
- package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
- package/dist/{config-RXS5T3JT.js → config-QZPCMYSO.js} +58 -50
- package/dist/{configure-2WYWSCSD.js → configure-TEGEBYCA.js} +21 -19
- package/dist/{context-I3BTOTCS.js → context-AV7OEZ4D.js} +11 -11
- package/dist/{context-MVOORGMF.js → context-E6H5RNMC.js} +49 -41
- package/dist/{context-PALKKQYL.js → context-GSXUE4CT.js} +25 -23
- package/dist/{context-clear-N2WOYZ2K.js → context-clear-SHIBYK6T.js} +48 -40
- package/dist/{context-working-set-MIEVECVZ.js → context-working-set-5ZGKPGZQ.js} +11 -10
- package/dist/{dispatch-runner-VVA4SRRH.js → dispatch-runner-EFMJT4LD.js} +88 -60
- package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
- package/dist/doctor-QOA5FNY5.js +313 -0
- package/dist/{eval-IJ5VEZDJ.js → eval-TFBYQH4H.js} +66 -64
- package/dist/eval-inventory-SXH7PDKX.js +316 -0
- package/dist/{evidence-L5APPXNV.js → evidence-ERGESKGN.js} +198 -44
- package/dist/{evolve-RGNKFJ52.js → evolve-VDXTSYCJ.js} +46 -38
- package/dist/{extensions-7WYWUX5A.js → extensions-7BGBHN57.js} +6 -6
- package/dist/{fleet-6CNVBZZP.js → fleet-2RRVDF2V.js} +189 -101
- package/dist/{fleet-commands-L2SXSYEI.js → fleet-commands-VJ726XIA.js} +10 -10
- package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
- package/dist/{fleet-graph-2J3OOIPO.js → fleet-graph-JF5QOATM.js} +16 -15
- package/dist/fleet-inspect-VLY4S7QM.js +442 -0
- package/dist/{fleet-preflight-CZRJ4JP5.js → fleet-preflight-AIZUEJOY.js} +6 -5
- package/dist/{fleet-validate-C5RI6DP7.js → fleet-validate-AJRPDMDV.js} +20 -18
- package/dist/fleet-verify-JFEL2L3H.js +175 -0
- package/dist/fleet-view-ZCON35AG.js +102 -0
- package/dist/{init-VBN2ACVA.js → init-DN2WWLFE.js} +64 -56
- package/dist/install-XGLBQY5E.js +13 -0
- package/dist/interop-OZBKXAYL.js +114 -0
- package/dist/{library-JHGUMLY2.js → library-YWZG7IMW.js} +19 -18
- package/dist/{memory-K4OQIYWG.js → memory-I4C4HMLW.js} +48 -40
- package/dist/{models-2NCZUWDD.js → models-CEYXJBO6.js} +30 -28
- package/dist/{monitor-MMVTJABD.js → monitor-NZ6GCI3P.js} +53 -47
- package/dist/{orchestrator-ZKBPCHW6.js → orchestrator-GCGQ4N5I.js} +6311 -7145
- package/dist/panes-HMABYVO4.js +58 -0
- package/dist/panes-KY6W3V2E.js +103 -0
- package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
- package/dist/{reset-DD5JGOY3.js → reset-DQ6FGCSH.js} +13 -11
- package/dist/resources-BB3MVJMD.js +111 -0
- package/dist/{run-QEGNX7FL.js → run-H2GQDUER.js} +113 -82
- package/dist/{share-JKD3BQMW.js → share-GTJN6A5O.js} +18 -17
- package/dist/{skills-LMQIKDOZ.js → skills-L55TEW6R.js} +31 -24
- package/dist/{skills-eval-I7X2774U.js → skills-eval-XVXPH2JI.js} +61 -52
- package/dist/skills-inventory-S4MXPJFV.js +126 -0
- package/dist/slash-commands-ZSGASKJC.js +77 -0
- package/dist/{steer-CF5TDANS.js → steer-RZGSCY4R.js} +3 -3
- package/dist/{support-I7LOJLIF.js → support-PKEUNNQL.js} +4 -4
- package/dist/{targets-RUSR6B5Z.js → targets-NCPZ644J.js} +31 -29
- package/dist/{terminal-lease-QYVORFR4.js → terminal-lease-44SV3YCN.js} +4 -4
- package/dist/tools-DAF3DI3C.js +27 -0
- package/dist/{trace-ODOQIVIW.js → trace-FYVW2MQA.js} +149 -7
- package/dist/tui-primitives-2AKXQNZK.js +13 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
- package/dist/{upgrade-XANW3FXB.js → upgrade-3XPP6OQL.js} +26 -24
- package/dist/{usage-4H7ZRXQT.js → usage-3NLHGTU2.js} +57 -49
- package/dist/{verifiers-UZXNBZEB.js → verifiers-SSQONKRT.js} +171 -12
- package/dist/{verify-BVKWTNDL.js → verify-3U6J7FZI.js} +9 -9
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
- package/dist/{wiki-generate-MY7WV2QI.js → wiki-generate-CEHYGPGQ.js} +67 -59
- package/dist/with-panes-MKB46MPQ.js +782 -0
- package/dist/worker/entry.js +101 -66
- package/docs/README.md +3 -2
- package/docs/acp.md +24 -3
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +4 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +43 -5
- package/docs/commands-and-modes.md +31 -2
- package/docs/configuration-and-targets.md +40 -10
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +1 -0
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +2 -2
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +25 -1
- package/docs/fleet-dispatch.md +22 -1
- package/docs/installation-and-lifecycle.md +15 -2
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +10 -1
- package/docs/observability.md +3 -3
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +1 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +18 -8
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +4 -2
- package/src/cli/acp.ts +6 -2
- package/src/cli/argv.ts +25 -0
- package/src/cli/configure.ts +23 -21
- package/src/cli/doctor-panes.ts +124 -0
- package/src/cli/doctor-toolchain.ts +57 -0
- package/src/cli/doctor.ts +20 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +13 -0
- package/src/cli/evidence-detail.ts +88 -0
- package/src/cli/evidence-inventory.ts +183 -0
- package/src/cli/evidence.ts +30 -5
- package/src/cli/fleet-decisions.ts +69 -0
- package/src/cli/fleet-inspect.ts +334 -0
- package/src/cli/fleet-verify.ts +133 -0
- package/src/cli/fleet-view.ts +810 -0
- package/src/cli/fleet.ts +148 -37
- package/src/cli/index.ts +14 -2
- package/src/cli/interop-inspect.ts +128 -0
- package/src/cli/interop.ts +34 -0
- package/src/cli/panes.ts +35 -0
- package/src/cli/reset.ts +5 -2
- package/src/cli/run.ts +58 -0
- package/src/cli/skills-inventory.ts +185 -0
- package/src/cli/skills.ts +16 -13
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +23 -2
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/core/bus-events.ts +4 -0
- package/src/core/config.ts +49 -0
- package/src/core/defaults.ts +93 -7
- package/src/core/response-schema.ts +44 -4
- package/src/core/theme-token-hex.ts +43 -0
- package/src/core/tool-names.ts +2 -1
- package/src/core/xdg.ts +1 -1
- package/src/domains/agents/fleets/build-review.md +0 -3
- package/src/domains/agents/fleets/build-test.md +0 -3
- package/src/domains/agents/result-contract-filesystem.ts +32 -0
- package/src/domains/agents/result-contract.ts +164 -35
- package/src/domains/config/classify.ts +3 -0
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +22 -21
- package/src/domains/dispatch/capacity-lease.ts +21 -1
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/extension.ts +222 -50
- package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
- package/src/domains/dispatch/fleet-plan.ts +7 -2
- package/src/domains/dispatch/fleet-run.ts +64 -1
- package/src/domains/dispatch/gate-decisions.ts +11 -1
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/gate-topology.ts +289 -0
- package/src/domains/dispatch/index.ts +19 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/reservation-store.ts +24 -4
- package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
- package/src/domains/dispatch/run-event-journal.ts +598 -0
- package/src/domains/dispatch/state.ts +45 -1
- package/src/domains/dispatch/types.ts +13 -0
- package/src/domains/dispatch/validation.ts +33 -8
- package/src/domains/eval/compare/compare.ts +3 -16
- package/src/domains/eval/inventory.ts +113 -0
- package/src/domains/eval/schema/serving.ts +31 -0
- package/src/domains/evidence/store.ts +6 -0
- package/src/domains/memory/index.ts +0 -1
- package/src/domains/memory/task-memory-policy.ts +6 -10
- package/src/domains/memory/task-memory-telemetry.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +33 -21
- package/src/domains/mux/contract.ts +434 -0
- package/src/domains/mux/detect.ts +158 -0
- package/src/domains/mux/extension.ts +47 -0
- package/src/domains/mux/index.ts +96 -0
- package/src/domains/mux/manifest.ts +6 -0
- package/src/domains/mux/operations.ts +164 -0
- package/src/domains/mux/pane-registry.ts +90 -0
- package/src/domains/mux/protocol.ts +49 -0
- package/src/domains/mux/socket-client.ts +816 -0
- package/src/domains/mux/types.ts +222 -0
- package/src/domains/mux/viewer-command.ts +59 -0
- package/src/domains/mux/yazi/assets/init.lua +2 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
- package/src/domains/mux/yazi/assets/yazi.toml +17 -0
- package/src/domains/mux/yazi/event-stream.ts +180 -0
- package/src/domains/mux/yazi/profile.ts +299 -0
- package/src/domains/mux/yazi/session.ts +228 -0
- package/src/domains/mux/yazi/theme.ts +30 -0
- package/src/domains/observability/cost.ts +21 -0
- package/src/domains/observability/index.ts +2 -0
- package/src/domains/observability/trace-store.ts +42 -0
- package/src/domains/providers/endpoint-capacity.ts +154 -22
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +20 -3
- package/src/domains/providers/index.ts +22 -0
- package/src/domains/providers/model-runtime-capabilities.ts +32 -0
- package/src/domains/providers/runtimes/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- package/src/domains/providers/runtimes/protocol/litellm.ts +375 -0
- package/src/domains/providers/support.ts +1 -0
- package/src/domains/providers/target-model-cache.ts +124 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/skills/loader.ts +33 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- package/src/domains/toolchain/archive.ts +175 -0
- package/src/domains/toolchain/contract.ts +28 -0
- package/src/domains/toolchain/extension.ts +47 -0
- package/src/domains/toolchain/index.ts +39 -0
- package/src/domains/toolchain/install.ts +327 -0
- package/src/domains/toolchain/manifest.ts +8 -0
- package/src/domains/toolchain/paths.ts +34 -0
- package/src/domains/toolchain/registry.ts +265 -0
- package/src/domains/toolchain/remove.ts +218 -0
- package/src/domains/toolchain/resolve.ts +182 -0
- package/src/domains/toolchain/types.ts +113 -0
- package/src/domains/toolchain/version.ts +88 -0
- package/src/engine/acp/server.ts +413 -70
- package/src/engine/acp/types.ts +19 -1
- package/src/engine/claude/sdk-module.ts +98 -0
- package/src/engine/claude/sdk-runtime.ts +19 -11
- package/src/engine/tui-primitives.ts +21 -0
- package/src/engine/tui.ts +1 -0
- package/src/engine/worker-runtime.ts +2 -13
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +103 -5
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- package/src/interactive/context-overlay.ts +1 -0
- package/src/interactive/cost-overlay.ts +2 -0
- package/src/interactive/council-grid.ts +1 -3
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +26 -16
- package/src/interactive/interactive-application.ts +153 -6
- package/src/interactive/interactive-input-runtime.ts +7 -0
- package/src/interactive/interactive-slash-runtime.ts +36 -6
- package/src/interactive/memory-overlay.ts +1 -0
- package/src/interactive/modal-marker.ts +170 -0
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +58 -2
- package/src/interactive/overlay-general-openers.ts +1 -0
- package/src/interactive/overlay-key-routing.ts +14 -3
- package/src/interactive/overlay-lifecycle.ts +19 -3
- package/src/interactive/overlay-model-selectors.ts +40 -3
- package/src/interactive/overlay-permission-lifecycle.ts +90 -22
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +1 -0
- package/src/interactive/overlays/ask-user.ts +136 -30
- package/src/interactive/overlays/auth-dialog.ts +1 -0
- package/src/interactive/overlays/context-reset.ts +1 -0
- package/src/interactive/overlays/cwd-fallback.ts +1 -0
- package/src/interactive/overlays/decisions.ts +11 -11
- package/src/interactive/overlays/extensions.ts +1 -0
- package/src/interactive/overlays/fleet-run-approval.ts +1 -0
- package/src/interactive/overlays/handoff-review.ts +1 -0
- package/src/interactive/overlays/help-reference.ts +2 -0
- package/src/interactive/overlays/interop.ts +1 -0
- package/src/interactive/overlays/library-install-confirm.ts +1 -0
- package/src/interactive/overlays/library-tabs.ts +28 -0
- package/src/interactive/overlays/list-overlay.ts +10 -1
- package/src/interactive/overlays/message-picker.ts +1 -0
- package/src/interactive/overlays/model-scope.ts +86 -0
- package/src/interactive/overlays/model-selector.ts +1 -0
- package/src/interactive/overlays/prompts.ts +1 -0
- package/src/interactive/overlays/session-selector.ts +1 -0
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +579 -44
- package/src/interactive/overlays/side-question.ts +1 -0
- package/src/interactive/overlays/skills-hub.ts +3 -11
- package/src/interactive/overlays/tree-selector.ts +1 -0
- package/src/interactive/pane-policy.ts +46 -0
- package/src/interactive/panes-runtime.ts +292 -0
- package/src/interactive/renderers/compaction-summary.ts +29 -0
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/slash-commands.ts +251 -15
- package/src/interactive/tasks-overlay.ts +1 -0
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +47 -2
- package/src/interactive/view/artifacts.ts +109 -1
- package/src/interactive/view/view-overlay.ts +1 -0
- package/src/interactive/watch-pane.ts +152 -0
- package/src/interactive/worker-progress.ts +7 -1
- package/src/interactive/worker-receipts.ts +19 -1
- package/src/interactive/worker-stream.ts +5 -0
- package/src/interactive/yazi-bridge.ts +444 -0
- package/src/tools/bootstrap.ts +26 -2
- package/src/tools/builtin-tool-catalog.ts +15 -0
- package/src/tools/compete-worktrees.ts +83 -2
- package/src/tools/core-bootstrap.ts +2 -1
- package/src/tools/dispatch-admission.ts +14 -3
- package/src/tools/dispatch-arguments.ts +20 -20
- package/src/tools/dispatch-run-events.ts +134 -19
- package/src/tools/dispatch-runner.ts +29 -7
- package/src/tools/dispatch-types.ts +15 -3
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/executables.ts +17 -14
- package/src/tools/observation.ts +54 -4
- package/src/tools/panes-surface.ts +38 -0
- package/src/tools/panes.ts +112 -0
- package/src/tools/policy.ts +10 -1
- package/src/tools/presentation.ts +1 -0
- package/dist/chunk-D73KXYPF.js +0 -37
- package/dist/chunk-MLOK6ZOS.js +0 -2888
- package/dist/chunk-YKOFT37S.js +0 -279
- package/dist/doctor-TWBWFK5V.js +0 -165
|
@@ -4,6 +4,7 @@ import type { SafeEventBus } from "../core/event-bus.js";
|
|
|
4
4
|
import { parseCouncilReport, parseOracleResult } from "../domains/agents/index.js";
|
|
5
5
|
import type { AgentSpec } from "../domains/agents/spec.js";
|
|
6
6
|
import type { ContextInitOptions } from "../domains/context/init-options.js";
|
|
7
|
+
import { AdmissionCanceledError } from "../domains/dispatch/admission-error.js";
|
|
7
8
|
import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
|
|
8
9
|
import { type AgentRoleFactsResolver, requestExecutionRole } from "../domains/dispatch/execution-role.js";
|
|
9
10
|
import type { RunReceipt } from "../domains/dispatch/types.js";
|
|
@@ -11,6 +12,14 @@ import type { JobThinkingLevel } from "../domains/dispatch/validation.js";
|
|
|
11
12
|
import type { ReceiptIntegrityOutcome } from "../domains/evidence/trust-status.js";
|
|
12
13
|
import type { InstalledExtension } from "../domains/extensions/index.js";
|
|
13
14
|
import type { InteropAgentId, InteropProposal, InteropReport } from "../domains/interop/index.js";
|
|
15
|
+
import {
|
|
16
|
+
isPanesPresetId,
|
|
17
|
+
PANES_PRESET_IDS,
|
|
18
|
+
PANES_PRESETS,
|
|
19
|
+
type PanesOperations,
|
|
20
|
+
type PanesPresetId,
|
|
21
|
+
type PanesStatus,
|
|
22
|
+
} from "../domains/mux/operations.js";
|
|
14
23
|
import type { ProvidersContract, ResolvedModelRef } from "../domains/providers/index.js";
|
|
15
24
|
import { resolveModelReference } from "../domains/providers/index.js";
|
|
16
25
|
import type {
|
|
@@ -27,13 +36,13 @@ import type { NoticeLevel } from "./command-output.js";
|
|
|
27
36
|
import {
|
|
28
37
|
buildCouncilDispatchArgs,
|
|
29
38
|
COUNCIL_MAX_ROUNDS,
|
|
39
|
+
COUNCIL_SYNTHESIS_LABEL,
|
|
30
40
|
COUNCIL_SYNTHESIS_MODES,
|
|
31
41
|
type CouncilCommandOptions,
|
|
32
42
|
type CouncilRosters,
|
|
33
43
|
isCouncilSynthesisMode,
|
|
34
44
|
resolveCouncilRoster,
|
|
35
45
|
} from "./council.js";
|
|
36
|
-
import { COUNCIL_SYNTHESIS_LABEL } from "./council-grid.js";
|
|
37
46
|
import {
|
|
38
47
|
formatOracleAnswer,
|
|
39
48
|
ORACLE_AGENT_ID,
|
|
@@ -41,8 +50,9 @@ import {
|
|
|
41
50
|
type OracleDigestSources,
|
|
42
51
|
packOracleDigest,
|
|
43
52
|
} from "./oracle.js";
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
53
|
+
import { isLibraryTab, LIBRARY_TABS } from "./overlays/library-tabs.js";
|
|
54
|
+
import type { SettingsCenterRowId } from "./overlays/settings.js";
|
|
55
|
+
import { SETTINGS_SECTIONS, type SettingsSectionId } from "./overlays/settings-sections.js";
|
|
46
56
|
import type { CommandArgsSpec, CommandPositionalSpec, ParsedArgs } from "./slash-spec.js";
|
|
47
57
|
import { matchFromSpec, usageLine } from "./slash-spec.js";
|
|
48
58
|
import {
|
|
@@ -60,6 +70,25 @@ import type { WorkerEntryState } from "./worker-stream.js";
|
|
|
60
70
|
* one user-facing slash command: how it parses, which SlashCommand kinds it
|
|
61
71
|
* produces, and how those kinds execute. Adding a new command is one entry
|
|
62
72
|
* rather than extending two parallel switches.
|
|
73
|
+
*
|
|
74
|
+
* This module is a CLI seam, which constrains what it may import.
|
|
75
|
+
* `src/cli/run.ts` reaches `parseSlashCommand` here so a headless
|
|
76
|
+
* `clio-coder run "/typo"` refuses the token by the same shape test and the same
|
|
77
|
+
* registry membership the editor uses; a second copy of the parser would drift
|
|
78
|
+
* from this one on the first command added. That makes the CLI a reacher of
|
|
79
|
+
* everything this file statically imports, so nothing here may reach the
|
|
80
|
+
* interactive render graph: no theme, no overlay frame, no overlay module, no
|
|
81
|
+
* `../engine/tui.js`. Those modules share one bundle chunk with the instant
|
|
82
|
+
* shell's Stage 0 closure, and a second, disjoint reacher makes esbuild split
|
|
83
|
+
* it, which is a startup-latency regression rather than a style problem. The
|
|
84
|
+
* parse-time data tables the registry needs live in leaves for that reason:
|
|
85
|
+
* `./overlays/settings-sections.js`, `./overlays/library-tabs.js`, and
|
|
86
|
+
* `COUNCIL_SYNTHESIS_LABEL` in `./council.js`. Import from those, not from the
|
|
87
|
+
* overlays that re-export them.
|
|
88
|
+
*
|
|
89
|
+
* Boundaries rule6 in `tests/boundaries/check-boundaries.ts` refuses a violation
|
|
90
|
+
* at lint time; `tests/contracts/instant-shell-import-graph.test.ts` is the
|
|
91
|
+
* measurement it protects.
|
|
63
92
|
*/
|
|
64
93
|
|
|
65
94
|
type ShareCommandVariant =
|
|
@@ -116,6 +145,13 @@ type SlashCommandVariant =
|
|
|
116
145
|
| { kind: "view"; filter?: string }
|
|
117
146
|
| { kind: "view-verify"; runId: string }
|
|
118
147
|
| { kind: "view-usage" }
|
|
148
|
+
/** `/panes`: mode, health, pane inventory, effective settings. */
|
|
149
|
+
| { kind: "panes" }
|
|
150
|
+
| { kind: "panes-show"; target: string }
|
|
151
|
+
/** A preset the model may also ask for, or operator-only argv. Never both. */
|
|
152
|
+
| { kind: "panes-open"; preset?: PanesPresetId; argv?: ReadonlyArray<string>; once?: boolean }
|
|
153
|
+
| { kind: "panes-close"; target: string }
|
|
154
|
+
| { kind: "panes-usage"; reason?: string }
|
|
119
155
|
| { kind: "thinking-set"; level: string }
|
|
120
156
|
| { kind: "output-set"; verbosity: string }
|
|
121
157
|
| { kind: "model" }
|
|
@@ -258,14 +294,20 @@ async function runAttributed(
|
|
|
258
294
|
progressBus?.emit(BusChannels.DispatchProgress, { runId: handle.runId, agentId: request.agentId, event });
|
|
259
295
|
}
|
|
260
296
|
const receipt = await handle.finalPromise;
|
|
261
|
-
if (receipt.
|
|
297
|
+
if (receipt.outcome === "canceled") {
|
|
298
|
+
notice("warn", `${command} aborted: ${receipt.outcomeDetail ?? "operator abort"}`);
|
|
299
|
+
} else if (receipt.exitCode !== 0 || receipt.failureMessage) {
|
|
262
300
|
const failure = receipt.failureMessage ? ` ${receipt.failureMessage}` : "";
|
|
263
301
|
notice("error", `${command} failed: exit=${receipt.exitCode}${failure}`);
|
|
264
302
|
}
|
|
265
303
|
if (share) shareReceipt(request.agentId, receipt, deps);
|
|
266
304
|
} catch (err) {
|
|
267
305
|
const msg = err instanceof Error ? err.message : String(err);
|
|
268
|
-
|
|
306
|
+
if (err instanceof AdmissionCanceledError) {
|
|
307
|
+
notice("warn", `${command} aborted: ${msg.replace(/^dispatch:\s*/u, "")}`);
|
|
308
|
+
} else {
|
|
309
|
+
notice("error", `${command} failed: ${msg}`);
|
|
310
|
+
}
|
|
269
311
|
}
|
|
270
312
|
}
|
|
271
313
|
|
|
@@ -629,6 +671,14 @@ export interface SlashCommandContext {
|
|
|
629
671
|
seedTaskMemory?: () => TaskMemorySeedCommandResult;
|
|
630
672
|
/** Open `/view`, the full observability artifact viewer. */
|
|
631
673
|
openView: (filter?: string) => void;
|
|
674
|
+
/**
|
|
675
|
+
* The pane layer's operator surface. It remains present when mux resolves to
|
|
676
|
+
* `none` because the Yazi preset can borrow the terminal for one selection;
|
|
677
|
+
* absent only when the host did not compose pane operations at all.
|
|
678
|
+
*/
|
|
679
|
+
panes?: PanesOperations;
|
|
680
|
+
/** Serialize a local async command so the next admitted slash command observes its committed state. */
|
|
681
|
+
runLocalOperation?: (operation: () => Promise<void>) => void;
|
|
632
682
|
/**
|
|
633
683
|
* Apply a thinking level named on the command line. Returns why it was
|
|
634
684
|
* refused so the caller can say so, because the level the operator typed may
|
|
@@ -640,8 +690,12 @@ export interface SlashCommandContext {
|
|
|
640
690
|
openModel: () => void;
|
|
641
691
|
/** Live providers contract used by `/model <pattern>` to resolve directly. */
|
|
642
692
|
providers: ProvidersContract;
|
|
643
|
-
/**
|
|
644
|
-
|
|
693
|
+
/**
|
|
694
|
+
* Apply a resolved model reference, or hand it to the scope dialog. "pending"
|
|
695
|
+
* means the operator has yet to choose session or global and nothing has
|
|
696
|
+
* changed; the dialog reports the outcome itself.
|
|
697
|
+
*/
|
|
698
|
+
applyModelRef: (ref: ResolvedModelRef) => "applied" | "pending";
|
|
645
699
|
openSettings: (section?: SettingsSectionId, rowId?: SettingsCenterRowId) => void;
|
|
646
700
|
openResume: () => void;
|
|
647
701
|
startNewSession: () => void;
|
|
@@ -662,10 +716,16 @@ export interface SlashCommandContext {
|
|
|
662
716
|
runCompact: (instructions: string | undefined) => void;
|
|
663
717
|
/**
|
|
664
718
|
* Escape hatch for the `view verify` entry: verify a receipt file on disk
|
|
665
|
-
* and emit
|
|
719
|
+
* and emit an actionable verification block. Kept on the context so the registry does
|
|
666
720
|
* not import the overlay module.
|
|
667
721
|
*/
|
|
668
|
-
verifyReceipt: (runId: string) => ReceiptIntegrityOutcome
|
|
722
|
+
verifyReceipt: (runId: string) => ReceiptIntegrityOutcome & {
|
|
723
|
+
receiptPath?: string;
|
|
724
|
+
sealedDigest?: string | null;
|
|
725
|
+
trustSummary?: string | null;
|
|
726
|
+
compromised?: boolean;
|
|
727
|
+
checks?: ReadonlyArray<{ name: string; ok: boolean; evidence: string }>;
|
|
728
|
+
};
|
|
669
729
|
/**
|
|
670
730
|
* Handles the "unknown" case: append the text to the chat panel as a user
|
|
671
731
|
* turn, submit to the chat loop, and schedule a re-render. Handlers for
|
|
@@ -677,6 +737,24 @@ export interface SlashCommandContext {
|
|
|
677
737
|
render: () => void;
|
|
678
738
|
}
|
|
679
739
|
|
|
740
|
+
type SlashReceiptVerification = ReturnType<SlashCommandContext["verifyReceipt"]>;
|
|
741
|
+
|
|
742
|
+
/** Compact multiline receipt verification for the composer notice surface. */
|
|
743
|
+
export function formatReceiptVerificationBlock(runId: string, result: SlashReceiptVerification): string {
|
|
744
|
+
const status = result.ok ? (result.compromised ? "compromised" : "ok") : result.retired ? "retired" : "fail";
|
|
745
|
+
const lines = [
|
|
746
|
+
`verify ${status} ${runId}`,
|
|
747
|
+
`receipt ${result.receiptPath ?? "unavailable"}`,
|
|
748
|
+
`digest ${result.sealedDigest ?? "unavailable"}`,
|
|
749
|
+
`evidence ${result.trustSummary ?? (!result.ok ? result.reason : "trust status unavailable")}`,
|
|
750
|
+
];
|
|
751
|
+
if (result.checks && result.checks.length > 0) {
|
|
752
|
+
lines.push("checks");
|
|
753
|
+
for (const check of result.checks) lines.push(` ${check.ok ? "✓" : "✗"} ${check.name}: ${check.evidence}`);
|
|
754
|
+
}
|
|
755
|
+
return lines.join("\n");
|
|
756
|
+
}
|
|
757
|
+
|
|
680
758
|
/** The one operator-authored turn used by slash and overlay handoff paths. */
|
|
681
759
|
export function formatUserTaskHandoff(task: Pick<UserTask, "id" | "title" | "note">): string {
|
|
682
760
|
const note = task.note ? ` ${task.note}.` : "";
|
|
@@ -765,6 +843,35 @@ function usageNotice(entry: BuiltinSlashCommand, subcommand?: string): string {
|
|
|
765
843
|
return usageLine(entry, subcommand).trim();
|
|
766
844
|
}
|
|
767
845
|
|
|
846
|
+
/**
|
|
847
|
+
* `/panes` output, as plain lines. Pure so the contract test asserts the text
|
|
848
|
+
* an operator reads rather than the object behind it, and so the registry keeps
|
|
849
|
+
* its promise not to reach a renderer.
|
|
850
|
+
*/
|
|
851
|
+
export function formatPanesStatus(status: PanesStatus): ReadonlyArray<string> {
|
|
852
|
+
const server = status.server ? `pane host ${status.server.version}, protocol ${status.server.protocol}` : "no server";
|
|
853
|
+
const lines = [
|
|
854
|
+
`panes: mode=${status.mode} ${status.available ? "available" : "unavailable"} (${server})`,
|
|
855
|
+
` ${status.reason}`,
|
|
856
|
+
...(status.socketPath ? [` socket ${status.socketPath}`] : []),
|
|
857
|
+
` settings: enabled=${status.settings.enabled} notifications=${status.settings.notifications} journal=${status.settings.journal}`,
|
|
858
|
+
` files: enabled=${status.settings.yazi.enabled} mode=${status.settings.yazi.mode} profile=${status.settings.yazi.profile} followCwd=${status.settings.yazi.followCwd}`,
|
|
859
|
+
` file pane: mode=${status.yazi.mode} pane=${status.yazi.paneId ?? "none"} cwd=${status.yazi.paneCwd ?? "unknown"} lastLine=${status.yazi.lastLineAt === null ? "never" : new Date(status.yazi.lastLineAt).toISOString()} dropped=${status.yazi.droppedLines}`,
|
|
860
|
+
];
|
|
861
|
+
if (status.panes.length === 0) {
|
|
862
|
+
lines.push(" no Clio-owned panes");
|
|
863
|
+
} else {
|
|
864
|
+
lines.push(` ${status.panes.length} Clio-owned pane(s):`);
|
|
865
|
+
for (const pane of status.panes) {
|
|
866
|
+
const adopted = pane.adopted ? " adopted" : "";
|
|
867
|
+
const pending = pane.pending ? " opening" : "";
|
|
868
|
+
lines.push(` ${pane.paneId} ${pane.purpose} ${pane.label}${adopted}${pending}`);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
lines.push(` presets: ${PANES_PRESETS.map((preset) => `${preset.id} (${preset.summary})`).join(", ")}`);
|
|
872
|
+
return lines;
|
|
873
|
+
}
|
|
874
|
+
|
|
768
875
|
export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
769
876
|
{
|
|
770
877
|
name: "quit",
|
|
@@ -1505,16 +1612,141 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1505
1612
|
}
|
|
1506
1613
|
if (command.kind !== "view-verify") return;
|
|
1507
1614
|
const result = ctx.verifyReceipt(command.runId);
|
|
1615
|
+
const block = formatReceiptVerificationBlock(command.runId, result);
|
|
1508
1616
|
if (result.ok) {
|
|
1509
|
-
ctx.notice("success",
|
|
1617
|
+
ctx.notice(result.compromised ? "warn" : "success", block);
|
|
1510
1618
|
} else if (result.retired !== undefined) {
|
|
1511
1619
|
// A retired seal is the expected state of a run from the previous
|
|
1512
1620
|
// release, so it is a warning that names the versions, never the
|
|
1513
1621
|
// failure a tampered receipt gets.
|
|
1514
|
-
ctx.notice("warn",
|
|
1622
|
+
ctx.notice("warn", block);
|
|
1515
1623
|
} else {
|
|
1516
|
-
ctx.notice("error",
|
|
1624
|
+
ctx.notice("error", block);
|
|
1625
|
+
}
|
|
1626
|
+
},
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
name: "panes",
|
|
1630
|
+
description: "Inspect the pane layer, watch a live run in a pane, or open a utility pane",
|
|
1631
|
+
group: "Inspect",
|
|
1632
|
+
kinds: ["panes", "panes-show", "panes-open", "panes-close", "panes-usage"],
|
|
1633
|
+
args: {
|
|
1634
|
+
subcommands: {
|
|
1635
|
+
show: { positionals: [{ name: "run-or-agent", required: true }] },
|
|
1636
|
+
// A rest positional, so an argv pane keeps its own flags: the parser
|
|
1637
|
+
// would otherwise refuse `--follow` as an unknown flag of `/panes`.
|
|
1638
|
+
open: { positionals: [{ name: "preset-or-argv", required: true, rest: true }] },
|
|
1639
|
+
close: { positionals: [{ name: "target", required: false }] },
|
|
1640
|
+
},
|
|
1641
|
+
},
|
|
1642
|
+
subcommandDescriptions: {
|
|
1643
|
+
show: "watch a live run or agent in the watch pane",
|
|
1644
|
+
open: `open a utility pane (${PANES_PRESET_IDS.join(", ")}, or a command)`,
|
|
1645
|
+
close: "close a Clio-owned pane, or all of them",
|
|
1646
|
+
},
|
|
1647
|
+
fromArgs(parsed) {
|
|
1648
|
+
if (parsed.error) return { kind: "panes-usage", reason: parsed.error };
|
|
1649
|
+
if (parsed.subcommand === "show") {
|
|
1650
|
+
return { kind: "panes-show", target: parsed.positionals[0] ?? "" };
|
|
1651
|
+
}
|
|
1652
|
+
if (parsed.subcommand === "open") {
|
|
1653
|
+
const rest = (parsed.rest ?? "").trim();
|
|
1654
|
+
if (rest.length === 0) return { kind: "panes-usage", reason: "Missing required argument: preset-or-argv" };
|
|
1655
|
+
const argv = rest.split(/\s+/).filter((token) => token.length > 0);
|
|
1656
|
+
const first = argv[0] ?? "";
|
|
1657
|
+
// A bare preset name is a preset; anything else is operator argv,
|
|
1658
|
+
// which the tool surface deliberately cannot ask for.
|
|
1659
|
+
if (argv.length === 1 && isPanesPresetId(first)) return { kind: "panes-open", preset: first };
|
|
1660
|
+
if (argv.length === 2 && first === "yazi" && argv[1] === "--once") {
|
|
1661
|
+
return { kind: "panes-open", preset: "yazi", once: true };
|
|
1662
|
+
}
|
|
1663
|
+
return { kind: "panes-open", argv };
|
|
1664
|
+
}
|
|
1665
|
+
if (parsed.subcommand === "close") {
|
|
1666
|
+
return { kind: "panes-close", target: parsed.positionals[0] ?? "all" };
|
|
1667
|
+
}
|
|
1668
|
+
if (parsed.positionals.length > 0) {
|
|
1669
|
+
return { kind: "panes-usage", reason: `Unexpected argument: ${parsed.positionals[0]}` };
|
|
1670
|
+
}
|
|
1671
|
+
return { kind: "panes" };
|
|
1672
|
+
},
|
|
1673
|
+
handle(command, ctx) {
|
|
1674
|
+
const entry = BUILTIN_SLASH_COMMANDS.find((candidate) => candidate.name === "panes");
|
|
1675
|
+
if (command.kind === "panes-usage") {
|
|
1676
|
+
// usageNotice trims the leading newline usageLine carries, so the reason
|
|
1677
|
+
// and the usage line need their own separator or they run together as
|
|
1678
|
+
// `Missing required argument: run-or-agentusage: /panes show ...`.
|
|
1679
|
+
if (entry) ctx.notice("info", command.reason ? `${command.reason}\n${usageNotice(entry)}` : usageNotice(entry));
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
const panes = ctx.panes;
|
|
1683
|
+
if (!panes) {
|
|
1684
|
+
// Inactive by choice, not unavailable: the operations object exists in
|
|
1685
|
+
// every `--with-panes` session, even one where no pane host answered.
|
|
1686
|
+
ctx.notice(
|
|
1687
|
+
"info",
|
|
1688
|
+
"panes are inactive: this session started without them. Restart with `clio-coder --with-panes`, or set panes.enabled=auto",
|
|
1689
|
+
);
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
const runLocal = ctx.runLocalOperation ?? ((operation: () => Promise<void>) => void operation());
|
|
1693
|
+
if (command.kind === "panes") {
|
|
1694
|
+
runLocal(async () => {
|
|
1695
|
+
for (const line of formatPanesStatus(panes.status())) ctx.io.stdout(`${line}\n`);
|
|
1696
|
+
ctx.render();
|
|
1697
|
+
});
|
|
1698
|
+
return;
|
|
1699
|
+
}
|
|
1700
|
+
if (command.kind === "panes-show") {
|
|
1701
|
+
runLocal(async () => {
|
|
1702
|
+
const result = await panes.show(command.target);
|
|
1703
|
+
if (result.status === "watching") {
|
|
1704
|
+
ctx.notice("success", `watching ${result.agentId} (${result.runId})${result.opened ? " in a new pane" : ""}`);
|
|
1705
|
+
} else if (result.status === "not-found") {
|
|
1706
|
+
const known = result.candidates.length > 0 ? `; live runs: ${result.candidates.join(", ")}` : "";
|
|
1707
|
+
ctx.notice("warn", `no live run matches ${result.target}${known}`);
|
|
1708
|
+
} else {
|
|
1709
|
+
ctx.notice("warn", result.reason);
|
|
1710
|
+
}
|
|
1711
|
+
});
|
|
1712
|
+
return;
|
|
1517
1713
|
}
|
|
1714
|
+
if (command.kind === "panes-open") {
|
|
1715
|
+
runLocal(async () => {
|
|
1716
|
+
const result = await panes.open({
|
|
1717
|
+
...(command.preset ? { preset: command.preset } : {}),
|
|
1718
|
+
...(command.argv ? { argv: command.argv } : {}),
|
|
1719
|
+
...(command.once ? { once: true } : {}),
|
|
1720
|
+
});
|
|
1721
|
+
if (result.status === "opened") {
|
|
1722
|
+
// The in-terminal chooser has already restored the TUI by the
|
|
1723
|
+
// time this resolves. A pick emitted its composer notice; an empty
|
|
1724
|
+
// chooser was cancellation and deliberately stays silent.
|
|
1725
|
+
if (result.paneId !== null) ctx.notice("success", `opened pane ${result.label} (${result.paneId})`);
|
|
1726
|
+
} else if (result.status === "missing-binary") {
|
|
1727
|
+
// This is a synchronous slash-surface line, not a transient pane-host
|
|
1728
|
+
// notification. It remains visible when no pane was ever created and
|
|
1729
|
+
// reuses the exact doctor/tools diagnostic including the install hint.
|
|
1730
|
+
ctx.io.stdout(`${result.detail}\n`);
|
|
1731
|
+
ctx.render();
|
|
1732
|
+
} else {
|
|
1733
|
+
ctx.notice("warn", result.reason);
|
|
1734
|
+
}
|
|
1735
|
+
});
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
if (command.kind !== "panes-close") return;
|
|
1739
|
+
runLocal(async () => {
|
|
1740
|
+
const result = await panes.close(command.target);
|
|
1741
|
+
if (result.status === "closed") {
|
|
1742
|
+
const what = result.labels.length > 0 ? `: ${result.labels.join(", ")}` : "";
|
|
1743
|
+
ctx.notice(result.closed > 0 ? "success" : "info", `closed ${result.closed} pane(s)${what}`);
|
|
1744
|
+
} else if (result.status === "not-found") {
|
|
1745
|
+
ctx.notice("warn", `no Clio-owned pane matches ${result.target}`);
|
|
1746
|
+
} else {
|
|
1747
|
+
ctx.notice("warn", result.reason);
|
|
1748
|
+
}
|
|
1749
|
+
});
|
|
1518
1750
|
},
|
|
1519
1751
|
},
|
|
1520
1752
|
{
|
|
@@ -1604,9 +1836,13 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1604
1836
|
return;
|
|
1605
1837
|
}
|
|
1606
1838
|
if (result.warning) ctx.notice("warn", result.warning);
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1839
|
+
// "pending" means the scope dialog is up: it says what landed and
|
|
1840
|
+
// where, so announcing a swap here would be announcing a choice the
|
|
1841
|
+
// operator has not made yet.
|
|
1842
|
+
if (ctx.applyModelRef(result.ref) === "applied") {
|
|
1843
|
+
const suffix = result.ref.thinkingLevel ? ` thinking=${result.ref.thinkingLevel}` : "";
|
|
1844
|
+
ctx.notice("success", `active this session: ${result.ref.target}/${result.ref.model}${suffix}`);
|
|
1845
|
+
}
|
|
1610
1846
|
ctx.render();
|
|
1611
1847
|
})();
|
|
1612
1848
|
},
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
| "action"
|
|
5
|
-
| "success"
|
|
6
|
-
| "warning"
|
|
7
|
-
| "error"
|
|
8
|
-
| "info"
|
|
9
|
-
| "reason"
|
|
10
|
-
| "dim"
|
|
11
|
-
| "muted"
|
|
12
|
-
| "title"
|
|
13
|
-
| "frame"
|
|
14
|
-
| "frameStrong";
|
|
1
|
+
import type { ClioToken } from "../../core/theme-token-hex.js";
|
|
2
|
+
|
|
3
|
+
export type { ClioToken } from "../../core/theme-token-hex.js";
|
|
15
4
|
|
|
16
5
|
interface TokenColor {
|
|
17
6
|
rgb: readonly [number, number, number];
|
|
@@ -26,6 +26,7 @@ import { residencyTargetKey } from "../core/residency-target-key.js";
|
|
|
26
26
|
import type { ToolName } from "../core/tool-names.js";
|
|
27
27
|
import { buildEvictionFields, planEviction } from "../domains/context/working-set/engine.js";
|
|
28
28
|
import { foldWorkingSet } from "../domains/context/working-set/fold.js";
|
|
29
|
+
import { isTurnStart } from "../domains/context/working-set/horizon.js";
|
|
29
30
|
import { resolveWorkingSetPolicy } from "../domains/context/working-set/policies/index.js";
|
|
30
31
|
import { selectVisibleEntries } from "../domains/context/working-set/visible.js";
|
|
31
32
|
import type { ObservabilityContract } from "../domains/observability/contract.js";
|
|
@@ -89,7 +90,7 @@ import {
|
|
|
89
90
|
toolNamesFromAgentState,
|
|
90
91
|
} from "./chat-loop-messages.js";
|
|
91
92
|
import { buildModelReplayAgentMessagesFromTurns } from "./model-session-replay.js";
|
|
92
|
-
import { renderCompactionSummaryLine } from "./renderers/compaction-summary.js";
|
|
93
|
+
import { renderCompactionSummaryLine, renderEvictionSkipLine } from "./renderers/compaction-summary.js";
|
|
93
94
|
import type { TurnMiddleware } from "./turn-middleware.js";
|
|
94
95
|
import type { AgentRuntime, ChatTurnState } from "./turn-state.js";
|
|
95
96
|
|
|
@@ -218,6 +219,27 @@ export interface TurnContext {
|
|
|
218
219
|
dispose(): void;
|
|
219
220
|
}
|
|
220
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Why the working-set stage declined, said in the terms the operator can act
|
|
224
|
+
* on. The two cases are worth separating: a session whose every turn is inside
|
|
225
|
+
* `protectLastTurns` was never offered a candidate, while a longer one was
|
|
226
|
+
* offered candidates the policy refused. The first is the shape smoke pass 2
|
|
227
|
+
* found (G1), and the setting it names is the one that changes it.
|
|
228
|
+
*/
|
|
229
|
+
function evictionSkipMessage(
|
|
230
|
+
visibleEntries: ReadonlyArray<SessionEntry>,
|
|
231
|
+
workingSet: Readonly<{ protectLastTurns: number; policy: string }>,
|
|
232
|
+
policyId: string,
|
|
233
|
+
): string {
|
|
234
|
+
const turns = visibleEntries.filter(isTurnStart).length;
|
|
235
|
+
return renderEvictionSkipLine({
|
|
236
|
+
reason: turns <= workingSet.protectLastTurns ? "all-protected" : "nothing-evictable",
|
|
237
|
+
turns,
|
|
238
|
+
protectLastTurns: workingSet.protectLastTurns,
|
|
239
|
+
policyId,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
221
243
|
export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
222
244
|
const { state, middleware } = deps;
|
|
223
245
|
const compactionTrigger = new AutoCompactionTrigger<CompactResult | null>();
|
|
@@ -661,6 +683,12 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
661
683
|
const autoEnabled = cfg?.auto !== false;
|
|
662
684
|
if (!force && !autoEnabled) return false;
|
|
663
685
|
let preSummaryStageActed = false;
|
|
686
|
+
// G1 from smoke pass 2: a short session generates all its pressure inside
|
|
687
|
+
// the protection window, the non-destructive layer finds nothing, and the
|
|
688
|
+
// destructive summary ran with nothing in the transcript saying eviction
|
|
689
|
+
// was considered and declined. Held here and emitted only if a summary
|
|
690
|
+
// actually follows.
|
|
691
|
+
let evictionSkipNotice: string | null = null;
|
|
664
692
|
const rememberEmptyAutomaticAttempt = (): void => {
|
|
665
693
|
if (!force && !preSummaryStageActed && activeAutoTurnId) emptyAutoCompactTurnId = activeAutoTurnId;
|
|
666
694
|
};
|
|
@@ -743,12 +771,16 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
743
771
|
}
|
|
744
772
|
} else if (settings.context.workingSet.enabled) {
|
|
745
773
|
let planned: ReturnType<typeof planEviction>;
|
|
774
|
+
let visibleEntries: ReadonlyArray<SessionEntry> = [];
|
|
775
|
+
let policyId = settings.context.workingSet.policy;
|
|
746
776
|
try {
|
|
747
777
|
const entries = deps.readSessionEntries() ?? [];
|
|
748
778
|
const view = foldWorkingSet(entries, state.lastTurnId ?? undefined);
|
|
749
779
|
const policy = resolveWorkingSetPolicy(settings.context.workingSet.policy);
|
|
780
|
+
policyId = policy.id;
|
|
781
|
+
visibleEntries = selectVisibleEntries(entries, state.lastTurnId ?? undefined);
|
|
750
782
|
planned = (deps.planEviction ?? planEviction)(policy, {
|
|
751
|
-
entries:
|
|
783
|
+
entries: visibleEntries,
|
|
752
784
|
view,
|
|
753
785
|
cwd: deps.session.current()?.cwd ?? null,
|
|
754
786
|
settings: settings.context.workingSet,
|
|
@@ -830,7 +862,16 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
830
862
|
emitCompactionActivity("failed", compactionFailureMessage(error));
|
|
831
863
|
throw error;
|
|
832
864
|
}
|
|
865
|
+
} else {
|
|
866
|
+
evictionSkipNotice = evictionSkipMessage(visibleEntries, settings.context.workingSet, policyId);
|
|
833
867
|
}
|
|
868
|
+
} else {
|
|
869
|
+
evictionSkipNotice = renderEvictionSkipLine({
|
|
870
|
+
reason: "disabled",
|
|
871
|
+
turns: 0,
|
|
872
|
+
protectLastTurns: settings.context.workingSet.protectLastTurns,
|
|
873
|
+
policyId: settings.context.workingSet.policy,
|
|
874
|
+
});
|
|
834
875
|
}
|
|
835
876
|
}
|
|
836
877
|
}
|
|
@@ -847,6 +888,10 @@ export function createTurnContext(deps: TurnContextDeps): TurnContext {
|
|
|
847
888
|
summaryLifecycleStarted = true;
|
|
848
889
|
};
|
|
849
890
|
if (force) startSummaryLifecycle();
|
|
891
|
+
// Said before the summary call, not after it: the operator is about to wait
|
|
892
|
+
// on a destructive stage, and the reason the cheap one was skipped is only
|
|
893
|
+
// useful ahead of it.
|
|
894
|
+
if (evictionSkipNotice) deps.emitNotice(evictionSkipNotice);
|
|
850
895
|
let result: CompactResult | null = null;
|
|
851
896
|
const beforeSnapshotId = currentContextSnapshot?.snapshotId ?? null;
|
|
852
897
|
try {
|
|
@@ -5,12 +5,14 @@ import type { DispatchContract } from "../../domains/dispatch/contract.js";
|
|
|
5
5
|
import { isReceiptIntegrity, verifyReceiptIntegrity } from "../../domains/dispatch/receipt-integrity.js";
|
|
6
6
|
import type { RunEnvelope, RunReceipt } from "../../domains/dispatch/types.js";
|
|
7
7
|
import { evidenceDirectory, inspectEvidence, listEvidenceOverviews } from "../../domains/evidence/store.js";
|
|
8
|
-
import { formatTrustSummaryLine } from "../../domains/evidence/trust-projection.js";
|
|
8
|
+
import { formatTrustSummaryLine, trustStateWord } from "../../domains/evidence/trust-projection.js";
|
|
9
9
|
import {
|
|
10
10
|
inspectRunReceiptTrustStatus,
|
|
11
11
|
type ReceiptIntegrityOutcome,
|
|
12
12
|
retiredReceiptIntegrity,
|
|
13
13
|
retiredReceiptIntegrityReason,
|
|
14
|
+
TRUST_STATUS_AXES,
|
|
15
|
+
type TrustStatusAxis,
|
|
14
16
|
} from "../../domains/evidence/trust-status.js";
|
|
15
17
|
import type { EvidenceFinding, EvidenceOverview, EvidenceSource } from "../../domains/evidence/types.js";
|
|
16
18
|
import { type AccountabilitySummary, readAccountabilitySummary } from "../../domains/observability/index.js";
|
|
@@ -113,6 +115,20 @@ const JSON_PRETTY_MAX_BYTES = 10 * 1024 * 1024;
|
|
|
113
115
|
|
|
114
116
|
export type ReceiptVerifyResult = ReceiptIntegrityOutcome;
|
|
115
117
|
|
|
118
|
+
export interface ReceiptVerificationCheck {
|
|
119
|
+
name: string;
|
|
120
|
+
ok: boolean;
|
|
121
|
+
evidence: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export type ReceiptVerificationReport = ReceiptIntegrityOutcome & {
|
|
125
|
+
receiptPath: string;
|
|
126
|
+
sealedDigest: string | null;
|
|
127
|
+
trustSummary: string | null;
|
|
128
|
+
compromised: boolean;
|
|
129
|
+
checks: ReceiptVerificationCheck[];
|
|
130
|
+
};
|
|
131
|
+
|
|
116
132
|
/**
|
|
117
133
|
* What a verify action reports. `retired` marks a seal this build does not
|
|
118
134
|
* verify because its integrity version was retired: not a pass, and not the
|
|
@@ -435,6 +451,98 @@ export function verifyReceiptFile(stateDir: string, runId: string): ReceiptVerif
|
|
|
435
451
|
return verifyReceiptIntegrity(r as unknown as RunReceipt, ledger.envelope);
|
|
436
452
|
}
|
|
437
453
|
|
|
454
|
+
const RECEIPT_FILE_FAILURE = /^(?:receipt file not found|read error:)/u;
|
|
455
|
+
const RECEIPT_CONTRACT_FAILURE =
|
|
456
|
+
/^(?:invalid json:|receipt is not an object|missing field:|runId invalid:|runId mismatch:|agentId invalid:|task invalid:|targetId invalid:|wireModelId invalid:|runtimeId invalid:|runtimeKind invalid:|exitCode out of range:|tokenCount out of range:|inputTokenCount out of range:|outputTokenCount out of range:|cacheReadTokenCount out of range:|cacheWriteTokenCount out of range:|costUsd out of range:|reasoningTokenCount out of range:|startedAt not ISO-8601:|endedAt not ISO-8601:|clioVersion empty|piMonoVersion invalid:|platform invalid:|nodeVersion invalid:|toolCalls out of range:|toolStats\[|compiledPromptHash invalid:|staticCompositionHash invalid:|sessionId invalid:|integrity invalid|execution role invalid|routing intent invalid|route decision invalid)/u;
|
|
457
|
+
const LEDGER_FAILURE = /^(?:run ledger not found|run not found in ledger|ledger mismatch:)/u;
|
|
458
|
+
|
|
459
|
+
function receiptIntegrityDigest(value: unknown): string | null {
|
|
460
|
+
if (!isRecord(value) || value.algorithm !== "sha256" || !isNonEmptyString(value.digest)) return null;
|
|
461
|
+
return `sha256:${value.digest}`;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function trustCheckEvidence(status: ReturnType<typeof inspectRunReceiptTrustStatus>["status"], axis: string): string {
|
|
465
|
+
const entry = status[axis as keyof typeof status];
|
|
466
|
+
if (typeof entry !== "object" || entry === null || !("state" in entry)) return "canonical trust projection";
|
|
467
|
+
if (entry.state === "absent") return `reason=${entry.reason}`;
|
|
468
|
+
const refs = entry.artifacts.map((artifact) => `${artifact.kind}:${artifact.id}`);
|
|
469
|
+
return refs.length > 0 ? refs.join(", ") : `${entry.authority.kind}:${entry.authority.id}`;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function compromisedTrustAxes(status: ReturnType<typeof inspectRunReceiptTrustStatus>["status"]): TrustStatusAxis[] {
|
|
473
|
+
return TRUST_STATUS_AXES.filter((axis) => {
|
|
474
|
+
const state = status[axis].state;
|
|
475
|
+
if (axis === "artifactIntegrity") return state === "failed";
|
|
476
|
+
if (axis === "validationGrounding") return state === "failed" || state === "ungrounded";
|
|
477
|
+
if (axis === "independentReview") return state === "failed" || state === "not_independent";
|
|
478
|
+
if (axis === "contextProvenance") return state === "invalid";
|
|
479
|
+
if (axis === "autonomyEnforcement") return state === "bypassed";
|
|
480
|
+
return false;
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** Actionable `/view verify` report without changing the low-level verifier contract. */
|
|
485
|
+
export function verifyReceiptFileReport(stateDir: string, runId: string): ReceiptVerificationReport {
|
|
486
|
+
const receiptPath = receiptFilePath(stateDir, runId);
|
|
487
|
+
const result = verifyReceiptFile(stateDir, runId);
|
|
488
|
+
let receipt: RunReceipt | null = null;
|
|
489
|
+
try {
|
|
490
|
+
receipt = JSON.parse(readFileSync(receiptPath, "utf8")) as RunReceipt;
|
|
491
|
+
} catch {
|
|
492
|
+
// The verifier's named file or JSON check below retains the actionable error.
|
|
493
|
+
}
|
|
494
|
+
const sealedDigest = receiptIntegrityDigest(receipt?.integrity);
|
|
495
|
+
const ledger = readRunEnvelope(stateDir, runId);
|
|
496
|
+
const inspection = receipt === null ? null : inspectRunReceiptTrustStatus(receipt, ledger.ok ? ledger.envelope : null);
|
|
497
|
+
const trustSummary = inspection === null ? null : formatTrustSummaryLine(inspection.status);
|
|
498
|
+
const compromiseAxes = inspection === null ? [] : compromisedTrustAxes(inspection.status);
|
|
499
|
+
const checks: ReceiptVerificationCheck[] = [];
|
|
500
|
+
|
|
501
|
+
if (!result.ok && RECEIPT_FILE_FAILURE.test(result.reason)) {
|
|
502
|
+
checks.push({ name: "receipt file", ok: false, evidence: `${receiptPath}: ${result.reason}` });
|
|
503
|
+
} else {
|
|
504
|
+
checks.push({ name: "receipt file", ok: true, evidence: receiptPath });
|
|
505
|
+
if (!result.ok && (RECEIPT_CONTRACT_FAILURE.test(result.reason) || result.retired !== undefined)) {
|
|
506
|
+
checks.push({ name: "receipt contract", ok: false, evidence: result.reason });
|
|
507
|
+
} else {
|
|
508
|
+
checks.push({
|
|
509
|
+
name: "receipt contract",
|
|
510
|
+
ok: true,
|
|
511
|
+
evidence: `current integrity v${receipt?.integrity.version ?? "unknown"}`,
|
|
512
|
+
});
|
|
513
|
+
if (!result.ok && LEDGER_FAILURE.test(result.reason)) {
|
|
514
|
+
checks.push({ name: "run ledger", ok: false, evidence: result.reason });
|
|
515
|
+
} else {
|
|
516
|
+
checks.push({ name: "run ledger", ok: true, evidence: `run ${runId} fields match` });
|
|
517
|
+
checks.push({
|
|
518
|
+
name: "sealed digest",
|
|
519
|
+
ok: result.ok,
|
|
520
|
+
evidence: result.ok ? `${sealedDigest ?? "digest unavailable"} matches receipt and ledger` : result.reason,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (inspection !== null) {
|
|
527
|
+
for (const axis of compromiseAxes) {
|
|
528
|
+
checks.push({
|
|
529
|
+
name: `trust ${axis}`,
|
|
530
|
+
ok: false,
|
|
531
|
+
evidence: `${trustStateWord(axis, inspection.status[axis].state)}; ${trustCheckEvidence(inspection.status, axis)}`,
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return {
|
|
537
|
+
...result,
|
|
538
|
+
receiptPath,
|
|
539
|
+
sealedDigest,
|
|
540
|
+
trustSummary,
|
|
541
|
+
compromised: compromiseAxes.length > 0,
|
|
542
|
+
checks,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
|
|
438
546
|
function pushCapped(lines: string[], line: string, maxLines: number): boolean {
|
|
439
547
|
if (lines.length >= maxLines) return false;
|
|
440
548
|
lines.push(line);
|