@iowarp/clio-coder 0.3.0 → 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 +123 -2
- package/CONTRIBUTING.md +23 -23
- package/README.md +295 -627
- package/dist/acp-BIYHVZIM.js +128 -0
- package/dist/{agents-Q4MYPMUW.js → agents-YT6SSRIT.js} +52 -27
- package/dist/assets/codewiki.json +1 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
- package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
- package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter.wasm +0 -0
- package/dist/{auth-O6HYIJ6J.js → auth-5TWEIYDN.js} +30 -15
- package/dist/chunk-2EHAIA3X.js +481 -0
- package/dist/{chunk-ME6DNWIU.js → chunk-2IR2NMPA.js} +12 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-3I7MS7N2.js +40 -0
- package/dist/chunk-3R73A4XB.js +69 -0
- package/dist/{chunk-JPOWPFCU.js → chunk-3ZXDFGR5.js} +52 -23
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-26BZQOAD.js → chunk-4BPJXDWC.js} +161 -260
- package/dist/chunk-4KLWL3UC.js +18 -0
- package/dist/{chunk-5LDRNKX2.js → chunk-4VP4KH3K.js} +161 -262
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/chunk-5TSRNF4G.js +510 -0
- package/dist/{chunk-WD6AJM35.js → chunk-5UUP6MWO.js} +48 -69
- package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
- 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-XNISANGE.js → chunk-77VKQEHF.js} +171 -74
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/{chunk-UWIJNAOB.js → chunk-7EYHLWU7.js} +907 -638
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-JWHCJDCI.js → chunk-A3CYT5EX.js} +257 -79
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/chunk-AO4RKG4M.js +277 -0
- package/dist/chunk-APJ265NV.js +7410 -0
- package/dist/chunk-ARBGF5F7.js +174 -0
- package/dist/{chunk-TFSSEXL6.js → chunk-BMEMKKIT.js} +14 -4
- package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/{chunk-67MTHP2E.js → chunk-ED4KHGC3.js} +13 -5
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/{chunk-O4EJEDHO.js → chunk-EPVUXGXG.js} +50 -35
- 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-7BHLZB3A.js → chunk-GGXXDWE4.js} +190 -1218
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-E3NYWENM.js → chunk-HFSBBKSQ.js} +55 -61
- package/dist/chunk-HKIYEGME.js +30 -0
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/chunk-IGLFWIYI.js +161 -0
- package/dist/chunk-IHXBNWMM.js +137 -0
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
- package/dist/{chunk-VOO7NYPP.js → chunk-J5HN4RYU.js} +27 -9
- package/dist/{chunk-4UQA7NCT.js → chunk-J5Q24KAG.js} +7 -2
- package/dist/{chunk-KBR4MZZR.js → chunk-JVCV3ICN.js} +7 -1
- package/dist/chunk-KJ5LWLOE.js +1077 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-3DANZDGR.js → chunk-LBNRH5WM.js} +100 -161
- package/dist/{chunk-TKHQ4DGZ.js → chunk-LZSJBIVT.js} +7358 -7414
- package/dist/{chunk-UGYAX5YI.js → chunk-M6SHUN7Q.js} +13 -8
- package/dist/chunk-MAW544W2.js +1882 -0
- package/dist/chunk-MBS4V7ZP.js +217 -0
- package/dist/{chunk-2J63S4SF.js → chunk-MFFY33HR.js} +167 -140
- package/dist/chunk-MNA4JGU4.js +255 -0
- package/dist/chunk-MQSRRFWA.js +3428 -0
- package/dist/{chunk-RQDWMVRB.js → chunk-MVVUPGPW.js} +138 -137
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/chunk-OHHN2SO4.js +5135 -0
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-BBUH4VAA.js → chunk-OOJYHWRB.js} +60 -361
- package/dist/{chunk-D5YD55AR.js → chunk-OQ33BKR3.js} +12 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-AMFR5YA3.js → chunk-ORBHGJC5.js} +26 -12
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/{chunk-7RBKDI66.js → chunk-QTYWRVRA.js} +104 -12
- package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
- package/dist/chunk-SRF2PJNW.js +184 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/{chunk-XV4ZJ6ZM.js → chunk-STBPMHSX.js} +473 -1194
- package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TXOTCRLG.js +15 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-527KG6XR.js → chunk-V4RXGQ5Q.js} +72 -185
- 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-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
- 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-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
- package/dist/{chunk-PIDUD6M2.js → chunk-YCWGATWI.js} +12 -5
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-UHTSULZS.js → chunk-ZDOOVTXZ.js} +38 -73
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-CLJ5HLUD.js → chunk-ZWLZP4ZT.js} +25 -6
- package/dist/cli/index.js +70 -56
- 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-JVHMUBEB.js → components-KELWS457.js} +31 -9
- package/dist/{config-ZFCDBMDC.js → config-GTLUW2PR.js} +104 -56
- package/dist/configure-R6A64DHX.js +42 -0
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-CDXTP2MP.js → context-JFZEJ7W5.js} +21 -13
- package/dist/{context-E3KIFVXI.js → context-RW5HC47S.js} +77 -36
- package/dist/{context-clear-3F4PLXOS.js → context-clear-6ZHBAZZT.js} +64 -30
- package/dist/{context-index-Q7YSYTR3.js → context-index-BZ4UYMTC.js} +36 -24
- package/dist/dispatch-runner-VKBRCWQC.js +1997 -0
- package/dist/{docs-YIETIWZI.js → docs-2C2LTVT2.js} +32 -13
- package/dist/doctor-KI767GSN.js +87 -0
- package/dist/{eval-B3KZZESM.js → eval-XSSNATB4.js} +93 -27
- package/dist/{evidence-V67CHM35.js → evidence-UA6AWDQQ.js} +55 -27
- package/dist/{evolve-YDZSUQYA.js → evolve-QNTFGV6Z.js} +59 -26
- package/dist/{extensions-SRG7XCAH.js → extensions-QVDOHDGJ.js} +23 -8
- package/dist/{fleet-CA2CRTVG.js → fleet-Q7UOMUSG.js} +173 -56
- package/dist/fleet-preflight-DDN536IT.js +26 -0
- package/dist/{init-2OZDJE2D.js → init-WBB65ZHQ.js} +79 -34
- package/dist/{memory-3PIQQAKX.js → memory-MD3O64RI.js} +57 -28
- package/dist/{models-DY35XI7Y.js → models-BZU34YWD.js} +49 -24
- package/dist/monitor-MEQA5C3I.js +661 -0
- package/dist/{chunk-PS4PFJQP.js → orchestrator-CGFKEP27.js} +22837 -18564
- package/dist/{paths-5OMXW7Z4.js → paths-UXLN5YYZ.js} +17 -6
- package/dist/preload-P6DGH2PZ.js +13 -0
- package/dist/{reset-PIFYNOS3.js → reset-L2FQEE3E.js} +25 -13
- package/dist/{run-3VSPP24F.js → run-IV4Q6RLN.js} +115 -63
- package/dist/{share-D36RQCXM.js → share-S5BZQC5I.js} +23 -10
- package/dist/{skills-F2MRLELY.js → skills-LQEKRDTN.js} +42 -15
- package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-3DC4HEWS.js} +90 -45
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-DZMEZAH4.js → targets-C4SSGQOB.js} +78 -60
- package/dist/terminal-lease-IT5JW2NR.js +395 -0
- package/dist/{trace-7NYCUI2J.js → trace-PNCASAXC.js} +48 -17
- package/dist/tree-sitter-HGKH6LG4.js +4673 -0
- package/dist/{uninstall-AD3JWHBB.js → uninstall-FZCQCDKC.js} +19 -8
- package/dist/{upgrade-WYYBKGDY.js → upgrade-7TT7SQ3G.js} +66 -24
- package/dist/{usage-ULIDAGFF.js → usage-GV4PKT3M.js} +71 -32
- package/dist/verify-G6V4D2G7.js +716 -0
- package/dist/version-KGEG7EPO.js +21 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-DQF6Z66B.js} +98 -48
- package/dist/worker/entry.js +297 -54
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +29 -21
- package/docs/acp.md +191 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +157 -7
- package/docs/artifact-placement.md +101 -0
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +4 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +224 -97
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +236 -38
- package/docs/context-engine.md +34 -7
- package/docs/development-pipeline.md +102 -0
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +3 -3
- package/docs/environment-variables.md +15 -6
- package/docs/eval-runner.md +3 -3
- package/docs/evals-internal.md +2 -2
- package/docs/evidence-and-memory.md +10 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +25 -18
- package/docs/fleet-demo-runbook.md +22 -23
- package/docs/fleet-dispatch.md +117 -16
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +107 -15
- package/docs/installation-and-lifecycle.md +75 -17
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +46 -15
- 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 +14 -14
- package/docs/prompt-envelope-and-tools.md +25 -4
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -111
- package/docs/safety-model.md +28 -8
- 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 +101 -0
- package/docs/tool-usage.md +6 -5
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +121 -28
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +33 -36
- package/skills/README.md +5 -6
- 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/git/file-ticket/SKILL.md +107 -0
- package/skills/git/file-ticket/evals.md +54 -0
- package/skills/git/fix-issue/SKILL.md +106 -0
- package/skills/git/fix-issue/evals.md +71 -0
- package/skills/git/ship/SKILL.md +92 -0
- package/skills/git/ship/evals.md +72 -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/skill-marketplace.json +12 -20
- 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 +115 -0
- package/src/cli/agents.ts +60 -0
- package/src/cli/args.ts +280 -0
- package/src/cli/argv.ts +170 -0
- package/src/cli/ask.ts +34 -0
- package/src/cli/auth.ts +468 -0
- package/src/cli/bootstrap-generate.ts +498 -0
- package/src/cli/clio.ts +96 -0
- package/src/cli/components.ts +195 -0
- package/src/cli/config-inspect.ts +336 -0
- package/src/cli/config.ts +72 -0
- package/src/cli/configure-interop.ts +67 -0
- package/src/cli/configure-layout.ts +172 -0
- package/src/cli/configure.ts +1525 -0
- package/src/cli/context-clear.ts +76 -0
- package/src/cli/context-index.ts +100 -0
- package/src/cli/context.ts +321 -0
- package/src/cli/default-target.ts +55 -0
- package/src/cli/docs.ts +346 -0
- package/src/cli/doctor.ts +54 -0
- package/src/cli/eval.ts +315 -0
- package/src/cli/evidence.ts +225 -0
- package/src/cli/evolve.ts +219 -0
- package/src/cli/extensions.ts +214 -0
- package/src/cli/fleet.ts +868 -0
- package/src/cli/index.ts +338 -0
- package/src/cli/init.ts +219 -0
- package/src/cli/initial-message.ts +47 -0
- package/src/cli/internal-dispatch.ts +55 -0
- package/src/cli/memory.ts +182 -0
- package/src/cli/models.ts +257 -0
- package/src/cli/modes/json-stream.ts +121 -0
- package/src/cli/modes/jsonl.ts +9 -0
- package/src/cli/modes/print.ts +604 -0
- package/src/cli/oauth-manual-input.ts +72 -0
- package/src/cli/oauth-select.ts +36 -0
- package/src/cli/output-guard.ts +48 -0
- package/src/cli/paths.ts +44 -0
- package/src/cli/provider-target.ts +113 -0
- package/src/cli/removal.ts +72 -0
- package/src/cli/reset.ts +253 -0
- package/src/cli/run.ts +497 -0
- package/src/cli/share.ts +243 -0
- package/src/cli/shared.ts +60 -0
- package/src/cli/skills-eval.ts +1240 -0
- package/src/cli/skills.ts +485 -0
- package/src/cli/steer-channel.ts +86 -0
- package/src/cli/targets.ts +1154 -0
- package/src/cli/text-layout.ts +112 -0
- package/src/cli/trace.ts +322 -0
- package/src/cli/uninstall.ts +405 -0
- package/src/cli/upgrade.ts +286 -0
- package/src/cli/usage.ts +876 -0
- package/src/cli/validate-model.ts +28 -0
- package/src/cli/version.ts +7 -0
- package/src/cli/wiki-generate.ts +510 -0
- package/src/core/agent-environment.ts +7 -0
- package/src/core/artifact-paths.ts +43 -0
- package/src/core/bash-exec.ts +313 -0
- package/src/core/boot-trace.ts +42 -0
- package/src/core/bus-events.ts +744 -0
- package/src/core/bus-trace.ts +53 -0
- package/src/core/c-header-language.ts +265 -0
- package/src/core/clio-repo.ts +78 -0
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +1722 -0
- package/src/core/context-floor.ts +33 -0
- package/src/core/defaults.ts +659 -0
- package/src/core/domain-loader.ts +177 -0
- package/src/core/event-bus.ts +94 -0
- package/src/core/file-references.ts +282 -0
- package/src/core/git-commit-attribution.ts +362 -0
- package/src/core/guardrails.ts +185 -0
- package/src/core/headless-permission.ts +21 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/init.ts +223 -0
- package/src/core/json-payload.ts +58 -0
- package/src/core/package-root.ts +54 -0
- package/src/core/path-canonical.ts +37 -0
- package/src/core/process-identity.ts +41 -0
- package/src/core/recent-models.ts +91 -0
- package/src/core/residency-protection.ts +56 -0
- package/src/core/resolve-config-value.ts +88 -0
- package/src/core/response-schema.ts +279 -0
- package/src/core/run-overrides.ts +77 -0
- package/src/core/safe-exec.ts +205 -0
- package/src/core/safe-id.ts +37 -0
- package/src/core/safe-resource-write.ts +162 -0
- package/src/core/session-routing.ts +339 -0
- package/src/core/settings-layers.ts +354 -0
- package/src/core/shared-bus.ts +8 -0
- package/src/core/shell-quote.ts +26 -0
- package/src/core/skill-activation.ts +190 -0
- package/src/core/startup-timer.ts +37 -0
- package/src/core/state-file-lock.ts +219 -0
- package/src/core/termination.ts +275 -0
- package/src/core/timers.ts +38 -0
- package/src/core/tool-names.ts +65 -0
- package/src/core/verification-scripts.ts +13 -0
- package/src/core/workspace-files.ts +492 -0
- package/src/core/xdg.ts +177 -0
- package/src/domains/agents/builtins/architect.md +4 -4
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +1 -1
- package/src/domains/agents/builtins/documenter.md +1 -1
- package/src/domains/agents/builtins/git-master.md +3 -3
- package/src/domains/agents/builtins/provenance.md +1 -1
- package/src/domains/agents/builtins/researcher.md +1 -1
- package/src/domains/agents/builtins/scout.md +1 -1
- package/src/domains/agents/builtins/tester.md +1 -1
- package/src/domains/agents/builtins/verifier.md +1 -1
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/catalog.ts +172 -0
- package/src/domains/agents/contract.ts +16 -0
- package/src/domains/agents/extension.ts +110 -0
- package/src/domains/agents/fleet-commands.ts +154 -0
- package/src/domains/agents/fleet-contract.ts +797 -0
- package/src/domains/agents/frontmatter.ts +40 -0
- package/src/domains/agents/index.ts +102 -0
- package/src/domains/agents/manifest.ts +6 -0
- package/src/domains/agents/recipe-schema.ts +202 -0
- package/src/domains/agents/recipe.ts +125 -0
- package/src/domains/agents/registry.ts +111 -0
- package/src/domains/agents/result-contract.ts +1265 -0
- package/src/domains/agents/spec.ts +371 -0
- package/src/domains/agents/write-boundary.ts +109 -0
- package/src/domains/components/diff.ts +99 -0
- package/src/domains/components/hash.ts +21 -0
- package/src/domains/components/index.ts +3 -0
- package/src/domains/components/scan.ts +304 -0
- package/src/domains/components/snapshot.ts +108 -0
- package/src/domains/components/types.ts +82 -0
- package/src/domains/config/agent-namespace.ts +13 -0
- package/src/domains/config/classify.ts +106 -0
- package/src/domains/config/contract.ts +22 -0
- package/src/domains/config/extension.ts +142 -0
- package/src/domains/config/index.ts +23 -0
- package/src/domains/config/keybindings.ts +200 -0
- package/src/domains/config/manifest.ts +6 -0
- package/src/domains/config/watcher.ts +41 -0
- package/src/domains/context/adoption.ts +880 -0
- package/src/domains/context/bootstrap-prompt.ts +273 -0
- package/src/domains/context/bootstrap.ts +1502 -0
- package/src/domains/context/clear.ts +91 -0
- package/src/domains/context/clio-md.ts +429 -0
- 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/cmake.ts +356 -0
- package/src/domains/context/codewiki/cooperative.ts +46 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/digest.ts +135 -0
- package/src/domains/context/codewiki/grammar-assets.ts +33 -0
- package/src/domains/context/codewiki/indexer.ts +1529 -0
- 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 +771 -0
- package/src/domains/context/contract.ts +68 -0
- package/src/domains/context/excluded-dirs.ts +1 -0
- package/src/domains/context/extension.ts +358 -0
- package/src/domains/context/fingerprint.ts +198 -0
- package/src/domains/context/index.ts +154 -0
- package/src/domains/context/init-options.ts +69 -0
- package/src/domains/context/manifest.ts +6 -0
- package/src/domains/context/operator-profile.ts +157 -0
- package/src/domains/context/project-metadata.ts +529 -0
- package/src/domains/context/project-rules.ts +227 -0
- package/src/domains/context/prompt-context.ts +61 -0
- package/src/domains/context/refresh.ts +178 -0
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/sibling-files.ts +10 -0
- package/src/domains/context/state.ts +237 -0
- package/src/domains/context/wiki/assemble.ts +303 -0
- package/src/domains/context/wiki/frontmatter.ts +210 -0
- package/src/domains/context/wiki/generate.ts +595 -0
- package/src/domains/context/wiki/layout.ts +111 -0
- package/src/domains/context/wiki/meta.ts +221 -0
- package/src/domains/context/wiki/plan-store.ts +217 -0
- package/src/domains/context/wiki/plan.ts +250 -0
- package/src/domains/context/wiki/prompts.ts +283 -0
- package/src/domains/context/wiki/staleness.ts +198 -0
- package/src/domains/dispatch/active-route-planner.ts +168 -0
- package/src/domains/dispatch/admission-queue.ts +150 -0
- package/src/domains/dispatch/admission.ts +334 -0
- package/src/domains/dispatch/agent-candidates.ts +307 -0
- package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
- package/src/domains/dispatch/agent-ledger-store.ts +257 -0
- package/src/domains/dispatch/agent-ledger.ts +212 -0
- package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
- package/src/domains/dispatch/assignment-events.ts +132 -0
- package/src/domains/dispatch/assignment-reconcile.ts +76 -0
- package/src/domains/dispatch/assignment-store.ts +162 -0
- package/src/domains/dispatch/assignment.ts +278 -0
- package/src/domains/dispatch/backoff.ts +59 -0
- package/src/domains/dispatch/batch-store.ts +134 -0
- package/src/domains/dispatch/batch-tracker.ts +66 -0
- package/src/domains/dispatch/capability-match.ts +155 -0
- package/src/domains/dispatch/capacity-lease.ts +413 -0
- package/src/domains/dispatch/code-step-store.ts +52 -0
- package/src/domains/dispatch/code-step.ts +387 -0
- package/src/domains/dispatch/contract.ts +278 -0
- package/src/domains/dispatch/dedup.ts +133 -0
- package/src/domains/dispatch/event-pump.ts +251 -0
- package/src/domains/dispatch/execution-handoff.ts +29 -0
- package/src/domains/dispatch/execution-plan.ts +328 -0
- package/src/domains/dispatch/execution-role.ts +277 -0
- package/src/domains/dispatch/execution-scheduler.ts +583 -0
- package/src/domains/dispatch/extension.ts +6006 -0
- package/src/domains/dispatch/failure-classification.ts +147 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/fleet-plan.ts +225 -0
- package/src/domains/dispatch/fleet-preflight.ts +394 -0
- package/src/domains/dispatch/gate-decisions.ts +1040 -0
- package/src/domains/dispatch/gate-role-prompts.ts +58 -0
- package/src/domains/dispatch/heartbeat.ts +27 -0
- package/src/domains/dispatch/index.ts +137 -0
- package/src/domains/dispatch/joint-route-adapter.ts +114 -0
- package/src/domains/dispatch/joint-route-resolver.ts +283 -0
- package/src/domains/dispatch/manifest.ts +6 -0
- package/src/domains/dispatch/orphan-recovery.ts +266 -0
- package/src/domains/dispatch/outcome.ts +109 -0
- package/src/domains/dispatch/phase-timing.ts +47 -0
- package/src/domains/dispatch/placement.ts +202 -0
- package/src/domains/dispatch/receipt-findings.ts +255 -0
- package/src/domains/dispatch/receipt-integrity.ts +383 -0
- package/src/domains/dispatch/recovery-candidates.ts +74 -0
- package/src/domains/dispatch/reproducibility.ts +48 -0
- package/src/domains/dispatch/reservation-store.ts +501 -0
- package/src/domains/dispatch/route-approval.ts +177 -0
- package/src/domains/dispatch/route-candidates.ts +57 -0
- package/src/domains/dispatch/route-decision.ts +1079 -0
- package/src/domains/dispatch/route-facts.ts +187 -0
- package/src/domains/dispatch/route-history.ts +238 -0
- package/src/domains/dispatch/route-observer.ts +488 -0
- package/src/domains/dispatch/route-policy.ts +327 -0
- package/src/domains/dispatch/route-quality.ts +256 -0
- package/src/domains/dispatch/route-readiness.ts +120 -0
- package/src/domains/dispatch/routing-intent.ts +287 -0
- package/src/domains/dispatch/run-identity.ts +56 -0
- package/src/domains/dispatch/scout-transition.ts +130 -0
- package/src/domains/dispatch/state.ts +302 -0
- package/src/domains/dispatch/tool-stats.ts +132 -0
- package/src/domains/dispatch/transport.ts +210 -0
- package/src/domains/dispatch/types.ts +799 -0
- package/src/domains/dispatch/validation-grounding.ts +154 -0
- package/src/domains/dispatch/validation.ts +721 -0
- package/src/domains/dispatch/worker-protocol.ts +275 -0
- package/src/domains/dispatch/worker-spawn.ts +585 -0
- package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
- package/src/domains/dispatch/write-boundary.ts +426 -0
- package/src/domains/eval/artifacts/redact.ts +42 -0
- package/src/domains/eval/artifacts/store.ts +173 -0
- package/src/domains/eval/compare/compare.ts +33 -0
- package/src/domains/eval/compare/gates.ts +66 -0
- package/src/domains/eval/compare/thresholds.ts +92 -0
- package/src/domains/eval/harness-metrics.ts +62 -0
- package/src/domains/eval/index.ts +66 -0
- package/src/domains/eval/metrics/chaos-stream.ts +93 -0
- package/src/domains/eval/metrics/context.ts +34 -0
- package/src/domains/eval/metrics/coverage.ts +21 -0
- package/src/domains/eval/metrics/evidence.ts +182 -0
- package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
- package/src/domains/eval/metrics/invariants.ts +736 -0
- package/src/domains/eval/metrics/latency.ts +4 -0
- package/src/domains/eval/metrics/token-stream.ts +139 -0
- package/src/domains/eval/metrics/tokens.ts +51 -0
- package/src/domains/eval/metrics/tool-calls.ts +7 -0
- package/src/domains/eval/proactive-memory.ts +279 -0
- package/src/domains/eval/provenance.ts +35 -0
- package/src/domains/eval/report.ts +234 -0
- package/src/domains/eval/reports/json.ts +5 -0
- package/src/domains/eval/reports/junit.ts +23 -0
- package/src/domains/eval/reports/markdown.ts +20 -0
- package/src/domains/eval/reports/swe-jsonl.ts +16 -0
- package/src/domains/eval/reports/text.ts +25 -0
- package/src/domains/eval/run-compare.ts +274 -0
- package/src/domains/eval/runner.ts +244 -0
- package/src/domains/eval/runners/clio-run.ts +148 -0
- package/src/domains/eval/runners/context-index.ts +56 -0
- package/src/domains/eval/runners/context-init.ts +203 -0
- package/src/domains/eval/runners/external-command.ts +350 -0
- package/src/domains/eval/runtime-paths.ts +171 -0
- package/src/domains/eval/schema/artifact.ts +75 -0
- package/src/domains/eval/schema/suite.ts +235 -0
- package/src/domains/eval/schema/validate.ts +339 -0
- package/src/domains/eval/store.ts +392 -0
- package/src/domains/eval/suites/load.ts +74 -0
- package/src/domains/eval/suites/matrix.ts +19 -0
- package/src/domains/eval/suites/resolve.ts +44 -0
- package/src/domains/eval/suites/run.ts +325 -0
- package/src/domains/eval/task-file.ts +186 -0
- package/src/domains/eval/types.ts +140 -0
- package/src/domains/eval/verifiers/command.ts +27 -0
- package/src/domains/eval/verifiers/file-exists.ts +6 -0
- package/src/domains/eval/verifiers/patch.ts +22 -0
- package/src/domains/eval/workspaces/git.ts +41 -0
- package/src/domains/eval/workspaces/local.ts +17 -0
- package/src/domains/eval/workspaces/temp-copy.ts +29 -0
- package/src/domains/evidence/build.ts +1754 -0
- package/src/domains/evidence/eval.ts +605 -0
- package/src/domains/evidence/failure-attribution.ts +54 -0
- package/src/domains/evidence/finish-contract-map.ts +42 -0
- package/src/domains/evidence/index.ts +55 -0
- package/src/domains/evidence/provenance.ts +200 -0
- package/src/domains/evidence/redact.ts +81 -0
- package/src/domains/evidence/store.ts +291 -0
- package/src/domains/evidence/types.ts +325 -0
- package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
- package/src/domains/evolution/index.ts +26 -0
- package/src/domains/evolution/manifest.ts +154 -0
- package/src/domains/evolution/validate.ts +304 -0
- package/src/domains/extensions/contract.ts +22 -0
- package/src/domains/extensions/discovery.ts +193 -0
- package/src/domains/extensions/extension.ts +46 -0
- package/src/domains/extensions/index.ts +34 -0
- package/src/domains/extensions/manager.ts +30 -0
- package/src/domains/extensions/manifest.ts +6 -0
- package/src/domains/extensions/resources.ts +38 -0
- package/src/domains/extensions/state.ts +224 -0
- package/src/domains/extensions/types.ts +83 -0
- package/src/domains/interop/consent.ts +185 -0
- package/src/domains/interop/contract.ts +29 -0
- package/src/domains/interop/detect.ts +173 -0
- package/src/domains/interop/extension.ts +59 -0
- package/src/domains/interop/index.ts +34 -0
- package/src/domains/interop/manifest.ts +6 -0
- package/src/domains/interop/registry.ts +139 -0
- package/src/domains/interop/state.ts +92 -0
- package/src/domains/interop/types.ts +109 -0
- package/src/domains/lifecycle/contract.ts +11 -0
- package/src/domains/lifecycle/doctor.ts +536 -0
- package/src/domains/lifecycle/extension.ts +23 -0
- package/src/domains/lifecycle/index.ts +21 -0
- package/src/domains/lifecycle/install-method.ts +51 -0
- package/src/domains/lifecycle/manifest.ts +6 -0
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +114 -0
- package/src/domains/lifecycle/state.ts +93 -0
- package/src/domains/lifecycle/upgrade-notice.ts +35 -0
- package/src/domains/lifecycle/version.ts +35 -0
- package/src/domains/memory/index.ts +128 -0
- package/src/domains/memory/operations.ts +143 -0
- package/src/domains/memory/prompt-section.ts +86 -0
- package/src/domains/memory/proposal.ts +180 -0
- package/src/domains/memory/store.ts +163 -0
- package/src/domains/memory/task-bank.ts +229 -0
- package/src/domains/memory/task-memory-handoff.ts +222 -0
- package/src/domains/memory/task-memory-policy.ts +602 -0
- package/src/domains/memory/task-memory-status.ts +58 -0
- package/src/domains/memory/task-memory-telemetry.ts +346 -0
- package/src/domains/memory/task-memory-trace.ts +89 -0
- package/src/domains/memory/types.ts +74 -0
- package/src/domains/memory/validate.ts +297 -0
- package/src/domains/middleware/budget.ts +216 -0
- package/src/domains/middleware/contract.ts +35 -0
- package/src/domains/middleware/dispatch-nudge.ts +469 -0
- package/src/domains/middleware/extension.ts +129 -0
- package/src/domains/middleware/hook-receipts.ts +70 -0
- package/src/domains/middleware/hooks-io.ts +186 -0
- package/src/domains/middleware/hooks.ts +432 -0
- package/src/domains/middleware/index.ts +154 -0
- package/src/domains/middleware/manifest.ts +6 -0
- package/src/domains/middleware/memory-intervention.ts +701 -0
- package/src/domains/middleware/rules.ts +42 -0
- package/src/domains/middleware/runtime.ts +333 -0
- package/src/domains/middleware/skills-reminder.ts +202 -0
- package/src/domains/middleware/snapshot.ts +71 -0
- package/src/domains/middleware/stalled-turn.ts +71 -0
- package/src/domains/middleware/task-board-reminder.ts +87 -0
- package/src/domains/middleware/task-nudge.ts +77 -0
- package/src/domains/middleware/tool-choice-control.ts +42 -0
- package/src/domains/middleware/types.ts +131 -0
- package/src/domains/middleware/validate.ts +329 -0
- package/src/domains/observability/accountability.ts +67 -0
- package/src/domains/observability/contract.ts +168 -0
- package/src/domains/observability/cost.ts +206 -0
- package/src/domains/observability/evidence-index.ts +123 -0
- package/src/domains/observability/extension.ts +281 -0
- package/src/domains/observability/index.ts +78 -0
- package/src/domains/observability/manifest.ts +10 -0
- package/src/domains/observability/metrics.ts +37 -0
- package/src/domains/observability/projection.ts +477 -0
- package/src/domains/observability/telemetry.ts +89 -0
- package/src/domains/observability/trace-store.ts +1454 -0
- package/src/domains/prompts/compiler.ts +614 -0
- package/src/domains/prompts/contract.ts +46 -0
- package/src/domains/prompts/extension.ts +336 -0
- package/src/domains/prompts/fragment-loader.ts +138 -0
- package/src/domains/prompts/fragments/identity/clio.md +5 -6
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +19 -0
- package/src/domains/prompts/fragments/operating/contract.md +4 -41
- 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/hash.ts +73 -0
- package/src/domains/prompts/index.ts +32 -0
- package/src/domains/prompts/manifest.ts +8 -0
- package/src/domains/prompts/memory-intervention.ts +57 -0
- package/src/domains/prompts/preload.ts +82 -0
- package/src/domains/providers/auth/api-key.ts +47 -0
- package/src/domains/providers/auth/backend-file.ts +79 -0
- package/src/domains/providers/auth/backend-memory.ts +72 -0
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/index.ts +37 -0
- package/src/domains/providers/auth/oauth.ts +37 -0
- package/src/domains/providers/auth/storage.ts +726 -0
- package/src/domains/providers/capabilities.ts +58 -0
- package/src/domains/providers/catalog.ts +162 -0
- package/src/domains/providers/contract.ts +162 -0
- package/src/domains/providers/credentials.ts +20 -0
- package/src/domains/providers/eligibility.ts +24 -0
- package/src/domains/providers/errors.ts +64 -0
- package/src/domains/providers/extension.ts +548 -0
- package/src/domains/providers/index.ts +142 -0
- package/src/domains/providers/knowledge-base-path.ts +102 -0
- package/src/domains/providers/manifest.ts +6 -0
- package/src/domains/providers/model-capabilities.ts +136 -0
- package/src/domains/providers/model-discovery.ts +144 -0
- package/src/domains/providers/model-family.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +723 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +120 -37
- package/src/domains/providers/plugins.ts +61 -0
- package/src/domains/providers/probe/fingerprint.ts +64 -0
- package/src/domains/providers/probe/http.ts +114 -0
- package/src/domains/providers/probe/reasoning.ts +111 -0
- package/src/domains/providers/registry.ts +187 -0
- package/src/domains/providers/resolver.ts +156 -0
- package/src/domains/providers/runtime-resolution.ts +720 -0
- package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +78 -0
- package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
- package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
- package/src/domains/providers/runtimes/claude/common.ts +55 -0
- package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
- package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
- package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
- package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
- package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
- package/src/domains/providers/runtimes/cloud/google.ts +41 -0
- package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
- package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
- package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +164 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
- package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
- package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
- package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
- package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
- package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
- package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
- package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
- package/src/domains/providers/runtimes/protocol/google.ts +27 -0
- package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
- package/src/domains/providers/support.ts +241 -0
- package/src/domains/providers/thinking-control-policy.ts +85 -0
- package/src/domains/providers/types/capability-flags.ts +114 -0
- package/src/domains/providers/types/cost-provenance.ts +7 -0
- package/src/domains/providers/types/inference.ts +41 -0
- package/src/domains/providers/types/knowledge-base.ts +156 -0
- package/src/domains/providers/types/local-model-quirks.ts +216 -0
- package/src/domains/providers/types/runtime-descriptor.ts +181 -0
- package/src/domains/providers/types/target-descriptor.ts +60 -0
- package/src/domains/resources/collision.ts +92 -0
- package/src/domains/resources/common-loader.ts +140 -0
- package/src/domains/resources/contract.ts +24 -0
- package/src/domains/resources/extension.ts +59 -0
- package/src/domains/resources/index.ts +74 -0
- package/src/domains/resources/loader.ts +85 -0
- package/src/domains/resources/manifest.ts +6 -0
- package/src/domains/resources/prompts/loader.ts +246 -0
- package/src/domains/resources/prompts/substitute.ts +1 -0
- package/src/domains/resources/skills/content-hash.ts +107 -0
- package/src/domains/resources/skills/evals.ts +175 -0
- package/src/domains/resources/skills/install.ts +427 -0
- package/src/domains/resources/skills/loader.ts +985 -0
- package/src/domains/resources/skills/marketplace.ts +301 -0
- package/src/domains/resources/skills/provenance-pin.ts +115 -0
- package/src/domains/safety/action-classifier.ts +270 -0
- package/src/domains/safety/approval-axis.ts +23 -0
- package/src/domains/safety/audit.ts +493 -0
- package/src/domains/safety/autonomy.ts +174 -0
- package/src/domains/safety/call-target.ts +59 -0
- package/src/domains/safety/contract.ts +65 -0
- package/src/domains/safety/damage-control.ts +44 -0
- package/src/domains/safety/default-path-policy.ts +117 -0
- package/src/domains/safety/extension.ts +383 -0
- package/src/domains/safety/finish-contract-registration.ts +128 -0
- package/src/domains/safety/finish-contract.ts +554 -0
- package/src/domains/safety/index.ts +44 -0
- package/src/domains/safety/loop-detector.ts +143 -0
- package/src/domains/safety/manifest.ts +6 -0
- package/src/domains/safety/path-policy.ts +164 -0
- package/src/domains/safety/policy-engine.ts +994 -0
- package/src/domains/safety/project-policy.ts +391 -0
- package/src/domains/safety/protected-artifacts-registration.ts +189 -0
- package/src/domains/safety/protected-artifacts.ts +993 -0
- package/src/domains/safety/rejection-feedback.ts +102 -0
- package/src/domains/safety/rigor.ts +72 -0
- package/src/domains/safety/rule-compiler.ts +48 -0
- package/src/domains/safety/rule-pack-loader.ts +92 -0
- package/src/domains/safety/run-effects.ts +197 -0
- package/src/domains/safety/scope.ts +61 -0
- package/src/domains/scheduling/budget.ts +35 -0
- package/src/domains/scheduling/cluster.ts +175 -0
- package/src/domains/scheduling/contract.ts +30 -0
- package/src/domains/scheduling/extension.ts +91 -0
- package/src/domains/scheduling/index.ts +12 -0
- package/src/domains/scheduling/manifest.ts +6 -0
- package/src/domains/session/archive-readers.ts +208 -0
- package/src/domains/session/checkpoint.ts +38 -0
- package/src/domains/session/compaction/auto.ts +89 -0
- package/src/domains/session/compaction/branch-summary.ts +187 -0
- package/src/domains/session/compaction/compact.ts +493 -0
- package/src/domains/session/compaction/cut-point.ts +172 -0
- package/src/domains/session/compaction/defaults.ts +34 -0
- package/src/domains/session/compaction/mask-observations.ts +265 -0
- package/src/domains/session/compaction/session-entries.ts +18 -0
- package/src/domains/session/compaction/tokens.ts +148 -0
- package/src/domains/session/context-accounting.ts +583 -0
- package/src/domains/session/context-ledger.ts +362 -0
- package/src/domains/session/contract.ts +159 -0
- package/src/domains/session/cwd-fallback.ts +65 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +572 -0
- package/src/domains/session/extension.ts +403 -0
- package/src/domains/session/history.ts +172 -0
- package/src/domains/session/index.ts +84 -0
- package/src/domains/session/manager.ts +128 -0
- package/src/domains/session/manifest.ts +6 -0
- package/src/domains/session/migrations/index.ts +27 -0
- package/src/domains/session/prompt-manifest.ts +173 -0
- package/src/domains/session/protected-artifact-journal.ts +241 -0
- package/src/domains/session/protected-artifacts.ts +90 -0
- package/src/domains/session/retry.ts +230 -0
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +569 -0
- package/src/domains/session/tree/active-path.ts +137 -0
- package/src/domains/session/tree/fork.ts +159 -0
- package/src/domains/session/tree/manager.ts +128 -0
- package/src/domains/session/tree/navigator.ts +177 -0
- package/src/domains/session/tree/preview.ts +259 -0
- package/src/domains/session/usage.ts +148 -0
- package/src/domains/session/workspace/git-probe.ts +167 -0
- package/src/domains/session/workspace/index.ts +4 -0
- package/src/domains/session/workspace/project-type.ts +217 -0
- package/src/domains/session/workspace/snapshot.ts +74 -0
- package/src/domains/share/archive.ts +684 -0
- package/src/domains/share/contract.ts +9 -0
- package/src/domains/share/extension.ts +26 -0
- package/src/domains/share/index.ts +28 -0
- package/src/domains/share/manifest.ts +6 -0
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/adapter.ts +397 -0
- package/src/engine/acp/errors.ts +128 -0
- package/src/engine/acp/event-mapper.ts +154 -0
- package/src/engine/acp/server.ts +2238 -0
- package/src/engine/acp/tool-mediator.ts +686 -0
- package/src/engine/acp/transport.ts +775 -0
- package/src/engine/acp/types.ts +196 -0
- package/src/engine/agent.ts +29 -0
- package/src/engine/ai.ts +207 -0
- package/src/engine/alcf-oauth.ts +205 -0
- package/src/engine/antigravity/subprocess-runtime.ts +205 -0
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/degraded-inference.ts +95 -0
- package/src/engine/apis/index.ts +16 -0
- package/src/engine/apis/llamacpp-residency.ts +292 -0
- package/src/engine/apis/lmstudio-residency.ts +76 -0
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +528 -0
- package/src/engine/apis/openai-completions.ts +795 -0
- package/src/engine/apis/output-budget.ts +99 -0
- package/src/engine/apis/residency-lock.ts +29 -0
- package/src/engine/apis/residency.ts +776 -0
- package/src/engine/apis/resident-models.ts +42 -0
- package/src/engine/apis/sampling-overrides.ts +38 -0
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/claude/sdk-runtime.ts +685 -0
- package/src/engine/claude/session-id.ts +5 -0
- package/src/engine/claude/subprocess-runtime.ts +316 -0
- package/src/engine/claude/tool-safety.ts +400 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/external-subprocess.ts +23 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/harmony-response.ts +165 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/loop-guard.ts +1127 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +196 -0
- package/src/engine/pi-mono-names.ts +13 -0
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +272 -0
- package/src/engine/select-list.ts +53 -0
- package/src/engine/session.ts +834 -0
- package/src/engine/strip-tokenizer-sentinels.ts +125 -0
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +111 -0
- package/src/engine/types.ts +63 -0
- package/src/engine/worker-events.ts +100 -0
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1022 -0
- package/src/engine/worker-tools.ts +208 -0
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +2011 -0
- package/src/interactive/application-controller.ts +433 -0
- package/src/interactive/bus-notices.ts +265 -0
- package/src/interactive/chat-loop-messages.ts +626 -0
- package/src/interactive/chat-loop-policy.ts +18 -0
- package/src/interactive/chat-loop.ts +1090 -0
- package/src/interactive/chat-panel.ts +1820 -0
- package/src/interactive/chat-renderer.ts +1228 -0
- package/src/interactive/clio-editor.ts +161 -0
- package/src/interactive/command-fallbacks.ts +23 -0
- package/src/interactive/command-output.ts +85 -0
- package/src/interactive/context-activity.ts +203 -0
- package/src/interactive/context-meter.ts +223 -0
- package/src/interactive/context-overlay.ts +246 -0
- package/src/interactive/cost-overlay.ts +279 -0
- package/src/interactive/dispatch-board.ts +1319 -0
- package/src/interactive/dispatch-steering.ts +86 -0
- package/src/interactive/editor-bash.ts +46 -0
- package/src/interactive/editor-steer.ts +51 -0
- package/src/interactive/editor-submit.ts +507 -0
- 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/external-editor.ts +67 -0
- package/src/interactive/follow-up-queue-panel.ts +75 -0
- package/src/interactive/footer/dashboard.ts +538 -0
- package/src/interactive/footer/notifications.ts +275 -0
- package/src/interactive/footer/widgets.ts +1264 -0
- package/src/interactive/footer-panel.ts +187 -0
- package/src/interactive/format-time.ts +97 -0
- package/src/interactive/index.ts +11 -0
- package/src/interactive/interactive-application.ts +939 -0
- package/src/interactive/interactive-event-projection.ts +385 -0
- package/src/interactive/interactive-input-runtime.ts +307 -0
- package/src/interactive/interactive-presentation.ts +584 -0
- package/src/interactive/interactive-shell.ts +388 -0
- package/src/interactive/interactive-slash-runtime.ts +554 -0
- package/src/interactive/interactive-subscriptions.ts +111 -0
- package/src/interactive/interactive-tickers.ts +183 -0
- package/src/interactive/keybinding-manager.ts +496 -0
- package/src/interactive/layout.ts +57 -0
- package/src/interactive/leader-key.ts +143 -0
- package/src/interactive/loop-guard-interrupt.ts +101 -0
- package/src/interactive/memory-overlay.ts +280 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
- package/src/interactive/overlay-auth-lifecycle.ts +308 -0
- package/src/interactive/overlay-frame.ts +502 -0
- package/src/interactive/overlay-general-openers.ts +274 -0
- package/src/interactive/overlay-key-routing.ts +216 -0
- package/src/interactive/overlay-lifecycle.ts +426 -0
- package/src/interactive/overlay-model-selectors.ts +127 -0
- package/src/interactive/overlay-permission-lifecycle.ts +345 -0
- package/src/interactive/overlay-resource-openers.ts +112 -0
- package/src/interactive/overlay-session-lifecycle.ts +327 -0
- package/src/interactive/overlay-transitions.ts +57 -0
- package/src/interactive/overlays/agents.ts +69 -0
- package/src/interactive/overlays/ask-user.ts +921 -0
- package/src/interactive/overlays/auth-dialog.ts +221 -0
- package/src/interactive/overlays/context-reset.ts +108 -0
- package/src/interactive/overlays/cwd-fallback.ts +141 -0
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/extensions.ts +54 -0
- package/src/interactive/overlays/help-reference.ts +145 -0
- package/src/interactive/overlays/interop.ts +139 -0
- package/src/interactive/overlays/keybinding-detail.ts +90 -0
- package/src/interactive/overlays/list-overlay.ts +606 -0
- package/src/interactive/overlays/message-picker.ts +155 -0
- package/src/interactive/overlays/model-selector.ts +1109 -0
- package/src/interactive/overlays/prompts.ts +72 -0
- package/src/interactive/overlays/session-selector-search.ts +31 -0
- package/src/interactive/overlays/session-selector.ts +284 -0
- package/src/interactive/overlays/settings.ts +3451 -0
- package/src/interactive/overlays/skills-hub.ts +237 -0
- package/src/interactive/overlays/tree-selector.ts +422 -0
- package/src/interactive/permission-overlay.ts +170 -0
- package/src/interactive/render-trace.ts +534 -0
- package/src/interactive/renderers/branch-summary.ts +86 -0
- package/src/interactive/renderers/code-ink.ts +420 -0
- package/src/interactive/renderers/compaction-summary.ts +112 -0
- package/src/interactive/renderers/diff.ts +137 -0
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/notice.ts +28 -0
- package/src/interactive/renderers/retry-status.ts +31 -0
- package/src/interactive/renderers/structured.ts +89 -0
- package/src/interactive/renderers/tool-execution.ts +1357 -0
- package/src/interactive/renderers/worker-entry.ts +280 -0
- package/src/interactive/session-last-turn.ts +186 -0
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/session-transcript.ts +105 -0
- package/src/interactive/session-usage-reseed.ts +74 -0
- package/src/interactive/slash-autocomplete.ts +256 -0
- package/src/interactive/slash-commands.ts +1407 -0
- package/src/interactive/slash-spec.ts +424 -0
- package/src/interactive/status/controller.ts +260 -0
- package/src/interactive/status/index.ts +23 -0
- package/src/interactive/status/state-machine.ts +530 -0
- package/src/interactive/status/summary.ts +170 -0
- package/src/interactive/status/types.ts +121 -0
- package/src/interactive/status/verbs.ts +163 -0
- package/src/interactive/status/watchdog.ts +24 -0
- 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 +540 -0
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/components.ts +55 -0
- package/src/interactive/theme/glyphs.ts +70 -0
- package/src/interactive/theme/index.ts +15 -0
- package/src/interactive/theme/labels.ts +88 -0
- package/src/interactive/theme/rules.ts +138 -0
- package/src/interactive/theme/segments.ts +88 -0
- package/src/interactive/theme/tokens.ts +121 -0
- package/src/interactive/thinking-level-policy.ts +6 -0
- package/src/interactive/tool-prose-loop.ts +122 -0
- package/src/interactive/tool-prose-registration.ts +48 -0
- package/src/interactive/turn-context.ts +855 -0
- package/src/interactive/turn-middleware.ts +283 -0
- package/src/interactive/turn-persistence.ts +458 -0
- package/src/interactive/turn-queues.ts +181 -0
- package/src/interactive/turn-recovery.ts +323 -0
- package/src/interactive/turn-runtime.ts +869 -0
- package/src/interactive/turn-state.ts +133 -0
- package/src/interactive/view/artifacts.ts +1452 -0
- package/src/interactive/view/view-overlay.ts +735 -0
- package/src/interactive/welcome-dashboard.ts +537 -0
- package/src/interactive/worker-receipts.ts +143 -0
- package/src/interactive/worker-replay.ts +111 -0
- package/src/interactive/worker-share.ts +100 -0
- package/src/interactive/worker-stream.ts +446 -0
- package/src/interactive/workspace-facts.ts +141 -0
- package/src/tools/agent-tools.ts +402 -0
- package/src/tools/artifact.ts +103 -0
- package/src/tools/ask-user.ts +666 -0
- package/src/tools/bash.ts +204 -0
- package/src/tools/bootstrap.ts +77 -0
- 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 +549 -0
- package/src/tools/codewiki/shared.ts +118 -0
- package/src/tools/compete-worktrees.ts +898 -0
- package/src/tools/context/docs-engine.ts +630 -0
- package/src/tools/context/index.ts +514 -0
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +151 -0
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-arguments.ts +228 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +746 -0
- 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-scout.ts +461 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +244 -0
- package/src/tools/edit-diff.ts +534 -0
- package/src/tools/edit.ts +128 -0
- package/src/tools/executables.ts +22 -0
- package/src/tools/file-mutation-queue.ts +35 -0
- package/src/tools/find.ts +294 -0
- package/src/tools/grep.ts +495 -0
- package/src/tools/ignore-policy.ts +169 -0
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +206 -0
- package/src/tools/ls.ts +110 -0
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +767 -0
- package/src/tools/network-policy.ts +29 -0
- package/src/tools/observation.ts +421 -0
- package/src/tools/observers.ts +99 -0
- package/src/tools/path-utils.ts +79 -0
- package/src/tools/policy.ts +154 -0
- package/src/tools/profiles.ts +108 -0
- package/src/tools/read.ts +173 -0
- package/src/tools/registry.ts +1169 -0
- package/src/tools/result-shaping.ts +204 -0
- package/src/tools/safe-exec.ts +128 -0
- package/src/tools/spawn-hygiene.ts +182 -0
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +77 -0
- package/src/tools/tasks.ts +265 -0
- package/src/tools/truncate-utf8.ts +17 -0
- package/src/tools/truncate.ts +43 -0
- package/src/tools/verify/frontend.ts +687 -0
- package/src/tools/verify/index.ts +31 -0
- package/src/tools/verify/scripts.ts +108 -0
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +759 -0
- package/src/tools/worker-evidence.ts +215 -0
- package/src/tools/write.ts +57 -0
- package/src/utils/exif-orientation.ts +192 -0
- package/src/utils/git.ts +24 -0
- package/src/utils/image-resize.ts +148 -0
- package/src/utils/photon.ts +103 -0
- package/src/worker/control-lane.ts +22 -0
- package/src/worker/entry.ts +294 -0
- package/src/worker/event-projection.ts +56 -0
- package/src/worker/heartbeat.ts +24 -0
- package/src/worker/ledger-mirror.ts +95 -0
- package/src/worker/ndjson.ts +40 -0
- package/src/worker/protocol.ts +529 -0
- package/src/worker/resource-facts.ts +79 -0
- package/src/worker/runtime-registry.ts +12 -0
- package/src/worker/spec-contract.ts +675 -0
- package/src/worker/stdin-demux.ts +316 -0
- package/dist/acp-UMLFVA3F.js +0 -92
- package/dist/chunk-262G75JS.js +0 -35
- package/dist/chunk-6CWDTGUC.js +0 -20
- package/dist/chunk-BYEU76JP.js +0 -899
- package/dist/chunk-GNGDQYDU.js +0 -34688
- package/dist/chunk-GOTUR54M.js +0 -9
- package/dist/chunk-NI4DEJMC.js +0 -88
- package/dist/chunk-TPOCL34A.js +0 -2876
- package/dist/chunk-UU3R62TT.js +0 -128
- package/dist/clio-KIQ5SNDS.js +0 -53
- package/dist/configure-G4E3A2PG.js +0 -27
- package/dist/doctor-M5HJJZOL.js +0 -61
- package/dist/domains/agents/builtins/architect.md +0 -33
- package/dist/domains/agents/builtins/coder.md +0 -31
- package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
- package/dist/domains/agents/builtins/debugger.md +0 -30
- package/dist/domains/agents/builtins/documenter.md +0 -31
- package/dist/domains/agents/builtins/git-master.md +0 -30
- package/dist/domains/agents/builtins/provenance.md +0 -30
- package/dist/domains/agents/builtins/researcher.md +0 -71
- package/dist/domains/agents/builtins/scout.md +0 -42
- package/dist/domains/agents/builtins/tester.md +0 -31
- package/dist/domains/agents/builtins/verifier.md +0 -30
- package/dist/domains/agents/builtins/wiki-writer.md +0 -41
- package/dist/fleet-preflight-CLIAX7YR.js +0 -21
- package/dist/preload-KZVHET2B.js +0 -11
- package/dist/version-ROZ6CZKH.js +0 -16
- 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 -794
- 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 -314
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/skills/git/commit-crafting/SKILL.md +0 -79
- package/skills/git/commit-crafting/evals.md +0 -92
- package/skills/git/create-pr/SKILL.md +0 -116
- package/skills/git/create-pr/evals.md +0 -114
- package/skills/git/investigate-issue/SKILL.md +0 -139
- package/skills/git/investigate-issue/evals.md +0 -94
- package/skills/git/review-changes/SKILL.md +0 -103
- package/skills/git/review-changes/evals.md +0 -85
|
@@ -0,0 +1,1228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coalescing wrapper around chat events (slice 12.5d).
|
|
3
|
+
*
|
|
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
|
+
* entire transcript on every delta, which scaled linearly with response
|
|
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`.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
BashExecutionEntry,
|
|
18
|
+
BranchSummaryEntry,
|
|
19
|
+
CompactionSummaryEntry,
|
|
20
|
+
CustomEntry,
|
|
21
|
+
FileEntryEntry,
|
|
22
|
+
MessageEntry,
|
|
23
|
+
ModelChangeEntry,
|
|
24
|
+
ProtectedArtifactEntry,
|
|
25
|
+
SessionEntry,
|
|
26
|
+
SessionInfoEntry,
|
|
27
|
+
ThinkingLevelChangeEntry,
|
|
28
|
+
WorkerRunEntry,
|
|
29
|
+
} from "../domains/session/entries.js";
|
|
30
|
+
import { filterEntriesToActivePath } from "../domains/session/tree/active-path.js";
|
|
31
|
+
import {
|
|
32
|
+
type BashExecutionMessage,
|
|
33
|
+
BRANCH_SUMMARY_PREFIX,
|
|
34
|
+
BRANCH_SUMMARY_SUFFIX,
|
|
35
|
+
bashExecutionToText,
|
|
36
|
+
COMPACTION_SUMMARY_PREFIX,
|
|
37
|
+
COMPACTION_SUMMARY_SUFFIX,
|
|
38
|
+
} from "../engine/messages.js";
|
|
39
|
+
import { wrapTextWithAnsi } from "../engine/tui.js";
|
|
40
|
+
import type { AgentMessage } from "../engine/types.js";
|
|
41
|
+
import type { ChatLoopEvent, RetryStatusPayload } from "./chat-loop.js";
|
|
42
|
+
import { isSelfExplainingAbort } from "./chat-loop-messages.js";
|
|
43
|
+
import type { ChatPanel } from "./chat-panel.js";
|
|
44
|
+
import { renderBranchSummaryEntry } from "./renderers/branch-summary.js";
|
|
45
|
+
import { renderCompactionSummaryEntry } from "./renderers/compaction-summary.js";
|
|
46
|
+
import { styleTaggedNotice } from "./renderers/notice.js";
|
|
47
|
+
import { formatRetryStatus } from "./renderers/retry-status.js";
|
|
48
|
+
import { renderBashTranscriptExecution, renderToolResultOnly } from "./renderers/tool-execution.js";
|
|
49
|
+
import {
|
|
50
|
+
classifyStreamEvent,
|
|
51
|
+
createStreamPacer,
|
|
52
|
+
type SmoothStreamingMode,
|
|
53
|
+
type StreamPacer,
|
|
54
|
+
type StreamPacerSlice,
|
|
55
|
+
} from "./stream-pacer.js";
|
|
56
|
+
import { readWorkerReceiptFactsForReplay } from "./worker-receipts.js";
|
|
57
|
+
import { workerEntriesFromRunEntries } from "./worker-replay.js";
|
|
58
|
+
import type { WorkerReceiptReader } from "./worker-stream.js";
|
|
59
|
+
|
|
60
|
+
const DEFAULT_COALESCE_MS = 16;
|
|
61
|
+
const MAX_REPLAY_TEXT_CHARS = 20_000;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Event kinds whose render is deferred into a coalesce window. All other
|
|
65
|
+
* `ChatLoopEvent` kinds render synchronously and cancel any pending timer.
|
|
66
|
+
*/
|
|
67
|
+
const DELTA_TYPES: ReadonlySet<ChatLoopEvent["type"]> = new Set([
|
|
68
|
+
"text_delta",
|
|
69
|
+
"thinking_delta",
|
|
70
|
+
"tool_execution_update",
|
|
71
|
+
]);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A raw `message_update` wrapper whose inner event is a text or thinking
|
|
75
|
+
* delta is transparent to the transcript: the panel ignores it, and the
|
|
76
|
+
* derived `text_delta`/`thinking_delta` emitted in the same stack (see
|
|
77
|
+
* turn-runtime's public-event fan-out) is the canonical display input. Yet
|
|
78
|
+
* this renderer classified the wrapper as non-delta, so every provider chunk
|
|
79
|
+
* cancelled the pending coalesce window and requested an immediate render.
|
|
80
|
+
* The coalescer was defeated exactly while streaming, which is the one time
|
|
81
|
+
* it matters. Wrappers carrying tool-call formation stay on the synchronous
|
|
82
|
+
* path, because the panel consumes those directly.
|
|
83
|
+
*/
|
|
84
|
+
function isTransparentAssistantWrapper(event: ChatLoopEvent): boolean {
|
|
85
|
+
if (event.type !== "message_update") return false;
|
|
86
|
+
const inner = (event as { assistantMessageEvent?: { type?: unknown } }).assistantMessageEvent;
|
|
87
|
+
return inner?.type === "text_delta" || inner?.type === "thinking_delta";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface CreateCoalescingChatRendererDeps {
|
|
91
|
+
chatPanel: ChatPanel;
|
|
92
|
+
requestRender: () => void;
|
|
93
|
+
/** Coalesce window in ms. Defaults to 16 (one frame at 60fps). */
|
|
94
|
+
coalesceMs?: number;
|
|
95
|
+
/** Override for tests. Mirrors the setTimeout signature. */
|
|
96
|
+
setTimer?: (cb: () => void, ms: number) => unknown;
|
|
97
|
+
/** Override for tests. Mirrors the clearTimeout signature. */
|
|
98
|
+
clearTimer?: (id: unknown) => void;
|
|
99
|
+
/** Monotonic clock shared with the pacer; injectable for deterministic tests. */
|
|
100
|
+
now?: () => number;
|
|
101
|
+
/** Sequence captured at canonical projection ingress before this panel consumer runs. */
|
|
102
|
+
visibleEventSequence?: (event: ChatLoopEvent) => number | null;
|
|
103
|
+
onQueue?: (eventSeq: number, action: "admit" | "dequeue") => void;
|
|
104
|
+
onPanelApplied?: (eventSeq: number) => void;
|
|
105
|
+
/** Legacy aggregate callback retained for non-text cumulative tool-update observations. */
|
|
106
|
+
onDelta?: () => void;
|
|
107
|
+
/** Canonical presentation-ingress identity; absent keeps the exact legacy coalescer. */
|
|
108
|
+
streamIngress?: (event: ChatLoopEvent) => { sequence: number; generation: string | number; ingressAt: number } | null;
|
|
109
|
+
getSmoothStreamingMode?: () => SmoothStreamingMode;
|
|
110
|
+
isAutoPacingAllowed?: () => boolean;
|
|
111
|
+
/** Force and await one actual frame plus any stdout drain. */
|
|
112
|
+
commitFrame?: (reason?: string) => Promise<unknown>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface CoalescingChatRenderer {
|
|
116
|
+
applyEvent(event: ChatLoopEvent): void;
|
|
117
|
+
/** Cancel the pending coalesce timer (if any) and request one synchronous render. */
|
|
118
|
+
flush(): void;
|
|
119
|
+
/** Ordered barrier for replay, worker, command-output, and other panel mutations. */
|
|
120
|
+
mutate(mutation: () => void, reason?: string): void;
|
|
121
|
+
/** Drop queued presentation content before replacing/resetting the transcript. */
|
|
122
|
+
reset(mutation: () => void): void;
|
|
123
|
+
/** Drain paced content and await the first committed frame containing it. */
|
|
124
|
+
flushAndCommit(reason?: string): Promise<void>;
|
|
125
|
+
/** Apply a live mode change as an immediate ordered drain boundary. */
|
|
126
|
+
setSmoothStreamingMode(mode: SmoothStreamingMode): void;
|
|
127
|
+
dispose(): void;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function createCoalescingChatRenderer(deps: CreateCoalescingChatRendererDeps): CoalescingChatRenderer {
|
|
131
|
+
const setTimer = deps.setTimer ?? ((cb, ms) => setTimeout(cb, ms));
|
|
132
|
+
const clearTimer =
|
|
133
|
+
deps.clearTimer ??
|
|
134
|
+
((id) => {
|
|
135
|
+
clearTimeout(id as ReturnType<typeof setTimeout>);
|
|
136
|
+
});
|
|
137
|
+
const coalesceMs = deps.coalesceMs ?? DEFAULT_COALESCE_MS;
|
|
138
|
+
|
|
139
|
+
let pendingTimer: unknown = null;
|
|
140
|
+
let mutationDepth = 0;
|
|
141
|
+
let transactionNeedsRender = false;
|
|
142
|
+
let disposed = false;
|
|
143
|
+
let pacer: StreamPacer | null = null;
|
|
144
|
+
|
|
145
|
+
const fireCoalesced = (): void => {
|
|
146
|
+
if (disposed) return;
|
|
147
|
+
pendingTimer = null;
|
|
148
|
+
deps.requestRender();
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const cancelPending = (): boolean => {
|
|
152
|
+
if (pendingTimer === null) return false;
|
|
153
|
+
clearTimer(pendingTimer);
|
|
154
|
+
pendingTimer = null;
|
|
155
|
+
return true;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const requestTransactionalRender = (coalesce: boolean): void => {
|
|
159
|
+
if (mutationDepth > 0) {
|
|
160
|
+
transactionNeedsRender = true;
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (!coalesce) {
|
|
164
|
+
cancelPending();
|
|
165
|
+
deps.requestRender();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
deps.onDelta?.();
|
|
169
|
+
if (pendingTimer === null) pendingTimer = setTimer(fireCoalesced, coalesceMs);
|
|
170
|
+
};
|
|
171
|
+
const transaction = (operation: () => void, coalesce = false): void => {
|
|
172
|
+
mutationDepth += 1;
|
|
173
|
+
try {
|
|
174
|
+
operation();
|
|
175
|
+
} finally {
|
|
176
|
+
mutationDepth -= 1;
|
|
177
|
+
if (mutationDepth === 0 && transactionNeedsRender) {
|
|
178
|
+
transactionNeedsRender = false;
|
|
179
|
+
requestTransactionalRender(coalesce);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const applySlice = (slice: StreamPacerSlice): void => {
|
|
184
|
+
const event =
|
|
185
|
+
slice.kind === "text"
|
|
186
|
+
? ({ type: "text_delta", contentIndex: slice.contentIndex, delta: slice.text, partialText: "" } as const)
|
|
187
|
+
: ({ type: "thinking_delta", contentIndex: slice.contentIndex, delta: slice.text, partialThinking: "" } as const);
|
|
188
|
+
deps.chatPanel.applyEvent(event);
|
|
189
|
+
if (slice.finalForItem) {
|
|
190
|
+
deps.onPanelApplied?.(slice.sequence);
|
|
191
|
+
deps.onQueue?.(slice.sequence, "dequeue");
|
|
192
|
+
}
|
|
193
|
+
requestTransactionalRender(true);
|
|
194
|
+
};
|
|
195
|
+
if (deps.streamIngress && deps.getSmoothStreamingMode) {
|
|
196
|
+
pacer = createStreamPacer({
|
|
197
|
+
mode: deps.getSmoothStreamingMode(),
|
|
198
|
+
onSlice: applySlice,
|
|
199
|
+
onDiscard: (sequence) => deps.onQueue?.(sequence, "dequeue"),
|
|
200
|
+
...(deps.now ? { now: deps.now } : {}),
|
|
201
|
+
...(deps.setTimer ? { setTimer: deps.setTimer } : {}),
|
|
202
|
+
...(deps.clearTimer ? { clearTimer: deps.clearTimer } : {}),
|
|
203
|
+
...(deps.isAutoPacingAllowed ? { isAutoPacingAllowed: deps.isAutoPacingAllowed } : {}),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const syncPacerMode = (): SmoothStreamingMode => {
|
|
207
|
+
const mode = deps.getSmoothStreamingMode?.() ?? "off";
|
|
208
|
+
if (pacer && pacer.mode !== mode) transaction(() => pacer?.setMode(mode));
|
|
209
|
+
return mode;
|
|
210
|
+
};
|
|
211
|
+
const drainPacer = (reason: string): void => {
|
|
212
|
+
if (pacer?.snapshot().queuedItems) pacer.flush(reason);
|
|
213
|
+
};
|
|
214
|
+
const applyLegacy = (event: ChatLoopEvent): void => {
|
|
215
|
+
const visibleEventSeq = deps.visibleEventSequence?.(event) ?? null;
|
|
216
|
+
if (visibleEventSeq !== null) deps.onQueue?.(visibleEventSeq, "admit");
|
|
217
|
+
deps.chatPanel.applyEvent(event);
|
|
218
|
+
if (visibleEventSeq !== null) {
|
|
219
|
+
deps.onPanelApplied?.(visibleEventSeq);
|
|
220
|
+
deps.onQueue?.(visibleEventSeq, "dequeue");
|
|
221
|
+
}
|
|
222
|
+
if (DELTA_TYPES.has(event.type)) {
|
|
223
|
+
requestTransactionalRender(true);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
requestTransactionalRender(false);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const renderer: CoalescingChatRenderer = {
|
|
230
|
+
applyEvent(event) {
|
|
231
|
+
if (disposed) return;
|
|
232
|
+
if (isTransparentAssistantWrapper(event)) return;
|
|
233
|
+
const mode = syncPacerMode();
|
|
234
|
+
const ingress = deps.streamIngress?.(event) ?? null;
|
|
235
|
+
if (!pacer || mode === "off") {
|
|
236
|
+
applyLegacy(event);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const classification = classifyStreamEvent(event);
|
|
240
|
+
if (classification === "paced-display-content") {
|
|
241
|
+
if (ingress === null) {
|
|
242
|
+
applyLegacy(event);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const delta = event as Extract<ChatLoopEvent, { type: "text_delta" | "thinking_delta" }>;
|
|
246
|
+
if (delta.delta.length === 0) {
|
|
247
|
+
applyLegacy(event);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
deps.onQueue?.(ingress.sequence, "admit");
|
|
251
|
+
transaction(() => {
|
|
252
|
+
pacer?.enqueue({
|
|
253
|
+
sequence: ingress.sequence,
|
|
254
|
+
generation: ingress.generation,
|
|
255
|
+
kind: delta.type === "text_delta" ? "text" : "thinking",
|
|
256
|
+
contentIndex: delta.contentIndex,
|
|
257
|
+
text: delta.delta,
|
|
258
|
+
ingressAt: ingress.ingressAt,
|
|
259
|
+
folded: delta.type === "thinking_delta" && !deps.chatPanel.isThinkingExpanded(),
|
|
260
|
+
});
|
|
261
|
+
}, true);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (classification === "cumulative-live-state") {
|
|
265
|
+
transaction(() => {
|
|
266
|
+
drainPacer("cumulative-live-state");
|
|
267
|
+
applyLegacy(event);
|
|
268
|
+
}, true);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
transaction(() => {
|
|
272
|
+
drainPacer(`boundary:${event.type}`);
|
|
273
|
+
applyLegacy(event);
|
|
274
|
+
});
|
|
275
|
+
},
|
|
276
|
+
flush() {
|
|
277
|
+
if (disposed) return;
|
|
278
|
+
transaction(() => drainPacer("explicit-flush"));
|
|
279
|
+
const wasPending = cancelPending();
|
|
280
|
+
if (wasPending) deps.requestRender();
|
|
281
|
+
},
|
|
282
|
+
mutate(mutation, reason = "panel-mutation") {
|
|
283
|
+
if (disposed) return;
|
|
284
|
+
transaction(() => {
|
|
285
|
+
drainPacer(reason);
|
|
286
|
+
mutation();
|
|
287
|
+
requestTransactionalRender(false);
|
|
288
|
+
});
|
|
289
|
+
},
|
|
290
|
+
reset(mutation) {
|
|
291
|
+
if (disposed) return;
|
|
292
|
+
transaction(() => {
|
|
293
|
+
pacer?.invalidateEpoch();
|
|
294
|
+
mutation();
|
|
295
|
+
requestTransactionalRender(false);
|
|
296
|
+
});
|
|
297
|
+
},
|
|
298
|
+
async flushAndCommit(reason = "final-frame") {
|
|
299
|
+
if (disposed) return;
|
|
300
|
+
transaction(() => drainPacer(reason));
|
|
301
|
+
cancelPending();
|
|
302
|
+
if (deps.commitFrame) await deps.commitFrame(reason);
|
|
303
|
+
else deps.requestRender();
|
|
304
|
+
},
|
|
305
|
+
setSmoothStreamingMode(mode) {
|
|
306
|
+
if (disposed || !pacer || pacer.mode === mode) return;
|
|
307
|
+
transaction(() => pacer?.setMode(mode));
|
|
308
|
+
},
|
|
309
|
+
dispose() {
|
|
310
|
+
if (disposed) return;
|
|
311
|
+
transaction(() => pacer?.dispose("renderer-dispose"));
|
|
312
|
+
cancelPending();
|
|
313
|
+
disposed = true;
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
return renderer;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Options for the rehydrate helper used by /resume and /fork.
|
|
321
|
+
*/
|
|
322
|
+
export interface RehydrateChatPanelOptions {
|
|
323
|
+
/**
|
|
324
|
+
* Select the active branch ancestry without truncating later sidecars.
|
|
325
|
+
* Live compaction replay uses this so a summary appended after the current
|
|
326
|
+
* message leaf remains visible. Unset offline readers retain their
|
|
327
|
+
* file-order fallback.
|
|
328
|
+
*/
|
|
329
|
+
activeLeafTurnId?: string;
|
|
330
|
+
/**
|
|
331
|
+
* Pin the active-branch leaf and stop replay after that turn (inclusive).
|
|
332
|
+
* /tree switches and /fork pass the selected turn id so replay follows
|
|
333
|
+
* that turn's ancestry. Unset (default) treats the most recently appended
|
|
334
|
+
* message turn as the leaf.
|
|
335
|
+
*/
|
|
336
|
+
uptoTurnId?: string;
|
|
337
|
+
/**
|
|
338
|
+
* Render orphan tool results (results with no matching prior call) in full,
|
|
339
|
+
* without the live view's middle-elision. `/export` sets this so its
|
|
340
|
+
* throwaway panel writes complete tool bodies; the paired-result path reads
|
|
341
|
+
* the same intent from the panel's `unboundedToolBodies` option.
|
|
342
|
+
*/
|
|
343
|
+
unboundedToolBodies?: boolean;
|
|
344
|
+
/**
|
|
345
|
+
* Sealed-receipt reader for the worker blocks a `workerRun` entry names.
|
|
346
|
+
* Defaults to `<state>/receipts/<runId>.json`; tests inject their own. This
|
|
347
|
+
* is the one place replay reads outside the entry stream, and it swallows
|
|
348
|
+
* every failure, so a session whose receipts are gone still replays.
|
|
349
|
+
*/
|
|
350
|
+
readWorkerReceipt?: WorkerReceiptReader;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function extractTurnText(payload: unknown): string {
|
|
354
|
+
if (typeof payload === "string") return payload;
|
|
355
|
+
if (!payload || typeof payload !== "object") return "";
|
|
356
|
+
const p = payload as Record<string, unknown>;
|
|
357
|
+
if (typeof p.text === "string") return p.text;
|
|
358
|
+
if (Array.isArray(p.content)) {
|
|
359
|
+
for (const block of p.content) {
|
|
360
|
+
if (!block || typeof block !== "object") continue;
|
|
361
|
+
const b = block as Record<string, unknown>;
|
|
362
|
+
if (b.type === "text" && typeof b.text === "string") return b.text;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return "";
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function stringifyPreview(value: unknown, limit = 600): string {
|
|
369
|
+
if (value === undefined) return "";
|
|
370
|
+
if (typeof value === "string") return value.length <= limit ? value : `${value.slice(0, limit - 3)}...`;
|
|
371
|
+
try {
|
|
372
|
+
const text = JSON.stringify(value);
|
|
373
|
+
if (!text) return "";
|
|
374
|
+
return text.length <= limit ? text : `${text.slice(0, limit - 3)}...`;
|
|
375
|
+
} catch {
|
|
376
|
+
const text = String(value);
|
|
377
|
+
return text.length <= limit ? text : `${text.slice(0, limit - 3)}...`;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function truncateReplayText(text: string, limit = MAX_REPLAY_TEXT_CHARS): string {
|
|
382
|
+
if (text.length <= limit) return text;
|
|
383
|
+
const omitted = text.length - limit;
|
|
384
|
+
return `${text.slice(0, limit)}\n\n[... ${omitted} more characters truncated from replay context]`;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function timestampMillis(timestamp: string): number {
|
|
388
|
+
const parsed = Date.parse(timestamp);
|
|
389
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function makeTextMessage(role: "user" | "assistant", text: string, timestamp: string): AgentMessage {
|
|
393
|
+
const message: Record<string, unknown> = {
|
|
394
|
+
role,
|
|
395
|
+
content: [{ type: "text", text }],
|
|
396
|
+
timestamp: timestampMillis(timestamp),
|
|
397
|
+
};
|
|
398
|
+
if (role === "assistant") message.stopReason = "stop";
|
|
399
|
+
return message as unknown as AgentMessage;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function cloneContentBlocks(content: unknown, maxTextChars?: number): unknown[] | null {
|
|
403
|
+
if (!Array.isArray(content)) return null;
|
|
404
|
+
return content
|
|
405
|
+
.filter((block) => !!block && typeof block === "object")
|
|
406
|
+
.map((block) => {
|
|
407
|
+
const cloned: Record<string, unknown> = { ...(block as Record<string, unknown>) };
|
|
408
|
+
if (typeof maxTextChars === "number") {
|
|
409
|
+
if (typeof cloned.text === "string") cloned.text = truncateReplayText(cloned.text, maxTextChars);
|
|
410
|
+
if (typeof cloned.thinking === "string") cloned.thinking = truncateReplayText(cloned.thinking, maxTextChars);
|
|
411
|
+
}
|
|
412
|
+
return cloned;
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function richMessageFromEntry(entry: MessageEntry, maxTextChars?: number): AgentMessage | null {
|
|
417
|
+
if (entry.role !== "user" && entry.role !== "assistant") return null;
|
|
418
|
+
const obj = payloadObject(entry.payload);
|
|
419
|
+
const content = cloneContentBlocks(obj?.content, maxTextChars);
|
|
420
|
+
const text = truncateReplayText(extractTurnText(entry.payload), maxTextChars);
|
|
421
|
+
const stopReason = typeof obj?.stopReason === "string" ? obj.stopReason : undefined;
|
|
422
|
+
if (!content && text.length === 0 && !messageFailure(entry) && stopReason !== "length") return null;
|
|
423
|
+
const message: Record<string, unknown> = {
|
|
424
|
+
role: entry.role,
|
|
425
|
+
content: content ?? [{ type: "text", text }],
|
|
426
|
+
timestamp: timestampMillis(entry.timestamp),
|
|
427
|
+
};
|
|
428
|
+
if (entry.role === "assistant") {
|
|
429
|
+
const failure = messageFailure(entry);
|
|
430
|
+
message.stopReason = failure?.stopReason ?? stopReason ?? "stop";
|
|
431
|
+
if (failure) message.errorMessage = failure.errorMessage;
|
|
432
|
+
for (const key of [
|
|
433
|
+
"usage",
|
|
434
|
+
"api",
|
|
435
|
+
"provider",
|
|
436
|
+
"model",
|
|
437
|
+
"responseModel",
|
|
438
|
+
"responseId",
|
|
439
|
+
"diagnostics",
|
|
440
|
+
"contextUsageInvalidated",
|
|
441
|
+
]) {
|
|
442
|
+
if (obj?.[key] !== undefined) message[key] = obj[key];
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return message as unknown as AgentMessage;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function recordToolCallsFromMessage(message: AgentMessage, seen: Set<string>): void {
|
|
449
|
+
const content = (message as { content?: unknown }).content;
|
|
450
|
+
if (!Array.isArray(content)) return;
|
|
451
|
+
for (const block of content) {
|
|
452
|
+
if (!block || typeof block !== "object") continue;
|
|
453
|
+
const b = block as Record<string, unknown>;
|
|
454
|
+
if (b.type !== "toolCall") continue;
|
|
455
|
+
if (typeof b.id === "string" && b.id.length > 0) seen.add(b.id);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function toolCallMessageFromEntry(entry: MessageEntry): AgentMessage {
|
|
460
|
+
const call = extractToolCall(entry);
|
|
461
|
+
const block: Record<string, unknown> = { type: "toolCall", id: call.id, name: call.name };
|
|
462
|
+
if (call.args !== undefined) block.arguments = call.args;
|
|
463
|
+
return {
|
|
464
|
+
role: "assistant",
|
|
465
|
+
content: [block],
|
|
466
|
+
stopReason: "toolUse",
|
|
467
|
+
timestamp: timestampMillis(entry.timestamp),
|
|
468
|
+
} as unknown as AgentMessage;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function toolResultContent(result: unknown): unknown[] {
|
|
472
|
+
const obj = payloadObject(result);
|
|
473
|
+
if (Array.isArray(obj?.content)) {
|
|
474
|
+
return cloneContentBlocks(obj.content, MAX_REPLAY_TEXT_CHARS) ?? [];
|
|
475
|
+
}
|
|
476
|
+
if (isTextResult(result)) return [{ type: "text", text: truncateReplayText(result.text) }];
|
|
477
|
+
if (typeof result === "string") return [{ type: "text", text: truncateReplayText(result) }];
|
|
478
|
+
return [{ type: "text", text: stringifyPreview(result, 10_000) }];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function displayReplayToolResult(result: unknown): unknown {
|
|
482
|
+
const content = toolResultContent(result);
|
|
483
|
+
// Preserve the details record (observation envelope, exec records) so the
|
|
484
|
+
// replayed ledger line carries the same outcome facts as the live one.
|
|
485
|
+
const details = payloadObject(result)?.details;
|
|
486
|
+
return details !== null && details !== undefined && typeof details === "object" ? { content, details } : content;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function textFromContentBlocks(content: unknown): string {
|
|
490
|
+
if (!Array.isArray(content)) return "";
|
|
491
|
+
const parts: string[] = [];
|
|
492
|
+
for (const block of content) {
|
|
493
|
+
if (!block || typeof block !== "object") continue;
|
|
494
|
+
const b = block as Record<string, unknown>;
|
|
495
|
+
if (b.type === "text" && typeof b.text === "string") parts.push(b.text);
|
|
496
|
+
}
|
|
497
|
+
return parts.join("");
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function toolResultText(result: unknown): string {
|
|
501
|
+
const obj = payloadObject(result);
|
|
502
|
+
const contentText = textFromContentBlocks(obj?.content);
|
|
503
|
+
if (contentText.length > 0) return contentText;
|
|
504
|
+
if (isTextResult(result)) return result.text;
|
|
505
|
+
if (typeof result === "string") return result;
|
|
506
|
+
return stringifyPreview(result, 10_000);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function comparableReplayText(text: string): string {
|
|
510
|
+
return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim();
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function messagePayloadComparableText(payload: unknown): string {
|
|
514
|
+
const text = extractTurnText(payload);
|
|
515
|
+
if (text.length > 0) return text;
|
|
516
|
+
return textFromContentBlocks(payloadObject(payload)?.content);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function isLegacyToolResultAssistantDuplicate(toolResult: MessageEntry, assistant: MessageEntry): boolean {
|
|
520
|
+
const priorText = comparableReplayText(toolResultText(extractToolResult(toolResult).result));
|
|
521
|
+
if (priorText.length === 0) return false;
|
|
522
|
+
const assistantText = comparableReplayText(messagePayloadComparableText(assistant.payload));
|
|
523
|
+
return assistantText.length > 0 && assistantText === priorText;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function isTextResult(value: unknown): value is { text: string } {
|
|
527
|
+
return payloadObject(value)?.text !== undefined && typeof (value as { text?: unknown }).text === "string";
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function toolResultMessageFromEntry(entry: MessageEntry): AgentMessage {
|
|
531
|
+
const result = extractToolResult(entry);
|
|
532
|
+
return {
|
|
533
|
+
role: "toolResult",
|
|
534
|
+
content: toolResultContent(result.result),
|
|
535
|
+
toolCallId: result.id ?? entry.turnId,
|
|
536
|
+
toolName: result.name,
|
|
537
|
+
isError: result.isError,
|
|
538
|
+
timestamp: timestampMillis(entry.timestamp),
|
|
539
|
+
} as AgentMessage;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
function textBlockFromEntry(entry: MessageEntry): string {
|
|
543
|
+
const text = extractTurnText(entry.payload);
|
|
544
|
+
if (text.length > 0) return text;
|
|
545
|
+
return stringifyPreview(entry.payload);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function chatMessageText(entry: MessageEntry): string {
|
|
549
|
+
return extractTurnText(entry.payload);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
const LEADING_SYSTEM_REMINDER = /^\s*<system-reminder>[\s\S]*?<\/system-reminder>\s*/u;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* What the operator typed for a replayed user turn. The persisted text is the
|
|
556
|
+
* composed prompt (a system-reminder block and any skill preamble ride ahead of
|
|
557
|
+
* the operator's words, as visible text the model receives), and the live
|
|
558
|
+
* transcript only ever showed the typed part. Entries written since the
|
|
559
|
+
* operator text was persisted carry it directly; older entries drop the
|
|
560
|
+
* leading reminder scaffolding so a /fork or /resume redraw does not attribute
|
|
561
|
+
* it to the operator (#81).
|
|
562
|
+
*/
|
|
563
|
+
function replayedUserText(entry: MessageEntry): string {
|
|
564
|
+
const obj = payloadObject(entry.payload);
|
|
565
|
+
if (typeof obj?.operatorText === "string") return obj.operatorText;
|
|
566
|
+
let text = extractTurnText(entry.payload);
|
|
567
|
+
for (;;) {
|
|
568
|
+
const stripped = text.replace(LEADING_SYSTEM_REMINDER, "");
|
|
569
|
+
if (stripped === text) return text;
|
|
570
|
+
text = stripped;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
function messageFailure(entry: MessageEntry): { stopReason: "error" | "aborted"; errorMessage: string } | null {
|
|
575
|
+
const obj = payloadObject(entry.payload);
|
|
576
|
+
if (!obj) return null;
|
|
577
|
+
const stopReason = obj?.stopReason;
|
|
578
|
+
if (stopReason !== "error" && stopReason !== "aborted") return null;
|
|
579
|
+
const raw = obj.errorMessage;
|
|
580
|
+
if (isSelfExplainingAbort({ stopReason, errorMessage: raw, text: extractTurnText(entry.payload) })) return null;
|
|
581
|
+
const errorMessage =
|
|
582
|
+
typeof raw === "string" && raw.length > 0
|
|
583
|
+
? raw
|
|
584
|
+
: stopReason === "aborted"
|
|
585
|
+
? "request aborted"
|
|
586
|
+
: "model target returned an error";
|
|
587
|
+
return { stopReason, errorMessage };
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
function payloadObject(payload: unknown): Record<string, unknown> | null {
|
|
591
|
+
return payload && typeof payload === "object" && !Array.isArray(payload) ? (payload as Record<string, unknown>) : null;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
function parseMaybeJson(value: unknown): unknown {
|
|
595
|
+
if (typeof value !== "string") return value;
|
|
596
|
+
const trimmed = value.trim();
|
|
597
|
+
if (!trimmed) return value;
|
|
598
|
+
try {
|
|
599
|
+
return JSON.parse(trimmed) as unknown;
|
|
600
|
+
} catch {
|
|
601
|
+
return value;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
function firstContentBlock(payload: unknown, type: string): Record<string, unknown> | null {
|
|
606
|
+
const obj = payloadObject(payload);
|
|
607
|
+
const content = obj?.content;
|
|
608
|
+
if (!Array.isArray(content)) return null;
|
|
609
|
+
for (const block of content) {
|
|
610
|
+
if (!block || typeof block !== "object") continue;
|
|
611
|
+
const b = block as Record<string, unknown>;
|
|
612
|
+
if (b.type === type) return b;
|
|
613
|
+
}
|
|
614
|
+
return null;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
interface ReplayToolCall {
|
|
618
|
+
id: string;
|
|
619
|
+
name: string;
|
|
620
|
+
args: unknown;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
function extractToolCall(entry: MessageEntry): ReplayToolCall {
|
|
624
|
+
const payload = entry.payload;
|
|
625
|
+
const obj = payloadObject(payload);
|
|
626
|
+
const block = firstContentBlock(payload, "toolCall");
|
|
627
|
+
const fn = payloadObject(obj?.function);
|
|
628
|
+
const id =
|
|
629
|
+
(typeof obj?.id === "string" && obj.id) ||
|
|
630
|
+
(typeof obj?.toolCallId === "string" && obj.toolCallId) ||
|
|
631
|
+
(typeof obj?.tool_call_id === "string" && obj.tool_call_id) ||
|
|
632
|
+
(typeof block?.id === "string" && block.id) ||
|
|
633
|
+
entry.turnId;
|
|
634
|
+
const name =
|
|
635
|
+
(typeof obj?.name === "string" && obj.name) ||
|
|
636
|
+
(typeof obj?.toolName === "string" && obj.toolName) ||
|
|
637
|
+
(typeof obj?.tool === "string" && obj.tool) ||
|
|
638
|
+
(typeof fn?.name === "string" && fn.name) ||
|
|
639
|
+
(typeof block?.name === "string" && block.name) ||
|
|
640
|
+
"tool";
|
|
641
|
+
const args =
|
|
642
|
+
obj?.arguments ??
|
|
643
|
+
obj?.args ??
|
|
644
|
+
obj?.input ??
|
|
645
|
+
parseMaybeJson(fn?.arguments) ??
|
|
646
|
+
block?.arguments ??
|
|
647
|
+
block?.args ??
|
|
648
|
+
undefined;
|
|
649
|
+
return { id, name, args };
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
interface ReplayToolResult {
|
|
653
|
+
id: string | null;
|
|
654
|
+
name: string;
|
|
655
|
+
result: unknown;
|
|
656
|
+
isError: boolean;
|
|
657
|
+
durationMs?: number;
|
|
658
|
+
resultSummary?: Record<string, unknown>;
|
|
659
|
+
/** Persisted admission verdict; absent on history written before it was recorded. */
|
|
660
|
+
outcome?: string;
|
|
661
|
+
blockReason?: string;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
function extractToolResult(entry: MessageEntry): ReplayToolResult {
|
|
665
|
+
const payload = entry.payload;
|
|
666
|
+
const obj = payloadObject(payload);
|
|
667
|
+
const contentText = extractTurnText(payload);
|
|
668
|
+
const id =
|
|
669
|
+
(typeof obj?.toolCallId === "string" && obj.toolCallId) ||
|
|
670
|
+
(typeof obj?.tool_call_id === "string" && obj.tool_call_id) ||
|
|
671
|
+
(typeof obj?.id === "string" && obj.id) ||
|
|
672
|
+
null;
|
|
673
|
+
const name =
|
|
674
|
+
(typeof obj?.toolName === "string" && obj.toolName) ||
|
|
675
|
+
(typeof obj?.name === "string" && obj.name) ||
|
|
676
|
+
(typeof obj?.tool === "string" && obj.tool) ||
|
|
677
|
+
"tool";
|
|
678
|
+
const result =
|
|
679
|
+
obj?.result ?? obj?.output ?? obj?.out ?? obj?.content ?? (contentText.length > 0 ? contentText : payload);
|
|
680
|
+
const durationMs = typeof obj?.durationMs === "number" && Number.isFinite(obj.durationMs) ? obj.durationMs : undefined;
|
|
681
|
+
const resultSummary = payloadObject(obj?.resultSummary) ?? undefined;
|
|
682
|
+
const outcome = typeof obj?.outcome === "string" && obj.outcome.length > 0 ? obj.outcome : undefined;
|
|
683
|
+
const blockReason = typeof obj?.blockReason === "string" && obj.blockReason.length > 0 ? obj.blockReason : undefined;
|
|
684
|
+
return {
|
|
685
|
+
id,
|
|
686
|
+
name,
|
|
687
|
+
result,
|
|
688
|
+
isError: obj?.isError === true || obj?.error === true,
|
|
689
|
+
...(durationMs !== undefined ? { durationMs } : {}),
|
|
690
|
+
...(resultSummary !== undefined ? { resultSummary } : {}),
|
|
691
|
+
...(outcome !== undefined ? { outcome } : {}),
|
|
692
|
+
...(blockReason !== undefined ? { blockReason } : {}),
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
function renderReplayLine(text: string, width: number): string[] {
|
|
697
|
+
// Style a leading bracketed tag (`[skill]`, `[checkpoint]`, ...) dim with a
|
|
698
|
+
// muted body; free-form lines such as `system:` prefixes pass through
|
|
699
|
+
// unchanged so only bracketed notices pick up the treatment.
|
|
700
|
+
return wrapTextWithAnsi(styleTaggedNotice(text), width);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
function appendReplayLine(chatPanel: ChatPanel, text: string): void {
|
|
704
|
+
chatPanel.appendReplayBlock((width) => renderReplayLine(truncateReplayText(text), width));
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function renderBashExecutionEntry(entry: BashExecutionEntry, width: number): string[] {
|
|
708
|
+
return renderBashTranscriptExecution(
|
|
709
|
+
{
|
|
710
|
+
command: entry.command,
|
|
711
|
+
output: truncateReplayText(entry.output.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\s+$/g, "")),
|
|
712
|
+
running: false,
|
|
713
|
+
exitCode: entry.exitCode,
|
|
714
|
+
cancelled: entry.cancelled,
|
|
715
|
+
truncated: entry.truncated,
|
|
716
|
+
fullOutputPath: entry.fullOutputPath,
|
|
717
|
+
excludeFromContext: entry.excludeFromContext,
|
|
718
|
+
},
|
|
719
|
+
width,
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function renderRetryStatusEntry(entry: CustomEntry, width: number): string[] {
|
|
724
|
+
const data = payloadObject(entry.data);
|
|
725
|
+
if (!data) return wrapTextWithAnsi(styleTaggedNotice("[retry] status"), width);
|
|
726
|
+
const rawPhase = data.phase;
|
|
727
|
+
if (
|
|
728
|
+
rawPhase !== "scheduled" &&
|
|
729
|
+
rawPhase !== "waiting" &&
|
|
730
|
+
rawPhase !== "retrying" &&
|
|
731
|
+
rawPhase !== "cancelled" &&
|
|
732
|
+
rawPhase !== "exhausted" &&
|
|
733
|
+
rawPhase !== "recovered"
|
|
734
|
+
) {
|
|
735
|
+
return wrapTextWithAnsi(styleTaggedNotice("[retry] status"), width);
|
|
736
|
+
}
|
|
737
|
+
const attempt = typeof data.attempt === "number" ? data.attempt : null;
|
|
738
|
+
const maxAttempts = typeof data.maxAttempts === "number" ? data.maxAttempts : null;
|
|
739
|
+
if (attempt === null || maxAttempts === null) return wrapTextWithAnsi(styleTaggedNotice("[retry] status"), width);
|
|
740
|
+
const status: RetryStatusPayload = {
|
|
741
|
+
phase: rawPhase,
|
|
742
|
+
attempt,
|
|
743
|
+
maxAttempts,
|
|
744
|
+
...(typeof data.errorMessage === "string" && data.errorMessage.length > 0 ? { errorMessage: data.errorMessage } : {}),
|
|
745
|
+
...(typeof data.delayMs === "number" ? { delayMs: data.delayMs } : {}),
|
|
746
|
+
...(typeof data.seconds === "number" ? { seconds: data.seconds } : {}),
|
|
747
|
+
};
|
|
748
|
+
return wrapTextWithAnsi(formatRetryStatus(status), width);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Custom entries the replay renders. A custom entry is an extension point: some
|
|
753
|
+
* carry operator-facing text, and the rest are diagnostics the live transcript
|
|
754
|
+
* never shows. `promptRecompiled` is the latter, and replay dumped it as the
|
|
755
|
+
* literal type name plus a JSON blob of hashes in the middle of a resumed
|
|
756
|
+
* conversation, so a fork or resume showed a line the session itself never did.
|
|
757
|
+
* Rendering is opt-in: a known type, or `display: true` from a writer that means
|
|
758
|
+
* the entry to be seen.
|
|
759
|
+
*/
|
|
760
|
+
function rendersCustomEntry(entry: CustomEntry): boolean {
|
|
761
|
+
if (entry.display === false) return false;
|
|
762
|
+
if (entry.customType === "retryStatus") return true;
|
|
763
|
+
if (entry.customType === "finishContractAdvisory" || entry.customType === "middlewareReminder") return true;
|
|
764
|
+
return entry.display === true;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
function renderCustomEntry(entry: CustomEntry, width: number): string[] {
|
|
768
|
+
if (entry.customType === "retryStatus") return renderRetryStatusEntry(entry, width);
|
|
769
|
+
// "finishContractAdvisory" is the pre-middleware name for the same entry
|
|
770
|
+
// shape; older session ledgers still carry it.
|
|
771
|
+
if (entry.customType === "finishContractAdvisory" || entry.customType === "middlewareReminder") {
|
|
772
|
+
return renderReminderMessageEntry(entry, width);
|
|
773
|
+
}
|
|
774
|
+
if (entry.display !== true) return [];
|
|
775
|
+
const body = stringifyPreview(entry.data);
|
|
776
|
+
const suffix = body.length > 0 ? ` ${body}` : "";
|
|
777
|
+
return wrapTextWithAnsi(`custom:${entry.customType}${suffix}`, width);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
function renderReminderMessageEntry(entry: CustomEntry, width: number): string[] {
|
|
781
|
+
const data = payloadObject(entry.data);
|
|
782
|
+
const message = typeof data?.message === "string" && data.message.length > 0 ? data.message : "middleware reminder";
|
|
783
|
+
return wrapTextWithAnsi(message, width);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
function renderModelChangeEntry(entry: ModelChangeEntry, width: number): string[] {
|
|
787
|
+
const target = entry.target ? `${entry.target}/` : "";
|
|
788
|
+
return wrapTextWithAnsi(styleTaggedNotice(`[model] ${target}${entry.provider}/${entry.modelId}`), width);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
function renderThinkingChangeEntry(entry: ThinkingLevelChangeEntry, width: number): string[] {
|
|
792
|
+
return wrapTextWithAnsi(styleTaggedNotice(`[thinking] ${entry.thinkingLevel}`), width);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
function renderFileEntry(entry: FileEntryEntry, width: number): string[] {
|
|
796
|
+
const bytes = typeof entry.bytes === "number" ? `, ${entry.bytes} bytes` : "";
|
|
797
|
+
return wrapTextWithAnsi(styleTaggedNotice(`[file ${entry.operation}] ${entry.path}${bytes}`), width);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function renderProtectedArtifactEntry(entry: ProtectedArtifactEntry, width: number): string[] {
|
|
801
|
+
const validation =
|
|
802
|
+
entry.artifact.validationCommand === undefined
|
|
803
|
+
? ""
|
|
804
|
+
: ` after ${entry.artifact.validationCommand}${entry.artifact.validationExitCode === undefined ? "" : ` exit ${entry.artifact.validationExitCode}`}`;
|
|
805
|
+
return wrapTextWithAnsi(
|
|
806
|
+
styleTaggedNotice(`[protected] ${entry.artifact.path}${validation}: ${entry.artifact.reason}`),
|
|
807
|
+
width,
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
function renderSessionInfoEntry(entry: SessionInfoEntry, width: number): string[] {
|
|
812
|
+
if (entry.name) return wrapTextWithAnsi(styleTaggedNotice(`[session] ${entry.name}`), width);
|
|
813
|
+
if (entry.label && entry.targetTurnId) {
|
|
814
|
+
return wrapTextWithAnsi(styleTaggedNotice(`[label] ${entry.targetTurnId}: ${entry.label}`), width);
|
|
815
|
+
}
|
|
816
|
+
return [];
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
function truncateAtTurn(entries: ReadonlyArray<SessionEntry>, uptoTurnId?: string): SessionEntry[] {
|
|
820
|
+
if (!uptoTurnId) return [...entries];
|
|
821
|
+
const index = entries.findIndex((entry) => entry.turnId === uptoTurnId);
|
|
822
|
+
if (index < 0) return [...entries];
|
|
823
|
+
return entries.slice(0, index + 1);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
function latestCompactionIndex(entries: ReadonlyArray<SessionEntry>): number {
|
|
827
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
828
|
+
if (entries[i]?.kind === "compactionSummary") return i;
|
|
829
|
+
}
|
|
830
|
+
return -1;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function toolCallIdsInEntry(entry: SessionEntry): string[] {
|
|
834
|
+
if (entry.kind !== "message") return [];
|
|
835
|
+
if (entry.role === "tool_call") return [extractToolCall(entry).id];
|
|
836
|
+
if (entry.role !== "assistant") return [];
|
|
837
|
+
const obj = payloadObject(entry.payload);
|
|
838
|
+
if (!Array.isArray(obj?.content)) return [];
|
|
839
|
+
const ids: string[] = [];
|
|
840
|
+
for (const block of obj.content) {
|
|
841
|
+
if (!block || typeof block !== "object") continue;
|
|
842
|
+
const record = block as Record<string, unknown>;
|
|
843
|
+
if (record.type !== "toolCall") continue;
|
|
844
|
+
if (typeof record.id === "string" && record.id.length > 0) ids.push(record.id);
|
|
845
|
+
}
|
|
846
|
+
return ids;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
function toolResultIdInEntry(entry: SessionEntry): string | null {
|
|
850
|
+
if (entry.kind !== "message" || entry.role !== "tool_result") return null;
|
|
851
|
+
return extractToolResult(entry).id;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
function findPriorToolCallEntry(
|
|
855
|
+
entries: ReadonlyArray<SessionEntry>,
|
|
856
|
+
toolCallId: string,
|
|
857
|
+
endExclusive: number,
|
|
858
|
+
): SessionEntry | null {
|
|
859
|
+
for (let index = Math.min(endExclusive, entries.length) - 1; index >= 0; index -= 1) {
|
|
860
|
+
const entry = entries[index];
|
|
861
|
+
if (!entry) continue;
|
|
862
|
+
if (toolCallIdsInEntry(entry).includes(toolCallId)) return entry;
|
|
863
|
+
}
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
function repairToolResultOrphans(
|
|
868
|
+
allEntries: ReadonlyArray<SessionEntry>,
|
|
869
|
+
selected: ReadonlyArray<SessionEntry>,
|
|
870
|
+
compactionIndex: number,
|
|
871
|
+
): SessionEntry[] {
|
|
872
|
+
const out: SessionEntry[] = [];
|
|
873
|
+
const seenToolCalls = new Set<string>();
|
|
874
|
+
const emittedTurnIds = new Set<string>();
|
|
875
|
+
const remember = (entry: SessionEntry): void => {
|
|
876
|
+
emittedTurnIds.add(entry.turnId);
|
|
877
|
+
for (const id of toolCallIdsInEntry(entry)) seenToolCalls.add(id);
|
|
878
|
+
};
|
|
879
|
+
for (const entry of selected) {
|
|
880
|
+
const resultId = toolResultIdInEntry(entry);
|
|
881
|
+
if (resultId !== null && !seenToolCalls.has(resultId)) {
|
|
882
|
+
const dependency = findPriorToolCallEntry(allEntries, resultId, compactionIndex);
|
|
883
|
+
if (dependency !== null && !emittedTurnIds.has(dependency.turnId)) {
|
|
884
|
+
out.push(dependency);
|
|
885
|
+
remember(dependency);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
out.push(entry);
|
|
889
|
+
remember(entry);
|
|
890
|
+
}
|
|
891
|
+
return out;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Normalize a heterogeneous session JSONL stream into the entry sequence the
|
|
896
|
+
* replay surfaces should show. The stream is first narrowed to the active
|
|
897
|
+
* branch of the turn tree (activeLeafTurnId selects a live branch;
|
|
898
|
+
* uptoTurnId selects and historically truncates; otherwise the most recent
|
|
899
|
+
* append wins), so abandoned sibling turns from earlier /tree switches never
|
|
900
|
+
* replay. When the remaining slice contains a compaction boundary, render the
|
|
901
|
+
* latest summary first and keep only the retained suffix plus later entries,
|
|
902
|
+
* mirroring pi-coding-agent's buildSessionContext behavior.
|
|
903
|
+
*/
|
|
904
|
+
export function selectReplayEntries(
|
|
905
|
+
turns: ReadonlyArray<SessionEntry>,
|
|
906
|
+
options: RehydrateChatPanelOptions = {},
|
|
907
|
+
): SessionEntry[] {
|
|
908
|
+
const active = filterEntriesToActivePath(turns, options.activeLeafTurnId ?? options.uptoTurnId);
|
|
909
|
+
const entries = truncateAtTurn(active, options.uptoTurnId);
|
|
910
|
+
const compactionIndex = latestCompactionIndex(entries);
|
|
911
|
+
if (compactionIndex < 0) return dropLegacyToolResultAssistantDuplicates(entries);
|
|
912
|
+
|
|
913
|
+
const compaction = entries[compactionIndex] as CompactionSummaryEntry;
|
|
914
|
+
const selected: SessionEntry[] = [compaction];
|
|
915
|
+
const firstKeptIndex = compaction.firstKeptTurnId
|
|
916
|
+
? entries.findIndex((entry) => entry.turnId === compaction.firstKeptTurnId)
|
|
917
|
+
: -1;
|
|
918
|
+
if (firstKeptIndex >= 0 && firstKeptIndex < compactionIndex) {
|
|
919
|
+
selected.push(...entries.slice(firstKeptIndex, compactionIndex));
|
|
920
|
+
}
|
|
921
|
+
selected.push(...entries.slice(compactionIndex + 1));
|
|
922
|
+
return dropLegacyToolResultAssistantDuplicates(repairToolResultOrphans(entries, selected, compactionIndex));
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
function dropLegacyToolResultAssistantDuplicates(entries: ReadonlyArray<SessionEntry>): SessionEntry[] {
|
|
926
|
+
const out: SessionEntry[] = [];
|
|
927
|
+
for (const entry of entries) {
|
|
928
|
+
const previous = out[out.length - 1];
|
|
929
|
+
if (
|
|
930
|
+
entry.kind === "message" &&
|
|
931
|
+
entry.role === "assistant" &&
|
|
932
|
+
previous?.kind === "message" &&
|
|
933
|
+
previous.role === "tool_result" &&
|
|
934
|
+
isLegacyToolResultAssistantDuplicate(previous, entry)
|
|
935
|
+
) {
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
out.push(entry);
|
|
939
|
+
}
|
|
940
|
+
return out;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
function compactionContextText(entry: CompactionSummaryEntry): string {
|
|
944
|
+
return `${COMPACTION_SUMMARY_PREFIX}${entry.summary}${COMPACTION_SUMMARY_SUFFIX}`;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
function branchContextText(entry: BranchSummaryEntry): string {
|
|
948
|
+
return `${BRANCH_SUMMARY_PREFIX}${entry.summary}${BRANCH_SUMMARY_SUFFIX}`;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/** Project Clio's ledger entry onto pi's bash message so pi owns the replay wording. */
|
|
952
|
+
function bashContextText(entry: BashExecutionEntry): string {
|
|
953
|
+
const message: BashExecutionMessage = {
|
|
954
|
+
role: "bashExecution",
|
|
955
|
+
command: entry.command,
|
|
956
|
+
output: truncateReplayText(entry.output),
|
|
957
|
+
exitCode: entry.exitCode ?? undefined,
|
|
958
|
+
cancelled: entry.cancelled,
|
|
959
|
+
truncated: entry.truncated,
|
|
960
|
+
...(entry.fullOutputPath !== undefined ? { fullOutputPath: entry.fullOutputPath } : {}),
|
|
961
|
+
timestamp: Date.parse(entry.timestamp) || 0,
|
|
962
|
+
};
|
|
963
|
+
return bashExecutionToText(message);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
function appendContextMessage(out: AgentMessage[], role: "user" | "assistant", text: string, timestamp: string): void {
|
|
967
|
+
const trimmed = text.trim();
|
|
968
|
+
if (trimmed.length === 0) return;
|
|
969
|
+
out.push(makeTextMessage(role, truncateReplayText(trimmed), timestamp));
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
function skillActivationContextText(entry: Extract<SessionEntry, { kind: "skillActivation" }>): string {
|
|
973
|
+
const activation = entry.activation;
|
|
974
|
+
const turn = activation.turnId ? ` turn=${activation.turnId}` : "";
|
|
975
|
+
return `Active skill loaded: ${activation.name} source=${activation.source} hash=${activation.hash} path=${activation.filePath} triggeredBy=${activation.triggeredBy}${turn}. Continue honoring this skill unless the user changes direction.`;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
export function buildReplayAgentMessagesFromTurns(
|
|
979
|
+
turns: ReadonlyArray<SessionEntry>,
|
|
980
|
+
options: RehydrateChatPanelOptions = {},
|
|
981
|
+
): AgentMessage[] {
|
|
982
|
+
const out: AgentMessage[] = [];
|
|
983
|
+
const seenToolCalls = new Set<string>();
|
|
984
|
+
for (const entry of selectReplayEntries(turns, options)) {
|
|
985
|
+
switch (entry.kind) {
|
|
986
|
+
case "message": {
|
|
987
|
+
const text = textBlockFromEntry(entry);
|
|
988
|
+
if (entry.role === "user" || entry.role === "assistant") {
|
|
989
|
+
if (entry.role === "assistant" && messageFailure(entry)) break;
|
|
990
|
+
const message = richMessageFromEntry(entry, MAX_REPLAY_TEXT_CHARS);
|
|
991
|
+
if (message) {
|
|
992
|
+
out.push(message);
|
|
993
|
+
recordToolCallsFromMessage(message, seenToolCalls);
|
|
994
|
+
}
|
|
995
|
+
} else if (entry.role === "tool_call") {
|
|
996
|
+
const call = extractToolCall(entry);
|
|
997
|
+
if (!seenToolCalls.has(call.id)) {
|
|
998
|
+
const message = toolCallMessageFromEntry(entry);
|
|
999
|
+
out.push(message);
|
|
1000
|
+
recordToolCallsFromMessage(message, seenToolCalls);
|
|
1001
|
+
}
|
|
1002
|
+
} else if (entry.role === "tool_result") {
|
|
1003
|
+
out.push(toolResultMessageFromEntry(entry));
|
|
1004
|
+
} else if (entry.role === "system") {
|
|
1005
|
+
appendContextMessage(out, "user", `System note: ${text}`, entry.timestamp);
|
|
1006
|
+
}
|
|
1007
|
+
break;
|
|
1008
|
+
}
|
|
1009
|
+
case "bashExecution":
|
|
1010
|
+
if (!entry.excludeFromContext) appendContextMessage(out, "user", bashContextText(entry), entry.timestamp);
|
|
1011
|
+
break;
|
|
1012
|
+
case "branchSummary":
|
|
1013
|
+
appendContextMessage(out, "user", branchContextText(entry), entry.timestamp);
|
|
1014
|
+
break;
|
|
1015
|
+
case "compactionSummary":
|
|
1016
|
+
appendContextMessage(out, "user", compactionContextText(entry), entry.timestamp);
|
|
1017
|
+
break;
|
|
1018
|
+
case "skillActivation":
|
|
1019
|
+
appendContextMessage(out, "user", skillActivationContextText(entry), entry.timestamp);
|
|
1020
|
+
break;
|
|
1021
|
+
case "custom":
|
|
1022
|
+
case "modelChange":
|
|
1023
|
+
case "thinkingLevelChange":
|
|
1024
|
+
case "fileEntry":
|
|
1025
|
+
case "sessionInfo":
|
|
1026
|
+
case "label":
|
|
1027
|
+
case "protectedArtifact":
|
|
1028
|
+
case "taskLedger":
|
|
1029
|
+
case "decisionLedger":
|
|
1030
|
+
// A worker's answer is not the operator's words and not the model's.
|
|
1031
|
+
// It reaches the model only when an operator shares it, and a share
|
|
1032
|
+
// is already a user message by the time it lands in the ledger.
|
|
1033
|
+
case "workerRun":
|
|
1034
|
+
break;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
return out;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Rehydrate a chat panel from a persisted session's turn list. The
|
|
1042
|
+
* interactive layer calls this after /resume or /fork so the user sees the
|
|
1043
|
+
* prior transcript instead of a blank pane; without it, swapping the
|
|
1044
|
+
* session contract updated meta but left the visible chat untouched
|
|
1045
|
+
* (Row 51 and Row 52 on the Phase 12 ledger).
|
|
1046
|
+
*
|
|
1047
|
+
* Replays a structured SessionEntry stream. Compaction summaries, branch
|
|
1048
|
+
* summaries, bash executions, custom entries, and metadata entries are
|
|
1049
|
+
* rendered explicitly. Tool call/result entries are best-effort: when a
|
|
1050
|
+
* result can be paired to a prior call id it updates that tool segment,
|
|
1051
|
+
* otherwise it falls back to a standalone transcript line.
|
|
1052
|
+
*
|
|
1053
|
+
* Worker blocks are rebuilt from their `workerRun` entries plus the sealed
|
|
1054
|
+
* receipts those entries name, so a resumed session shows the answer a `/run`
|
|
1055
|
+
* produced rather than a header with nothing under it. The block is applied
|
|
1056
|
+
* through the same panel call the live reducer uses, which is what makes an
|
|
1057
|
+
* agent-origin card land under the tool segment that spawned it here too.
|
|
1058
|
+
*
|
|
1059
|
+
* Callers read turns via `openSession(id).turns()` and pass them in explicitly.
|
|
1060
|
+
* The receipt reader is the one thing this touches beyond the panel; it is a
|
|
1061
|
+
* parameter with a disk-backed default, and it never throws.
|
|
1062
|
+
*/
|
|
1063
|
+
export function rehydrateChatPanelFromTurns(
|
|
1064
|
+
chatPanel: ChatPanel,
|
|
1065
|
+
turns: ReadonlyArray<SessionEntry>,
|
|
1066
|
+
options: RehydrateChatPanelOptions = {},
|
|
1067
|
+
): void {
|
|
1068
|
+
const pendingToolIds: string[] = [];
|
|
1069
|
+
const selected = selectReplayEntries(turns, options);
|
|
1070
|
+
// One block per assignment, drawn where its first attempt started. Later
|
|
1071
|
+
// attempts of the same assignment fold into that block as `↻` rail lines, so
|
|
1072
|
+
// a failover replays as the one run it was rather than as two.
|
|
1073
|
+
const workerStates = workerEntriesFromRunEntries(
|
|
1074
|
+
selected.filter((entry): entry is WorkerRunEntry => entry.kind === "workerRun"),
|
|
1075
|
+
options.readWorkerReceipt ?? readWorkerReceiptFactsForReplay,
|
|
1076
|
+
);
|
|
1077
|
+
const placedAssignments = new Set<string>();
|
|
1078
|
+
for (const entry of selected) {
|
|
1079
|
+
switch (entry.kind) {
|
|
1080
|
+
case "message": {
|
|
1081
|
+
if (entry.role === "user") {
|
|
1082
|
+
const text = truncateReplayText(replayedUserText(entry));
|
|
1083
|
+
if (text.length > 0) chatPanel.appendUser(text);
|
|
1084
|
+
break;
|
|
1085
|
+
}
|
|
1086
|
+
if (entry.role === "assistant") {
|
|
1087
|
+
const text = chatMessageText(entry);
|
|
1088
|
+
const failure = messageFailure(entry);
|
|
1089
|
+
const richMessage = richMessageFromEntry(entry, MAX_REPLAY_TEXT_CHARS);
|
|
1090
|
+
if (richMessage || text.length > 0 || failure) {
|
|
1091
|
+
const message = richMessage ?? makeTextMessage("assistant", truncateReplayText(text), entry.timestamp);
|
|
1092
|
+
if (failure) {
|
|
1093
|
+
(message as { stopReason?: string; errorMessage?: string }).stopReason = failure.stopReason;
|
|
1094
|
+
(message as { stopReason?: string; errorMessage?: string }).errorMessage = failure.errorMessage;
|
|
1095
|
+
}
|
|
1096
|
+
chatPanel.applyEvent({ type: "message_end", message });
|
|
1097
|
+
chatPanel.applyEvent({ type: "agent_end", messages: [message] });
|
|
1098
|
+
}
|
|
1099
|
+
break;
|
|
1100
|
+
}
|
|
1101
|
+
if (entry.role === "tool_call") {
|
|
1102
|
+
const call = extractToolCall(entry);
|
|
1103
|
+
pendingToolIds.push(call.id);
|
|
1104
|
+
chatPanel.applyEvent({
|
|
1105
|
+
type: "tool_execution_start",
|
|
1106
|
+
toolCallId: call.id,
|
|
1107
|
+
toolName: call.name,
|
|
1108
|
+
args: call.args,
|
|
1109
|
+
});
|
|
1110
|
+
chatPanel.markToolReplayed?.(call.id);
|
|
1111
|
+
break;
|
|
1112
|
+
}
|
|
1113
|
+
if (entry.role === "tool_result") {
|
|
1114
|
+
const result = extractToolResult(entry);
|
|
1115
|
+
const fallbackId = result.id ?? pendingToolIds.pop() ?? null;
|
|
1116
|
+
if (fallbackId) {
|
|
1117
|
+
const pendingIndex = pendingToolIds.indexOf(fallbackId);
|
|
1118
|
+
if (pendingIndex >= 0) pendingToolIds.splice(pendingIndex, 1);
|
|
1119
|
+
chatPanel.applyEvent({
|
|
1120
|
+
type: "tool_execution_end",
|
|
1121
|
+
toolCallId: fallbackId,
|
|
1122
|
+
toolName: result.name,
|
|
1123
|
+
result: displayReplayToolResult(result.result),
|
|
1124
|
+
isError: result.isError,
|
|
1125
|
+
...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
|
|
1126
|
+
...(result.resultSummary !== undefined ? { resultSummary: result.resultSummary } : {}),
|
|
1127
|
+
...(result.outcome !== undefined ? { outcome: result.outcome } : {}),
|
|
1128
|
+
...(result.blockReason !== undefined ? { blockReason: result.blockReason } : {}),
|
|
1129
|
+
} as ChatLoopEvent);
|
|
1130
|
+
} else {
|
|
1131
|
+
chatPanel.appendReplayBlock((width) =>
|
|
1132
|
+
renderToolResultOnly(
|
|
1133
|
+
{
|
|
1134
|
+
toolCallId: result.id ?? "",
|
|
1135
|
+
toolName: result.name,
|
|
1136
|
+
result: displayReplayToolResult(result.result),
|
|
1137
|
+
isError: result.isError,
|
|
1138
|
+
...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
|
|
1139
|
+
...(result.resultSummary !== undefined ? { resultSummary: result.resultSummary } : {}),
|
|
1140
|
+
...(result.outcome === "blocked" ? { outcome: "blocked" as const } : {}),
|
|
1141
|
+
...(result.blockReason !== undefined ? { blockReason: result.blockReason } : {}),
|
|
1142
|
+
},
|
|
1143
|
+
width,
|
|
1144
|
+
{ unbounded: options.unboundedToolBodies === true },
|
|
1145
|
+
),
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1150
|
+
if (entry.role === "system") {
|
|
1151
|
+
const text = textBlockFromEntry(entry);
|
|
1152
|
+
if (text.length > 0) appendReplayLine(chatPanel, `system: ${text}`);
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
if (entry.role === "checkpoint") {
|
|
1156
|
+
const text = textBlockFromEntry(entry);
|
|
1157
|
+
appendReplayLine(chatPanel, text.length > 0 ? `[checkpoint] ${text}` : "[checkpoint]");
|
|
1158
|
+
break;
|
|
1159
|
+
}
|
|
1160
|
+
break;
|
|
1161
|
+
}
|
|
1162
|
+
case "bashExecution":
|
|
1163
|
+
chatPanel.appendReplayBlock((width) => renderBashExecutionEntry(entry, width));
|
|
1164
|
+
break;
|
|
1165
|
+
case "custom":
|
|
1166
|
+
if (rendersCustomEntry(entry)) chatPanel.appendReplayBlock((width) => renderCustomEntry(entry, width));
|
|
1167
|
+
break;
|
|
1168
|
+
case "modelChange":
|
|
1169
|
+
chatPanel.appendReplayBlock((width) => renderModelChangeEntry(entry, width));
|
|
1170
|
+
break;
|
|
1171
|
+
case "thinkingLevelChange":
|
|
1172
|
+
chatPanel.appendReplayBlock((width) => renderThinkingChangeEntry(entry, width));
|
|
1173
|
+
break;
|
|
1174
|
+
case "fileEntry":
|
|
1175
|
+
chatPanel.appendReplayBlock((width) => renderFileEntry(entry, width));
|
|
1176
|
+
break;
|
|
1177
|
+
case "protectedArtifact":
|
|
1178
|
+
chatPanel.appendReplayBlock((width) => renderProtectedArtifactEntry(entry, width));
|
|
1179
|
+
break;
|
|
1180
|
+
case "skillActivation":
|
|
1181
|
+
appendReplayLine(chatPanel, `[skill] ${entry.activation.name} ${entry.activation.triggeredBy}`);
|
|
1182
|
+
break;
|
|
1183
|
+
case "branchSummary":
|
|
1184
|
+
if (entry.summary.trim().length > 0) {
|
|
1185
|
+
chatPanel.appendReplayBlock((width) =>
|
|
1186
|
+
renderBranchSummaryEntry({ ...entry, summary: truncateReplayText(entry.summary) }, width),
|
|
1187
|
+
);
|
|
1188
|
+
}
|
|
1189
|
+
break;
|
|
1190
|
+
case "compactionSummary":
|
|
1191
|
+
if (entry.summary.trim().length > 0) {
|
|
1192
|
+
chatPanel.appendReplayBlock((width) =>
|
|
1193
|
+
renderCompactionSummaryEntry({ ...entry, summary: truncateReplayText(entry.summary) }, width),
|
|
1194
|
+
);
|
|
1195
|
+
}
|
|
1196
|
+
break;
|
|
1197
|
+
case "sessionInfo":
|
|
1198
|
+
if (entry.name || entry.label) chatPanel.appendReplayBlock((width) => renderSessionInfoEntry(entry, width));
|
|
1199
|
+
break;
|
|
1200
|
+
case "workerRun": {
|
|
1201
|
+
if (placedAssignments.has(entry.assignmentId)) break;
|
|
1202
|
+
const state = workerStates.get(entry.assignmentId);
|
|
1203
|
+
if (state === undefined) break;
|
|
1204
|
+
placedAssignments.add(entry.assignmentId);
|
|
1205
|
+
chatPanel.applyWorkerState(state);
|
|
1206
|
+
break;
|
|
1207
|
+
}
|
|
1208
|
+
case "label":
|
|
1209
|
+
case "taskLedger":
|
|
1210
|
+
case "decisionLedger":
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
for (const pendingId of pendingToolIds) {
|
|
1215
|
+
chatPanel.applyEvent({
|
|
1216
|
+
type: "tool_execution_end",
|
|
1217
|
+
toolCallId: pendingId,
|
|
1218
|
+
toolName: "tool",
|
|
1219
|
+
result: "missing result; session ended before the tool completed",
|
|
1220
|
+
isError: true,
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
// Replay favors a compact historical ledger even though fresh non-resource
|
|
1224
|
+
// calls auto-expand for live arguments and output. Collapse reconstructed
|
|
1225
|
+
// tools explicitly; /export re-expands them afterward via
|
|
1226
|
+
// toggleAllToolsExpanded, while /resume and /fork retain the compact form.
|
|
1227
|
+
chatPanel.collapseAllTools();
|
|
1228
|
+
}
|