@iowarp/clio-coder 0.3.1 → 0.3.3
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 +233 -373
- package/CONTRIBUTING.md +23 -23
- package/README.md +284 -613
- package/dist/{acp-FPR54DGL.js → acp-P2AQILE2.js} +43 -53
- package/dist/{agents-OGPIHPJH.js → agents-72W3BI7I.js} +43 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
- package/dist/chunk-2DJ2KNFG.js +2095 -0
- package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-PV4JUBVJ.js → chunk-2TLUCQVG.js} +40 -21
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
- package/dist/chunk-4VP4KH3K.js +962 -0
- package/dist/chunk-4XUGQOHA.js +797 -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-4QKXUHSR.js → chunk-5UFT4SUX.js} +70 -20
- 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-6N5PTWMY.js +136 -0
- package/dist/chunk-6SGHMWE3.js +277 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/chunk-7CR24IG7.js +242 -0
- 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-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
- 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-COU2UHX6.js +400 -0
- package/dist/chunk-DSELYM6W.js +1077 -0
- package/dist/chunk-DUYJ5IO6.js +644 -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-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/{chunk-RPTR2H26.js → chunk-FNTMWMX5.js} +21 -15
- package/dist/chunk-FQ4SKYE4.js +29 -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-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
- package/dist/chunk-J7CWMCQD.js +255 -0
- package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
- package/dist/chunk-KZWTDYJF.js +217 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-G34LV2PF.js → chunk-LM5TQCJZ.js} +84 -170
- package/dist/chunk-LW6DSM3M.js +5135 -0
- package/dist/chunk-LWLEKMDQ.js +3482 -0
- package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
- package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
- package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
- package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/{chunk-Q3RUPKEJ.js → chunk-OC7FIQPC.js} +58 -189
- 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-MAR7Y6HW.js → chunk-PAJK6MAQ.js} +23 -16
- package/dist/{chunk-M5T5VO65.js → chunk-PIWWS5BL.js} +837 -635
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/chunk-SRDMMSEP.js +16405 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/chunk-STBPMHSX.js +2456 -0
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TZK7PACC.js +174 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/{chunk-ASND7OZK.js → chunk-UFIIWP2H.js} +13 -13
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-PFEFKVGL.js → chunk-V6RTAOC2.js} +13 -11
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/{chunk-EYOKLTMF.js → chunk-VPAYEGVX.js} +17 -3
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/{chunk-TEKV33Q5.js → chunk-X6IAEBZR.js} +65 -33
- package/dist/chunk-XBXAASKX.js +18 -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/chunk-ZWMF7253.js +1882 -0
- package/dist/cli/index.js +62 -54
- package/dist/clio-JOU4FXVA.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-XCDVKR23.js} +92 -55
- package/dist/configure-4GAP54ZW.js +42 -0
- package/dist/{context-5RADCKTR.js → context-4UOGGLQ5.js} +71 -35
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-3KWFLHJG.js → context-77FM5DV5.js} +15 -13
- package/dist/{context-clear-7TSNPAAI.js → context-clear-XXJRLCJJ.js} +54 -28
- package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
- package/dist/dispatch-runner-QPRDDBDX.js +1997 -0
- package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
- package/dist/{doctor-UC5NAJYQ.js → doctor-HR46URBJ.js} +27 -17
- package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
- package/dist/{evidence-YEGUW4L3.js → evidence-6HG2PY2B.js} +46 -26
- package/dist/{evolve-TXARCTPG.js → evolve-K7YU3NCY.js} +45 -25
- package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
- package/dist/{fleet-6G3DHNYE.js → fleet-VY3HHKN6.js} +163 -54
- package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
- package/dist/{init-KZ5QTF6M.js → init-JYGXI3FK.js} +69 -32
- package/dist/{memory-73ESV5YC.js → memory-WFZMGYHX.js} +48 -27
- package/dist/{models-A4PVNWJK.js → models-I5QWSEOM.js} +39 -25
- package/dist/monitor-GE4ID3IA.js +661 -0
- package/dist/{chunk-FCIH3BIZ.js → orchestrator-EM5MC3HM.js} +15979 -12407
- 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-ZU3QMZPZ.js} +101 -61
- package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
- package/dist/{skills-2V6RA3OQ.js → skills-X5VXCRNQ.js} +34 -14
- package/dist/{skills-eval-S2TVJO4F.js → skills-eval-WKIHWTHR.js} +70 -34
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-TYXLPB23.js → targets-SNCPI2NR.js} +43 -27
- package/dist/terminal-lease-BNAHVHBS.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-JQHHPQ4K.js} +45 -25
- package/dist/{usage-ZAFSXKKG.js → usage-OR4O5SMZ.js} +62 -31
- package/dist/verify-375KUB3Y.js +716 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-UEXP2ARI.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 +387 -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 +45 -9
- 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 +715 -278
- package/src/interactive/chat-renderer.ts +306 -85
- 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 +253 -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 +42 -22
- package/src/interactive/footer-panel.ts +8 -3
- package/src/interactive/format-time.ts +14 -2
- package/src/interactive/interactive-application.ts +203 -17
- package/src/interactive/interactive-event-projection.ts +18 -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 +184 -117
- 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/ask-user.ts +146 -24
- 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 +516 -168
- 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/status/index.ts +12 -1
- package/src/interactive/status/reasoning.ts +87 -0
- package/src/interactive/status/summary.ts +13 -2
- 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/transcript-detail.ts +120 -0
- 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 +271 -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/presentation.ts +107 -0
- package/src/tools/registry.ts +45 -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
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Coalescing wrapper around chat events (slice 12.5d).
|
|
3
3
|
*
|
|
4
|
-
* Streaming responses fire
|
|
5
|
-
* high frequency. The TUI's per-event `requestRender()` call rebuilt the
|
|
4
|
+
* Streaming responses fire text, thinking, and cumulative tool-result updates
|
|
5
|
+
* at very high frequency. The TUI's per-event `requestRender()` call rebuilt the
|
|
6
6
|
* entire transcript on every delta, which scaled linearly with response
|
|
7
|
-
* length and made long answers visibly lag. This wrapper applies
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* length and made long answers visibly lag. This wrapper applies events to
|
|
8
|
+
* the panel synchronously (so internal state stays consistent) but defers
|
|
9
|
+
* `requestRender()` for delta events to a single coalesced timer (~16ms =
|
|
10
|
+
* one frame at 60fps). Non-delta events render synchronously so finalizers
|
|
11
|
+
* like `message_end` are never deferred. The one exception is the raw
|
|
12
|
+
* text/thinking wrapper, which is dropped before the panel entirely; see
|
|
13
|
+
* `isTransparentAssistantWrapper`.
|
|
12
14
|
*/
|
|
13
15
|
|
|
16
|
+
import { ToolNames } from "../core/tool-names.js";
|
|
14
17
|
import type {
|
|
15
18
|
BashExecutionEntry,
|
|
16
19
|
BranchSummaryEntry,
|
|
@@ -26,8 +29,17 @@ import type {
|
|
|
26
29
|
WorkerRunEntry,
|
|
27
30
|
} from "../domains/session/entries.js";
|
|
28
31
|
import { filterEntriesToActivePath } from "../domains/session/tree/active-path.js";
|
|
32
|
+
import {
|
|
33
|
+
type BashExecutionMessage,
|
|
34
|
+
BRANCH_SUMMARY_PREFIX,
|
|
35
|
+
BRANCH_SUMMARY_SUFFIX,
|
|
36
|
+
bashExecutionToText,
|
|
37
|
+
COMPACTION_SUMMARY_PREFIX,
|
|
38
|
+
COMPACTION_SUMMARY_SUFFIX,
|
|
39
|
+
} from "../engine/messages.js";
|
|
29
40
|
import { wrapTextWithAnsi } from "../engine/tui.js";
|
|
30
41
|
import type { AgentMessage } from "../engine/types.js";
|
|
42
|
+
import { toolPresentationPolicy } from "../tools/presentation.js";
|
|
31
43
|
import type { ChatLoopEvent, RetryStatusPayload } from "./chat-loop.js";
|
|
32
44
|
import { isSelfExplainingAbort } from "./chat-loop-messages.js";
|
|
33
45
|
import type { ChatPanel } from "./chat-panel.js";
|
|
@@ -35,8 +47,16 @@ import { renderBranchSummaryEntry } from "./renderers/branch-summary.js";
|
|
|
35
47
|
import { renderCompactionSummaryEntry } from "./renderers/compaction-summary.js";
|
|
36
48
|
import { styleTaggedNotice } from "./renderers/notice.js";
|
|
37
49
|
import { formatRetryStatus } from "./renderers/retry-status.js";
|
|
38
|
-
import { renderToolResultOnly } from "./renderers/tool-execution.js";
|
|
39
|
-
import {
|
|
50
|
+
import { renderBashTranscriptExecution, renderToolResultOnly } from "./renderers/tool-execution.js";
|
|
51
|
+
import {
|
|
52
|
+
classifyStreamEvent,
|
|
53
|
+
createStreamPacer,
|
|
54
|
+
type SmoothStreamingMode,
|
|
55
|
+
type StreamPacer,
|
|
56
|
+
type StreamPacerSlice,
|
|
57
|
+
} from "./stream-pacer.js";
|
|
58
|
+
import { type FoldOverride, policyToolFold, resolveFold, type TranscriptDetailPolicy } from "./transcript-detail.js";
|
|
59
|
+
import { readWorkerReceiptFactsForReplay } from "./worker-receipts.js";
|
|
40
60
|
import { workerEntriesFromRunEntries } from "./worker-replay.js";
|
|
41
61
|
import type { WorkerReceiptReader } from "./worker-stream.js";
|
|
42
62
|
|
|
@@ -47,7 +67,28 @@ const MAX_REPLAY_TEXT_CHARS = 20_000;
|
|
|
47
67
|
* Event kinds whose render is deferred into a coalesce window. All other
|
|
48
68
|
* `ChatLoopEvent` kinds render synchronously and cancel any pending timer.
|
|
49
69
|
*/
|
|
50
|
-
const DELTA_TYPES: ReadonlySet<ChatLoopEvent["type"]> = new Set([
|
|
70
|
+
const DELTA_TYPES: ReadonlySet<ChatLoopEvent["type"]> = new Set([
|
|
71
|
+
"text_delta",
|
|
72
|
+
"thinking_delta",
|
|
73
|
+
"tool_execution_update",
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A raw `message_update` wrapper whose inner event is a text or thinking
|
|
78
|
+
* delta is transparent to the transcript: the panel ignores it, and the
|
|
79
|
+
* derived `text_delta`/`thinking_delta` emitted in the same stack (see
|
|
80
|
+
* turn-runtime's public-event fan-out) is the canonical display input. Yet
|
|
81
|
+
* this renderer classified the wrapper as non-delta, so every provider chunk
|
|
82
|
+
* cancelled the pending coalesce window and requested an immediate render.
|
|
83
|
+
* The coalescer was defeated exactly while streaming, which is the one time
|
|
84
|
+
* it matters. Wrappers carrying tool-call formation stay on the synchronous
|
|
85
|
+
* path, because the panel consumes those directly.
|
|
86
|
+
*/
|
|
87
|
+
function isTransparentAssistantWrapper(event: ChatLoopEvent): boolean {
|
|
88
|
+
if (event.type !== "message_update") return false;
|
|
89
|
+
const inner = (event as { assistantMessageEvent?: { type?: unknown } }).assistantMessageEvent;
|
|
90
|
+
return inner?.type === "text_delta" || inner?.type === "thinking_delta";
|
|
91
|
+
}
|
|
51
92
|
|
|
52
93
|
export interface CreateCoalescingChatRendererDeps {
|
|
53
94
|
chatPanel: ChatPanel;
|
|
@@ -58,14 +99,35 @@ export interface CreateCoalescingChatRendererDeps {
|
|
|
58
99
|
setTimer?: (cb: () => void, ms: number) => unknown;
|
|
59
100
|
/** Override for tests. Mirrors the clearTimeout signature. */
|
|
60
101
|
clearTimer?: (id: unknown) => void;
|
|
61
|
-
/**
|
|
102
|
+
/** Monotonic clock shared with the pacer; injectable for deterministic tests. */
|
|
103
|
+
now?: () => number;
|
|
104
|
+
/** Sequence captured at canonical projection ingress before this panel consumer runs. */
|
|
105
|
+
visibleEventSequence?: (event: ChatLoopEvent) => number | null;
|
|
106
|
+
onQueue?: (eventSeq: number, action: "admit" | "dequeue") => void;
|
|
107
|
+
onPanelApplied?: (eventSeq: number) => void;
|
|
108
|
+
/** Legacy aggregate callback retained for non-text cumulative tool-update observations. */
|
|
62
109
|
onDelta?: () => void;
|
|
110
|
+
/** Canonical presentation-ingress identity; absent keeps the exact legacy coalescer. */
|
|
111
|
+
streamIngress?: (event: ChatLoopEvent) => { sequence: number; generation: string | number; ingressAt: number } | null;
|
|
112
|
+
getSmoothStreamingMode?: () => SmoothStreamingMode;
|
|
113
|
+
isAutoPacingAllowed?: () => boolean;
|
|
114
|
+
/** Force and await one actual frame plus any stdout drain. */
|
|
115
|
+
commitFrame?: (reason?: string) => Promise<unknown>;
|
|
63
116
|
}
|
|
64
117
|
|
|
65
118
|
export interface CoalescingChatRenderer {
|
|
66
119
|
applyEvent(event: ChatLoopEvent): void;
|
|
67
120
|
/** Cancel the pending coalesce timer (if any) and request one synchronous render. */
|
|
68
121
|
flush(): void;
|
|
122
|
+
/** Ordered barrier for replay, worker, command-output, and other panel mutations. */
|
|
123
|
+
mutate(mutation: () => void, reason?: string): void;
|
|
124
|
+
/** Drop queued presentation content before replacing/resetting the transcript. */
|
|
125
|
+
reset(mutation: () => void): void;
|
|
126
|
+
/** Drain paced content and await the first committed frame containing it. */
|
|
127
|
+
flushAndCommit(reason?: string): Promise<void>;
|
|
128
|
+
/** Apply a live mode change as an immediate ordered drain boundary. */
|
|
129
|
+
setSmoothStreamingMode(mode: SmoothStreamingMode): void;
|
|
130
|
+
dispose(): void;
|
|
69
131
|
}
|
|
70
132
|
|
|
71
133
|
export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererDeps): CoalescingChatRenderer {
|
|
@@ -78,8 +140,13 @@ export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererD
|
|
|
78
140
|
const coalesceMs = deps.coalesceMs ?? DEFAULT_COALESCE_MS;
|
|
79
141
|
|
|
80
142
|
let pendingTimer: unknown = null;
|
|
143
|
+
let mutationDepth = 0;
|
|
144
|
+
let transactionNeedsRender = false;
|
|
145
|
+
let disposed = false;
|
|
146
|
+
let pacer: StreamPacer | null = null;
|
|
81
147
|
|
|
82
148
|
const fireCoalesced = (): void => {
|
|
149
|
+
if (disposed) return;
|
|
83
150
|
pendingTimer = null;
|
|
84
151
|
deps.requestRender();
|
|
85
152
|
};
|
|
@@ -91,24 +158,165 @@ export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererD
|
|
|
91
158
|
return true;
|
|
92
159
|
};
|
|
93
160
|
|
|
94
|
-
|
|
161
|
+
const requestTransactionalRender = (coalesce: boolean): void => {
|
|
162
|
+
if (mutationDepth > 0) {
|
|
163
|
+
transactionNeedsRender = true;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (!coalesce) {
|
|
167
|
+
cancelPending();
|
|
168
|
+
deps.requestRender();
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
deps.onDelta?.();
|
|
172
|
+
if (pendingTimer === null) pendingTimer = setTimer(fireCoalesced, coalesceMs);
|
|
173
|
+
};
|
|
174
|
+
const transaction = (operation: () => void, coalesce = false): void => {
|
|
175
|
+
mutationDepth += 1;
|
|
176
|
+
try {
|
|
177
|
+
operation();
|
|
178
|
+
} finally {
|
|
179
|
+
mutationDepth -= 1;
|
|
180
|
+
if (mutationDepth === 0 && transactionNeedsRender) {
|
|
181
|
+
transactionNeedsRender = false;
|
|
182
|
+
requestTransactionalRender(coalesce);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
const applySlice = (slice: StreamPacerSlice): void => {
|
|
187
|
+
const event =
|
|
188
|
+
slice.kind === "text"
|
|
189
|
+
? ({ type: "text_delta", contentIndex: slice.contentIndex, delta: slice.text, partialText: "" } as const)
|
|
190
|
+
: ({ type: "thinking_delta", contentIndex: slice.contentIndex, delta: slice.text, partialThinking: "" } as const);
|
|
191
|
+
deps.chatPanel.applyEvent(event);
|
|
192
|
+
if (slice.finalForItem) {
|
|
193
|
+
deps.onPanelApplied?.(slice.sequence);
|
|
194
|
+
deps.onQueue?.(slice.sequence, "dequeue");
|
|
195
|
+
}
|
|
196
|
+
requestTransactionalRender(true);
|
|
197
|
+
};
|
|
198
|
+
if (deps.streamIngress && deps.getSmoothStreamingMode) {
|
|
199
|
+
pacer = createStreamPacer({
|
|
200
|
+
mode: deps.getSmoothStreamingMode(),
|
|
201
|
+
onSlice: applySlice,
|
|
202
|
+
onDiscard: (sequence) => deps.onQueue?.(sequence, "dequeue"),
|
|
203
|
+
...(deps.now ? { now: deps.now } : {}),
|
|
204
|
+
...(deps.setTimer ? { setTimer: deps.setTimer } : {}),
|
|
205
|
+
...(deps.clearTimer ? { clearTimer: deps.clearTimer } : {}),
|
|
206
|
+
...(deps.isAutoPacingAllowed ? { isAutoPacingAllowed: deps.isAutoPacingAllowed } : {}),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
const syncPacerMode = (): SmoothStreamingMode => {
|
|
210
|
+
const mode = deps.getSmoothStreamingMode?.() ?? "off";
|
|
211
|
+
if (pacer && pacer.mode !== mode) transaction(() => pacer?.setMode(mode));
|
|
212
|
+
return mode;
|
|
213
|
+
};
|
|
214
|
+
const drainPacer = (reason: string): void => {
|
|
215
|
+
if (pacer?.snapshot().queuedItems) pacer.flush(reason);
|
|
216
|
+
};
|
|
217
|
+
const applyLegacy = (event: ChatLoopEvent): void => {
|
|
218
|
+
const visibleEventSeq = deps.visibleEventSequence?.(event) ?? null;
|
|
219
|
+
if (visibleEventSeq !== null) deps.onQueue?.(visibleEventSeq, "admit");
|
|
220
|
+
deps.chatPanel.applyEvent(event);
|
|
221
|
+
if (visibleEventSeq !== null) {
|
|
222
|
+
deps.onPanelApplied?.(visibleEventSeq);
|
|
223
|
+
deps.onQueue?.(visibleEventSeq, "dequeue");
|
|
224
|
+
}
|
|
225
|
+
if (DELTA_TYPES.has(event.type)) {
|
|
226
|
+
requestTransactionalRender(true);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
requestTransactionalRender(false);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const renderer: CoalescingChatRenderer = {
|
|
95
233
|
applyEvent(event) {
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
234
|
+
if (disposed) return;
|
|
235
|
+
if (isTransparentAssistantWrapper(event)) return;
|
|
236
|
+
const mode = syncPacerMode();
|
|
237
|
+
const ingress = deps.streamIngress?.(event) ?? null;
|
|
238
|
+
if (!pacer || mode === "off") {
|
|
239
|
+
applyLegacy(event);
|
|
101
240
|
return;
|
|
102
241
|
}
|
|
103
|
-
|
|
104
|
-
|
|
242
|
+
const classification = classifyStreamEvent(event);
|
|
243
|
+
if (classification === "paced-display-content") {
|
|
244
|
+
if (ingress === null) {
|
|
245
|
+
applyLegacy(event);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const delta = event as Extract<ChatLoopEvent, { type: "text_delta" | "thinking_delta" }>;
|
|
249
|
+
if (delta.delta.length === 0) {
|
|
250
|
+
applyLegacy(event);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
deps.onQueue?.(ingress.sequence, "admit");
|
|
254
|
+
transaction(() => {
|
|
255
|
+
pacer?.enqueue({
|
|
256
|
+
sequence: ingress.sequence,
|
|
257
|
+
generation: ingress.generation,
|
|
258
|
+
kind: delta.type === "text_delta" ? "text" : "thinking",
|
|
259
|
+
contentIndex: delta.contentIndex,
|
|
260
|
+
text: delta.delta,
|
|
261
|
+
ingressAt: ingress.ingressAt,
|
|
262
|
+
folded: delta.type === "thinking_delta" && !deps.chatPanel.isThinkingExpanded(),
|
|
263
|
+
});
|
|
264
|
+
}, true);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (classification === "cumulative-live-state") {
|
|
268
|
+
transaction(() => {
|
|
269
|
+
drainPacer("cumulative-live-state");
|
|
270
|
+
applyLegacy(event);
|
|
271
|
+
}, true);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
transaction(() => {
|
|
275
|
+
drainPacer(`boundary:${event.type}`);
|
|
276
|
+
applyLegacy(event);
|
|
277
|
+
});
|
|
105
278
|
},
|
|
106
279
|
flush() {
|
|
280
|
+
if (disposed) return;
|
|
281
|
+
transaction(() => drainPacer("explicit-flush"));
|
|
107
282
|
const wasPending = cancelPending();
|
|
108
|
-
if (
|
|
109
|
-
|
|
283
|
+
if (wasPending) deps.requestRender();
|
|
284
|
+
},
|
|
285
|
+
mutate(mutation, reason = "panel-mutation") {
|
|
286
|
+
if (disposed) return;
|
|
287
|
+
transaction(() => {
|
|
288
|
+
drainPacer(reason);
|
|
289
|
+
mutation();
|
|
290
|
+
requestTransactionalRender(false);
|
|
291
|
+
});
|
|
292
|
+
},
|
|
293
|
+
reset(mutation) {
|
|
294
|
+
if (disposed) return;
|
|
295
|
+
transaction(() => {
|
|
296
|
+
pacer?.invalidateEpoch();
|
|
297
|
+
mutation();
|
|
298
|
+
requestTransactionalRender(false);
|
|
299
|
+
});
|
|
300
|
+
},
|
|
301
|
+
async flushAndCommit(reason = "final-frame") {
|
|
302
|
+
if (disposed) return;
|
|
303
|
+
transaction(() => drainPacer(reason));
|
|
304
|
+
cancelPending();
|
|
305
|
+
if (deps.commitFrame) await deps.commitFrame(reason);
|
|
306
|
+
else deps.requestRender();
|
|
307
|
+
},
|
|
308
|
+
setSmoothStreamingMode(mode) {
|
|
309
|
+
if (disposed || !pacer || pacer.mode === mode) return;
|
|
310
|
+
transaction(() => pacer?.setMode(mode));
|
|
311
|
+
},
|
|
312
|
+
dispose() {
|
|
313
|
+
if (disposed) return;
|
|
314
|
+
transaction(() => pacer?.dispose("renderer-dispose"));
|
|
315
|
+
cancelPending();
|
|
316
|
+
disposed = true;
|
|
110
317
|
},
|
|
111
318
|
};
|
|
319
|
+
return renderer;
|
|
112
320
|
}
|
|
113
321
|
|
|
114
322
|
/**
|
|
@@ -263,18 +471,18 @@ function toolCallMessageFromEntry(entry: MessageEntry): AgentMessage {
|
|
|
263
471
|
} as unknown as AgentMessage;
|
|
264
472
|
}
|
|
265
473
|
|
|
266
|
-
function toolResultContent(result: unknown): unknown[] {
|
|
474
|
+
function toolResultContent(result: unknown, unbounded = false): unknown[] {
|
|
267
475
|
const obj = payloadObject(result);
|
|
268
476
|
if (Array.isArray(obj?.content)) {
|
|
269
|
-
return cloneContentBlocks(obj.content, MAX_REPLAY_TEXT_CHARS) ?? [];
|
|
477
|
+
return cloneContentBlocks(obj.content, unbounded ? undefined : MAX_REPLAY_TEXT_CHARS) ?? [];
|
|
270
478
|
}
|
|
271
|
-
if (isTextResult(result)) return [{ type: "text", text: truncateReplayText(result.text) }];
|
|
272
|
-
if (typeof result === "string") return [{ type: "text", text: truncateReplayText(result) }];
|
|
273
|
-
return [{ type: "text", text: stringifyPreview(result, 10_000) }];
|
|
479
|
+
if (isTextResult(result)) return [{ type: "text", text: unbounded ? result.text : truncateReplayText(result.text) }];
|
|
480
|
+
if (typeof result === "string") return [{ type: "text", text: unbounded ? result : truncateReplayText(result) }];
|
|
481
|
+
return [{ type: "text", text: stringifyPreview(result, unbounded ? Number.POSITIVE_INFINITY : 10_000) }];
|
|
274
482
|
}
|
|
275
483
|
|
|
276
|
-
function displayReplayToolResult(result: unknown): unknown {
|
|
277
|
-
const content = toolResultContent(result);
|
|
484
|
+
function displayReplayToolResult(result: unknown, unbounded = false): unknown {
|
|
485
|
+
const content = toolResultContent(result, unbounded);
|
|
278
486
|
// Preserve the details record (observation envelope, exec records) so the
|
|
279
487
|
// replayed ledger line carries the same outcome facts as the live one.
|
|
280
488
|
const details = payloadObject(result)?.details;
|
|
@@ -499,30 +707,29 @@ function appendReplayLine(chatPanel: ChatPanel, text: string): void {
|
|
|
499
707
|
chatPanel.appendReplayBlock((width) => renderReplayLine(truncateReplayText(text), width));
|
|
500
708
|
}
|
|
501
709
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
return lines;
|
|
710
|
+
function renderBashExecutionEntry(
|
|
711
|
+
entry: BashExecutionEntry,
|
|
712
|
+
width: number,
|
|
713
|
+
folded: boolean,
|
|
714
|
+
unbounded: boolean,
|
|
715
|
+
): string[] {
|
|
716
|
+
const normalizedOutput = entry.output.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\s+$/g, "");
|
|
717
|
+
return renderBashTranscriptExecution(
|
|
718
|
+
{
|
|
719
|
+
command: entry.command,
|
|
720
|
+
output: unbounded ? normalizedOutput : truncateReplayText(normalizedOutput),
|
|
721
|
+
running: false,
|
|
722
|
+
exitCode: entry.exitCode,
|
|
723
|
+
cancelled: entry.cancelled,
|
|
724
|
+
truncated: entry.truncated,
|
|
725
|
+
fullOutputPath: entry.fullOutputPath,
|
|
726
|
+
excludeFromContext: entry.excludeFromContext,
|
|
727
|
+
folded,
|
|
728
|
+
},
|
|
729
|
+
width,
|
|
730
|
+
undefined,
|
|
731
|
+
{ unbounded, diffStyle: "plain" },
|
|
732
|
+
);
|
|
526
733
|
}
|
|
527
734
|
|
|
528
735
|
function renderRetryStatusEntry(entry: CustomEntry, width: number): string[] {
|
|
@@ -746,33 +953,26 @@ function dropLegacyToolResultAssistantDuplicates(entries: ReadonlyArray<SessionE
|
|
|
746
953
|
}
|
|
747
954
|
|
|
748
955
|
function compactionContextText(entry: CompactionSummaryEntry): string {
|
|
749
|
-
return
|
|
750
|
-
"The conversation history before this point was compacted into the following summary:",
|
|
751
|
-
"",
|
|
752
|
-
"<summary>",
|
|
753
|
-
entry.summary,
|
|
754
|
-
"</summary>",
|
|
755
|
-
].join("\n");
|
|
956
|
+
return `${COMPACTION_SUMMARY_PREFIX}${entry.summary}${COMPACTION_SUMMARY_SUFFIX}`;
|
|
756
957
|
}
|
|
757
958
|
|
|
758
959
|
function branchContextText(entry: BranchSummaryEntry): string {
|
|
759
|
-
return
|
|
760
|
-
"The following is a summary of a branch that this conversation came back from:",
|
|
761
|
-
"",
|
|
762
|
-
"<summary>",
|
|
763
|
-
entry.summary,
|
|
764
|
-
"</summary>",
|
|
765
|
-
].join("\n");
|
|
960
|
+
return `${BRANCH_SUMMARY_PREFIX}${entry.summary}${BRANCH_SUMMARY_SUFFIX}`;
|
|
766
961
|
}
|
|
767
962
|
|
|
963
|
+
/** Project Clio's ledger entry onto pi's bash message so pi owns the replay wording. */
|
|
768
964
|
function bashContextText(entry: BashExecutionEntry): string {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
965
|
+
const message: BashExecutionMessage = {
|
|
966
|
+
role: "bashExecution",
|
|
967
|
+
command: entry.command,
|
|
968
|
+
output: truncateReplayText(entry.output),
|
|
969
|
+
exitCode: entry.exitCode ?? undefined,
|
|
970
|
+
cancelled: entry.cancelled,
|
|
971
|
+
truncated: entry.truncated,
|
|
972
|
+
...(entry.fullOutputPath !== undefined ? { fullOutputPath: entry.fullOutputPath } : {}),
|
|
973
|
+
timestamp: Date.parse(entry.timestamp) || 0,
|
|
974
|
+
};
|
|
975
|
+
return bashExecutionToText(message);
|
|
776
976
|
}
|
|
777
977
|
|
|
778
978
|
function appendContextMessage(out: AgentMessage[], role: "user" | "assistant", text: string, timestamp: string): void {
|
|
@@ -838,6 +1038,7 @@ export function buildReplayAgentMessagesFromTurns(
|
|
|
838
1038
|
case "label":
|
|
839
1039
|
case "protectedArtifact":
|
|
840
1040
|
case "taskLedger":
|
|
1041
|
+
case "decisionLedger":
|
|
841
1042
|
// A worker's answer is not the operator's words and not the model's.
|
|
842
1043
|
// It reaches the model only when an operator shares it, and a share
|
|
843
1044
|
// is already a user message by the time it lands in the ledger.
|
|
@@ -877,19 +1078,21 @@ export function rehydrateChatPanelFromTurns(
|
|
|
877
1078
|
options: RehydrateChatPanelOptions = {},
|
|
878
1079
|
): void {
|
|
879
1080
|
const pendingToolIds: string[] = [];
|
|
1081
|
+
let runAssistantMessages: AgentMessage[] = [];
|
|
880
1082
|
const selected = selectReplayEntries(turns, options);
|
|
881
1083
|
// One block per assignment, drawn where its first attempt started. Later
|
|
882
1084
|
// attempts of the same assignment fold into that block as `↻` rail lines, so
|
|
883
1085
|
// a failover replays as the one run it was rather than as two.
|
|
884
1086
|
const workerStates = workerEntriesFromRunEntries(
|
|
885
1087
|
selected.filter((entry): entry is WorkerRunEntry => entry.kind === "workerRun"),
|
|
886
|
-
options.readWorkerReceipt ??
|
|
1088
|
+
options.readWorkerReceipt ?? readWorkerReceiptFactsForReplay,
|
|
887
1089
|
);
|
|
888
1090
|
const placedAssignments = new Set<string>();
|
|
889
1091
|
for (const entry of selected) {
|
|
890
1092
|
switch (entry.kind) {
|
|
891
1093
|
case "message": {
|
|
892
1094
|
if (entry.role === "user") {
|
|
1095
|
+
runAssistantMessages = [];
|
|
893
1096
|
const text = truncateReplayText(replayedUserText(entry));
|
|
894
1097
|
if (text.length > 0) chatPanel.appendUser(text);
|
|
895
1098
|
break;
|
|
@@ -905,7 +1108,8 @@ export function rehydrateChatPanelFromTurns(
|
|
|
905
1108
|
(message as { stopReason?: string; errorMessage?: string }).errorMessage = failure.errorMessage;
|
|
906
1109
|
}
|
|
907
1110
|
chatPanel.applyEvent({ type: "message_end", message });
|
|
908
|
-
|
|
1111
|
+
runAssistantMessages.push(message);
|
|
1112
|
+
chatPanel.applyEvent({ type: "agent_end", messages: runAssistantMessages });
|
|
909
1113
|
}
|
|
910
1114
|
break;
|
|
911
1115
|
}
|
|
@@ -918,6 +1122,7 @@ export function rehydrateChatPanelFromTurns(
|
|
|
918
1122
|
toolName: call.name,
|
|
919
1123
|
args: call.args,
|
|
920
1124
|
});
|
|
1125
|
+
chatPanel.markToolReplayed?.(call.id);
|
|
921
1126
|
break;
|
|
922
1127
|
}
|
|
923
1128
|
if (entry.role === "tool_result") {
|
|
@@ -930,7 +1135,7 @@ export function rehydrateChatPanelFromTurns(
|
|
|
930
1135
|
type: "tool_execution_end",
|
|
931
1136
|
toolCallId: fallbackId,
|
|
932
1137
|
toolName: result.name,
|
|
933
|
-
result: displayReplayToolResult(result.result),
|
|
1138
|
+
result: displayReplayToolResult(result.result, options.unboundedToolBodies === true),
|
|
934
1139
|
isError: result.isError,
|
|
935
1140
|
...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
|
|
936
1141
|
...(result.resultSummary !== undefined ? { resultSummary: result.resultSummary } : {}),
|
|
@@ -943,7 +1148,7 @@ export function rehydrateChatPanelFromTurns(
|
|
|
943
1148
|
{
|
|
944
1149
|
toolCallId: result.id ?? "",
|
|
945
1150
|
toolName: result.name,
|
|
946
|
-
result: displayReplayToolResult(result.result),
|
|
1151
|
+
result: displayReplayToolResult(result.result, options.unboundedToolBodies === true),
|
|
947
1152
|
isError: result.isError,
|
|
948
1153
|
...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
|
|
949
1154
|
...(result.resultSummary !== undefined ? { resultSummary: result.resultSummary } : {}),
|
|
@@ -969,9 +1174,25 @@ export function rehydrateChatPanelFromTurns(
|
|
|
969
1174
|
}
|
|
970
1175
|
break;
|
|
971
1176
|
}
|
|
972
|
-
case "bashExecution":
|
|
973
|
-
|
|
1177
|
+
case "bashExecution": {
|
|
1178
|
+
let fold: FoldOverride;
|
|
1179
|
+
const presentation = toolPresentationPolicy(ToolNames.Bash, undefined);
|
|
1180
|
+
const policyFold = (detail: TranscriptDetailPolicy) => policyToolFold(detail, presentation);
|
|
1181
|
+
const unbounded = options.unboundedToolBodies === true;
|
|
1182
|
+
chatPanel.appendReplayBlock(
|
|
1183
|
+
(width, detail) =>
|
|
1184
|
+
renderBashExecutionEntry(entry, width, resolveFold(fold, policyFold(detail)) === "folded", unbounded),
|
|
1185
|
+
undefined,
|
|
1186
|
+
{
|
|
1187
|
+
policyFold,
|
|
1188
|
+
fold: () => fold,
|
|
1189
|
+
setFold: (next: FoldOverride) => {
|
|
1190
|
+
fold = next;
|
|
1191
|
+
},
|
|
1192
|
+
},
|
|
1193
|
+
);
|
|
974
1194
|
break;
|
|
1195
|
+
}
|
|
975
1196
|
case "custom":
|
|
976
1197
|
if (rendersCustomEntry(entry)) chatPanel.appendReplayBlock((width) => renderCustomEntry(entry, width));
|
|
977
1198
|
break;
|
|
@@ -1017,6 +1238,7 @@ export function rehydrateChatPanelFromTurns(
|
|
|
1017
1238
|
}
|
|
1018
1239
|
case "label":
|
|
1019
1240
|
case "taskLedger":
|
|
1241
|
+
case "decisionLedger":
|
|
1020
1242
|
break;
|
|
1021
1243
|
}
|
|
1022
1244
|
}
|
|
@@ -1029,10 +1251,9 @@ export function rehydrateChatPanelFromTurns(
|
|
|
1029
1251
|
isError: true,
|
|
1030
1252
|
});
|
|
1031
1253
|
}
|
|
1032
|
-
//
|
|
1033
|
-
//
|
|
1034
|
-
//
|
|
1035
|
-
//
|
|
1036
|
-
|
|
1037
|
-
chatPanel.collapseAllTools();
|
|
1254
|
+
// A rehydrated transcript starts from the transcript detail policy alone:
|
|
1255
|
+
// whatever the operator had opened or folded before the switch belonged to
|
|
1256
|
+
// the transcript they left. /export reaches the same policy with a verbose
|
|
1257
|
+
// panel, so nothing here is terminal-only.
|
|
1258
|
+
chatPanel.clearFoldOverrides();
|
|
1038
1259
|
}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import { Editor, type TUI, truncateToWidth, visibleWidth } from "../engine/tui.js";
|
|
1
|
+
import { Editor, stripTerminalSequences, type TUI, truncateToWidth, visibleWidth } from "../engine/tui.js";
|
|
2
2
|
import type { ClioTheme } from "./theme/index.js";
|
|
3
3
|
import { clioTheme, editorTheme, GLYPH, rule } from "./theme/index.js";
|
|
4
4
|
|
|
5
|
-
const ANSI = new RegExp(`${String.fromCharCode(27)}\\[[0-9;?]*[A-Za-z]`, "g");
|
|
6
5
|
const REVERSE_VIDEO_BLANK = `${String.fromCharCode(27)}[7m ${String.fromCharCode(27)}[0m`;
|
|
7
6
|
const EMPTY_PROMPT = "Ask Clio… / for commands";
|
|
8
7
|
const MIN_HINT_WIDTH = 60;
|
|
9
8
|
|
|
10
|
-
function stripAnsi(text: string): string {
|
|
11
|
-
return text.replace(ANSI, "");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
9
|
function hasScrollIndicator(line: string): boolean {
|
|
15
|
-
const stripped =
|
|
10
|
+
const stripped = stripTerminalSequences(line);
|
|
16
11
|
return stripped.includes(GLYPH.up) || stripped.includes(GLYPH.down);
|
|
17
12
|
}
|
|
18
13
|
|
|
@@ -91,7 +86,7 @@ function renderEmptyPrompt(line: string, width: number, theme: ClioTheme): strin
|
|
|
91
86
|
function findBottomRail(lines: readonly string[], width: number): number {
|
|
92
87
|
const rail = "─".repeat(Math.max(0, width));
|
|
93
88
|
for (let index = 1; index < lines.length; index += 1) {
|
|
94
|
-
if (
|
|
89
|
+
if (stripTerminalSequences(lines[index] ?? "") === rail) return index;
|
|
95
90
|
}
|
|
96
91
|
return -1;
|
|
97
92
|
}
|
|
@@ -12,12 +12,12 @@ export function runCompactWithNotice(
|
|
|
12
12
|
instructions: string | undefined,
|
|
13
13
|
): void {
|
|
14
14
|
if (!onCompact) {
|
|
15
|
-
emitCommandNotice(notice, "error", "compact", "compaction not wired; pass onCompact to startInteractive");
|
|
15
|
+
emitCommandNotice(notice, "error", "context compact", "compaction not wired; pass onCompact to startInteractive");
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
const task = onCompact(instructions);
|
|
19
19
|
void task.catch((err) => {
|
|
20
20
|
const msg = err instanceof Error ? err.message : String(err);
|
|
21
|
-
emitCommandNotice(notice, "error", "compact", msg);
|
|
21
|
+
emitCommandNotice(notice, "error", "context compact", msg);
|
|
22
22
|
});
|
|
23
23
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { relative } from "node:path";
|
|
1
3
|
import { BusChannels } from "../core/bus-events.js";
|
|
2
4
|
import type { SafeEventBus } from "../core/event-bus.js";
|
|
3
5
|
import type { ContextLedger, ContextLedgerGroup } from "../domains/session/context-ledger.js";
|
|
@@ -40,6 +42,27 @@ function contextWindowProvenanceLabel(source: ContextLedger["contextWindowSource
|
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
/** A handbook path the operator can read at a glance: workspace-relative when
|
|
46
|
+
* the file sits under the current directory, `~`-shortened otherwise. */
|
|
47
|
+
function displayHandbookPath(filePath: string): string {
|
|
48
|
+
const rel = relative(process.cwd(), filePath);
|
|
49
|
+
if (rel.length > 0 && !rel.startsWith("..")) return rel;
|
|
50
|
+
const home = homedir();
|
|
51
|
+
return home.length > 0 && filePath.startsWith(`${home}/`) ? `~${filePath.slice(home.length)}` : filePath;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Which CLIO-CODER*.md file(s) the compiled prompt actually selected. With
|
|
56
|
+
* override semantics the operator cannot infer the winner from the preload
|
|
57
|
+
* size alone, so the effective chain is named explicitly, nearest last.
|
|
58
|
+
*/
|
|
59
|
+
function handbookProvenanceLines(handbookFiles: ReadonlyArray<string> | null): string[] {
|
|
60
|
+
if (!handbookFiles || handbookFiles.length === 0) return [];
|
|
61
|
+
const first = handbookFiles[0];
|
|
62
|
+
if (handbookFiles.length === 1 && first !== undefined) return [`handbook: ${displayHandbookPath(first)}`];
|
|
63
|
+
return ["handbooks (ancestor → nearest):", ...handbookFiles.map((filePath) => ` ${displayHandbookPath(filePath)}`)];
|
|
64
|
+
}
|
|
65
|
+
|
|
43
66
|
function gridDimensions(ledger: ContextLedger, contentWidth: number): { cols: number; rows: number } {
|
|
44
67
|
const cols = Math.max(12, Math.min(contentWidth, 40));
|
|
45
68
|
const rows = ledger.contextWindow >= 200_000 ? 8 : 6;
|
|
@@ -58,7 +81,7 @@ function legendRow(group: ContextLedgerGroup, contentWidth: number): string {
|
|
|
58
81
|
return `${swatch} ${theme.fg(labelToken, labelText)} ${theme.fg("muted", right)}`;
|
|
59
82
|
}
|
|
60
83
|
|
|
61
|
-
function renderContextLedgerLines(ledger: ContextLedger, contentWidth: number): string[] {
|
|
84
|
+
export function renderContextLedgerLines(ledger: ContextLedger, contentWidth: number): string[] {
|
|
62
85
|
const theme = clioTheme();
|
|
63
86
|
const lines: string[] = [];
|
|
64
87
|
|
|
@@ -92,6 +115,9 @@ function renderContextLedgerLines(ledger: ContextLedger, contentWidth: number):
|
|
|
92
115
|
if (ledger.projectPreload && ledger.groups.some((group) => group.category === "project")) {
|
|
93
116
|
lines.push(theme.fg("dim", `project preload: ${ledger.projectPreload}`));
|
|
94
117
|
}
|
|
118
|
+
for (const handbookLine of handbookProvenanceLines(ledger.projectHandbookFiles)) {
|
|
119
|
+
lines.push(theme.fg("dim", handbookLine));
|
|
120
|
+
}
|
|
95
121
|
const compaction =
|
|
96
122
|
ledger.compactionThreshold !== null
|
|
97
123
|
? `autocompact at ${Math.round(ledger.compactionThreshold * 100)}% (${ledger.compactionAuto ? "auto" : "manual"})`
|