zidane 7.2.4 → 8.0.4
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/LICENSE +21 -0
- package/README.md +34 -6
- package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
- package/dist/acp-DQDhi2dj.js.map +1 -0
- package/dist/acp-cli.d.ts +1 -1
- package/dist/acp-cli.js +9 -66
- package/dist/acp-cli.js.map +1 -1
- package/dist/acp.d.ts +10 -590
- package/dist/acp.d.ts.map +1 -1
- package/dist/acp.js +3 -3
- package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
- package/dist/agent-DSLNmBp0.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -2
- package/dist/aliasing-lVFbm81n.js +217 -0
- package/dist/aliasing-lVFbm81n.js.map +1 -0
- package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
- package/dist/anthropic-CD00LhUP.js.map +1 -0
- package/dist/artifacts-CV2hUKnL.js.map +1 -1
- package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
- package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
- package/dist/call-tool-dHlbGOIY.js +70 -0
- package/dist/call-tool-dHlbGOIY.js.map +1 -0
- package/dist/chat/pure.d.ts +372 -6
- package/dist/chat/pure.d.ts.map +1 -1
- package/dist/chat/pure.js +35 -244
- package/dist/chat/pure.js.map +1 -1
- package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
- package/dist/chat-JPJJ8uu5.js.map +1 -0
- package/dist/chat.d.ts +4 -6
- package/dist/chat.js +23 -12
- package/dist/cli-shared-C-YCaglL.js +159 -0
- package/dist/cli-shared-C-YCaglL.js.map +1 -0
- package/dist/client-core-BQSyDALT.d.ts +2115 -0
- package/dist/client-core-BQSyDALT.d.ts.map +1 -0
- package/dist/codemode-worker.d.ts +1 -0
- package/dist/codemode-worker.js +155 -0
- package/dist/codemode-worker.js.map +1 -0
- package/dist/codemode.d.ts +352 -0
- package/dist/codemode.d.ts.map +1 -0
- package/dist/codemode.js +5 -0
- package/dist/connection-Dr-Js4yZ.d.ts +28 -0
- package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
- package/dist/connection-loop-gdh22LTI.js +112 -0
- package/dist/connection-loop-gdh22LTI.js.map +1 -0
- package/dist/context-segments-BHKlagL6.js +1016 -0
- package/dist/context-segments-BHKlagL6.js.map +1 -0
- package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
- package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
- package/dist/contexts/daytona.d.ts +19 -8
- package/dist/contexts/daytona.d.ts.map +1 -1
- package/dist/contexts/daytona.js +1 -440
- package/dist/contexts/docker.d.ts +36 -7
- package/dist/contexts/docker.d.ts.map +1 -1
- package/dist/contexts/docker.js +1 -456
- package/dist/contexts/e2b.d.ts +68 -13
- package/dist/contexts/e2b.d.ts.map +1 -1
- package/dist/contexts/e2b.js +1 -382
- package/dist/contexts/sandbox.d.ts +1 -1
- package/dist/contexts/sandbox.js +5 -0
- package/dist/contexts/sandbox.js.map +1 -1
- package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
- package/dist/contexts-d7UolYot.js.map +1 -0
- package/dist/contexts.d.ts +3 -3
- package/dist/contexts.js +1 -1
- package/dist/cred-keys-GpBg71cP.js +105 -0
- package/dist/cred-keys-GpBg71cP.js.map +1 -0
- package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
- package/dist/credentials-JttEuRON.js.map +1 -0
- package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
- package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
- package/dist/daemon-cli.d.ts +1 -1
- package/dist/daemon-cli.js +3 -2
- package/dist/daemon-cli.js.map +1 -1
- package/dist/daytona-DG3omipZ.js +513 -0
- package/dist/daytona-DG3omipZ.js.map +1 -0
- package/dist/defaults-Cx3zvDOV.js +23 -0
- package/dist/defaults-Cx3zvDOV.js.map +1 -0
- package/dist/dispatcher-BMlu2BmZ.js +4941 -0
- package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
- package/dist/docker-BZhMMJUp.js +727 -0
- package/dist/docker-BZhMMJUp.js.map +1 -0
- package/dist/e2b-CEVOdRib.js +480 -0
- package/dist/e2b-CEVOdRib.js.map +1 -0
- package/dist/edit-utils-EGosADZq.js +234 -0
- package/dist/edit-utils-EGosADZq.js.map +1 -0
- package/dist/environment-8wsKE2Ln.js +214 -0
- package/dist/environment-8wsKE2Ln.js.map +1 -0
- package/dist/eval-BNcvle_J.js +1595 -0
- package/dist/eval-BNcvle_J.js.map +1 -0
- package/dist/eval.d.ts +2 -2
- package/dist/eval.js +1 -1489
- package/dist/executor-Cx5-8yqi.js +621 -0
- package/dist/executor-Cx5-8yqi.js.map +1 -0
- package/dist/extension-authoring-DyGGmq9V.js +385 -0
- package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
- package/dist/extensions.d.ts +2 -2
- package/dist/extensions.js +3 -3
- package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
- package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
- package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
- package/dist/format-C2NQEVUH.js.map +1 -0
- package/dist/format-bytes-C7tfc3Zm.js +55 -0
- package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
- package/dist/headless-C_rNUuYC.js +960 -0
- package/dist/headless-C_rNUuYC.js.map +1 -0
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -413
- package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
- package/dist/history-search-CcYzF8-0.js.map +1 -0
- package/dist/history-search-worker.d.ts +1 -1
- package/dist/history-search-worker.js +1 -1
- package/dist/host-D7NrI03V.js +378 -0
- package/dist/host-D7NrI03V.js.map +1 -0
- package/dist/host-signals-BcP5QKUD.js +118 -0
- package/dist/host-signals-BcP5QKUD.js.map +1 -0
- package/dist/identity-CwfO8K-t.js +26 -0
- package/dist/identity-CwfO8K-t.js.map +1 -0
- package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
- package/dist/index-BGe1fQT7.d.ts.map +1 -0
- package/dist/index-BVQsIKGn.d.ts +448 -0
- package/dist/index-BVQsIKGn.d.ts.map +1 -0
- package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
- package/dist/index-CHABJd-L.d.ts.map +1 -0
- package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
- package/dist/index-D6a7qXpg.d.ts.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +27 -23
- package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
- package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
- package/dist/ipc/remote.d.ts +313 -0
- package/dist/ipc/remote.d.ts.map +1 -0
- package/dist/ipc/remote.js +4 -0
- package/dist/ipc.d.ts +6 -964
- package/dist/ipc.js +403 -4
- package/dist/ipc.js.map +1 -0
- package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
- package/dist/isolation-D9L650W5.d.ts.map +1 -0
- package/dist/json-rpc--HXQti1E.js +350 -0
- package/dist/json-rpc--HXQti1E.js.map +1 -0
- package/dist/links-j8rED1sR.js +603 -0
- package/dist/links-j8rED1sR.js.map +1 -0
- package/dist/local-terminal-D8QThwo_.js +252 -0
- package/dist/local-terminal-D8QThwo_.js.map +1 -0
- package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
- package/dist/logger-Gtqlayx8.js.map +1 -0
- package/dist/logs-view-CWG8aUAG.js.map +1 -1
- package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
- package/dist/mcp-_wecH9Qe.js.map +1 -0
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +2 -2
- package/dist/media-sniff-UKijEaiQ.js.map +1 -1
- package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
- package/dist/messages-BqiwcD2Q.js.map +1 -0
- package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
- package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
- package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
- package/dist/openai-compat-CFrpH7uq.js.map +1 -0
- package/dist/orchestration-BCGmB8Ps.js +511 -0
- package/dist/orchestration-BCGmB8Ps.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -2
- package/dist/output/stream-json.d.ts.map +1 -1
- package/dist/output/stream-json.js +1 -1
- package/dist/output/terminal.d.ts +1 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +13 -7
- package/dist/output/terminal.js.map +1 -1
- package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
- package/dist/plugins-DS7mahzZ.js.map +1 -0
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +1 -2
- package/dist/prelude-Cxo4t74B.js +517 -0
- package/dist/prelude-Cxo4t74B.js.map +1 -0
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -2
- package/dist/project-root-B8zADr4o.js +167 -0
- package/dist/project-root-B8zADr4o.js.map +1 -0
- package/dist/project-user-paths-BSgtrRxl.js +58 -0
- package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
- package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
- package/dist/prompts-DYcvqShf.d.ts.map +1 -0
- package/dist/protocol-DnhqqSmE.js +13 -0
- package/dist/protocol-DnhqqSmE.js.map +1 -0
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +1 -2
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/arcee.js +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/baseten.js +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/cerebras.js +3 -2
- package/dist/providers/cerebras.js.map +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai-compat.js +1 -2
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +15 -12
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +3 -2
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +3 -3
- package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
- package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/registry-D6ShBWJU.js +5234 -0
- package/dist/registry-D6ShBWJU.js.map +1 -0
- package/dist/remote-hosts-BtA_9ZGp.js +97 -0
- package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
- package/dist/restate.d.ts +2 -3
- package/dist/restate.d.ts.map +1 -1
- package/dist/restate.js +631 -572
- package/dist/restate.js.map +1 -1
- package/dist/run-summary-CklLiZ4y.js +288 -0
- package/dist/run-summary-CklLiZ4y.js.map +1 -0
- package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
- package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
- package/dist/session/sqlite.d.ts +1 -2
- package/dist/session/sqlite.d.ts.map +1 -1
- package/dist/session/sqlite.js +1 -616
- package/dist/session-factory-BUGY5P40.js +1576 -0
- package/dist/session-factory-BUGY5P40.js.map +1 -0
- package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
- package/dist/session-xh9JXu6i.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/settings-keys-Ckf29NeM.js +677 -0
- package/dist/settings-keys-Ckf29NeM.js.map +1 -0
- package/dist/shell-path-Dqaoow2J.js +412 -0
- package/dist/shell-path-Dqaoow2J.js.map +1 -0
- package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
- package/dist/skills-DKqZJm4X.js.map +1 -0
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js +1 -2
- package/dist/source-mPExaUm8.js +381 -0
- package/dist/source-mPExaUm8.js.map +1 -0
- package/dist/sqlite-DV1DQzN2.js +698 -0
- package/dist/sqlite-DV1DQzN2.js.map +1 -0
- package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
- package/dist/src-BRMYRJib.js.map +1 -0
- package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
- package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
- package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
- package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
- package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
- package/dist/timeout-DEaqslLO.d.ts.map +1 -1
- package/dist/todo-edits-Dn251YUP.js +1790 -0
- package/dist/todo-edits-Dn251YUP.js.map +1 -0
- package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
- package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
- package/dist/tool-state-Dku6YqAB.js +989 -0
- package/dist/tool-state-Dku6YqAB.js.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -2
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +1 -2
- package/dist/tools/prompts.d.ts +1 -1
- package/dist/tools/prompts.js +7 -7
- package/dist/tools/prompts.js.map +1 -1
- package/dist/tools/web-search.d.ts +1 -2
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +2 -2
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools-_DnT3AGM.js +578 -0
- package/dist/tools-_DnT3AGM.js.map +1 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -2
- package/dist/tui.d.ts +534 -517
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +34933 -27242
- package/dist/tui.js.map +1 -1
- package/dist/turn-operations-B8sokwi5.js +333 -0
- package/dist/turn-operations-B8sokwi5.js.map +1 -0
- package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
- package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
- package/dist/types-C7ZFOztE.d.ts +132 -0
- package/dist/types-C7ZFOztE.d.ts.map +1 -0
- package/dist/types-CH5XpIHw.js +114 -0
- package/dist/types-CH5XpIHw.js.map +1 -0
- package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
- package/dist/types-Cu0ZGDu9.js.map +1 -0
- package/dist/types-IqegbJEE.d.ts +624 -0
- package/dist/types-IqegbJEE.d.ts.map +1 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.js +1 -1
- package/dist/url-D8HCl65b.js +1259 -0
- package/dist/url-D8HCl65b.js.map +1 -0
- package/dist/wasm-BVT-j5cl.js +33 -0
- package/dist/wasm-BVT-j5cl.js.map +1 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
- package/dist/ws-CIHMvlSh.js +952 -0
- package/dist/ws-CIHMvlSh.js.map +1 -0
- package/dist/ws-client-N7NxzvQp.js +230 -0
- package/dist/ws-client-N7NxzvQp.js.map +1 -0
- package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
- package/dist/xai-CvJTeLrI.js.map +1 -0
- package/dist/xdg-zweed0-t.js +117 -0
- package/dist/xdg-zweed0-t.js.map +1 -0
- package/docs/ACP.md +52 -0
- package/docs/ARCHITECTURE.md +103 -6
- package/docs/ARTIFACTS.md +8 -4
- package/docs/CHAT.md +165 -14
- package/docs/EXECUTION_CONTEXT.md +8 -0
- package/docs/EXTENSIONS.md +123 -2
- package/docs/HEADLESS.md +2 -0
- package/docs/IPC.md +775 -64
- package/docs/MACHINES.md +456 -0
- package/docs/PANELS.md +3 -0
- package/docs/README.md +4 -0
- package/docs/RESTATE.md +3 -2
- package/docs/RUN_IN_BACKGROUND.md +10 -2
- package/docs/SERVER.md +1085 -0
- package/docs/SKILL.md +6 -1
- package/docs/TERMINAL.md +75 -0
- package/docs/TUI.md +65 -14
- package/package.json +58 -26
- package/scripts/eval.ts +4 -0
- package/dist/acp-D-tVyUjw.js.map +0 -1
- package/dist/agent-D0zZnGbt.js.map +0 -1
- package/dist/anthropic-C2aole0G.js.map +0 -1
- package/dist/approvals-DKaJZYlm.js.map +0 -1
- package/dist/atomic-write-B7zr1ddF.js.map +0 -1
- package/dist/auth-BG2rVKSt.js.map +0 -1
- package/dist/completion-core-BRo86R_L.js.map +0 -1
- package/dist/contexts/daytona.js.map +0 -1
- package/dist/contexts/docker.js.map +0 -1
- package/dist/contexts/e2b.js.map +0 -1
- package/dist/contexts-CRE9pw07.js.map +0 -1
- package/dist/eval.js.map +0 -1
- package/dist/format-BF745pLL.js.map +0 -1
- package/dist/glob-DluQFSw1.js +0 -270
- package/dist/glob-DluQFSw1.js.map +0 -1
- package/dist/headless.js.map +0 -1
- package/dist/history-search-C4bk1Wz_.js.map +0 -1
- package/dist/index-BgN1T3lk.d.ts.map +0 -1
- package/dist/index-C37_ppWv.d.ts.map +0 -1
- package/dist/index-C6NEd5y_.d.ts.map +0 -1
- package/dist/ipc-zVSyo6K1.js +0 -331
- package/dist/ipc-zVSyo6K1.js.map +0 -1
- package/dist/ipc.d.ts.map +0 -1
- package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
- package/dist/json-rpc-rSWMUh9b.js +0 -192
- package/dist/json-rpc-rSWMUh9b.js.map +0 -1
- package/dist/logger--C1VQjwJ.js.map +0 -1
- package/dist/mcp-CgNd-f3F.js.map +0 -1
- package/dist/messages-2jcOA_5R.js.map +0 -1
- package/dist/openai-compat-Dy56weK8.js.map +0 -1
- package/dist/output-cap-C9zukcCj.js +0 -100
- package/dist/output-cap-C9zukcCj.js.map +0 -1
- package/dist/panels-B6gRk4bf.js +0 -789
- package/dist/panels-B6gRk4bf.js.map +0 -1
- package/dist/plugins-gbI7SBA6.js.map +0 -1
- package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
- package/dist/run-summary-BU_NgwUT.js +0 -269
- package/dist/run-summary-BU_NgwUT.js.map +0 -1
- package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
- package/dist/session/sqlite.js.map +0 -1
- package/dist/session-BqRP1hS7.js.map +0 -1
- package/dist/shell-path-h5czzllR.js +0 -1549
- package/dist/shell-path-h5czzllR.js.map +0 -1
- package/dist/skills-BC3dodWp.js.map +0 -1
- package/dist/src-CkNQKFKr.js.map +0 -1
- package/dist/todo-edits-UOwgxGKu.js +0 -528
- package/dist/todo-edits-UOwgxGKu.js.map +0 -1
- package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
- package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
- package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
- package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
- package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
- package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
- package/dist/turn-operations-DrbJlpq9.js.map +0 -1
- package/dist/types-CWgENVLY.js.map +0 -1
- package/dist/xai-CazjStOK.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo-edits-Dn251YUP.js","names":["str"],"sources":["../src/chat/hosts/host-index.ts","../src/chat/hosts/session-key.ts","../src/chat/auth-rows.ts","../src/chat/fold-actions.ts","../src/chat/instruction-rows.ts","../src/chat/machines-view.ts","../src/chat/mcp-form.ts","../src/chat/model-name.ts","../src/chat/notice-format.ts","../src/chat/palette.ts","../src/chat/panels.ts","../src/chat/prompt-text.ts","../src/chat/stream-failure.ts","../src/chat/stream-rate.ts","../src/chat/todo-edits.ts"],"sourcesContent":["/**\n * Which host an id lives on: a session (or a request a host handed out: an\n * approval, a question, a terminal). A client learns it from what a host\n * tells it (its lists, a create, an activation, its signals) and routes\n * every later call on that id there.\n *\n * Never guessed: an id no host told about is an error\n * ({@link UnknownHostIdError}), one several hosts list is an error unless the\n * lookup names its host ({@link AmbiguousHostIdError}), and the ids of a host\n * that was removed stay remembered as such ({@link HostRemovedError}) until\n * a host claims them again, so nothing aimed at a removed server quietly\n * lands on another host.\n * Node-free, shared by the TUI and the GUI main process.\n */\n\n/** No host told this client about the id: nothing to route it to. */\nexport class UnknownHostIdError extends Error {\n readonly code = 'unknown-host-id'\n constructor(readonly id: string, noun = 'session') {\n super(`No host is known for ${noun} \"${id}\": list or open it on its host first.`)\n this.name = 'UnknownHostIdError'\n }\n}\n\n/** The id lived on a host that was removed from this window. */\nexport class HostRemovedError extends Error {\n readonly code = 'host-removed'\n constructor(readonly hostKey: string, readonly hostName: string) {\n super(`${hostName} was removed.`)\n this.name = 'HostRemovedError'\n }\n}\n\n/**\n * Several hosts list the id (two hosts can hold the same session id: a\n * server sharing this machine's data dir, a copied store) and the lookup\n * did not say which: refused, never guessed.\n */\nexport class AmbiguousHostIdError extends Error {\n readonly code = 'ambiguous-host-id'\n constructor(readonly id: string, readonly hostKeys: readonly string[], noun = 'session') {\n super(`${noun[0]!.toUpperCase()}${noun.slice(1)} \"${id}\" exists on several hosts (${hostKeys.join(', ')}): say which one.`)\n this.name = 'AmbiguousHostIdError'\n }\n}\n\n/**\n * Keyed by (host, id): the same id may live on several hosts. A lookup that\n * names its host (`hostKey`) gets exactly that pair; one that doesn't\n * resolves only when one host has the id.\n */\nexport interface HostIndex {\n /** `id` lives on `hostKey` (clears that pair's removed-host mark). */\n note: (id: string, hostKey: string) => void\n /** The id is gone from `hostKey` (deleted there), or from every host. */\n forget: (id: string, hostKey?: string) => void\n /** With `hostKey`: it, when `id` is known live there. Without: the one live host of `id` (`undefined` when none, or several). */\n hostOf: (id: string, hostKey?: string) => string | undefined\n /** Every live host of `id`. */\n hostsOf: (id: string) => string[]\n /**\n * The live host of `id` (with `hostKey`: that pair). Throws\n * {@link HostRemovedError}, {@link UnknownHostIdError}, or without\n * `hostKey` {@link AmbiguousHostIdError} when several hosts have it.\n */\n require: (id: string, hostKey?: string) => string\n /** The removed host `id` lived on (with `hostKey`: that one), if any. */\n removedHostOf: (id: string, hostKey?: string) => { key: string, name: string } | undefined\n /** Ids noted on `hostKey`. */\n idsOf: (hostKey: string) => string[]\n /** The host was removed: its pairs are marked so (lookups say so); returns their ids. */\n dropHost: (hostKey: string, hostName: string) => string[]\n}\n\nexport function createHostIndex(noun = 'session'): HostIndex {\n /** id → live host keys, in the order they were noted. */\n const live = new Map<string, Set<string>>()\n /** id → removed host key → its name. */\n const removed = new Map<string, Map<string, string>>()\n const liveOf = (id: string): string[] => [...(live.get(id) ?? [])]\n const removedOf = (id: string, hostKey?: string): { key: string, name: string } | undefined => {\n const marks = removed.get(id)\n if (!marks)\n return undefined\n if (hostKey !== undefined) {\n const name = marks.get(hostKey)\n return name === undefined ? undefined : { key: hostKey, name }\n }\n const first = [...marks][0]\n return first ? { key: first[0], name: first[1] } : undefined\n }\n const index: HostIndex = {\n note: (id, hostKey) => {\n let hosts = live.get(id)\n if (!hosts)\n live.set(id, hosts = new Set())\n hosts.add(hostKey)\n const marks = removed.get(id)\n marks?.delete(hostKey)\n if (marks?.size === 0)\n removed.delete(id)\n },\n forget: (id, hostKey) => {\n if (hostKey === undefined) {\n live.delete(id)\n removed.delete(id)\n return\n }\n live.get(id)?.delete(hostKey)\n if (live.get(id)?.size === 0)\n live.delete(id)\n removed.get(id)?.delete(hostKey)\n if (removed.get(id)?.size === 0)\n removed.delete(id)\n },\n hostOf: (id, hostKey) => {\n const hosts = liveOf(id)\n if (hostKey !== undefined)\n return hosts.includes(hostKey) ? hostKey : undefined\n return hosts.length === 1 ? hosts[0] : undefined\n },\n hostsOf: liveOf,\n require: (id, hostKey) => {\n const hosts = liveOf(id)\n if (hostKey !== undefined) {\n if (hosts.includes(hostKey))\n return hostKey\n const gone = removedOf(id, hostKey)\n if (gone)\n throw new HostRemovedError(gone.key, gone.name)\n throw new UnknownHostIdError(id, noun)\n }\n if (hosts.length === 1)\n return hosts[0]!\n if (hosts.length > 1)\n throw new AmbiguousHostIdError(id, hosts, noun)\n const gone = removedOf(id)\n if (gone)\n throw new HostRemovedError(gone.key, gone.name)\n throw new UnknownHostIdError(id, noun)\n },\n removedHostOf: removedOf,\n idsOf: hostKey => [...live].filter(([, hosts]) => hosts.has(hostKey)).map(([id]) => id),\n dropHost: (hostKey, hostName) => {\n const ids = index.idsOf(hostKey)\n for (const id of ids) {\n index.forget(id, hostKey)\n let marks = removed.get(id)\n if (!marks)\n removed.set(id, marks = new Map())\n marks.set(hostKey, hostName)\n }\n return ids\n },\n }\n return index\n}\n","/**\n * A session's identity across hosts: the (host, session) pair, as one\n * string every client keys rows, maps and persisted state by. Two hosts may\n * hold the same session id (a server sharing this computer's data dir, a\n * copied store), so a bare id never names a session on its own once several\n * hosts are listed.\n *\n * The host is named by its HOST KEY, the key of a client's host directory:\n * {@link LOCAL_HOST_KEY} for This computer (the in-process host or the\n * daemon), a saved server's `hostId` (for a server, hostKey === hostId),\n * or a client's own key for a host it never saves (the TUI's `--host`\n * server: `'ad-hoc'`).\n *\n * The encoding, shared by the TUI and the GUI:\n *\n * - This computer: the bare id (`abc`). Local-only users see exactly the\n * ids, and state persisted before keys existed still means the same\n * session.\n * - Any other host: `<hostKey>␟<id>` (U+001F, never in a host key).\n *\n * A local id that itself contains U+001F is written `local␟<id>`, so a key\n * always parses back to the pair it was made from. Node-free.\n */\nimport { LOCAL_HOST_KEY } from './connection'\n\nexport const SESSION_KEY_SEPARATOR = '\\u001F'\n\n/** The pair a session key names. */\nexport interface SessionKeyParts {\n /** Always explicit: {@link LOCAL_HOST_KEY} for This computer. */\n hostKey: string\n sessionId: string\n}\n\n/** The key of `sessionId` on `hostKey` (`null` / absent / {@link LOCAL_HOST_KEY}: a local session). */\nexport function sessionKey(hostKey: string | null | undefined, sessionId: string): string {\n if (!hostKey || hostKey === LOCAL_HOST_KEY)\n return sessionId.includes(SESSION_KEY_SEPARATOR) ? `${LOCAL_HOST_KEY}${SESSION_KEY_SEPARATOR}${sessionId}` : sessionId\n if (hostKey.includes(SESSION_KEY_SEPARATOR))\n throw new Error('A host key cannot contain U+001F.')\n return `${hostKey}${SESSION_KEY_SEPARATOR}${sessionId}`\n}\n\n/** The pair `key` names (a bare id: This computer's). */\nexport function parseSessionKey(key: string): SessionKeyParts {\n const at = key.indexOf(SESSION_KEY_SEPARATOR)\n if (at < 0)\n return { hostKey: LOCAL_HOST_KEY, sessionId: key }\n return { hostKey: key.slice(0, at), sessionId: key.slice(at + 1) }\n}\n","/**\n * Renderer-agnostic data model for the Authentication settings list when a\n * provider holds more than one credential source.\n *\n * Mirrors `chat/mcp-rows.ts` deliberately: a flat row list plus a single\n * integer cursor that walks both provider headers AND their nested source\n * rows, so a renderer iterates once and never needs separate \"which provider\n * am I on / which source inside it\" state.\n *\n * Lives in `chat/` rather than `tui/` for the same reason as the MCP model —\n * the flattening and cursor arithmetic are pure, and pure means they can be\n * asserted directly instead of through a rendered modal.\n *\n * A provider is only expandable when it has MORE THAN ONE source. Single-source\n * providers (the overwhelming majority) stay exactly as they were: one row, no\n * chevron, no expansion state. That keeps the list quiet and means this model\n * changes nothing for anyone who hasn't stacked two credentials.\n */\n\nimport type { AuthMethod, ProviderAuth } from './auth'\n\n/**\n * One row in the flattened Authentication list. Two kinds:\n *\n * - `'provider'` — provider header with label, configured badge, and (when\n * expandable) the chevron. Always present.\n * - `'source'` — one credential source belonging to the provider above.\n * Present only while that provider is expanded.\n */\nexport type VisibleAuthRow\n = | { kind: 'provider', provider: ProviderAuth, expandable: boolean }\n | { kind: 'source', providerKey: string, method: AuthMethod }\n\n/**\n * Stored credentials, i.e. the ones a user can actually choose between.\n *\n * `env` is excluded: it is observed rather than stored, and is usually just the\n * mirror `applyApiKeyEnv` wrote from the stored API key, so counting it would\n * advertise a choice that does not exist.\n */\nexport function selectableSources(provider: ProviderAuth): AuthMethod[] {\n return provider.methods.filter(m => m.source !== 'env')\n}\n\n/** A provider earns a chevron only when there is a real choice to reveal. */\nexport function isExpandableProvider(provider: ProviderAuth): boolean {\n return selectableSources(provider).length > 1\n}\n\n/**\n * Flatten the provider list plus the expanded set into the visible-row list.\n *\n * - `providers` — filtered / ordered provider list (post-search).\n * - `expanded` — keys of providers whose sources are open. Keys for\n * providers that are no longer expandable are ignored rather\n * than cleaned up, so stale expansion state (a credential\n * removed while the modal is open) can't desync the cursor.\n */\nexport function buildVisibleAuthRows(\n providers: readonly ProviderAuth[],\n expanded: ReadonlySet<string>,\n): VisibleAuthRow[] {\n const out: VisibleAuthRow[] = []\n for (const provider of providers) {\n const expandable = isExpandableProvider(provider)\n out.push({ kind: 'provider', provider, expandable })\n if (!expandable || !expanded.has(provider.key))\n continue\n for (const method of selectableSources(provider))\n out.push({ kind: 'source', providerKey: provider.key, method })\n // The env slot is listed for context whenever the provider declares one,\n // present or not. It disappears from `methods` the moment a stored OAuth\n // grant wins (`applyApiKeyEnv` clears the var so the refresh path reads the\n // file), and a row that vanishes on selection reads as a bug.\n if (provider.envKey) {\n const envMethod = provider.methods.find(m => m.source === 'env')\n out.push({\n kind: 'source',\n providerKey: provider.key,\n method: envMethod ?? { source: 'env', detail: provider.envKey, active: false },\n })\n }\n }\n return out\n}\n\n/**\n * Provider key a row \"belongs to\" — its own for a provider header, the parent's\n * for a source row.\n */\nexport function parentProviderKey(row: VisibleAuthRow): string {\n return row.kind === 'provider' ? row.provider.key : row.providerKey\n}\n\n/**\n * Index in `rows` of the header for the given provider key, or `-1`.\n *\n * Collapse handlers snap the cursor up to the parent BEFORE the row list\n * shrinks; without that the cursor keeps its flat index and silently lands on\n * whichever sibling row slid into that slot.\n */\nexport function indexOfProviderRow(rows: readonly VisibleAuthRow[], providerKey: string): number {\n return rows.findIndex(r => r.kind === 'provider' && r.provider.key === providerKey)\n}\n","/**\n * The words for what the agent did, shared by the GUI's compact fold and\n * the TUI's: one overview line per tool call (`Ran bun test`, `Edited\n * Timeline.tsx +12 −3`, `Read select-stops.ts`), and the settled summary\n * of a batch (`Read a file, ran a command +3`).\n *\n * An overview says WHAT happened, not the payload; the payload stays one\n * click away and in `title`.\n */\nimport type { EditPayload } from './types'\nimport { readFileInputPaths } from '../tools/read-file-targets'\nimport { computeLineDiff } from './edit-diff'\n\n// ---------------------------------------------------------------------------\n// Shell commands → a gist\n// ---------------------------------------------------------------------------\n\n/** Programs whose first argument is the thing they do (`git status`, `bun test`). */\nconst SUBCOMMAND_PROGRAMS = new Set([\n 'git',\n 'gh',\n 'bun',\n 'npm',\n 'pnpm',\n 'yarn',\n 'npx',\n 'bunx',\n 'cargo',\n 'go',\n 'docker',\n 'kubectl',\n 'make',\n 'uv',\n 'pip',\n 'pip3',\n 'brew',\n 'deno',\n 'node',\n 'playwright',\n 'vitest',\n 'jest',\n 'tsc',\n 'eslint',\n 'prettier',\n])\n/** Wrappers that only change how the next program runs. */\nconst WRAPPERS = new Set(['sudo', 'time', 'nice', 'nohup', 'exec', 'command', 'caffeinate'])\n/** Setup steps that carry no meaning of their own. */\nconst SETUP = new Set(['cd', 'pushd', 'popd', 'export', 'set', 'source', '.', 'unset', 'true', 'mkdir'])\n\n/** Split on `&&`, `||`, `;`, `|` and newlines outside quotes. */\nfunction splitSegments(command: string): string[] {\n const out: string[] = []\n let cur = ''\n let quote: '\"' | '\\'' | null = null\n for (let i = 0; i < command.length; i++) {\n const ch = command[i]!\n if (quote) {\n if (ch === quote)\n quote = null\n cur += ch\n continue\n }\n if (ch === '\"' || ch === '\\'') {\n quote = ch\n cur += ch\n continue\n }\n const two = command.slice(i, i + 2)\n if (two === '&&' || two === '||') {\n out.push(cur)\n cur = ''\n i++\n continue\n }\n if (ch === ';' || ch === '|' || ch === '\\n') {\n out.push(cur)\n cur = ''\n continue\n }\n cur += ch\n }\n out.push(cur)\n return out.map(s => s.trim()).filter(Boolean)\n}\n\n/** Words of a segment, quotes kept as one word (unquoted). */\nfunction words(segment: string): string[] {\n const out: string[] = []\n const re = /\"([^\"]*)\"|'([^']*)'|(\\S+)/g\n for (const m of segment.matchAll(re))\n out.push(m[1] ?? m[2] ?? m[3] ?? '')\n return out\n}\n\n/** The gist of one segment (`bun run build`, `python3`), or null for setup noise. */\nfunction segmentGist(segment: string): string | null {\n let w = words(segment)\n // Leading env assignments (`FOO=1 cmd`), then wrappers (`sudo`, `env -u X`, `timeout 30`).\n for (;;) {\n if (w.length === 0)\n return null\n const head = w[0]!\n if (/^[A-Z_]\\w*=/i.test(head)) {\n w = w.slice(1)\n }\n else if (WRAPPERS.has(head)) {\n w = w.slice(1)\n }\n else if (head === 'env') {\n w = w.slice(1)\n while (w[0] && (w[0].startsWith('-') || /^[A-Z_]\\w*=/i.test(w[0]))) {\n const flag = w[0]\n w = w.slice(1)\n if (flag === '-u' && w[0])\n w = w.slice(1)\n }\n }\n else if (head === 'timeout' && w[1] && /^\\d/.test(w[1])) {\n w = w.slice(2)\n }\n else {\n break\n }\n }\n const program = w[0]!.split('/').pop()!\n if (SETUP.has(program))\n return null\n if (!SUBCOMMAND_PROGRAMS.has(program))\n return program\n const rest = w.slice(1).filter(arg => !arg.startsWith('-'))\n let sub: string | undefined = rest[0]\n // `npx tsc`, `bunx playwright test`: the tool after the runner, and its own subcommand.\n if ((program === 'npx' || program === 'bunx') && sub) {\n const tool = sub.split('/').pop()!\n const next = rest[1]\n return SUBCOMMAND_PROGRAMS.has(tool) && next && !next.includes('/') && !next.includes('.')\n ? `${tool} ${next}`\n : tool\n }\n // `bun run build`: the script name is the subcommand's point.\n if ((sub === 'run' || sub === 'exec') && rest[1] && ['bun', 'npm', 'pnpm', 'yarn'].includes(program)) {\n return `${program} ${sub} ${rest[1]}`\n }\n // A path or file is an argument, not a subcommand (`node script.js` → `node`).\n if (sub && (sub.includes('/') || /\\.[a-z]+$/i.test(sub)))\n sub = undefined\n return sub ? `${program} ${sub}` : program\n}\n\n/**\n * `Ran <gist>` for a shell command: heredoc bodies dropped, setup steps\n * (`cd`, `export`, `set -e`) skipped, env and wrappers peeled off, program\n * plus subcommand kept. Further meaningful steps read as `+N`.\n */\nexport function commandGist(command: string): { gist: string, more: number } {\n // eslint-disable-next-line regexp/no-super-linear-backtracking -- bounded by one command's text\n const withoutHeredocs = command.replace(/<<-?\\s*(['\"]?)(\\w+)\\1[\\s\\S]*?(?:\\n\\2\\b|$)/g, '')\n const gists = splitSegments(withoutHeredocs)\n .map(segmentGist)\n .filter((g): g is string => g !== null)\n if (gists.length === 0)\n return { gist: 'a command', more: 0 }\n return { gist: gists[0]!, more: gists.length - 1 }\n}\n\n// ---------------------------------------------------------------------------\n// One tool call → its overview\n// ---------------------------------------------------------------------------\n\n/** What a tool call is, independent of how a surface stores it. */\nexport interface ToolOverviewInput {\n name: string\n displayName: string\n input?: Record<string, unknown>\n /** The formatted target (`tool-formatters`), when there is one. */\n target?: string\n /** The call's result text, once it has one. */\n result?: string | null\n /** `null` while running. */\n ok?: boolean | null\n edit?: EditPayload\n}\n\nexport interface ToolOverview {\n label: string\n /** Quiet context after the label: a file's directory, `+2` chained commands. */\n hint?: string\n added?: number\n removed?: number\n /** The full payload (the whole command, the full path). */\n title?: string\n}\n\nfunction splitPath(path: string): { name: string, dir: string } {\n const clean = path.replace(/\\/+$/, '')\n const i = clean.lastIndexOf('/')\n return i < 0 ? { name: clean, dir: '' } : { name: clean.slice(i + 1), dir: clean.slice(0, i) }\n}\n\nfunction str(input: Record<string, unknown> | undefined, key: string): string | undefined {\n const v = input?.[key]\n return typeof v === 'string' && v.trim() !== '' ? v : undefined\n}\n\n/** Line counts exactly as the diff in the details shows them. */\nfunction editCounts(edit: EditPayload | undefined): { added: number, removed: number } | null {\n if (!edit)\n return null\n let added = 0\n let removed = 0\n for (const h of edit.hunks) {\n for (const d of computeLineDiff(h.oldString, h.newString)) {\n if (d.op === 'add')\n added++\n else if (d.op === 'remove')\n removed++\n }\n }\n return { added, removed }\n}\n\nfunction shortUrl(url: string): string {\n const short = url.replace(/^https?:\\/\\//, '').replace(/\\/$/, '')\n return short.length > 48 ? `${short.slice(0, 47)}…` : short\n}\n\n/**\n * The dev browser in words: where it went and what it did. Clicks and typing\n * read their result's first line (`Clicked \"Save\"`), which names the element;\n * the ref the model used (`e12`) means nothing to a person.\n */\nfunction browserOverview(tool: ToolOverviewInput): ToolOverview | null {\n const input = tool.input\n const url = str(input, 'url')\n const head = typeof tool.result === 'string' && tool.ok\n ? tool.result.split('\\n')[0]!.replace(/\\. No navigation, dialog or error\\.$|\\.$/, '')\n : ''\n switch (tool.name) {\n case 'browser_open':\n return url ? { label: `Opened ${shortUrl(url)}`, title: url } : { label: 'Opened the browser' }\n case 'browser_navigate': {\n const action = str(input, 'action')\n if (action === 'back')\n return { label: 'Went back' }\n if (action === 'forward')\n return { label: 'Went forward' }\n if (action === 'reload')\n return { label: 'Reloaded the page' }\n return url ? { label: `Went to ${shortUrl(url)}`, title: url } : { label: 'Navigated' }\n }\n case 'browser_snapshot':\n return { label: 'Read the page' }\n case 'browser_screenshot':\n return { label: 'Took a screenshot' }\n case 'browser_click':\n return { label: head.startsWith('Clicked') ? head : `Clicked ${tool.target ?? 'the page'}` }\n case 'browser_type':\n return { label: head.startsWith('Typed') ? head : 'Typed in the page' }\n case 'browser_press':\n return { label: head.startsWith('Pressed') ? head : `Pressed ${str(input, 'key') ?? 'a key'}` }\n case 'browser_scroll':\n return { label: 'Scrolled the page' }\n case 'browser_wait_for': {\n const what = str(input, 'text') ?? str(input, 'selector') ?? str(input, 'urlIncludes')\n return { label: what ? `Waited for “${what.length > 40 ? `${what.slice(0, 39)}…` : what}”` : 'Waited' }\n }\n case 'browser_evaluate': {\n const expression = str(input, 'expression') ?? ''\n return { label: 'Ran a script in the page', ...(expression ? { title: expression.slice(0, 600) } : {}) }\n }\n case 'browser_console':\n return { label: 'Read the console' }\n default:\n return null\n }\n}\n\n/** The overview line for one tool call. */\nexport function toolOverview(tool: ToolOverviewInput): ToolOverview {\n const input = tool.input\n if (tool.name.startsWith('browser_')) {\n const browser = browserOverview(tool)\n if (browser)\n return browser\n }\n switch (tool.name) {\n case 'shell':\n case 'bash': {\n const command = str(input, 'command') ?? tool.target ?? ''\n // The model's description says what the call does (\"Run the GUI\n // typecheck\"); the command is behind it (title, and the opened input).\n const description = str(input, 'description')?.trim()\n if (description)\n return { label: description.length > 120 ? `${description.slice(0, 119)}…` : description, title: command.slice(0, 600) }\n const { gist, more } = commandGist(command)\n return { label: `Ran ${gist}`, ...(more > 0 ? { hint: `+${more}` } : {}), title: command.slice(0, 600) }\n }\n case 'read_file': {\n const batch = str(input, 'path') ? [] : readFileInputPaths(input)\n if (batch.length > 1)\n return { label: `Read ${splitPath(batch[0]).name} +${batch.length - 1}`, title: batch.join('\\n') }\n const path = str(input, 'path') ?? batch[0] ?? tool.target ?? ''\n const { name, dir } = splitPath(path)\n return { label: `Read ${name || 'a file'}`, ...(dir ? { hint: dir } : {}), title: path }\n }\n case 'edit':\n case 'multi_edit':\n case 'write_file': {\n const path = str(input, 'path') ?? tool.edit?.path ?? tool.target ?? ''\n const { name, dir } = splitPath(path)\n const counts = editCounts(tool.edit)\n const verb = tool.name === 'write_file' ? 'Wrote' : 'Edited'\n return {\n label: `${verb} ${name || 'a file'}`,\n ...(dir ? { hint: dir } : {}),\n ...(counts && (counts.added > 0 || counts.removed > 0) ? counts : {}),\n title: path,\n }\n }\n case 'grep': {\n const pattern = str(input, 'pattern') ?? tool.target ?? ''\n const where = str(input, 'path')\n return {\n label: pattern ? `Searched for “${pattern.length > 48 ? `${pattern.slice(0, 47)}…` : pattern}”` : 'Searched',\n ...(where ? { hint: where } : {}),\n title: pattern,\n }\n }\n case 'glob': {\n const pattern = str(input, 'pattern') ?? tool.target ?? ''\n return { label: pattern ? `Found files ${pattern}` : 'Found files', title: pattern }\n }\n case 'spawn': {\n // The worker is named by what it was asked to do; the full task sits behind it.\n const task = str(input, 'task') ?? tool.target ?? ''\n const first = task.split('\\n').find(line => line.trim()) ?? ''\n return { label: 'Agent', ...(first ? { hint: first.length > 80 ? `${first.slice(0, 79)}…` : first } : {}), ...(task ? { title: task.slice(0, 600) } : {}) }\n }\n case 'present_plan': {\n const title = str(input, 'title')\n return { label: 'Presented a plan', ...(title ? { hint: title, title } : {}) }\n }\n case 'ask_user': {\n const n = Array.isArray(input?.questions) ? input.questions.length : 0\n return { label: n > 0 ? `Asked ${n} question${n === 1 ? '' : 's'}` : 'Asked a question' }\n }\n case 'todowrite': {\n const todos = Array.isArray(input?.todos) ? (input.todos as { status?: unknown }[]) : []\n const done = todos.filter(t => t.status === 'completed').length\n return { label: 'Updated todos', ...(todos.length > 0 ? { hint: `${done} of ${todos.length} done` } : {}) }\n }\n case 'list_files': {\n const path = str(input, 'path') ?? tool.target ?? '.'\n return { label: `Listed ${path}`, title: path }\n }\n default: {\n const target = tool.target\n const short = target && target.length > 60 ? `${target.slice(0, 59)}…` : target\n return { label: short ? `${tool.displayName} ${short}` : tool.displayName, ...(target ? { title: target } : {}) }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Many calls → one summary\n// ---------------------------------------------------------------------------\n\n/**\n * Verb phrase per canonical tool name for a batch summary. Unknown tools\n * derive one from their display name, so MCP and host tools read cleanly.\n */\nconst BATCH_VERB_PHRASE: Record<string, string> = {\n shell: 'ran a command',\n read_file: 'read a file',\n grep: 'searched',\n glob: 'searched for files',\n list_files: 'listed files',\n edit: 'edited a file',\n multi_edit: 'edited a file',\n write_file: 'created a file',\n spawn: 'spawned a subagent',\n tool_search: 'searched for tools',\n skills_use: 'activated a skill',\n skills_read: 'read a skill',\n skills_run_script: 'ran a skill script',\n ask_user: 'asked a question',\n present_plan: 'presented a plan',\n browser_open: 'opened the browser',\n browser_navigate: 'navigated',\n browser_snapshot: 'read the page',\n browser_screenshot: 'took a screenshot',\n browser_click: 'clicked',\n browser_type: 'typed',\n browser_press: 'pressed a key',\n browser_scroll: 'scrolled',\n browser_wait_for: 'waited',\n browser_evaluate: 'ran a script in the page',\n browser_console: 'read the console',\n terminal_list: 'listed terminals',\n terminal_read: 'read a terminal',\n terminal_write: 'typed in a terminal',\n}\n\nexport function toolPhrase(name: string, displayName: string): string {\n return BATCH_VERB_PHRASE[name] ?? `used ${displayName.toLowerCase()}`\n}\n\n/**\n * Cap on distinct phrases in a summary: a 40-call exchange reads \"Ran a\n * command, searched, read a file, edited a file +23\", where +N counts the\n * calls the shown phrases do not cover.\n */\nconst MAX_SUMMARY_PHRASES = 4\n\n/**\n * \"Ran a command, read a file +2\" for a run of calls. Adjacent identical\n * phrases merge, so three reads in a row say \"read a file\" once.\n */\nexport function summarizeTools(tools: ReadonlyArray<{ name: string, displayName: string }>): string {\n const phrases: Array<{ phrase: string, calls: number }> = []\n for (const t of tools) {\n const phrase = toolPhrase(t.name, t.displayName)\n const last = phrases[phrases.length - 1]\n if (last && last.phrase === phrase)\n last.calls += 1\n else\n phrases.push({ phrase, calls: 1 })\n }\n if (phrases.length === 0)\n return 'Ran tools'\n const shown = phrases.slice(0, MAX_SUMMARY_PHRASES)\n const shownCalls = shown.reduce((n, p) => n + p.calls, 0)\n const rest = tools.length - shownCalls\n const joined = shown.map(p => p.phrase).join(', ')\n const capped = rest > 0 ? `${joined} +${rest}` : joined\n return capped.charAt(0).toUpperCase() + capped.slice(1)\n}\n\n/**\n * A message as a person skims it: its words, markdown syntax and code\n * blocks dropped, whitespace folded. For the compact stacks of earlier\n * messages.\n */\nexport function messagePreview(text: string): string {\n return text\n .replace(/```[\\s\\S]*?(?:```|$)/g, ' ')\n .replace(/`([^`]*)`/g, '$1')\n .replace(/!?\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\n .replace(/^\\s{0,3}(?:#{1,6}\\s+|>\\s?|[-*+]\\s+|\\d+[.)]\\s+)/gm, '')\n .replace(/(\\*\\*|__|\\*|_|~~)(\\S(?:.*?\\S)?)\\1/g, '$2')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n","/**\n * Renderer-agnostic visible-row model for the Settings → Instructions tab.\n *\n * Simpler than the MCP / extension row models next door: a segment's expanded\n * TEXT is rendered inside its own row box rather than as sibling rows, so the\n * cursor walks one slot per segment no matter how long the text is. Expanding a\n * 1500-line AGENTS.md must not turn ↓ into 1500 keypresses.\n *\n * Pure (no OpenTUI / React) so the filtering + preview clamping is\n * unit-testable.\n */\n\nimport type { ContextSegment } from './context-segments'\n\n/**\n * Upper bound on preview lines rendered for one expanded segment. Mirrors the\n * Logs tab's render cap: the scrollbox can hold arbitrary height, but pasting a\n * runaway 64KB instruction file into the layout pass is a waste of a frame.\n * File-backed segments have `$EDITOR` as the escape hatch for the remainder.\n */\nexport const INSTRUCTION_PREVIEW_LINE_CAP = 400\n\n/** One selectable row: a context segment, plus its resolved open state. */\nexport interface VisibleInstructionRow {\n segment: ContextSegment\n expanded: boolean\n}\n\nexport interface BuildVisibleInstructionRowsOptions {\n segments: readonly ContextSegment[]\n /** Segment ids the user has expanded. */\n expanded: ReadonlySet<string>\n /** True when a search query is active. */\n queryActive: boolean\n /** Whether a segment matches the query. Ignored when `queryActive` is false. */\n matchSegment: (segment: ContextSegment) => boolean\n}\n\n/**\n * Filter segments by the active query and resolve each one's expanded state.\n *\n * Deliberately does NOT auto-expand matches the way the Extensions tab does:\n * the search corpus includes each segment's full text, so a query typically\n * matches deep inside a long document — auto-expanding every hit would dump\n * thousands of lines into the viewport on a keystroke. The user expands the row\n * they care about.\n */\nexport function buildVisibleInstructionRows(\n opts: BuildVisibleInstructionRowsOptions,\n): VisibleInstructionRow[] {\n const { segments, expanded, queryActive, matchSegment } = opts\n const out: VisibleInstructionRow[] = []\n for (const segment of segments) {\n if (queryActive && !matchSegment(segment))\n continue\n out.push({ segment, expanded: expanded.has(segment.id) })\n }\n return out\n}\n\n/**\n * Split a segment's text into renderable preview lines, clamped to\n * {@link INSTRUCTION_PREVIEW_LINE_CAP}.\n *\n * `hidden` is how many lines were dropped off the tail, so the view can render\n * an honest \"+N more lines\" marker instead of silently truncating. Tabs are\n * expanded to two spaces because the terminal text renderable doesn't\n * interpret `\\t`, and `\\r` is stripped so CRLF files don't leave artefacts at\n * every line end.\n */\nexport function instructionPreviewLines(text: string): { lines: string[], hidden: number } {\n const all = text.replace(/\\r\\n?/g, '\\n').replace(/\\t/g, ' ').split('\\n')\n // Trailing blank lines carry no information in a preview and would render as\n // dead space under the last line of a file that ends with a newline.\n while (all.length > 0 && all[all.length - 1]!.trim() === '')\n all.pop()\n if (all.length <= INSTRUCTION_PREVIEW_LINE_CAP)\n return { lines: all, hidden: 0 }\n return {\n lines: all.slice(0, INSTRUCTION_PREVIEW_LINE_CAP),\n hidden: all.length - INSTRUCTION_PREVIEW_LINE_CAP,\n }\n}\n\n/**\n * Short badge for a segment's origin — the \"where does this come from\" column.\n * `'file'` is intentionally the only one that reads like a location, since it's\n * the only origin the user can act on.\n */\nexport function instructionOriginBadge(segment: ContextSegment): string {\n switch (segment.origin) {\n case 'file':\n return 'file'\n case 'generated':\n return 'generated'\n case 'mcp':\n return 'mcp server'\n case 'built-in':\n return 'built-in'\n }\n}\n","/**\n * What clients show about machines (`docs/MACHINES.md` § Client UI), shared\n * by the TUI and the GUI renderer (node-free, re-exported by\n * `zidane/chat/pure`): the \"waiting for <machine>…\" state of a session, a\n * machine's folders as a folder-picker listing, environment kinds grouped\n * by machine, and the words for a link's state.\n */\nimport type { MachineLinkState } from './machine-protocol'\nimport { parseMachineKind } from './machine-protocol'\n\n/** The `label` of the notices a host emits about a session's machine. */\nexport const MACHINE_NOTICE_LABEL = 'machine'\n\nconst WAITING_RE = /^waiting for (\\S+?)…/\nconst BACK_RE = /^\\S+ is back\\./\nconst GAVE_UP_RE = /^\\S+ stayed offline for /\n\n/**\n * The machine a session's run is paused on, from its notices (`waiting for\n * laptop…` until `laptop is back.` or `laptop stayed offline … run stopped`),\n * `null` when none. `online`: machines known to be back since (a\n * `machine:status` the window saw), which clear the wait at once.\n */\nexport function machineWaiting(events: readonly { text?: string, notice?: { label?: string } }[], online: ReadonlySet<string> = new Set()): string | null {\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i]!\n if (event.notice?.label !== MACHINE_NOTICE_LABEL || typeof event.text !== 'string')\n continue\n if (BACK_RE.test(event.text) || GAVE_UP_RE.test(event.text))\n return null\n const waiting = WAITING_RE.exec(event.text)?.[1]\n if (waiting)\n return online.has(waiting) ? null : waiting\n }\n return null\n}\n\n/** A folder listing a folder picker renders (the shape of `fs.listDirs`). */\nexport interface MachineDirListing {\n roots: string[]\n path: string\n parent: string | null\n entries: { path: string, name: string, isGitRepo: boolean }[]\n}\n\nfunction dirname(path: string): string {\n const trimmed = path.replace(/\\/+$/, '')\n const at = trimmed.lastIndexOf('/')\n return at <= 0 ? '/' : trimmed.slice(0, at)\n}\n\nfunction basename(path: string): string {\n const trimmed = path.replace(/\\/+$/, '')\n return trimmed.slice(trimmed.lastIndexOf('/') + 1) || trimmed\n}\n\n/** `machines.listDirs` as a folder listing: the parent stops at the root the folder is in. */\nexport function machineDirListing(result: { path: string, dirs: string[], roots: string[] }): MachineDirListing {\n const { path } = result\n return {\n roots: result.roots,\n path,\n parent: result.roots.includes(path) ? null : dirname(path),\n entries: result.dirs.map(dir => ({ path: dir, name: basename(dir), isGitRepo: false })),\n }\n}\n\n/**\n * Environment kinds in picker order: this host's own first, then each\n * machine's together (`local@` before `worktree@`), machines by name.\n */\nexport function orderByMachine<T extends { kind: string, machine?: { name: string } }>(descriptors: readonly T[]): T[] {\n const rank = (d: T): [number, string, number] => {\n const parsed = parseMachineKind(d.kind)\n return parsed ? [1, parsed.name, parsed.base === 'local' ? 0 : 1] : [0, '', 0]\n }\n return descriptors\n .map((d, i) => ({ d, i, r: rank(d) }))\n .sort((a, b) => a.r[0] - b.r[0] || a.r[1].localeCompare(b.r[1]) || a.r[2] - b.r[2] || a.i - b.i)\n .map(entry => entry.d)\n}\n\n/** Why a machine kind can't be picked now (its machine is offline), else `undefined`. */\nexport function machineBlockedReason(descriptor: { machine?: { name: string, status: 'online' | 'offline' } }): string | undefined {\n return descriptor.machine?.status === 'offline' ? `${descriptor.machine.name} is offline` : undefined\n}\n\n/** A session's environment as its header shows it: `local@laptop`, `worktree@laptop ⎇ feat`, `⎇ feat`, or the kind. */\nexport function environmentLabel(environment: { kind: string, branch?: string }): string {\n if (parseMachineKind(environment.kind))\n return environment.branch ? `${environment.kind} ⎇ ${environment.branch}` : environment.kind\n return environment.branch ? `⎇ ${environment.branch}` : environment.kind\n}\n\nexport const MACHINE_LINK_STATE_TEXT: Record<MachineLinkState, string> = {\n 'connecting': 'connecting…',\n 'connected': 'connected',\n 'reconnecting': 'reconnecting…',\n 'offline': 'offline',\n 'auth-refused': 'refused',\n 'identity': 'another server answers there',\n 'refused': 'refused',\n}\n\n/** \"seen 5 min ago\" for a machine's `lastSeen`. */\nexport function lastSeenText(lastSeen: number | undefined, now: number): string {\n if (lastSeen === undefined)\n return 'never seen'\n const minutes = Math.max(0, Math.round((now - lastSeen) / 60_000))\n if (minutes < 1)\n return 'seen just now'\n if (minutes < 60)\n return `seen ${minutes} min ago`\n const hours = Math.round(minutes / 60)\n return hours < 48 ? `seen ${hours} h ago` : `seen ${Math.round(hours / 24)} d ago`\n}\n","/**\n * Add-MCP form model — values, validation, and the two tokenizers it depends\n * on. Renderer-agnostic and node-free.\n *\n * Lives in `chat/` because BOTH clients render this form (the TUI's\n * `settings-form-dialog`, the GUI's `McpsPanel`). It used to exist as two\n * copies that had already diverged in formatting; validation is the one place\n * a divergence would matter, because it decides which MCP configs each surface\n * accepts. One implementation means the same `mcps.json` entry is accepted or\n * rejected identically everywhere.\n */\nimport type { McpServerConfig } from '../types'\n\n/** Where a written MCP entry lands. */\nexport type InstallScopeChoice = 'user' | 'project'\n\nexport type McpTransport = 'stdio' | 'streamable-http' | 'sse'\n\nexport const MCP_TRANSPORTS: readonly McpTransport[] = ['stdio', 'streamable-http', 'sse']\n\nexport interface McpFormValues {\n name: string\n transport: McpTransport\n /** stdio: full command line (first token = command, rest = args). */\n commandLine: string\n /** http/sse: server URL. */\n url: string\n /** One `KEY=VALUE` per line — stdio only. Values may contain spaces. */\n env: string\n /** One `Name: value` (or `Name=value`) per line — http/sse only. */\n headers: string\n scope: InstallScopeChoice\n}\n\nexport interface McpFormResult {\n entry: McpServerConfig\n scope: InstallScopeChoice\n}\n\n/**\n * Validate + normalize the raw field values into a config entry.\n * Returns the first problem in row order so the dialog can surface it.\n */\nexport function validateMcpForm(values: McpFormValues): { ok: true, result: McpFormResult } | { ok: false, error: string } {\n const name = values.name.trim()\n if (name.length === 0)\n return { ok: false, error: 'name is required' }\n if (!/^[\\w.-]+$/.test(name))\n return { ok: false, error: 'name must be alphanumerics, dots, hyphens, underscores' }\n\n if (values.transport === 'stdio') {\n const tokens = splitCommandLine(values.commandLine)\n if (tokens.length === 0)\n return { ok: false, error: 'command is required for stdio servers' }\n const env = parseKeyValueLines(values.env, { label: 'env', separators: ['='] })\n if (!env.ok)\n return { ok: false, error: env.error }\n const entry: McpServerConfig = {\n name,\n transport: 'stdio',\n command: tokens[0] as string,\n ...(tokens.length > 1 ? { args: tokens.slice(1) } : {}),\n ...(Object.keys(env.pairs).length > 0 ? { env: env.pairs } : {}),\n }\n return { ok: true, result: { entry, scope: values.scope } }\n }\n\n const url = values.url.trim()\n if (url.length === 0)\n return { ok: false, error: 'url is required for http/sse servers' }\n if (!/^https?:\\/\\//.test(url))\n return { ok: false, error: 'url must start with http:// or https://' }\n const headers = parseKeyValueLines(values.headers, { label: 'headers', separators: [':', '='] })\n if (!headers.ok)\n return { ok: false, error: headers.error }\n return {\n ok: true,\n result: {\n entry: {\n name,\n transport: values.transport,\n url,\n ...(Object.keys(headers.pairs).length > 0 ? { headers: headers.pairs } : {}),\n },\n scope: values.scope,\n },\n }\n}\n\n/**\n * Split a command line into tokens, honoring single/double quotes so\n * `npx -y my-server --root \"/path with spaces\"` round-trips. No escape\n * processing beyond quote grouping — this is a form field, not a shell.\n */\nexport function splitCommandLine(line: string): string[] {\n const out: string[] = []\n const re = /\"([^\"]*)\"|'([^']*)'|(\\S+)/g\n for (let m = re.exec(line); m !== null; m = re.exec(line))\n out.push((m[1] ?? m[2] ?? m[3]) as string)\n return out\n}\n\n/**\n * Parse one key/value pair PER LINE. Line-based (not whitespace-split)\n * because values legitimately contain spaces — `Authorization: Bearer\n * abc123` is the canonical headers case, and env values like\n * `GREETING=hello world` are equally valid. The first separator found\n * (in `separators` priority order, `:` before `=` for headers) splits;\n * the rest of the line is the value, trimmed. Blank lines skipped.\n */\nexport function parseKeyValueLines(\n raw: string,\n opts: { label: string, separators: readonly string[] },\n): { ok: true, pairs: Record<string, string> } | { ok: false, error: string } {\n const pairs: Record<string, string> = {}\n for (const line of raw.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.length === 0)\n continue\n let splitAt = -1\n for (const sep of opts.separators) {\n const idx = trimmed.indexOf(sep)\n if (idx > 0 && (splitAt === -1 || idx < splitAt))\n splitAt = idx\n }\n if (splitAt <= 0) {\n const forms = opts.separators.map(s => `KEY${s}VALUE`).join(' or ')\n return { ok: false, error: `${opts.label} entries must be ${forms}, one per line (got \"${trimmed}\")` }\n }\n const key = trimmed.slice(0, splitAt).trim()\n const value = trimmed.slice(splitAt + 1).trim()\n if (key.length === 0)\n return { ok: false, error: `${opts.label} entry has an empty key (\"${trimmed}\")` }\n pairs[key] = value\n }\n return { ok: true, pairs }\n}\n","/**\n * The name a person uses for a model, for pills, pickers and lists.\n *\n * - First-party providers drop their own brand: under Anthropic, \"Claude\n * Opus 4.6\" is \"Opus 4.6\"; under OpenAI, \"OpenAI GPT-5\" is \"GPT-5\".\n * - Aggregators prefix the vendor (\"Anthropic: Claude Opus 4.6\"): the name\n * is what follows, the vendor comes back separately for a caller that\n * shows it (a meta, a tooltip).\n * - \"(latest)\" is dropped: next to a snapshot it reads as a recency claim.\n * - Without a catalog name, the id is made readable: `claude-opus-4-7-20250722`\n * → \"Opus 4.7\" under Anthropic.\n */\n\nexport interface ModelNameInput {\n providerKey?: string | null\n modelId: string\n /** The catalog's display name, when known. */\n modelName?: string | null\n}\n\nexport interface ModelDisplayName {\n name: string\n /** The model's maker, when the name carried it (aggregators: \"Anthropic\"). */\n vendor?: string\n}\n\n/** Brand words a first-party provider's names start with. */\nconst OWN_BRAND: Record<string, RegExp> = {\n anthropic: /^claude[\\s-]+/i,\n openai: /^openai[\\s:-]+/i,\n}\n\nconst ACRONYMS = new Set(['gpt', 'glm', 'oss', 'ai', 'r1', 'vl'])\n\n/** `claude-opus-4-7-20250722` → `Claude Opus 4.7`; `gpt-5.5` → `GPT 5.5`. */\nfunction readableId(id: string): string {\n const last = id.split('/').pop() ?? id\n const parts = last\n .replace(/-\\d{8}$/, '')\n .split(/[-_]/)\n .filter(Boolean)\n const out: string[] = []\n for (const part of parts) {\n const prev = out[out.length - 1]\n // Consecutive number parts are a version: 4-7 → 4.7.\n if (/^\\d+$/.test(part) && prev && /^\\d+(?:\\.\\d+)*$/.test(prev)) {\n out[out.length - 1] = `${prev}.${part}`\n continue\n }\n out.push(ACRONYMS.has(part.toLowerCase()) ? part.toUpperCase() : part.charAt(0).toUpperCase() + part.slice(1))\n }\n return out.join(' ')\n}\n\nexport function modelDisplayName({ providerKey, modelId, modelName }: ModelNameInput): ModelDisplayName {\n let name = (modelName && modelName !== modelId ? modelName : readableId(modelId)).trim()\n let vendor: string | undefined\n\n name = name.replace(/\\s*\\(latest\\)\\s*$/i, '')\n\n const prefixed = /^([^:]{2,40}):\\s+(\\S.*)$/.exec(name)\n if (prefixed) {\n vendor = prefixed[1]!.trim()\n name = prefixed[2]!.trim()\n }\n\n // A bare first-party id (`claude-opus-4-7`) names its maker even when the\n // caller has no provider at hand (a receipt, a usage row).\n const key = providerKey ?? (/^claude[-_]/i.test(modelId) ? 'anthropic' : undefined)\n const brand = key ? OWN_BRAND[key] : undefined\n if (brand && brand.test(name) && name.replace(brand, '').trim())\n name = name.replace(brand, '').trim()\n\n return vendor ? { name, vendor } : { name }\n}\n","/**\n * Presentation constants for structured transcript notices (`StreamEvent.notice`).\n *\n * Shared by the TUI transcript and the GUI timeline so a `warn` notice reads\n * with the same glyph on both, and so the label vocabulary (`model fallback`,\n * `output limit`, `repeat guard`, …) is recognisably the same row across\n * surfaces. Pure; re-exported from `zidane/chat/pure`.\n */\nimport type { StreamEvent } from './types'\n\nexport type NoticeSeverity = NonNullable<StreamEvent['notice']>['severity']\n\n/** Leading glyph per severity. `info` is deliberately quiet — a middle dot. */\nexport const NOTICE_GLYPH: Readonly<Record<NoticeSeverity, string>> = {\n info: '·',\n warn: '!',\n error: '✗',\n}\n","/**\n * Command palette: the renderer-agnostic model.\n *\n * Everything the user can do from the palette is a {@link PaletteItem}:\n * built-in key actions, `/` commands, panels, sessions, settings toggles\n * and extension actions all flow through one shape, so one search covers\n * the app. Items are JSON-safe data and `run` is addressed by id, the same\n * contract side panels use: an extension's provider executes where the\n * extension lives (TUI in-process, GUI main process) and the palette\n * paints in the host with its own components.\n *\n * This module is pure (no React, no node): ranking, grouping, recents and\n * the normaliser applied before items cross IPC. The TUI and the GUI each\n * render the result; they never re-implement the ordering.\n */\nimport type { PanelIcon } from '../extensions/panels'\nimport type { JsonValue } from '../types'\n\nexport type PaletteHost = 'gui' | 'tui'\n\n/** `toggle` shows a checked state; `picker` opens a nested list on run. */\nexport type PaletteItemKind = 'action' | 'toggle' | 'picker'\n\nexport interface PaletteItem {\n /** Stable, unique across providers: `builtin:openSettings`, `slash:compact`, `<extension>/<id>`. */\n id: string\n title: string\n description?: string\n /** Section header. Hosts order groups by first appearance after `Recent`. */\n group: string\n /** Extra search terms not shown in the row. */\n keywords?: readonly string[]\n icon?: PanelIcon\n kind?: PaletteItemKind\n /** For `toggle` items. */\n checked?: boolean\n /** Resolved chord spec (`ctrl+shift+k`); the host formats it for display. */\n keybinding?: string\n /** Reason the item cannot run right now; it stays listed, muted. */\n disabled?: string\n /**\n * Only appears once the query matches it: bulk catalogs (every file in\n * the project) stay out of the empty-query listing but are one keystroke\n * away.\n */\n searchOnly?: boolean\n /** Provider that owns `run` for this item. Stamped by the aggregator. */\n source: string\n}\n\n/** JSON-safe snapshot of the host handed to providers. Never holds functions. */\nexport interface PaletteContext {\n host: PaletteHost\n cwd?: string\n sessionId?: string\n /** A run is in flight on the active session. */\n busy?: boolean\n}\n\n/**\n * What a provider's `run` may hand back. `items` opens a nested picker\n * (branches, environments); the host keeps a stack so Backspace on an\n * empty query goes back one level. `prompt` sends text to the chat,\n * `insert` puts it in the composer (a `/` command that takes arguments).\n */\nexport type PaletteRunResult\n = | void\n | undefined\n | { kind: 'items', title?: string, placeholder?: string, items: readonly PaletteItem[] }\n | { kind: 'prompt', text: string }\n | { kind: 'insert', text: string }\n | { kind: 'notify', text: string, tone?: 'info' | 'warn' | 'error' }\n\nexport interface PaletteProvider {\n id: string\n /** Items for the current context. Called on open, on `subscribe` emits, and on explicit refresh. */\n items: (ctx: PaletteContext) => readonly PaletteItem[] | Promise<readonly PaletteItem[]>\n run: (itemId: string, ctx: PaletteContext) => PaletteRunResult | Promise<PaletteRunResult>\n /** Live updates while the palette is open, same contract as panels. */\n subscribe?: (emit: () => void) => () => void\n}\n\n// ---------------------------------------------------------------------------\n// Ranking\n// ---------------------------------------------------------------------------\n\nexport interface RankedPaletteItem {\n item: PaletteItem\n score: number\n /** Indices into `item.title` to highlight. Empty when the match came from elsewhere. */\n titleMatches: readonly number[]\n}\n\n/** Group name the hosts use for the most-recently-used rows shown on an empty query. */\nexport const PALETTE_RECENT_GROUP = 'Recent'\nexport const PALETTE_RECENTS_MAX = 12\n/** Ranked rows returned for a query; the host virtualises anyway, this bounds the work. */\nexport const PALETTE_RESULT_MAX = 200\n\nconst WORD_BREAKS = new Set([' ', '/', '-', '_', ':', '.'])\n\n/** What a hit at `at` is worth: the very start, a word start, a camelCase hump, or anywhere. */\nfunction startBonus(text: string, lower: string, at: number): number {\n if (at === 0)\n return 8\n if (WORD_BREAKS.has(lower[at - 1]!))\n return 6\n if (text[at] !== lower[at] && text[at - 1] === lower[at - 1])\n return 4\n return 1\n}\n\n/** Bonus per character for a term found whole: \"set\" in \"settings\" beats s·e·t across words. */\nconst WHOLE_TERM_BONUS = 2\n\n/**\n * Subsequence match of `query` in `text` with the usual bonuses: word\n * starts and the very beginning score higher, gaps cost, runs of adjacent\n * hits are rewarded, and the query found whole (as one run) beats the same\n * letters scattered. Returns null when not every query character appears\n * in order. Case-insensitive; `query` must already be lower-cased.\n */\nexport function fuzzyMatch(text: string, query: string): { score: number, indices: number[] } | null {\n return matchLowered(text, text.toLowerCase(), query)\n}\n\nconst NO_INDICES: number[] = []\n\n/** `indices` null: the score alone (a fallback field never highlights), without the allocations. */\nfunction matchLowered(\n text: string,\n lower: string,\n query: string,\n indices: number[] | null = [],\n): { score: number, indices: number[], whole: boolean } | null {\n if (query.length === 0)\n return { score: 0, indices: [], whole: true }\n // Scattered: each character at its first place after the previous one.\n let score = 0\n let from = 0\n let prev = -2\n for (let q = 0; q < query.length; q++) {\n const at = lower.indexOf(query[q]!, from)\n if (at === -1)\n return null\n score += startBonus(text, lower, at)\n if (at === prev + 1)\n score += 3\n else if (prev >= 0)\n score -= Math.min(3, at - prev - 1) * 0.5\n indices?.push(at)\n prev = at\n from = at + 1\n }\n // Whole: the best place the query appears as one run, if it does.\n let whole = -Infinity\n let wholeAt = -1\n for (let at = lower.indexOf(query); at !== -1; at = lower.indexOf(query, at + 1)) {\n const value = startBonus(text, lower, at) + (query.length - 1) * 4 + query.length * WHOLE_TERM_BONUS\n if (value > whole) {\n whole = value\n wholeAt = at\n }\n // A word start is the best a later place could do (the very start only comes first).\n if (at === 0 || WORD_BREAKS.has(lower[at - 1]!))\n break\n }\n const found = whole > score\n if (found) {\n score = whole\n if (indices) {\n for (let q = 0; q < query.length; q++) indices[q] = wholeAt + q\n }\n }\n // Shorter targets win ties: \"Open settings\" over \"Open settings: keybindings\".\n score -= text.length * 0.02\n return { score, indices: indices ?? NO_INDICES, whole: found }\n}\n\n/** An item's searchable text, lower-cased once per item instead of once per key. */\ninterface Haystack {\n title: string\n fields: readonly (readonly [text: string, lower: string])[]\n}\n\nconst haystacks = new WeakMap<PaletteItem, Haystack>()\n\nfunction haystackOf(item: PaletteItem): Haystack {\n let h = haystacks.get(item)\n if (!h) {\n const texts = [item.title, item.description, item.group, ...(item.keywords ?? [])].filter(\n (t): t is string => !!t,\n )\n h = { title: item.title.toLowerCase(), fields: texts.map(t => [t, t.toLowerCase()] as const) }\n haystacks.set(item, h)\n }\n return h\n}\n\n/**\n * Every whitespace-separated term must match (AND); scores add. `whole`:\n * each term was found as one run (the words typed, not letters picked\n * across the text). `indices` collects the merged highlight when given;\n * ranking scores without it and highlights only the rows it keeps.\n */\nfunction matchTerms(\n text: string,\n lower: string,\n terms: readonly string[],\n indices: number[] | null,\n): { score: number, whole: boolean } | null {\n let score = 0\n let whole = true\n for (const term of terms) {\n const m = matchLowered(text, lower, term, indices && [])\n if (!m)\n return null\n score += m.score\n whole &&= m.whole\n indices?.push(...m.indices)\n }\n return { score, whole }\n}\n\nfunction titleIndices(item: PaletteItem, terms: readonly string[]): number[] {\n const indices: number[] = []\n matchTerms(item.title, haystackOf(item).title, terms, indices)\n return terms.length === 1 ? indices : [...new Set(indices)].sort((a, b) => a - b)\n}\n\nconst collator = new Intl.Collator()\n\nfunction termsOf(query: string): string[] {\n return query.trim().toLowerCase().split(/\\s+/).filter(Boolean)\n}\n\n/** On an empty query: recents first (most recent on top), then the catalog in provider order. */\nfunction listUnfiltered(items: readonly PaletteItem[], recents: readonly string[]): RankedPaletteItem[] {\n const recentRank = new Map(recents.map((id, i) => [id, i]))\n const out: RankedPaletteItem[] = []\n for (const item of items) {\n const r = recentRank.get(item.id)\n // Search-only items surface on an empty query only as recents.\n if (item.searchOnly && r === undefined)\n continue\n out.push({ item, score: r === undefined ? 0 : PALETTE_RECENTS_MAX - r, titleMatches: [] })\n }\n // Stable: recents by recency, everything else keeps provider order.\n return out.sort((a, b) => b.score - a.score).slice(0, PALETTE_RESULT_MAX)\n}\n\n/** The ranked rows for `terms`, and every item that matched (the pool a longer query searches). */\nfunction rankTerms(\n items: readonly PaletteItem[],\n terms: readonly string[],\n): { ranked: RankedPaletteItem[], matched: PaletteItem[] } {\n const hits: { item: PaletteItem, score: number, inTitle: boolean }[] = []\n for (const item of items) {\n const hay = haystackOf(item)\n // The words typed, found in the title, come first; letters picked across a\n // title compete with what the description and keywords found.\n const title = matchTerms(item.title, hay.title, terms, null)\n if (title?.whole) {\n hits.push({ item, score: 100 + title.score, inTitle: true })\n continue\n }\n // Fallback: every term must land somewhere across title, description, keywords, group.\n let total = 0\n let ok = true\n for (const term of terms) {\n let best = -Infinity\n for (const [text, lower] of hay.fields) {\n const m = matchLowered(text, lower, term, null)\n if (m && m.score > best)\n best = m.score\n }\n if (best === -Infinity) {\n ok = false\n break\n }\n total += best\n }\n if (title && title.score >= total)\n hits.push({ item, score: title.score, inTitle: true })\n else if (ok)\n hits.push({ item, score: total, inTitle: false })\n }\n const matched = hits.map(h => h.item)\n hits.sort((a, b) => b.score - a.score || collator.compare(a.item.title, b.item.title))\n const ranked = hits.slice(0, PALETTE_RESULT_MAX).map(({ item, score, inTitle }) => ({\n item,\n score,\n titleMatches: inTitle ? titleIndices(item, terms) : [],\n }))\n return { ranked, matched }\n}\n\n/**\n * Score every item against `query`. Terms are AND-ed: `tog sid` needs both\n * `tog` and `sid` in order somewhere in the text. Title matches dominate;\n * description, keywords and group are fallbacks that never outrank a\n * title hit. On an empty query recents come first (most recent on top),\n * then the catalog in provider order.\n */\nexport function rankPaletteItems(\n items: readonly PaletteItem[],\n query: string,\n recents: readonly string[] = [],\n): RankedPaletteItem[] {\n const terms = termsOf(query)\n return terms.length === 0 ? listUnfiltered(items, recents) : rankTerms(items, terms).ranked\n}\n\n/** `next` asks for at least what `prev` did: each earlier term grew or stayed, new ones came after. */\nfunction narrows(prev: readonly string[], next: readonly string[]): boolean {\n return next.length >= prev.length && prev.every((term, i) => next[i]!.startsWith(term))\n}\n\n/**\n * `rankPaletteItems` for a palette being typed into: it remembers the last\n * query, and when the next one only adds to it (one more character, one\n * more word) it searches just what matched before. A longer query never\n * matches an item the shorter one missed, so the result is the same.\n */\nexport function createPaletteRanker(): typeof rankPaletteItems {\n let last: { items: readonly PaletteItem[], terms: readonly string[], matched: PaletteItem[] } | null = null\n return (items, query, recents = []) => {\n const terms = termsOf(query)\n if (terms.length === 0) {\n last = null\n return listUnfiltered(items, recents)\n }\n const pool = last && last.items === items && narrows(last.terms, terms) ? last.matched : items\n const { ranked, matched } = rankTerms(pool, terms)\n last = { items, terms, matched }\n return ranked\n }\n}\n\nexport interface PaletteGroup {\n title: string\n rows: readonly RankedPaletteItem[]\n}\n\n/**\n * Sections for display. With a query the ranking already interleaves\n * providers, so groups follow the order of their best row. Without a\n * query the recents (ids in `recents`, present in `ranked`) form a\n * leading `Recent` section and the rest keeps provider order.\n */\nexport function groupPaletteRows(\n ranked: readonly RankedPaletteItem[],\n query: string,\n recents: readonly string[] = [],\n): PaletteGroup[] {\n const groups = new Map<string, RankedPaletteItem[]>()\n const push = (title: string, row: RankedPaletteItem) => {\n const list = groups.get(title)\n if (list)\n list.push(row)\n else groups.set(title, [row])\n }\n const isRecent = new Set(query.trim() ? [] : recents)\n for (const row of ranked)\n push(isRecent.has(row.item.id) ? PALETTE_RECENT_GROUP : row.item.group, row)\n return [...groups.entries()].map(([title, rows]) => ({ title, rows }))\n}\n\n/** Most-recent-first list of ids, deduplicated and capped. */\nexport function pushPaletteRecent(recents: readonly string[], id: string): string[] {\n return [id, ...recents.filter(r => r !== id)].slice(0, PALETTE_RECENTS_MAX)\n}\n\n// ---------------------------------------------------------------------------\n// Normalisation (before items cross IPC or reach a renderer)\n// ---------------------------------------------------------------------------\n\nexport const PALETTE_LIMITS = {\n items: 500,\n textChars: 500,\n keywords: 16,\n} as const\n\nfunction str(v: unknown, max: number = PALETTE_LIMITS.textChars): string | undefined {\n return typeof v === 'string' && v.length > 0 ? (v.length > max ? `${v.slice(0, max - 1)}…` : v) : undefined\n}\n\n/**\n * Coerce whatever a provider returned into well-formed items: entries\n * without an id or title are dropped, strings are capped, unknown kinds\n * fall back to `action`, and `source` is stamped with the provider id.\n * Never throws.\n */\nexport function normalizePaletteItems(input: unknown, source: string, defaultGroup: string): PaletteItem[] {\n if (!Array.isArray(input))\n return []\n const out: PaletteItem[] = []\n const seen = new Set<string>()\n for (const raw of input.slice(0, PALETTE_LIMITS.items)) {\n if (!raw || typeof raw !== 'object')\n continue\n const r = raw as Record<string, unknown>\n const id = str(r.id, 200)\n const title = str(r.title, 200)\n if (!id || !title || seen.has(id))\n continue\n seen.add(id)\n const item: PaletteItem = { id, title, group: str(r.group, 80) ?? defaultGroup, source }\n const description = str(r.description)\n if (description)\n item.description = description\n if (Array.isArray(r.keywords)) {\n const kw = r.keywords.filter((k): k is string => typeof k === 'string' && k.length > 0).slice(0, PALETTE_LIMITS.keywords)\n if (kw.length > 0)\n item.keywords = kw.map(k => k.slice(0, 60))\n }\n if (r.icon && typeof r.icon === 'object') {\n const icon = r.icon as Record<string, unknown>\n const gui = str(icon.gui, 120)\n const tui = str(icon.tui, 8)\n if (gui || tui)\n item.icon = { ...(gui ? { gui } : {}), ...(tui ? { tui } : {}) }\n }\n if (r.kind === 'toggle' || r.kind === 'picker')\n item.kind = r.kind\n if (typeof r.checked === 'boolean')\n item.checked = r.checked\n const keybinding = str(r.keybinding, 60)\n if (keybinding)\n item.keybinding = keybinding\n const disabled = str(r.disabled, 200)\n if (disabled)\n item.disabled = disabled\n if (r.searchOnly === true)\n item.searchOnly = true\n out.push(item)\n }\n return out\n}\n\n/** Same guard for a `run` result: anything malformed becomes `undefined` (nothing to do). */\nexport function normalizePaletteRunResult(input: unknown, source: string, defaultGroup: string): PaletteRunResult {\n if (!input || typeof input !== 'object')\n return undefined\n const r = input as Record<string, unknown>\n switch (r.kind) {\n case 'items': {\n const out: Extract<PaletteRunResult, { kind: 'items' }> = {\n kind: 'items',\n items: normalizePaletteItems(r.items, source, defaultGroup),\n }\n const title = str(r.title, 200)\n const placeholder = str(r.placeholder, 200)\n if (title)\n out.title = title\n if (placeholder)\n out.placeholder = placeholder\n return out\n }\n case 'prompt':\n case 'insert': {\n const text = str(r.text, 20_000)\n return text ? { kind: r.kind, text } : undefined\n }\n case 'notify': {\n const text = str(r.text, 1000)\n if (!text)\n return undefined\n const tone = r.tone === 'warn' || r.tone === 'error' ? r.tone : 'info'\n return { kind: 'notify', text, tone }\n }\n default:\n return undefined\n }\n}\n\n/** Type guard hosts use before forwarding a payload from an untrusted provider. */\nexport function isPaletteContext(v: unknown): v is PaletteContext {\n if (!v || typeof v !== 'object')\n return false\n const c = v as Record<string, JsonValue | undefined>\n return (c.host === 'gui' || c.host === 'tui')\n && (c.cwd === undefined || typeof c.cwd === 'string')\n && (c.sessionId === undefined || typeof c.sessionId === 'string')\n && (c.busy === undefined || typeof c.busy === 'boolean')\n}\n","/**\n * Side-panel catalog and open state. Renderer-agnostic: the TUI rail and\n * the GUI side panel both read the same catalog (built-ins first, then\n * extension panels in load order) and drive the same state machine.\n *\n * The one behavioural rule worth spelling out: `openProactive`. Agent- or\n * extension-driven opens (a PR was created, a badge flipped) must never\n * yank the panel away from a tab the user chose. So a proactive request\n * is honoured only while the user has not picked a tab since the previous\n * proactive open; the moment they click a tab, proactive opens are ignored\n * until the next user pick resets the gate.\n */\nimport type { ExtensionPanelEntry, PanelIcon } from '../extensions/panels'\n\nexport const INBOX_PANEL_ID = 'inbox'\nexport const TODOS_PANEL_ID = 'todos'\nexport const ARTIFACTS_PANEL_ID = 'artifacts'\nexport const DIFFS_PANEL_ID = 'diffs'\nexport const FILES_PANEL_ID = 'files'\nexport const BROWSER_PANEL_ID = 'browser'\nexport const TERMINAL_PANEL_ID = 'terminal'\n\n/** Built-in tabs the hosts render with their own components. */\nexport type BuiltinPanelId\n = | typeof INBOX_PANEL_ID\n | typeof TODOS_PANEL_ID\n | typeof ARTIFACTS_PANEL_ID\n | typeof DIFFS_PANEL_ID\n | typeof FILES_PANEL_ID\n | typeof BROWSER_PANEL_ID\n | typeof TERMINAL_PANEL_ID\n\nexport interface BuiltinPanelTab {\n id: BuiltinPanelId\n label: string\n icon: PanelIcon\n builtin: true\n}\n\nexport interface ExtensionPanelTab {\n id: string\n label: string\n icon?: PanelIcon\n builtin: false\n owner: string\n}\n\nexport type PanelTab = BuiltinPanelTab | ExtensionPanelTab\n\nexport const BUILTIN_PANEL_TABS: readonly BuiltinPanelTab[] = [\n // Agent-facing surfaces first: what is waiting on the user, then the plan.\n { id: INBOX_PANEL_ID, label: 'Inbox', icon: { gui: 'i-ph-tray', tui: '✉' }, builtin: true },\n { id: TODOS_PANEL_ID, label: 'Todos', icon: { gui: 'i-ph-list-checks', tui: '▣' }, builtin: true },\n { id: ARTIFACTS_PANEL_ID, label: 'Artifacts', icon: { gui: 'i-ph-cube', tui: '◆' }, builtin: true },\n { id: DIFFS_PANEL_ID, label: 'Diffs', icon: { gui: 'i-ph-git-diff', tui: '±' }, builtin: true },\n { id: FILES_PANEL_ID, label: 'Files', icon: { gui: 'i-ph-tree-structure', tui: '▤' }, builtin: true },\n { id: BROWSER_PANEL_ID, label: 'Browser', icon: { gui: 'i-ph-globe-simple', tui: '◎' }, builtin: true },\n { id: TERMINAL_PANEL_ID, label: 'Terminal', icon: { gui: 'i-ph-terminal-window', tui: '❯' }, builtin: true },\n]\n\nexport interface PanelCatalogOptions {\n /** Hide the artifacts tab (the user's `artifacts: false` setting). */\n showArtifacts?: boolean\n /** Built-in ids the host can't render (the TUI has no diff viewer yet). */\n omitBuiltins?: readonly BuiltinPanelId[]\n}\n\n/** Built-ins first, then extension panels in registry (load) order. */\nexport function buildPanelCatalog(\n extensionPanels: readonly Pick<ExtensionPanelEntry, 'id' | 'label' | 'icon' | 'owner'>[],\n options: PanelCatalogOptions = {},\n): PanelTab[] {\n const tabs: PanelTab[] = []\n for (const tab of BUILTIN_PANEL_TABS) {\n if (tab.id === ARTIFACTS_PANEL_ID && options.showArtifacts === false)\n continue\n if (options.omitBuiltins?.includes(tab.id))\n continue\n tabs.push(tab)\n }\n const seen = new Set(tabs.map(t => t.id))\n for (const p of extensionPanels) {\n if (seen.has(p.id))\n continue\n seen.add(p.id)\n tabs.push({ id: p.id, label: p.label, builtin: false, owner: p.owner, ...(p.icon ? { icon: p.icon } : {}) })\n }\n return tabs\n}\n\n// ---------------------------------------------------------------------------\n// State\n// ---------------------------------------------------------------------------\n\nexport interface PanelState {\n open: boolean\n /** Active tab id; `null` when nothing has been chosen yet (hosts pick the first tab). */\n activeId: string | null\n /** Monotonic counter bumped on every user pick; gates proactive opens. */\n userPicks: number\n /** `userPicks` value at the last proactive open that was honoured. */\n proactiveAt: number\n}\n\nexport const INITIAL_PANEL_STATE: PanelState = { open: false, activeId: null, userPicks: 0, proactiveAt: 0 }\n\n/** Add a tab to the host's pinned strip (idempotent, keeps order). */\nexport function pinTab(pinned: readonly string[], id: string): readonly string[] {\n return pinned.includes(id) ? pinned : [...pinned, id]\n}\n\n/**\n * Apply a user reorder of the VISIBLE strip to the pinned list. `pinned` can\n * hold ids the catalog no longer shows (an extension disabled for this cwd);\n * they keep their slots, and the visible ids fill the remaining slots in the\n * new order, so re-enabling the extension brings its tab back where it was.\n * Ids in `visible` that aren't pinned are ignored. Returns `pinned` itself\n * when nothing moved.\n */\nexport function reorderTabs(pinned: readonly string[], visible: readonly string[]): readonly string[] {\n const shown = new Set(visible.filter(id => pinned.includes(id)))\n const order = visible.filter(id => shown.has(id))\n let next = 0\n const out = pinned.map(id => (shown.has(id) ? order[next++]! : id))\n return out.every((id, i) => id === pinned[i]) ? pinned : out\n}\n\n/**\n * Move one visible tab `delta` slots within the visible strip (keyboard\n * reorder), clamped at the ends. Hidden pinned ids keep their slots.\n */\nexport function moveTab(\n pinned: readonly string[],\n visible: readonly string[],\n id: string,\n delta: number,\n): readonly string[] {\n const from = visible.indexOf(id)\n if (from < 0)\n return pinned\n const to = Math.max(0, Math.min(visible.length - 1, from + delta))\n if (to === from)\n return pinned\n const order = [...visible]\n order.splice(from, 1)\n order.splice(to, 0, id)\n return reorderTabs(pinned, order)\n}\n\n/** The user clicked a tab (or a keybinding cycled to it). Always honoured, always opens. */\nexport function pickTab(state: PanelState, id: string): PanelState {\n return { ...state, open: true, activeId: id, userPicks: state.userPicks + 1 }\n}\n\nexport function togglePanel(state: PanelState): PanelState {\n return { ...state, open: !state.open }\n}\n\nexport function closePanel(state: PanelState): PanelState {\n return { ...state, open: false }\n}\n\n/**\n * Agent / extension asked to show a tab. Honoured only until the user has\n * picked a tab themselves (a badge that flipped must never steal the tab);\n * otherwise the request is dropped and the state returned unchanged.\n */\nexport function openProactive(state: PanelState, id: string): PanelState {\n if (state.userPicks !== state.proactiveAt)\n return state\n return { ...state, open: true, activeId: id }\n}\n\n/**\n * The agent is blocked on the user (a plan to approve, a question to\n * answer): show the tab regardless of earlier picks. Costs at most a tab\n * switch, and nothing in that tab decides implicitly. Not a user pick, so\n * it does not lock out later proactive opens.\n */\nexport function openForAttention(state: PanelState, id: string): PanelState {\n if (state.open && state.activeId === id)\n return state\n return { ...state, open: true, activeId: id }\n}\n\n/**\n * Resolve the tab to render: the active one when it still exists, else the\n * first tab, else `null` (empty catalog). Keeps state stable when an\n * extension is disabled and its tab vanishes.\n */\nexport function resolveActiveTab(state: PanelState, catalog: readonly PanelTab[]): PanelTab | null {\n if (catalog.length === 0)\n return null\n return catalog.find(t => t.id === state.activeId) ?? catalog[0]\n}\n\n/** Cycle to the next / previous tab (wraps). Counts as a user pick. */\nexport function cycleTab(state: PanelState, catalog: readonly PanelTab[], direction: 1 | -1): PanelState {\n if (catalog.length === 0)\n return state\n const current = resolveActiveTab(state, catalog)\n const idx = current ? catalog.findIndex(t => t.id === current.id) : 0\n const next = catalog[(idx + direction + catalog.length) % catalog.length]\n return pickTab(state, next.id)\n}\n","/**\n * Display form of a stored prompt. Prompts sent before the composer kept one\n * newline per line break carry a markdown paragraph gap after every line\n * (`a\\n\\nb`, and `a\\n\\n\\n\\nb` for one blank line): shown as plain text, that\n * spread a short message over a whole screen. Runs of three or more newlines\n * collapse to one blank line; chip spans are remapped onto the result.\n */\nimport type { PromptSegmentRef } from './prompt-segments'\n\nexport function tidyPromptText(\n text: string,\n refs: readonly PromptSegmentRef[],\n): { text: string, refs: PromptSegmentRef[] } {\n const trimmed = text.trimEnd()\n if (!/\\n{3,}/.test(trimmed))\n return { text: trimmed, refs: refs.filter(r => r.end <= trimmed.length) }\n // map[i] = index in the output of input index i (and map[len] = output length).\n const map: number[] = Array.from({ length: trimmed.length + 1 })\n let out = ''\n for (let i = 0; i < trimmed.length;) {\n const run = /^\\n{3,}/.exec(trimmed.slice(i, i + 64))\n if (run && trimmed[i] === '\\n') {\n let end = i\n while (trimmed[end] === '\\n') end++\n for (let k = i; k < end; k++) map[k] = out.length + Math.min(k - i, 2)\n out += '\\n\\n'\n i = end\n continue\n }\n map[i] = out.length\n out += trimmed[i]\n i++\n }\n map[trimmed.length] = out.length\n const remapped = refs\n .filter(r => r.end <= trimmed.length)\n .map(r => ({ ...r, start: map[r.start]!, end: map[r.end]! }))\n return { text: out, refs: remapped }\n}\n","/**\n * The markers the loop writes into an assistant turn when its stream ends\n * early (`src/loop.ts`): `[✗ Streaming failed before any output: <message>]`\n * (or `mid-output`) when the provider throws, `[⏹ Streaming was aborted.]`\n * when the user stops the run. Either is appended blank-line-separated to\n * whatever had streamed. The marker stays in the persisted turn for the\n * model; hosts split it off to show a quiet \"stopped\" line instead of prose.\n */\n\nexport interface StreamFailure {\n /** The provider message, `''` when there is none (always for an abort). */\n message: string\n /** Text had streamed before the stream ended. */\n midOutput: boolean\n /** The user stopped the run; not a failure of the provider. */\n aborted: boolean\n}\n\nconst FAILED = /(?:^|\\n\\n)\\[✗ Streaming failed (before any output|mid-output)(?:: ([\\s\\S]*))?\\.?\\]\\s*$/\nconst ABORTED = /(?:^|\\n\\n)\\[⏹ Streaming was aborted\\.\\]\\s*$/\n\n/** Split a reply into what the model wrote and the stop marker at its end, if any. */\nexport function splitStreamFailure(text: string): { text: string, failure: StreamFailure | null } {\n const aborted = ABORTED.exec(text)\n if (aborted) {\n const before = text.slice(0, aborted.index).trimEnd()\n return { text: before, failure: { message: '', midOutput: before !== '', aborted: true } }\n }\n const m = FAILED.exec(text)\n if (!m)\n return { text, failure: null }\n return {\n text: text.slice(0, m.index).trimEnd(),\n failure: { message: (m[2] ?? '').trim(), midOutput: m[1] === 'mid-output', aborted: false },\n }\n}\n\n/** Cheap pre-check before splitting: the text may end in a stop marker. */\nexport function mayHaveStreamFailure(text: string): boolean {\n return text.includes('[✗ Streaming failed') || text.includes('[⏹ Streaming was aborted')\n}\n\n/** What the \"continue\" action sends after a run that had done work. */\nexport const CONTINUE_PROMPT = 'Continue from where you stopped.'\n","/**\n * Output throughput for the live run readout (`41 tok/s`), from the turn's\n * `stream:progress` samples.\n *\n * `tokens / elapsed since the request` was wrong in two ways that produced\n * absurd rates: the count mid-stream is an estimate from the visible text,\n * then jumps to the provider's real figure right before the stream ends\n * (for Anthropic that includes hidden reasoning, often many times the\n * estimate), so the division reported that correction as throughput; and\n * the denominator included the time to first token, so early readings\n * swung. Here the rate is tokens GAINED per second over a short trailing\n * window of samples: a correction (the estimate→provider snap, or a count\n * that goes backwards) rebases the window instead of counting, readings\n * are smoothed, and anything no model can produce is dropped.\n */\n\nexport interface RateSample {\n turnId: string\n /** ms since the turn's request; only differences are used. */\n elapsedMs: number\n outputTokens: number\n estimated: boolean\n}\n\nexport interface RateState {\n turnId: string | null\n /** Samples inside the window, oldest first; the first is the baseline. */\n samples: readonly { t: number, n: number }[]\n estimated: boolean | null\n /** Smoothed tokens/second, `null` until the window has enough span. */\n rate: number | null\n}\n\nexport const EMPTY_RATE: RateState = { turnId: null, samples: [], estimated: null, rate: null }\n\n/** Trailing window the rate is measured over. */\nconst WINDOW_MS = 3000\n/** Minimum span before a reading counts: shorter spans are one or two ticks of noise. */\nconst MIN_SPAN_MS = 1200\n/** Faster than any served model today (the fastest wafer-scale ones run ~3k): a reading above is a glitch. */\nexport const MAX_PLAUSIBLE_RATE = 6000\n/** Weight of a new reading in the smoothed rate. */\nconst SMOOTHING = 0.35\n\nexport function stepStreamRate(state: RateState, sample: RateSample): RateState {\n const point = { t: sample.elapsedMs, n: sample.outputTokens }\n if (state.turnId !== sample.turnId) {\n return { turnId: sample.turnId, samples: [point], estimated: sample.estimated, rate: null }\n }\n const last = state.samples[state.samples.length - 1]\n // A correction, not throughput: the provider's count replaced the estimate,\n // or the count went backwards. Rebase on this sample, keep the last rate.\n const corrected\n = (state.estimated === true && !sample.estimated) || (last !== undefined && point.n < last.n) || !last\n if (corrected) {\n return { ...state, samples: [point], estimated: sample.estimated }\n }\n if (point.t <= last.t)\n return state // out-of-order or duplicate tick\n\n // Keep the window, plus the newest sample older than it as the baseline.\n const kept = [...state.samples, point]\n let start = 0\n while (start < kept.length - 2 && kept[start + 1]!.t <= point.t - WINDOW_MS)\n start++\n const samples = kept.slice(start)\n\n const base = samples[0]!\n const span = point.t - base.t\n let rate = state.rate\n if (span >= MIN_SPAN_MS) {\n const reading = ((point.n - base.n) / span) * 1000\n if (reading >= 0 && reading <= MAX_PLAUSIBLE_RATE) {\n rate = rate === null ? reading : rate + SMOOTHING * (reading - rate)\n }\n }\n return { turnId: state.turnId, samples, estimated: sample.estimated, rate }\n}\n\n/** Whole tokens per second for display, or `null` when there is no honest reading. */\nexport function streamRateValue(state: RateState): number | null {\n if (state.rate === null)\n return null\n const rounded = Math.round(state.rate)\n return rounded > 0 ? rounded : null\n}\n","/**\n * User-initiated todo-list edits — pure transforms over `TodoItem[]`.\n *\n * The todo list is normally MODEL-owned: `todowrite` passes the full array on\n * every call, so a checkpoint replaces whatever was there. These transforms let\n * the TUI's `ctrl+t` panel edit the same list, with one consequence the UI must\n * surface rather than hide: **a user edit made during a live run is overwritten\n * by the agent's next checkpoint**. Nothing here can prevent that — it is the\n * tool's contract — so the modal warns while a run is in flight instead of\n * pretending the edit is durable.\n *\n * Kept pure and renderer-agnostic (no React, no node) so the reducers are\n * unit-testable and a GUI shell can drive the same edits.\n */\n\nimport type { TodoItem, TodoStatus } from './todos'\n\n/**\n * Prefix for ids minted here, distinguishing user-authored rows from the\n * model's own ids in a session file. Purely diagnostic — nothing branches on\n * it — but it makes \"who added this\" answerable after the fact.\n */\nconst USER_TODO_ID_PREFIX = 'user-'\n\n/**\n * Mint an id that cannot collide with an existing row.\n *\n * Counter-based rather than random: a stable, readable id keeps session diffs\n * legible, and the collision check makes it safe against ids the model already\n * used (including previous `user-*` ones after a reload).\n */\nexport function nextTodoId(items: readonly TodoItem[]): string {\n const taken = new Set(items.map(i => i.id))\n for (let n = 1; ; n++) {\n const id = `${USER_TODO_ID_PREFIX}${n}`\n if (!taken.has(id))\n return id\n }\n}\n\n/**\n * Append a todo. Returns the list unchanged when `content` is blank — an empty\n * row is never what the user meant, and rejecting it here means every caller\n * (keyboard, click, future GUI) gets the same guard.\n */\nexport function addTodo(items: readonly TodoItem[], content: string): TodoItem[] {\n const trimmed = content.trim()\n if (!trimmed)\n return [...items]\n return [...items, { id: nextTodoId(items), content: trimmed, status: 'pending' }]\n}\n\n/**\n * Replace one todo's text. Blank content is rejected (see {@link addTodo}); an\n * unknown id is a no-op rather than an error, because the list can be replaced\n * by a `todowrite` between render and keypress.\n */\nexport function editTodo(items: readonly TodoItem[], id: string, content: string): TodoItem[] {\n const trimmed = content.trim()\n if (!trimmed)\n return [...items]\n return items.map(item => item.id === id ? { ...item, content: trimmed } : item)\n}\n\n/** Drop one todo. Unknown id is a no-op, same rationale as {@link editTodo}. */\nexport function removeTodo(items: readonly TodoItem[], id: string): TodoItem[] {\n return items.filter(item => item.id !== id)\n}\n\n/** Drop everything. Separate from `removeTodo` so the caller's intent is explicit at the call site. */\nexport function clearTodos(): TodoItem[] {\n return []\n}\n\n/**\n * Advance a todo's status one step: pending → in_progress → completed →\n * pending. `cancelled` also lands on `pending`, so a dropped item can be\n * revived without a dedicated key.\n *\n * Cycling INTO `in_progress` demotes any other in-progress row to `pending`:\n * the list's whole purpose is \"what is being worked on right now\", and two\n * live rows make that unanswerable — `TodoIndicator`'s successor\n * (`todoProgressLabel`) reads the first one and would silently ignore the rest.\n */\nexport function cycleTodoStatus(items: readonly TodoItem[], id: string): TodoItem[] {\n const target = items.find(item => item.id === id)\n if (!target)\n return [...items]\n const next = nextStatus(target.status)\n return items.map((item) => {\n if (item.id === id)\n return { ...item, status: next }\n if (next === 'in_progress' && item.status === 'in_progress')\n return { ...item, status: 'pending' as TodoStatus }\n return item\n })\n}\n\nfunction nextStatus(status: TodoStatus): TodoStatus {\n switch (status) {\n case 'pending':\n return 'in_progress'\n case 'in_progress':\n return 'completed'\n case 'completed':\n case 'cancelled':\n default:\n return 'pending'\n }\n}\n\n/**\n * Steering text for a \"retry this todo\" request.\n *\n * Quotes the content so a model reading it can match the row verbatim against\n * its own list, and names the status because \"retry\" means different things\n * for a row it believes is `completed` versus one it abandoned as `cancelled`.\n * Shared by the TUI and GUI modals so both surfaces steer with byte-identical\n * text; pinned by a test rather than living inside a JSX callback.\n */\nexport function buildTodoRetryMessage(item: TodoItem): string {\n return `Retry this todo (currently ${item.status}): \"${item.content}\"`\n}\n"],"mappings":"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"}
|