@iowarp/clio-coder 0.3.1 → 0.3.2
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 +90 -2
- package/CONTRIBUTING.md +23 -23
- package/README.md +284 -613
- package/dist/{acp-FPR54DGL.js → acp-BIYHVZIM.js} +43 -53
- package/dist/{agents-OGPIHPJH.js → agents-YT6SSRIT.js} +43 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
- package/dist/{chunk-PV4JUBVJ.js → chunk-2EHAIA3X.js} +40 -21
- package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/{chunk-MAR7Y6HW.js → chunk-3ZXDFGR5.js} +23 -16
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
- package/dist/chunk-4KLWL3UC.js +18 -0
- package/dist/chunk-4VP4KH3K.js +962 -0
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
- package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
- package/dist/chunk-65DEGPJ6.js +52 -0
- package/dist/chunk-6EJMN2Y3.js +17 -0
- package/dist/chunk-6EJV5X2W.js +16405 -0
- package/dist/chunk-6N5PTWMY.js +136 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/{chunk-TEKV33Q5.js → chunk-77VKQEHF.js} +65 -33
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/{chunk-M5T5VO65.js → chunk-7EYHLWU7.js} +837 -635
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/chunk-AO4RKG4M.js +277 -0
- package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
- package/dist/chunk-ARBGF5F7.js +174 -0
- package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/chunk-ED4KHGC3.js +143 -0
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/{chunk-RPTR2H26.js → chunk-EPVUXGXG.js} +21 -15
- package/dist/chunk-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/chunk-FQ4SKYE4.js +29 -0
- package/dist/chunk-G2DE3C7R.js +644 -0
- package/dist/chunk-G4BMMOKF.js +182 -0
- package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
- package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/{chunk-4QKXUHSR.js → chunk-IGLFWIYI.js} +70 -20
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-PFEFKVGL.js → chunk-J5HN4RYU.js} +13 -11
- package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
- package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
- package/dist/chunk-KJ5LWLOE.js +1077 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-G34LV2PF.js → chunk-LBNRH5WM.js} +84 -170
- package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
- package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
- package/dist/chunk-MAW544W2.js +1882 -0
- package/dist/chunk-MBS4V7ZP.js +217 -0
- package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
- package/dist/chunk-MNA4JGU4.js +255 -0
- package/dist/chunk-MQSRRFWA.js +3428 -0
- package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/chunk-OHHN2SO4.js +5135 -0
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
- package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/{chunk-ASND7OZK.js → chunk-QTYWRVRA.js} +13 -13
- package/dist/{chunk-EYOKLTMF.js → chunk-SRF2PJNW.js} +17 -3
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/chunk-STBPMHSX.js +2456 -0
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-Q3RUPKEJ.js → chunk-V4RXGQ5Q.js} +58 -189
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/chunk-WMSVI4G2.js +2095 -0
- package/dist/chunk-WVO7V2QY.js +797 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/chunk-X75S7HFS.js +374 -0
- package/dist/chunk-XN3L4EYL.js +46 -0
- package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
- package/dist/cli/index.js +62 -54
- package/dist/clio-4LY5K2AC.js +25 -0
- package/dist/code-nav-7AX6FYE6.js +600 -0
- package/dist/codewiki/build-worker.js +66 -0
- package/dist/compile-cache-CVJMMODC.js +18 -0
- package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
- package/dist/{config-IRUQ7SE4.js → config-GTLUW2PR.js} +92 -55
- package/dist/configure-R6A64DHX.js +42 -0
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-3KWFLHJG.js → context-JFZEJ7W5.js} +15 -13
- package/dist/{context-5RADCKTR.js → context-RW5HC47S.js} +71 -35
- package/dist/{context-clear-7TSNPAAI.js → context-clear-6ZHBAZZT.js} +54 -28
- package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
- package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
- package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
- package/dist/{doctor-UC5NAJYQ.js → doctor-KI767GSN.js} +27 -17
- package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
- package/dist/{evidence-YEGUW4L3.js → evidence-UA6AWDQQ.js} +46 -26
- package/dist/{evolve-TXARCTPG.js → evolve-QNTFGV6Z.js} +45 -25
- package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
- package/dist/{fleet-6G3DHNYE.js → fleet-Q7UOMUSG.js} +163 -54
- package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
- package/dist/{init-KZ5QTF6M.js → init-WBB65ZHQ.js} +69 -32
- package/dist/{memory-73ESV5YC.js → memory-MD3O64RI.js} +48 -27
- package/dist/{models-A4PVNWJK.js → models-BZU34YWD.js} +39 -25
- package/dist/monitor-MEQA5C3I.js +661 -0
- package/dist/{chunk-FCIH3BIZ.js → orchestrator-CGFKEP27.js} +11832 -8687
- package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
- package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
- package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
- package/dist/{run-YTPEYQOH.js → run-IV4Q6RLN.js} +101 -61
- package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
- package/dist/{skills-2V6RA3OQ.js → skills-LQEKRDTN.js} +34 -14
- package/dist/{skills-eval-S2TVJO4F.js → skills-eval-3DC4HEWS.js} +70 -34
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-TYXLPB23.js → targets-C4SSGQOB.js} +43 -27
- package/dist/terminal-lease-IT5JW2NR.js +395 -0
- package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
- package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
- package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
- package/dist/{upgrade-33G2LMM5.js → upgrade-7TT7SQ3G.js} +45 -25
- package/dist/{usage-ZAFSXKKG.js → usage-GV4PKT3M.js} +62 -31
- package/dist/verify-G6V4D2G7.js +716 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-DQF6Z66B.js} +74 -34
- package/dist/worker/entry.js +221 -36
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +22 -17
- package/docs/acp.md +168 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +136 -7
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +114 -71
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +174 -46
- package/docs/context-engine.md +29 -6
- package/docs/development-pipeline.md +26 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +13 -5
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +6 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +9 -9
- package/docs/fleet-dispatch.md +7 -5
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +34 -27
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +45 -14
- package/docs/observability.md +8 -5
- package/docs/performance-methodology.md +491 -0
- package/docs/pi-boundary.md +72 -0
- package/docs/proactive-memory.md +3 -3
- package/docs/prompt-envelope-and-tools.md +24 -3
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -115
- package/docs/safety-model.md +9 -5
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +55 -12
- package/docs/skills-marketplace.md +12 -8
- package/docs/time-conventions.md +1 -1
- package/docs/tool-usage.md +3 -3
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +47 -10
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +19 -22
- package/skills/coding/ast-grep/SKILL.md +136 -0
- package/skills/coding/ast-grep/evals.md +56 -0
- package/skills/coding/ast-grep/references/rule_reference.md +297 -0
- package/skills/coding/coding-standards/SKILL.md +113 -0
- package/skills/coding/coding-standards/evals.md +34 -0
- package/skills/coding/prototype/SKILL.md +86 -0
- package/skills/coding/prototype/evals.md +42 -0
- package/skills/coding/prototype/references/LOGIC.md +67 -0
- package/skills/coding/prototype/references/UI.md +112 -0
- package/skills/coding/tdd/SKILL.md +101 -0
- package/skills/coding/tdd/evals.md +41 -0
- package/skills/coding/tdd/references/mocking.md +59 -0
- package/skills/coding/tdd/references/tests.md +77 -0
- package/skills/context/context-handoff/SKILL.md +126 -0
- package/skills/context/context-handoff/evals.md +57 -0
- package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
- package/skills/context/context-prime/SKILL.md +95 -0
- package/skills/context/context-prime/evals.md +54 -0
- package/skills/meta/clio-dev/SKILL.md +91 -0
- package/skills/meta/clio-dev/evals.md +45 -0
- package/skills/meta/clio-test/SKILL.md +130 -0
- package/skills/meta/clio-test/evals.md +43 -0
- package/skills/meta/clio-test/references/harness.md +97 -0
- package/skills/meta/clio-test/references/test-map.md +59 -0
- package/skills/meta/credentials/SKILL.md +125 -0
- package/skills/meta/credentials/evals.md +104 -0
- package/skills/meta/find-skills/SKILL.md +72 -0
- package/skills/meta/find-skills/evals.md +47 -0
- package/skills/meta/herdr/SKILL.md +127 -0
- package/skills/meta/herdr/evals.md +38 -0
- package/skills/meta/skill-craft/SKILL.md +102 -0
- package/skills/meta/skill-craft/evals.md +41 -0
- package/skills/planning/architecture/SKILL.md +129 -0
- package/skills/planning/architecture/evals.md +36 -0
- package/skills/planning/backlog/SKILL.md +90 -0
- package/skills/planning/backlog/evals.md +43 -0
- package/skills/planning/prd/SKILL.md +82 -0
- package/skills/planning/prd/evals.md +49 -0
- package/skills/planning/product-intent/SKILL.md +112 -0
- package/skills/planning/product-intent/evals.md +36 -0
- package/skills/planning/tech-spec/SKILL.md +115 -0
- package/skills/planning/tech-spec/evals.md +47 -0
- package/skills/registry.yaml +136 -0
- package/skills/research/arxiv-literature/SKILL.md +104 -0
- package/skills/research/arxiv-literature/evals.md +58 -0
- package/skills/research/experiment-protocol/SKILL.md +122 -0
- package/skills/research/experiment-protocol/evals.md +91 -0
- package/skills/research/scientific-debugging/SKILL.md +119 -0
- package/skills/research/scientific-debugging/evals.md +138 -0
- package/skills/research/scientific-modernization/SKILL.md +138 -0
- package/skills/research/scientific-modernization/evals.md +84 -0
- package/skills/workflow/design-council/SKILL.md +139 -0
- package/skills/workflow/design-council/evals.md +97 -0
- package/skills/workflow/grill-me/SKILL.md +186 -0
- package/skills/workflow/grill-me/evals.md +78 -0
- package/skills/workflow/workflow-distiller/SKILL.md +136 -0
- package/skills/workflow/workflow-distiller/evals.md +107 -0
- package/src/cli/acp.ts +31 -4
- package/src/cli/clio.ts +68 -6
- package/src/cli/config-inspect.ts +28 -22
- package/src/cli/configure.ts +47 -9
- package/src/cli/context-clear.ts +2 -2
- package/src/cli/context-index.ts +21 -23
- package/src/cli/context.ts +13 -8
- package/src/cli/default-target.ts +9 -17
- package/src/cli/docs.ts +11 -5
- package/src/cli/evidence.ts +4 -1
- package/src/cli/extensions.ts +10 -1
- package/src/cli/fleet.ts +47 -6
- package/src/cli/index.ts +55 -26
- package/src/cli/memory.ts +3 -1
- package/src/cli/models.ts +1 -1
- package/src/cli/modes/json-stream.ts +37 -1
- package/src/cli/modes/print.ts +24 -9
- package/src/cli/run.ts +2 -2
- package/src/cli/skills-eval.ts +23 -8
- package/src/cli/skills.ts +19 -4
- package/src/cli/targets.ts +4 -0
- package/src/cli/text-layout.ts +15 -5
- package/src/cli/trace.ts +62 -14
- package/src/cli/upgrade.ts +18 -2
- package/src/cli/usage.ts +10 -3
- package/src/cli/wiki-generate.ts +2 -1
- package/src/core/agent-environment.ts +7 -0
- package/src/core/bash-exec.ts +72 -1
- package/src/core/boot-trace.ts +9 -4
- package/src/core/bus-events.ts +20 -4
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +131 -2
- package/src/core/defaults.ts +39 -5
- package/src/core/domain-loader.ts +12 -5
- package/src/core/git-commit-attribution.ts +362 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/response-schema.ts +1 -1
- package/src/core/safe-exec.ts +13 -1
- package/src/core/settings-layers.ts +155 -21
- package/src/core/skill-activation.ts +1 -1
- package/src/core/startup-timer.ts +3 -3
- package/src/core/state-file-lock.ts +13 -1
- package/src/core/termination.ts +78 -5
- package/src/domains/config/classify.ts +15 -3
- package/src/domains/config/extension.ts +19 -13
- package/src/domains/config/index.ts +10 -0
- package/src/domains/config/keybindings.ts +42 -6
- package/src/domains/context/bootstrap-prompt.ts +1 -1
- package/src/domains/context/bootstrap.ts +111 -18
- package/src/domains/context/clear.ts +16 -11
- package/src/domains/context/clio-md.ts +111 -9
- package/src/domains/context/codewiki/artifact.ts +400 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
- package/src/domains/context/codewiki/build-worker.ts +54 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/indexer.ts +59 -144
- package/src/domains/context/codewiki/paths.ts +67 -0
- package/src/domains/context/codewiki/schema.ts +80 -0
- package/src/domains/context/codewiki/tree-sitter.ts +1 -1
- package/src/domains/context/contract.ts +11 -5
- package/src/domains/context/extension.ts +94 -143
- package/src/domains/context/fingerprint.ts +3 -1
- package/src/domains/context/index.ts +12 -22
- package/src/domains/context/project-metadata.ts +19 -0
- package/src/domains/context/prompt-context.ts +9 -10
- package/src/domains/context/refresh.ts +29 -21
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/wiki/generate.ts +39 -34
- package/src/domains/context/wiki/plan.ts +1 -1
- package/src/domains/context/wiki/prompts.ts +21 -8
- package/src/domains/dispatch/code-step.ts +20 -1
- package/src/domains/dispatch/extension.ts +158 -21
- package/src/domains/dispatch/failure-classification.ts +6 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/orphan-recovery.ts +50 -8
- package/src/domains/dispatch/receipt-integrity.ts +5 -0
- package/src/domains/dispatch/state.ts +31 -6
- package/src/domains/dispatch/transport.ts +2 -1
- package/src/domains/dispatch/types.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +21 -2
- package/src/domains/eval/metrics/context.ts +1 -1
- package/src/domains/eval/types.ts +0 -1
- package/src/domains/evidence/build.ts +41 -1
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +24 -4
- package/src/domains/middleware/hooks-io.ts +12 -0
- package/src/domains/middleware/skills-reminder.ts +30 -15
- package/src/domains/prompts/compiler.ts +142 -84
- package/src/domains/prompts/contract.ts +18 -2
- package/src/domains/prompts/extension.ts +39 -7
- package/src/domains/prompts/fragment-loader.ts +0 -1
- package/src/domains/prompts/fragments/identity/clio.md +2 -4
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
- package/src/domains/prompts/fragments/operating/contract.md +4 -50
- package/src/domains/prompts/fragments/operating/delegation.md +42 -0
- package/src/domains/prompts/fragments/operating/skills.md +26 -0
- package/src/domains/prompts/fragments/operating/worker.md +16 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
- package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
- package/src/domains/prompts/fragments/safety/read-only.md +4 -4
- package/src/domains/prompts/fragments/safety/suggest.md +2 -2
- package/src/domains/prompts/fragments/wiki/page.md +10 -0
- package/src/domains/prompts/fragments/wiki/plan.md +10 -0
- package/src/domains/prompts/preload.ts +3 -3
- package/src/domains/providers/auth/api-key.ts +1 -1
- package/src/domains/providers/auth/backend-file.ts +20 -10
- package/src/domains/providers/auth/backend-memory.ts +59 -4
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/oauth.ts +2 -1
- package/src/domains/providers/auth/storage.ts +97 -38
- package/src/domains/providers/capabilities.ts +12 -4
- package/src/domains/providers/contract.ts +15 -4
- package/src/domains/providers/extension.ts +18 -6
- package/src/domains/providers/model-runtime-capabilities.ts +15 -4
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
- package/src/domains/providers/plugins.ts +5 -3
- package/src/domains/providers/probe/fingerprint.ts +25 -5
- package/src/domains/providers/registry.ts +31 -10
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -2
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/support.ts +6 -3
- package/src/domains/providers/types/local-model-quirks.ts +7 -9
- package/src/domains/providers/types/runtime-descriptor.ts +12 -1
- package/src/domains/providers/types/target-descriptor.ts +22 -0
- package/src/domains/resources/contract.ts +0 -1
- package/src/domains/resources/extension.ts +1 -3
- package/src/domains/resources/loader.ts +3 -4
- package/src/domains/resources/prompts/loader.ts +16 -2
- package/src/domains/resources/prompts/substitute.ts +1 -65
- package/src/domains/resources/skills/content-hash.ts +2 -0
- package/src/domains/resources/skills/install.ts +17 -0
- package/src/domains/resources/skills/loader.ts +17 -10
- package/src/domains/resources/skills/marketplace.ts +55 -9
- package/src/domains/safety/action-classifier.ts +4 -2
- package/src/domains/safety/audit.ts +8 -2
- package/src/domains/safety/extension.ts +1 -1
- package/src/domains/session/compaction/branch-summary.ts +3 -2
- package/src/domains/session/compaction/cut-point.ts +2 -1
- package/src/domains/session/compaction/tokens.ts +2 -1
- package/src/domains/session/context-ledger.ts +14 -0
- package/src/domains/session/contract.ts +15 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +66 -3
- package/src/domains/session/extension.ts +93 -12
- package/src/domains/session/retry.ts +10 -18
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +207 -13
- package/src/domains/session/tree/active-path.ts +44 -5
- package/src/domains/session/tree/fork.ts +26 -27
- package/src/domains/session/tree/preview.ts +2 -2
- package/src/domains/session/workspace/git-probe.ts +17 -11
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/errors.ts +96 -0
- package/src/engine/acp/server.ts +1728 -146
- package/src/engine/acp/transport.ts +135 -14
- package/src/engine/acp/types.ts +26 -0
- package/src/engine/agent.ts +3 -3
- package/src/engine/ai.ts +32 -27
- package/src/engine/alcf-oauth.ts +26 -19
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/index.ts +3 -7
- package/src/engine/apis/llamacpp-residency.ts +49 -9
- package/src/engine/apis/lmstudio-residency.ts +5 -21
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +24 -3
- package/src/engine/apis/openai-completions.ts +170 -91
- package/src/engine/apis/residency.ts +139 -3
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +16 -12
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +16 -59
- package/src/engine/strip-tokenizer-sentinels.ts +1 -1
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +17 -9
- package/src/engine/types.ts +3 -6
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1 -1
- package/src/engine/worker-tools.ts +9 -4
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +288 -150
- package/src/interactive/application-controller.ts +89 -2
- package/src/interactive/chat-loop.ts +266 -41
- package/src/interactive/chat-panel.ts +173 -47
- package/src/interactive/chat-renderer.ts +262 -72
- package/src/interactive/clio-editor.ts +3 -8
- package/src/interactive/command-fallbacks.ts +2 -2
- package/src/interactive/context-overlay.ts +27 -1
- package/src/interactive/editor-submit.ts +228 -24
- package/src/interactive/export-html/ansi-to-html.ts +161 -0
- package/src/interactive/export-html/index.ts +51 -0
- package/src/interactive/export-html/template.ts +45 -0
- package/src/interactive/export-html/tool-renderer.ts +54 -0
- package/src/interactive/footer/dashboard.ts +4 -0
- package/src/interactive/footer/notifications.ts +1 -1
- package/src/interactive/footer/widgets.ts +20 -2
- package/src/interactive/footer-panel.ts +2 -2
- package/src/interactive/format-time.ts +14 -2
- package/src/interactive/interactive-application.ts +201 -17
- package/src/interactive/interactive-event-projection.ts +6 -1
- package/src/interactive/interactive-input-runtime.ts +50 -4
- package/src/interactive/interactive-presentation.ts +151 -19
- package/src/interactive/interactive-shell.ts +268 -14
- package/src/interactive/interactive-slash-runtime.ts +176 -114
- package/src/interactive/interactive-tickers.ts +38 -7
- package/src/interactive/keybinding-manager.ts +1 -1
- package/src/interactive/layout.ts +40 -3
- package/src/interactive/overlay-frame.ts +1 -1
- package/src/interactive/overlay-general-openers.ts +58 -1
- package/src/interactive/overlay-key-routing.ts +3 -0
- package/src/interactive/overlay-lifecycle.ts +13 -0
- package/src/interactive/overlay-permission-lifecycle.ts +2 -1
- package/src/interactive/overlay-session-lifecycle.ts +69 -12
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/help-reference.ts +15 -10
- package/src/interactive/overlays/model-selector.ts +34 -16
- package/src/interactive/overlays/session-selector.ts +18 -0
- package/src/interactive/overlays/settings.ts +105 -17
- package/src/interactive/overlays/skills-hub.ts +4 -4
- package/src/interactive/overlays/tree-selector.ts +41 -6
- package/src/interactive/render-trace.ts +499 -90
- package/src/interactive/renderers/compaction-summary.ts +2 -2
- package/src/interactive/renderers/diff.ts +115 -104
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/tool-execution.ts +386 -133
- package/src/interactive/renderers/worker-entry.ts +20 -4
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/slash-autocomplete.ts +6 -114
- package/src/interactive/slash-commands.ts +135 -47
- package/src/interactive/slash-spec.ts +9 -38
- package/src/interactive/status/controller.ts +5 -1
- package/src/interactive/stdout-backpressure.ts +99 -0
- package/src/interactive/stream-pacer.ts +530 -0
- package/src/interactive/stream-pacing-policy.ts +66 -0
- package/src/interactive/tasks-overlay.ts +368 -14
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/tokens.ts +1 -1
- package/src/interactive/turn-context.ts +4 -3
- package/src/interactive/turn-persistence.ts +30 -13
- package/src/interactive/turn-queues.ts +12 -0
- package/src/interactive/turn-recovery.ts +25 -8
- package/src/interactive/turn-runtime.ts +79 -12
- package/src/interactive/turn-state.ts +10 -0
- package/src/interactive/view/artifacts.ts +114 -4
- package/src/interactive/view/view-overlay.ts +3 -0
- package/src/interactive/welcome-dashboard.ts +17 -16
- package/src/interactive/worker-receipts.ts +52 -3
- package/src/interactive/worker-stream.ts +5 -1
- package/src/tools/agent-tools.ts +23 -3
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +23 -13
- package/src/tools/bash.ts +30 -2
- package/src/tools/bootstrap.ts +34 -431
- package/src/tools/builtin-tool-catalog.ts +265 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +8 -22
- package/src/tools/codewiki/shared.ts +41 -38
- package/src/tools/context/docs-engine.ts +14 -3
- package/src/tools/context/index.ts +107 -28
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +5 -5
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +9 -4
- package/src/tools/dispatch-run-events.ts +238 -0
- package/src/tools/dispatch-runner.ts +2370 -0
- package/src/tools/dispatch-scout-admission.ts +295 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +67 -3161
- package/src/tools/find.ts +4 -2
- package/src/tools/grep.ts +2 -2
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +3 -3
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +2 -32
- package/src/tools/observers.ts +2 -2
- package/src/tools/registry.ts +39 -27
- package/src/tools/safe-exec.ts +2 -2
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +2 -13
- package/src/tools/tasks.ts +108 -11
- package/src/tools/truncate.ts +25 -184
- package/src/tools/verify/frontend.ts +3 -1
- package/src/tools/verify/index.ts +3 -38
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +2 -20
- package/src/tools/write.ts +7 -2
- package/src/worker/entry.ts +39 -2
- package/src/worker/spec-contract.ts +26 -5
- package/dist/chunk-7SS2CTV2.js +0 -61361
- package/dist/chunk-DKGKUHFA.js +0 -924
- package/dist/chunk-GEP36Y4X.js +0 -12796
- package/dist/chunk-XYWBQRDM.js +0 -137
- package/dist/clio-BZVGEUFJ.js +0 -58
- package/dist/configure-S7S6F6CL.js +0 -32
- package/docs/html/agents_blueprint.html +0 -936
- package/docs/html/alcf_blueprint.html +0 -324
- package/docs/html/architecture_blueprint.html +0 -850
- package/docs/html/commands_blueprint.html +0 -939
- package/docs/html/config_knobs_audit_blueprint.html +0 -178
- package/docs/html/configuration_blueprint.html +0 -1080
- package/docs/html/context_blueprint.html +0 -603
- package/docs/html/documentation_blueprint.html +0 -832
- package/docs/html/environment_blueprint.html +0 -404
- package/docs/html/eval_blueprint.html +0 -743
- package/docs/html/evals_internal_blueprint.html +0 -190
- package/docs/html/evolution_blueprint.html +0 -674
- package/docs/html/extensions_blueprint.html +0 -2065
- package/docs/html/fleet_dispatch_blueprint.html +0 -286
- package/docs/html/index.html +0 -919
- package/docs/html/lifecycle_blueprint.html +0 -723
- package/docs/html/memory_blueprint.html +0 -699
- package/docs/html/middleware_blueprint.html +0 -664
- package/docs/html/models_blueprint.html +0 -2366
- package/docs/html/observability_blueprint.html +0 -683
- package/docs/html/provider_adapter_blueprint.html +0 -245
- package/docs/html/safety_blueprint.html +0 -1386
- package/docs/html/shared.css +0 -571
- package/docs/html/shared.js +0 -143
- package/docs/html/skills_blueprint.html +0 -671
- package/docs/html/soak_blueprint.html +0 -182
- package/docs/html/tool_usage_blueprint.html +0 -350
- package/docs/html/tools_blueprint.html +0 -2249
- package/docs/html/trace_blueprint.html +0 -235
- package/docs/html/tui_design_blueprint.html +0 -374
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/src/core/release.ts +0 -2
- package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
- package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
- package/src/engine/apis/lmstudio-native.ts +0 -1438
- package/src/engine/apis/thinking-replay.ts +0 -11
- package/src/tools/string-enum.ts +0 -15
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { sanitizeCallTargetText } from "../../domains/safety/call-target.js";
|
|
16
|
+
import { formatSize } from "../../engine/truncate.js";
|
|
16
17
|
import { visibleWidth, wrapTextWithAnsi } from "../../engine/tui.js";
|
|
18
|
+
import type { ApprovalRequestView } from "../permission-overlay.js";
|
|
17
19
|
import { clioTheme, formatCompactMs, GLYPH } from "../theme/index.js";
|
|
18
|
-
import {
|
|
20
|
+
import { renderDiffLines } from "./diff.js";
|
|
19
21
|
import { tryRenderJson, tryRenderXml } from "./structured.js";
|
|
20
22
|
|
|
21
23
|
const theme = clioTheme();
|
|
@@ -34,7 +36,6 @@ const BODY_INDENT_VISIBLE_WIDTH = 2;
|
|
|
34
36
|
const HEADER_PREFIX_PLAIN = "▸ ";
|
|
35
37
|
const ARG_PREVIEW_LIMIT = 60;
|
|
36
38
|
const WEB_FETCH_ARG_PREVIEW_LIMIT = 140;
|
|
37
|
-
const RESULT_PREVIEW_LIMIT = 4000;
|
|
38
39
|
const FULL_RESULT_PREVIEW_LIMIT = 60_000;
|
|
39
40
|
const FULL_RESULT_ROW_LIMIT = 120;
|
|
40
41
|
const STREAMING_RESULT_ROW_LIMIT = 20;
|
|
@@ -54,6 +55,8 @@ export interface ToolExecutionStart {
|
|
|
54
55
|
args: unknown;
|
|
55
56
|
/** Live elapsed time supplied by the panel for running segments. */
|
|
56
57
|
elapsedMs?: number | undefined;
|
|
58
|
+
/** Pi may stream a tool call's arguments before execution starts. */
|
|
59
|
+
phase?: "forming" | "ready" | "running" | undefined;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
export interface ToolExecutionFinished {
|
|
@@ -73,6 +76,10 @@ export interface ToolExecutionFinished {
|
|
|
73
76
|
* model reading the same transcript, to guess at the rule.
|
|
74
77
|
*/
|
|
75
78
|
blockReason?: string | undefined;
|
|
79
|
+
/** Structured exit status when the caller has one; text parsing is legacy fallback only. */
|
|
80
|
+
exitCode?: number | string | null | undefined;
|
|
81
|
+
/** Local `!!` bash output is visible to the operator but excluded from model context. */
|
|
82
|
+
excludeFromContext?: boolean | undefined;
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
export interface ToolBodyRenderOptions {
|
|
@@ -83,6 +90,8 @@ export interface ToolBodyRenderOptions {
|
|
|
83
90
|
* the complete tool output the model actually received.
|
|
84
91
|
*/
|
|
85
92
|
unbounded?: boolean;
|
|
93
|
+
/** Live rows color mutation diffs; replay and export deliberately use plain text. */
|
|
94
|
+
diffStyle?: "color" | "plain";
|
|
86
95
|
}
|
|
87
96
|
|
|
88
97
|
/** Row cap for a tool body: unbounded lifts both the row and char limits. */
|
|
@@ -218,10 +227,9 @@ function bashExitCodeFromResult(result: unknown): string | null {
|
|
|
218
227
|
|
|
219
228
|
/**
|
|
220
229
|
* Map of known tools to their canonical "primary" arg field. When the arg is
|
|
221
|
-
* a string the header summarises it directly and the
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
* to a JSON-dump summary plus the full args body.
|
|
230
|
+
* a string the header summarises it directly and the expanded argument list
|
|
231
|
+
* omits only that repeated field. Tools not in this map (or with an unexpected
|
|
232
|
+
* arg shape) fall back to a JSON summary plus their complete redacted fields.
|
|
225
233
|
*/
|
|
226
234
|
const PRIMARY_ARG_FIELD: Record<string, string> = {
|
|
227
235
|
read: "path",
|
|
@@ -244,8 +252,8 @@ const PRIMARY_ARG_FIELD: Record<string, string> = {
|
|
|
244
252
|
|
|
245
253
|
/**
|
|
246
254
|
* Returns the captured primary-arg string when the header successfully used a
|
|
247
|
-
* known tool's canonical arg, otherwise null.
|
|
248
|
-
*
|
|
255
|
+
* known tool's canonical arg, otherwise null. The argument renderer uses the
|
|
256
|
+
* same map to omit that one repeated field below `read(README.md)`.
|
|
249
257
|
*/
|
|
250
258
|
function capturedPrimaryArg(toolName: string, args: unknown): string | null {
|
|
251
259
|
const field = PRIMARY_ARG_FIELD[toolName];
|
|
@@ -318,12 +326,6 @@ function stringField(record: Record<string, unknown> | null, key: string): strin
|
|
|
318
326
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
319
327
|
}
|
|
320
328
|
|
|
321
|
-
function formatBytes(bytes: number): string {
|
|
322
|
-
if (bytes < 1024) return `${bytes}B`;
|
|
323
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
324
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
329
|
function countSummary(observation: Record<string, unknown>): string | null {
|
|
328
330
|
const unit = stringField(observation, "unit") ?? "results";
|
|
329
331
|
const shown = numberField(observation, "shownCount");
|
|
@@ -396,9 +398,46 @@ function shownBytesOf(finished: ToolExecutionFinished): number | null {
|
|
|
396
398
|
const observation = observationOf(finished);
|
|
397
399
|
const fromObservation = numberField(observation, "shownBytes");
|
|
398
400
|
if (fromObservation !== null) return fromObservation;
|
|
401
|
+
const resultSize = detailsOf(finished.result)?.resultSize;
|
|
402
|
+
const fromResultSize = isPlainObject(resultSize) ? numberField(resultSize, "shownBytes") : null;
|
|
403
|
+
if (fromResultSize !== null) return fromResultSize;
|
|
399
404
|
return numberField(finished.resultSummary ?? null, "bytes");
|
|
400
405
|
}
|
|
401
406
|
|
|
407
|
+
function totalBytesOf(finished: ToolExecutionFinished): number | null {
|
|
408
|
+
const observation = observationOf(finished);
|
|
409
|
+
const fromObservation = numberField(observation, "totalBytes");
|
|
410
|
+
if (fromObservation !== null) return fromObservation;
|
|
411
|
+
const resultSize = detailsOf(finished.result)?.resultSize;
|
|
412
|
+
if (isPlainObject(resultSize)) {
|
|
413
|
+
const total = numberField(resultSize, "bytes");
|
|
414
|
+
if (total !== null) return total;
|
|
415
|
+
}
|
|
416
|
+
return shownBytesOf(finished);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function resultSizeOf(finished: ToolExecutionFinished): Record<string, unknown> | null {
|
|
420
|
+
const value = detailsOf(finished.result)?.resultSize;
|
|
421
|
+
return isPlainObject(value) ? value : null;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function isTruncatedResult(finished: ToolExecutionFinished): boolean {
|
|
425
|
+
const observation = observationOf(finished);
|
|
426
|
+
if (observation?.truncated === true) return true;
|
|
427
|
+
if (resultSizeOf(finished)?.truncated === true) return true;
|
|
428
|
+
const truncation = detailsOf(finished.result)?.truncation;
|
|
429
|
+
if (isPlainObject(truncation) && truncation.truncated === true) return true;
|
|
430
|
+
return finished.resultSummary?.truncated === true;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function structuredExitCode(finished: ToolExecutionFinished): string | null {
|
|
434
|
+
if (isNonExecutedOutcome(finished.outcome)) return null;
|
|
435
|
+
if (finished.exitCode !== undefined && finished.exitCode !== null) return String(finished.exitCode);
|
|
436
|
+
const exitCode = detailsOf(finished.result)?.exitCode;
|
|
437
|
+
if (typeof exitCode === "number" || typeof exitCode === "string") return String(exitCode);
|
|
438
|
+
return finished.toolName === "bash" && finished.isError ? bashExitCodeFromResult(finished.result) : null;
|
|
439
|
+
}
|
|
440
|
+
|
|
402
441
|
/**
|
|
403
442
|
* The dim ledger tail appended to a finished collapsed subline: outcome facts,
|
|
404
443
|
* then byte size (duration rides on the status glyph), then the offload path
|
|
@@ -410,7 +449,7 @@ function ledgerTail(finished: ToolExecutionFinished): { facts: string; offload:
|
|
|
410
449
|
const outcome = outcomeSummary(finished);
|
|
411
450
|
if (outcome !== null) parts.push(outcome);
|
|
412
451
|
const bytes = isNonExecutedOutcome(finished.outcome) ? null : shownBytesOf(finished);
|
|
413
|
-
if (bytes !== null && bytes > 0) parts.push(
|
|
452
|
+
if (bytes !== null && bytes > 0) parts.push(formatSize(bytes));
|
|
414
453
|
const offloadPath = offloadPathOf(finished);
|
|
415
454
|
return {
|
|
416
455
|
facts: parts.length > 0 ? dim(` · ${parts.join(" · ")}`) : "",
|
|
@@ -430,24 +469,40 @@ const AWAITING_APPROVAL_TAIL = ` ${yellow(GLYPH.phaseBlocked)}${dim(" awaiting a
|
|
|
430
469
|
* No elapsed counter (nothing is running) and no status glyph (nothing has
|
|
431
470
|
* finished): the awaiting-approval tail is the segment's whole state.
|
|
432
471
|
*/
|
|
433
|
-
export function renderToolAwaitingApproval(
|
|
472
|
+
export function renderToolAwaitingApproval(
|
|
473
|
+
call: ToolExecutionStart,
|
|
474
|
+
width: number,
|
|
475
|
+
view?: ApprovalRequestView,
|
|
476
|
+
): string[] {
|
|
434
477
|
const parts = sublineParts({ toolCallId: call.toolCallId, toolName: call.toolName, args: call.args }, undefined, {});
|
|
435
|
-
|
|
478
|
+
const lines = wrapSublineWithTail(parts.lead, AWAITING_APPROVAL_TAIL, width);
|
|
479
|
+
if (view === undefined) return lines;
|
|
480
|
+
const axis = view.axis.kind === "net" ? `safety-net rail ${view.axis.ruleId}` : `autonomy level ${view.axis.level}`;
|
|
481
|
+
const facts = [
|
|
482
|
+
["action", view.actionClass],
|
|
483
|
+
["axis", axis],
|
|
484
|
+
...(view.target !== undefined && view.target.length > 0 ? [["target", view.target]] : []),
|
|
485
|
+
] as const;
|
|
486
|
+
for (const [label, value] of facts) {
|
|
487
|
+
lines.push(...indentAndWrap(`${dim(`${label} ·`)} ${value}`, width, false));
|
|
488
|
+
}
|
|
489
|
+
return lines;
|
|
436
490
|
}
|
|
437
491
|
|
|
438
492
|
/**
|
|
439
|
-
* Header status
|
|
440
|
-
* `"ok"`
|
|
493
|
+
* Header status follows Pi's call lifecycle before and during execution, then
|
|
494
|
+
* becomes `"ok"` or `"error"` at settlement. The
|
|
441
495
|
* glyph hangs off the right of the header line so the tool name + args read
|
|
442
496
|
* left-to-right without extra punctuation.
|
|
443
497
|
*/
|
|
444
|
-
type HeaderStatus = "ok" | "error" | undefined;
|
|
498
|
+
type HeaderStatus = "forming" | "ready" | "running" | "ok" | "error" | undefined;
|
|
445
499
|
|
|
446
500
|
/** Keeps a refusal reason to one scannable clause on the status tail. */
|
|
447
501
|
const BLOCK_REASON_LIMIT = 72;
|
|
448
502
|
|
|
449
503
|
interface StatusMeta {
|
|
450
504
|
durationMs?: number | undefined;
|
|
505
|
+
elapsedMs?: number | undefined;
|
|
451
506
|
exitCode?: string | null;
|
|
452
507
|
outcome?: ToolExecutionFinished["outcome"];
|
|
453
508
|
/** Refusal reason, rendered only alongside a non-executed outcome. */
|
|
@@ -456,6 +511,12 @@ interface StatusMeta {
|
|
|
456
511
|
|
|
457
512
|
function statusGlyph(status: HeaderStatus, meta: StatusMeta = {}): string {
|
|
458
513
|
if (status === undefined) return "";
|
|
514
|
+
if (status === "forming") return ` ${dim(GLYPH.queued)}${dim(" forming call")}`;
|
|
515
|
+
if (status === "ready") return ` ${dim(GLYPH.queued)}${dim(" ready")}`;
|
|
516
|
+
if (status === "running") {
|
|
517
|
+
const elapsed = optionalCompactMs(meta.elapsedMs);
|
|
518
|
+
return ` ${cyan(GLYPH.running)}${dim(elapsed === null ? " running" : ` running · ${elapsed}`)}`;
|
|
519
|
+
}
|
|
459
520
|
const duration = optionalCompactMs(meta.durationMs);
|
|
460
521
|
const durationSuffix = duration ? dim(` · ${duration}`) : "";
|
|
461
522
|
if (status === "ok") return ` ${green(STATUS_OK_GLYPH)}${durationSuffix}`;
|
|
@@ -615,12 +676,13 @@ function buildSublineBody(
|
|
|
615
676
|
outcome?: ToolExecutionFinished["outcome"],
|
|
616
677
|
): string {
|
|
617
678
|
if (isNonExecutedOutcome(outcome)) return buildUnknownToolBody(toolName, args);
|
|
679
|
+
if (status === "forming" || status === "ready") return buildUnknownToolBody(toolName, args);
|
|
618
680
|
if (toolName === "web_fetch") {
|
|
619
681
|
const meta = status === undefined ? null : webFetchMeta(result);
|
|
620
682
|
return `${buildUnknownToolBody(toolName, args)}${meta ? dim(` · ${meta}`) : ""}`;
|
|
621
683
|
}
|
|
622
684
|
if (toolName === "bash") {
|
|
623
|
-
const lead = status === undefined ? "running " : "ran ";
|
|
685
|
+
const lead = status === "running" || status === undefined ? "running " : "ran ";
|
|
624
686
|
return (
|
|
625
687
|
buildFieldSublineBody(args, "command", lead, { wrapInBackticks: true }) ?? buildUnknownToolBody(toolName, args)
|
|
626
688
|
);
|
|
@@ -660,9 +722,7 @@ function sublineParts(
|
|
|
660
722
|
tail: `${statusGlyph(status, meta)}${ledger.offload}`,
|
|
661
723
|
};
|
|
662
724
|
}
|
|
663
|
-
|
|
664
|
-
const running = elapsed !== null ? dim(` · ${elapsed}`) : "";
|
|
665
|
-
return { lead: `${dim(HEADER_PREFIX_PLAIN)}${body}${resource}${running}`, tail: "" };
|
|
725
|
+
return { lead: `${dim(HEADER_PREFIX_PLAIN)}${body}${resource}`, tail: statusGlyph(status, meta) };
|
|
666
726
|
}
|
|
667
727
|
|
|
668
728
|
/**
|
|
@@ -708,33 +768,69 @@ function indentAndWrap(line: string, width: number, isError: boolean): string[]
|
|
|
708
768
|
return out;
|
|
709
769
|
}
|
|
710
770
|
|
|
771
|
+
function scalarArgValue(value: unknown): string | null {
|
|
772
|
+
if (typeof value === "string") {
|
|
773
|
+
const lines = value.split("\n").length;
|
|
774
|
+
const bytes = Buffer.byteLength(value, "utf8");
|
|
775
|
+
if (lines > 1 || value.length > 160) return dim(`<${lines} lines · ${formatSize(bytes)} text>`);
|
|
776
|
+
return green(JSON.stringify(value));
|
|
777
|
+
}
|
|
778
|
+
if (typeof value === "number") return cyan(String(value));
|
|
779
|
+
if (typeof value === "boolean") return yellow(String(value));
|
|
780
|
+
if (value === null) return dim("null");
|
|
781
|
+
return null;
|
|
782
|
+
}
|
|
783
|
+
|
|
711
784
|
/**
|
|
712
|
-
* Render
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
785
|
+
* Render secondary arguments as a compact typed field list. The primary path,
|
|
786
|
+
* command, pattern, or query already lives in the call signature; keeping the
|
|
787
|
+
* rest means `cwd`, timeout, range, glob, and flags no longer disappear merely
|
|
788
|
+
* because one field was important enough for the header. Nested values retain
|
|
789
|
+
* the structured JSON renderer, while large strings become byte/line facts
|
|
790
|
+
* instead of flooding the transcript.
|
|
717
791
|
*/
|
|
718
|
-
function renderArgsBody(args: unknown, width: number, isError: boolean): string[] {
|
|
792
|
+
function renderArgsBody(toolName: string, args: unknown, width: number, isError: boolean): string[] {
|
|
719
793
|
if (isEmptyArgs(args)) return [];
|
|
794
|
+
const safeArgs = redactToolArgs(args);
|
|
795
|
+
if (!isPlainObject(safeArgs)) {
|
|
796
|
+
const bodyWidth = Math.max(1, width - BODY_INDENT_VISIBLE_WIDTH);
|
|
797
|
+
const lines = tryRenderJson(safeArgs, bodyWidth, { lineLimit: ARGS_BODY_LINE_LIMIT });
|
|
798
|
+
return lines?.flatMap((line) => indentAndWrap(line, width, isError)) ?? [];
|
|
799
|
+
}
|
|
800
|
+
const primary = PRIMARY_ARG_FIELD[toolName];
|
|
801
|
+
const entries = Object.entries(safeArgs).filter(([key]) => key !== primary);
|
|
802
|
+
if (entries.length === 0) return [];
|
|
720
803
|
const out: string[] = [];
|
|
721
804
|
const bodyWidth = Math.max(1, width - BODY_INDENT_VISIBLE_WIDTH);
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
for (const
|
|
725
|
-
|
|
805
|
+
out.push(...indentAndWrap(`${cyanBold("args")}${dim(` · ${entries.length}`)}`, width, isError));
|
|
806
|
+
const keyWidth = Math.min(18, Math.max(...entries.map(([key]) => visibleWidth(key))));
|
|
807
|
+
for (const [key, value] of entries) {
|
|
808
|
+
const label = `${cyan(key.padEnd(keyWidth))} `;
|
|
809
|
+
const scalar = scalarArgValue(value);
|
|
810
|
+
if (scalar !== null) {
|
|
811
|
+
out.push(...indentAndWrap(`${label}${scalar}`, width, isError));
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
814
|
+
out.push(...indentAndWrap(cyan(key), width, isError));
|
|
815
|
+
const lines = tryRenderJson(value, Math.max(1, bodyWidth - 2), { lineLimit: ARGS_BODY_LINE_LIMIT });
|
|
816
|
+
for (const line of lines ?? [jsonStringifySafe(value)]) {
|
|
817
|
+
out.push(...indentAndWrap(` ${line}`, width, isError));
|
|
818
|
+
if (out.length >= ARGS_BODY_LINE_LIMIT) break;
|
|
819
|
+
}
|
|
820
|
+
if (out.length >= ARGS_BODY_LINE_LIMIT) break;
|
|
726
821
|
}
|
|
822
|
+
if (out.length >= ARGS_BODY_LINE_LIMIT) out.push(...indentAndWrap(dim("… more arguments hidden"), width, isError));
|
|
727
823
|
return out;
|
|
728
824
|
}
|
|
729
825
|
|
|
730
826
|
/**
|
|
731
827
|
* pi-agent-core wraps tool results in `{ content: [{ type: "text", text }, ...] }`
|
|
732
|
-
* envelopes. Rendering that JSON verbatim hides the actual
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
*
|
|
828
|
+
* envelopes. Rendering that JSON verbatim hides the actual output and, for a
|
|
829
|
+
* mixed result, can dump a base64 image into the terminal. Text blocks are
|
|
830
|
+
* joined, image blocks become compact MIME/size placeholders, and unknown
|
|
831
|
+
* content blocks are named without serializing their payload.
|
|
736
832
|
*/
|
|
737
|
-
|
|
833
|
+
function unwrapResultEnvelope(result: unknown): unknown {
|
|
738
834
|
if (typeof result === "string" || result === null || result === undefined) return result;
|
|
739
835
|
const blocks = Array.isArray(result)
|
|
740
836
|
? result
|
|
@@ -745,16 +841,25 @@ export function unwrapResultEnvelope(result: unknown): unknown {
|
|
|
745
841
|
const parts: string[] = [];
|
|
746
842
|
for (const block of blocks) {
|
|
747
843
|
if (!isPlainObject(block)) return result;
|
|
748
|
-
if (block.type
|
|
749
|
-
|
|
844
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
845
|
+
parts.push(block.text);
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
if (block.type === "image" && typeof block.data === "string") {
|
|
849
|
+
const mimeType = typeof block.mimeType === "string" ? block.mimeType : "image/unknown";
|
|
850
|
+
const padding = block.data.endsWith("==") ? 2 : block.data.endsWith("=") ? 1 : 0;
|
|
851
|
+
const bytes = Math.max(0, Math.floor((block.data.length * 3) / 4) - padding);
|
|
852
|
+
parts.push(`[image ${mimeType} · ${formatSize(bytes)}]`);
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
855
|
+
if (typeof block.type === "string") {
|
|
856
|
+
parts.push(`[${block.type} content]`);
|
|
857
|
+
continue;
|
|
858
|
+
}
|
|
859
|
+
return result;
|
|
750
860
|
}
|
|
751
861
|
if (parts.length === 0) return result;
|
|
752
|
-
return parts.join("");
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
export function previewResult(result: unknown): string {
|
|
756
|
-
if (typeof result === "string") return truncate(result, RESULT_PREVIEW_LIMIT);
|
|
757
|
-
return truncate(jsonStringifySafe(result), RESULT_PREVIEW_LIMIT);
|
|
862
|
+
return parts.join("\n");
|
|
758
863
|
}
|
|
759
864
|
|
|
760
865
|
function isEmptyResult(result: unknown): boolean {
|
|
@@ -822,50 +927,14 @@ function highlightBashCommand(command: string): string {
|
|
|
822
927
|
.join("");
|
|
823
928
|
}
|
|
824
929
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
new_string: string;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
/**
|
|
832
|
-
* Defensive shape check: edit-tool args must carry both `old_string` and
|
|
833
|
-
* `new_string` strings before we can render a diff. `path` is optional; the
|
|
834
|
-
* diff renderer falls back to `"file"` when absent. Anything else falls
|
|
835
|
-
* through to the standard result block so the dispatch is opportunistic and
|
|
836
|
-
* never throws.
|
|
837
|
-
*/
|
|
838
|
-
function asEditDiffArgs(args: unknown): EditDiffArgs | null {
|
|
839
|
-
if (!isPlainObject(args)) return null;
|
|
840
|
-
const oldString = args.old_string;
|
|
841
|
-
const newString = args.new_string;
|
|
842
|
-
if (typeof oldString !== "string" || typeof newString !== "string") return null;
|
|
843
|
-
const out: EditDiffArgs = { old_string: oldString, new_string: newString };
|
|
844
|
-
if (typeof args.path === "string") out.path = args.path;
|
|
845
|
-
return out;
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
// The `diff` library appends a `` sentinel row when a
|
|
849
|
-
// side of the comparison lacks a trailing newline. It is transcript noise, so
|
|
850
|
-
// the edit diff block drops it. The marker text carries no ANSI, so a substring
|
|
851
|
-
// check against the styled row is reliable and keeps this module free of raw
|
|
852
|
-
// escape literals.
|
|
853
|
-
const NO_NEWLINE_MARKER = "\";
|
|
854
|
-
|
|
855
|
-
function isNoNewlineMarkerRow(row: string): boolean {
|
|
856
|
-
return row.includes(NO_NEWLINE_MARKER);
|
|
930
|
+
function resultDiff(result: unknown): string | null {
|
|
931
|
+
const value = detailsOf(result)?.diff;
|
|
932
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
857
933
|
}
|
|
858
934
|
|
|
859
|
-
function
|
|
935
|
+
function renderMutationDiffBlock(diff: string, width: number, color: boolean): string[] {
|
|
860
936
|
const bodyWidth = Math.max(1, width - BODY_INDENT_VISIBLE_WIDTH);
|
|
861
|
-
|
|
862
|
-
if (args.path !== undefined) input.filename = args.path;
|
|
863
|
-
const out: string[] = [];
|
|
864
|
-
for (const line of renderUnifiedDiff(input, bodyWidth)) {
|
|
865
|
-
if (isNoNewlineMarkerRow(line)) continue;
|
|
866
|
-
out.push(`${RAIL_DIM}${line}`);
|
|
867
|
-
}
|
|
868
|
-
return out;
|
|
937
|
+
return renderDiffLines(diff, bodyWidth, { color }).map((line) => `${RAIL_DIM}${line}`);
|
|
869
938
|
}
|
|
870
939
|
|
|
871
940
|
interface BashArgs {
|
|
@@ -884,6 +953,79 @@ function asBashArgs(args: unknown): BashArgs | null {
|
|
|
884
953
|
return { command: redactSecretString(command) };
|
|
885
954
|
}
|
|
886
955
|
|
|
956
|
+
function resultLineCount(result: unknown): number {
|
|
957
|
+
const unwrapped = unwrapResultEnvelope(result);
|
|
958
|
+
if (typeof unwrapped !== "string" || unwrapped.length === 0) return 0;
|
|
959
|
+
const normalized = unwrapped.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
960
|
+
const withoutTerminator = normalized.endsWith("\n") ? normalized.slice(0, -1) : normalized;
|
|
961
|
+
return withoutTerminator.split("\n").length;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
function toolUsageFact(result: unknown): string | null {
|
|
965
|
+
if (!isPlainObject(result) || !isPlainObject(result.usage)) return null;
|
|
966
|
+
const total = numberField(result.usage, "totalTokens");
|
|
967
|
+
if (total === null || total <= 0) return null;
|
|
968
|
+
return `${total} tool token${total === 1 ? "" : "s"}`;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
function outputFacts(finished: ToolExecutionFinished): string[] {
|
|
972
|
+
const parts: string[] = [];
|
|
973
|
+
if (isNonExecutedOutcome(finished.outcome)) {
|
|
974
|
+
if (finished.excludeFromContext === true) parts.push("excluded from context");
|
|
975
|
+
return parts;
|
|
976
|
+
}
|
|
977
|
+
const exitCode = structuredExitCode(finished) ?? (finished.toolName === "bash" && !finished.isError ? "0" : null);
|
|
978
|
+
if (exitCode !== null) parts.push(`exit ${exitCode}`);
|
|
979
|
+
const observation = observationOf(finished);
|
|
980
|
+
const count = observation === null ? null : countSummary(observation);
|
|
981
|
+
if (count !== null) parts.push(count);
|
|
982
|
+
const lines = resultLineCount(finished.result);
|
|
983
|
+
if (count === null && lines > 0) parts.push(`${lines} line${lines === 1 ? "" : "s"}`);
|
|
984
|
+
const shownBytes = shownBytesOf(finished);
|
|
985
|
+
const totalBytes = totalBytesOf(finished);
|
|
986
|
+
if (shownBytes !== null && shownBytes > 0) {
|
|
987
|
+
parts.push(
|
|
988
|
+
totalBytes !== null && totalBytes > shownBytes
|
|
989
|
+
? `${formatSize(shownBytes)} shown / ${formatSize(totalBytes)} total`
|
|
990
|
+
: formatSize(shownBytes),
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
if (isTruncatedResult(finished)) parts.push("truncated");
|
|
994
|
+
const details = detailsOf(finished.result);
|
|
995
|
+
if (details?.timedOut === true) parts.push("timed out");
|
|
996
|
+
if (details?.outputCapped === true) parts.push("output capped");
|
|
997
|
+
const usage = toolUsageFact(finished.result);
|
|
998
|
+
if (usage !== null) parts.push(usage);
|
|
999
|
+
if (isPlainObject(finished.result) && Array.isArray(finished.result.addedToolNames)) {
|
|
1000
|
+
const added = finished.result.addedToolNames.filter((name): name is string => typeof name === "string");
|
|
1001
|
+
if (added.length > 0) parts.push(`added ${added.join(", ")}`);
|
|
1002
|
+
}
|
|
1003
|
+
if (isPlainObject(finished.result) && finished.result.terminate === true) parts.push("terminal result");
|
|
1004
|
+
if (finished.excludeFromContext === true) parts.push("excluded from context");
|
|
1005
|
+
return parts;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
function renderOutputMeta(
|
|
1009
|
+
finished: ToolExecutionFinished,
|
|
1010
|
+
width: number,
|
|
1011
|
+
isError: boolean,
|
|
1012
|
+
label = "output",
|
|
1013
|
+
): string[] {
|
|
1014
|
+
const facts = outputFacts(finished);
|
|
1015
|
+
const suffix = facts.length > 0 ? dim(` · ${facts.join(" · ")}`) : "";
|
|
1016
|
+
return indentAndWrap(`${cyanBold(label)}${suffix}`, width, isError);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
function renderOutputFooter(finished: ToolExecutionFinished, width: number, isError: boolean): string[] {
|
|
1020
|
+
const out: string[] = [];
|
|
1021
|
+
const offloadPath = isNonExecutedOutcome(finished.outcome) ? null : offloadPathOf(finished);
|
|
1022
|
+
if (offloadPath !== null) out.push(...indentAndWrap(`${yellow("full output")} ${offloadPath}`, width, isError));
|
|
1023
|
+
const hint =
|
|
1024
|
+
stringField(resultSizeOf(finished), "followUpHint") ?? stringField(finished.resultSummary ?? null, "followUpHint");
|
|
1025
|
+
if (hint !== null) out.push(...indentAndWrap(`${dim("next")} ${hint}`, width, isError));
|
|
1026
|
+
return out;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
887
1029
|
/**
|
|
888
1030
|
* Bash subrenderer: emits `$ <cmd>` (full command) on its own line under the
|
|
889
1031
|
* rail, then the unwrapped output via the same chain as `renderResultBlock`.
|
|
@@ -927,11 +1069,17 @@ function renderResultBlock(
|
|
|
927
1069
|
|
|
928
1070
|
/**
|
|
929
1071
|
* Header-only render for a tool call that has not yet finished. Used by the
|
|
930
|
-
* live chat panel
|
|
931
|
-
*
|
|
1072
|
+
* live chat panel from streamed argument formation through execution. The
|
|
1073
|
+
* lifecycle tail distinguishes a forming call, a ready call, and a running
|
|
1074
|
+
* call without inventing execution time before Pi starts the tool.
|
|
932
1075
|
*/
|
|
933
1076
|
export function renderToolCallHeader(call: ToolExecutionStart, width: number): string[] {
|
|
934
|
-
return wrap(
|
|
1077
|
+
return wrap(
|
|
1078
|
+
headerLine(call.toolName, call.args, call.phase ?? "running", {
|
|
1079
|
+
elapsedMs: call.elapsedMs,
|
|
1080
|
+
}),
|
|
1081
|
+
width,
|
|
1082
|
+
);
|
|
935
1083
|
}
|
|
936
1084
|
|
|
937
1085
|
/** Running-only footer used when an operator pauses live output; execution continues. */
|
|
@@ -939,11 +1087,7 @@ export function renderToolRunningStatus(call: ToolExecutionStart, width: number)
|
|
|
939
1087
|
const elapsed = optionalCompactMs(call.elapsedMs);
|
|
940
1088
|
return [
|
|
941
1089
|
...renderToolCallHeader(call, width),
|
|
942
|
-
...indentAndWrap(
|
|
943
|
-
dim(elapsed ? `(running... ${elapsed}; live output hidden)` : "(running; live output hidden)"),
|
|
944
|
-
width,
|
|
945
|
-
false,
|
|
946
|
-
),
|
|
1090
|
+
...indentAndWrap(dim(elapsed ? `live output paused · ${elapsed}` : "live output paused"), width, false),
|
|
947
1091
|
];
|
|
948
1092
|
}
|
|
949
1093
|
|
|
@@ -952,7 +1096,7 @@ function sublineStatus(call: ToolExecutionStart | ToolExecutionFinished): Header
|
|
|
952
1096
|
// carries a `result` field, so a `ToolExecutionStart` with a stray
|
|
953
1097
|
// `isError: false` (e.g. from a future event-shape change) cannot trip the
|
|
954
1098
|
// finished path. `result` is the type's load-bearing field.
|
|
955
|
-
if (!("result" in call)) return
|
|
1099
|
+
if (!("result" in call)) return call.phase ?? "running";
|
|
956
1100
|
return call.isError ? "error" : "ok";
|
|
957
1101
|
}
|
|
958
1102
|
|
|
@@ -982,13 +1126,13 @@ export function renderToolSubline(
|
|
|
982
1126
|
"result" in call
|
|
983
1127
|
? {
|
|
984
1128
|
durationMs: call.durationMs,
|
|
985
|
-
exitCode:
|
|
1129
|
+
exitCode: structuredExitCode(call),
|
|
986
1130
|
outcome: call.outcome,
|
|
987
1131
|
blockReason: call.blockReason,
|
|
988
1132
|
}
|
|
989
|
-
: {};
|
|
1133
|
+
: { elapsedMs: call.elapsedMs };
|
|
990
1134
|
const parts = sublineParts(call, status, meta);
|
|
991
|
-
const showHint =
|
|
1135
|
+
const showHint = "result" in call && expandKey !== undefined && expandKey.length > 0;
|
|
992
1136
|
const tail = showHint ? `${parts.tail}${dim(` (${expandKey})`)}` : parts.tail;
|
|
993
1137
|
return wrapSublineWithTail(parts.lead, tail, width);
|
|
994
1138
|
}
|
|
@@ -1008,22 +1152,23 @@ export function renderToolExecution(
|
|
|
1008
1152
|
const status: HeaderStatus = finished.isError ? "error" : "ok";
|
|
1009
1153
|
const statusMeta: StatusMeta = {
|
|
1010
1154
|
durationMs: finished.durationMs,
|
|
1011
|
-
exitCode:
|
|
1155
|
+
exitCode: structuredExitCode(finished),
|
|
1012
1156
|
outcome: finished.outcome,
|
|
1013
1157
|
blockReason: finished.blockReason,
|
|
1014
1158
|
};
|
|
1015
1159
|
const out: string[] = [];
|
|
1016
1160
|
out.push(...wrap(headerLine(finished.toolName, finished.args, status, statusMeta), width));
|
|
1017
1161
|
|
|
1018
|
-
// Edit
|
|
1019
|
-
//
|
|
1020
|
-
//
|
|
1021
|
-
//
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
out.push(...
|
|
1162
|
+
// Edit and write tools produce one bounded numbered diff on result.details.
|
|
1163
|
+
// It is the authority because canonical edit args can contain multiple
|
|
1164
|
+
// replacements and fuzzy matching can change the actual base text. Live rows
|
|
1165
|
+
// receive Pi's word-level styling; replay and export request plain rows.
|
|
1166
|
+
if ((finished.toolName === "edit" || finished.toolName === "write") && finished.isError === false) {
|
|
1167
|
+
const diff = resultDiff(finished.result);
|
|
1168
|
+
if (diff !== null) {
|
|
1169
|
+
out.push(...renderOutputMeta(finished, width, false, "change"));
|
|
1170
|
+
out.push(...renderMutationDiffBlock(diff, width, opts.diffStyle !== "plain"));
|
|
1171
|
+
out.push(...renderOutputFooter(finished, width, false));
|
|
1027
1172
|
return out;
|
|
1028
1173
|
}
|
|
1029
1174
|
}
|
|
@@ -1035,20 +1180,35 @@ export function renderToolExecution(
|
|
|
1035
1180
|
if (finished.toolName === "bash") {
|
|
1036
1181
|
const bashArgs = asBashArgs(redactToolArgs(finished.args));
|
|
1037
1182
|
if (bashArgs !== null) {
|
|
1183
|
+
out.push(...renderArgsBody(finished.toolName, finished.args, width, finished.isError));
|
|
1184
|
+
out.push(
|
|
1185
|
+
...renderOutputMeta(
|
|
1186
|
+
finished,
|
|
1187
|
+
width,
|
|
1188
|
+
finished.isError,
|
|
1189
|
+
isNonExecutedOutcome(finished.outcome) ? "decision" : "output",
|
|
1190
|
+
),
|
|
1191
|
+
);
|
|
1038
1192
|
out.push(...renderBashResultBlock(bashArgs, finished.result, width, finished.isError, opts));
|
|
1193
|
+
out.push(...renderOutputFooter(finished, width, finished.isError));
|
|
1039
1194
|
return out;
|
|
1040
1195
|
}
|
|
1041
1196
|
}
|
|
1042
1197
|
|
|
1043
|
-
//
|
|
1044
|
-
//
|
|
1045
|
-
//
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1198
|
+
// The primary argument already lives in the signature. Keep the secondary
|
|
1199
|
+
// fields below it so flags, ranges, working directories, and timeouts remain
|
|
1200
|
+
// inspectable without repeating the primary value.
|
|
1201
|
+
out.push(...renderArgsBody(finished.toolName, finished.args, width, finished.isError));
|
|
1202
|
+
out.push(
|
|
1203
|
+
...renderOutputMeta(
|
|
1204
|
+
finished,
|
|
1205
|
+
width,
|
|
1206
|
+
finished.isError,
|
|
1207
|
+
isNonExecutedOutcome(finished.outcome) ? "decision" : "output",
|
|
1208
|
+
),
|
|
1209
|
+
);
|
|
1051
1210
|
out.push(...renderResultBlock(finished.result, finished.isError, width, opts));
|
|
1211
|
+
out.push(...renderOutputFooter(finished, width, finished.isError));
|
|
1052
1212
|
return out;
|
|
1053
1213
|
}
|
|
1054
1214
|
|
|
@@ -1065,13 +1225,15 @@ export function renderToolResultOnly(
|
|
|
1065
1225
|
const status: HeaderStatus = finished.isError ? "error" : "ok";
|
|
1066
1226
|
const statusMeta: StatusMeta = {
|
|
1067
1227
|
durationMs: finished.durationMs,
|
|
1068
|
-
exitCode:
|
|
1228
|
+
exitCode: structuredExitCode(finished),
|
|
1069
1229
|
outcome: finished.outcome,
|
|
1070
1230
|
blockReason: finished.blockReason,
|
|
1071
1231
|
};
|
|
1072
1232
|
const out: string[] = [];
|
|
1073
1233
|
out.push(...wrap(headerLine(finished.toolName, undefined, status, statusMeta), width));
|
|
1234
|
+
out.push(...renderOutputMeta(finished, width, finished.isError));
|
|
1074
1235
|
out.push(...renderResultBlock(finished.result, finished.isError, width, opts));
|
|
1236
|
+
out.push(...renderOutputFooter(finished, width, finished.isError));
|
|
1075
1237
|
return out;
|
|
1076
1238
|
}
|
|
1077
1239
|
|
|
@@ -1079,26 +1241,117 @@ export function renderToolResultOnly(
|
|
|
1079
1241
|
* Streaming render for an in-flight tool call whose expanded block should
|
|
1080
1242
|
* surface the latest partial output. Used by the chat panel between
|
|
1081
1243
|
* `tool_execution_start` and `tool_execution_end` when the user has expanded
|
|
1082
|
-
* the tool segment. The header carries
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1085
|
-
* and a dim `(running...)` marker on the trailing line communicates that the
|
|
1086
|
-
* block is still being written. An empty `partialOutput` renders
|
|
1244
|
+
* the tool segment. The header carries the running lifecycle tail, secondary
|
|
1245
|
+
* arguments remain visible, and the latest cumulative Pi result renders under
|
|
1246
|
+
* a labeled live-output rail capped at the streaming row limit. An empty result renders
|
|
1087
1247
|
* `(no output yet)` so the user can distinguish a slow start from a stalled
|
|
1088
1248
|
* call.
|
|
1089
1249
|
*/
|
|
1090
|
-
export function renderToolStreamingExecution(
|
|
1250
|
+
export function renderToolStreamingExecution(
|
|
1251
|
+
call: ToolExecutionStart,
|
|
1252
|
+
width: number,
|
|
1253
|
+
partialResult: unknown,
|
|
1254
|
+
): string[] {
|
|
1091
1255
|
const out: string[] = [];
|
|
1092
|
-
out.push(...
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1256
|
+
out.push(...renderToolCallHeader({ ...call, phase: "running" }, width));
|
|
1257
|
+
out.push(...renderArgsBody(call.toolName, call.args, width, false));
|
|
1258
|
+
const partial: ToolExecutionFinished = {
|
|
1259
|
+
toolCallId: call.toolCallId,
|
|
1260
|
+
toolName: call.toolName,
|
|
1261
|
+
args: call.args,
|
|
1262
|
+
result: partialResult,
|
|
1263
|
+
isError: false,
|
|
1264
|
+
};
|
|
1265
|
+
out.push(...renderOutputMeta(partial, width, false, "live output"));
|
|
1266
|
+
const partialOutput = unwrapResultEnvelope(partialResult);
|
|
1267
|
+
if (isEmptyResult(partialOutput)) {
|
|
1097
1268
|
out.push(...indentAndWrap(dim("(no output yet)"), width, false));
|
|
1098
1269
|
} else {
|
|
1099
|
-
|
|
1270
|
+
if (call.toolName === "bash") {
|
|
1271
|
+
const bashArgs = asBashArgs(redactToolArgs(call.args));
|
|
1272
|
+
if (bashArgs !== null) {
|
|
1273
|
+
const commandLine = `${cyanBold("$")} ${highlightBashCommand(stripShellWrapperForDisplay(bashArgs.command))}`;
|
|
1274
|
+
out.push(...indentAndWrap(commandLine, width, false));
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
out.push(
|
|
1278
|
+
...renderOutputRows(resultText(partialOutput, FULL_RESULT_PREVIEW_LIMIT), width, false, STREAMING_RESULT_ROW_LIMIT),
|
|
1279
|
+
);
|
|
1100
1280
|
}
|
|
1101
|
-
const elapsed = optionalCompactMs(call.elapsedMs);
|
|
1102
|
-
out.push(...indentAndWrap(dim(elapsed !== null ? `(running... ${elapsed})` : "(running...)"), width, false));
|
|
1103
1281
|
return out;
|
|
1104
1282
|
}
|
|
1283
|
+
|
|
1284
|
+
/** Display-only lifecycle for operator-issued `!` and `!!` bash commands. */
|
|
1285
|
+
export interface BashTranscriptExecution {
|
|
1286
|
+
command: string;
|
|
1287
|
+
output: string;
|
|
1288
|
+
running: boolean;
|
|
1289
|
+
elapsedMs?: number | undefined;
|
|
1290
|
+
totalBytes?: number | undefined;
|
|
1291
|
+
exitCode?: number | null | undefined;
|
|
1292
|
+
cancelled?: boolean | undefined;
|
|
1293
|
+
truncated?: boolean | undefined;
|
|
1294
|
+
fullOutputPath?: string | undefined;
|
|
1295
|
+
excludeFromContext?: boolean | undefined;
|
|
1296
|
+
error?: string | undefined;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
/**
|
|
1300
|
+
* Render local bash with the same call, argument, output, and settlement grammar
|
|
1301
|
+
* as model-initiated bash. This is a view projection only; callers keep Clio's
|
|
1302
|
+
* existing immutable `bashExecution` ledger entry.
|
|
1303
|
+
*/
|
|
1304
|
+
export function renderBashTranscriptExecution(execution: BashTranscriptExecution, width: number): string[] {
|
|
1305
|
+
const shownBytes = Buffer.byteLength(execution.output, "utf8");
|
|
1306
|
+
const totalBytes = execution.totalBytes ?? shownBytes;
|
|
1307
|
+
const args: Record<string, unknown> = { command: execution.command };
|
|
1308
|
+
if (execution.excludeFromContext === true) args.context = "excluded from model context";
|
|
1309
|
+
const details = {
|
|
1310
|
+
resultSize: {
|
|
1311
|
+
bytes: totalBytes,
|
|
1312
|
+
shownBytes,
|
|
1313
|
+
truncated: execution.truncated === true,
|
|
1314
|
+
policy: "tail",
|
|
1315
|
+
...(execution.fullOutputPath !== undefined ? { offloadPath: execution.fullOutputPath } : {}),
|
|
1316
|
+
},
|
|
1317
|
+
};
|
|
1318
|
+
const result = {
|
|
1319
|
+
content: [{ type: "text", text: execution.output }],
|
|
1320
|
+
details,
|
|
1321
|
+
};
|
|
1322
|
+
if (execution.running) {
|
|
1323
|
+
return renderToolStreamingExecution(
|
|
1324
|
+
{
|
|
1325
|
+
toolCallId: "local-bash",
|
|
1326
|
+
toolName: "bash",
|
|
1327
|
+
args,
|
|
1328
|
+
elapsedMs: execution.elapsedMs,
|
|
1329
|
+
phase: "running",
|
|
1330
|
+
},
|
|
1331
|
+
width,
|
|
1332
|
+
result,
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
const message = execution.error?.trim();
|
|
1336
|
+
const output = message
|
|
1337
|
+
? `${execution.output}${execution.output.length > 0 ? "\n\n" : ""}${message}`
|
|
1338
|
+
: execution.output;
|
|
1339
|
+
return renderToolExecution(
|
|
1340
|
+
{
|
|
1341
|
+
toolCallId: "local-bash",
|
|
1342
|
+
toolName: "bash",
|
|
1343
|
+
args,
|
|
1344
|
+
result: { ...result, content: [{ type: "text", text: output }] },
|
|
1345
|
+
isError: execution.cancelled === true || execution.error !== undefined || (execution.exitCode ?? 0) !== 0,
|
|
1346
|
+
exitCode: execution.exitCode,
|
|
1347
|
+
...(execution.cancelled === true ? { outcome: "aborted" as const } : {}),
|
|
1348
|
+
excludeFromContext: execution.excludeFromContext,
|
|
1349
|
+
resultSummary: {
|
|
1350
|
+
bytes: shownBytes,
|
|
1351
|
+
truncated: execution.truncated === true,
|
|
1352
|
+
...(execution.fullOutputPath !== undefined ? { offloadPath: execution.fullOutputPath } : {}),
|
|
1353
|
+
},
|
|
1354
|
+
},
|
|
1355
|
+
width,
|
|
1356
|
+
);
|
|
1357
|
+
}
|