zidane 9.1.1 → 9.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-Di9WvMDF.js → acp-CeCavNlg.js} +7 -7
- package/dist/{acp-Di9WvMDF.js.map → acp-CeCavNlg.js.map} +1 -1
- package/dist/acp-cli.js +5 -5
- package/dist/acp.d.ts +2 -2
- package/dist/acp.js +1 -1
- package/dist/{agent-DJhpTS-B.js → agent-Dh_XZ7fj.js} +74 -19
- package/dist/agent-Dh_XZ7fj.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/{auth-store-port-DFgf22oo.js → auth-store-port-BKpjlJ8a.js} +2 -2
- package/dist/{auth-store-port-DFgf22oo.js.map → auth-store-port-BKpjlJ8a.js.map} +1 -1
- package/dist/{auto-update-restart-BFB7Ek87.js → auto-update-restart-CQJtndMG.js} +277 -41
- package/dist/auto-update-restart-CQJtndMG.js.map +1 -0
- package/dist/{browser-BcoCCB_n.js → browser-BkdeKnxO.js} +56 -2
- package/dist/browser-BkdeKnxO.js.map +1 -0
- package/dist/{browser-entry-ypi8CyE-.d.ts → browser-entry-BCwruqNa.d.ts} +10 -10
- package/dist/{browser-entry-ypi8CyE-.d.ts.map → browser-entry-BCwruqNa.d.ts.map} +1 -1
- package/dist/channels.d.ts +5 -5
- package/dist/chat/browser.d.ts +4 -4
- package/dist/chat/browser.js +6 -6
- package/dist/chat/pure.d.ts +5 -5
- package/dist/chat/pure.js +8 -8
- package/dist/chat.d.ts +5 -5
- package/dist/chat.js +55 -55
- package/dist/chat.js.map +1 -1
- package/dist/{cli-shared-CabruH8Z.js → cli-shared-DeRHgYvl.js} +4 -4
- package/dist/{cli-shared-CabruH8Z.js.map → cli-shared-DeRHgYvl.js.map} +1 -1
- package/dist/cli-style-DBEm6CyT.js +105 -0
- package/dist/cli-style-DBEm6CyT.js.map +1 -0
- package/dist/{client-core-CIixwznM.d.ts → client-core-C_4m_oL6.d.ts} +4 -4
- package/dist/{client-core-CIixwznM.d.ts.map → client-core-C_4m_oL6.d.ts.map} +1 -1
- package/dist/{client-CCaIXWue.d.ts → client-ygTASGis.d.ts} +2 -2
- package/dist/{client-CCaIXWue.d.ts.map → client-ygTASGis.d.ts.map} +1 -1
- package/dist/codemode-worker.js +8 -5
- package/dist/codemode-worker.js.map +1 -1
- package/dist/codemode.d.ts +16 -0
- package/dist/codemode.d.ts.map +1 -1
- package/dist/codemode.js +2 -2
- package/dist/{connection-loop-QmWL-fJf.d.ts → connection-loop-D_pRONCr.d.ts} +4 -4
- package/dist/{connection-loop-QmWL-fJf.d.ts.map → connection-loop-D_pRONCr.d.ts.map} +1 -1
- package/dist/contexts/daytona.d.ts +3 -3
- package/dist/contexts/docker.d.ts +1 -1
- package/dist/contexts/e2b.d.ts +2 -2
- package/dist/contexts/sandbox.d.ts +1 -1
- package/dist/{contexts-C72b0mMa.js → contexts-DLZTSRHU.js} +17 -106
- package/dist/contexts-DLZTSRHU.js.map +1 -0
- package/dist/contexts.d.ts +4 -4
- package/dist/contexts.js +2 -2
- package/dist/{credentials-wwETW8rI.js → credentials-Bqg-qNBM.js} +2 -2
- package/dist/{credentials-wwETW8rI.js.map → credentials-Bqg-qNBM.js.map} +1 -1
- package/dist/{cwd-picker-CcekODCt.js → cwd-picker-BsHA6HKv.js} +4 -4
- package/dist/{cwd-picker-CcekODCt.js.map → cwd-picker-BsHA6HKv.js.map} +1 -1
- package/dist/daemon-cli.js +4 -3
- package/dist/daemon-cli.js.map +1 -1
- package/dist/{decisions-CXmK0nz9.js → decisions-hsw5XS2g.js} +3 -1
- package/dist/decisions-hsw5XS2g.js.map +1 -0
- package/dist/{discovery-DycXFxdA.js → discovery-CX7nbMCn.js} +4 -4
- package/dist/{discovery-DycXFxdA.js.map → discovery-CX7nbMCn.js.map} +1 -1
- package/dist/durable/sqlite.d.ts +2 -2
- package/dist/durable.d.ts +1 -1
- package/dist/{engine-VQ86XGdG.js → engine-CxBGgU94.js} +6 -6
- package/dist/{engine-VQ86XGdG.js.map → engine-CxBGgU94.js.map} +1 -1
- package/dist/{eval-Bod0I1W_.js → eval-CfGUDAkN.js} +3 -3
- package/dist/{eval-Bod0I1W_.js.map → eval-CfGUDAkN.js.map} +1 -1
- package/dist/eval.d.ts +1 -1
- package/dist/eval.js +1 -1
- package/dist/{executor-C7RQrkEq.js → executor-j_LFRBwS.js} +4 -4
- package/dist/{executor-C7RQrkEq.js.map → executor-j_LFRBwS.js.map} +1 -1
- package/dist/{extension-mark-BqKdEZwF.js → extension-mark-_rhkDWL5.js} +9 -6
- package/dist/extension-mark-_rhkDWL5.js.map +1 -0
- package/dist/extensions/testing.d.ts +1 -1
- package/dist/extensions/testing.js +2 -2
- package/dist/{extensions-BCx4QuGB.js → extensions-ADlhBQ_1.js} +8 -8
- package/dist/{extensions-BCx4QuGB.js.map → extensions-ADlhBQ_1.js.map} +1 -1
- package/dist/{extensions-client-D8tEAcMw.d.ts → extensions-client-D4Q2XRKV.d.ts} +31 -5
- package/dist/extensions-client-D4Q2XRKV.d.ts.map +1 -0
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +6 -6
- package/dist/{fold-rules-DvLK8pbf.d.ts → fold-rules-1DpDwG9h.d.ts} +2 -2
- package/dist/{fold-rules-DvLK8pbf.d.ts.map → fold-rules-1DpDwG9h.d.ts.map} +1 -1
- package/dist/{google-Crva32sk.js → google-B-Dhmzzf.js} +2 -2
- package/dist/{google-Crva32sk.js.map → google-B-Dhmzzf.js.map} +1 -1
- package/dist/{headless-CCm-jLLT.js → headless-CQm19BL0.js} +4 -4
- package/dist/{headless-CCm-jLLT.js.map → headless-CQm19BL0.js.map} +1 -1
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -1
- package/dist/history-worker.js +1 -1
- package/dist/{host-wO_6GW0y.js → host-C61ntFBC.js} +276 -103
- package/dist/host-C61ntFBC.js.map +1 -0
- package/dist/{host-BHMs9jsN.js → host-DEoEzQal.js} +13 -4
- package/dist/host-DEoEzQal.js.map +1 -0
- package/dist/{host-scoped-settings-CrbcqOkP.js → host-scoped-settings-WBYaCork.js} +2 -2
- package/dist/{host-scoped-settings-CrbcqOkP.js.map → host-scoped-settings-WBYaCork.js.map} +1 -1
- package/dist/{host-signals-Jsjd_-4g.js → host-signals-Cb2TlGtN.js} +5 -5
- package/dist/{host-signals-Jsjd_-4g.js.map → host-signals-Cb2TlGtN.js.map} +1 -1
- package/dist/{host-version-CNAr9pov.js → host-version-BIx4CuBM.js} +2 -2
- package/dist/{host-version-CNAr9pov.js.map → host-version-BIx4CuBM.js.map} +1 -1
- package/dist/{index-C6nnKu32.d.ts → index-B0PLo9jn.d.ts} +4 -4
- package/dist/{index-C6nnKu32.d.ts.map → index-B0PLo9jn.d.ts.map} +1 -1
- package/dist/{index-Djnc8Peh.d.ts → index-De4x-s76.d.ts} +14 -14
- package/dist/{index-Djnc8Peh.d.ts.map → index-De4x-s76.d.ts.map} +1 -1
- package/dist/{index-CGbOWa7y.d.ts → index-WlE93Q6d.d.ts} +411 -3
- package/dist/index-WlE93Q6d.d.ts.map +1 -0
- package/dist/{index-CCf_WeTQ.d.ts → index-f-XWIoYo.d.ts} +2 -2
- package/dist/{index-CCf_WeTQ.d.ts.map → index-f-XWIoYo.d.ts.map} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +17 -17
- package/dist/ipc/browser-types.d.ts +304 -7
- package/dist/ipc/browser-types.d.ts.map +1 -1
- package/dist/ipc/browser.d.ts +4 -4
- package/dist/ipc/browser.js +2 -2
- package/dist/ipc/remote.d.ts +6 -6
- package/dist/ipc/remote.js +3 -3
- package/dist/{ipc-BzWhIybr.js → ipc-DiH_P-wr.js} +4 -4
- package/dist/{ipc-BzWhIybr.js.map → ipc-DiH_P-wr.js.map} +1 -1
- package/dist/ipc.d.ts +10 -10
- package/dist/ipc.js +8 -8
- package/dist/{json-Dj-YATkZ.js → json-BjClr43H.js} +2 -20
- package/dist/json-BjClr43H.js.map +1 -0
- package/dist/{links-CJG_rFvf.js → links-BbC_lOnn.js} +9 -9
- package/dist/{links-CJG_rFvf.js.map → links-BbC_lOnn.js.map} +1 -1
- package/dist/{loaded-entry-DTURJo_R.js → loaded-entry-C0vkCVNQ.js} +2 -2
- package/dist/{loaded-entry-DTURJo_R.js.map → loaded-entry-C0vkCVNQ.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/{media-type-BtA0cbfI.d.ts → media-type-ZSmAGHvg.d.ts} +188 -7
- package/dist/media-type-ZSmAGHvg.d.ts.map +1 -0
- package/dist/{memory-DuVGrzbl.js → memory-C3w8nO8f.js} +132 -31
- package/dist/memory-C3w8nO8f.js.map +1 -0
- package/dist/model-test-CAtJ76kM.js.map +1 -1
- package/dist/{move-session-kylExJ5H.js → move-session-D7ILECs-.js} +4 -4
- package/dist/{move-session-kylExJ5H.js.map → move-session-D7ILECs-.js.map} +1 -1
- package/dist/{nested-call-record-DlzPeTB7.js → nested-call-record-OayszZBQ.js} +4 -3
- package/dist/nested-call-record-OayszZBQ.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -1
- package/dist/output/terminal.d.ts +1 -1
- package/dist/{path-display-COVV71Yu.js → path-display-DRAEpKOU.js} +3 -3
- package/dist/{path-display-COVV71Yu.js.map → path-display-DRAEpKOU.js.map} +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/{prelude-CVKoUzV8.js → prelude-BwiSR1uA.js} +16 -5
- package/dist/prelude-BwiSR1uA.js.map +1 -0
- package/dist/{presets-CBt6rFfS.js → presets-CMY43nUP.js} +3 -3
- package/dist/{presets-CBt6rFfS.js.map → presets-CMY43nUP.js.map} +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/{protocol-CEVqBO-q.d.ts → protocol-C2lqKuMd.d.ts} +50 -7
- package/dist/protocol-C2lqKuMd.d.ts.map +1 -0
- package/dist/protocol-DOGyHgLQ.js.map +1 -1
- package/dist/protocol-NSllElLw.js.map +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/google.d.ts +1 -1
- package/dist/providers/google.js +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/neuralwatt.d.ts +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/{providers-Z0TaBp1O.js → providers-CpXV_uLE.js} +5 -5
- package/dist/providers-CpXV_uLE.js.map +1 -0
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +1 -1
- package/dist/{readonly-db-D7Z-k0pQ.js → readonly-db-DrbT8tX6.js} +2 -2
- package/dist/{readonly-db-D7Z-k0pQ.js.map → readonly-db-DrbT8tX6.js.map} +1 -1
- package/dist/{registry-BKjeBnoy.js → registry-CJHvmvaP.js} +2 -2
- package/dist/{registry-BKjeBnoy.js.map → registry-CJHvmvaP.js.map} +1 -1
- package/dist/{registry-B6Ww76iW.js → registry-CN6JlZKj.js} +2 -2
- package/dist/{registry-B6Ww76iW.js.map → registry-CN6JlZKj.js.map} +1 -1
- package/dist/{registry-B9INJwJR.js → registry-CnnKaY9s.js} +324 -39
- package/dist/registry-CnnKaY9s.js.map +1 -0
- package/dist/{remote-hosts-BMWoHCWO.js → remote-hosts-DoO9CJUQ.js} +4 -4
- package/dist/{remote-hosts-BMWoHCWO.js.map → remote-hosts-DoO9CJUQ.js.map} +1 -1
- package/dist/{repo-url-D4Dr8NfZ.js → repo-url-DLjjuVk_.js} +169 -2
- package/dist/repo-url-DLjjuVk_.js.map +1 -0
- package/dist/restate.d.ts +2 -2
- package/dist/{sandbox-BwiPGKF7.d.ts → sandbox-B4OW6oNx.d.ts} +2 -2
- package/dist/{sandbox-BwiPGKF7.d.ts.map → sandbox-B4OW6oNx.d.ts.map} +1 -1
- package/dist/script-progress-CrZ507Qq.js +900 -0
- package/dist/script-progress-CrZ507Qq.js.map +1 -0
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/{setting-BQBSyUq0.js → setting-D_FpKFMw.js} +6 -6
- package/dist/{setting-BQBSyUq0.js.map → setting-D_FpKFMw.js.map} +1 -1
- package/dist/{settings-catalog-4IU2i_jG.js → settings-catalog-DEZlXP51.js} +14 -2
- package/dist/settings-catalog-DEZlXP51.js.map +1 -0
- package/dist/{settings-keys-iI_Y-7MC.js → settings-keys-CW2UgHgb.js} +3 -3
- package/dist/{settings-keys-iI_Y-7MC.js.map → settings-keys-CW2UgHgb.js.map} +1 -1
- package/dist/{skills-CFXRItJ6.js → skills-CEbosUlM.js} +2 -2
- package/dist/{skills-CFXRItJ6.js.map → skills-CEbosUlM.js.map} +1 -1
- package/dist/skills.d.ts +1 -1
- package/dist/skills.js +1 -1
- package/dist/{source-Bl1Z501r.js → source-3ZnEPOSa.js} +3 -2
- package/dist/source-3ZnEPOSa.js.map +1 -0
- package/dist/{sqlite-runtime-BZ2L4RaG.d.ts → sqlite-runtime-CS_LBaAN.d.ts} +2 -2
- package/dist/sqlite-runtime-CS_LBaAN.d.ts.map +1 -0
- package/dist/{src-BY_ND2xn.js → src-BmTXDta8.js} +2 -2
- package/dist/{src-BY_ND2xn.js.map → src-BmTXDta8.js.map} +1 -1
- package/dist/{store-C6gI7FfZ.js → store-ByCDaKgJ.js} +14 -3
- package/dist/store-ByCDaKgJ.js.map +1 -0
- package/dist/{system-freeze-m5o1sGIM.js → system-freeze-XgDPIwQS.js} +3 -3
- package/dist/{system-freeze-m5o1sGIM.js.map → system-freeze-XgDPIwQS.js.map} +1 -1
- package/dist/{todo-edits-CbukbjyV.js → todo-edits-Dyj32ds6.js} +4 -3
- package/dist/todo-edits-Dyj32ds6.js.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -1
- package/dist/tools/web-search.d.ts +1 -1
- package/dist/{tools-CVTGhggj.js → tools-BsrGQ8K4.js} +2 -2
- package/dist/{tools-CVTGhggj.js.map → tools-BsrGQ8K4.js.map} +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +3 -3
- package/dist/{transcript-anchors-CiSi_UBn.js → transcript-anchors-DMjvyUjk.js} +3 -3
- package/dist/{transcript-anchors-CiSi_UBn.js.map → transcript-anchors-DMjvyUjk.js.map} +1 -1
- package/dist/{transcript-reconcile-jbSBjLq2.js → transcript-reconcile-DpQO85wl.js} +3 -3
- package/dist/{transcript-reconcile-jbSBjLq2.js.map → transcript-reconcile-DpQO85wl.js.map} +1 -1
- package/dist/tui.d.ts +9 -9
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +289 -38
- package/dist/tui.js.map +1 -1
- package/dist/{types-bDQagoiL.d.ts → types-2HrgolQz.d.ts} +20 -8
- package/dist/types-2HrgolQz.d.ts.map +1 -0
- package/dist/types-4q1bFG53.js +122 -0
- package/dist/types-4q1bFG53.js.map +1 -0
- package/dist/{types-DnRd9_cA.d.ts → types-SXqk6hLD.d.ts} +3 -3
- package/dist/{types-DnRd9_cA.d.ts.map → types-SXqk6hLD.d.ts.map} +1 -1
- package/dist/types-myxheQkw.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/{usage-summary-BfcXjiSM.js → usage-summary-BM7B3JdI.js} +2 -2
- package/dist/{usage-summary-BfcXjiSM.js.map → usage-summary-BM7B3JdI.js.map} +1 -1
- package/dist/{version-DqqqvHDP.js → version-szdW1Od9.js} +2 -2
- package/dist/{version-DqqqvHDP.js.map → version-szdW1Od9.js.map} +1 -1
- package/dist/{wait-task-BX4NcOOm.js → wait-task-BiI5UaZQ.js} +13 -3
- package/dist/wait-task-BiI5UaZQ.js.map +1 -0
- package/dist/{wire-CLm2rMK0.js → wire-C3l9jl9x.js} +2 -2
- package/dist/{wire-CLm2rMK0.js.map → wire-C3l9jl9x.js.map} +1 -1
- package/dist/{write-file-0E6TUJ9A.js → write-file-Dquu7MzB.js} +5 -3
- package/dist/write-file-Dquu7MzB.js.map +1 -0
- package/dist/{ws-DfGGYQ4W.js → ws-CEHi0CiB.js} +4 -4
- package/dist/{ws-DfGGYQ4W.js.map → ws-CEHi0CiB.js.map} +1 -1
- package/dist/{ws-client-CFMbhsNq.js → ws-client-t8XNWxcq.js} +2 -2
- package/dist/{ws-client-CFMbhsNq.js.map → ws-client-t8XNWxcq.js.map} +1 -1
- package/docs/CHAT.md +55 -0
- package/docs/CODEMODE.md +37 -0
- package/docs/EXTENSIONS.md +8 -6
- package/docs/RELEASE-NOTES-NEXT.md +48 -1
- package/docs/RELEASE.md +9 -1
- package/package.json +2 -3
- package/dist/agent-DJhpTS-B.js.map +0 -1
- package/dist/auto-update-restart-BFB7Ek87.js.map +0 -1
- package/dist/browser-BcoCCB_n.js.map +0 -1
- package/dist/contexts-C72b0mMa.js.map +0 -1
- package/dist/decisions-CXmK0nz9.js.map +0 -1
- package/dist/extension-mark-BqKdEZwF.js.map +0 -1
- package/dist/extensions-client-D8tEAcMw.d.ts.map +0 -1
- package/dist/host-BHMs9jsN.js.map +0 -1
- package/dist/host-wO_6GW0y.js.map +0 -1
- package/dist/index-CGbOWa7y.d.ts.map +0 -1
- package/dist/json-Dj-YATkZ.js.map +0 -1
- package/dist/media-type-BtA0cbfI.d.ts.map +0 -1
- package/dist/memory-DuVGrzbl.js.map +0 -1
- package/dist/nested-call-events-BYk8XvGX.js +0 -182
- package/dist/nested-call-events-BYk8XvGX.js.map +0 -1
- package/dist/nested-call-record-DlzPeTB7.js.map +0 -1
- package/dist/prelude-CVKoUzV8.js.map +0 -1
- package/dist/protocol-CEVqBO-q.d.ts.map +0 -1
- package/dist/providers-Z0TaBp1O.js.map +0 -1
- package/dist/registry-B9INJwJR.js.map +0 -1
- package/dist/repo-url-D4Dr8NfZ.js.map +0 -1
- package/dist/settings-catalog-4IU2i_jG.js.map +0 -1
- package/dist/source-Bl1Z501r.js.map +0 -1
- package/dist/sqlite-runtime-BZ2L4RaG.d.ts.map +0 -1
- package/dist/store-C6gI7FfZ.js.map +0 -1
- package/dist/todo-edits-CbukbjyV.js.map +0 -1
- package/dist/types-DTMEhKJO.js +0 -14
- package/dist/types-DTMEhKJO.js.map +0 -1
- package/dist/types-bDQagoiL.d.ts.map +0 -1
- package/dist/wait-task-BX4NcOOm.js.map +0 -1
- package/dist/write-file-0E6TUJ9A.js.map +0 -1
- package/scripts/eval.ts +0 -179
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-DOGyHgLQ.js","names":[],"sources":["../src/ipc/protocol.ts"],"sourcesContent":["/**\n * zidane/ipc wire protocol — the transport-agnostic contract between a chat\n * host (the process that owns live `Agent` instances) and its clients (GUI\n * renderer, TUI window, `zidane attach`, …).\n *\n * The host-domain shapes (the `HostSignal` push union and everything it\n * carries) live in `src/chat/host/signals.ts` — the host must not depend on\n * `src/ipc/**`. This module re-exports them unchanged and adds the\n * transport-only contract: the typed JSON-RPC method map, session rows, and\n * the daemon handshake.\n *\n * Everything in this file is JSON-serializable: it must survive Electron's\n * structured clone AND a JSON-RPC socket hop unchanged. Canonical agent\n * types (`StreamEvent`, `InteractionRequest`, …) are re-used where they are\n * already wire-safe; host-only shapes (live `resolve` callbacks, `Map`s)\n * never appear here.\n *\n * Versioning: bump `IPC_PROTOCOL_VERSION` on any breaking change to the\n * signal union or the method map. The daemon handshake refuses mismatched\n * peers so a stale daemon never talks to an upgraded client (see\n * `daemon/lifecycle.ts`).\n */\nimport type { BrowserResponse } from '../chat/browser/protocol'\nimport type { HostCapabilities } from '../chat/capabilities'\nimport type { ClaudeImportSummary } from '../chat/claude-import'\nimport type { CommandOutputBlock } from '../chat/commands'\nimport type { ProviderFieldView } from '../chat/credentials'\nimport type { EnvironmentActionResult, EnvironmentActionSummary, EnvironmentRequest, EnvironmentTeardownResult, EnvironmentVerifyResult } from '../chat/environment'\nimport type { EnvironmentDescriptor, EnvironmentSettingsChange } from '../chat/environment-settings'\nimport type { ExtensionSourceListing } from '../chat/extension-sources'\nimport type { FileEntry } from '../chat/files-discovery'\nimport type { GitBranchRow, GitCommitInfo, GitInfo, GitPr, GitPrListResult, GitSwitchTarget, GitSyncResult, RepoCloneResult } from '../chat/git/types'\nimport type { CompactionReport } from '../chat/host/compaction'\nimport type { CacheImpact, CacheImpactChange, CacheReport, ContextSegmentsReport, WorkspaceListFilesOptions } from '../chat/host/engine'\nimport type {\n CatalogItemProvenance,\n CatalogKind,\n CommandRunParams,\n LinkOpenParams,\n SettingsSetParams,\n UiClientAnnounce,\n UiInvokeRequest,\n WireExtensionCommands,\n WireExtensionEntry,\n WireExtensionSettings,\n WireIntegration,\n WireKeymap,\n WireStorageLocation,\n WireStorageSetResult,\n WireUiList,\n} from '../chat/host/extensions-wire'\nimport type { SessionLaunchOverrides } from '../chat/host/launch-overrides'\nimport type {\n CreateSessionParams as OrchestrationCreateParams,\n EventQuery as OrchestrationEventQuery,\n PendingRequestRow as OrchestrationPendingRequest,\n WaitResult as OrchestrationWaitResult,\n WorkerRow as OrchestrationWorkerRow,\n WorkerSummary as OrchestrationWorkerSummary,\n} from '../chat/host/orchestration'\nimport type {\n CommandArgSuggestionSummary,\n CommandSummary,\n HostSettings,\n HostSignal,\n PendingInteraction,\n PromptAttachment,\n QueuedItem,\n RunningWorkItem,\n SendOptions,\n SessionPresence,\n TodosSnapshot,\n WireApprovalRequest,\n} from '../chat/host/signals'\nimport type {\n ApprovalDecision,\n ContextBreakdown,\n InteractionResponse,\n ProviderKey,\n SearchTurnResult,\n SessionEnvironmentSummary,\n SessionHeader,\n SessionHistoryMatch,\n SessionMeta,\n StreamEvent,\n SystemMdFile,\n TodoItem,\n} from '../chat/index'\nimport type { IntegrationInfo, IntegrationState } from '../chat/integrations'\nimport type { MachineInfo, MachineLinksStatus, MachineRegisterParams } from '../chat/machine-protocol'\nimport type { McpServerStatus } from '../chat/mcp-status'\nimport type { OnboardingDetection, OnboardingImportPreview, OnboardingProvider, OnboardingSettingsChange, OnboardingState } from '../chat/onboarding/types'\nimport type { SessionEvent } from '../chat/orchestration'\nimport type { PaletteContext, PaletteItem, PaletteRunResult } from '../chat/palette'\nimport type { FolderLocation } from '../chat/project-root'\nimport type { ProviderUsageSnapshot } from '../chat/provider-usage-format'\nimport type { RunEstimateView } from '../chat/run-estimate'\nimport type { SafelistProject } from '../chat/safe-mode'\nimport type { ServerUpdateStatus } from '../chat/server-update'\nimport type { SessionExportFormat } from '../chat/session-export'\nimport type { SessionPolicy } from '../chat/session-policy'\nimport type { TuiState } from '../chat/store'\nimport type { SyncCategory, SyncClaimResult, SyncPayload, SyncPushResult, SyncStatus } from '../chat/sync/types'\nimport type { TerminalAdoptResult, TerminalAttachResult, TerminalInfo, TerminalOpenInput, TerminalProjectOpenInput, TerminalProjectState, TerminalProjectStateInput, TerminalSessionState } from '../chat/terminal/protocol'\nimport type { UsageRange, UsageSummary } from '../chat/usage-summary'\nimport type { DiagnosticsResult, DiagnosticsToolInfo } from '../chat/workspace/diagnostics/types'\nimport type { EntryResult } from '../chat/workspace/entries'\nimport type { ContentSearchResult } from '../chat/workspace/search'\nimport type { GitStatusEntry, ResolvedPath } from '../chat/workspace/types'\nimport type { OwnedProcess } from '../contexts/owned-processes'\nimport type { SessionProcess } from '../contexts/session-processes'\nimport type { ExecResult, ListFilesEntry } from '../contexts/types'\nimport type { CreateExtensionInput, CreateExtensionResult } from '../extension-authoring'\nimport type { Json } from '../extensions/api/storage'\nimport type {\n BadgeActionEffect,\n BadgeMenuItem,\n BadgeTarget,\n ExtensionActionRunResult,\n ExtensionActionSummary,\n ExtensionCompletionItemSummary,\n ExtensionCompletionProviderSummary,\n ExtensionConfigActionStatus,\n ExtensionReferenceView,\n PanelContent,\n PanelLoadContextInput,\n PanelSummary,\n ReferenceProviderWire,\n SessionBadgeEntry,\n WireExtensionConfigSchema,\n} from '../extensions/index'\nimport type { ExtensionInstallOrigin } from '../extensions/install'\nimport type { RpcCallParams, RpcResponseEnvelope } from '../extensions/rpc/wire'\nimport type { StorageArea, StorageSnapshot } from '../extensions/storage/port'\nimport type { LogRecord } from '../logger'\nimport type { McpServerInstance } from '../mcp/server-pool'\nimport type { PerfOsThread, PerfSample } from '../perf/types'\nimport type { SessionArtifact } from '../session/artifacts'\nimport type { SessionData } from '../session/index'\nimport type { SkillSourceListing } from '../skills/sources'\nimport type { JsonValue, McpServerConfig, SessionTurn, ThinkingLevel } from '../types'\nimport type { ClientScope } from './scopes'\nimport { isMethodNotFound } from '../chat/hosts/connection'\n\nexport type { GitBranchRow, GitCommitInfo, GitInfo, GitPr, GitPrItem, GitPrListResult, GitSwitchTarget, GitSyncResult, RepoCloneResult, RepoProgress } from '../chat/git/types'\n\nexport type {\n CommandRunParams,\n DialogRequest,\n ExtensionsSignal,\n IntegrationFlowStep,\n LinkOpenParams,\n NavigateTarget,\n RpcEventEnvelope,\n SettingsSetParams,\n UiChange,\n UiClientAnnounce,\n UiClientRequest,\n UiInvokeRequest,\n UiSnapshot,\n WireComposerEdit,\n WireExtensionCommand,\n WireExtensionCommands,\n WireExtensionEntry,\n WireExtensionSettings,\n WireIntegration,\n WireIntegrationMethod,\n WireKeymap,\n WireStorageLocation,\n WireStorageSetResult,\n WireUiBundle,\n WireUiList,\n} from '../chat/host/extensions-wire'\n\nexport type {\n ApprovalOriginator,\n CommandArgSuggestionSummary,\n CommandSummary,\n DeliveryState,\n HostSettings,\n HostSignal,\n PendingInteraction,\n PromptAttachment,\n QueuedItem,\n RunningWorkItem,\n SendOptions,\n SerializedPreview,\n SessionPresence,\n TodosSnapshot,\n WireApprovalRequest,\n} from '../chat/host/signals'\n\nexport type { IntegrationInfo, IntegrationState } from '../chat/integrations'\n\n/** The machine protocol (`docs/MACHINES.md`), versioned on its own (`MACHINE_PROTOCOL_VERSION`). */\nexport {\n isValidMachineName,\n MACHINE_HOST_METHODS,\n MACHINE_IDEMPOTENT_METHODS,\n MACHINE_PROTOCOL_VERSION,\n MachineErrorCode,\n machineKind,\n parseMachineKind,\n} from '../chat/machine-protocol'\nexport type {\n MachineCapabilities,\n MachineHandleRef,\n MachineInfo,\n MachineMethodName,\n MachineMethods,\n MachineNotifications,\n MachineParams,\n MachineRegisterParams,\n MachineRegisterResult,\n MachineResult,\n MachineRoot,\n MachineStatusChange,\n} from '../chat/machine-protocol'\nexport type { ServerUpdateStatus, UpdateState } from '../chat/server-update'\nexport type { SessionExportFormat } from '../chat/session-export'\nexport type { Diagnostic, DiagnosticSeverity, DiagnosticsResult, DiagnosticsToolInfo } from '../chat/workspace/diagnostics/types'\nexport type { EntryRefusal, EntryResult } from '../chat/workspace/entries'\nexport type { ContentMatch, ContentSearchResult } from '../chat/workspace/search'\nexport type { GitStatusEntry, ResolvedPath } from '../chat/workspace/types'\n\n/**\n * Changes since v5. Entries marked additive, or \"no version bump\", did\n * not raise the version. The current version is `IPC_PROTOCOL_VERSION`.\n *\n * - `event` signals carry an optional `echo` flag marking host-generated\n * SEND/STEER echoes of the user's own message.\n * - `chat.pushQueued` result gained the `'queued'` delivered variant.\n * - `sessions.setModel` now honors `fallbacks`: it persists the canonical\n * `metadata.modelChain` and CLEARS a previously persisted chain when\n * omitted/empty. It also accepts `effort` / `modelOptions` and resets\n * both when omitted (a pick is atomic — no stale per-model knobs).\n * - additive: `extension.emit` notification + `extension:signal` fan-out\n * (the permission-gated per-extension cross-window bus, `ctx.bus`;\n * removed in zidane 10).\n * Older daemons ignore the unknown notification; older clients drop the\n * unknown signal kind — no version bump needed.\n * - additive: `extension.emit` / `extension:signal` carry an optional\n * `nonce` (the emitter's per-process random id) so receivers dedupe on\n * `(extensionId, nonce, seq)` instead of the collision-prone\n * `(extensionId, seq)`. Older peers omit it and fall back to the\n * seq-only key — no version bump needed.\n * - `SessionRow.modelFallbacks` is now populated from the session's\n * persisted `metadata.modelChain`.\n * - Default socket path moved from `<stateDir>/daemon.sock` to the\n * dedicated `<stateDir>/daemon/daemon.sock` (dir chmod'd 0700) so the\n * daemon can harden its socket dir without touching shared state files.\n * - ADDITIVE (no version bump — older daemons answer \"method not\n * found\", clients degrade to local compute): `suggest.resolve` RPC\n * resolves inline ghost-text autocomplete daemon-side, and the\n * `suggest:changed` signal fans the result out to every OTHER peer\n * on the session so mirroring windows paint the same ghost without\n * recomputing.\n * - ADDITIVE (no version bump — optional field, older daemons simply\n * omit it and clients fall back to the single `suggestion`):\n * `suggest.resolve` results and `suggest:changed` signals carry the\n * resolver's full ordered `candidates` list so daemon mode keeps\n * ↑/↓ candidate rotation instead of degrading to one suggestion.\n * - ADDITIVE (no version bump — `optional()` swallows \"method not\n * found\" on an older daemon, which then simply keeps its stale\n * registries as before): `runtime.reload` RPC drops the daemon's\n * cached extension registries and retires live agents after a window\n * reloaded its extensions.\n * - ADDITIVE (no version bump): `terminal.registerViewer` /\n * `terminal.unregisterViewer`. The desktop app registers as a client that\n * can show terminals; agents only get terminal tools while one is\n * attached. An older daemon answers \"method not found\" (and keeps giving\n * every agent the tools, as before); an older desktop app on a newer\n * daemon never registers, so its agents run without terminal tools.\n * - ADDITIVE (no version bump): project / draft terminals\n * (docs/PROJECT-SCOPE-AUDIT.md): `terminal.projectState`,\n * `terminal.openInProject`, `terminal.adopt`, `terminal.releaseDraft`,\n * the `terminal:project-changed` signal, and `HelloResult.projectTerminals`.\n * An older daemon answers \"method not found\" and omits the flag; clients\n * then offer terminals only in sessions.\n * - ADDITIVE (no version bump): `queue.attachments` returns a queued\n * entry's attachments with their bytes, and `queue.update` accepts\n * `attachments` to replace them. An older daemon answers \"method not\n * found\" / ignores the field: the entry's attachments stay as queued.\n * - ADDITIVE (no version bump): `chat.steer` / `chat.followUp` resolve to\n * whether the message reached a live run. Older daemons resolve `null`,\n * which clients treat as delivered (the pre-existing behavior).\n * - ADDITIVE (no version bump): `sessions.fork`, `sessions.deleteTurn`,\n * `sessions.editTurnText`, `sessions.setFolder`, `sessions.appendTurns`,\n * `sessions.rewind`.\n * History and folder edits run in the host instead of being written to\n * the store by the client (then `sessions.touch` + `chat.rebuildAgent`).\n * Older clients keep the old path, which still works on a shared disk.\n * A newer client only meets an older daemon while it retires (the\n * release fence drains it otherwise), and then gets \"method not found\".\n * - ADDITIVE (no version bump): `sessions.listMeta`, `sessions.getMeta`,\n * `sessions.get`, `sessions.setExtensionState` serve a client the\n * session data it used to read and write in its own store, so a window\n * on another machine sees the host's sessions. `sessions.create` accepts `effort`, `modelOptions` and\n * `pinnedSkills`; `todos.set` accepts `persistIdle`. An older host answers\n * \"method not found\" / ignores the fields: a window falls back to the\n * store it shares with a local daemon, and refuses a remote host.\n * - ADDITIVE (no version bump): `daemon.info` reports `activeWork` (a run,\n * compaction, `/` command or background task in flight). An older host\n * omits it; `zidane server wait-idle` then says it can't tell.\n * - ADDITIVE (no version bump): `sessions.loadEvents` paging accepts\n * `beforeTurnId` (the page ends right before that turn, winning over\n * `before`; an unknown turn is invalid params) and the page echoes it.\n * An older host ignores the param and omits the echo, which is how a\n * client tells.\n * - ADDITIVE (no version bump): `sessions.cacheImpact` and\n * `sessions.cacheReport`. An older host answers \"method not found\":\n * pickers show no cache estimate and session details no Cache section.\n * - ADDITIVE (no version bump): `sessions.moveEnvironment`. An older host\n * answers \"method not found\", shown as the move's error. Its\n * `removeOldWorktree` param and `oldWorktree` result came later: an older\n * host ignores the param and answers with no result.\n * - ADDITIVE (no version bump): a folder's git checkout and files\n * (`git.*`, `files.*`, the caller-only `git:clone:progress` signal),\n * `sessions.export` and `hud.get`. Clients find them in the hello's\n * `methods`; an older host lacks them and those controls stay hidden.\n * `hud.get` and the `hud:state` / `hud:notify` signals are gone since\n * zidane 10: extensions show status through `Slot` items\n * (`extensions.ui.list`, `extensions:ui`); a client that still asks\n * for `hud.get` gets \"method not found\".\n * - ADDITIVE (no version bump): `sessions.titleStatus`,\n * `artifacts.refresh`, `usage.summary`, `git.watch` / `git.unwatch`\n * (the watcher-only `git:refs` signal), `files.mediaTicket` (media at\n * `GET /zidane/media`), project-scope `extensions.create`, and\n * `auth.status`'s `customFields` / `configuredFields`. The methods are\n * in the hello's `methods`; an older host omits the fields.\n * - ADDITIVE (no version bump): `daemon.ownedProcesses`. An older host\n * answers \"method not found\"; the desktop app's performance monitor\n * then counts none of its processes as the app's own.\n * - ADDITIVE (no version bump): `daemon.sessionProcesses`. An older host\n * answers \"method not found\"; the performance monitor then shows none of\n * its processes under a session.\n * - ADDITIVE (no version bump): `sessions.setPolicy` (and\n * `sessions.create`'s `policy`), `integrations.register` / `update` /\n * `list`, `mcp.instances` and `mcp.restart`. An older host answers\n * \"method not found\" and ignores the field.\n * - ADDITIVE (no version bump): `interactions.rehydrateSessions`,\n * `tokens.revokeSelf`, `fs.mkdir`, `fs.searchDirs`, the hello's `clone`\n * and `createFolders` (`git.clone` and `git.cloneCancel` take a `chat`\n * token), `whenIdle` on `sessions.appendTurns`, `origin`, `literal` and\n * `clientMessageId` on the send methods, the `delivery:changed` and\n * `integrations:changed` signals, and `takenOver` on `run:end`. An older\n * host answers \"method not found\" or ignores the fields; an older client\n * drops the unknown signals and reads a taken-over run as failed.\n * - 14: the `orchestration.*` verbs act as the CONNECTION (its token, or\n * the local window) instead of taking a `mainId`; `createWorker` takes\n * `tools` / `subscribe` and an optional `prompt`; new\n * `orchestration.wait`, `orchestration.events`, `orchestration.pending`, `orchestration.answer`\n * (`chat`) and `orchestration.approve` (`approve`); `answeredBy` on\n * `interaction:resolved` / `approval:resolved` and on interaction\n * responses. A v13 peer still speaks: `orchestration.main` is unchanged\n * and a stray `mainId` is ignored.\n */\nexport const IPC_PROTOCOL_VERSION = 14\n\n/**\n * The oldest protocol version this build still speaks, as a client and as a\n * zidane-server. A server accepts a client whose range\n * (`minProtocolVersion`…`protocolVersion`) overlaps its own, and the\n * connection speaks the lower of the two versions, so a web app deployed\n * against one release keeps working after the server moves one version on.\n * Raise it only when the code that speaks a version is removed. A local\n * daemon keeps the exact-version fence: it is respawned on upgrade.\n */\n// Typed `number`: it trails `IPC_PROTOCOL_VERSION` between bumps, and comparing two literal types reads as a mistake to the compiler.\nexport const IPC_MIN_PROTOCOL_VERSION: number = 13\n\n/**\n * JSON-RPC error codes specific to the zidane daemon. Lives here (not in\n * `daemon/server.ts`) so clients can import the codes without pulling the\n * server's module graph.\n */\nexport const IpcErrorCode = {\n VersionMismatch: -32010,\n NotHandshaken: -32011,\n /** A network transport's per-connection request budget is spent; retry later. */\n RateLimited: -32012,\n /**\n * The reply would exceed the transport's message size: nothing was sent\n * but this error (the connection stays). Ask for less (a transcript: a\n * smaller page, see {@link loadAllEvents}).\n */\n ResponseTooLarge: -32013,\n /**\n * The handler threw: the host refused or failed the call (`message` says\n * why). Hosts before it answered -32000, which ACP uses for\n * `AuthenticationRequired`; clients treat both as a plain remote error.\n */\n HandlerFailed: -32014,\n /**\n * The connection's token doesn't reach this method (`./scopes`: a `chat`\n * token calling an `admin` method). `data.required` names the scope it\n * needs. Additive: hosts before scopes never refuse this way.\n */\n Forbidden: -32015,\n} as const\n\n/**\n * The `data` of a `HandlerFailed` error from an extension install\n * (`catalog.install`, `extensions.changeOrigin`) that found extensions in\n * the source but not the one it needed: the installer's error code\n * (`name-mismatch`, `multiple-candidates`, `no-extension`) and the names it\n * found, for a client to list. Additive: older hosts send the names in the\n * message only.\n */\nexport interface ExtensionInstallErrorData {\n /** The installer's error code: `name-mismatch`, `multiple-candidates` or `no-extension`. */\n installError: string\n /** The extension names the source holds. */\n candidates: string[]\n}\n\n/**\n * The {@link ExtensionInstallErrorData} of a call's error `data`, or\n * `undefined` when it carries none.\n *\n * @param data - A JSON-RPC error's `data`, untrusted.\n */\nexport function extensionInstallErrorData(data: unknown): ExtensionInstallErrorData | undefined {\n if (typeof data !== 'object' || data === null)\n return undefined\n const { installError, candidates } = data as Partial<Record<keyof ExtensionInstallErrorData, unknown>>\n if (typeof installError !== 'string' || !Array.isArray(candidates) || !candidates.every(c => typeof c === 'string'))\n return undefined\n return { installError, candidates: [...candidates] }\n}\n\n/**\n * Client heartbeat request (`{}` → `{}`), outside the method table: every\n * host answers it, before the handshake too. A host predating it answers\n * \"method not found\", which still proves it alive.\n */\nexport const PING_METHOD = '$/ping'\n\n/**\n * Session-scoped signals fanned out to every peer carry their number in\n * their session as this extra field on the `ipc.signal` params (clients\n * predating it ignore it; `IpcClient` strips it and hands it to listeners as\n * {@link SignalMeta}). Per session, from 1, gap-free within one host process.\n */\nexport const SIGNAL_SEQ_FIELD = '$seq'\n\n/** What a signal listener gets beside the signal: its number in its session, when it has one. */\nexport interface SignalMeta {\n /** Position of the signal in its session. Starts at 1 and has no gaps within one host process. */\n seq: number\n}\n\n/** A session signal with its position in the session, as kept in the host's replay log. */\nexport interface SequencedSignal {\n /** Position of the signal in its session. */\n seq: number\n /** The signal itself. */\n signal: HostSignal\n}\n\n/** Result of `sessions.resume`. On success, the signals the client missed after its last position. Otherwise the reason it must reload instead. */\nexport type SessionResumeResult\n = | { ok: true, signals: SequencedSignal[] }\n /** `epoch`: another host process numbered them. `gap`: the log no longer covers the position. */\n | { ok: false, reason: 'epoch' | 'gap' }\n\n/* -------------------------------------------------------------------------\n * Request/response methods (client → host)\n * ---------------------------------------------------------------------- */\n\n/**\n * The optional client id of a send (`chat.send`, `chat.pushQueued`,\n * `queue.add`): a fresh one per user submission, the same one on its retries.\n * Per session, the first send with an id runs; a retry with the same id and\n * content answers the first result without running again, even across a host\n * restart; the same id with other content is refused (invalid params). A retry\n * of a send accepted but never settled (its host stopped) is refused with\n * \"already accepted\". A failed send frees its id. At most 128 characters; the\n * host keeps the last 256 ids per session. Additive: an older host ignores it.\n */\nexport interface SendRequestId {\n requestId?: string\n}\n\n/**\n * Typed method map for the daemon transport. Keys are JSON-RPC method\n * names; each entry pins params/result so both the daemon dispatch table\n * and the client proxy are checked against the same contract.\n *\n * Scope: the chat core every client needs. Host-UI-specific surfaces\n * (folder pickers, themes, keybindings) intentionally stay client-local.\n */\nexport interface IpcMethods {\n /**\n * `wake` is host-internal (see `SendOptions.wake`) — not accepted over the wire.\n * `requestId`: see {@link SendRequestId}.\n * The prompt goes through the extensions' prompt transforms and\n * `prompt` interceptors of the session's folder first, once per\n * submission, on the host (clients never run them). `consumed` says one took it instead of a run (`runId` is\n * then `''`): `handled` (an extension consumed it), `steer` / `followUp`\n * (delivered to the live run). Additive.\n */\n 'chat.send': { params: Omit<SendOptions, 'wake'> & SendRequestId, result: { runId: string, consumed?: 'handled' | 'steer' | 'followUp' } }\n /** Aborts the session's live run. Does nothing when no run is live. */\n 'chat.interrupt': { params: { sessionId: string }, result: void }\n /**\n * `true` when the message reached a live run; `false` when nothing was running (it was not delivered).\n * The message goes through the `prompt` interceptors first, as `chat.send` (`true` when one handled it).\n */\n 'chat.steer': { params: { sessionId: string, message: string, clientMessageId?: string }, result: boolean }\n /**\n * Adds a follow-up message to the live run. Resolves `true` when a run was live to take it, `false` when nothing was running and the message was dropped, not queued.\n * The message goes through the `prompt` interceptors first, as `chat.send` (`true` when one handled it).\n */\n 'chat.followUp': { params: { sessionId: string, message: string, clientMessageId?: string }, result: boolean }\n /**\n * Delivers a queued message. Steers a live run, otherwise starts a run or runs it as a command. `delivered` says which path it took. `keepDraft` keeps the shared composer draft instead of clearing it on the other clients.\n * The message goes through the `prompt` interceptors first, as `chat.send`; `consumed` says one took it (`delivered` is then `send` for `handled`, `steer` otherwise). Additive.\n */\n 'chat.pushQueued': {\n params: { sessionId: string, message: string, activatedSkills?: string[], keepDraft?: boolean, origin?: SendOptions['origin'], literal?: boolean, clientMessageId?: string, metadata?: SendOptions['metadata'] } & SendRequestId\n result: { delivered: 'steer' | 'send' | 'command' | 'queued', consumed?: 'handled' | 'steer' | 'followUp' }\n }\n /** Resolves `true` while the session has a live run. */\n 'chat.isRunning': { params: { sessionId: string }, result: boolean }\n /**\n * Retire the session's live agent so the next run rebuilds against\n * fresh config/credentials (MCP login, extension reload). Run-end\n * deferred when a run is in flight; HITL/queue state survives.\n */\n 'chat.rebuildAgent': { params: { sessionId: string }, result: void }\n /**\n * `zidane run --system / --mcp` for a host-backed window: launch overrides\n * for the session's agent (`ChatHost.setLaunchOverrides`), owned by the\n * calling client and dropped when it disconnects. A call with neither field clears them.\n */\n 'sessions.setLaunchOverrides': { params: { sessionId: string } & SessionLaunchOverrides, result: void }\n /**\n * Drop the daemon's cached runtime configs (extension registries, per\n * cwd) and retire every live agent so the next command or run rebuilds\n * against what is on disk now. Sent by a window after it reloaded its\n * own extensions (install, update, remove, `/reload`): extension `/`\n * commands execute daemon-side, so without this the daemon keeps\n * running the code it loaded at boot. Busy sessions rebuild at run end.\n */\n 'runtime.reload': { params: Record<string, never>, result: void }\n /**\n * Lists the tool calls and background tasks the session's live run tracks\n * and can cancel. Empty when no run is live. `children: true` adds the\n * subagents' running calls (`childId` set), for their starts: a\n * transcript read from disk times them too. Older hosts ignore it.\n */\n 'chat.listWork': { params: { sessionId: string, children?: boolean }, result: RunningWorkItem[] }\n /** Cancels one tracked work item by `id`, or every visible item with `\"all\"`. Resolves `true` when something was cancelled. `reason` is passed to a cancelled tool call. */\n 'chat.cancelWork': { params: { sessionId: string, id: string | 'all', reason?: string }, result: boolean }\n\n /** Lists session rows. `projectRoot` filters by project, `archive` picks active, archived or all sessions. */\n 'sessions.list': { params: { projectRoot?: string | null, archive?: 'active' | 'archived' | 'all' }, result: SessionRow[] }\n /**\n * The session list as a window renders it (`SessionMeta`: title, turn /\n * message / run counts, project, cwd, environment, artifact count, the\n * orchestration main flag), newest first. `projectRoot`: omitted = every\n * project, `null` = untagged sessions.\n */\n 'sessions.listMeta': { params: { projectRoot?: string | null }, result: SessionMeta[] }\n /** One `SessionMeta` by id (rows a filtered list can't return, e.g. the main); `null` when unknown. */\n 'sessions.getMeta': { params: { sessionId: string }, result: SessionMeta | null }\n /**\n * The whole session document as the host holds it: the live copy when an\n * agent is live (turns persisted mid-run, todos kept in memory), else the\n * stored one, a stale `running` marker demoted. `null` when unknown.\n */\n 'sessions.get': { params: { sessionId: string, turns?: boolean }, result: SessionDocumentHead | null }\n /**\n * A slice of a session's turns, `[from, from + limit)` (default from 0,\n * {@link SESSION_TURNS_PAGE} turns, at most {@link SESSION_TURNS_MAX_PAGE}),\n * from the same copy `sessions.get` reads, and how many turns it has: a\n * client reads a long session's document a page at a time\n * ({@link loadSessionDocument}) instead of in one reply. With\n * `sessions.get` `turns: false` (the document without its turns), what an\n * export needs. Pages and that head come from one snapshot of the\n * document per content version (read once, not per page), and name it\n * (`version`): a client that sees it change mid-load starts over rather\n * than mix two versions ({@link loadSessionDocument}). `null` when\n * unknown. Additive: an older host answers \"method not found\", ignores\n * `turns: false`, and names no version.\n */\n 'sessions.getTurns': { params: { sessionId: string, from?: number, limit?: number }, result: { turns: SessionTurn[], total: number, version?: string } | null }\n /**\n * The full text of one tool result (`callId`; `turnId`, when known, the\n * turn that holds it): what a clipped tool row shows on expand, without\n * the session crossing the wire. `null` when no such result. Additive.\n */\n 'sessions.getToolResult': { params: { sessionId: string, callId: string, turnId?: string }, result: string | null }\n /**\n * One session's header: its list row plus metadata, profile and status,\n * without turns or runs (the live copy when an agent holds it). What a\n * window re-reads on `sessions:changed`. Additive. `usage: true` adds the\n * footer's numbers, computed host-side from the turns and runs\n * (`contextTokens`, `costUsd`, and while the host runs the session\n * `runStartedAt` / `runOutputTokens`): a client needs no document for its\n * context gauge, cost pill or run readout. Older hosts ignore it.\n */\n 'sessions.getHeader': { params: { sessionId: string, usage?: boolean }, result: SessionHeader | null }\n /**\n * One key of an extension's per-session state (`metadata.extensions`, the\n * bag `ctx.session` and renderer `useSessionState` share), written by the\n * host into its copy of the session. `value` omitted deletes the key.\n */\n 'sessions.setExtensionState': { params: { sessionId: string, extension: string, key: string, value?: JsonValue }, result: void }\n /** Creates a session and resolves with its row. */\n 'sessions.create': { params: CreateSessionParams, result: SessionRow }\n /** Resolves with what happened to the session's environment (a provider may keep it). */\n 'sessions.delete': { params: { sessionId: string }, result: { environment?: EnvironmentTeardownResult } }\n /**\n * A session's `/side` session (`sessions.create` with `sideOf`; hidden from\n * `sessions.list`), the newest when there are several, with the session's\n * own row (`null`: unknown). Additive.\n */\n 'sessions.sideSession': { params: { sessionId: string }, result: SideSessionLookup }\n /** Provision a failed (or restart-stranded) environment again. */\n 'sessions.retryEnvironment': { params: { sessionId: string }, result: void }\n /** Move an idle session to another environment (`local`, `worktree`, `local@M`, `worktree@M`, any direction), in `cwd` on the target; provisioning continues in the background. */\n 'sessions.moveEnvironment': { params: { sessionId: string, environment: EnvironmentRequest, cwd?: string, removeOldWorktree?: boolean }, result: { oldWorktree?: EnvironmentTeardownResult } }\n /** The per-session commands the session's environment offers right now (push, open PR, …). */\n 'sessions.environmentActions': { params: { sessionId: string }, result: EnvironmentActionSummary[] }\n /** Run one of them in the session's environment (resumed when suspended). */\n 'sessions.runEnvironmentAction': { params: { sessionId: string, actionId: string }, result: EnvironmentActionResult }\n /**\n * The session's workspace (`ChatHost.workspace*`): its execution context,\n * rooted inside the environment when the files live there, else at the\n * session's cwd. Paths and exec `cwd` resolve against the root as the\n * execution context resolves them; containment is the context's own.\n * `cwd` / `env` on exec and the list / size methods are additive: an\n * older daemon ignores the former and answers \"method not found\" to the\n * latter (active clients are build-fenced, so this is a transient case).\n */\n 'sessions.workspaceExec': { params: { sessionId: string, command: string, cwd?: string, env?: Record<string, string>, timeoutSeconds?: number }, result: ExecResult }\n /**\n * The same command, streamed (`!` on a remote host): the reply names the\n * exec, its output follows as `workspace:exec:data` signals and ends with\n * one `workspace:exec:exit`, all to this connection only (signals may\n * precede the reply). Bounded per connection (concurrent commands, chunk\n * size, total output: past it the process is stopped and the exit says\n * `truncated`). A dropped connection kills what it started. Additive: an\n * older host answers \"method not found\" and clients use `workspaceExec`.\n */\n 'sessions.workspaceExecStream': { params: { sessionId: string, command: string, cwd?: string }, result: { execId: string } }\n /** Kill a streamed command's process group (this connection's only; `cancelled: false` otherwise or when it already ended). */\n 'sessions.workspaceExecCancel': { params: { execId: string }, result: { cancelled: boolean } }\n /** Reads a text file from the session's workspace. */\n 'sessions.workspaceReadFile': { params: { sessionId: string, path: string }, result: string }\n /** Writes a text file in the session's workspace. */\n 'sessions.workspaceWriteFile': { params: { sessionId: string, path: string, content: string }, result: void }\n /** Lists the entries under `path` in the session's workspace. */\n 'sessions.workspaceListFiles': { params: { sessionId: string, path: string, options?: WorkspaceListFilesOptions }, result: ListFilesEntry[] }\n /** Size in bytes of a file in the session's workspace, or `null` when it does not exist. */\n 'sessions.workspaceFileSize': { params: { sessionId: string, path: string }, result: number | null }\n /*\n * Entry actions in the session's workspace (`ChatHost.workspaceCreate` …):\n * paths relative to the root, never `..` or absolute, nothing\n * overwritten; a refusal is a result (`ok: false`), not an error. Additive.\n */\n /** Creates a file (`content`: base64 bytes, default empty) or a folder; `freeName` takes the next free name instead of refusing a taken one. */\n 'sessions.workspaceCreate': { params: { sessionId: string, path: string, kind: 'file' | 'dir', content?: string, freeName?: boolean }, result: EntryResult }\n /** Moves (renames) `from` to `to`. */\n 'sessions.workspaceMove': { params: { sessionId: string, from: string, to: string }, result: EntryResult }\n /** Copies `from` into folder `toDir` (`''`: the root) under a free name. */\n 'sessions.workspaceCopy': { params: { sessionId: string, from: string, toDir: string }, result: EntryResult }\n /** Removes `path` (a folder whole), for good. */\n 'sessions.workspaceRemove': { params: { sessionId: string, path: string }, result: EntryResult }\n /** The workspace's empty folders, relative to its root (a file listing leaves them out), capped. */\n 'sessions.workspaceEmptyDirs': { params: { sessionId: string }, result: string[] }\n /**\n * Every environment kind the host can create, described for a new session\n * in `cwd` (availability, default, branch suggestion, options — secrets\n * only as \"configured\"). What pickers and the Environments settings render.\n * `kind`: a machine kind (`local@laptop`) says `cwd` is that machine's\n * folder, checked against its roots instead of this host's\n * (`docs/MACHINES.md` § Folders); the same on `commands.*`, `catalog.*`\n * and `models.list`. Additive.\n */\n 'environments.list': { params: { cwd?: string, kind?: string }, result: EnvironmentDescriptor[] }\n /**\n * Apply one Environments-settings edit (enable, default, options,\n * secrets), validated against the kind's schema. Settings changes fan out\n * as `settings:changed`; secrets are stored host-side and never returned.\n */\n 'environments.update': { params: EnvironmentSettingsChange, result: void }\n /** \"Test connection\" for a kind with its current options. */\n 'environments.verify': { params: { kind: string }, result: EnvironmentVerifyResult }\n /** Renames a session. */\n 'sessions.setTitle': { params: { sessionId: string, title: string }, result: void }\n /**\n * Title the session ON the host: its providers and credentials (a server\n * session's transcript never goes to the window's provider), the same\n * generator (`generateSessionTitle`), written as `sessions.setTitle` does.\n * `providerKey` / `model`: the window's pick, used when the host has that\n * provider; otherwise the session's own provider and model. The Main\n * session is refused (it keeps its name). Additive: an older host answers\n * \"method not found\".\n */\n 'sessions.generateTitle': { params: { sessionId: string, providerKey?: string, model?: string }, result: { title: string } }\n /**\n * How the session's title came about, as the session details dialog words\n * it (`describeTitleStatus`): where it came from (`auto`, `typed by you`,\n * `untitled`, …), then the last automatic titling attempt when there was\n * one (`generated 2h ago`, `check failed 5m ago (…)`). Additive.\n */\n 'sessions.titleStatus': { params: { sessionId: string }, result: string[] }\n /** Archives or restores a session. */\n 'sessions.setArchived': { params: { sessionId: string, archived: boolean }, result: void }\n /** Keep the session at the top of lists (`metadata.favorite`). Not activity: no recency bump. Additive. */\n 'sessions.setFavorite': { params: { sessionId: string, favorite: boolean }, result: void }\n /**\n * Replaces the session's rules (`metadata.policy`, {@link SessionPolicy}); `{}` clears them.\n * Loosening the current rules (a looser `approvalMode`, 'ask' > 'decide' > 'off', removing a rule, raising a ceiling) needs an approve token. Additive.\n */\n 'sessions.setPolicy': { params: { sessionId: string, policy: SessionPolicy }, result: void }\n /** Move the session to a space (`metadata.spaceId`); the Default space id clears it. See `chat/spaces`. */\n 'sessions.setSpace': { params: { sessionId: string, spaceId: string }, result: void }\n /** Switches the agent the session runs as. */\n 'sessions.setAgentId': { params: { sessionId: string, agentId: string }, result: void }\n /** Sets the thinking effort of the session. */\n 'sessions.setEffort': { params: { sessionId: string, effort: ThinkingLevel }, result: void }\n /**\n * The one model-swap contract (`ChatHost.setSessionModel`). A pick is a\n * whole: `fallbacks` (ordered, primary excluded) REPLACES the persisted\n * `metadata.modelChain` (omitted/empty clears it); `effort` and\n * `modelOptions` are reset to the supplied values (omitted clears them —\n * per-model knobs never leak onto the new model). The live agent is\n * retired so the next run rebuilds on the new pick (run-end deferred\n * while a run is in flight).\n */\n 'sessions.setModel': {\n params: {\n sessionId: string\n providerKey: ProviderKey\n modelId: string\n /** The stored account of the provider to run on (credential id); omitted = its active account. Additive. */\n account?: string\n fallbacks?: ModelFallbackRef[]\n effort?: ThinkingLevel\n modelOptions?: Record<string, boolean>\n }\n result: void\n }\n /** Replaces the model-specific boolean options of the session. */\n 'sessions.setModelOptions': { params: { sessionId: string, options: Record<string, boolean> }, result: void }\n /**\n * The session's transcript as canonical events. Without `before` / `limit`:\n * every turn, as a plain array (the shape every client predating paging\n * reads). With either: one page, `{ events, cursor? }`, the last `limit`\n * turns (default {@link LOAD_EVENTS_PAGE_TURNS}, at most\n * {@link LOAD_EVENTS_MAX_PAGE_TURNS}) before turn position `before`\n * (default: the end), its start moved back to an exchange boundary when one\n * is near so a tool call is never cut from its result. `cursor`: the\n * `before` of the previous page, absent at the first turn. Typed here as\n * the unpaged call every client makes; a paged call goes through\n * {@link loadEventsPage}. Paging is additive: an older host ignores the\n * fields and answers the whole array.\n */\n 'sessions.loadEvents': { params: { sessionId: string }, result: StreamEvent[] }\n /**\n * Reattach without a reload: the session's signals numbered after\n * `afterSeq` (see {@link SIGNAL_SEQ_FIELD}), in order, as long as this host\n * process (`epoch`, from `HelloResult.signalEpoch`) still holds them all.\n * Otherwise refused, and the client reloads with `sessions.loadEvents`.\n * Additive: an older host answers \"method not found\", same fallback.\n */\n 'sessions.resume': { params: { sessionId: string, epoch: string, afterSeq: number }, result: SessionResumeResult }\n /** One turn of a session by id, or `null` when unknown. */\n 'sessions.getTurn': { params: { sessionId: string, turnId: string }, result: SessionTurn | null }\n /** The session's context usage broken down by category, or `null` when unknown. */\n 'sessions.contextBreakdown': { params: { sessionId: string }, result: ContextBreakdown | null }\n /**\n * Artifacts one session recorded (PRs, branches, commits, files,\n * extension kinds — see `session/artifacts.ts`), newest first. Empty on\n * stores without artifact support. Additive; pre-artifact daemons\n * reject the method and clients treat that as empty.\n */\n 'sessions.artifacts': { params: { sessionId: string, kind?: string, limit?: number }, result: SessionArtifact[] }\n /**\n * Artifacts across sessions, filtered by project root (`null` = untagged\n * sessions, omitted = every project) and/or kind/uri (reverse lookup).\n */\n 'artifacts.list': { params: { projectRoot?: string | null, kind?: string, uri?: string, since?: number, limit?: number }, result: SessionArtifact[] }\n /** Remove one artifact. `false` when the store has no artifact support. Fans out `artifact:changed`. */\n 'artifacts.delete': { params: { sessionId: string, artifactId: string }, result: boolean }\n /**\n * Upsert an artifact — the lazy `resolve()` write-back (refreshed\n * `label` / `meta`). Same merge semantics as `SessionStore.upsertArtifact`;\n * `null` when the session is unknown or the store lacks support.\n */\n 'artifacts.upsert': { params: { artifact: SessionArtifact }, result: SessionArtifact | null }\n /**\n * Re-resolves one stored artifact (is the pull request merged?): its kind's\n * `resolve()` runs on the host, with the extensions of the folder the\n * artifact landed in. A change is stored and fans out `artifact:changed`.\n * `force` asks past the kind's own freshness window. `null` when nothing\n * changed (no resolver, nothing new, an unknown artifact). Additive.\n */\n 'artifacts.refresh': { params: { sessionId: string, artifactId: string, force?: boolean }, result: SessionArtifact | null }\n /**\n * The badges under sessions' titles (commits, pull requests, extension\n * kinds with a `badge`), for up to `ARTIFACT_BADGES_MAX` sessions at once,\n * keyed by session id. Each session's badges come from the extensions of\n * the folder its newest artifact landed in. They change with the\n * session's `artifact:recorded` / `artifact:changed` and with\n * `catalog:changed` (`extensions`): read them again then. Additive.\n */\n 'artifacts.badges': { params: { sessionIds: string[] }, result: Record<string, SessionBadgeEntry[]> }\n /**\n * Transcript search over ONE session, daemon-side. The daemon owns the\n * authoritative turns (live wrapper when an agent is active — fresh\n * mid-run, which a window's load-time snapshot is not) and an LRU index\n * cache shared by every window, so repeat queries pay match cost only.\n * Results come back in TURN ORDER (search is a transcript filter).\n */\n 'history.searchSession': {\n params: { sessionId: string, query: string, limit?: number }\n result: SearchTurnResult[]\n }\n /**\n * Cross-session content search, daemon-side. One RPC replaces a\n * window's per-session index/build/search round-trips — indexes are\n * built once in the daemon and shared by every window.\n */\n 'history.searchAll': {\n params: { query: string, sessionIds: string[], excerptLimit?: number }\n result: Record<string, SessionHistoryMatch>\n }\n /**\n * A window appended transcript content OUT-OF-BAND (local `/` command\n * output, `!` shell turns — written straight to the shared store, not\n * through a host run). The daemon fans out `sessions:changed` so every\n * window (issuer included) re-converges on the canonical replay NOW\n * instead of at the next run end. Sent as a notification.\n */\n 'sessions.touch': { params: { sessionId: string }, result: void }\n /** Fork at `turnId` into a new session (`ChatHost.forkSession`); announced as a `sessions:changed` create. */\n 'sessions.fork': { params: { sessionId: string, turnId: string, title?: string }, result: { id: string } }\n /** History edits (`ChatHost.deleteTurn` / `editTurnText`): refused while the session runs. */\n 'sessions.deleteTurn': { params: { sessionId: string, turnId: string }, result: void }\n /** Replaces the text of one turn. Refused while the session runs. */\n 'sessions.editTurnText': { params: { sessionId: string, turnId: string, text: string }, result: void }\n /** Cut the history at `turnId` in place (`ChatHost.rewindSession`); `inclusive` keeps the turn. Refused while the session runs. */\n 'sessions.rewind': { params: { sessionId: string, turnId: string, inclusive: boolean }, result: void }\n /** Bind to a folder, or back to a plain chat with `cwd: ''` (`ChatHost.setSessionFolder`). */\n 'sessions.setFolder': { params: { sessionId: string, cwd: string }, result: void }\n /** Turns written outside a run, e.g. `!` shell output (`ChatHost.appendTurns`). `whenIdle`: refused while a run is live or an interrupted run waits (a channel's context messages). */\n 'sessions.appendTurns': { params: { sessionId: string, turns: SessionTurn[], whenIdle?: boolean }, result: void }\n /**\n * `ctx.appendNote` outside a run: a display-only note, rendered live and\n * persisted (`ChatHost.appendNote`). False for an unknown session or no blocks.\n */\n 'sessions.appendNote': { params: { sessionId: string, blocks: CommandOutputBlock[] }, result: boolean }\n /** Compact now (`ChatHost.compactSessionNow`): what was done, `null` when nothing was. Older daemons resolve `null`. */\n 'sessions.compact': { params: { sessionId: string }, result: CompactionReport | null }\n\n /** The session's todo list, or `null` when it has none. */\n 'todos.get': { params: { sessionId: string }, result: TodosSnapshot | null }\n /**\n * Apply a user todo edit (add / edit / remove / cycle / clear) to the\n * session the MODEL reads.\n *\n * Required because todos live in `session.metadata` and `todowrite` reads\n * them off the daemon agent's in-memory `Session`. A window writing its own\n * `Session` instance persisted an edit that the daemon never observed, so the\n * model's next `todowrite` silently overwrote it.\n *\n * Sends the whole list rather than a delta: the mutators in\n * `chat/todo-edits.ts` are already whole-list transforms, and a delta would\n * need conflict rules against a list the model rewrites concurrently.\n *\n * `null` = no live agent (or no run owns a todo slot), and the caller should\n * apply its own store-level write — race-free, since nothing is appending.\n *\n * `persistIdle`: with no live agent, the host applies the edit to the stored\n * session itself (the run the list belongs to must exist) instead of\n * answering `null`. Older hosts ignore it.\n */\n 'todos.set': { params: { sessionId: string, items: readonly TodoItem[], persistIdle?: boolean }, result: TodosSnapshot | null }\n\n /*\n * Orchestration — the verbs over other sessions (docs/ORCHESTRATION.md).\n * The caller is the CONNECTION: its token's principal on a zidane-server,\n * the local window otherwise. It reaches every session (the Main\n * included) except `/side` sessions; what it creates is tagged with it\n * (`createdBy`), and revoking its token stops those sessions. The Main's\n * own switch (`Settings.orchestration`) gates only the Main.\n */\n /** The main session id, creating it (directory-less) when the setting is on and none exists. */\n 'orchestration.main': { params: Record<string, never>, result: string | null }\n /** Creates a session (optionally holding orchestration tools and a subscription) and resolves with its id. */\n 'orchestration.createWorker': { params: OrchestrationCreateParams, result: string }\n /** Lists sessions with their live status, newest first, up to `limit`. The list can be partial. */\n 'orchestration.list': { params: { limit?: number }, result: OrchestrationWorkerRow[] }\n /** Summary of one session; rejects when unknown. */\n 'orchestration.read': { params: { sessionId: string }, result: OrchestrationWorkerSummary }\n /** Queues a prompt as the session's next turn; `false` when declined (the person stopped the session, or their queued prompts go first). */\n 'orchestration.send': { params: { sessionId: string, prompt: string }, result: boolean }\n /** Sends a steering message to a session's live run. */\n 'orchestration.steer': { params: { sessionId: string, message: string }, result: void }\n /** Cancels a session's run. */\n 'orchestration.cancel': { params: { sessionId: string }, result: void }\n /** The last `limit` turns of a session as plain text. */\n 'orchestration.transcript': { params: { sessionId: string, limit?: number }, result: string }\n /** Resolves once the session is idle or blocked, or after `timeoutSec` (default 30, at most 50). */\n 'orchestration.wait': { params: { sessionId: string, timeoutSec?: number }, result: OrchestrationWaitResult }\n /** Searches the recent session events (runs ended, sessions blocked), newest first. */\n 'orchestration.events': { params: OrchestrationEventQuery, result: SessionEvent[] }\n /** The prompts waiting for an answer (questions, plans, tool approvals), of one session or all. */\n 'orchestration.pending': { params: { sessionId?: string }, result: OrchestrationPendingRequest[] }\n /** Answers a question or a plan, recording the connection as `answeredBy`. `false` when it was answered first. */\n 'orchestration.answer': { params: { requestId: string, response: InteractionResponse }, result: boolean }\n /** Decides a tool approval (an `approve` token), recording the connection as `answeredBy`. `false` when it was decided first. */\n 'orchestration.approve': { params: { requestId: string, decision: ApprovalDecision }, result: boolean }\n\n /** Extension-contributed `/` commands discovered for `cwd`. */\n 'commands.list': { params: { cwd: string, kind?: string }, result: CommandSummary[] }\n /** Argument suggestions for `/name <prefix>` — best-effort, empty on failure. */\n 'commands.completeArgs': { params: { cwd: string, name: string, argsPrefix: string, kind?: string }, result: CommandArgSuggestionSummary[] }\n /** The agent profiles `cwd` offers (`''`: no folder), as the agent picker lists them: a profile a setting turns off (Codemode) is left out. Additive. */\n 'agents.list': { params: { cwd: string }, result: HostAgentProfile[] }\n /**\n * The extension completion providers (`ctx.registerCompletionProvider`) of\n * `cwd` a composer can render: a one-character trigger each, `@` `/` `#`\n * left to the built-in completers, first wins on id and trigger. Additive.\n */\n 'completions.providers': { params: { cwd: string }, result: ExtensionCompletionProviderSummary[] }\n /**\n * One provider's items for `query` (the text after its trigger), at most\n * 8. A newer call for the same provider on the connection aborts this one;\n * `[]` past 5 s or when the provider throws. Additive.\n */\n 'completions.suggest': { params: { cwd: string, providerId: string, query: string, text: string, cursor: number }, result: ExtensionCompletionItemSummary[] }\n /** Runs the providers' submit hooks (`resolveReferences`, `onSubmit`) on a prompt about to be sent; resolves after them, or after 5 s. Additive. */\n 'completions.submit': { params: { cwd: string, text: string, cursor: number }, result: void }\n /**\n * The extension text reference providers (`ctx.registerReferences`) of\n * `cwd`: the patterns a client matches prose with. `peek`: only from a\n * registry already built for `cwd` (`null` when none is), so a list of\n * titles across projects never builds one per project. Additive.\n */\n 'references.providers': { params: { cwd: string, peek?: boolean }, result: ReferenceProviderWire[] | null }\n /** The views of the keys a client found, in order: `null` for one that names nothing. At most 50 keys per call. Additive. */\n 'references.resolve': { params: { cwd: string, items: { providerId: string, key: string }[] }, result: (ExtensionReferenceView | null)[] }\n /** The extensions' items (`ctx.registerBadgeActions`) of a badge's menu in `cwd`; the built-in ones are the client's. Additive. */\n 'badges.actions': { params: { cwd: string, target: BadgeTarget }, result: BadgeMenuItem[] }\n /** Runs an extension's badge item; the effect (copy, open, a notice) is the client's to apply. Additive. */\n 'badges.run': { params: { cwd: string, source: string, id: string, target: BadgeTarget }, result: BadgeActionEffect }\n /**\n * The side panels `cwd`'s extensions register. A panel's `load` and\n * `onAction` run on the host, bound to `cwd` and the session `ctx` names,\n * with a hard timeout: a failing panel answers an empty content naming why\n * (`load`) or `ok: false` (`action`), never an error. Additive.\n */\n 'panels.list': { params: { cwd: string }, result: PanelSummary[] }\n /** One panel's content for `ctx` (the session it shows beside, what opened it). Additive. */\n 'panels.load': { params: { cwd: string, panelId: string, ctx?: PanelLoadContextInput }, result: PanelContent }\n /** Run one of a panel's actions (a row's or the footer's `actionId`, its `payload`). Additive. */\n 'panels.action': { params: { cwd: string, panelId: string, actionId: string, payload?: unknown, ctx?: PanelLoadContextInput }, result: { ok: true } | { ok: false, error: string } }\n /**\n * Keep a panel's live updates on: this connection gets `panel:changed`\n * when its content changes. Calls count; a dropped connection releases its\n * own. Additive.\n */\n 'panels.watch': { params: { cwd: string, panelId: string }, result: void }\n /** Release one `panels.watch` of this connection. */\n 'panels.unwatch': { params: { cwd: string, panelId: string }, result: void }\n /**\n * The command palette items `cwd`'s extensions contribute (each item's\n * `source` is its provider), and running one. A provider that fails lists\n * one disabled row naming why; a failed run answers `ok: false`. Additive.\n */\n 'palette.list': { params: { cwd: string, ctx: PaletteContext }, result: PaletteItem[] }\n /** Run `itemId` on its provider (`source`); a nested list, a prompt or a draft comes back as `result`. Additive. */\n 'palette.run': { params: { cwd: string, source: string, itemId: string, ctx: PaletteContext }, result: { ok: true, result: PaletteRunResult } | { ok: false, error: string } }\n /** As `panels.watch`, for every provider of `cwd`: `palette:changed`. Additive. */\n 'palette.watch': { params: { cwd: string }, result: void }\n /** Release one `palette.watch` of this connection. */\n 'palette.unwatch': { params: { cwd: string }, result: void }\n\n /** Lists pending interactions (questions and prompts the agent asked the user), optionally for one session. */\n 'interactions.list': { params: { sessionId?: string }, result: PendingInteraction[] }\n /** Answers a pending interaction. */\n 'interactions.respond': { params: { requestId: string, response: InteractionResponse }, result: { ok: boolean } }\n /** Cancels a pending interaction. `reason` is passed back to the agent. */\n 'interactions.cancel': { params: { requestId: string, reason?: string }, result: { ok: boolean } }\n /** Re-sends the session's pending interactions, for a client that connected after they were raised. */\n 'interactions.rehydrate': { params: { sessionId: string }, result: PendingInteraction[] }\n /**\n * `interactions.rehydrate` for each of `sessionIds` not running on this\n * host, loading only those whose run waits to be resumed or whose last\n * turns hold an unanswered question or plan (a channel start, over every\n * conversation it had).\n */\n 'interactions.rehydrateSessions': { params: { sessionIds: string[] }, result: PendingInteraction[] }\n /**\n * Dev browser: a window offers to host the pages the agent's `browser_*`\n * tools drive (the GUI's main process). Released when the connection\n * drops. It then answers each `browser:request` signal addressed to it.\n */\n 'browser.registerHost': { params: { hostId: string }, result: { ok: boolean } }\n /** Withdraws a window as dev browser host. */\n 'browser.unregisterHost': { params: { hostId: string }, result: { ok: boolean } }\n /** Answers a `browser:request` signal with the host's result. */\n 'browser.respond': { params: { requestId: string, response: BrowserResponse }, result: { ok: boolean } }\n /**\n * Terminals, run by the host in the session's environment. `clientId`\n * names one view (a window's drawer or panel); views attached through a\n * connection are detached when it drops. Output arrives as\n * `terminal:output` signals; `ack` what was written to keep it flowing.\n */\n 'terminal.state': { params: { sessionId: string }, result: TerminalSessionState }\n /** Opens a terminal in a session's environment. */\n 'terminal.open': { params: TerminalOpenInput, result: TerminalInfo }\n /** Attaches a view (`clientId`) to a terminal and resolves with the output it can replay. */\n /** `maxLines` caps the history snapshot to the last lines a view can show (0 or absent: no cap). */\n 'terminal.attach': { params: { terminalId: string, clientId: string, maxLines?: number }, result: TerminalAttachResult }\n /** Detaches a view from a terminal. */\n 'terminal.detach': { params: { terminalId: string, clientId: string }, result: void }\n /** `clientId` + `response`: bytes the view's emulator generated (DSR/DA replies), dropped unless that view owns the size. */\n 'terminal.write': { params: { terminalId: string, data: string, clientId?: string, response?: boolean }, result: void }\n /** Resizes the terminal to a view's size. `claim` makes this view own the size. */\n 'terminal.resize': { params: { terminalId: string, clientId: string, cols: number, rows: number, claim?: boolean }, result: void }\n /** Acknowledges terminal output up to `offset`, so the host keeps it flowing. */\n 'terminal.ack': { params: { terminalId: string, clientId: string, offset: number }, result: void }\n /** Restarts a terminal's process and resolves with its info. */\n 'terminal.restart': { params: { terminalId: string }, result: TerminalInfo }\n /** Closes a terminal. */\n 'terminal.close': { params: { terminalId: string }, result: void }\n /** Hides a terminal from the agent, or shows it again. */\n 'terminal.setHidden': { params: { terminalId: string, hidden: boolean }, result: void }\n /**\n * This connection can show terminals (the desktop app). While at least one\n * viewer is attached, agents get the terminal tools; the registration is\n * dropped with the connection.\n */\n 'terminal.registerViewer': { params: { viewerId: string }, result: { ok: boolean } }\n /** Withdraws a viewer registered with `terminal.registerViewer`. */\n 'terminal.unregisterViewer': { params: { viewerId: string }, result: { ok: boolean } }\n /**\n * Terminals without a session: a shell on the host's machine in a\n * project's folder, or in a new-chat draft's (`draftId`). Agents never see\n * them. `terminal:project-changed` carries a scope's full list.\n */\n 'terminal.projectState': { params: TerminalProjectStateInput, result: TerminalProjectState }\n /** Opens a terminal bound to a project rather than a session. */\n 'terminal.openInProject': { params: TerminalProjectOpenInput, result: TerminalInfo }\n /** The draft became `sessionId`: its terminals move there in one pass (over the cap: back to the project). */\n 'terminal.adopt': { params: { draftId: string, sessionId: string }, result: TerminalAdoptResult }\n /** The draft was discarded (or became a server session): its terminals go back to the project. */\n 'terminal.releaseDraft': { params: { draftId: string }, result: void }\n\n /** Answers a pending approval request with a decision. */\n 'approvals.resolve': { params: { requestId: string, decision: ApprovalDecision }, result: void }\n /** Denies every pending approval, or only those of `sessionId` when given. */\n 'approvals.denyAll': { params: { sessionId?: string }, result: void }\n /** Lists the approval requests waiting for an answer. */\n 'approvals.listPending': { params: Record<string, never>, result: WireApprovalRequest[] }\n /** The host's \"Always allow\" entries, per project (its `projects.json`): what approving with `accept-safelist` added. Additive. */\n 'safelist.list': { params: Record<string, never>, result: { projects: SafelistProject[] } }\n /** Revoke one \"Always allow\" entry of a project; `removed: false` when it was not there. Additive. */\n 'safelist.remove': { params: { project: string, entry: string }, result: { removed: boolean } }\n\n /**\n * Type-ahead queue, host-owned so every window sees and can manipulate\n * the same list. `queue.add` queues when a run is in flight and sends\n * immediately otherwise; the host auto-drains the queue FIFO at run end.\n */\n 'queue.list': { params: { sessionId: string }, result: QueuedItem[] }\n\n /**\n * Which `SYSTEM.md` override composes this session's prompt, for windows\n * attaching to an already-warm agent.\n *\n * The `system-md` signal fires once per agent BUILD and the daemon caches\n * agents, so the normal multi-window case (daemon already running, open a\n * second terminal or the GUI) would otherwise never learn that the built-in\n * safety and git doctrine has been replaced. `null` = no live agent yet, in\n * which case the next build broadcasts it.\n */\n 'sessions.systemMd': {\n params: { sessionId: string }\n result: { file: SystemMdFile | null, shadowed: readonly SystemMdFile[] } | null\n }\n /**\n * Every chunk of the session's system prompt with provenance — the\n * Instructions tab. Built from the live agent's assembly, so it reflects\n * MCP instructions, extension fragments and the resolved `SYSTEM.md`.\n */\n 'sessions.contextSegments': { params: { sessionId: string }, result: ContextSegmentsReport | null }\n /**\n * What a switch would cost the session's prompt cache, as the host applies\n * it (`ChatHost.cacheImpact`): what pickers show next to each option.\n * `null` without a live agent or for an empty change. Additive: an older\n * host answers \"method not found\", and clients show no estimate.\n */\n 'sessions.cacheImpact': { params: { sessionId: string, change: CacheImpactChange }, result: CacheImpact | null }\n /**\n * The session's last requests and what the cache did for each\n * (`ChatHost.cacheReport`): what `/cache` prints, for the GUI's session\n * details. `null` for an unknown session. Additive: an older host answers\n * \"method not found\".\n */\n 'sessions.cacheReport': { params: { sessionId: string, limit?: number }, result: CacheReport | null }\n /**\n * The session's transcript rendered as a file to hand to the user: Markdown (title, metadata, every turn) or the\n * session's JSON. Nothing is written on the host. Additive (no version bump).\n */\n 'sessions.export': { params: { sessionId: string, format: SessionExportFormat }, result: SessionExportFile }\n /** Seed a user-scope `SYSTEM.md` from the session's doctrine; throws when an override could not apply. */\n 'sessions.createSystemOverride': { params: { sessionId: string }, result: { path: string, created: boolean } }\n /**\n * Adds a message to the session's queue. `delivered` tells whether it was queued, sent right away, or used to steer a live run.\n * The message goes through the `prompt` interceptors first, as `chat.send`; `consumed` says one took it (`delivered` is then `sent` for `handled`, `steer` otherwise). Additive.\n */\n 'queue.add': {\n /**\n * `asCommand`: see `SendOptions.asCommand` — the host refuses when it cannot resolve it.\n * `keepDraft`: see `SendOptions.keepDraft` — a prompt from outside the composer.\n * `delivery`: steer or follow up the live run when one takes it (as `ctx.submitPrompt`), queued or sent otherwise. Additive.\n * `requestId`: see {@link SendRequestId}.\n */\n params: { sessionId: string, text: string, activatedSkills?: string[], attachments?: PromptAttachment[], asCommand?: string, keepDraft?: boolean, origin?: SendOptions['origin'], literal?: boolean, clientMessageId?: string, metadata?: SendOptions['metadata'], delivery?: 'steer' | 'followUp' } & SendRequestId\n result: { delivered: 'queued' | 'sent' | 'steer', consumed?: 'handled' | 'steer' | 'followUp' }\n }\n /** Removes a queued entry by id. Resolves `true` when it was removed. */\n 'queue.remove': { params: { sessionId: string, id: string }, result: boolean }\n /**\n * Edit a queued entry in place; order is kept. `attachments` replaces the\n * entry's list when given. `false` when already sent / dropped.\n */\n 'queue.update': { params: { sessionId: string, id: string, text: string, attachments?: PromptAttachment[] }, result: boolean }\n /** A queued entry's attachments with their bytes; `null` when already sent / dropped. */\n 'queue.attachments': { params: { sessionId: string, id: string }, result: PromptAttachment[] | null }\n /** Steer a queued entry into the live run now (falls back to send when idle). */\n 'queue.pushNow': { params: { sessionId: string, id: string }, result: { delivered: 'steer' | 'send' | 'queued' | 'missing' } }\n\n /** Current shared draft for a session — backfill on window attach. */\n 'drafts.get': { params: { sessionId: string }, result: { text: string, shell?: boolean, attachments?: PromptAttachment[], search?: { active: boolean, query: string } } }\n /**\n * Replace the session's shared draft. Fans out `draft:changed` to every\n * OTHER peer. Ephemeral daemon state — drafts don't survive a daemon\n * restart and are cleared when any window submits the prompt.\n *\n * `shell` carries the prompt's shell mode OUT OF BAND — never encoded\n * into the text, so a literal leading `!` in a normal draft can't flip\n * other windows into shell-execution semantics.\n */\n 'drafts.set': { params: { sessionId: string, text: string, shell?: boolean }, result: void }\n /** Replace the shared draft's composing attachments (notification). */\n 'drafts.setAttachments': { params: { sessionId: string, attachments: PromptAttachment[] }, result: void }\n /** Replace the shared transcript-search state (notification, per keystroke). */\n 'search.set': { params: { sessionId: string, active: boolean, query: string }, result: void }\n /**\n * Token spend, models, streaks and activity over `range`, from the host's\n * session store, as the desktop app's welcome screen shows its own\n * (`summarizeUsage`). Days are the host's local days; `userName` is\n * `null` (the host's user is not the reader). Refused by a store that\n * keeps no usage history (not a SQLite file). Additive.\n */\n 'usage.summary': { params: { range: UsageRange }, result: UsageSummary }\n /**\n * The plan and subscription windows of each provider the host holds a\n * credential for (every account), probed with the host's credentials and\n * cached a few minutes; `refresh` probes past the cache. A provider that\n * can't be read reports `status: 'unavailable'`. Additive.\n */\n 'usage.providers': { params: { refresh?: boolean }, result: readonly ProviderUsageSnapshot[] }\n /**\n * GitHub's API limits as the host's GitHub client last saw them, per\n * GitHub host; `probe` asks GitHub (`/rate_limit`, which costs no call).\n * Additive.\n */\n 'usage.github': { params: { probe?: boolean }, result: ProviderUsageSnapshot[] }\n /**\n * Resolve inline ghost-text autocomplete daemon-side (the typing\n * window's request IS the single computation): canonical resolver\n * against the session cwd's extension registry. Latest-wins per\n * session — a `seq` older than the newest seen returns\n * `{ suggestion: null }` without computing, and a newer request\n * aborts an in-flight compute. The result additionally fans out as\n * `suggest:changed` to every OTHER peer.\n */\n 'suggest.resolve': { params: { sessionId: string, text: string, caret: number, seq: number }, result: { suggestion: string | null, seq: number, candidates?: string[] } }\n\n /** Reads the host settings. */\n 'settings.get': { params: Record<string, never>, result: HostSettings }\n /** Applies a partial settings patch and resolves with the full settings after it. */\n 'settings.set': { params: { patch: Partial<HostSettings> }, result: HostSettings }\n /** The picks remembered across apps (`state.json`): effort and options per model, the next chat's model chain. `null` when none is. Additive. */\n 'prefs.get': { params: Record<string, never>, result: HostComposerPrefs | null }\n /** Merges picks into `state.json` (each top-level key replaces). Additive. */\n 'prefs.set': { params: { patch: HostComposerPrefs }, result: void }\n /** The sidebar views a client saved on this host, by space id (`state.json`'s `sidebarViews`): each client checks what it reads. Additive. */\n 'sidebar.getViews': { params: Record<string, never>, result: Record<string, unknown> }\n /** Saves one space's sidebar view (at most 4 KiB of JSON), stored as given: the kit's record is the filter axes plus `session`, the conversation last open in that space. Additive. */\n 'sidebar.setView': { params: { spaceId: string, view: Record<string, unknown> }, result: void }\n /** The space a client's sidebar showed last, `null` when none was saved. Additive. */\n 'sidebar.getSpace': { params: Record<string, never>, result: string | null }\n /** Saves the space the sidebar shows. Additive. */\n 'sidebar.setSpace': { params: { spaceId: string }, result: void }\n /**\n * The options the enabled extensions declare for `cwd`\n * (`registerConfigItem`), without the action items or the callbacks; the\n * values live on the settings' `extensionConfig`. Additive.\n */\n 'extensions.configSchema': { params: { cwd: string }, result: WireExtensionConfigSchema }\n /** The action rows (`registerConfigItem` type `'action'`) the enabled extensions declare for `cwd`. Additive. */\n 'extensions.actions': { params: { cwd: string }, result: ExtensionActionSummary[] }\n /** The actions' passive `status()` probes, keyed `extension:key`; a probe that throws or takes over 3 s is left out. Additive. */\n 'extensions.actionStatuses': { params: { cwd: string }, result: Record<string, ExtensionConfigActionStatus> }\n /**\n * Runs an action on the host. The config patch it returns comes back\n * sanitized, not written: the client saves it (`settings.set`). One run of\n * an action at a time. A token needs the action's `scope` (the action row's\n * `scope`; default, and for config-declared actions, `admin`). Additive.\n */\n 'extensions.runAction': { params: { cwd: string, extension: string, key: string }, result: ExtensionActionRunResult }\n /**\n * Scaffolds a new extension and reloads the registries: in the host user's\n * `extensions` folder (`scope: 'user'`, the default), or in a project\n * (`scope: 'project'`: `cwd`'s checkout, which must lie in the workspace\n * roots; it loads once the project is trusted). Sessions stay in the\n * roots: one may open in a project extension's folder, never in a user\n * extension's. It writes code the host will run: a zidane-server's\n * `allowRemoteInstalls` gates it, every attempt is audited. Every window\n * gets `catalog:changed`. Additive.\n */\n 'extensions.create': { params: CreateExtensionInput, result: CreateExtensionResult }\n\n /*\n * Extension API. Every method that names a `cwd` acts on the extension\n * runtime of that folder's registry; a folder without extensions answers\n * empty. Signals: `rpc.event`, `extensions:*`, `ui:*`\n * (`./chat/host/extensions-wire`).\n */\n /**\n * Calls an extension's RPC method as this connection. Never throws for a\n * failed call: a declared error, invalid input, a missing provider or a\n * method whose `scope` this connection's token does not reach\n * (`rpc.forbidden`; a local connection is not limited) comes back as\n * `ok: false` with its `type`. `directory` (or `cwd`) picks the runtime;\n * without it, the newest runtime that has the contract. `callId` lets\n * `rpc.cancel` abort it. Also served as `POST /rpc/<contract>/<method>` on a\n * zidane-server, with the same token. Additive.\n */\n 'rpc.call': { params: RpcCallParams & { cwd?: string }, result: RpcResponseEnvelope }\n /** Aborts this connection's `rpc.call` of `callId`; it answers `rpc.aborted`. `false` when none is in flight. Additive. */\n 'rpc.cancel': { params: { callId: string }, result: boolean }\n /**\n * Every UI item of `cwd`'s extensions, per token, in wire form, and\n * each active extension's compiled `ui` bundle (`bundles`, by extension\n * id). `extensions:ui` pushes each change after it. Additive.\n */\n 'extensions.ui.list': { params: { cwd: string }, result: WireUiList }\n /**\n * The extensions of `cwd`: status, folder, `tui` entry and compiled\n * `ui` bundle. What a window draws extensions from in daemon mode,\n * without running their `setup`. `extensions:entries` says when to list\n * again. Additive.\n */\n 'extensions.entries': { params: { cwd: string }, result: WireExtensionEntry[] }\n /**\n * Runs one callback of a UI item by its id (a panel's `load` / `onAction`,\n * a reference `resolve`, a badge menu or action, a settings page action,\n * status or check). Callbacks run on the host under their extension's\n * guard. Additive.\n */\n 'extensions.ui.invoke': { params: { cwd: string } & UiInvokeRequest, result: unknown }\n /**\n * Offers a link the user opened to `cwd`'s extensions' link handlers\n * (`LinkHandler`), higher `priority` first; a handler that returns\n * `false`, throws or times out passes it on. `handled: false`: open it the\n * app's own way. Apps call it for every link they open, except with Alt\n * held. Additive.\n */\n 'extensions.links.open': { params: LinkOpenParams, result: { handled: boolean } }\n /**\n * What this connection shows and whether it shows dialogs: dialogs\n * (`ui:dialog`) and UI requests (`ui:client`) go to the client viewing the\n * session, else the last active one. Only announced clients get them.\n * Send again on focus or session change. Additive.\n */\n 'ui.client.announce': { params: UiClientAnnounce, result: void }\n /** Answers a `ui:client` request sent to this connection. `false` when it is no longer pending. Additive. */\n 'ui.client.reply': { params: { requestId: string, result: unknown }, result: boolean }\n /** Answers a `ui:dialog` shown on this connection (`answer` absent: cancelled). `false` when it is no longer pending. Additive. */\n 'ui.dialog.answer': { params: { dialogId: string, answer?: unknown }, result: boolean }\n /**\n * Checks one value of a `form` dialog shown on this connection: the\n * field's error message, or `null` when it is valid (or the dialog is no\n * longer pending here). Clients call it as the user edits a field and\n * before they answer, and show the message under the field. The host checks\n * the answer again: an answer with an invalid value makes the extension's\n * `ctx.ui.form` reject, so a client must not answer until every field\n * validates. Additive.\n */\n 'ui.dialog.validate': { params: { dialogId: string, key: string, value: unknown }, result: string | null }\n /** Everything stored at a location of `cwd`'s extension storage, and the project root its `project`/`session` files live under. Additive. */\n 'extensions.storage.load': { params: { cwd: string } & WireStorageLocation, result: StorageSnapshot & { projectRoot?: string } }\n /**\n * Writes (or, `value` absent, deletes) one storage entry. The extensions\n * holding it see the change at once; every other connection gets\n * `extensions:storage`. A `stores` write must be a `{ v, value }` record of\n * the store's version whose value passes its schema (checked against every\n * runtime of the folder holding the store); otherwise it is refused and\n * nothing changes. The result says which, with the entry as the host holds\n * it now, for the client to reconcile. Additive (the result was `void`).\n */\n 'extensions.storage.set': { params: { cwd: string, area: StorageArea, key: string, value?: Json } & WireStorageLocation, result: WireStorageSetResult }\n /** The extensions' settings of `cwd` with values, locks and the layer each value comes from. `sessionId` adds that session's layer. Additive. */\n 'extensions.settings': { params: { cwd: string, sessionId?: string }, result: WireExtensionSettings }\n /**\n * Writes one extension setting at a scope: `user` in the settings file, `project`\n * in the project's `extension-settings.json`, `session` in memory; a\n * secret goes to the credentials file, never a settings file. Refused for\n * a locked, unknown or action key, a scope the setting doesn't allow, or a\n * value that fails its checks. Additive.\n */\n 'extensions.settings.set': { params: SettingsSetParams, result: void }\n /** The extension commands of `cwd` with their effective bindings, scopes and modes, and the keymap mode on top for `sessionId`. Additive. */\n 'extensions.commands': { params: { cwd: string, sessionId?: string }, result: WireExtensionCommands }\n /** Runs a command by its published id (an extension command or a built-in). `false` when nothing ran. Additive. */\n 'extensions.command.run': { params: CommandRunParams, result: boolean }\n /** Activates a keymap mode on the host for `cwd` (as `ctx.keymap.mode.push`) until `extensions.keymap.pop` or this connection closes. Returns its handle. Additive. */\n 'extensions.keymap.push': { params: { cwd: string, mode: string, priority?: number, sessionId?: string }, result: string }\n /** Pops a mode this connection pushed. Additive. */\n 'extensions.keymap.pop': { params: { handle: string }, result: boolean }\n /** Every command of `cwd` with its effective bindings, scope and mode (`ctx.keymap.list`), and the active mode stack for `sessionId` (`ctx.keymap.active`). Additive. */\n 'extensions.keymap.list': { params: { cwd: string, sessionId?: string }, result: WireKeymap }\n /** The extension integrations of `cwd` (`ctx.integrations.register`) and their connections. Additive. */\n 'extensions.integrations.list': { params: { cwd: string }, result: WireIntegration[] }\n /** Connects with an API key: verified by the extension, then kept in the credentials file. Additive. */\n 'extensions.integrations.connectKey': { params: { cwd: string, integrationId: string, key: string, methodId?: string }, result: WireIntegration }\n /**\n * Runs an OAuth or command method. Its steps (open this URL, enter this\n * code, paste the redirect) come to this connection as\n * `extensions:integration-flow` with the returned `flowId`; the call resolves\n * when the flow ends. Additive.\n */\n 'extensions.integrations.start': { params: { cwd: string, integrationId: string, methodId: string, flowId?: string }, result: WireIntegration }\n /** Answers a flow step that asked for input (`inputId`). `value` absent cancels the flow. Additive. */\n 'extensions.integrations.flowInput': { params: { flowId: string, inputId: string, value?: string }, result: boolean }\n /** Removes the connection of `account`, or every connection of the integration when it is absent. Additive. */\n 'extensions.integrations.disconnect': { params: { cwd: string, integrationId: string, account?: string }, result: void }\n /** Makes the connection of `account` the integration's default. Additive. */\n 'extensions.integrations.setDefault': { params: { cwd: string, integrationId: string, account: string }, result: void }\n /** Which catalog items of `cwd` extensions added, changed or removed, with the extension that did it (Settings shows it). Additive. */\n 'extensions.catalogs.provenance': { params: { cwd: string, kind: CatalogKind }, result: CatalogItemProvenance[] }\n\n /** Current presence snapshot — backfill for a freshly opened session list. */\n 'presence.list': { params: Record<string, never>, result: SessionPresence[] }\n /**\n * Tag the calling peer as watching a session (one per connection; the\n * TUI opens one connection per activated session). Sent as a\n * notification right after the handshake. Detach is implicit — the\n * daemon recomputes presence when the socket drops.\n */\n 'presence.watch': { params: { sessionId: string }, result: void }\n\n /**\n * Report an integration this client runs (a channel). Registering a name\n * again from the same connection replaces it; a name another live\n * connection registered is refused. It goes away when this connection\n * closes. Every window gets `integrations:changed`. Additive.\n */\n 'integrations.register': { params: { name: string, kind: string, state: IntegrationState, detail?: string }, result: void }\n /** Change the state of an integration this connection registered; `detail` replaces the previous one (absent clears it). Additive. */\n 'integrations.update': { params: { name: string, state: IntegrationState, detail?: string }, result: void }\n /** The integrations registered on this host, in registration order. Additive. */\n 'integrations.list': { params: Record<string, never>, result: IntegrationInfo[] }\n\n /** What this host can do: OS, tools on PATH, sandbox, environment kinds, what it allows. Cached a minute; `refresh` probes again. */\n 'host.capabilities': { params: { refresh?: boolean }, result: HostCapabilities }\n /** A zidane-server's self-update: its state, the setting, the newest release seen. */\n 'server.update.status': { params: Record<string, never>, result: ServerUpdateStatus }\n /** Turn the zidane-server's self-update on or off. */\n 'server.update.configure': { params: { enabled: boolean }, result: ServerUpdateStatus }\n /**\n * Check for a newer zidane-server release now. With auto-update on, a newer\n * one installs; off, it is downloaded and verified, and the state turns `ready`.\n */\n 'server.update.check': { params: Record<string, never>, result: ServerUpdateStatus }\n /** Install the release that is `ready` or `waiting` now, without waiting for background work to finish. */\n 'server.update.install': { params: Record<string, never>, result: ServerUpdateStatus }\n /**\n * A zidane-server's recent log records, oldest first: its own lines and\n * its extensions' (setup, runtime warnings), from a bounded in-memory\n * buffer. Other hosts refuse it. Additive.\n */\n 'logs.list': { params: Record<string, never>, result: { records: LogRecord[] } }\n /** Follow the log: this connection gets `logs:record` for each new record. Calls count; a dropped connection releases its own. Additive. */\n 'logs.watch': { params: Record<string, never>, result: void }\n /** Release one `logs.watch` of this connection. */\n 'logs.unwatch': { params: Record<string, never>, result: void }\n /**\n * Follow the host's own performance (Settings › Performance on a server):\n * this connection gets `perf:sample` every 2 s. The host samples only while\n * a connection watches. Calls count; a dropped connection releases its own.\n * Additive.\n */\n 'perf.watch': { params: Record<string, never>, result: void }\n /** Release one `perf.watch` of this connection. Additive. */\n 'perf.unwatch': { params: Record<string, never>, result: void }\n /** The samples the host holds (the last 5 minutes of watching), oldest first. Additive. */\n 'perf.history': { params: Record<string, never>, result: { samples: PerfSample[] } }\n /** The OS threads of one of the processes the host lists (its own tree), busiest first. Refuses any other pid. Additive. */\n 'perf.threads': { params: { pid: number }, result: { threads: PerfOsThread[] } }\n /**\n * Where this host lets a session's folder be: a server's workspace roots\n * (`confined`: `sessions.create` / `setFolder` refuse anything outside),\n * or the user's home on a local host (unconfined). Additive.\n */\n 'fs.roots': { params: Record<string, never>, result: FsRoots }\n /**\n * The folders in `path` (default: the first root), for a folder picker on\n * the host's machine. Only inside the roots (real paths: `..` and\n * symlinks out are refused), no dotfiles. Additive.\n */\n 'fs.listDirs': { params: { path?: string }, result: FsDirListing }\n /**\n * Creates folder `name` in `parent` (inside the roots, real paths: `..` and\n * symlinks out are refused). `name` is one path segment and does not start\n * with a dot. Refused when the host turns it off (a zidane-server's\n * `allowCreateFolders`, the hello's `createFolders`). Additive.\n */\n 'fs.mkdir': { params: { parent: string, name: string }, result: FsDirEntry }\n /**\n * The folders whose name holds `query` (case-insensitive), in `path` and\n * below it (default: every root). Bounded: four levels down, 200 results,\n * no dot folders, no `node_modules`, symlinks not followed. `truncated`:\n * the result or read bound cut the search short. Additive.\n */\n 'fs.searchDirs': { params: { query: string, path?: string }, result: FsDirSearch }\n\n /*\n * A folder's git checkout. `cwd` must be a folder inside the host's\n * workspace roots (`fs.roots`); git and `gh` run as the host's user.\n * Additive (no version bump).\n */\n /** Where the checkout stands (branch, upstream, ahead / behind, uncommitted changes); `null` outside a checkout. */\n 'git.status': { params: { cwd: string }, result: GitInfo | null }\n /** The local branches, most recently committed first, each against the default branch. */\n 'git.branches': { params: { cwd: string }, result: GitBranchRow[] }\n /**\n * Open pull requests (`gh`): waiting on you, yours, then recent others; `search` searches every open one.\n * `null` without `gh` (or signed out); `rateLimited` while GitHub refuses and nothing is cached.\n */\n 'git.pullRequests': { params: { cwd: string, search?: string, fresh?: boolean }, result: GitPrListResult }\n /** `branch`'s open (or draft) pull request, or `null`. `fresh`: past the cache. */\n 'git.branchPullRequest': { params: { cwd: string, branch: string, fresh?: boolean }, result: GitPr | null }\n /** One commit's facts, for a sha chip; `null` when the repository has no such commit. */\n 'git.commit': { params: { cwd: string, sha: string }, result: GitCommitInfo | null }\n /** Each changed path's status against HEAD, untracked files included. */\n 'git.fileStatus': { params: { cwd: string }, result: GitStatusEntry[] }\n /**\n * The working tree against HEAD as a unified patch (untracked files as new files), the whole checkout or one\n * `path`, with `context` lines (absent: 3; `null`: whole files).\n */\n 'git.diff': { params: { cwd: string, path?: string, context?: number | null }, result: string }\n /**\n * Switches the checkout to a branch or a pull request (`{ pr }`, through `gh`). Never forced; refused while an\n * agent runs in the checkout (`sessionId`: the asking session, counted too). A branch another worktree holds is\n * git's refusal plus that worktree and its sessions (`sessionId` left out).\n */\n 'git.checkout': { params: { cwd: string, target: GitSwitchTarget, sessionId?: string }, result: GitCheckoutResult }\n /** Starts branch `name` from the current checkout and switches to it; refused while an agent runs in it. */\n 'git.createBranch': { params: { cwd: string, name: string, sessionId?: string }, result: GitCheckoutResult }\n /** Pulls (merging) then pushes the current branch, or publishes it without an upstream; refused while an agent runs in it. */\n 'git.sync': { params: { cwd: string, sessionId?: string }, result: GitSyncResult }\n /**\n * Clones `input` (a git or forge URL, or `owner/repo`) into a new folder of `parent` (inside the roots). A folder\n * already holding that repository is answered as `existed`. One clone per connection; git's progress comes as\n * `git:clone:progress` signals to the caller only. A dropped connection cancels it. Refused when the host turns\n * cloning off (a zidane-server's `allowClone`, the hello's `clone`).\n */\n 'git.clone': { params: { input: string, parent: string }, result: RepoCloneResult }\n /** Cancels this connection's clone: the half-cloned folder is removed and `git.clone` answers `cancelled`. */\n 'git.cloneCancel': { params: Record<string, never>, result: void }\n /**\n * Follows `cwd`'s checkout: once its refs move (a commit, a fetch, a push, a\n * branch switch, from this host or any other process), this connection\n * gets `git:refs` for `cwd`. `false`: not a repository, nothing watched.\n * Calls count: each `git.watch` takes one `git.unwatch`; a dropped\n * connection releases its own. Additive.\n */\n 'git.watch': { params: { cwd: string }, result: boolean }\n /** Releases one `git.watch` of `cwd` by this connection. */\n 'git.unwatch': { params: { cwd: string }, result: void }\n\n /*\n * A folder's files beyond what a session's workspace reads: `cwd` must be a folder inside the host's workspace\n * roots. Additive (no version bump).\n */\n /**\n * Lines containing `query` (fixed string, at most 500 characters) under `cwd`: ripgrep, else `git grep`, else a\n * walk. A later search with the same `searchId` on the connection cancels this one.\n */\n 'files.search': { params: { cwd: string, query: string, caseSensitive?: boolean, searchId?: string }, result: ContentSearchResult }\n /** What names in prose point at (files, folders, else branches), in order: what a transcript's path chips open. */\n 'files.resolvePaths': { params: { cwd: string, texts: string[] }, result: ResolvedPath[] }\n /** The files under `cwd` and the folders holding them, as `@` completes them: git's list (ignore rules kept), else a walk; capped. */\n 'files.list': { params: { cwd: string }, result: FileEntry[] }\n /** Where `cwd` sits: its git checkout (the folder itself outside git) and its project (the main checkout for a worktree). */\n 'files.location': { params: { cwd: string }, result: FolderLocation }\n /**\n * Runs the project's own linters and typecheckers on `paths` (relative to `cwd`), cached until the files move.\n * `disabled`: tool ids switched off; `timeoutMs`: per tool.\n */\n 'files.diagnostics': { params: { cwd: string, paths: string[], disabled?: string[], timeoutMs?: number }, result: DiagnosticsResult }\n /** Drops the cached diagnostics of `cwd`: the next run checks again. */\n 'files.diagnosticsInvalidate': { params: { cwd: string }, result: void }\n /** The diagnostics tools and whether each runs for `cwd` (configured, missing its binary, not used). */\n 'files.diagnosticsTools': { params: { cwd: string }, result: DiagnosticsToolInfo[] }\n /**\n * Lets this connection's media play from `GET /zidane/media`\n * (`SERVER_MEDIA_PATH`): `?ticket&cwd&path` serves a file of a folder in\n * the workspace roots, `&side=old|new` one side of its git change, with\n * byte ranges, for an image, a video or audio only. The client picks the\n * ticket (at least 32 random URL-safe characters) so an address is known\n * before the call lands; it is good while this connection is open and\n * carries its token's scope. One per connection: a new one replaces it.\n * Only a zidane-server serves media. Additive.\n */\n 'files.mediaTicket': { params: { ticket: string }, result: void }\n\n /**\n * The host's provider credentials, as the host's agents use them (its\n * data dir's `credentials.json` and environment): per provider, whether\n * something is configured, its stored API key / OAuth accounts (labels,\n * which is active) and an env var it reads. Never a secret. Additive.\n */\n 'auth.status': { params: Record<string, never>, result: { providers: HostProviderAuth[] } }\n /**\n * Store an API key for one of the host's providers as its active\n * credential, apply it to the host's environment, and rebuild agents\n * (idle now, busy ones at run end). Returns the provider's new status.\n * OAuth sign-in goes through `auth.oauth.*`. Additive.\n */\n 'auth.setApiKey': { params: { provider: string, key: string }, result: HostProviderAuth }\n /**\n * Remove one stored credential (`account`: its key from `auth.status`) or,\n * without one, every stored credential of the provider; then as\n * `auth.setApiKey`. A key the host only has from its own environment is\n * left alone. Additive.\n */\n 'auth.remove': { params: { provider: string, account?: string }, result: { removed: boolean, provider: HostProviderAuth } }\n /**\n * Stores a provider's API key and its custom fields (a local server's URL,\n * a cloud's region; `onboarding.providers` lists them), merged into the\n * stored credential: a field left out keeps its value, an empty one is\n * removed (a blank secret keeps the stored one), a required one may not be\n * emptied, no `value` keeps the stored key. Additive.\n */\n 'auth.configure': { params: { provider: string, value?: string, customFields?: Record<string, string> }, result: HostProviderAuth }\n /**\n * Make one of a provider's stored credentials the active one (`target`: an\n * account key from `auth.status`, or the first stored one of a source),\n * then as `auth.setApiKey`. A credential no longer stored is refused.\n * Additive.\n */\n 'auth.setPreferred': { params: { provider: string, target: 'apikey' | 'oauth' | { key: string } }, result: HostProviderAuth }\n /** Rename a stored OAuth account (`account`: its key from `auth.status`). Presentation only: nothing is rebuilt. Additive. */\n 'auth.rename': { params: { provider: string, account: string, label: string }, result: HostProviderAuth }\n /**\n * OAuth sign-in with the browser on the CLIENT and the tokens on the host:\n * the host starts a provider's login (`provider`) or an MCP server's\n * (`mcpServer`, found in `cwd`'s catalog, as `catalog.mcps`), keeping the\n * PKCE verifier and `state`, and answers with the authorization URL.\n * `mode: 'loopback'`: the client listens at `redirectUri` (a provider's\n * fixed port; for an MCP server the loopback URI the client passed) and\n * forwards the code; `'browser'`: the client opens `url` (pasting a code if\n * the page shows one); `'device'`: shows `userCode`. The flow belongs to\n * this connection, is single-use and expires (`expiresAt`). Additive.\n *\n * A client that can't listen (a browser) signs in to an MCP server through\n * a zidane-server's own redirect: `redirectUri` is the server's\n * `/zidane/oauth/callback` (`SERVER_OAUTH_CALLBACK_PATH`) at the origin\n * the client reaches it by. The server takes the code there and the flow\n * is `'browser'` (the client opens `url`, then `complete`s without a\n * code). A server whose pre-registered client pins its redirect stays\n * `'loopback'`: its page fails to load and the user pastes that page's\n * address (`complete` with `input`).\n */\n 'auth.oauth.begin': { params: { provider?: string, mcpServer?: string, cwd?: string, kind?: string, redirectUri?: string }, result: HostOAuthBegin }\n /**\n * Deliver the code (`code` + `state` from the loopback, or `input`: what\n * the user pasted) once, then wait for the host's token exchange; without\n * either, just wait (device and polling flows). A wrong `state` or another\n * connection's flow is refused. Tokens stay on the host: the result says\n * what changed, never a secret.\n */\n 'auth.oauth.complete': { params: { flowId: string, code?: string, state?: string, input?: string }, result: HostOAuthComplete }\n /**\n * Answer the step a flow is waiting on (`HostOAuthBegin.step` before its\n * URL, `HostOAuthComplete.step` after): a select's option id (none:\n * cancel), a prompt's text. Answers with where the flow is now: its URL, or\n * the next step. Then `complete` as before. Additive.\n */\n 'auth.oauth.respond': { params: { flowId: string, stepId: string, value?: string }, result: HostOAuthBegin }\n /** Abandon a flow of this connection. */\n 'auth.oauth.cancel': { params: { flowId: string }, result: { cancelled: boolean } }\n\n /**\n * What the host discovered for the settings tabs, each entry with whether\n * the host's settings enable it (an unset allowlist enables everything).\n * `cwd` adds the project scope of that folder (inside the workspace roots\n * on a server); without it, the user scope (the host user's home). The\n * enabled lists are written with `settings.set`. Installing, removing and\n * MCP sign-in stay on the host's machine. Additive.\n */\n 'catalog.skills': { params: { cwd?: string, kind?: string }, result: { skills: HostCatalogSkill[] } }\n /** MCP servers: `env` and `headers` values, URL credentials and query values are redacted. */\n 'catalog.mcps': { params: { cwd?: string, kind?: string }, result: { servers: HostCatalogMcp[], errors: HostCatalogError[] } }\n /** Extensions installed for `cwd`. */\n 'catalog.extensions': { params: { cwd?: string, kind?: string }, result: { extensions: HostCatalogExtension[] } }\n /** Plugins installed for `cwd`, with what each contributes. */\n 'catalog.plugins': { params: { cwd?: string, kind?: string }, result: { plugins: HostCatalogPlugin[] } }\n /**\n * Install a skill or an extension on the host, in its user's scope only\n * (`scope` may only be `'user'`): a GitHub (`owner/repo[#ref][:dir]`, a\n * GitHub URL, a skills.sh URL) or npm spec; paths are refused. `skills` /\n * `all` pick from a multi-skill source (the `multiple-candidates` error\n * lists them), `extension` from a multi-extension one (an extension's\n * `multiple-candidates` or `no-extension` error carries the names found as\n * {@link ExtensionInstallErrorData}). Runs the host's\n * package managers and fetches code there: a zidane-server's\n * `allowRemoteInstalls` gates it, every attempt is audited. Bounded in\n * time; the progress lines come back with the result. Every window gets\n * `catalog:changed`. Additive (`remoteInstalls` on `ipc.hello`).\n */\n 'catalog.install': { params: { kind: HostInstallKind, spec: string, scope?: 'user', skills?: string[], all?: boolean, extension?: string, overwrite?: boolean }, result: { installed: string[], message: string, progress: string[] } }\n /** Remove a user-scope skill or extension of the host by name (its directory). As `catalog.install`. */\n 'catalog.remove': { params: { kind: HostInstallKind, name: string }, result: { removed: string, message: string } }\n /** Update a user-scope extension installed from a source. As `catalog.install`. */\n 'catalog.update': { params: { kind: HostInstallKind, name: string }, result: { updated: string, upToDate: boolean, message: string } }\n /** The skills of a source (`owner/repo[#ref][:dir]`, a GitHub or skills.sh URL), fetched by the host with its GitHub login; `catalog.install` with `skills` installs picked ones. Additive. */\n 'skills.browse': { params: { source: string }, result: SkillSourceListing }\n /**\n * The extensions of a source (`owner/repo[#ref][:dir]`, a GitHub URL, an\n * npm package, or a folder on the host), read from their manifests by the\n * host with its GitHub login; nothing runs. Never fails for an unreadable\n * source: the listing carries `error` (the default source `Tahul/zidane`\n * then lists the native catalog, `builtin: true`). Each row's `install`\n * is what `catalog.install` takes (`spec`, `extension`). Additive.\n */\n 'extensions.browse': { params: { source: string }, result: ExtensionSourceListing }\n /**\n * Install an installed extension again from another source (GitHub or\n * npm): the source must hold an extension of the same `name` (else the\n * `name-mismatch` install error, its `data` an\n * {@link ExtensionInstallErrorData} with the names found); the folder is\n * replaced only once the new copy validated, and `.install.json`\n * records the new source, which `catalog.update` then follows. A\n * zidane-server takes `scope: 'user'` only, gated and audited as\n * `catalog.install`. Additive.\n */\n 'extensions.changeOrigin': { params: { name: string, scope: 'user' | 'project', source: string }, result: { name: string, origin: ExtensionInstallOrigin, message: string, progress: string[] } }\n /**\n * What the setup wizard finds on the host's machine for `cwd` (default:\n * the host user's home): the providers and their credentials, other agents\n * to import from, local model servers and the install signals. Additive.\n */\n 'onboarding.detect': { params: { cwd?: string }, result: OnboardingDetection }\n /** The providers as the wizard's Connect step lists them, with their custom fields and the model each runs when none is picked. Additive. */\n 'onboarding.providers': { params: { cwd?: string }, result: HostOnboardingProvider[] }\n /**\n * The setup wizard's write: `settings.set` sets (`settings.reset` back to\n * their defaults, unless also set), as `settings.set` applies them, and\n * `records` (the run finished, its steps) merged into the host's stored\n * ones. Returns the settings in effect. Additive.\n */\n 'onboarding.complete': { params: { settings: OnboardingSettingsChange, records: OnboardingState }, result: HostSettings }\n /** What `~/.claude` on the host holds: whether there is a setup, and its transcripts for `cwd` and in every project. Additive. */\n 'claudeImport.detect': { params: { cwd?: string }, result: ClaudeImportDetection }\n /** What each piece of the Claude Code import would copy and skip. Additive. */\n 'claudeImport.preview': { params: { cwd?: string }, result: OnboardingImportPreview }\n /**\n * Imports a Claude Code setup into the host's own places: conversations\n * into its session store, MCP servers, skills, commands and subagents into\n * the host user's files. Idempotent (what is there is skipped, never\n * overwritten). It copies commands the host will run: a zidane-server's\n * `allowRemoteInstalls` gates it, every attempt is audited. Every window\n * gets `catalog:changed`. Additive.\n */\n 'claudeImport.run': { params: { cwd?: string } & ClaudeImportSelection, result: ClaudeImportSummary }\n /**\n * Add or replace an MCP server in the host user's `mcps.json`, or with\n * `scope: 'project'` in `cwd`'s project (a folder inside the workspace\n * roots on a server). Its `env` / `headers` values are stored there and\n * never come back (`catalog.mcps` redacts them, the reply names the server\n * only). `clientSecret`, the secret of its `oauth` client, goes to the\n * host's MCP credential store, never to `mcps.json`; an entry without an\n * `oauth` client drops a stored one. As `catalog.install`.\n */\n 'mcp.upsert': { params: { config: McpServerConfig, scope?: 'user' | 'project', cwd?: string, clientSecret?: string }, result: { name: string, created: boolean } }\n /** Remove an MCP server from the host user's `mcps.json`; `removed: false` when it has none. As `catalog.install`. */\n 'mcp.remove': { params: { name: string }, result: { removed: boolean } }\n /**\n * Connect to one of `cwd`'s MCP servers (as `catalog.mcps`), list its\n * tools into the host's tools cache and record how it went: the server's\n * new `status`. Every window gets `catalog:changed`. Additive.\n */\n 'mcp.test': { params: { name: string, cwd?: string, kind?: string }, result: McpServerStatus }\n /** Forget an MCP server's sign-in on the host (its tokens). Every window gets `catalog:changed`. Additive. */\n 'mcp.signOut': { params: { name: string }, result: void }\n /**\n * The host's shared MCP server processes (`src/mcp/server-pool.ts`),\n * `cwd`'s only when given: name, folder, shared or per session, how many\n * sessions hold it, its pid, whether it is retired. Remote servers and\n * `scope: 'context'` ones are never listed (they are per session). Additive.\n */\n 'mcp.instances': { params: { cwd?: string }, result: McpServerInstance[] }\n /**\n * End `name`'s process now (in `cwd` only, when given) for every session\n * holding it. Calls in flight fail with \"<name> restarted\" and are not\n * retried; the next call starts a fresh process. Answers how many\n * processes were restarted (0: none was running). Additive.\n */\n 'mcp.restart': { params: { name: string, cwd?: string }, result: { restarted: number } }\n /**\n * The host's credentialed providers (what its agents can run) and their\n * models, for a model picker of a session on that host. `cwd` adds the\n * providers its extensions contribute there. Additive.\n */\n 'models.list': { params: { cwd?: string, kind?: string }, result: { providers: HostModelProvider[] } }\n /**\n * Send one tiny decision with this host's credentials, to check a decision\n * model works. `model` is `\"providerKey/modelId\"`, tested exactly; omitted =\n * the host's `Settings.decisionModel` (or the first available). Never\n * fails: a broken model comes back as `ok: false` with a reason. Additive.\n */\n 'decisions.test': { params: { cwd?: string, kind?: string, model?: string }, result: HostDecisionTestResult }\n /**\n * Send one tiny prompt with this host's credentials, to check a chat model\n * answers. `model` is `\"providerKey[@account]/modelId\"`, tested exactly.\n * Never fails: a broken model comes back as `ok: false` with a reason.\n * Additive.\n */\n 'models.test': { params: { cwd?: string, kind?: string, model: string }, result: HostModelTestResult }\n\n /**\n * The machines this host knows (`docs/MACHINES.md`), online or not, and\n * forgetting one (it disconnects; its `local@` / `worktree@` kinds stop\n * resolving). Additive.\n */\n 'machines.list': { params: Record<string, never>, result: MachineInfo[] }\n /** Forgets a machine. It disconnects and its kinds stop resolving. */\n 'machines.forget': { params: { machineId: string }, result: { forgotten: boolean } }\n /**\n * Folders of a machine, for a client's folder picker: the host proxies a\n * listing to the machine (`fs.list`, confined to its roots there): the\n * folders in `path` (absent: its first root), and every root. Additive.\n */\n 'machines.listDirs': { params: { machineId: string, path?: string }, result: { path: string, dirs: string[], roots: string[] } }\n /**\n * A local host's machine links (`docs/MACHINES.md` § Client UI), behind\n * remote hosts: share this computer with a saved server (the machine agent\n * runs in this host's process, with the machine token `token` or the one\n * already stored for that server), stop sharing, use a saved server as a\n * machine (reverse direction), and read their state. Refused while remote\n * hosts are off. Additive.\n */\n 'machines.share.start': { params: { hostId: string, name: string, roots: string[], token?: string }, result: MachineLinksStatus }\n /** Stops sharing this computer with a server. */\n 'machines.share.stop': { params: { hostId: string }, result: MachineLinksStatus }\n /** Turns on or off using a server as this computer's linked server. */\n 'machines.useServer': { params: { hostId: string, enabled: boolean }, result: MachineLinksStatus }\n /** State of this host's machine links: the shares it offers and the servers it uses. */\n 'machines.links.status': { params: Record<string, never>, result: MachineLinksStatus }\n /**\n * Reverse direction (`docs/MACHINES.md` § Reverse direction): a client asks\n * this server to lend itself as a machine over this very connection\n * (`allowAsMachine` on, else refused). `hostId` names the asking host, so\n * a reconnect finds its tasks and terminals again. Then `machine.call`\n * carries each host→machine request (`MachineMethods`), answered by the\n * server's confined executor; machine notifications come back as\n * `machine:notification` signals on this connection only.\n */\n 'machine.attach': { params: { hostId: string }, result: MachineRegisterParams }\n /** Runs one machine-protocol method on this server's executor and resolves with its JSON result. Refused when the server does not lend itself as a machine. */\n 'machine.call': { params: { method: string, params?: JsonValue }, result: JsonValue }\n /** Ends this connection's machine attachment. `detached` is `false` when it had none. */\n 'machine.detach': { params: Record<string, never>, result: { detached: boolean } }\n /**\n * Mint a `machine`-scoped token on this server (a zidane-server only), so\n * a window can share its computer in one step. An admin token may\n * (`./scopes`). Audited.\n */\n 'tokens.createMachineToken': { params: { name: string }, result: { id: string, name: string, token: string } }\n /** This server's tokens, revoked ones included, never their secrets (a zidane-server only). Additive. */\n 'tokens.list': { params: Record<string, never>, result: ServerTokenInfo[] }\n /**\n * Create a token with a scope (`./scopes`; `machine` lends a computer). The secret is in the\n * result only: show it once. Bound to the calling token (`createdBy`), so revoking that one\n * revokes this one too. Audited. Additive.\n */\n 'tokens.create': { params: { name: string, scope: ServerTokenScope }, result: ServerTokenInfo & { token: string } }\n /**\n * Revoke a live token by id, with the live tokens it minted; their connections drop and the\n * runs and terminals they started stop. Audited. Additive.\n */\n 'tokens.revoke': { params: { id: string }, result: { revoked: ServerTokenInfo[] } }\n /**\n * Revoke the token this connection authenticated with, and the live tokens it minted (a\n * browser's sign out). Any client scope may: it only gives up its own access. Audited. Additive.\n */\n 'tokens.revokeSelf': { params: Record<string, never>, result: { revoked: ServerTokenInfo[] } }\n /**\n * Issue a one-time pairing code (`XXXX-XXXX`, a zidane-server only): a browser posts it to\n * `POST /zidane/pair` and gets a token of `scope`, named `browser: <name>` and bound to the\n * calling token (`createdBy`). `ttlMs`: 30000 to 3600000, default 600000. Single use; five\n * wrong secrets burn it. Audited. Additive.\n */\n 'tokens.pair': { params: { scope: ClientScope, ttlMs?: number, name?: string }, result: { code: string, expiresAt: number } }\n /**\n * Issue a one-time machine join code (a zidane-server only): a machine posts it to\n * `POST /zidane/pair` and gets a machine token named `name`. A public server caps\n * `ttlMs` at 10 minutes. Audited as `pair.create` with scope `machine`. Additive.\n */\n 'tokens.machineInvite': { params: { name?: string, ttlMs?: number }, result: { code: string, expiresAt: number } }\n\n /**\n * Settings sync, a client's computer → this server (`docs/SERVER.md`\n * § Settings sync). A zidane-server only; other hosts refuse. One source\n * device per server: `sync.claim` makes the caller it (or says who is,\n * unless `takeover`), `sync.push` applies one category's snapshot through\n * the host's own setters, skipping fields edited here since (overrides),\n * `sync.reset` drops an override, `sync.release` stops the source. Every\n * call is audited with its token. Additive.\n */\n 'sync.status': { params: Record<string, never>, result: SyncStatus }\n /** Makes the caller the settings source device. When another device is the source, the result says which, unless `takeover` is set. `categories` and `keys` narrow what it syncs. */\n 'sync.claim': { params: { deviceId: string, deviceName: string, takeover?: boolean, categories?: SyncCategory[], keys?: string[] }, result: SyncClaimResult }\n /** Applies one category's snapshot from the source device. */\n 'sync.push': { params: { deviceId: string, category: SyncCategory, payload: SyncPayload }, result: SyncPushResult }\n /** Drops the local override of one field so sync applies to it again. */\n 'sync.reset': { params: { field: string }, result: { reset: boolean } }\n /** Stops the source device's sync. */\n 'sync.release': { params: { deviceId: string }, result: { released: boolean } }\n\n /** Daemon identity and version: `protocolVersion`, `appVersion`, `pid`, `startedAt` and the host identity fields of the `hello` result. */\n 'daemon.info': { params: Record<string, never>, result: HelloResult }\n /**\n * The processes the daemon started for its own work (MCP servers, bounded\n * tool runs such as git and linters), which lead their own process group\n * like a session's command does. The desktop app's performance monitor\n * counts them as the app's. Additive: an older daemon answers \"method not\n * found\", read as none.\n */\n 'daemon.ownedProcesses': { params: Record<string, never>, result: OwnedProcess[] }\n /**\n * The processes the daemon started for a session (its shell tool's\n * commands and background tasks, its terminals, its own MCP servers), by\n * session id. The desktop app's performance monitor shows what each session\n * uses. Additive: an older daemon answers \"method not found\", read as none.\n */\n 'daemon.sessionProcesses': { params: Record<string, never>, result: SessionProcess[] }\n /**\n * Graceful drain: deny pending approvals, abort live runs, close the\n * socket. Used by clients that detect a protocol-version mismatch and\n * need the stale daemon gone before respawning.\n *\n * `whenIdle` (version-skew retirement): a daemon with active work does\n * NOT abort it. It answers `{ deferred: true }` and exits once idle.\n * Explicit stops (`zidane daemon stop`) omit it and drain immediately.\n * Daemons predating the flag ignore it and drain immediately.\n */\n 'daemon.shutdown': { params: { whenIdle?: boolean }, result: { deferred?: boolean } | void }\n}\n\n/**\n * The host's identity from a hello (or `daemon.info`) reply; `null` from a host that predates it.\n * @param hello - The `hello` or `daemon.info` result.\n * @returns The host reference, or `null` when the reply carries no host id or kind.\n */\nexport function hostRefOf(hello: HelloResult): HostRef | null {\n if (typeof hello.hostId !== 'string' || !hello.hostKind)\n return null\n return { id: hello.hostId, kind: hello.hostKind, name: hello.hostName ?? hello.hostId }\n}\n\n/** Name of any method in {@link IpcMethods}. */\nexport type IpcMethodName = keyof IpcMethods\n/** Params type of the method `M` in {@link IpcMethods}. */\nexport type IpcParams<M extends IpcMethodName> = IpcMethods[M]['params']\n/** Result type of the method `M` in {@link IpcMethods}. */\nexport type IpcResult<M extends IpcMethodName> = IpcMethods[M]['result']\n\n/** Turns per `sessions.loadEvents` page when only `before` is given. */\nexport const LOAD_EVENTS_PAGE_TURNS = 200\n/** Largest `limit` a host honors. */\nexport const LOAD_EVENTS_MAX_PAGE_TURNS = 1000\n\n/** Paging options of `sessions.loadEvents`. */\nexport interface LoadEventsPaging {\n /** Turn position (exclusive) the page ends at: a previous page's `cursor`. */\n before?: number\n /** Turns in the page. */\n limit?: number\n /**\n * The page ends right before the turn with this id (same alignment as\n * `before` at its position); wins over `before`. A turn the stored\n * transcript doesn't hold fails the request (invalid params, the message\n * names `beforeTurnId`). An older host ignores it: see\n * {@link SessionEventsPage.beforeTurnId}.\n */\n beforeTurnId?: string\n}\n\n/** One page of a session's stream events, as `sessions.loadEvents` answers it. */\nexport interface SessionEventsPage {\n /** Stream events of the page. */\n events: StreamEvent[]\n /** Pass as `before` for the page before this one; absent once the first turn is in. */\n cursor?: number\n /**\n * The events are this page's slice of the whole replay, so pages\n * concatenate to exactly one whole `loadEvents`. Absent from an older\n * host, whose pages replay on their own ({@link loadAllEvents} restores\n * the exchange separator at their joins).\n */\n exact?: true\n /**\n * With `exact`: how many events of the whole replay come before this\n * page. Lets a client open on the tail of a long transcript and still\n * say how much it left out ({@link loadEventsTail}). Absent from an\n * older host.\n */\n start?: number\n /**\n * The request's `beforeTurnId`, echoed: absent when the host ignored\n * the anchor (an older host, which then paged by `before` / from the end).\n */\n beforeTurnId?: string\n}\n\n/**\n * One page of `sessions.loadEvents` (see its paging). An older host answers\n * the whole transcript: it comes back as one page with no cursor.\n * @param request - Sends `sessions.loadEvents` to the host.\n * @param params - Session id and paging.\n * @returns The page, normalized from either host reply shape.\n */\nexport async function loadEventsPage(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n params: { sessionId: string } & LoadEventsPaging,\n): Promise<SessionEventsPage> {\n const result = await request('sessions.loadEvents', params) as StreamEvent[] | SessionEventsPage\n return Array.isArray(result) ? { events: result } : result\n}\n\nfunction isResponseTooLarge(err: unknown): boolean {\n return typeof err === 'object' && err !== null && (err as { code?: unknown }).code === IpcErrorCode.ResponseTooLarge\n}\n\n/**\n * A session's whole transcript, loaded a page at a time from the end so no\n * single reply carries it all (a long session with images can outgrow a\n * transport's message size). A page refused as too large is asked again at\n * half the turns, down to one; a single turn that still doesn't fit fails\n * the load. An older host answers the whole transcript to the first call.\n * @param request - Sends `sessions.loadEvents` to the host.\n * @param sessionId - Session to load.\n * @param options - Paging options.\n * @param options.pageTurns - Turns per page to start with.\n * @returns Every stream event of the session.\n */\nexport async function loadAllEvents(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n sessionId: string,\n options: { pageTurns?: number } = {},\n): Promise<StreamEvent[]> {\n return (await loadEventsFromEnd(request, sessionId, options.pageTurns ?? LOAD_EVENTS_PAGE_TURNS)).events\n}\n\n/**\n * The end of a session's transcript: pages from the end until `enough`\n * holds for what was loaded (or the first turn is in), and how many events\n * of the whole replay come before it (`earlier`). Only exact pages can stop\n * early, since only they say where they start: an older host's transcript\n * loads whole, with `earlier` 0.\n */\nexport async function loadEventsTail(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n sessionId: string,\n enough: (events: readonly StreamEvent[]) => boolean,\n options: { pageTurns?: number } = {},\n): Promise<{ events: StreamEvent[], earlier: number }> {\n return loadEventsFromEnd(request, sessionId, options.pageTurns ?? LOAD_EVENTS_PAGE_TURNS, enough)\n}\n\nasync function loadEventsFromEnd(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n sessionId: string,\n pageTurns: number,\n enough?: (events: readonly StreamEvent[]) => boolean,\n): Promise<{ events: StreamEvent[], earlier: number }> {\n let limit = pageTurns\n const pages: StreamEvent[][] = []\n let newerExact = false\n let allExact = true\n let before: number | undefined\n for (;;) {\n let page: SessionEventsPage\n try {\n page = await loadEventsPage(request, { sessionId, limit, ...(before !== undefined ? { before } : {}) })\n }\n catch (err) {\n if (isResponseTooLarge(err) && limit > 1) {\n limit = Math.max(1, Math.floor(limit / 2))\n continue\n }\n throw err\n }\n /*\n * An exact page is a slice of the whole replay: nothing to restore. An\n * older host's pages replay on their own, so the exchange separator a\n * whole replay puts before a prompt that follows an exchange is missing\n * where the newer page starts (its pages start at a prompt when they\n * can): put it back.\n */\n const newer = pages[0]\n if (newer && !newerExact && newer[0]?.kind === 'user-prompt' && page.events.length > 0)\n newer.unshift({ kind: 'separator', text: '' })\n newerExact = page.exact === true\n allExact &&= newerExact && page.start !== undefined\n pages.unshift(page.events)\n // Done at the first turn; a cursor that doesn't move back would loop.\n if (page.cursor === undefined || page.cursor <= 0 || (before !== undefined && page.cursor >= before))\n break\n if (enough && allExact) {\n const events = pages.flat()\n if (enough(events))\n return { events, earlier: page.start! }\n }\n before = page.cursor\n }\n return { events: pages.flat(), earlier: 0 }\n}\n\n/** Turns per `sessions.getTurns` page by default. */\nexport const SESSION_TURNS_PAGE = 200\n/** Largest `limit` a host honors for `sessions.getTurns`. */\nexport const SESSION_TURNS_MAX_PAGE = 1000\n\ntype SessionDocumentRequest = <M extends 'sessions.get' | 'sessions.getTurns'>(method: M, params: IpcParams<M>) => Promise<IpcResult<M>>\n\n/**\n * What `sessions.get` answers: the document; with `turns: false`, the\n * version of the snapshot it was cut from, the one `sessions.getTurns`\n * pages carry.\n */\nexport type SessionDocumentHead = SessionData & { version?: string }\n\n/** How many times a paged read starts over because the session changed under it, before it asks for the whole document in one reply. */\nconst SESSION_DOCUMENT_RESTARTS = 3\n\n/**\n * A session's whole document, read a page of turns at a time so no reply\n * carries it all (`sessions.getTurns` pages, then the `sessions.get`\n * `turns: false` head; a page refused as too large is asked again at half\n * the turns). Every page and the head name the snapshot they come from: a\n * version change mid-read (a turn appended, a compaction) starts the read\n * over, so the result is one version, never pages of two. After\n * {@link SESSION_DOCUMENT_RESTARTS} restarts (a session busier than the\n * read), the whole document comes in one reply. A host that predates\n * `sessions.getTurns` sends it that way too; one that names no version is\n * read as before. `null` when the host doesn't know the session.\n * @param request - Sends `sessions.get` and `sessions.getTurns` to the host.\n * @param sessionId - Session to read.\n * @param options - Paging options.\n * @param options.pageTurns - Turns per page to start with.\n * @returns The session document, or `null` when unknown.\n */\nexport async function loadSessionDocument(\n request: SessionDocumentRequest,\n sessionId: string,\n options: { pageTurns?: number } = {},\n): Promise<SessionData | null> {\n const paging = { limit: options.pageTurns ?? SESSION_TURNS_PAGE }\n for (let attempt = 0; attempt <= SESSION_DOCUMENT_RESTARTS; attempt++) {\n const read = await readSessionDocumentOnce(request, sessionId, paging)\n if (read !== 'changed')\n return read\n }\n return withoutVersion(await request('sessions.get', { sessionId }))\n}\n\nfunction withoutVersion(head: SessionDocumentHead | null): SessionData | null {\n if (!head)\n return null\n const { version: _version, ...data } = head\n return data\n}\n\n/** One paged read; `'changed'`: the version moved between two of its replies. */\nasync function readSessionDocumentOnce(request: SessionDocumentRequest, sessionId: string, paging: { limit: number }): Promise<SessionData | null | 'changed'> {\n const turns: SessionTurn[] = []\n let total = Infinity\n let version: { of?: string } | null = null\n while (turns.length < total) {\n let page: IpcResult<'sessions.getTurns'>\n try {\n page = await request('sessions.getTurns', { sessionId, from: turns.length, limit: paging.limit })\n }\n catch (err) {\n if (turns.length === 0 && isMethodNotFound(err))\n return withoutVersion(await request('sessions.get', { sessionId }))\n if (isResponseTooLarge(err) && paging.limit > 1) {\n paging.limit = Math.max(1, Math.floor(paging.limit / 2))\n continue\n }\n throw err\n }\n if (!page)\n return null\n if (version === null)\n version = { ...(page.version !== undefined ? { of: page.version } : {}) }\n else if (page.version !== version.of)\n return 'changed'\n total = page.total\n // A session that shrank meanwhile on a host that names no version ends the read where it is.\n if (page.turns.length === 0)\n break\n turns.push(...page.turns)\n }\n const head = await request('sessions.get', { sessionId, turns: false })\n if (!head)\n return null\n if (version !== null && head.version !== version.of)\n return 'changed'\n return { ...withoutVersion(head)!, turns }\n}\n\n/** A catalog entry's on/off state as the host's settings decide it. */\ninterface HostCatalogToggle {\n name: string\n /** The host's settings enable it (always `false` for an entry that cannot load). */\n enabled: boolean\n /**\n * Its own allowlist governs it (`enabledSkills`, …). `false`: contributed\n * by a plugin or extension (their toggle governs it), or broken.\n */\n toggleable: boolean\n}\n\n/** A skill in the host's catalog. */\nexport interface HostCatalogSkill extends HostCatalogToggle {\n /** What the skill is for. */\n description: string\n /** Where the skill was found. */\n source?: 'project' | 'user' | 'inline' | 'builtin'\n /** `SKILL.md` on the host's machine. */\n location?: string\n /** `disk`: a scan path; else the plugin or extension that contributes it (`contributedBy`). */\n origin: 'disk' | 'plugin' | 'extension'\n /** Name of the plugin or extension that contributes the skill, when `origin` is not `disk`. */\n contributedBy?: string\n}\n\n/** Every secret-bearing value of a catalog entry is replaced by this. */\nexport const REDACTED = '<redacted>'\n\n/** An MCP server in the host's catalog. Secret values are redacted. */\nexport interface HostCatalogMcp extends HostCatalogToggle {\n /** How the server is reached. */\n transport: 'stdio' | 'sse' | 'streamable-http'\n /** Whether the config is the project's or the user's. */\n source: 'project' | 'user'\n /** The config file on the host's machine. */\n path: string\n /** Command that starts a `stdio` server. */\n command?: string\n /** Arguments of the command. */\n args?: string[]\n /** Credentials and query values redacted. */\n url?: string\n /** Working directory of the command. */\n cwd?: string\n /** `context` runs the server in the agent's execution context. `host` runs it on the host. Always sent for a `stdio` server (absent from an older host). */\n scope?: 'host' | 'context'\n /** Its config's `shared` (absent: `true`): one process for every session. The host's `mcpSharing` setting wins over it. */\n shared?: boolean\n /** `oauth` when the server signs in with OAuth. */\n auth?: 'oauth'\n /** Names only: every value is {@link REDACTED}. */\n env?: Record<string, string>\n /** Header names. Every value is {@link REDACTED}. */\n headers?: Record<string, string>\n /** Its sign-in state, tools as last listed and last Test (`mcp.test`) on the host. Absent from an older host. */\n status?: McpServerStatus\n}\n\n/** A config file that failed to parse (or an informational skip). */\nexport interface HostCatalogError {\n /** Path of the config file. */\n path: string\n /** Whether the file is the project's or the user's. */\n source: 'project' | 'user'\n /** Why it failed or was skipped. */\n message: string\n /** `true` when the entry is a skip notice, not a failure. */\n informational?: boolean\n}\n\n/** An extension in the host's catalog. */\nexport interface HostCatalogExtension extends HostCatalogToggle {\n /** Where the extension was found. */\n source: 'user' | 'project' | 'inline' | 'builtin'\n /** Version from the extension manifest. */\n version?: string\n /** What the extension does. */\n description?: string\n /** Directory of the extension on the host's machine. */\n dir?: string\n /** Why it did not load. */\n error?: string\n /** What it contributes: `tools`, `skills`, `mcps`, `commands`, … */\n capabilities?: string[]\n /** Its display name (the definition's `displayName`, else the manifest's). Absent: the name. Additive. */\n displayName?: string\n /** Its icon (the definition's `icon`, else the manifest's): what `extensionMark` reads. Additive. */\n icon?: { gui?: string, tui?: string }\n /** The source it was installed from (`.install.json`), which an update follows. Absent: not installed from a source. Additive. */\n origin?: ExtensionInstallOrigin\n}\n\n/** A plugin in the host's catalog. */\nexport interface HostCatalogPlugin extends HostCatalogToggle {\n /** Where the plugin comes from: a directory on disk, or an extension. */\n origin: { kind: 'disk', scope: 'project' | 'user', dir: string } | { kind: 'extension', extensionName: string, dir: string }\n /** `false`: the manifest was rejected (`error` says why). */\n ok: boolean\n /** Version from the plugin manifest. */\n version?: string\n /** What the plugin does. */\n description?: string\n /** Names of the skills the plugin contributes. */\n skills: string[]\n /** Names of the MCP servers the plugin contributes. */\n mcpServers: string[]\n /** Why the manifest was rejected, when `ok` is `false`. */\n error?: string\n}\n\n/** One provider a host can run, with its models (`models.list`). */\nexport interface HostModelProvider {\n /** Provider key. */\n key: string\n /** Display name. */\n label: string\n /** Models the provider offers on this host. */\n models: HostModelInfo[]\n /**\n * The host's stored accounts of the provider a session can be pinned to\n * (`ProviderAuth.accounts`), when it has several. Ids are the host's own:\n * a pick on a server names one of its accounts. `models`: that account's\n * own list (an extension's `models.set(id, list, { account })`), sent only\n * when it differs from {@link HostModelProvider.models}; absent, the\n * account runs on `models`. Additive.\n */\n accounts?: Array<{ id: string, label: string, active: boolean, models?: HostModelInfo[] }>\n /**\n * Decision models of the provider's Decisions endpoint, with whether this\n * host's credentials can use them. Absent on providers without one, and\n * from hosts that predate decisions. Additive.\n */\n decisionModels?: HostDecisionModel[]\n /**\n * Image models of the provider's image endpoint, with whether this host's\n * credentials can use them. Absent on providers without one, and from\n * hosts that predate image generation. Additive.\n */\n imageModels?: HostImageModel[]\n}\n\n/** One image model a host's provider serves (`HostModelProvider.imageModels`). */\nexport interface HostImageModel {\n id: string\n name: string\n /** The model takes reference images. */\n references: boolean\n /** The model can return a transparent background. */\n transparency: boolean\n available: boolean\n reason?: string\n /** The model `generate_image` uses while no image model is picked. Additive. */\n isDefault?: boolean\n}\n\n/** `decisions.test`: how the probe decision went. */\nexport interface HostDecisionTestResult {\n ok: boolean\n provider?: string\n model?: string\n durationMs: number\n reason?: string\n message?: string\n}\n\n/** `models.test`: how the probe prompt went, in the fields of `decisions.test`. */\nexport type HostModelTestResult = HostDecisionTestResult\n\n/** One decision model a host's provider serves (`models.list`). */\nexport interface HostDecisionModel {\n id: string\n available: boolean\n reason?: string\n}\n\n/** `ModelInfo` as it crosses the wire. */\nexport interface HostModelInfo {\n /** Model id. */\n id: string\n /** Display name. */\n name?: string\n /** Context window in tokens. */\n contextWindow: number\n /** Maximum output tokens. */\n maxTokens?: number\n /** Whether the model supports reasoning. */\n reasoning?: boolean\n /** Input kinds the model accepts. */\n input?: ('text' | 'image')[]\n /** Price per million tokens, by token kind. */\n cost?: { input: number, output: number, cacheRead?: number, cacheWrite?: number }\n /** Provider that serves the model. */\n provider?: string\n /** Model-specific boolean options, with an optional cost multiplier per token kind. */\n options?: { id: string, label: string, description?: string, costMultiplier?: { input?: number, output?: number, cacheRead?: number, cacheWrite?: number } }[]\n}\n\n/** One credential source of a host's provider (`auth.status`); no secret. */\nexport interface HostAuthMethod {\n /** Where the credential comes from: a stored API key, an OAuth login, or an environment variable. */\n source: 'apikey' | 'oauth' | 'env'\n /** A stored credential the provider resolves (`env` never is). */\n active: boolean\n /** Credentials-file key of a stored credential: the `account` of `auth.remove`. */\n key?: string\n /** OAuth account name. */\n label?: string\n /** Display detail: `credentials.json`, an OAuth account and its expiry, an env var name. */\n detail: string\n}\n\n/**\n * A question the provider's sign-in asks before (or after) its URL: a choice\n * between flows, or a free text. The client shows it and answers with\n * `auth.oauth.respond`; the host never picks for the user.\n */\nexport type HostOAuthStep\n = | { id: string, kind: 'select', message: string, options: Array<{ id: string, label: string }> }\n | { id: string, kind: 'prompt', message: string, placeholder?: string, allowEmpty?: boolean }\n\n/** Result of `auth.oauth.begin`. */\nexport interface HostOAuthBegin {\n /** Random, single-use, bound to the connection that began it. */\n flowId: string\n /** The authorization URL (a device flow: its verification URL); `''` while a `step` comes first. */\n url: string\n /** How the client gets the code back. `step`: answer `step` (`auth.oauth.respond`) before the URL exists. */\n mode: 'loopback' | 'browser' | 'device' | 'step'\n /** A question to answer before the URL exists. Set when `mode` is `step`. */\n step?: HostOAuthStep\n /** `loopback`: where the browser is sent back, on the client's machine. */\n redirectUri?: string\n /** `device`: the code to enter at `url`. */\n userCode?: string\n /** Text to show the user while they sign in. */\n instructions?: string\n /** Epoch ms: the host forgets the flow after it. */\n expiresAt: number\n}\n\n/** `auth.oauth.complete`: the outcome, never a token. */\nexport interface HostOAuthComplete {\n /** A provider sign-in: its new status. */\n provider?: HostProviderAuth\n /** An MCP server sign-in: its name. */\n mcpServer?: string\n /** Not finished: the sign-in asks this. Answer it (`auth.oauth.respond`), then `complete` again. */\n step?: HostOAuthStep\n}\n\n/** Sign-in state of one provider on a host, from `auth.status`. Holds no secret. */\nexport interface HostProviderAuth {\n /** Provider key. */\n key: string\n /** Display name. */\n label: string\n /** Some credential source is present. */\n configured: boolean\n /** The provider signs in with OAuth (on the host's machine only). */\n oauth: boolean\n /** The env var it reads, when it declares one. */\n envKey?: string\n /** Credential sources of the provider. */\n methods: HostAuthMethod[]\n /** Its configuration fields (a local server's URL, a cloud's region), what `auth.configure` takes. Additive. */\n customFields?: ProviderFieldView[]\n /** The non-secret field values set now (stored, else from the host's environment). Additive. */\n configuredFields?: Record<string, string>\n}\n\n/** Folders a host lets clients browse, from `fs.roots`. */\nexport interface FsRoots {\n /** Real paths, the default first. */\n roots: string[]\n /** Session folders must be inside `roots` (a server). */\n confined: boolean\n}\n\n/** One folder in an {@link FsDirListing}. */\nexport interface FsDirEntry {\n /** Folder name. */\n name: string\n /** Real path (a symlink resolved). */\n path: string\n /** Holds a `.git`. */\n isGitRepo: boolean\n}\n\n/**\n * What `git.checkout` / `git.createBranch` answered. `worktree`: another worktree holds the branch, at this path;\n * `chats`: the host's unarchived sessions in that checkout.\n */\nexport type GitCheckoutResult = { ok: true } | { ok: false, error: string, worktree?: string, chats?: string[] }\n\n/** A session's transcript as a file (`sessions.export`): its name and text. */\nexport interface SessionExportFile {\n /** `<session id>.md` or `.json`. */\n filename: string\n /** The rendered transcript. */\n content: string\n}\n\n/** A folder listing from `fs.listDirs`. */\nexport interface FsDirListing {\n /** Real paths of the browsable roots. */\n roots: string[]\n /** The listed folder, as a real path. */\n path: string\n /** The folder above, or `null` at a root. */\n parent: string | null\n /** Sorted by name. */\n entries: FsDirEntry[]\n /** More folders than the listing returns. */\n truncated?: boolean\n}\n\n/** What `fs.searchDirs` found. */\nexport interface FsDirSearch {\n /** The matching folders: exact names first, then names that start with the query, then the rest; shallow first. */\n results: FsDirEntry[]\n /** The result bound or the bound on folders read cut the search short. */\n truncated?: boolean\n}\n\n/** One ordered model-fallback target (primary excluded). */\nexport interface ModelFallbackRef {\n /** Provider of the fallback model. */\n providerKey: ProviderKey\n /** Id of the fallback model. */\n modelId: string\n /** The stored account of the provider (credential id); omitted = its active account. Additive. */\n account?: string\n}\n\n/** One row of a cross-window session list. */\nexport interface SessionRow {\n /** Session id. */\n id: string\n /** Session title. */\n title: string\n /** Project the session belongs to, or `null` when it has none. */\n projectRoot: string | null\n /** Working directory of the session. */\n cwd: string\n /** Id of the agent the session runs as. */\n agentId?: string\n /** Run state of the session. */\n status: 'idle' | 'running' | 'completed' | 'error'\n /** Creation time, epoch ms. */\n createdAt: number\n /** Time of the last change, epoch ms. */\n updatedAt: number\n /** Whether the session is archived. */\n archived: boolean\n /** Listed first (`metadata.favorite`). Additive. */\n favorite?: boolean\n /** Orchestration main session — see `SessionMeta.isMain`. Additive. */\n isMain?: boolean\n /** The session's space when not Default — see `SessionMeta.spaceId`. Additive. */\n spaceId?: string\n /** Provider the session runs on. */\n providerKey?: ProviderKey\n /** Model the session runs on. */\n modelId?: string\n /** The pinned account of `providerKey` (credential id), when one is. Additive. */\n account?: string\n /** Thinking effort of the session. */\n effort?: ThinkingLevel\n /** Model-specific boolean options of the session. */\n modelOptions?: Record<string, boolean>\n /** Validated (head-matched) fallback chain tail, for pickers/badges. */\n modelFallbacks?: ModelFallbackRef[]\n /** Non-local environment summary (kind, state, branch, error). */\n environment?: SessionEnvironmentSummary\n /** The host serving this row (`HelloResult.hostId`). Additive: absent from older hosts. */\n hostId?: string\n /**\n * The repository the session's folder is a checkout of (`github.com/owner/repo`,\n * see `repoKeyOf`). Copies of one repository on two machines have the same key.\n * Absent outside git, without a shared remote, and from older hosts. Additive.\n */\n repoKey?: string\n /**\n * While `status` is `running`: when the run in progress began, epoch ms on\n * the host's clock, so a client that missed its `run:start` still shows how\n * long it has been going. Additive: absent from older hosts.\n */\n runStartedAt?: number\n /**\n * While `status` is `running`: the estimates of its runs in progress, the\n * session's own first, then its subagents' (`Settings.runEstimates`), so a\n * window opened mid-run counts down from the same point. Absent when none\n * is estimated, and from older hosts. Additive.\n */\n runEstimates?: RunEstimateView[]\n /**\n * Facet values extensions computed for the session (`ctx.sessions.facets`),\n * keyed `<extensionId>.<key>`; queries read them as `facet.<extensionId>.<key>`.\n * Stored with the session, so a list computes nothing. `sessions:facets`\n * announces a change. Absent when it has none, and from older hosts. Additive.\n */\n facets?: Record<string, JsonValue>\n}\n\n/** Params of `sessions.create`. */\nexport interface CreateSessionParams {\n /** Tool-execution directory — `projectRoot` is derived from it host-side. */\n cwd: string\n /** Title of the session. Omitted: the host picks one. */\n title?: string\n /** Id of the agent the session runs as. */\n agentId?: string\n /** Provider the session runs on. */\n providerKey?: ProviderKey\n /** Model the session runs on. */\n modelId?: string\n /** The stored account of `providerKey` to run on (credential id). Additive: older hosts ignore it. */\n account?: string\n /** Seed an ordered fallback chain alongside the model pick. */\n fallbacks?: ModelFallbackRef[]\n /** The model pick's reasoning effort and options, stamped with it. */\n effort?: ThinkingLevel\n /** Model-specific boolean options, stamped with the model pick. */\n modelOptions?: Record<string, boolean>\n /** Skills pinned from the first turn (an authoring session's docs skill). */\n pinnedSkills?: string[]\n /** Mark as an extension-authoring session (auto-activates the docs skill). */\n extensionEdit?: boolean\n /** Mark as a skill-authoring session for the named skill (dir = `cwd`). */\n skillEdit?: { name: string }\n /** Where the session's work happens. Omitted → local. */\n environment?: EnvironmentRequest\n /** The space the session belongs to. Omitted → Default. Additive: older hosts ignore it. */\n spaceId?: string\n /** Create it as a hidden `/side` session of this parent. Additive: older hosts ignore it. */\n sideOf?: string\n /** The session's rules (`sessions.setPolicy`). Additive: older hosts ignore it. */\n policy?: SessionPolicy\n}\n\n/* -------------------------------------------------------------------------\n * Daemon handshake\n * ---------------------------------------------------------------------- */\n\n/** Params of the `hello` handshake. */\nexport interface HelloParams {\n /** Protocol version the client speaks. */\n protocolVersion: number\n /**\n * The oldest version the client can speak down to ({@link IPC_MIN_PROTOCOL_VERSION}).\n * A zidane-server accepts when the ranges overlap. Absent: `protocolVersion` only. Additive.\n */\n minProtocolVersion?: number\n /** Client's zidane version — surfaced in daemon diagnostics. */\n appVersion: string\n /** Process id of the client. */\n pid: number\n /**\n * Build fingerprint (module mtime; `'unknown'` in compiled binaries).\n * When BOTH sides report a real id and they differ, the daemon rejects\n * the handshake like a protocol-version mismatch — the client drains it\n * and respawns. Closes same-version code drift during development.\n */\n buildId?: string\n /**\n * Version of the zidane code the client runs (`ZIDANE_VERSION`, inlined at\n * build). Unlike `buildId` this survives compiled binaries, so it closes\n * the gap released builds had: same protocol version, older code. A\n * client STRICTLY NEWER than the daemon is rejected like a build mismatch\n * and the stale daemon is drained; an older client is accepted and\n * degrades via `optional()`.\n */\n codeVersion?: string\n}\n\n/**\n * What a host process is: a window's own (`in-process`), the local shared\n * daemon (`daemon`), or a remote `zidane-server` (`server`).\n */\nexport type HostKind = 'in-process' | 'daemon' | 'server'\n\n/** Which host a client is talking to, as clients keep it (from `hostRefOf`). */\nexport interface HostRef {\n /** Stable across restarts: persisted in the host's data dir. */\n id: string\n /** What kind of host it is. */\n kind: HostKind\n /** Display name: the machine's hostname by default. */\n name: string\n}\n\n/** Result of the `hello` handshake and of `daemon.info`. */\nexport interface HelloResult {\n /** Protocol version the host speaks. */\n protocolVersion: number\n /** The oldest version the host still speaks ({@link IPC_MIN_PROTOCOL_VERSION}). Additive. */\n minProtocolVersion?: number\n /**\n * The version this connection speaks: the lower of the client's and the host's. Additive:\n * absent, the connection speaks `protocolVersion`.\n */\n negotiatedProtocolVersion?: number\n /**\n * The client scope this connection's token grants (`./scopes`): calls above it are refused.\n * Absent: every method (a local window). Additive.\n */\n scope?: ClientScope\n /**\n * The methods this connection may call on this host: the ones it handles, within `scope`.\n * Clients show what is offered instead of failing on what isn't. Additive.\n */\n methods?: IpcMethodName[]\n /** zidane version of the host. */\n appVersion: string\n /** Process id of the host. */\n pid: number\n /** Start time of the host process, epoch ms. */\n startedAt: number\n /** Build fingerprint of the host code. `'unknown'` in compiled binaries. */\n buildId?: string\n /** Version of the zidane code the host runs. */\n codeVersion?: string\n /**\n * Host identity (additive). `hostId` is a UUID persisted once in the host's\n * data dir, so it survives restarts; the in-process host and the local\n * daemon share the data dir, and so the id: they are the same computer.\n */\n hostId?: string\n /** What kind of host this is. */\n hostKind?: HostKind\n /** Display name of the host. */\n hostName?: string\n /**\n * The daemon is older than a client that attached while it had active\n * work: it accepted the handshake instead of draining (which would abort\n * those runs) and exits once idle. Clients attach normally; their\n * reconnect path lands on a fresh daemon after the exit.\n */\n retiring?: boolean\n /**\n * Names this host process's signal numbering ({@link SIGNAL_SEQ_FIELD}):\n * a position from another epoch cannot be resumed. Additive.\n */\n signalEpoch?: string\n /**\n * This server lends itself as a machine to the hosts of its clients\n * (`machine.attach`, `allowAsMachine` on). Absent: it doesn't. Additive.\n */\n machineServe?: boolean\n /**\n * This server takes installs and removals from its clients (`catalog.install`\n * / `remove` / `update`, `mcp.upsert` / `remove`; `allowRemoteInstalls` on).\n * Absent: it doesn't (or predates them). Additive.\n */\n remoteInstalls?: boolean\n /**\n * Clients may clone repositories into its workspace roots (`git.clone`). A\n * zidane-server's `allowClone`; a local host always does. Absent: an older\n * host, where `git.clone` needs an admin token. Additive.\n */\n clone?: boolean\n /**\n * Clients may create folders in its workspace roots (`fs.mkdir`). A\n * zidane-server's `allowCreateFolders`; a local host always does. Absent:\n * an older host, without `fs.mkdir`. Additive.\n */\n createFolders?: boolean\n /**\n * The host process's home folder (`os.homedir()`). Clients show it as `~` in\n * the paths they display; nothing else reads it. Absent: an older host. Additive.\n */\n homeDir?: string\n /** This server takes settings sync from a client's computer (`sync.*`). Absent: it doesn't. Additive. */\n sync?: boolean\n /** The sync categories it takes. Absent with `sync`: the ones before `environments`. Additive. */\n syncCategories?: SyncCategory[]\n /**\n * This host runs terminals without a session (`terminal.openInProject` and\n * the other project / draft terminal methods). Absent: sessions only. Additive.\n */\n projectTerminals?: true\n /**\n * `daemon.info` only: a run, compaction, `/` command or background task is\n * in flight on this host (open terminals do not count). `zidane server\n * wait-idle` waits for `false` before a restart. Additive.\n */\n activeWork?: boolean\n}\n\n/** A zidane-server token's scope: a client scope (`./scopes`), or `machine` (it lends a computer). */\nexport type ServerTokenScope = ClientScope | 'machine'\n\n/** A zidane-server token as `tokens.*` lists it: never its secret or its hash. */\nexport interface ServerTokenInfo {\n /** Stable id (`tok_…`). */\n id: string\n /** The name it was created with, such as the device it is for. */\n name: string\n /** What it may do. */\n scope: ServerTokenScope\n /** When it was created, epoch ms. */\n createdAt: number\n /** When it last opened a connection, epoch ms. */\n lastUsedAt?: number\n /** When it was revoked, epoch ms. Absent: live. */\n revokedAt?: number\n /** The token that created it, when a client did (`tokens.create`, `tokens.createMachineToken`). */\n createdBy?: string\n /** When it stops working, epoch ms. Absent: never. */\n expiresAt?: number\n}\n\n/** `catalog.install` / `remove` / `update`: what is installed from a client, in the host user's scope. */\nexport type HostInstallKind = 'skill' | 'extension'\n\n/**\n * Which catalog a `catalog:changed` signal says to re-read. `models`: what\n * `models.list` answers changed (an extension's provider or account list,\n * after a sign-in or a new default account). Additive.\n */\nexport type HostCatalogName = 'skills' | 'mcps' | 'extensions' | 'plugins' | 'models'\n\n/** An agent profile as `agents.list` offers it. */\nexport interface HostAgentProfile {\n /** Stable id (`sessions.setAgentId`). */\n id: string\n /** Its name. */\n label: string\n /** What it does. */\n description: string\n /** A theme color name or a CSS color. */\n accent: string\n}\n\n/** The picks `prefs.get` / `prefs.set` remember across apps (`state.json`). */\nexport type HostComposerPrefs = Pick<TuiState, 'lastEffortByModel' | 'lastModelOptionsByModel' | 'lastModelChain'>\n\n/** `sessions.sideSession`: a session's `/side` session and its own row. */\nexport interface SideSessionLookup {\n /** The side session, `null` until one is created. */\n side: SessionRow | null\n /** The session asked about, `null` when it is unknown. */\n parent: SessionRow | null\n}\n\n/** A provider of `onboarding.providers`: the wizard's row, with the model it runs when none is picked. */\nexport type HostOnboardingProvider = OnboardingProvider & { defaultModel?: string }\n\n/** `claudeImport.detect`: what `~/.claude` on the host holds. */\nexport interface ClaudeImportDetection {\n /** There is a Claude Code setup to import. */\n available: boolean\n /** The transcripts found for the folder, and in every project. */\n counts: { project: number, all: number }\n}\n\n/** What `claudeImport.run` imports. */\nexport interface ClaudeImportSelection {\n /** Conversations. */\n sessions: boolean\n /** MCP servers. */\n mcps: boolean\n /** Skills. */\n skills: boolean\n /** Commands, and subagents unless `agents` says otherwise. */\n commands: boolean\n /** Subagents. Absent: they follow `commands`. */\n agents?: boolean\n /** Conversations of every project, not just the folder's. */\n allProjects: boolean\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqWA,MAAa,uBAAuB;;;;;;;;;;AAYpC,MAAa,2BAAmC;;;;;;AAOhD,MAAa,eAAe;CAC1B,iBAAiB;CACjB,eAAe;;CAEf,aAAa;;;;;;CAMb,kBAAkB;;;;;;CAMlB,eAAe;;;;;;CAMf,WAAW;AACb;;;;;;;AAuBA,SAAgB,0BAA0B,MAAsD;CAC9F,IAAI,OAAO,SAAS,YAAY,SAAS,MACvC,OAAO,KAAA;CACT,MAAM,EAAE,cAAc,eAAe;CACrC,IAAI,OAAO,iBAAiB,YAAY,CAAC,MAAM,QAAQ,UAAU,KAAK,CAAC,WAAW,OAAM,MAAK,OAAO,MAAM,QAAQ,GAChH,OAAO,KAAA;CACT,OAAO;EAAE;EAAc,YAAY,CAAC,GAAG,UAAU;CAAE;AACrD;;;;;;AAOA,MAAa,cAAc;;;;;;;AAQ3B,MAAa,mBAAmB;;;;;;AA45ChC,SAAgB,UAAU,OAAoC;CAC5D,IAAI,OAAO,MAAM,WAAW,YAAY,CAAC,MAAM,UAC7C,OAAO;CACT,OAAO;EAAE,IAAI,MAAM;EAAQ,MAAM,MAAM;EAAU,MAAM,MAAM,YAAY,MAAM;CAAO;AACxF;;AAUA,MAAa,yBAAyB;;AAEtC,MAAa,6BAA6B;;;;;;;;AAoD1C,eAAsB,eACpB,SACA,QAC4B;CAC5B,MAAM,SAAS,MAAM,QAAQ,uBAAuB,MAAM;CAC1D,OAAO,MAAM,QAAQ,MAAM,IAAI,EAAE,QAAQ,OAAO,IAAI;AACtD;AAEA,SAAS,mBAAmB,KAAuB;CACjD,OAAO,OAAO,QAAQ,YAAY,QAAQ,QAAS,IAA2B,SAAS,aAAa;AACtG;;;;;;;;;;;;;AAcA,eAAsB,cACpB,SACA,WACA,UAAkC,CAAC,GACX;CACxB,QAAQ,MAAM,kBAAkB,SAAS,WAAW,QAAQ,aAAA,GAAmC,EAAA,CAAG;AACpG;;;;;;;;AASA,eAAsB,eACpB,SACA,WACA,QACA,UAAkC,CAAC,GACkB;CACrD,OAAO,kBAAkB,SAAS,WAAW,QAAQ,aAAA,KAAqC,MAAM;AAClG;AAEA,eAAe,kBACb,SACA,WACA,WACA,QACqD;CACrD,IAAI,QAAQ;CACZ,MAAM,QAAyB,CAAC;CAChC,IAAI,aAAa;CACjB,IAAI,WAAW;CACf,IAAI;CACJ,SAAS;EACP,IAAI;EACJ,IAAI;GACF,OAAO,MAAM,eAAe,SAAS;IAAE;IAAW;IAAO,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;GAAG,CAAC;EACxG,SACO,KAAK;GACV,IAAI,mBAAmB,GAAG,KAAK,QAAQ,GAAG;IACxC,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC;IACzC;GACF;GACA,MAAM;EACR;EAQA,MAAM,QAAQ,MAAM;EACpB,IAAI,SAAS,CAAC,cAAc,MAAM,EAAE,EAAE,SAAS,iBAAiB,KAAK,OAAO,SAAS,GACnF,MAAM,QAAQ;GAAE,MAAM;GAAa,MAAM;EAAG,CAAC;EAC/C,aAAa,KAAK,UAAU;EAC5B,aAAa,cAAc,KAAK,UAAU,KAAA;EAC1C,MAAM,QAAQ,KAAK,MAAM;EAEzB,IAAI,KAAK,WAAW,KAAA,KAAa,KAAK,UAAU,KAAM,WAAW,KAAA,KAAa,KAAK,UAAU,QAC3F;EACF,IAAI,UAAU,UAAU;GACtB,MAAM,SAAS,MAAM,KAAK;GAC1B,IAAI,OAAO,MAAM,GACf,OAAO;IAAE;IAAQ,SAAS,KAAK;GAAO;EAC1C;EACA,SAAS,KAAK;CAChB;CACA,OAAO;EAAE,QAAQ,MAAM,KAAK;EAAG,SAAS;CAAE;AAC5C;;AAGA,MAAa,qBAAqB;;AAElC,MAAa,yBAAyB;;AAYtC,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;AAmBlC,eAAsB,oBACpB,SACA,WACA,UAAkC,CAAC,GACN;CAC7B,MAAM,SAAS,EAAE,OAAO,QAAQ,aAAA,IAAgC;CAChE,KAAK,IAAI,UAAU,GAAG,WAAW,2BAA2B,WAAW;EACrE,MAAM,OAAO,MAAM,wBAAwB,SAAS,WAAW,MAAM;EACrE,IAAI,SAAS,WACX,OAAO;CACX;CACA,OAAO,eAAe,MAAM,QAAQ,gBAAgB,EAAE,UAAU,CAAC,CAAC;AACpE;AAEA,SAAS,eAAe,MAAsD;CAC5E,IAAI,CAAC,MACH,OAAO;CACT,MAAM,EAAE,SAAS,UAAU,GAAG,SAAS;CACvC,OAAO;AACT;;AAGA,eAAe,wBAAwB,SAAiC,WAAmB,QAAoE;CAC7J,MAAM,QAAuB,CAAC;CAC9B,IAAI,QAAQ;CACZ,IAAI,UAAkC;CACtC,OAAO,MAAM,SAAS,OAAO;EAC3B,IAAI;EACJ,IAAI;GACF,OAAO,MAAM,QAAQ,qBAAqB;IAAE;IAAW,MAAM,MAAM;IAAQ,OAAO,OAAO;GAAM,CAAC;EAClG,SACO,KAAK;GACV,IAAI,MAAM,WAAW,KAAK,iBAAiB,GAAG,GAC5C,OAAO,eAAe,MAAM,QAAQ,gBAAgB,EAAE,UAAU,CAAC,CAAC;GACpE,IAAI,mBAAmB,GAAG,KAAK,OAAO,QAAQ,GAAG;IAC/C,OAAO,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,QAAQ,CAAC,CAAC;IACvD;GACF;GACA,MAAM;EACR;EACA,IAAI,CAAC,MACH,OAAO;EACT,IAAI,YAAY,MACd,UAAU,EAAE,GAAI,KAAK,YAAY,KAAA,IAAY,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC,EAAG;OACrE,IAAI,KAAK,YAAY,QAAQ,IAChC,OAAO;EACT,QAAQ,KAAK;EAEb,IAAI,KAAK,MAAM,WAAW,GACxB;EACF,MAAM,KAAK,GAAG,KAAK,KAAK;CAC1B;CACA,MAAM,OAAO,MAAM,QAAQ,gBAAgB;EAAE;EAAW,OAAO;CAAM,CAAC;CACtE,IAAI,CAAC,MACH,OAAO;CACT,IAAI,YAAY,QAAQ,KAAK,YAAY,QAAQ,IAC/C,OAAO;CACT,OAAO;EAAE,GAAG,eAAe,IAAI;EAAI;CAAM;AAC3C;;AA6BA,MAAa,WAAW"}
|
|
1
|
+
{"version":3,"file":"protocol-DOGyHgLQ.js","names":[],"sources":["../src/ipc/protocol.ts"],"sourcesContent":["/**\n * zidane/ipc wire protocol — the transport-agnostic contract between a chat\n * host (the process that owns live `Agent` instances) and its clients (GUI\n * renderer, TUI window, `zidane attach`, …).\n *\n * The host-domain shapes (the `HostSignal` push union and everything it\n * carries) live in `src/chat/host/signals.ts` — the host must not depend on\n * `src/ipc/**`. This module re-exports them unchanged and adds the\n * transport-only contract: the typed JSON-RPC method map, session rows, and\n * the daemon handshake.\n *\n * Everything in this file is JSON-serializable: it must survive Electron's\n * structured clone AND a JSON-RPC socket hop unchanged. Canonical agent\n * types (`StreamEvent`, `InteractionRequest`, …) are re-used where they are\n * already wire-safe; host-only shapes (live `resolve` callbacks, `Map`s)\n * never appear here.\n *\n * Versioning: bump `IPC_PROTOCOL_VERSION` on any breaking change to the\n * signal union or the method map. The daemon handshake refuses mismatched\n * peers so a stale daemon never talks to an upgraded client (see\n * `daemon/lifecycle.ts`).\n */\nimport type { BrowserResponse } from '../chat/browser/protocol'\nimport type { HostCapabilities } from '../chat/capabilities'\nimport type { ClaudeImportSummary } from '../chat/claude-import'\nimport type { CommandOutputBlock } from '../chat/commands'\nimport type { ProviderFieldView } from '../chat/credentials'\nimport type { EnvironmentActionResult, EnvironmentActionSummary, EnvironmentRequest, EnvironmentTeardownResult, EnvironmentVerifyResult } from '../chat/environment'\nimport type { EnvironmentDescriptor, EnvironmentSettingsChange } from '../chat/environment-settings'\nimport type { ExtensionSourceListing } from '../chat/extension-sources'\nimport type { FileEntry } from '../chat/files-discovery'\nimport type { GitBranchRow, GitCommitInfo, GitInfo, GitPr, GitPrListResult, GitSwitchTarget, GitSyncResult, RepoCloneResult } from '../chat/git/types'\nimport type { CompactionReport } from '../chat/host/compaction'\nimport type { CacheImpact, CacheImpactChange, CacheReport, ContextSegmentsReport, WorkspaceListFilesOptions } from '../chat/host/engine'\nimport type {\n CatalogItemProvenance,\n CatalogKind,\n CommandRunParams,\n LinkOpenParams,\n SettingsSetParams,\n UiClientAnnounce,\n UiInvokeRequest,\n WireExtensionCommands,\n WireExtensionEntry,\n WireExtensionSettings,\n WireIntegration,\n WireKeymap,\n WireStorageLocation,\n WireStorageSetResult,\n WireUiList,\n} from '../chat/host/extensions-wire'\nimport type { SessionLaunchOverrides } from '../chat/host/launch-overrides'\nimport type {\n CreateSessionParams as OrchestrationCreateParams,\n EventQuery as OrchestrationEventQuery,\n PendingRequestRow as OrchestrationPendingRequest,\n WaitResult as OrchestrationWaitResult,\n WorkerRow as OrchestrationWorkerRow,\n WorkerSummary as OrchestrationWorkerSummary,\n} from '../chat/host/orchestration'\nimport type {\n CommandArgSuggestionSummary,\n CommandSummary,\n HostSettings,\n HostSignal,\n PendingInteraction,\n PromptAttachment,\n QueuedItem,\n RunningWorkItem,\n SendOptions,\n SessionPresence,\n TodosSnapshot,\n WireApprovalRequest,\n} from '../chat/host/signals'\nimport type {\n ApprovalDecision,\n ContextBreakdown,\n InteractionResponse,\n ProviderKey,\n SearchTurnResult,\n SessionEnvironmentSummary,\n SessionHeader,\n SessionHistoryMatch,\n SessionMeta,\n StreamEvent,\n SystemMdFile,\n TodoItem,\n} from '../chat/index'\nimport type { IntegrationInfo, IntegrationState } from '../chat/integrations'\nimport type { MachineInfo, MachineLinksStatus, MachineRegisterParams } from '../chat/machine-protocol'\nimport type { McpServerStatus } from '../chat/mcp-status'\nimport type { OnboardingDetection, OnboardingImportPreview, OnboardingProvider, OnboardingSettingsChange, OnboardingState } from '../chat/onboarding/types'\nimport type { SessionEvent } from '../chat/orchestration'\nimport type { PaletteContext, PaletteItem, PaletteRunResult } from '../chat/palette'\nimport type { FolderLocation } from '../chat/project-root'\nimport type { ProviderUsageSnapshot } from '../chat/provider-usage-format'\nimport type { RunEstimateView } from '../chat/run-estimate'\nimport type { SafelistProject } from '../chat/safe-mode'\nimport type { ServerUpdateStatus } from '../chat/server-update'\nimport type { SessionExportFormat } from '../chat/session-export'\nimport type { SessionPolicy } from '../chat/session-policy'\nimport type { BlockRun } from '../chat/shell-blocks'\nimport type { TuiState } from '../chat/store'\nimport type { SyncCategory, SyncClaimResult, SyncPayload, SyncPushResult, SyncStatus } from '../chat/sync/types'\nimport type { TerminalAdoptResult, TerminalAttachResult, TerminalInfo, TerminalOpenInput, TerminalProjectOpenInput, TerminalProjectState, TerminalProjectStateInput, TerminalSessionState } from '../chat/terminal/protocol'\nimport type { UsageRange, UsageSummary } from '../chat/usage-summary'\nimport type { DiagnosticsResult, DiagnosticsToolInfo } from '../chat/workspace/diagnostics/types'\nimport type { EntryResult } from '../chat/workspace/entries'\nimport type { ContentSearchResult } from '../chat/workspace/search'\nimport type { GitStatusEntry, ResolvedPath } from '../chat/workspace/types'\nimport type { OwnedProcess } from '../contexts/owned-processes'\nimport type { SessionProcess } from '../contexts/session-processes'\nimport type { ExecResult, ListFilesEntry } from '../contexts/types'\nimport type { CreateExtensionInput, CreateExtensionResult } from '../extension-authoring'\nimport type { Json } from '../extensions/api/storage'\nimport type {\n BadgeActionEffect,\n BadgeMenuItem,\n BadgeTarget,\n ExtensionActionRunResult,\n ExtensionActionSummary,\n ExtensionCompletionItemSummary,\n ExtensionCompletionProviderSummary,\n ExtensionConfigActionStatus,\n ExtensionReferenceView,\n PanelContent,\n PanelLoadContextInput,\n PanelSummary,\n ReferenceProviderWire,\n SessionBadgeEntry,\n WireExtensionConfigSchema,\n} from '../extensions/index'\nimport type { ExtensionInstallOrigin } from '../extensions/install'\nimport type { RpcCallParams, RpcResponseEnvelope } from '../extensions/rpc/wire'\nimport type { StorageArea, StorageSnapshot } from '../extensions/storage/port'\nimport type { LogRecord } from '../logger'\nimport type { McpServerInstance } from '../mcp/server-pool'\nimport type { PerfOsThread, PerfSample } from '../perf/types'\nimport type { SessionArtifact } from '../session/artifacts'\nimport type { SessionData } from '../session/index'\nimport type { SkillSourceListing } from '../skills/sources'\nimport type { JsonValue, McpServerConfig, SessionTurn, ThinkingLevel } from '../types'\nimport type { ClientScope } from './scopes'\nimport { isMethodNotFound } from '../chat/hosts/connection'\n\nexport type { GitBranchRow, GitCommitInfo, GitInfo, GitPr, GitPrItem, GitPrListResult, GitSwitchTarget, GitSyncResult, RepoCloneResult, RepoProgress } from '../chat/git/types'\n\nexport type {\n CommandRunParams,\n DialogRequest,\n ExtensionsSignal,\n IntegrationFlowStep,\n LinkOpenParams,\n NavigateTarget,\n RpcEventEnvelope,\n SettingsSetParams,\n UiChange,\n UiClientAnnounce,\n UiClientRequest,\n UiInvokeRequest,\n UiSnapshot,\n WireComposerEdit,\n WireExtensionCommand,\n WireExtensionCommands,\n WireExtensionEntry,\n WireExtensionSettings,\n WireIntegration,\n WireIntegrationMethod,\n WireKeymap,\n WireStorageLocation,\n WireStorageSetResult,\n WireUiBundle,\n WireUiList,\n} from '../chat/host/extensions-wire'\n\nexport type {\n ApprovalOriginator,\n CommandArgSuggestionSummary,\n CommandSummary,\n DeliveryState,\n HostSettings,\n HostSignal,\n PendingInteraction,\n PromptAttachment,\n QueuedItem,\n RunningWorkItem,\n SendOptions,\n SerializedPreview,\n SessionPresence,\n TodosSnapshot,\n WireApprovalRequest,\n} from '../chat/host/signals'\n\nexport type { IntegrationInfo, IntegrationState } from '../chat/integrations'\n\n/** The machine protocol (`docs/MACHINES.md`), versioned on its own (`MACHINE_PROTOCOL_VERSION`). */\nexport {\n isValidMachineName,\n MACHINE_HOST_METHODS,\n MACHINE_IDEMPOTENT_METHODS,\n MACHINE_PROTOCOL_VERSION,\n MachineErrorCode,\n machineKind,\n parseMachineKind,\n} from '../chat/machine-protocol'\nexport type {\n MachineCapabilities,\n MachineHandleRef,\n MachineInfo,\n MachineMethodName,\n MachineMethods,\n MachineNotifications,\n MachineParams,\n MachineRegisterParams,\n MachineRegisterResult,\n MachineResult,\n MachineRoot,\n MachineStatusChange,\n} from '../chat/machine-protocol'\nexport type { ServerUpdateStatus, UpdateState } from '../chat/server-update'\nexport type { SessionExportFormat } from '../chat/session-export'\nexport type { Diagnostic, DiagnosticSeverity, DiagnosticsResult, DiagnosticsToolInfo } from '../chat/workspace/diagnostics/types'\nexport type { EntryRefusal, EntryResult } from '../chat/workspace/entries'\nexport type { ContentMatch, ContentSearchResult } from '../chat/workspace/search'\nexport type { GitStatusEntry, ResolvedPath } from '../chat/workspace/types'\n\n/**\n * Changes since v5. Entries marked additive, or \"no version bump\", did\n * not raise the version. The current version is `IPC_PROTOCOL_VERSION`.\n *\n * - `event` signals carry an optional `echo` flag marking host-generated\n * SEND/STEER echoes of the user's own message.\n * - `chat.pushQueued` result gained the `'queued'` delivered variant.\n * - `sessions.setModel` now honors `fallbacks`: it persists the canonical\n * `metadata.modelChain` and CLEARS a previously persisted chain when\n * omitted/empty. It also accepts `effort` / `modelOptions` and resets\n * both when omitted (a pick is atomic — no stale per-model knobs).\n * - additive: `extension.emit` notification + `extension:signal` fan-out\n * (the permission-gated per-extension cross-window bus, `ctx.bus`;\n * removed in zidane 10).\n * Older daemons ignore the unknown notification; older clients drop the\n * unknown signal kind — no version bump needed.\n * - additive: `extension.emit` / `extension:signal` carry an optional\n * `nonce` (the emitter's per-process random id) so receivers dedupe on\n * `(extensionId, nonce, seq)` instead of the collision-prone\n * `(extensionId, seq)`. Older peers omit it and fall back to the\n * seq-only key — no version bump needed.\n * - `SessionRow.modelFallbacks` is now populated from the session's\n * persisted `metadata.modelChain`.\n * - Default socket path moved from `<stateDir>/daemon.sock` to the\n * dedicated `<stateDir>/daemon/daemon.sock` (dir chmod'd 0700) so the\n * daemon can harden its socket dir without touching shared state files.\n * - ADDITIVE (no version bump — older daemons answer \"method not\n * found\", clients degrade to local compute): `suggest.resolve` RPC\n * resolves inline ghost-text autocomplete daemon-side, and the\n * `suggest:changed` signal fans the result out to every OTHER peer\n * on the session so mirroring windows paint the same ghost without\n * recomputing.\n * - ADDITIVE (no version bump — optional field, older daemons simply\n * omit it and clients fall back to the single `suggestion`):\n * `suggest.resolve` results and `suggest:changed` signals carry the\n * resolver's full ordered `candidates` list so daemon mode keeps\n * ↑/↓ candidate rotation instead of degrading to one suggestion.\n * - ADDITIVE (no version bump — `optional()` swallows \"method not\n * found\" on an older daemon, which then simply keeps its stale\n * registries as before): `runtime.reload` RPC drops the daemon's\n * cached extension registries and retires live agents after a window\n * reloaded its extensions.\n * - ADDITIVE (no version bump): `terminal.registerViewer` /\n * `terminal.unregisterViewer`. The desktop app registers as a client that\n * can show terminals; agents only get terminal tools while one is\n * attached. An older daemon answers \"method not found\" (and keeps giving\n * every agent the tools, as before); an older desktop app on a newer\n * daemon never registers, so its agents run without terminal tools.\n * - ADDITIVE (no version bump): project / draft terminals\n * (docs/PROJECT-SCOPE-AUDIT.md): `terminal.projectState`,\n * `terminal.openInProject`, `terminal.adopt`, `terminal.releaseDraft`,\n * the `terminal:project-changed` signal, and `HelloResult.projectTerminals`.\n * An older daemon answers \"method not found\" and omits the flag; clients\n * then offer terminals only in sessions.\n * - ADDITIVE (no version bump): `queue.attachments` returns a queued\n * entry's attachments with their bytes, and `queue.update` accepts\n * `attachments` to replace them. An older daemon answers \"method not\n * found\" / ignores the field: the entry's attachments stay as queued.\n * - ADDITIVE (no version bump): `chat.steer` / `chat.followUp` resolve to\n * whether the message reached a live run. Older daemons resolve `null`,\n * which clients treat as delivered (the pre-existing behavior).\n * - ADDITIVE (no version bump): `sessions.fork`, `sessions.deleteTurn`,\n * `sessions.editTurnText`, `sessions.setFolder`, `sessions.appendTurns`,\n * `sessions.rewind`.\n * History and folder edits run in the host instead of being written to\n * the store by the client (then `sessions.touch` + `chat.rebuildAgent`).\n * Older clients keep the old path, which still works on a shared disk.\n * A newer client only meets an older daemon while it retires (the\n * release fence drains it otherwise), and then gets \"method not found\".\n * - ADDITIVE (no version bump): `sessions.listMeta`, `sessions.getMeta`,\n * `sessions.get`, `sessions.setExtensionState` serve a client the\n * session data it used to read and write in its own store, so a window\n * on another machine sees the host's sessions. `sessions.create` accepts `effort`, `modelOptions` and\n * `pinnedSkills`; `todos.set` accepts `persistIdle`. An older host answers\n * \"method not found\" / ignores the fields: a window falls back to the\n * store it shares with a local daemon, and refuses a remote host.\n * - ADDITIVE (no version bump): `daemon.info` reports `activeWork` (a run,\n * compaction, `/` command or background task in flight). An older host\n * omits it; `zidane server wait-idle` then says it can't tell.\n * - ADDITIVE (no version bump): `sessions.loadEvents` paging accepts\n * `beforeTurnId` (the page ends right before that turn, winning over\n * `before`; an unknown turn is invalid params) and the page echoes it.\n * An older host ignores the param and omits the echo, which is how a\n * client tells.\n * - ADDITIVE (no version bump): `sessions.cacheImpact` and\n * `sessions.cacheReport`. An older host answers \"method not found\":\n * pickers show no cache estimate and session details no Cache section.\n * - ADDITIVE (no version bump): `sessions.moveEnvironment`. An older host\n * answers \"method not found\", shown as the move's error. Its\n * `removeOldWorktree` param and `oldWorktree` result came later: an older\n * host ignores the param and answers with no result.\n * - ADDITIVE (no version bump): a folder's git checkout and files\n * (`git.*`, `files.*`, the caller-only `git:clone:progress` signal),\n * `sessions.export` and `hud.get`. Clients find them in the hello's\n * `methods`; an older host lacks them and those controls stay hidden.\n * `hud.get` and the `hud:state` / `hud:notify` signals are gone since\n * zidane 10: extensions show status through `Slot` items\n * (`extensions.ui.list`, `extensions:ui`); a client that still asks\n * for `hud.get` gets \"method not found\".\n * - ADDITIVE (no version bump): `sessions.titleStatus`,\n * `artifacts.refresh`, `usage.summary`, `git.watch` / `git.unwatch`\n * (the watcher-only `git:refs` signal), `files.mediaTicket` (media at\n * `GET /zidane/media`), project-scope `extensions.create`, and\n * `auth.status`'s `customFields` / `configuredFields`. The methods are\n * in the hello's `methods`; an older host omits the fields.\n * - ADDITIVE (no version bump): `daemon.ownedProcesses`. An older host\n * answers \"method not found\"; the desktop app's performance monitor\n * then counts none of its processes as the app's own.\n * - ADDITIVE (no version bump): `daemon.sessionProcesses`. An older host\n * answers \"method not found\"; the performance monitor then shows none of\n * its processes under a session.\n * - ADDITIVE (no version bump): `sessions.setPolicy` (and\n * `sessions.create`'s `policy`), `integrations.register` / `update` /\n * `list`, `mcp.instances` and `mcp.restart`. An older host answers\n * \"method not found\" and ignores the field.\n * - ADDITIVE (no version bump): `interactions.rehydrateSessions`,\n * `tokens.revokeSelf`, `fs.mkdir`, `fs.searchDirs`, the hello's `clone`\n * and `createFolders` (`git.clone` and `git.cloneCancel` take a `chat`\n * token), `whenIdle` on `sessions.appendTurns`, `origin`, `literal` and\n * `clientMessageId` on the send methods, the `delivery:changed` and\n * `integrations:changed` signals, and `takenOver` on `run:end`. An older\n * host answers \"method not found\" or ignores the fields; an older client\n * drops the unknown signals and reads a taken-over run as failed.\n * - 14: the `orchestration.*` verbs act as the CONNECTION (its token, or\n * the local window) instead of taking a `mainId`; `createWorker` takes\n * `tools` / `subscribe` and an optional `prompt`; new\n * `orchestration.wait`, `orchestration.events`, `orchestration.pending`, `orchestration.answer`\n * (`chat`) and `orchestration.approve` (`approve`); `answeredBy` on\n * `interaction:resolved` / `approval:resolved` and on interaction\n * responses. A v13 peer still speaks: `orchestration.main` is unchanged\n * and a stray `mainId` is ignored.\n */\nexport const IPC_PROTOCOL_VERSION = 14\n\n/**\n * The oldest protocol version this build still speaks, as a client and as a\n * zidane-server. A server accepts a client whose range\n * (`minProtocolVersion`…`protocolVersion`) overlaps its own, and the\n * connection speaks the lower of the two versions, so a web app deployed\n * against one release keeps working after the server moves one version on.\n * Raise it only when the code that speaks a version is removed. A local\n * daemon keeps the exact-version fence: it is respawned on upgrade.\n */\n// Typed `number`: it trails `IPC_PROTOCOL_VERSION` between bumps, and comparing two literal types reads as a mistake to the compiler.\nexport const IPC_MIN_PROTOCOL_VERSION: number = 13\n\n/**\n * JSON-RPC error codes specific to the zidane daemon. Lives here (not in\n * `daemon/server.ts`) so clients can import the codes without pulling the\n * server's module graph.\n */\nexport const IpcErrorCode = {\n VersionMismatch: -32010,\n NotHandshaken: -32011,\n /** A network transport's per-connection request budget is spent; retry later. */\n RateLimited: -32012,\n /**\n * The reply would exceed the transport's message size: nothing was sent\n * but this error (the connection stays). Ask for less (a transcript: a\n * smaller page, see {@link loadAllEvents}).\n */\n ResponseTooLarge: -32013,\n /**\n * The handler threw: the host refused or failed the call (`message` says\n * why). Hosts before it answered -32000, which ACP uses for\n * `AuthenticationRequired`; clients treat both as a plain remote error.\n */\n HandlerFailed: -32014,\n /**\n * The connection's token doesn't reach this method (`./scopes`: a `chat`\n * token calling an `admin` method). `data.required` names the scope it\n * needs. Additive: hosts before scopes never refuse this way.\n */\n Forbidden: -32015,\n} as const\n\n/**\n * The `data` of a `HandlerFailed` error from an extension install\n * (`catalog.install`, `extensions.changeOrigin`) that found extensions in\n * the source but not the one it needed: the installer's error code\n * (`name-mismatch`, `multiple-candidates`, `no-extension`) and the names it\n * found, for a client to list. Additive: older hosts send the names in the\n * message only.\n */\nexport interface ExtensionInstallErrorData {\n /** The installer's error code: `name-mismatch`, `multiple-candidates` or `no-extension`. */\n installError: string\n /** The extension names the source holds. */\n candidates: string[]\n}\n\n/**\n * The {@link ExtensionInstallErrorData} of a call's error `data`, or\n * `undefined` when it carries none.\n *\n * @param data - A JSON-RPC error's `data`, untrusted.\n */\nexport function extensionInstallErrorData(data: unknown): ExtensionInstallErrorData | undefined {\n if (typeof data !== 'object' || data === null)\n return undefined\n const { installError, candidates } = data as Partial<Record<keyof ExtensionInstallErrorData, unknown>>\n if (typeof installError !== 'string' || !Array.isArray(candidates) || !candidates.every(c => typeof c === 'string'))\n return undefined\n return { installError, candidates: [...candidates] }\n}\n\n/**\n * Client heartbeat request (`{}` → `{}`), outside the method table: every\n * host answers it, before the handshake too. A host predating it answers\n * \"method not found\", which still proves it alive.\n */\nexport const PING_METHOD = '$/ping'\n\n/**\n * Session-scoped signals fanned out to every peer carry their number in\n * their session as this extra field on the `ipc.signal` params (clients\n * predating it ignore it; `IpcClient` strips it and hands it to listeners as\n * {@link SignalMeta}). Per session, from 1, gap-free within one host process.\n */\nexport const SIGNAL_SEQ_FIELD = '$seq'\n\n/** What a signal listener gets beside the signal: its number in its session, when it has one. */\nexport interface SignalMeta {\n /** Position of the signal in its session. Starts at 1 and has no gaps within one host process. */\n seq: number\n}\n\n/** A session signal with its position in the session, as kept in the host's replay log. */\nexport interface SequencedSignal {\n /** Position of the signal in its session. */\n seq: number\n /** The signal itself. */\n signal: HostSignal\n}\n\n/** Result of `sessions.resume`. On success, the signals the client missed after its last position. Otherwise the reason it must reload instead. */\nexport type SessionResumeResult\n = | { ok: true, signals: SequencedSignal[] }\n /** `epoch`: another host process numbered them. `gap`: the log no longer covers the position. */\n | { ok: false, reason: 'epoch' | 'gap' }\n\n/* -------------------------------------------------------------------------\n * Request/response methods (client → host)\n * ---------------------------------------------------------------------- */\n\n/**\n * The optional client id of a send (`chat.send`, `chat.pushQueued`,\n * `queue.add`): a fresh one per user submission, the same one on its retries.\n * Per session, the first send with an id runs; a retry with the same id and\n * content answers the first result without running again, even across a host\n * restart; the same id with other content is refused (invalid params). A retry\n * of a send accepted but never settled (its host stopped) is refused with\n * \"already accepted\". A failed send frees its id. At most 128 characters; the\n * host keeps the last 256 ids per session. Additive: an older host ignores it.\n */\nexport interface SendRequestId {\n requestId?: string\n}\n\n/**\n * Typed method map for the daemon transport. Keys are JSON-RPC method\n * names; each entry pins params/result so both the daemon dispatch table\n * and the client proxy are checked against the same contract.\n *\n * Scope: the chat core every client needs. Host-UI-specific surfaces\n * (folder pickers, themes, keybindings) intentionally stay client-local.\n */\nexport interface IpcMethods {\n /**\n * `wake` is host-internal (see `SendOptions.wake`) — not accepted over the wire.\n * `requestId`: see {@link SendRequestId}.\n * The prompt goes through the extensions' prompt transforms and\n * `prompt` interceptors of the session's folder first, once per\n * submission, on the host (clients never run them). `consumed` says one took it instead of a run (`runId` is\n * then `''`): `handled` (an extension consumed it), `steer` / `followUp`\n * (delivered to the live run). Additive.\n */\n 'chat.send': { params: Omit<SendOptions, 'wake'> & SendRequestId, result: { runId: string, consumed?: 'handled' | 'steer' | 'followUp' } }\n /** Aborts the session's live run. Does nothing when no run is live. */\n 'chat.interrupt': { params: { sessionId: string }, result: void }\n /**\n * `true` when the message reached a live run; `false` when nothing was running (it was not delivered).\n * The message goes through the `prompt` interceptors first, as `chat.send` (`true` when one handled it).\n */\n 'chat.steer': { params: { sessionId: string, message: string, clientMessageId?: string }, result: boolean }\n /**\n * Adds a follow-up message to the live run. Resolves `true` when a run was live to take it, `false` when nothing was running and the message was dropped, not queued.\n * The message goes through the `prompt` interceptors first, as `chat.send` (`true` when one handled it).\n */\n 'chat.followUp': { params: { sessionId: string, message: string, clientMessageId?: string }, result: boolean }\n /**\n * Delivers a queued message. Steers a live run, otherwise starts a run or runs it as a command. `delivered` says which path it took. `keepDraft` keeps the shared composer draft instead of clearing it on the other clients.\n * The message goes through the `prompt` interceptors first, as `chat.send`; `consumed` says one took it (`delivered` is then `send` for `handled`, `steer` otherwise). Additive.\n */\n 'chat.pushQueued': {\n params: { sessionId: string, message: string, activatedSkills?: string[], keepDraft?: boolean, origin?: SendOptions['origin'], literal?: boolean, clientMessageId?: string, metadata?: SendOptions['metadata'] } & SendRequestId\n result: { delivered: 'steer' | 'send' | 'command' | 'queued', consumed?: 'handled' | 'steer' | 'followUp' }\n }\n /** Resolves `true` while the session has a live run. */\n 'chat.isRunning': { params: { sessionId: string }, result: boolean }\n /**\n * Retire the session's live agent so the next run rebuilds against\n * fresh config/credentials (MCP login, extension reload). Run-end\n * deferred when a run is in flight; HITL/queue state survives.\n */\n 'chat.rebuildAgent': { params: { sessionId: string }, result: void }\n /**\n * `zidane run --system / --mcp` for a host-backed window: launch overrides\n * for the session's agent (`ChatHost.setLaunchOverrides`), owned by the\n * calling client and dropped when it disconnects. A call with neither field clears them.\n */\n 'sessions.setLaunchOverrides': { params: { sessionId: string } & SessionLaunchOverrides, result: void }\n /**\n * Drop the daemon's cached runtime configs (extension registries, per\n * cwd) and retire every live agent so the next command or run rebuilds\n * against what is on disk now. Sent by a window after it reloaded its\n * own extensions (install, update, remove, `/reload`): extension `/`\n * commands execute daemon-side, so without this the daemon keeps\n * running the code it loaded at boot. Busy sessions rebuild at run end.\n */\n 'runtime.reload': { params: Record<string, never>, result: void }\n /**\n * Lists the tool calls and background tasks the session's live run tracks\n * and can cancel. Empty when no run is live. `children: true` adds the\n * subagents' running calls (`childId` set), for their starts: a\n * transcript read from disk times them too. Older hosts ignore it.\n */\n 'chat.listWork': { params: { sessionId: string, children?: boolean }, result: RunningWorkItem[] }\n /** Cancels one tracked work item by `id`, or every visible item with `\"all\"`. Resolves `true` when something was cancelled. `reason` is passed to a cancelled tool call. */\n 'chat.cancelWork': { params: { sessionId: string, id: string | 'all', reason?: string }, result: boolean }\n\n /** Lists session rows. `projectRoot` filters by project, `archive` picks active, archived or all sessions. */\n 'sessions.list': { params: { projectRoot?: string | null, archive?: 'active' | 'archived' | 'all' }, result: SessionRow[] }\n /**\n * The session list as a window renders it (`SessionMeta`: title, turn /\n * message / run counts, project, cwd, environment, artifact count, the\n * orchestration main flag), newest first. `projectRoot`: omitted = every\n * project, `null` = untagged sessions.\n */\n 'sessions.listMeta': { params: { projectRoot?: string | null }, result: SessionMeta[] }\n /** One `SessionMeta` by id (rows a filtered list can't return, e.g. the main); `null` when unknown. */\n 'sessions.getMeta': { params: { sessionId: string }, result: SessionMeta | null }\n /**\n * The whole session document as the host holds it: the live copy when an\n * agent is live (turns persisted mid-run, todos kept in memory), else the\n * stored one, a stale `running` marker demoted. `null` when unknown.\n */\n 'sessions.get': { params: { sessionId: string, turns?: boolean }, result: SessionDocumentHead | null }\n /**\n * A slice of a session's turns, `[from, from + limit)` (default from 0,\n * {@link SESSION_TURNS_PAGE} turns, at most {@link SESSION_TURNS_MAX_PAGE}),\n * from the same copy `sessions.get` reads, and how many turns it has: a\n * client reads a long session's document a page at a time\n * ({@link loadSessionDocument}) instead of in one reply. With\n * `sessions.get` `turns: false` (the document without its turns), what an\n * export needs. Pages and that head come from one snapshot of the\n * document per content version (read once, not per page), and name it\n * (`version`): a client that sees it change mid-load starts over rather\n * than mix two versions ({@link loadSessionDocument}). `null` when\n * unknown. Additive: an older host answers \"method not found\", ignores\n * `turns: false`, and names no version.\n */\n 'sessions.getTurns': { params: { sessionId: string, from?: number, limit?: number }, result: { turns: SessionTurn[], total: number, version?: string } | null }\n /**\n * The full text of one tool result (`callId`; `turnId`, when known, the\n * turn that holds it): what a clipped tool row shows on expand, without\n * the session crossing the wire. `null` when no such result. Additive.\n */\n 'sessions.getToolResult': { params: { sessionId: string, callId: string, turnId?: string }, result: string | null }\n /**\n * One session's header: its list row plus metadata, profile and status,\n * without turns or runs (the live copy when an agent holds it). What a\n * window re-reads on `sessions:changed`. Additive. `usage: true` adds the\n * footer's numbers, computed host-side from the turns and runs\n * (`contextTokens`, `costUsd`, and while the host runs the session\n * `runStartedAt` / `runOutputTokens`): a client needs no document for its\n * context gauge, cost pill or run readout. Older hosts ignore it.\n */\n 'sessions.getHeader': { params: { sessionId: string, usage?: boolean }, result: SessionHeader | null }\n /**\n * One key of an extension's per-session state (`metadata.extensions`, the\n * bag `ctx.session` and renderer `useSessionState` share), written by the\n * host into its copy of the session. `value` omitted deletes the key.\n */\n 'sessions.setExtensionState': { params: { sessionId: string, extension: string, key: string, value?: JsonValue }, result: void }\n /** Creates a session and resolves with its row. */\n 'sessions.create': { params: CreateSessionParams, result: SessionRow }\n /** Resolves with what happened to the session's environment (a provider may keep it). */\n 'sessions.delete': { params: { sessionId: string }, result: { environment?: EnvironmentTeardownResult } }\n /**\n * A session's `/side` session (`sessions.create` with `sideOf`; hidden from\n * `sessions.list`), the newest when there are several, with the session's\n * own row (`null`: unknown). Additive.\n */\n 'sessions.sideSession': { params: { sessionId: string }, result: SideSessionLookup }\n /** Provision a failed (or restart-stranded) environment again. */\n 'sessions.retryEnvironment': { params: { sessionId: string }, result: void }\n /** Move an idle session to another environment (`local`, `worktree`, `local@M`, `worktree@M`, any direction), in `cwd` on the target; provisioning continues in the background. */\n 'sessions.moveEnvironment': { params: { sessionId: string, environment: EnvironmentRequest, cwd?: string, removeOldWorktree?: boolean }, result: { oldWorktree?: EnvironmentTeardownResult } }\n /** The per-session commands the session's environment offers right now (push, open PR, …). */\n 'sessions.environmentActions': { params: { sessionId: string }, result: EnvironmentActionSummary[] }\n /** Run one of them in the session's environment (resumed when suspended). */\n 'sessions.runEnvironmentAction': { params: { sessionId: string, actionId: string }, result: EnvironmentActionResult }\n /**\n * The session's workspace (`ChatHost.workspace*`): its execution context,\n * rooted inside the environment when the files live there, else at the\n * session's cwd. Paths and exec `cwd` resolve against the root as the\n * execution context resolves them; containment is the context's own.\n * `cwd` / `env` on exec and the list / size methods are additive: an\n * older daemon ignores the former and answers \"method not found\" to the\n * latter (active clients are build-fenced, so this is a transient case).\n */\n 'sessions.workspaceExec': { params: { sessionId: string, command: string, cwd?: string, env?: Record<string, string>, timeoutSeconds?: number }, result: ExecResult }\n /**\n * The same command, streamed (`!` on a remote host): the reply names the\n * exec, its output follows as `workspace:exec:data` signals and ends with\n * one `workspace:exec:exit`, all to this connection only (signals may\n * precede the reply). Bounded per connection (concurrent commands, chunk\n * size, total output: past it the process is stopped and the exit says\n * `truncated`). A dropped connection kills what it started. Additive: an\n * older host answers \"method not found\" and clients use `workspaceExec`.\n */\n 'sessions.workspaceExecStream': { params: { sessionId: string, command: string, cwd?: string }, result: { execId: string } }\n /** Kill a streamed command's process group (this connection's only; `cancelled: false` otherwise or when it already ended). */\n 'sessions.workspaceExecCancel': { params: { execId: string }, result: { cancelled: boolean } }\n /**\n * Runs a shell block of a reply (Run here) in the session's folder, with no input. The reply names the run; its\n * output follows as `block-run:data` signals and ends with one `block-run:end` carrying the saved run, to this\n * connection only. Nothing enters the conversation; the run becomes the block's last (`sessions.blockRuns`),\n * announced to every window by `block-runs:changed`. A dropped connection stops what it started.\n */\n 'sessions.runBlock': { params: { sessionId: string, turnId: string, code: string, language: string }, result: { runId: string } }\n /** Stops a Run here this connection started (`cancelled: false` when it is not running). */\n 'sessions.runBlockCancel': { params: { runId: string }, result: { cancelled: boolean } }\n /** The session's saved block runs, by key (`blockRunKey`). */\n 'sessions.blockRuns': { params: { sessionId: string }, result: { runs: Record<string, BlockRun> } }\n /** Forgets a block's saved run. */\n 'sessions.removeBlockRun': { params: { sessionId: string, key: string }, result: void }\n /** Reads a text file from the session's workspace. */\n 'sessions.workspaceReadFile': { params: { sessionId: string, path: string }, result: string }\n /** Writes a text file in the session's workspace. */\n 'sessions.workspaceWriteFile': { params: { sessionId: string, path: string, content: string }, result: void }\n /** Lists the entries under `path` in the session's workspace. */\n 'sessions.workspaceListFiles': { params: { sessionId: string, path: string, options?: WorkspaceListFilesOptions }, result: ListFilesEntry[] }\n /** Size in bytes of a file in the session's workspace, or `null` when it does not exist. */\n 'sessions.workspaceFileSize': { params: { sessionId: string, path: string }, result: number | null }\n /*\n * Entry actions in the session's workspace (`ChatHost.workspaceCreate` …):\n * paths relative to the root, never `..` or absolute, nothing\n * overwritten; a refusal is a result (`ok: false`), not an error. Additive.\n */\n /** Creates a file (`content`: base64 bytes, default empty) or a folder; `freeName` takes the next free name instead of refusing a taken one. */\n 'sessions.workspaceCreate': { params: { sessionId: string, path: string, kind: 'file' | 'dir', content?: string, freeName?: boolean }, result: EntryResult }\n /** Moves (renames) `from` to `to`. */\n 'sessions.workspaceMove': { params: { sessionId: string, from: string, to: string }, result: EntryResult }\n /** Copies `from` into folder `toDir` (`''`: the root) under a free name. */\n 'sessions.workspaceCopy': { params: { sessionId: string, from: string, toDir: string }, result: EntryResult }\n /** Removes `path` (a folder whole), for good. */\n 'sessions.workspaceRemove': { params: { sessionId: string, path: string }, result: EntryResult }\n /** The workspace's empty folders, relative to its root (a file listing leaves them out), capped. */\n 'sessions.workspaceEmptyDirs': { params: { sessionId: string }, result: string[] }\n /**\n * Every environment kind the host can create, described for a new session\n * in `cwd` (availability, default, branch suggestion, options — secrets\n * only as \"configured\"). What pickers and the Environments settings render.\n * `kind`: a machine kind (`local@laptop`) says `cwd` is that machine's\n * folder, checked against its roots instead of this host's\n * (`docs/MACHINES.md` § Folders); the same on `commands.*`, `catalog.*`\n * and `models.list`. Additive.\n */\n 'environments.list': { params: { cwd?: string, kind?: string }, result: EnvironmentDescriptor[] }\n /**\n * Apply one Environments-settings edit (enable, default, options,\n * secrets), validated against the kind's schema. Settings changes fan out\n * as `settings:changed`; secrets are stored host-side and never returned.\n */\n 'environments.update': { params: EnvironmentSettingsChange, result: void }\n /** \"Test connection\" for a kind with its current options. */\n 'environments.verify': { params: { kind: string }, result: EnvironmentVerifyResult }\n /** Renames a session. */\n 'sessions.setTitle': { params: { sessionId: string, title: string }, result: void }\n /**\n * Title the session ON the host: its providers and credentials (a server\n * session's transcript never goes to the window's provider), the same\n * generator (`generateSessionTitle`), written as `sessions.setTitle` does.\n * `providerKey` / `model`: the window's pick, used when the host has that\n * provider; otherwise the session's own provider and model. The Main\n * session is refused (it keeps its name). Additive: an older host answers\n * \"method not found\".\n */\n 'sessions.generateTitle': { params: { sessionId: string, providerKey?: string, model?: string }, result: { title: string } }\n /**\n * How the session's title came about, as the session details dialog words\n * it (`describeTitleStatus`): where it came from (`auto`, `typed by you`,\n * `untitled`, …), then the last automatic titling attempt when there was\n * one (`generated 2h ago`, `check failed 5m ago (…)`). Additive.\n */\n 'sessions.titleStatus': { params: { sessionId: string }, result: string[] }\n /** Archives or restores a session. */\n 'sessions.setArchived': { params: { sessionId: string, archived: boolean }, result: void }\n /** Keep the session at the top of lists (`metadata.favorite`). Not activity: no recency bump. Additive. */\n 'sessions.setFavorite': { params: { sessionId: string, favorite: boolean }, result: void }\n /**\n * Replaces the session's rules (`metadata.policy`, {@link SessionPolicy}); `{}` clears them.\n * Loosening the current rules (a looser `approvalMode`, 'ask' > 'decide' > 'off', removing a rule, raising a ceiling) needs an approve token. Additive.\n */\n 'sessions.setPolicy': { params: { sessionId: string, policy: SessionPolicy }, result: void }\n /** Move the session to a space (`metadata.spaceId`); the Default space id clears it. See `chat/spaces`. */\n 'sessions.setSpace': { params: { sessionId: string, spaceId: string }, result: void }\n /** Switches the agent the session runs as. */\n 'sessions.setAgentId': { params: { sessionId: string, agentId: string }, result: void }\n /** Sets the thinking effort of the session. */\n 'sessions.setEffort': { params: { sessionId: string, effort: ThinkingLevel }, result: void }\n /**\n * The one model-swap contract (`ChatHost.setSessionModel`). A pick is a\n * whole: `fallbacks` (ordered, primary excluded) REPLACES the persisted\n * `metadata.modelChain` (omitted/empty clears it); `effort` and\n * `modelOptions` are reset to the supplied values (omitted clears them —\n * per-model knobs never leak onto the new model). The live agent is\n * retired so the next run rebuilds on the new pick (run-end deferred\n * while a run is in flight).\n */\n 'sessions.setModel': {\n params: {\n sessionId: string\n providerKey: ProviderKey\n modelId: string\n /** The stored account of the provider to run on (credential id); omitted = its active account. Additive. */\n account?: string\n fallbacks?: ModelFallbackRef[]\n effort?: ThinkingLevel\n modelOptions?: Record<string, boolean>\n }\n result: void\n }\n /** Replaces the model-specific boolean options of the session. */\n 'sessions.setModelOptions': { params: { sessionId: string, options: Record<string, boolean> }, result: void }\n /**\n * The session's transcript as canonical events. Without `before` / `limit`:\n * every turn, as a plain array (the shape every client predating paging\n * reads). With either: one page, `{ events, cursor? }`, the last `limit`\n * turns (default {@link LOAD_EVENTS_PAGE_TURNS}, at most\n * {@link LOAD_EVENTS_MAX_PAGE_TURNS}) before turn position `before`\n * (default: the end), its start moved back to an exchange boundary when one\n * is near so a tool call is never cut from its result. `cursor`: the\n * `before` of the previous page, absent at the first turn. Typed here as\n * the unpaged call every client makes; a paged call goes through\n * {@link loadEventsPage}. Paging is additive: an older host ignores the\n * fields and answers the whole array.\n */\n 'sessions.loadEvents': { params: { sessionId: string }, result: StreamEvent[] }\n /**\n * Reattach without a reload: the session's signals numbered after\n * `afterSeq` (see {@link SIGNAL_SEQ_FIELD}), in order, as long as this host\n * process (`epoch`, from `HelloResult.signalEpoch`) still holds them all.\n * Otherwise refused, and the client reloads with `sessions.loadEvents`.\n * Additive: an older host answers \"method not found\", same fallback.\n */\n 'sessions.resume': { params: { sessionId: string, epoch: string, afterSeq: number }, result: SessionResumeResult }\n /** One turn of a session by id, or `null` when unknown. */\n 'sessions.getTurn': { params: { sessionId: string, turnId: string }, result: SessionTurn | null }\n /** The session's context usage broken down by category, or `null` when unknown. */\n 'sessions.contextBreakdown': { params: { sessionId: string }, result: ContextBreakdown | null }\n /**\n * Artifacts one session recorded (PRs, branches, commits, files,\n * extension kinds — see `session/artifacts.ts`), newest first. Empty on\n * stores without artifact support. Additive; pre-artifact daemons\n * reject the method and clients treat that as empty.\n */\n 'sessions.artifacts': { params: { sessionId: string, kind?: string, limit?: number }, result: SessionArtifact[] }\n /**\n * Artifacts across sessions, filtered by project root (`null` = untagged\n * sessions, omitted = every project) and/or kind/uri (reverse lookup).\n */\n 'artifacts.list': { params: { projectRoot?: string | null, kind?: string, uri?: string, since?: number, limit?: number }, result: SessionArtifact[] }\n /** Remove one artifact. `false` when the store has no artifact support. Fans out `artifact:changed`. */\n 'artifacts.delete': { params: { sessionId: string, artifactId: string }, result: boolean }\n /**\n * Upsert an artifact — the lazy `resolve()` write-back (refreshed\n * `label` / `meta`). Same merge semantics as `SessionStore.upsertArtifact`;\n * `null` when the session is unknown or the store lacks support.\n */\n 'artifacts.upsert': { params: { artifact: SessionArtifact }, result: SessionArtifact | null }\n /**\n * Re-resolves one stored artifact (is the pull request merged?): its kind's\n * `resolve()` runs on the host, with the extensions of the folder the\n * artifact landed in. A change is stored and fans out `artifact:changed`.\n * `force` asks past the kind's own freshness window. `null` when nothing\n * changed (no resolver, nothing new, an unknown artifact). Additive.\n */\n 'artifacts.refresh': { params: { sessionId: string, artifactId: string, force?: boolean }, result: SessionArtifact | null }\n /**\n * The badges under sessions' titles (commits, pull requests, extension\n * kinds with a `badge`), for up to `ARTIFACT_BADGES_MAX` sessions at once,\n * keyed by session id. Each session's badges come from the extensions of\n * the folder its newest artifact landed in. They change with the\n * session's `artifact:recorded` / `artifact:changed` and with\n * `catalog:changed` (`extensions`): read them again then. Additive.\n */\n 'artifacts.badges': { params: { sessionIds: string[] }, result: Record<string, SessionBadgeEntry[]> }\n /**\n * Transcript search over ONE session, daemon-side. The daemon owns the\n * authoritative turns (live wrapper when an agent is active — fresh\n * mid-run, which a window's load-time snapshot is not) and an LRU index\n * cache shared by every window, so repeat queries pay match cost only.\n * Results come back in TURN ORDER (search is a transcript filter).\n */\n 'history.searchSession': {\n params: { sessionId: string, query: string, limit?: number }\n result: SearchTurnResult[]\n }\n /**\n * Cross-session content search, daemon-side. One RPC replaces a\n * window's per-session index/build/search round-trips — indexes are\n * built once in the daemon and shared by every window.\n */\n 'history.searchAll': {\n params: { query: string, sessionIds: string[], excerptLimit?: number }\n result: Record<string, SessionHistoryMatch>\n }\n /**\n * A window appended transcript content OUT-OF-BAND (local `/` command\n * output, `!` shell turns — written straight to the shared store, not\n * through a host run). The daemon fans out `sessions:changed` so every\n * window (issuer included) re-converges on the canonical replay NOW\n * instead of at the next run end. Sent as a notification.\n */\n 'sessions.touch': { params: { sessionId: string }, result: void }\n /** Fork at `turnId` into a new session (`ChatHost.forkSession`); announced as a `sessions:changed` create. */\n 'sessions.fork': { params: { sessionId: string, turnId: string, title?: string }, result: { id: string } }\n /** History edits (`ChatHost.deleteTurn` / `editTurnText`): refused while the session runs. */\n 'sessions.deleteTurn': { params: { sessionId: string, turnId: string }, result: void }\n /** Replaces the text of one turn. Refused while the session runs. */\n 'sessions.editTurnText': { params: { sessionId: string, turnId: string, text: string }, result: void }\n /** Cut the history at `turnId` in place (`ChatHost.rewindSession`); `inclusive` keeps the turn. Refused while the session runs. */\n 'sessions.rewind': { params: { sessionId: string, turnId: string, inclusive: boolean }, result: void }\n /** Bind to a folder, or back to a plain chat with `cwd: ''` (`ChatHost.setSessionFolder`). */\n 'sessions.setFolder': { params: { sessionId: string, cwd: string }, result: void }\n /** Turns written outside a run, e.g. `!` shell output (`ChatHost.appendTurns`). `whenIdle`: refused while a run is live or an interrupted run waits (a channel's context messages). */\n 'sessions.appendTurns': { params: { sessionId: string, turns: SessionTurn[], whenIdle?: boolean }, result: void }\n /**\n * `ctx.appendNote` outside a run: a display-only note, rendered live and\n * persisted (`ChatHost.appendNote`). False for an unknown session or no blocks.\n */\n 'sessions.appendNote': { params: { sessionId: string, blocks: CommandOutputBlock[] }, result: boolean }\n /** Compact now (`ChatHost.compactSessionNow`): what was done, `null` when nothing was. Older daemons resolve `null`. */\n 'sessions.compact': { params: { sessionId: string }, result: CompactionReport | null }\n\n /** The session's todo list, or `null` when it has none. */\n 'todos.get': { params: { sessionId: string }, result: TodosSnapshot | null }\n /**\n * Apply a user todo edit (add / edit / remove / cycle / clear) to the\n * session the MODEL reads.\n *\n * Required because todos live in `session.metadata` and `todowrite` reads\n * them off the daemon agent's in-memory `Session`. A window writing its own\n * `Session` instance persisted an edit that the daemon never observed, so the\n * model's next `todowrite` silently overwrote it.\n *\n * Sends the whole list rather than a delta: the mutators in\n * `chat/todo-edits.ts` are already whole-list transforms, and a delta would\n * need conflict rules against a list the model rewrites concurrently.\n *\n * `null` = no live agent (or no run owns a todo slot), and the caller should\n * apply its own store-level write — race-free, since nothing is appending.\n *\n * `persistIdle`: with no live agent, the host applies the edit to the stored\n * session itself (the run the list belongs to must exist) instead of\n * answering `null`. Older hosts ignore it.\n */\n 'todos.set': { params: { sessionId: string, items: readonly TodoItem[], persistIdle?: boolean }, result: TodosSnapshot | null }\n\n /*\n * Orchestration — the verbs over other sessions (docs/ORCHESTRATION.md).\n * The caller is the CONNECTION: its token's principal on a zidane-server,\n * the local window otherwise. It reaches every session (the Main\n * included) except `/side` sessions; what it creates is tagged with it\n * (`createdBy`), and revoking its token stops those sessions. The Main's\n * own switch (`Settings.orchestration`) gates only the Main.\n */\n /** The main session id, creating it (directory-less) when the setting is on and none exists. */\n 'orchestration.main': { params: Record<string, never>, result: string | null }\n /** Creates a session (optionally holding orchestration tools and a subscription) and resolves with its id. */\n 'orchestration.createWorker': { params: OrchestrationCreateParams, result: string }\n /** Lists sessions with their live status, newest first, up to `limit`. The list can be partial. */\n 'orchestration.list': { params: { limit?: number }, result: OrchestrationWorkerRow[] }\n /** Summary of one session; rejects when unknown. */\n 'orchestration.read': { params: { sessionId: string }, result: OrchestrationWorkerSummary }\n /** Queues a prompt as the session's next turn; `false` when declined (the person stopped the session, or their queued prompts go first). */\n 'orchestration.send': { params: { sessionId: string, prompt: string }, result: boolean }\n /** Sends a steering message to a session's live run. */\n 'orchestration.steer': { params: { sessionId: string, message: string }, result: void }\n /** Cancels a session's run. */\n 'orchestration.cancel': { params: { sessionId: string }, result: void }\n /** The last `limit` turns of a session as plain text. */\n 'orchestration.transcript': { params: { sessionId: string, limit?: number }, result: string }\n /** Resolves once the session is idle or blocked, or after `timeoutSec` (default 30, at most 50). */\n 'orchestration.wait': { params: { sessionId: string, timeoutSec?: number }, result: OrchestrationWaitResult }\n /** Searches the recent session events (runs ended, sessions blocked), newest first. */\n 'orchestration.events': { params: OrchestrationEventQuery, result: SessionEvent[] }\n /** The prompts waiting for an answer (questions, plans, tool approvals), of one session or all. */\n 'orchestration.pending': { params: { sessionId?: string }, result: OrchestrationPendingRequest[] }\n /** Answers a question or a plan, recording the connection as `answeredBy`. `false` when it was answered first. */\n 'orchestration.answer': { params: { requestId: string, response: InteractionResponse }, result: boolean }\n /** Decides a tool approval (an `approve` token), recording the connection as `answeredBy`. `false` when it was decided first. */\n 'orchestration.approve': { params: { requestId: string, decision: ApprovalDecision }, result: boolean }\n\n /** Extension-contributed `/` commands discovered for `cwd`. */\n 'commands.list': { params: { cwd: string, kind?: string }, result: CommandSummary[] }\n /** Argument suggestions for `/name <prefix>` — best-effort, empty on failure. */\n 'commands.completeArgs': { params: { cwd: string, name: string, argsPrefix: string, kind?: string }, result: CommandArgSuggestionSummary[] }\n /** The agent profiles `cwd` offers (`''`: no folder), as the agent picker lists them: a profile a setting turns off (Codemode) is left out. Additive. */\n 'agents.list': { params: { cwd: string }, result: HostAgentProfile[] }\n /**\n * The extension completion providers (`ctx.registerCompletionProvider`) of\n * `cwd` a composer can render: a one-character trigger each, `@` `/` `#`\n * left to the built-in completers, first wins on id and trigger. Additive.\n */\n 'completions.providers': { params: { cwd: string }, result: ExtensionCompletionProviderSummary[] }\n /**\n * One provider's items for `query` (the text after its trigger), at most\n * 8. A newer call for the same provider on the connection aborts this one;\n * `[]` past 5 s or when the provider throws. Additive.\n */\n 'completions.suggest': { params: { cwd: string, providerId: string, query: string, text: string, cursor: number }, result: ExtensionCompletionItemSummary[] }\n /** Runs the providers' submit hooks (`resolveReferences`, `onSubmit`) on a prompt about to be sent; resolves after them, or after 5 s. Additive. */\n 'completions.submit': { params: { cwd: string, text: string, cursor: number }, result: void }\n /**\n * The extension text reference providers (`ctx.registerReferences`) of\n * `cwd`: the patterns a client matches prose with. `peek`: only from a\n * registry already built for `cwd` (`null` when none is), so a list of\n * titles across projects never builds one per project. Additive.\n */\n 'references.providers': { params: { cwd: string, peek?: boolean }, result: ReferenceProviderWire[] | null }\n /** The views of the keys a client found, in order: `null` for one that names nothing. At most 50 keys per call. Additive. */\n 'references.resolve': { params: { cwd: string, items: { providerId: string, key: string }[] }, result: (ExtensionReferenceView | null)[] }\n /** The extensions' items (`ctx.registerBadgeActions`) of a badge's menu in `cwd`; the built-in ones are the client's. Additive. */\n 'badges.actions': { params: { cwd: string, target: BadgeTarget }, result: BadgeMenuItem[] }\n /** Runs an extension's badge item; the effect (copy, open, a notice) is the client's to apply. Additive. */\n 'badges.run': { params: { cwd: string, source: string, id: string, target: BadgeTarget }, result: BadgeActionEffect }\n /**\n * The side panels `cwd`'s extensions register. A panel's `load` and\n * `onAction` run on the host, bound to `cwd` and the session `ctx` names,\n * with a hard timeout: a failing panel answers an empty content naming why\n * (`load`) or `ok: false` (`action`), never an error. Additive.\n */\n 'panels.list': { params: { cwd: string }, result: PanelSummary[] }\n /** One panel's content for `ctx` (the session it shows beside, what opened it). Additive. */\n 'panels.load': { params: { cwd: string, panelId: string, ctx?: PanelLoadContextInput }, result: PanelContent }\n /** Run one of a panel's actions (a row's or the footer's `actionId`, its `payload`). Additive. */\n 'panels.action': { params: { cwd: string, panelId: string, actionId: string, payload?: unknown, ctx?: PanelLoadContextInput }, result: { ok: true } | { ok: false, error: string } }\n /**\n * Keep a panel's live updates on: this connection gets `panel:changed`\n * when its content changes. Calls count; a dropped connection releases its\n * own. Additive.\n */\n 'panels.watch': { params: { cwd: string, panelId: string }, result: void }\n /** Release one `panels.watch` of this connection. */\n 'panels.unwatch': { params: { cwd: string, panelId: string }, result: void }\n /**\n * The command palette items `cwd`'s extensions contribute (each item's\n * `source` is its provider), and running one. A provider that fails lists\n * one disabled row naming why; a failed run answers `ok: false`. Additive.\n */\n 'palette.list': { params: { cwd: string, ctx: PaletteContext }, result: PaletteItem[] }\n /** Run `itemId` on its provider (`source`); a nested list, a prompt or a draft comes back as `result`. Additive. */\n 'palette.run': { params: { cwd: string, source: string, itemId: string, ctx: PaletteContext }, result: { ok: true, result: PaletteRunResult } | { ok: false, error: string } }\n /** As `panels.watch`, for every provider of `cwd`: `palette:changed`. Additive. */\n 'palette.watch': { params: { cwd: string }, result: void }\n /** Release one `palette.watch` of this connection. */\n 'palette.unwatch': { params: { cwd: string }, result: void }\n\n /** Lists pending interactions (questions and prompts the agent asked the user), optionally for one session. */\n 'interactions.list': { params: { sessionId?: string }, result: PendingInteraction[] }\n /** Answers a pending interaction. */\n 'interactions.respond': { params: { requestId: string, response: InteractionResponse }, result: { ok: boolean } }\n /** Cancels a pending interaction. `reason` is passed back to the agent. */\n 'interactions.cancel': { params: { requestId: string, reason?: string }, result: { ok: boolean } }\n /** Re-sends the session's pending interactions, for a client that connected after they were raised. */\n 'interactions.rehydrate': { params: { sessionId: string }, result: PendingInteraction[] }\n /**\n * `interactions.rehydrate` for each of `sessionIds` not running on this\n * host, loading only those whose run waits to be resumed or whose last\n * turns hold an unanswered question or plan (a channel start, over every\n * conversation it had).\n */\n 'interactions.rehydrateSessions': { params: { sessionIds: string[] }, result: PendingInteraction[] }\n /**\n * Dev browser: a window offers to host the pages the agent's `browser_*`\n * tools drive (the GUI's main process). Released when the connection\n * drops. It then answers each `browser:request` signal addressed to it.\n */\n 'browser.registerHost': { params: { hostId: string }, result: { ok: boolean } }\n /** Withdraws a window as dev browser host. */\n 'browser.unregisterHost': { params: { hostId: string }, result: { ok: boolean } }\n /** Answers a `browser:request` signal with the host's result. */\n 'browser.respond': { params: { requestId: string, response: BrowserResponse }, result: { ok: boolean } }\n /**\n * Terminals, run by the host in the session's environment. `clientId`\n * names one view (a window's drawer or panel); views attached through a\n * connection are detached when it drops. Output arrives as\n * `terminal:output` signals; `ack` what was written to keep it flowing.\n */\n 'terminal.state': { params: { sessionId: string }, result: TerminalSessionState }\n /** Opens a terminal in a session's environment. */\n 'terminal.open': { params: TerminalOpenInput, result: TerminalInfo }\n /** Attaches a view (`clientId`) to a terminal and resolves with the output it can replay. */\n /** `maxLines` caps the history snapshot to the last lines a view can show (0 or absent: no cap). */\n 'terminal.attach': { params: { terminalId: string, clientId: string, maxLines?: number }, result: TerminalAttachResult }\n /** Detaches a view from a terminal. */\n 'terminal.detach': { params: { terminalId: string, clientId: string }, result: void }\n /** `clientId` + `response`: bytes the view's emulator generated (DSR/DA replies), dropped unless that view owns the size. */\n 'terminal.write': { params: { terminalId: string, data: string, clientId?: string, response?: boolean }, result: void }\n /** Resizes the terminal to a view's size. `claim` makes this view own the size. */\n 'terminal.resize': { params: { terminalId: string, clientId: string, cols: number, rows: number, claim?: boolean }, result: void }\n /** Acknowledges terminal output up to `offset`, so the host keeps it flowing. */\n 'terminal.ack': { params: { terminalId: string, clientId: string, offset: number }, result: void }\n /** Restarts a terminal's process and resolves with its info. */\n 'terminal.restart': { params: { terminalId: string }, result: TerminalInfo }\n /** Closes a terminal. */\n 'terminal.close': { params: { terminalId: string }, result: void }\n /** Hides a terminal from the agent, or shows it again. */\n 'terminal.setHidden': { params: { terminalId: string, hidden: boolean }, result: void }\n /**\n * This connection can show terminals (the desktop app). While at least one\n * viewer is attached, agents get the terminal tools; the registration is\n * dropped with the connection.\n */\n 'terminal.registerViewer': { params: { viewerId: string }, result: { ok: boolean } }\n /** Withdraws a viewer registered with `terminal.registerViewer`. */\n 'terminal.unregisterViewer': { params: { viewerId: string }, result: { ok: boolean } }\n /**\n * Terminals without a session: a shell on the host's machine in a\n * project's folder, or in a new-chat draft's (`draftId`). Agents never see\n * them. `terminal:project-changed` carries a scope's full list.\n */\n 'terminal.projectState': { params: TerminalProjectStateInput, result: TerminalProjectState }\n /** Opens a terminal bound to a project rather than a session. */\n 'terminal.openInProject': { params: TerminalProjectOpenInput, result: TerminalInfo }\n /** The draft became `sessionId`: its terminals move there in one pass (over the cap: back to the project). */\n 'terminal.adopt': { params: { draftId: string, sessionId: string }, result: TerminalAdoptResult }\n /** The draft was discarded (or became a server session): its terminals go back to the project. */\n 'terminal.releaseDraft': { params: { draftId: string }, result: void }\n\n /** Answers a pending approval request with a decision. */\n 'approvals.resolve': { params: { requestId: string, decision: ApprovalDecision }, result: void }\n /** Denies every pending approval, or only those of `sessionId` when given. */\n 'approvals.denyAll': { params: { sessionId?: string }, result: void }\n /** Lists the approval requests waiting for an answer. */\n 'approvals.listPending': { params: Record<string, never>, result: WireApprovalRequest[] }\n /** The host's \"Always allow\" entries, per project (its `projects.json`): what approving with `accept-safelist` added. Additive. */\n 'safelist.list': { params: Record<string, never>, result: { projects: SafelistProject[] } }\n /** Revoke one \"Always allow\" entry of a project; `removed: false` when it was not there. Additive. */\n 'safelist.remove': { params: { project: string, entry: string }, result: { removed: boolean } }\n\n /**\n * Type-ahead queue, host-owned so every window sees and can manipulate\n * the same list. `queue.add` queues when a run is in flight and sends\n * immediately otherwise; the host auto-drains the queue FIFO at run end.\n */\n 'queue.list': { params: { sessionId: string }, result: QueuedItem[] }\n\n /**\n * Which `SYSTEM.md` override composes this session's prompt, for windows\n * attaching to an already-warm agent.\n *\n * The `system-md` signal fires once per agent BUILD and the daemon caches\n * agents, so the normal multi-window case (daemon already running, open a\n * second terminal or the GUI) would otherwise never learn that the built-in\n * safety and git doctrine has been replaced. `null` = no live agent yet, in\n * which case the next build broadcasts it.\n */\n 'sessions.systemMd': {\n params: { sessionId: string }\n result: { file: SystemMdFile | null, shadowed: readonly SystemMdFile[] } | null\n }\n /**\n * Every chunk of the session's system prompt with provenance — the\n * Instructions tab. Built from the live agent's assembly, so it reflects\n * MCP instructions, extension fragments and the resolved `SYSTEM.md`.\n */\n 'sessions.contextSegments': { params: { sessionId: string }, result: ContextSegmentsReport | null }\n /**\n * What a switch would cost the session's prompt cache, as the host applies\n * it (`ChatHost.cacheImpact`): what pickers show next to each option.\n * `null` without a live agent or for an empty change. Additive: an older\n * host answers \"method not found\", and clients show no estimate.\n */\n 'sessions.cacheImpact': { params: { sessionId: string, change: CacheImpactChange }, result: CacheImpact | null }\n /**\n * The session's last requests and what the cache did for each\n * (`ChatHost.cacheReport`): what `/cache` prints, for the GUI's session\n * details. `null` for an unknown session. Additive: an older host answers\n * \"method not found\".\n */\n 'sessions.cacheReport': { params: { sessionId: string, limit?: number }, result: CacheReport | null }\n /**\n * The session's transcript rendered as a file to hand to the user: Markdown (title, metadata, every turn) or the\n * session's JSON. Nothing is written on the host. Additive (no version bump).\n */\n 'sessions.export': { params: { sessionId: string, format: SessionExportFormat }, result: SessionExportFile }\n /** Seed a user-scope `SYSTEM.md` from the session's doctrine; throws when an override could not apply. */\n 'sessions.createSystemOverride': { params: { sessionId: string }, result: { path: string, created: boolean } }\n /**\n * Adds a message to the session's queue. `delivered` tells whether it was queued, sent right away, or used to steer a live run.\n * The message goes through the `prompt` interceptors first, as `chat.send`; `consumed` says one took it (`delivered` is then `sent` for `handled`, `steer` otherwise). Additive.\n */\n 'queue.add': {\n /**\n * `asCommand`: see `SendOptions.asCommand` — the host refuses when it cannot resolve it.\n * `keepDraft`: see `SendOptions.keepDraft` — a prompt from outside the composer.\n * `delivery`: steer or follow up the live run when one takes it (as `ctx.submitPrompt`), queued or sent otherwise. Additive.\n * `requestId`: see {@link SendRequestId}.\n */\n params: { sessionId: string, text: string, activatedSkills?: string[], attachments?: PromptAttachment[], asCommand?: string, keepDraft?: boolean, origin?: SendOptions['origin'], literal?: boolean, clientMessageId?: string, metadata?: SendOptions['metadata'], delivery?: 'steer' | 'followUp' } & SendRequestId\n result: { delivered: 'queued' | 'sent' | 'steer', consumed?: 'handled' | 'steer' | 'followUp' }\n }\n /** Removes a queued entry by id. Resolves `true` when it was removed. */\n 'queue.remove': { params: { sessionId: string, id: string }, result: boolean }\n /**\n * Edit a queued entry in place; order is kept. `attachments` replaces the\n * entry's list when given. `false` when already sent / dropped.\n */\n 'queue.update': { params: { sessionId: string, id: string, text: string, attachments?: PromptAttachment[] }, result: boolean }\n /** A queued entry's attachments with their bytes; `null` when already sent / dropped. */\n 'queue.attachments': { params: { sessionId: string, id: string }, result: PromptAttachment[] | null }\n /** Steer a queued entry into the live run now (falls back to send when idle). */\n 'queue.pushNow': { params: { sessionId: string, id: string }, result: { delivered: 'steer' | 'send' | 'queued' | 'missing' } }\n\n /** Current shared draft for a session — backfill on window attach. */\n 'drafts.get': { params: { sessionId: string }, result: { text: string, shell?: boolean, attachments?: PromptAttachment[], search?: { active: boolean, query: string } } }\n /**\n * Replace the session's shared draft. Fans out `draft:changed` to every\n * OTHER peer. Ephemeral daemon state — drafts don't survive a daemon\n * restart and are cleared when any window submits the prompt.\n *\n * `shell` carries the prompt's shell mode OUT OF BAND — never encoded\n * into the text, so a literal leading `!` in a normal draft can't flip\n * other windows into shell-execution semantics.\n */\n 'drafts.set': { params: { sessionId: string, text: string, shell?: boolean }, result: void }\n /** Replace the shared draft's composing attachments (notification). */\n 'drafts.setAttachments': { params: { sessionId: string, attachments: PromptAttachment[] }, result: void }\n /** Replace the shared transcript-search state (notification, per keystroke). */\n 'search.set': { params: { sessionId: string, active: boolean, query: string }, result: void }\n /**\n * Token spend, models, streaks and activity over `range`, from the host's\n * session store, as the desktop app's welcome screen shows its own\n * (`summarizeUsage`). Days are the host's local days; `userName` is\n * `null` (the host's user is not the reader). Refused by a store that\n * keeps no usage history (not a SQLite file). Additive.\n */\n 'usage.summary': { params: { range: UsageRange }, result: UsageSummary }\n /**\n * The plan and subscription windows of each provider the host holds a\n * credential for (every account), probed with the host's credentials and\n * cached a few minutes; `refresh` probes past the cache. A provider that\n * can't be read reports `status: 'unavailable'`. Additive.\n */\n 'usage.providers': { params: { refresh?: boolean }, result: readonly ProviderUsageSnapshot[] }\n /**\n * GitHub's API limits as the host's GitHub client last saw them, per\n * GitHub host; `probe` asks GitHub (`/rate_limit`, which costs no call).\n * Additive.\n */\n 'usage.github': { params: { probe?: boolean }, result: ProviderUsageSnapshot[] }\n /**\n * Resolve inline ghost-text autocomplete daemon-side (the typing\n * window's request IS the single computation): canonical resolver\n * against the session cwd's extension registry. Latest-wins per\n * session — a `seq` older than the newest seen returns\n * `{ suggestion: null }` without computing, and a newer request\n * aborts an in-flight compute. The result additionally fans out as\n * `suggest:changed` to every OTHER peer.\n */\n 'suggest.resolve': { params: { sessionId: string, text: string, caret: number, seq: number }, result: { suggestion: string | null, seq: number, candidates?: string[] } }\n\n /** Reads the host settings. */\n 'settings.get': { params: Record<string, never>, result: HostSettings }\n /** Applies a partial settings patch and resolves with the full settings after it. */\n 'settings.set': { params: { patch: Partial<HostSettings> }, result: HostSettings }\n /** The picks remembered across apps (`state.json`): effort and options per model, the next chat's model chain. `null` when none is. Additive. */\n 'prefs.get': { params: Record<string, never>, result: HostComposerPrefs | null }\n /** Merges picks into `state.json` (each top-level key replaces). Additive. */\n 'prefs.set': { params: { patch: HostComposerPrefs }, result: void }\n /** The sidebar views a client saved on this host, by space id (`state.json`'s `sidebarViews`): each client checks what it reads. Additive. */\n 'sidebar.getViews': { params: Record<string, never>, result: Record<string, unknown> }\n /** Saves one space's sidebar view (at most 4 KiB of JSON), stored as given: the kit's record is the filter axes plus `session`, the conversation last open in that space. Additive. */\n 'sidebar.setView': { params: { spaceId: string, view: Record<string, unknown> }, result: void }\n /** The space a client's sidebar showed last, `null` when none was saved. Additive. */\n 'sidebar.getSpace': { params: Record<string, never>, result: string | null }\n /** Saves the space the sidebar shows. Additive. */\n 'sidebar.setSpace': { params: { spaceId: string }, result: void }\n /**\n * The options the enabled extensions declare for `cwd`\n * (`registerConfigItem`), without the action items or the callbacks; the\n * values live on the settings' `extensionConfig`. Additive.\n */\n 'extensions.configSchema': { params: { cwd: string }, result: WireExtensionConfigSchema }\n /** The action rows (`registerConfigItem` type `'action'`) the enabled extensions declare for `cwd`. Additive. */\n 'extensions.actions': { params: { cwd: string }, result: ExtensionActionSummary[] }\n /** The actions' passive `status()` probes, keyed `extension:key`; a probe that throws or takes over 3 s is left out. Additive. */\n 'extensions.actionStatuses': { params: { cwd: string }, result: Record<string, ExtensionConfigActionStatus> }\n /**\n * Runs an action on the host. The config patch it returns comes back\n * sanitized, not written: the client saves it (`settings.set`). One run of\n * an action at a time. A token needs the action's `scope` (the action row's\n * `scope`; default, and for config-declared actions, `admin`). Additive.\n */\n 'extensions.runAction': { params: { cwd: string, extension: string, key: string }, result: ExtensionActionRunResult }\n /**\n * Scaffolds a new extension and reloads the registries: in the host user's\n * `extensions` folder (`scope: 'user'`, the default), or in a project\n * (`scope: 'project'`: `cwd`'s checkout, which must lie in the workspace\n * roots; it loads once the project is trusted). Sessions stay in the\n * roots: one may open in a project extension's folder, never in a user\n * extension's. It writes code the host will run: a zidane-server's\n * `allowRemoteInstalls` gates it, every attempt is audited. Every window\n * gets `catalog:changed`. Additive.\n */\n 'extensions.create': { params: CreateExtensionInput, result: CreateExtensionResult }\n\n /*\n * Extension API. Every method that names a `cwd` acts on the extension\n * runtime of that folder's registry; a folder without extensions answers\n * empty. Signals: `rpc.event`, `extensions:*`, `ui:*`\n * (`./chat/host/extensions-wire`).\n */\n /**\n * Calls an extension's RPC method as this connection. Never throws for a\n * failed call: a declared error, invalid input, a missing provider or a\n * method whose `scope` this connection's token does not reach\n * (`rpc.forbidden`; a local connection is not limited) comes back as\n * `ok: false` with its `type`. `directory` (or `cwd`) picks the runtime;\n * without it, the newest runtime that has the contract. `callId` lets\n * `rpc.cancel` abort it. Also served as `POST /rpc/<contract>/<method>` on a\n * zidane-server, with the same token. Additive.\n */\n 'rpc.call': { params: RpcCallParams & { cwd?: string }, result: RpcResponseEnvelope }\n /** Aborts this connection's `rpc.call` of `callId`; it answers `rpc.aborted`. `false` when none is in flight. Additive. */\n 'rpc.cancel': { params: { callId: string }, result: boolean }\n /**\n * Every UI item of `cwd`'s extensions, per token, in wire form, and\n * each active extension's compiled `ui` bundle (`bundles`, by extension\n * id). `extensions:ui` pushes each change after it. Additive.\n */\n 'extensions.ui.list': { params: { cwd: string }, result: WireUiList }\n /**\n * The extensions of `cwd`: status, folder, `tui` entry and compiled\n * `ui` bundle. What a window draws extensions from in daemon mode,\n * without running their `setup`. `extensions:entries` says when to list\n * again. Additive.\n */\n 'extensions.entries': { params: { cwd: string }, result: WireExtensionEntry[] }\n /**\n * Runs one callback of a UI item by its id (a panel's `load` / `onAction`,\n * a reference `resolve`, a badge menu or action, a settings page action,\n * status or check). Callbacks run on the host under their extension's\n * guard. Additive.\n */\n 'extensions.ui.invoke': { params: { cwd: string } & UiInvokeRequest, result: unknown }\n /**\n * Offers a link the user opened to `cwd`'s extensions' link handlers\n * (`LinkHandler`), higher `priority` first; a handler that returns\n * `false`, throws or times out passes it on. `handled: false`: open it the\n * app's own way. Apps call it for every link they open, except with Alt\n * held. Additive.\n */\n 'extensions.links.open': { params: LinkOpenParams, result: { handled: boolean } }\n /**\n * What this connection shows and whether it shows dialogs: dialogs\n * (`ui:dialog`) and UI requests (`ui:client`) go to the client viewing the\n * session, else the last active one. Only announced clients get them.\n * Send again on focus or session change. Additive.\n */\n 'ui.client.announce': { params: UiClientAnnounce, result: void }\n /** Answers a `ui:client` request sent to this connection. `false` when it is no longer pending. Additive. */\n 'ui.client.reply': { params: { requestId: string, result: unknown }, result: boolean }\n /** Answers a `ui:dialog` shown on this connection (`answer` absent: cancelled). `false` when it is no longer pending. Additive. */\n 'ui.dialog.answer': { params: { dialogId: string, answer?: unknown }, result: boolean }\n /**\n * Checks one value of a `form` dialog shown on this connection: the\n * field's error message, or `null` when it is valid (or the dialog is no\n * longer pending here). Clients call it as the user edits a field and\n * before they answer, and show the message under the field. The host checks\n * the answer again: an answer with an invalid value makes the extension's\n * `ctx.ui.form` reject, so a client must not answer until every field\n * validates. Additive.\n */\n 'ui.dialog.validate': { params: { dialogId: string, key: string, value: unknown }, result: string | null }\n /** Everything stored at a location of `cwd`'s extension storage, and the project root its `project`/`session` files live under. Additive. */\n 'extensions.storage.load': { params: { cwd: string } & WireStorageLocation, result: StorageSnapshot & { projectRoot?: string } }\n /**\n * Writes (or, `value` absent, deletes) one storage entry. The extensions\n * holding it see the change at once; every other connection gets\n * `extensions:storage`. A `stores` write must be a `{ v, value }` record of\n * the store's version whose value passes its schema (checked against every\n * runtime of the folder holding the store); otherwise it is refused and\n * nothing changes. The result says which, with the entry as the host holds\n * it now, for the client to reconcile. Additive (the result was `void`).\n */\n 'extensions.storage.set': { params: { cwd: string, area: StorageArea, key: string, value?: Json } & WireStorageLocation, result: WireStorageSetResult }\n /** The extensions' settings of `cwd` with values, locks and the layer each value comes from. `sessionId` adds that session's layer. Additive. */\n 'extensions.settings': { params: { cwd: string, sessionId?: string }, result: WireExtensionSettings }\n /**\n * Writes one extension setting at a scope: `user` in the settings file, `project`\n * in the project's `extension-settings.json`, `session` in memory; a\n * secret goes to the credentials file, never a settings file. Refused for\n * a locked, unknown or action key, a scope the setting doesn't allow, or a\n * value that fails its checks. Additive.\n */\n 'extensions.settings.set': { params: SettingsSetParams, result: void }\n /** The extension commands of `cwd` with their effective bindings, scopes and modes, and the keymap mode on top for `sessionId`. Additive. */\n 'extensions.commands': { params: { cwd: string, sessionId?: string }, result: WireExtensionCommands }\n /** Runs a command by its published id (an extension command or a built-in). `false` when nothing ran. Additive. */\n 'extensions.command.run': { params: CommandRunParams, result: boolean }\n /** Activates a keymap mode on the host for `cwd` (as `ctx.keymap.mode.push`) until `extensions.keymap.pop` or this connection closes. Returns its handle. Additive. */\n 'extensions.keymap.push': { params: { cwd: string, mode: string, priority?: number, sessionId?: string }, result: string }\n /** Pops a mode this connection pushed. Additive. */\n 'extensions.keymap.pop': { params: { handle: string }, result: boolean }\n /** Every command of `cwd` with its effective bindings, scope and mode (`ctx.keymap.list`), and the active mode stack for `sessionId` (`ctx.keymap.active`). Additive. */\n 'extensions.keymap.list': { params: { cwd: string, sessionId?: string }, result: WireKeymap }\n /** The extension integrations of `cwd` (`ctx.integrations.register`) and their connections. Additive. */\n 'extensions.integrations.list': { params: { cwd: string }, result: WireIntegration[] }\n /** Connects with an API key: verified by the extension, then kept in the credentials file. Additive. */\n 'extensions.integrations.connectKey': { params: { cwd: string, integrationId: string, key: string, methodId?: string }, result: WireIntegration }\n /**\n * Runs an OAuth or command method. Its steps (open this URL, enter this\n * code, paste the redirect) come to this connection as\n * `extensions:integration-flow` with the returned `flowId`; the call resolves\n * when the flow ends. Additive.\n */\n 'extensions.integrations.start': { params: { cwd: string, integrationId: string, methodId: string, flowId?: string }, result: WireIntegration }\n /** Answers a flow step that asked for input (`inputId`). `value` absent cancels the flow. Additive. */\n 'extensions.integrations.flowInput': { params: { flowId: string, inputId: string, value?: string }, result: boolean }\n /** Removes the connection of `account`, or every connection of the integration when it is absent. Additive. */\n 'extensions.integrations.disconnect': { params: { cwd: string, integrationId: string, account?: string }, result: void }\n /** Makes the connection of `account` the integration's default. Additive. */\n 'extensions.integrations.setDefault': { params: { cwd: string, integrationId: string, account: string }, result: void }\n /** Which catalog items of `cwd` extensions added, changed or removed, with the extension that did it (Settings shows it). Additive. */\n 'extensions.catalogs.provenance': { params: { cwd: string, kind: CatalogKind }, result: CatalogItemProvenance[] }\n\n /** Current presence snapshot — backfill for a freshly opened session list. */\n 'presence.list': { params: Record<string, never>, result: SessionPresence[] }\n /**\n * Tag the calling peer as watching a session (one per connection; the\n * TUI opens one connection per activated session). Sent as a\n * notification right after the handshake. Detach is implicit — the\n * daemon recomputes presence when the socket drops.\n */\n 'presence.watch': { params: { sessionId: string }, result: void }\n\n /**\n * Report an integration this client runs (a channel). Registering a name\n * again from the same connection replaces it; a name another live\n * connection registered is refused. It goes away when this connection\n * closes. Every window gets `integrations:changed`. Additive.\n */\n 'integrations.register': { params: { name: string, kind: string, state: IntegrationState, detail?: string }, result: void }\n /** Change the state of an integration this connection registered; `detail` replaces the previous one (absent clears it). Additive. */\n 'integrations.update': { params: { name: string, state: IntegrationState, detail?: string }, result: void }\n /** The integrations registered on this host, in registration order. Additive. */\n 'integrations.list': { params: Record<string, never>, result: IntegrationInfo[] }\n\n /** What this host can do: OS, tools on PATH, sandbox, environment kinds, what it allows. Cached a minute; `refresh` probes again. */\n 'host.capabilities': { params: { refresh?: boolean }, result: HostCapabilities }\n /** A zidane-server's self-update: its state, the setting, the newest release seen. */\n 'server.update.status': { params: Record<string, never>, result: ServerUpdateStatus }\n /** Turn the zidane-server's self-update on or off. */\n 'server.update.configure': { params: { enabled: boolean }, result: ServerUpdateStatus }\n /**\n * Check for a newer zidane-server release now. With auto-update on, a newer\n * one installs; off, it is downloaded and verified, and the state turns `ready`.\n */\n 'server.update.check': { params: Record<string, never>, result: ServerUpdateStatus }\n /** Install the release that is `ready` or `waiting` now, without waiting for background work to finish. */\n 'server.update.install': { params: Record<string, never>, result: ServerUpdateStatus }\n /**\n * A zidane-server's recent log records, oldest first: its own lines and\n * its extensions' (setup, runtime warnings), from a bounded in-memory\n * buffer. Other hosts refuse it. Additive.\n */\n 'logs.list': { params: Record<string, never>, result: { records: LogRecord[] } }\n /** Follow the log: this connection gets `logs:record` for each new record. Calls count; a dropped connection releases its own. Additive. */\n 'logs.watch': { params: Record<string, never>, result: void }\n /** Release one `logs.watch` of this connection. */\n 'logs.unwatch': { params: Record<string, never>, result: void }\n /**\n * Follow the host's own performance (Settings › Performance on a server):\n * this connection gets `perf:sample` every 2 s. The host samples only while\n * a connection watches. Calls count; a dropped connection releases its own.\n * Additive.\n */\n 'perf.watch': { params: Record<string, never>, result: void }\n /** Release one `perf.watch` of this connection. Additive. */\n 'perf.unwatch': { params: Record<string, never>, result: void }\n /** The samples the host holds (the last 5 minutes of watching), oldest first. Additive. */\n 'perf.history': { params: Record<string, never>, result: { samples: PerfSample[] } }\n /** The OS threads of one of the processes the host lists (its own tree), busiest first. Refuses any other pid. Additive. */\n 'perf.threads': { params: { pid: number }, result: { threads: PerfOsThread[] } }\n /**\n * Where this host lets a session's folder be: a server's workspace roots\n * (`confined`: `sessions.create` / `setFolder` refuse anything outside),\n * or the user's home on a local host (unconfined). Additive.\n */\n 'fs.roots': { params: Record<string, never>, result: FsRoots }\n /**\n * The folders in `path` (default: the first root), for a folder picker on\n * the host's machine. Only inside the roots (real paths: `..` and\n * symlinks out are refused), no dotfiles. Additive.\n */\n 'fs.listDirs': { params: { path?: string }, result: FsDirListing }\n /**\n * Creates folder `name` in `parent` (inside the roots, real paths: `..` and\n * symlinks out are refused). `name` is one path segment and does not start\n * with a dot. Refused when the host turns it off (a zidane-server's\n * `allowCreateFolders`, the hello's `createFolders`). Additive.\n */\n 'fs.mkdir': { params: { parent: string, name: string }, result: FsDirEntry }\n /**\n * The folders whose name holds `query` (case-insensitive), in `path` and\n * below it (default: every root). Bounded: four levels down, 200 results,\n * no dot folders, no `node_modules`, symlinks not followed. `truncated`:\n * the result or read bound cut the search short. Additive.\n */\n 'fs.searchDirs': { params: { query: string, path?: string }, result: FsDirSearch }\n\n /*\n * A folder's git checkout. `cwd` must be a folder inside the host's\n * workspace roots (`fs.roots`); git and `gh` run as the host's user.\n * Additive (no version bump).\n */\n /** Where the checkout stands (branch, upstream, ahead / behind, uncommitted changes); `null` outside a checkout. */\n 'git.status': { params: { cwd: string }, result: GitInfo | null }\n /** The local branches, most recently committed first, each against the default branch. */\n 'git.branches': { params: { cwd: string }, result: GitBranchRow[] }\n /**\n * Open pull requests (`gh`): waiting on you, yours, then recent others; `search` searches every open one.\n * `null` without `gh` (or signed out); `rateLimited` while GitHub refuses and nothing is cached.\n */\n 'git.pullRequests': { params: { cwd: string, search?: string, fresh?: boolean }, result: GitPrListResult }\n /** `branch`'s open (or draft) pull request, or `null`. `fresh`: past the cache. */\n 'git.branchPullRequest': { params: { cwd: string, branch: string, fresh?: boolean }, result: GitPr | null }\n /** One commit's facts, for a sha chip; `null` when the repository has no such commit. */\n 'git.commit': { params: { cwd: string, sha: string }, result: GitCommitInfo | null }\n /** Each changed path's status against HEAD, untracked files included. */\n 'git.fileStatus': { params: { cwd: string }, result: GitStatusEntry[] }\n /**\n * The working tree against HEAD as a unified patch (untracked files as new files), the whole checkout or one\n * `path`, with `context` lines (absent: 3; `null`: whole files).\n */\n 'git.diff': { params: { cwd: string, path?: string, context?: number | null }, result: string }\n /**\n * Switches the checkout to a branch or a pull request (`{ pr }`, through `gh`). Never forced; refused while an\n * agent runs in the checkout (`sessionId`: the asking session, counted too). A branch another worktree holds is\n * git's refusal plus that worktree and its sessions (`sessionId` left out).\n */\n 'git.checkout': { params: { cwd: string, target: GitSwitchTarget, sessionId?: string }, result: GitCheckoutResult }\n /** Starts branch `name` from the current checkout and switches to it; refused while an agent runs in it. */\n 'git.createBranch': { params: { cwd: string, name: string, sessionId?: string }, result: GitCheckoutResult }\n /** Pulls (merging) then pushes the current branch, or publishes it without an upstream; refused while an agent runs in it. */\n 'git.sync': { params: { cwd: string, sessionId?: string }, result: GitSyncResult }\n /**\n * Clones `input` (a git or forge URL, or `owner/repo`) into a new folder of `parent` (inside the roots). A folder\n * already holding that repository is answered as `existed`. One clone per connection; git's progress comes as\n * `git:clone:progress` signals to the caller only. A dropped connection cancels it. Refused when the host turns\n * cloning off (a zidane-server's `allowClone`, the hello's `clone`).\n */\n 'git.clone': { params: { input: string, parent: string }, result: RepoCloneResult }\n /** Cancels this connection's clone: the half-cloned folder is removed and `git.clone` answers `cancelled`. */\n 'git.cloneCancel': { params: Record<string, never>, result: void }\n /**\n * Follows `cwd`'s checkout: once its refs move (a commit, a fetch, a push, a\n * branch switch, from this host or any other process), this connection\n * gets `git:refs` for `cwd`. `false`: not a repository, nothing watched.\n * Calls count: each `git.watch` takes one `git.unwatch`; a dropped\n * connection releases its own. Additive.\n */\n 'git.watch': { params: { cwd: string }, result: boolean }\n /** Releases one `git.watch` of `cwd` by this connection. */\n 'git.unwatch': { params: { cwd: string }, result: void }\n\n /*\n * A folder's files beyond what a session's workspace reads: `cwd` must be a folder inside the host's workspace\n * roots. Additive (no version bump).\n */\n /**\n * Lines containing `query` (fixed string, at most 500 characters) under `cwd`: ripgrep, else `git grep`, else a\n * walk. A later search with the same `searchId` on the connection cancels this one.\n */\n 'files.search': { params: { cwd: string, query: string, caseSensitive?: boolean, searchId?: string }, result: ContentSearchResult }\n /** What names in prose point at (files, folders, else branches), in order: what a transcript's path chips open. */\n 'files.resolvePaths': { params: { cwd: string, texts: string[] }, result: ResolvedPath[] }\n /** The files under `cwd` and the folders holding them, as `@` completes them: git's list (ignore rules kept), else a walk; capped. */\n 'files.list': { params: { cwd: string }, result: FileEntry[] }\n /** Where `cwd` sits: its git checkout (the folder itself outside git) and its project (the main checkout for a worktree). */\n 'files.location': { params: { cwd: string }, result: FolderLocation }\n /**\n * Runs the project's own linters and typecheckers on `paths` (relative to `cwd`), cached until the files move.\n * `disabled`: tool ids switched off; `timeoutMs`: per tool.\n */\n 'files.diagnostics': { params: { cwd: string, paths: string[], disabled?: string[], timeoutMs?: number }, result: DiagnosticsResult }\n /** Drops the cached diagnostics of `cwd`: the next run checks again. */\n 'files.diagnosticsInvalidate': { params: { cwd: string }, result: void }\n /** The diagnostics tools and whether each runs for `cwd` (configured, missing its binary, not used). */\n 'files.diagnosticsTools': { params: { cwd: string }, result: DiagnosticsToolInfo[] }\n /**\n * Lets this connection's media play from `GET /zidane/media`\n * (`SERVER_MEDIA_PATH`): `?ticket&cwd&path` serves a file of a folder in\n * the workspace roots, `&side=old|new` one side of its git change, with\n * byte ranges, for an image, a video or audio only. The client picks the\n * ticket (at least 32 random URL-safe characters) so an address is known\n * before the call lands; it is good while this connection is open and\n * carries its token's scope. One per connection: a new one replaces it.\n * Only a zidane-server serves media. Additive.\n */\n 'files.mediaTicket': { params: { ticket: string }, result: void }\n\n /**\n * The host's provider credentials, as the host's agents use them (its\n * data dir's `credentials.json` and environment): per provider, whether\n * something is configured, its stored API key / OAuth accounts (labels,\n * which is active) and an env var it reads. Never a secret. Additive.\n */\n 'auth.status': { params: Record<string, never>, result: { providers: HostProviderAuth[] } }\n /**\n * Store an API key for one of the host's providers as its active\n * credential, apply it to the host's environment, and rebuild agents\n * (idle now, busy ones at run end). Returns the provider's new status.\n * OAuth sign-in goes through `auth.oauth.*`. Additive.\n */\n 'auth.setApiKey': { params: { provider: string, key: string }, result: HostProviderAuth }\n /**\n * Remove one stored credential (`account`: its key from `auth.status`) or,\n * without one, every stored credential of the provider; then as\n * `auth.setApiKey`. A key the host only has from its own environment is\n * left alone. Additive.\n */\n 'auth.remove': { params: { provider: string, account?: string }, result: { removed: boolean, provider: HostProviderAuth } }\n /**\n * Stores a provider's API key and its custom fields (a local server's URL,\n * a cloud's region; `onboarding.providers` lists them), merged into the\n * stored credential: a field left out keeps its value, an empty one is\n * removed (a blank secret keeps the stored one), a required one may not be\n * emptied, no `value` keeps the stored key. Additive.\n */\n 'auth.configure': { params: { provider: string, value?: string, customFields?: Record<string, string> }, result: HostProviderAuth }\n /**\n * Make one of a provider's stored credentials the active one (`target`: an\n * account key from `auth.status`, or the first stored one of a source),\n * then as `auth.setApiKey`. A credential no longer stored is refused.\n * Additive.\n */\n 'auth.setPreferred': { params: { provider: string, target: 'apikey' | 'oauth' | { key: string } }, result: HostProviderAuth }\n /** Rename a stored OAuth account (`account`: its key from `auth.status`). Presentation only: nothing is rebuilt. Additive. */\n 'auth.rename': { params: { provider: string, account: string, label: string }, result: HostProviderAuth }\n /**\n * OAuth sign-in with the browser on the CLIENT and the tokens on the host:\n * the host starts a provider's login (`provider`) or an MCP server's\n * (`mcpServer`, found in `cwd`'s catalog, as `catalog.mcps`), keeping the\n * PKCE verifier and `state`, and answers with the authorization URL.\n * `mode: 'loopback'`: the client listens at `redirectUri` (a provider's\n * fixed port; for an MCP server the loopback URI the client passed) and\n * forwards the code; `'browser'`: the client opens `url` (pasting a code if\n * the page shows one); `'device'`: shows `userCode`. The flow belongs to\n * this connection, is single-use and expires (`expiresAt`). Additive.\n *\n * A client that can't listen (a browser) signs in to an MCP server through\n * a zidane-server's own redirect: `redirectUri` is the server's\n * `/zidane/oauth/callback` (`SERVER_OAUTH_CALLBACK_PATH`) at the origin\n * the client reaches it by. The server takes the code there and the flow\n * is `'browser'` (the client opens `url`, then `complete`s without a\n * code). A server whose pre-registered client pins its redirect stays\n * `'loopback'`: its page fails to load and the user pastes that page's\n * address (`complete` with `input`).\n */\n 'auth.oauth.begin': { params: { provider?: string, mcpServer?: string, cwd?: string, kind?: string, redirectUri?: string }, result: HostOAuthBegin }\n /**\n * Deliver the code (`code` + `state` from the loopback, or `input`: what\n * the user pasted) once, then wait for the host's token exchange; without\n * either, just wait (device and polling flows). A wrong `state` or another\n * connection's flow is refused. Tokens stay on the host: the result says\n * what changed, never a secret.\n */\n 'auth.oauth.complete': { params: { flowId: string, code?: string, state?: string, input?: string }, result: HostOAuthComplete }\n /**\n * Answer the step a flow is waiting on (`HostOAuthBegin.step` before its\n * URL, `HostOAuthComplete.step` after): a select's option id (none:\n * cancel), a prompt's text. Answers with where the flow is now: its URL, or\n * the next step. Then `complete` as before. Additive.\n */\n 'auth.oauth.respond': { params: { flowId: string, stepId: string, value?: string }, result: HostOAuthBegin }\n /** Abandon a flow of this connection. */\n 'auth.oauth.cancel': { params: { flowId: string }, result: { cancelled: boolean } }\n\n /**\n * What the host discovered for the settings tabs, each entry with whether\n * the host's settings enable it (an unset allowlist enables everything).\n * `cwd` adds the project scope of that folder (inside the workspace roots\n * on a server); without it, the user scope (the host user's home). The\n * enabled lists are written with `settings.set`. Installing, removing and\n * MCP sign-in stay on the host's machine. Additive.\n */\n 'catalog.skills': { params: { cwd?: string, kind?: string }, result: { skills: HostCatalogSkill[] } }\n /** MCP servers: `env` and `headers` values, URL credentials and query values are redacted. */\n 'catalog.mcps': { params: { cwd?: string, kind?: string }, result: { servers: HostCatalogMcp[], errors: HostCatalogError[] } }\n /** Extensions installed for `cwd`. */\n 'catalog.extensions': { params: { cwd?: string, kind?: string }, result: { extensions: HostCatalogExtension[] } }\n /** Plugins installed for `cwd`, with what each contributes. */\n 'catalog.plugins': { params: { cwd?: string, kind?: string }, result: { plugins: HostCatalogPlugin[] } }\n /**\n * Install a skill or an extension on the host, in its user's scope only\n * (`scope` may only be `'user'`): a GitHub (`owner/repo[#ref][:dir]`, a\n * GitHub URL, a skills.sh URL) or npm spec; paths are refused. `skills` /\n * `all` pick from a multi-skill source (the `multiple-candidates` error\n * lists them), `extension` from a multi-extension one (an extension's\n * `multiple-candidates` or `no-extension` error carries the names found as\n * {@link ExtensionInstallErrorData}). Runs the host's\n * package managers and fetches code there: a zidane-server's\n * `allowRemoteInstalls` gates it, every attempt is audited. Bounded in\n * time; the progress lines come back with the result. Every window gets\n * `catalog:changed`. Additive (`remoteInstalls` on `ipc.hello`).\n */\n 'catalog.install': { params: { kind: HostInstallKind, spec: string, scope?: 'user', skills?: string[], all?: boolean, extension?: string, overwrite?: boolean }, result: { installed: string[], message: string, progress: string[] } }\n /** Remove a user-scope skill or extension of the host by name (its directory). As `catalog.install`. */\n 'catalog.remove': { params: { kind: HostInstallKind, name: string }, result: { removed: string, message: string } }\n /** Update a user-scope extension installed from a source. As `catalog.install`. */\n 'catalog.update': { params: { kind: HostInstallKind, name: string }, result: { updated: string, upToDate: boolean, message: string } }\n /** The skills of a source (`owner/repo[#ref][:dir]`, a GitHub or skills.sh URL), fetched by the host with its GitHub login; `catalog.install` with `skills` installs picked ones. Additive. */\n 'skills.browse': { params: { source: string }, result: SkillSourceListing }\n /**\n * The extensions of a source (`owner/repo[#ref][:dir]`, a GitHub URL, an\n * npm package, or a folder on the host), read from their manifests by the\n * host with its GitHub login; nothing runs. Never fails for an unreadable\n * source: the listing carries `error` (the default source `Tahul/zidane`\n * then lists the native catalog, `builtin: true`). Each row's `install`\n * is what `catalog.install` takes (`spec`, `extension`). Additive.\n */\n 'extensions.browse': { params: { source: string }, result: ExtensionSourceListing }\n /**\n * Install an installed extension again from another source (GitHub or\n * npm): the source must hold an extension of the same `name` (else the\n * `name-mismatch` install error, its `data` an\n * {@link ExtensionInstallErrorData} with the names found); the folder is\n * replaced only once the new copy validated, and `.install.json`\n * records the new source, which `catalog.update` then follows. A\n * zidane-server takes `scope: 'user'` only, gated and audited as\n * `catalog.install`. Additive.\n */\n 'extensions.changeOrigin': { params: { name: string, scope: 'user' | 'project', source: string }, result: { name: string, origin: ExtensionInstallOrigin, message: string, progress: string[] } }\n /**\n * What the setup wizard finds on the host's machine for `cwd` (default:\n * the host user's home): the providers and their credentials, other agents\n * to import from, local model servers and the install signals. Additive.\n */\n 'onboarding.detect': { params: { cwd?: string }, result: OnboardingDetection }\n /** The providers as the wizard's Connect step lists them, with their custom fields and the model each runs when none is picked. Additive. */\n 'onboarding.providers': { params: { cwd?: string }, result: HostOnboardingProvider[] }\n /**\n * The setup wizard's write: `settings.set` sets (`settings.reset` back to\n * their defaults, unless also set), as `settings.set` applies them, and\n * `records` (the run finished, its steps) merged into the host's stored\n * ones. Returns the settings in effect. Additive.\n */\n 'onboarding.complete': { params: { settings: OnboardingSettingsChange, records: OnboardingState }, result: HostSettings }\n /** What `~/.claude` on the host holds: whether there is a setup, and its transcripts for `cwd` and in every project. Additive. */\n 'claudeImport.detect': { params: { cwd?: string }, result: ClaudeImportDetection }\n /** What each piece of the Claude Code import would copy and skip. Additive. */\n 'claudeImport.preview': { params: { cwd?: string }, result: OnboardingImportPreview }\n /**\n * Imports a Claude Code setup into the host's own places: conversations\n * into its session store, MCP servers, skills, commands and subagents into\n * the host user's files. Idempotent (what is there is skipped, never\n * overwritten). It copies commands the host will run: a zidane-server's\n * `allowRemoteInstalls` gates it, every attempt is audited. Every window\n * gets `catalog:changed`. Additive.\n */\n 'claudeImport.run': { params: { cwd?: string } & ClaudeImportSelection, result: ClaudeImportSummary }\n /**\n * Add or replace an MCP server in the host user's `mcps.json`, or with\n * `scope: 'project'` in `cwd`'s project (a folder inside the workspace\n * roots on a server). Its `env` / `headers` values are stored there and\n * never come back (`catalog.mcps` redacts them, the reply names the server\n * only). `clientSecret`, the secret of its `oauth` client, goes to the\n * host's MCP credential store, never to `mcps.json`; an entry without an\n * `oauth` client drops a stored one. As `catalog.install`.\n */\n 'mcp.upsert': { params: { config: McpServerConfig, scope?: 'user' | 'project', cwd?: string, clientSecret?: string }, result: { name: string, created: boolean } }\n /** Remove an MCP server from the host user's `mcps.json`; `removed: false` when it has none. As `catalog.install`. */\n 'mcp.remove': { params: { name: string }, result: { removed: boolean } }\n /**\n * Connect to one of `cwd`'s MCP servers (as `catalog.mcps`), list its\n * tools into the host's tools cache and record how it went: the server's\n * new `status`. Every window gets `catalog:changed`. Additive.\n */\n 'mcp.test': { params: { name: string, cwd?: string, kind?: string }, result: McpServerStatus }\n /** Forget an MCP server's sign-in on the host (its tokens). Every window gets `catalog:changed`. Additive. */\n 'mcp.signOut': { params: { name: string }, result: void }\n /**\n * The host's shared MCP server processes (`src/mcp/server-pool.ts`),\n * `cwd`'s only when given: name, folder, shared or per session, how many\n * sessions hold it, its pid, whether it is retired. Remote servers and\n * `scope: 'context'` ones are never listed (they are per session). Additive.\n */\n 'mcp.instances': { params: { cwd?: string }, result: McpServerInstance[] }\n /**\n * End `name`'s process now (in `cwd` only, when given) for every session\n * holding it. Calls in flight fail with \"<name> restarted\" and are not\n * retried; the next call starts a fresh process. Answers how many\n * processes were restarted (0: none was running). Additive.\n */\n 'mcp.restart': { params: { name: string, cwd?: string }, result: { restarted: number } }\n /**\n * The host's credentialed providers (what its agents can run) and their\n * models, for a model picker of a session on that host. `cwd` adds the\n * providers its extensions contribute there. Additive.\n */\n 'models.list': { params: { cwd?: string, kind?: string }, result: { providers: HostModelProvider[] } }\n /**\n * Send one tiny decision with this host's credentials, to check a decision\n * model works. `model` is `\"providerKey/modelId\"`, tested exactly; omitted =\n * the host's `Settings.decisionModel` (or the first available). Never\n * fails: a broken model comes back as `ok: false` with a reason. Additive.\n */\n 'decisions.test': { params: { cwd?: string, kind?: string, model?: string }, result: HostDecisionTestResult }\n /**\n * Send one tiny prompt with this host's credentials, to check a chat model\n * answers. `model` is `\"providerKey[@account]/modelId\"`, tested exactly.\n * Never fails: a broken model comes back as `ok: false` with a reason.\n * Additive.\n */\n 'models.test': { params: { cwd?: string, kind?: string, model: string }, result: HostModelTestResult }\n\n /**\n * The machines this host knows (`docs/MACHINES.md`), online or not, and\n * forgetting one (it disconnects; its `local@` / `worktree@` kinds stop\n * resolving). Additive.\n */\n 'machines.list': { params: Record<string, never>, result: MachineInfo[] }\n /** Forgets a machine. It disconnects and its kinds stop resolving. */\n 'machines.forget': { params: { machineId: string }, result: { forgotten: boolean } }\n /**\n * Folders of a machine, for a client's folder picker: the host proxies a\n * listing to the machine (`fs.list`, confined to its roots there): the\n * folders in `path` (absent: its first root), and every root. Additive.\n */\n 'machines.listDirs': { params: { machineId: string, path?: string }, result: { path: string, dirs: string[], roots: string[] } }\n /**\n * A local host's machine links (`docs/MACHINES.md` § Client UI), behind\n * remote hosts: share this computer with a saved server (the machine agent\n * runs in this host's process, with the machine token `token` or the one\n * already stored for that server), stop sharing, use a saved server as a\n * machine (reverse direction), and read their state. Refused while remote\n * hosts are off. Additive.\n */\n 'machines.share.start': { params: { hostId: string, name: string, roots: string[], token?: string }, result: MachineLinksStatus }\n /** Stops sharing this computer with a server. */\n 'machines.share.stop': { params: { hostId: string }, result: MachineLinksStatus }\n /** Turns on or off using a server as this computer's linked server. */\n 'machines.useServer': { params: { hostId: string, enabled: boolean }, result: MachineLinksStatus }\n /** State of this host's machine links: the shares it offers and the servers it uses. */\n 'machines.links.status': { params: Record<string, never>, result: MachineLinksStatus }\n /**\n * Reverse direction (`docs/MACHINES.md` § Reverse direction): a client asks\n * this server to lend itself as a machine over this very connection\n * (`allowAsMachine` on, else refused). `hostId` names the asking host, so\n * a reconnect finds its tasks and terminals again. Then `machine.call`\n * carries each host→machine request (`MachineMethods`), answered by the\n * server's confined executor; machine notifications come back as\n * `machine:notification` signals on this connection only.\n */\n 'machine.attach': { params: { hostId: string }, result: MachineRegisterParams }\n /** Runs one machine-protocol method on this server's executor and resolves with its JSON result. Refused when the server does not lend itself as a machine. */\n 'machine.call': { params: { method: string, params?: JsonValue }, result: JsonValue }\n /** Ends this connection's machine attachment. `detached` is `false` when it had none. */\n 'machine.detach': { params: Record<string, never>, result: { detached: boolean } }\n /**\n * Mint a `machine`-scoped token on this server (a zidane-server only), so\n * a window can share its computer in one step. An admin token may\n * (`./scopes`). Audited.\n */\n 'tokens.createMachineToken': { params: { name: string }, result: { id: string, name: string, token: string } }\n /** This server's tokens, revoked ones included, never their secrets (a zidane-server only). Additive. */\n 'tokens.list': { params: Record<string, never>, result: ServerTokenInfo[] }\n /**\n * Create a token with a scope (`./scopes`; `machine` lends a computer). The secret is in the\n * result only: show it once. Bound to the calling token (`createdBy`), so revoking that one\n * revokes this one too. Audited. Additive.\n */\n 'tokens.create': { params: { name: string, scope: ServerTokenScope }, result: ServerTokenInfo & { token: string } }\n /**\n * Revoke a live token by id, with the live tokens it minted; their connections drop and the\n * runs and terminals they started stop. Audited. Additive.\n */\n 'tokens.revoke': { params: { id: string }, result: { revoked: ServerTokenInfo[] } }\n /**\n * Revoke the token this connection authenticated with, and the live tokens it minted (a\n * browser's sign out). Any client scope may: it only gives up its own access. Audited. Additive.\n */\n 'tokens.revokeSelf': { params: Record<string, never>, result: { revoked: ServerTokenInfo[] } }\n /**\n * Issue a one-time pairing code (`XXXX-XXXX`, a zidane-server only): a browser posts it to\n * `POST /zidane/pair` and gets a token of `scope`, named `browser: <name>` and bound to the\n * calling token (`createdBy`). `ttlMs`: 30000 to 3600000, default 600000. Single use; five\n * wrong secrets burn it. Audited. Additive.\n */\n 'tokens.pair': { params: { scope: ClientScope, ttlMs?: number, name?: string }, result: { code: string, expiresAt: number } }\n /**\n * Issue a one-time machine join code (a zidane-server only): a machine posts it to\n * `POST /zidane/pair` and gets a machine token named `name`. A public server caps\n * `ttlMs` at 10 minutes. Audited as `pair.create` with scope `machine`. Additive.\n */\n 'tokens.machineInvite': { params: { name?: string, ttlMs?: number }, result: { code: string, expiresAt: number } }\n\n /**\n * Settings sync, a client's computer → this server (`docs/SERVER.md`\n * § Settings sync). A zidane-server only; other hosts refuse. One source\n * device per server: `sync.claim` makes the caller it (or says who is,\n * unless `takeover`), `sync.push` applies one category's snapshot through\n * the host's own setters, skipping fields edited here since (overrides),\n * `sync.reset` drops an override, `sync.release` stops the source. Every\n * call is audited with its token. Additive.\n */\n 'sync.status': { params: Record<string, never>, result: SyncStatus }\n /** Makes the caller the settings source device. When another device is the source, the result says which, unless `takeover` is set. `categories` and `keys` narrow what it syncs. */\n 'sync.claim': { params: { deviceId: string, deviceName: string, takeover?: boolean, categories?: SyncCategory[], keys?: string[] }, result: SyncClaimResult }\n /** Applies one category's snapshot from the source device. */\n 'sync.push': { params: { deviceId: string, category: SyncCategory, payload: SyncPayload }, result: SyncPushResult }\n /** Drops the local override of one field so sync applies to it again. */\n 'sync.reset': { params: { field: string }, result: { reset: boolean } }\n /** Stops the source device's sync. */\n 'sync.release': { params: { deviceId: string }, result: { released: boolean } }\n\n /** Daemon identity and version: `protocolVersion`, `appVersion`, `pid`, `startedAt` and the host identity fields of the `hello` result. */\n 'daemon.info': { params: Record<string, never>, result: HelloResult }\n /**\n * The processes the daemon started for its own work (MCP servers, bounded\n * tool runs such as git and linters), which lead their own process group\n * like a session's command does. The desktop app's performance monitor\n * counts them as the app's. Additive: an older daemon answers \"method not\n * found\", read as none.\n */\n 'daemon.ownedProcesses': { params: Record<string, never>, result: OwnedProcess[] }\n /**\n * The processes the daemon started for a session (its shell tool's\n * commands and background tasks, its terminals, its own MCP servers), by\n * session id. The desktop app's performance monitor shows what each session\n * uses. Additive: an older daemon answers \"method not found\", read as none.\n */\n 'daemon.sessionProcesses': { params: Record<string, never>, result: SessionProcess[] }\n /**\n * Graceful drain: deny pending approvals, abort live runs, close the\n * socket. Used by clients that detect a protocol-version mismatch and\n * need the stale daemon gone before respawning.\n *\n * `whenIdle` (version-skew retirement): a daemon with active work does\n * NOT abort it. It answers `{ deferred: true }` and exits once idle.\n * Explicit stops (`zidane daemon stop`) omit it and drain immediately.\n * Daemons predating the flag ignore it and drain immediately.\n */\n 'daemon.shutdown': { params: { whenIdle?: boolean }, result: { deferred?: boolean } | void }\n}\n\n/**\n * The host's identity from a hello (or `daemon.info`) reply; `null` from a host that predates it.\n * @param hello - The `hello` or `daemon.info` result.\n * @returns The host reference, or `null` when the reply carries no host id or kind.\n */\nexport function hostRefOf(hello: HelloResult): HostRef | null {\n if (typeof hello.hostId !== 'string' || !hello.hostKind)\n return null\n return { id: hello.hostId, kind: hello.hostKind, name: hello.hostName ?? hello.hostId }\n}\n\n/** Name of any method in {@link IpcMethods}. */\nexport type IpcMethodName = keyof IpcMethods\n/** Params type of the method `M` in {@link IpcMethods}. */\nexport type IpcParams<M extends IpcMethodName> = IpcMethods[M]['params']\n/** Result type of the method `M` in {@link IpcMethods}. */\nexport type IpcResult<M extends IpcMethodName> = IpcMethods[M]['result']\n\n/** Turns per `sessions.loadEvents` page when only `before` is given. */\nexport const LOAD_EVENTS_PAGE_TURNS = 200\n/** Largest `limit` a host honors. */\nexport const LOAD_EVENTS_MAX_PAGE_TURNS = 1000\n\n/** Paging options of `sessions.loadEvents`. */\nexport interface LoadEventsPaging {\n /** Turn position (exclusive) the page ends at: a previous page's `cursor`. */\n before?: number\n /** Turns in the page. */\n limit?: number\n /**\n * The page ends right before the turn with this id (same alignment as\n * `before` at its position); wins over `before`. A turn the stored\n * transcript doesn't hold fails the request (invalid params, the message\n * names `beforeTurnId`). An older host ignores it: see\n * {@link SessionEventsPage.beforeTurnId}.\n */\n beforeTurnId?: string\n}\n\n/** One page of a session's stream events, as `sessions.loadEvents` answers it. */\nexport interface SessionEventsPage {\n /** Stream events of the page. */\n events: StreamEvent[]\n /** Pass as `before` for the page before this one; absent once the first turn is in. */\n cursor?: number\n /**\n * The events are this page's slice of the whole replay, so pages\n * concatenate to exactly one whole `loadEvents`. Absent from an older\n * host, whose pages replay on their own ({@link loadAllEvents} restores\n * the exchange separator at their joins).\n */\n exact?: true\n /**\n * With `exact`: how many events of the whole replay come before this\n * page. Lets a client open on the tail of a long transcript and still\n * say how much it left out ({@link loadEventsTail}). Absent from an\n * older host.\n */\n start?: number\n /**\n * The request's `beforeTurnId`, echoed: absent when the host ignored\n * the anchor (an older host, which then paged by `before` / from the end).\n */\n beforeTurnId?: string\n}\n\n/**\n * One page of `sessions.loadEvents` (see its paging). An older host answers\n * the whole transcript: it comes back as one page with no cursor.\n * @param request - Sends `sessions.loadEvents` to the host.\n * @param params - Session id and paging.\n * @returns The page, normalized from either host reply shape.\n */\nexport async function loadEventsPage(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n params: { sessionId: string } & LoadEventsPaging,\n): Promise<SessionEventsPage> {\n const result = await request('sessions.loadEvents', params) as StreamEvent[] | SessionEventsPage\n return Array.isArray(result) ? { events: result } : result\n}\n\nfunction isResponseTooLarge(err: unknown): boolean {\n return typeof err === 'object' && err !== null && (err as { code?: unknown }).code === IpcErrorCode.ResponseTooLarge\n}\n\n/**\n * A session's whole transcript, loaded a page at a time from the end so no\n * single reply carries it all (a long session with images can outgrow a\n * transport's message size). A page refused as too large is asked again at\n * half the turns, down to one; a single turn that still doesn't fit fails\n * the load. An older host answers the whole transcript to the first call.\n * @param request - Sends `sessions.loadEvents` to the host.\n * @param sessionId - Session to load.\n * @param options - Paging options.\n * @param options.pageTurns - Turns per page to start with.\n * @returns Every stream event of the session.\n */\nexport async function loadAllEvents(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n sessionId: string,\n options: { pageTurns?: number } = {},\n): Promise<StreamEvent[]> {\n return (await loadEventsFromEnd(request, sessionId, options.pageTurns ?? LOAD_EVENTS_PAGE_TURNS)).events\n}\n\n/**\n * The end of a session's transcript: pages from the end until `enough`\n * holds for what was loaded (or the first turn is in), and how many events\n * of the whole replay come before it (`earlier`). Only exact pages can stop\n * early, since only they say where they start: an older host's transcript\n * loads whole, with `earlier` 0.\n */\nexport async function loadEventsTail(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n sessionId: string,\n enough: (events: readonly StreamEvent[]) => boolean,\n options: { pageTurns?: number } = {},\n): Promise<{ events: StreamEvent[], earlier: number }> {\n return loadEventsFromEnd(request, sessionId, options.pageTurns ?? LOAD_EVENTS_PAGE_TURNS, enough)\n}\n\nasync function loadEventsFromEnd(\n request: (method: 'sessions.loadEvents', params: { sessionId: string }) => Promise<StreamEvent[]>,\n sessionId: string,\n pageTurns: number,\n enough?: (events: readonly StreamEvent[]) => boolean,\n): Promise<{ events: StreamEvent[], earlier: number }> {\n let limit = pageTurns\n const pages: StreamEvent[][] = []\n let newerExact = false\n let allExact = true\n let before: number | undefined\n for (;;) {\n let page: SessionEventsPage\n try {\n page = await loadEventsPage(request, { sessionId, limit, ...(before !== undefined ? { before } : {}) })\n }\n catch (err) {\n if (isResponseTooLarge(err) && limit > 1) {\n limit = Math.max(1, Math.floor(limit / 2))\n continue\n }\n throw err\n }\n /*\n * An exact page is a slice of the whole replay: nothing to restore. An\n * older host's pages replay on their own, so the exchange separator a\n * whole replay puts before a prompt that follows an exchange is missing\n * where the newer page starts (its pages start at a prompt when they\n * can): put it back.\n */\n const newer = pages[0]\n if (newer && !newerExact && newer[0]?.kind === 'user-prompt' && page.events.length > 0)\n newer.unshift({ kind: 'separator', text: '' })\n newerExact = page.exact === true\n allExact &&= newerExact && page.start !== undefined\n pages.unshift(page.events)\n // Done at the first turn; a cursor that doesn't move back would loop.\n if (page.cursor === undefined || page.cursor <= 0 || (before !== undefined && page.cursor >= before))\n break\n if (enough && allExact) {\n const events = pages.flat()\n if (enough(events))\n return { events, earlier: page.start! }\n }\n before = page.cursor\n }\n return { events: pages.flat(), earlier: 0 }\n}\n\n/** Turns per `sessions.getTurns` page by default. */\nexport const SESSION_TURNS_PAGE = 200\n/** Largest `limit` a host honors for `sessions.getTurns`. */\nexport const SESSION_TURNS_MAX_PAGE = 1000\n\ntype SessionDocumentRequest = <M extends 'sessions.get' | 'sessions.getTurns'>(method: M, params: IpcParams<M>) => Promise<IpcResult<M>>\n\n/**\n * What `sessions.get` answers: the document; with `turns: false`, the\n * version of the snapshot it was cut from, the one `sessions.getTurns`\n * pages carry.\n */\nexport type SessionDocumentHead = SessionData & { version?: string }\n\n/** How many times a paged read starts over because the session changed under it, before it asks for the whole document in one reply. */\nconst SESSION_DOCUMENT_RESTARTS = 3\n\n/**\n * A session's whole document, read a page of turns at a time so no reply\n * carries it all (`sessions.getTurns` pages, then the `sessions.get`\n * `turns: false` head; a page refused as too large is asked again at half\n * the turns). Every page and the head name the snapshot they come from: a\n * version change mid-read (a turn appended, a compaction) starts the read\n * over, so the result is one version, never pages of two. After\n * {@link SESSION_DOCUMENT_RESTARTS} restarts (a session busier than the\n * read), the whole document comes in one reply. A host that predates\n * `sessions.getTurns` sends it that way too; one that names no version is\n * read as before. `null` when the host doesn't know the session.\n * @param request - Sends `sessions.get` and `sessions.getTurns` to the host.\n * @param sessionId - Session to read.\n * @param options - Paging options.\n * @param options.pageTurns - Turns per page to start with.\n * @returns The session document, or `null` when unknown.\n */\nexport async function loadSessionDocument(\n request: SessionDocumentRequest,\n sessionId: string,\n options: { pageTurns?: number } = {},\n): Promise<SessionData | null> {\n const paging = { limit: options.pageTurns ?? SESSION_TURNS_PAGE }\n for (let attempt = 0; attempt <= SESSION_DOCUMENT_RESTARTS; attempt++) {\n const read = await readSessionDocumentOnce(request, sessionId, paging)\n if (read !== 'changed')\n return read\n }\n return withoutVersion(await request('sessions.get', { sessionId }))\n}\n\nfunction withoutVersion(head: SessionDocumentHead | null): SessionData | null {\n if (!head)\n return null\n const { version: _version, ...data } = head\n return data\n}\n\n/** One paged read; `'changed'`: the version moved between two of its replies. */\nasync function readSessionDocumentOnce(request: SessionDocumentRequest, sessionId: string, paging: { limit: number }): Promise<SessionData | null | 'changed'> {\n const turns: SessionTurn[] = []\n let total = Infinity\n let version: { of?: string } | null = null\n while (turns.length < total) {\n let page: IpcResult<'sessions.getTurns'>\n try {\n page = await request('sessions.getTurns', { sessionId, from: turns.length, limit: paging.limit })\n }\n catch (err) {\n if (turns.length === 0 && isMethodNotFound(err))\n return withoutVersion(await request('sessions.get', { sessionId }))\n if (isResponseTooLarge(err) && paging.limit > 1) {\n paging.limit = Math.max(1, Math.floor(paging.limit / 2))\n continue\n }\n throw err\n }\n if (!page)\n return null\n if (version === null)\n version = { ...(page.version !== undefined ? { of: page.version } : {}) }\n else if (page.version !== version.of)\n return 'changed'\n total = page.total\n // A session that shrank meanwhile on a host that names no version ends the read where it is.\n if (page.turns.length === 0)\n break\n turns.push(...page.turns)\n }\n const head = await request('sessions.get', { sessionId, turns: false })\n if (!head)\n return null\n if (version !== null && head.version !== version.of)\n return 'changed'\n return { ...withoutVersion(head)!, turns }\n}\n\n/** A catalog entry's on/off state as the host's settings decide it. */\ninterface HostCatalogToggle {\n name: string\n /** The host's settings enable it (always `false` for an entry that cannot load). */\n enabled: boolean\n /**\n * Its own allowlist governs it (`enabledSkills`, …). `false`: contributed\n * by a plugin or extension (their toggle governs it), or broken.\n */\n toggleable: boolean\n}\n\n/** A skill in the host's catalog. */\nexport interface HostCatalogSkill extends HostCatalogToggle {\n /** What the skill is for. */\n description: string\n /** Where the skill was found. */\n source?: 'project' | 'user' | 'inline' | 'builtin'\n /** `SKILL.md` on the host's machine. */\n location?: string\n /** `disk`: a scan path; else the plugin or extension that contributes it (`contributedBy`). */\n origin: 'disk' | 'plugin' | 'extension'\n /** Name of the plugin or extension that contributes the skill, when `origin` is not `disk`. */\n contributedBy?: string\n}\n\n/** Every secret-bearing value of a catalog entry is replaced by this. */\nexport const REDACTED = '<redacted>'\n\n/** An MCP server in the host's catalog. Secret values are redacted. */\nexport interface HostCatalogMcp extends HostCatalogToggle {\n /** How the server is reached. */\n transport: 'stdio' | 'sse' | 'streamable-http'\n /** Whether the config is the project's or the user's. */\n source: 'project' | 'user'\n /** The config file on the host's machine. */\n path: string\n /** Command that starts a `stdio` server. */\n command?: string\n /** Arguments of the command. */\n args?: string[]\n /** Credentials and query values redacted. */\n url?: string\n /** Working directory of the command. */\n cwd?: string\n /** `context` runs the server in the agent's execution context. `host` runs it on the host. Always sent for a `stdio` server (absent from an older host). */\n scope?: 'host' | 'context'\n /** Its config's `shared` (absent: `true`): one process for every session. The host's `mcpSharing` setting wins over it. */\n shared?: boolean\n /** `oauth` when the server signs in with OAuth. */\n auth?: 'oauth'\n /** Names only: every value is {@link REDACTED}. */\n env?: Record<string, string>\n /** Header names. Every value is {@link REDACTED}. */\n headers?: Record<string, string>\n /** Its sign-in state, tools as last listed and last Test (`mcp.test`) on the host. Absent from an older host. */\n status?: McpServerStatus\n}\n\n/** A config file that failed to parse (or an informational skip). */\nexport interface HostCatalogError {\n /** Path of the config file. */\n path: string\n /** Whether the file is the project's or the user's. */\n source: 'project' | 'user'\n /** Why it failed or was skipped. */\n message: string\n /** `true` when the entry is a skip notice, not a failure. */\n informational?: boolean\n}\n\n/** An extension in the host's catalog. */\nexport interface HostCatalogExtension extends HostCatalogToggle {\n /** Where the extension was found. */\n source: 'user' | 'project' | 'inline' | 'builtin'\n /** Version from the extension manifest. */\n version?: string\n /** What the extension does. */\n description?: string\n /** Directory of the extension on the host's machine. */\n dir?: string\n /** Why it did not load. */\n error?: string\n /** What it contributes: `tools`, `skills`, `mcps`, `commands`, … */\n capabilities?: string[]\n /** Its display name (the definition's `displayName`, else the manifest's). Absent: the name. Additive. */\n displayName?: string\n /** Its icon (the definition's `icon`, else the manifest's): what `extensionMark` reads. Additive. */\n icon?: { gui?: string, tui?: string }\n /** The source it was installed from (`.install.json`), which an update follows. Absent: not installed from a source. Additive. */\n origin?: ExtensionInstallOrigin\n}\n\n/** A plugin in the host's catalog. */\nexport interface HostCatalogPlugin extends HostCatalogToggle {\n /** Where the plugin comes from: a directory on disk, or an extension. */\n origin: { kind: 'disk', scope: 'project' | 'user', dir: string } | { kind: 'extension', extensionName: string, dir: string }\n /** `false`: the manifest was rejected (`error` says why). */\n ok: boolean\n /** Version from the plugin manifest. */\n version?: string\n /** What the plugin does. */\n description?: string\n /** Names of the skills the plugin contributes. */\n skills: string[]\n /** Names of the MCP servers the plugin contributes. */\n mcpServers: string[]\n /** Why the manifest was rejected, when `ok` is `false`. */\n error?: string\n}\n\n/** One provider a host can run, with its models (`models.list`). */\nexport interface HostModelProvider {\n /** Provider key. */\n key: string\n /** Display name. */\n label: string\n /** Models the provider offers on this host. */\n models: HostModelInfo[]\n /**\n * The host's stored accounts of the provider a session can be pinned to\n * (`ProviderAuth.accounts`), when it has several. Ids are the host's own:\n * a pick on a server names one of its accounts. `models`: that account's\n * own list (an extension's `models.set(id, list, { account })`), sent only\n * when it differs from {@link HostModelProvider.models}; absent, the\n * account runs on `models`. Additive.\n */\n accounts?: Array<{ id: string, label: string, active: boolean, models?: HostModelInfo[] }>\n /**\n * Decision models of the provider's Decisions endpoint, with whether this\n * host's credentials can use them. Absent on providers without one, and\n * from hosts that predate decisions. Additive.\n */\n decisionModels?: HostDecisionModel[]\n /**\n * Image models of the provider's image endpoint, with whether this host's\n * credentials can use them. Absent on providers without one, and from\n * hosts that predate image generation. Additive.\n */\n imageModels?: HostImageModel[]\n}\n\n/** One image model a host's provider serves (`HostModelProvider.imageModels`). */\nexport interface HostImageModel {\n id: string\n name: string\n /** The model takes reference images. */\n references: boolean\n /** The model can return a transparent background. */\n transparency: boolean\n available: boolean\n reason?: string\n /** The model `generate_image` uses while no image model is picked. Additive. */\n isDefault?: boolean\n}\n\n/** `decisions.test`: how the probe decision went. */\nexport interface HostDecisionTestResult {\n ok: boolean\n provider?: string\n model?: string\n durationMs: number\n reason?: string\n message?: string\n}\n\n/** `models.test`: how the probe prompt went, in the fields of `decisions.test`. */\nexport type HostModelTestResult = HostDecisionTestResult\n\n/** One decision model a host's provider serves (`models.list`). */\nexport interface HostDecisionModel {\n id: string\n available: boolean\n reason?: string\n}\n\n/** `ModelInfo` as it crosses the wire. */\nexport interface HostModelInfo {\n /** Model id. */\n id: string\n /** Display name. */\n name?: string\n /** Context window in tokens. */\n contextWindow: number\n /** Maximum output tokens. */\n maxTokens?: number\n /** Whether the model supports reasoning. */\n reasoning?: boolean\n /** Input kinds the model accepts. */\n input?: ('text' | 'image')[]\n /** Price per million tokens, by token kind. */\n cost?: { input: number, output: number, cacheRead?: number, cacheWrite?: number }\n /** Provider that serves the model. */\n provider?: string\n /** Model-specific boolean options, with an optional cost multiplier per token kind. */\n options?: { id: string, label: string, description?: string, costMultiplier?: { input?: number, output?: number, cacheRead?: number, cacheWrite?: number } }[]\n}\n\n/** One credential source of a host's provider (`auth.status`); no secret. */\nexport interface HostAuthMethod {\n /** Where the credential comes from: a stored API key, an OAuth login, or an environment variable. */\n source: 'apikey' | 'oauth' | 'env'\n /** A stored credential the provider resolves (`env` never is). */\n active: boolean\n /** Credentials-file key of a stored credential: the `account` of `auth.remove`. */\n key?: string\n /** OAuth account name. */\n label?: string\n /** Display detail: `credentials.json`, an OAuth account and its expiry, an env var name. */\n detail: string\n}\n\n/**\n * A question the provider's sign-in asks before (or after) its URL: a choice\n * between flows, or a free text. The client shows it and answers with\n * `auth.oauth.respond`; the host never picks for the user.\n */\nexport type HostOAuthStep\n = | { id: string, kind: 'select', message: string, options: Array<{ id: string, label: string }> }\n | { id: string, kind: 'prompt', message: string, placeholder?: string, allowEmpty?: boolean }\n\n/** Result of `auth.oauth.begin`. */\nexport interface HostOAuthBegin {\n /** Random, single-use, bound to the connection that began it. */\n flowId: string\n /** The authorization URL (a device flow: its verification URL); `''` while a `step` comes first. */\n url: string\n /** How the client gets the code back. `step`: answer `step` (`auth.oauth.respond`) before the URL exists. */\n mode: 'loopback' | 'browser' | 'device' | 'step'\n /** A question to answer before the URL exists. Set when `mode` is `step`. */\n step?: HostOAuthStep\n /** `loopback`: where the browser is sent back, on the client's machine. */\n redirectUri?: string\n /** `device`: the code to enter at `url`. */\n userCode?: string\n /** Text to show the user while they sign in. */\n instructions?: string\n /** Epoch ms: the host forgets the flow after it. */\n expiresAt: number\n}\n\n/** `auth.oauth.complete`: the outcome, never a token. */\nexport interface HostOAuthComplete {\n /** A provider sign-in: its new status. */\n provider?: HostProviderAuth\n /** An MCP server sign-in: its name. */\n mcpServer?: string\n /** Not finished: the sign-in asks this. Answer it (`auth.oauth.respond`), then `complete` again. */\n step?: HostOAuthStep\n}\n\n/** Sign-in state of one provider on a host, from `auth.status`. Holds no secret. */\nexport interface HostProviderAuth {\n /** Provider key. */\n key: string\n /** Display name. */\n label: string\n /** Some credential source is present. */\n configured: boolean\n /** The provider signs in with OAuth (on the host's machine only). */\n oauth: boolean\n /** The env var it reads, when it declares one. */\n envKey?: string\n /** Credential sources of the provider. */\n methods: HostAuthMethod[]\n /** Its configuration fields (a local server's URL, a cloud's region), what `auth.configure` takes. Additive. */\n customFields?: ProviderFieldView[]\n /** The non-secret field values set now (stored, else from the host's environment). Additive. */\n configuredFields?: Record<string, string>\n}\n\n/** Folders a host lets clients browse, from `fs.roots`. */\nexport interface FsRoots {\n /** Real paths, the default first. */\n roots: string[]\n /** Session folders must be inside `roots` (a server). */\n confined: boolean\n}\n\n/** One folder in an {@link FsDirListing}. */\nexport interface FsDirEntry {\n /** Folder name. */\n name: string\n /** Real path (a symlink resolved). */\n path: string\n /** Holds a `.git`. */\n isGitRepo: boolean\n}\n\n/**\n * What `git.checkout` / `git.createBranch` answered. `worktree`: another worktree holds the branch, at this path;\n * `chats`: the host's unarchived sessions in that checkout.\n */\nexport type GitCheckoutResult = { ok: true } | { ok: false, error: string, worktree?: string, chats?: string[] }\n\n/** A session's transcript as a file (`sessions.export`): its name and text. */\nexport interface SessionExportFile {\n /** `<session id>.md` or `.json`. */\n filename: string\n /** The rendered transcript. */\n content: string\n}\n\n/** A folder listing from `fs.listDirs`. */\nexport interface FsDirListing {\n /** Real paths of the browsable roots. */\n roots: string[]\n /** The listed folder, as a real path. */\n path: string\n /** The folder above, or `null` at a root. */\n parent: string | null\n /** Sorted by name. */\n entries: FsDirEntry[]\n /** More folders than the listing returns. */\n truncated?: boolean\n}\n\n/** What `fs.searchDirs` found. */\nexport interface FsDirSearch {\n /** The matching folders: exact names first, then names that start with the query, then the rest; shallow first. */\n results: FsDirEntry[]\n /** The result bound or the bound on folders read cut the search short. */\n truncated?: boolean\n}\n\n/** One ordered model-fallback target (primary excluded). */\nexport interface ModelFallbackRef {\n /** Provider of the fallback model. */\n providerKey: ProviderKey\n /** Id of the fallback model. */\n modelId: string\n /** The stored account of the provider (credential id); omitted = its active account. Additive. */\n account?: string\n}\n\n/** One row of a cross-window session list. */\nexport interface SessionRow {\n /** Session id. */\n id: string\n /** Session title. */\n title: string\n /** Project the session belongs to, or `null` when it has none. */\n projectRoot: string | null\n /** Working directory of the session. */\n cwd: string\n /** Id of the agent the session runs as. */\n agentId?: string\n /** Run state of the session. */\n status: 'idle' | 'running' | 'completed' | 'error'\n /** Creation time, epoch ms. */\n createdAt: number\n /** Time of the last change, epoch ms. */\n updatedAt: number\n /** Whether the session is archived. */\n archived: boolean\n /** Listed first (`metadata.favorite`). Additive. */\n favorite?: boolean\n /** Orchestration main session — see `SessionMeta.isMain`. Additive. */\n isMain?: boolean\n /** The session's space when not Default — see `SessionMeta.spaceId`. Additive. */\n spaceId?: string\n /** Provider the session runs on. */\n providerKey?: ProviderKey\n /** Model the session runs on. */\n modelId?: string\n /** The pinned account of `providerKey` (credential id), when one is. Additive. */\n account?: string\n /** Thinking effort of the session. */\n effort?: ThinkingLevel\n /** Model-specific boolean options of the session. */\n modelOptions?: Record<string, boolean>\n /** Validated (head-matched) fallback chain tail, for pickers/badges. */\n modelFallbacks?: ModelFallbackRef[]\n /** Non-local environment summary (kind, state, branch, error). */\n environment?: SessionEnvironmentSummary\n /** The host serving this row (`HelloResult.hostId`). Additive: absent from older hosts. */\n hostId?: string\n /**\n * The repository the session's folder is a checkout of (`github.com/owner/repo`,\n * see `repoKeyOf`). Copies of one repository on two machines have the same key.\n * Absent outside git, without a shared remote, and from older hosts. Additive.\n */\n repoKey?: string\n /**\n * While `status` is `running`: when the run in progress began, epoch ms on\n * the host's clock, so a client that missed its `run:start` still shows how\n * long it has been going. Additive: absent from older hosts.\n */\n runStartedAt?: number\n /**\n * While `status` is `running`: the estimates of its runs in progress, the\n * session's own first, then its subagents' (`Settings.runEstimates`), so a\n * window opened mid-run counts down from the same point. Absent when none\n * is estimated, and from older hosts. Additive.\n */\n runEstimates?: RunEstimateView[]\n /**\n * Facet values extensions computed for the session (`ctx.sessions.facets`),\n * keyed `<extensionId>.<key>`; queries read them as `facet.<extensionId>.<key>`.\n * Stored with the session, so a list computes nothing. `sessions:facets`\n * announces a change. Absent when it has none, and from older hosts. Additive.\n */\n facets?: Record<string, JsonValue>\n}\n\n/** Params of `sessions.create`. */\nexport interface CreateSessionParams {\n /** Tool-execution directory — `projectRoot` is derived from it host-side. */\n cwd: string\n /** Title of the session. Omitted: the host picks one. */\n title?: string\n /** Id of the agent the session runs as. */\n agentId?: string\n /** Provider the session runs on. */\n providerKey?: ProviderKey\n /** Model the session runs on. */\n modelId?: string\n /** The stored account of `providerKey` to run on (credential id). Additive: older hosts ignore it. */\n account?: string\n /** Seed an ordered fallback chain alongside the model pick. */\n fallbacks?: ModelFallbackRef[]\n /** The model pick's reasoning effort and options, stamped with it. */\n effort?: ThinkingLevel\n /** Model-specific boolean options, stamped with the model pick. */\n modelOptions?: Record<string, boolean>\n /** Skills pinned from the first turn (an authoring session's docs skill). */\n pinnedSkills?: string[]\n /** Mark as an extension-authoring session (auto-activates the docs skill). */\n extensionEdit?: boolean\n /** Mark as a skill-authoring session for the named skill (dir = `cwd`). */\n skillEdit?: { name: string }\n /** Where the session's work happens. Omitted → local. */\n environment?: EnvironmentRequest\n /** The space the session belongs to. Omitted → Default. Additive: older hosts ignore it. */\n spaceId?: string\n /** Create it as a hidden `/side` session of this parent. Additive: older hosts ignore it. */\n sideOf?: string\n /** The session's rules (`sessions.setPolicy`). Additive: older hosts ignore it. */\n policy?: SessionPolicy\n}\n\n/* -------------------------------------------------------------------------\n * Daemon handshake\n * ---------------------------------------------------------------------- */\n\n/** Params of the `hello` handshake. */\nexport interface HelloParams {\n /** Protocol version the client speaks. */\n protocolVersion: number\n /**\n * The oldest version the client can speak down to ({@link IPC_MIN_PROTOCOL_VERSION}).\n * A zidane-server accepts when the ranges overlap. Absent: `protocolVersion` only. Additive.\n */\n minProtocolVersion?: number\n /** Client's zidane version — surfaced in daemon diagnostics. */\n appVersion: string\n /** Process id of the client. */\n pid: number\n /**\n * Build fingerprint (module mtime; `'unknown'` in compiled binaries).\n * When BOTH sides report a real id and they differ, the daemon rejects\n * the handshake like a protocol-version mismatch — the client drains it\n * and respawns. Closes same-version code drift during development.\n */\n buildId?: string\n /**\n * Version of the zidane code the client runs (`ZIDANE_VERSION`, inlined at\n * build). Unlike `buildId` this survives compiled binaries, so it closes\n * the gap released builds had: same protocol version, older code. A\n * client STRICTLY NEWER than the daemon is rejected like a build mismatch\n * and the stale daemon is drained; an older client is accepted and\n * degrades via `optional()`.\n */\n codeVersion?: string\n}\n\n/**\n * What a host process is: a window's own (`in-process`), the local shared\n * daemon (`daemon`), or a remote `zidane-server` (`server`).\n */\nexport type HostKind = 'in-process' | 'daemon' | 'server'\n\n/** Which host a client is talking to, as clients keep it (from `hostRefOf`). */\nexport interface HostRef {\n /** Stable across restarts: persisted in the host's data dir. */\n id: string\n /** What kind of host it is. */\n kind: HostKind\n /** Display name: the machine's hostname by default. */\n name: string\n}\n\n/** Result of the `hello` handshake and of `daemon.info`. */\nexport interface HelloResult {\n /** Protocol version the host speaks. */\n protocolVersion: number\n /** The oldest version the host still speaks ({@link IPC_MIN_PROTOCOL_VERSION}). Additive. */\n minProtocolVersion?: number\n /**\n * The version this connection speaks: the lower of the client's and the host's. Additive:\n * absent, the connection speaks `protocolVersion`.\n */\n negotiatedProtocolVersion?: number\n /**\n * The client scope this connection's token grants (`./scopes`): calls above it are refused.\n * Absent: every method (a local window). Additive.\n */\n scope?: ClientScope\n /**\n * The methods this connection may call on this host: the ones it handles, within `scope`.\n * Clients show what is offered instead of failing on what isn't. Additive.\n */\n methods?: IpcMethodName[]\n /** zidane version of the host. */\n appVersion: string\n /** Process id of the host. */\n pid: number\n /** Start time of the host process, epoch ms. */\n startedAt: number\n /** Build fingerprint of the host code. `'unknown'` in compiled binaries. */\n buildId?: string\n /** Version of the zidane code the host runs. */\n codeVersion?: string\n /**\n * Host identity (additive). `hostId` is a UUID persisted once in the host's\n * data dir, so it survives restarts; the in-process host and the local\n * daemon share the data dir, and so the id: they are the same computer.\n */\n hostId?: string\n /** What kind of host this is. */\n hostKind?: HostKind\n /** Display name of the host. */\n hostName?: string\n /**\n * The daemon is older than a client that attached while it had active\n * work: it accepted the handshake instead of draining (which would abort\n * those runs) and exits once idle. Clients attach normally; their\n * reconnect path lands on a fresh daemon after the exit.\n */\n retiring?: boolean\n /**\n * Names this host process's signal numbering ({@link SIGNAL_SEQ_FIELD}):\n * a position from another epoch cannot be resumed. Additive.\n */\n signalEpoch?: string\n /**\n * This server lends itself as a machine to the hosts of its clients\n * (`machine.attach`, `allowAsMachine` on). Absent: it doesn't. Additive.\n */\n machineServe?: boolean\n /**\n * This server takes installs and removals from its clients (`catalog.install`\n * / `remove` / `update`, `mcp.upsert` / `remove`; `allowRemoteInstalls` on).\n * Absent: it doesn't (or predates them). Additive.\n */\n remoteInstalls?: boolean\n /**\n * Clients may clone repositories into its workspace roots (`git.clone`). A\n * zidane-server's `allowClone`; a local host always does. Absent: an older\n * host, where `git.clone` needs an admin token. Additive.\n */\n clone?: boolean\n /**\n * Clients may create folders in its workspace roots (`fs.mkdir`). A\n * zidane-server's `allowCreateFolders`; a local host always does. Absent:\n * an older host, without `fs.mkdir`. Additive.\n */\n createFolders?: boolean\n /**\n * The host process's home folder (`os.homedir()`). Clients show it as `~` in\n * the paths they display; nothing else reads it. Absent: an older host. Additive.\n */\n homeDir?: string\n /** This server takes settings sync from a client's computer (`sync.*`). Absent: it doesn't. Additive. */\n sync?: boolean\n /** The sync categories it takes. Absent with `sync`: the ones before `environments`. Additive. */\n syncCategories?: SyncCategory[]\n /**\n * This host runs terminals without a session (`terminal.openInProject` and\n * the other project / draft terminal methods). Absent: sessions only. Additive.\n */\n projectTerminals?: true\n /**\n * `daemon.info` only: a run, compaction, `/` command or background task is\n * in flight on this host (open terminals do not count). `zidane server\n * wait-idle` waits for `false` before a restart. Additive.\n */\n activeWork?: boolean\n}\n\n/** A zidane-server token's scope: a client scope (`./scopes`), or `machine` (it lends a computer). */\nexport type ServerTokenScope = ClientScope | 'machine'\n\n/** A zidane-server token as `tokens.*` lists it: never its secret or its hash. */\nexport interface ServerTokenInfo {\n /** Stable id (`tok_…`). */\n id: string\n /** The name it was created with, such as the device it is for. */\n name: string\n /** What it may do. */\n scope: ServerTokenScope\n /** When it was created, epoch ms. */\n createdAt: number\n /** When it last opened a connection, epoch ms. */\n lastUsedAt?: number\n /** When it was revoked, epoch ms. Absent: live. */\n revokedAt?: number\n /** The token that created it, when a client did (`tokens.create`, `tokens.createMachineToken`). */\n createdBy?: string\n /** When it stops working, epoch ms. Absent: never. */\n expiresAt?: number\n}\n\n/** `catalog.install` / `remove` / `update`: what is installed from a client, in the host user's scope. */\nexport type HostInstallKind = 'skill' | 'extension'\n\n/**\n * Which catalog a `catalog:changed` signal says to re-read. `models`: what\n * `models.list` answers changed (an extension's provider or account list,\n * after a sign-in or a new default account). Additive.\n */\nexport type HostCatalogName = 'skills' | 'mcps' | 'extensions' | 'plugins' | 'models'\n\n/** An agent profile as `agents.list` offers it. */\nexport interface HostAgentProfile {\n /** Stable id (`sessions.setAgentId`). */\n id: string\n /** Its name. */\n label: string\n /** What it does. */\n description: string\n /** A theme color name or a CSS color. */\n accent: string\n}\n\n/** The picks `prefs.get` / `prefs.set` remember across apps (`state.json`). */\nexport type HostComposerPrefs = Pick<TuiState, 'lastEffortByModel' | 'lastModelOptionsByModel' | 'lastModelChain'>\n\n/** `sessions.sideSession`: a session's `/side` session and its own row. */\nexport interface SideSessionLookup {\n /** The side session, `null` until one is created. */\n side: SessionRow | null\n /** The session asked about, `null` when it is unknown. */\n parent: SessionRow | null\n}\n\n/** A provider of `onboarding.providers`: the wizard's row, with the model it runs when none is picked. */\nexport type HostOnboardingProvider = OnboardingProvider & { defaultModel?: string }\n\n/** `claudeImport.detect`: what `~/.claude` on the host holds. */\nexport interface ClaudeImportDetection {\n /** There is a Claude Code setup to import. */\n available: boolean\n /** The transcripts found for the folder, and in every project. */\n counts: { project: number, all: number }\n}\n\n/** What `claudeImport.run` imports. */\nexport interface ClaudeImportSelection {\n /** Conversations. */\n sessions: boolean\n /** MCP servers. */\n mcps: boolean\n /** Skills. */\n skills: boolean\n /** Commands, and subagents unless `agents` says otherwise. */\n commands: boolean\n /** Subagents. Absent: they follow `commands`. */\n agents?: boolean\n /** Conversations of every project, not just the folder's. */\n allProjects: boolean\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsWA,MAAa,uBAAuB;;;;;;;;;;AAYpC,MAAa,2BAAmC;;;;;;AAOhD,MAAa,eAAe;CAC1B,iBAAiB;CACjB,eAAe;;CAEf,aAAa;;;;;;CAMb,kBAAkB;;;;;;CAMlB,eAAe;;;;;;CAMf,WAAW;AACb;;;;;;;AAuBA,SAAgB,0BAA0B,MAAsD;CAC9F,IAAI,OAAO,SAAS,YAAY,SAAS,MACvC,OAAO,KAAA;CACT,MAAM,EAAE,cAAc,eAAe;CACrC,IAAI,OAAO,iBAAiB,YAAY,CAAC,MAAM,QAAQ,UAAU,KAAK,CAAC,WAAW,OAAM,MAAK,OAAO,MAAM,QAAQ,GAChH,OAAO,KAAA;CACT,OAAO;EAAE;EAAc,YAAY,CAAC,GAAG,UAAU;CAAE;AACrD;;;;;;AAOA,MAAa,cAAc;;;;;;;AAQ3B,MAAa,mBAAmB;;;;;;AAy6ChC,SAAgB,UAAU,OAAoC;CAC5D,IAAI,OAAO,MAAM,WAAW,YAAY,CAAC,MAAM,UAC7C,OAAO;CACT,OAAO;EAAE,IAAI,MAAM;EAAQ,MAAM,MAAM;EAAU,MAAM,MAAM,YAAY,MAAM;CAAO;AACxF;;AAUA,MAAa,yBAAyB;;AAEtC,MAAa,6BAA6B;;;;;;;;AAoD1C,eAAsB,eACpB,SACA,QAC4B;CAC5B,MAAM,SAAS,MAAM,QAAQ,uBAAuB,MAAM;CAC1D,OAAO,MAAM,QAAQ,MAAM,IAAI,EAAE,QAAQ,OAAO,IAAI;AACtD;AAEA,SAAS,mBAAmB,KAAuB;CACjD,OAAO,OAAO,QAAQ,YAAY,QAAQ,QAAS,IAA2B,SAAS,aAAa;AACtG;;;;;;;;;;;;;AAcA,eAAsB,cACpB,SACA,WACA,UAAkC,CAAC,GACX;CACxB,QAAQ,MAAM,kBAAkB,SAAS,WAAW,QAAQ,aAAA,GAAmC,EAAA,CAAG;AACpG;;;;;;;;AASA,eAAsB,eACpB,SACA,WACA,QACA,UAAkC,CAAC,GACkB;CACrD,OAAO,kBAAkB,SAAS,WAAW,QAAQ,aAAA,KAAqC,MAAM;AAClG;AAEA,eAAe,kBACb,SACA,WACA,WACA,QACqD;CACrD,IAAI,QAAQ;CACZ,MAAM,QAAyB,CAAC;CAChC,IAAI,aAAa;CACjB,IAAI,WAAW;CACf,IAAI;CACJ,SAAS;EACP,IAAI;EACJ,IAAI;GACF,OAAO,MAAM,eAAe,SAAS;IAAE;IAAW;IAAO,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;GAAG,CAAC;EACxG,SACO,KAAK;GACV,IAAI,mBAAmB,GAAG,KAAK,QAAQ,GAAG;IACxC,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC;IACzC;GACF;GACA,MAAM;EACR;EAQA,MAAM,QAAQ,MAAM;EACpB,IAAI,SAAS,CAAC,cAAc,MAAM,EAAE,EAAE,SAAS,iBAAiB,KAAK,OAAO,SAAS,GACnF,MAAM,QAAQ;GAAE,MAAM;GAAa,MAAM;EAAG,CAAC;EAC/C,aAAa,KAAK,UAAU;EAC5B,aAAa,cAAc,KAAK,UAAU,KAAA;EAC1C,MAAM,QAAQ,KAAK,MAAM;EAEzB,IAAI,KAAK,WAAW,KAAA,KAAa,KAAK,UAAU,KAAM,WAAW,KAAA,KAAa,KAAK,UAAU,QAC3F;EACF,IAAI,UAAU,UAAU;GACtB,MAAM,SAAS,MAAM,KAAK;GAC1B,IAAI,OAAO,MAAM,GACf,OAAO;IAAE;IAAQ,SAAS,KAAK;GAAO;EAC1C;EACA,SAAS,KAAK;CAChB;CACA,OAAO;EAAE,QAAQ,MAAM,KAAK;EAAG,SAAS;CAAE;AAC5C;;AAGA,MAAa,qBAAqB;;AAElC,MAAa,yBAAyB;;AAYtC,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;AAmBlC,eAAsB,oBACpB,SACA,WACA,UAAkC,CAAC,GACN;CAC7B,MAAM,SAAS,EAAE,OAAO,QAAQ,aAAA,IAAgC;CAChE,KAAK,IAAI,UAAU,GAAG,WAAW,2BAA2B,WAAW;EACrE,MAAM,OAAO,MAAM,wBAAwB,SAAS,WAAW,MAAM;EACrE,IAAI,SAAS,WACX,OAAO;CACX;CACA,OAAO,eAAe,MAAM,QAAQ,gBAAgB,EAAE,UAAU,CAAC,CAAC;AACpE;AAEA,SAAS,eAAe,MAAsD;CAC5E,IAAI,CAAC,MACH,OAAO;CACT,MAAM,EAAE,SAAS,UAAU,GAAG,SAAS;CACvC,OAAO;AACT;;AAGA,eAAe,wBAAwB,SAAiC,WAAmB,QAAoE;CAC7J,MAAM,QAAuB,CAAC;CAC9B,IAAI,QAAQ;CACZ,IAAI,UAAkC;CACtC,OAAO,MAAM,SAAS,OAAO;EAC3B,IAAI;EACJ,IAAI;GACF,OAAO,MAAM,QAAQ,qBAAqB;IAAE;IAAW,MAAM,MAAM;IAAQ,OAAO,OAAO;GAAM,CAAC;EAClG,SACO,KAAK;GACV,IAAI,MAAM,WAAW,KAAK,iBAAiB,GAAG,GAC5C,OAAO,eAAe,MAAM,QAAQ,gBAAgB,EAAE,UAAU,CAAC,CAAC;GACpE,IAAI,mBAAmB,GAAG,KAAK,OAAO,QAAQ,GAAG;IAC/C,OAAO,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,QAAQ,CAAC,CAAC;IACvD;GACF;GACA,MAAM;EACR;EACA,IAAI,CAAC,MACH,OAAO;EACT,IAAI,YAAY,MACd,UAAU,EAAE,GAAI,KAAK,YAAY,KAAA,IAAY,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC,EAAG;OACrE,IAAI,KAAK,YAAY,QAAQ,IAChC,OAAO;EACT,QAAQ,KAAK;EAEb,IAAI,KAAK,MAAM,WAAW,GACxB;EACF,MAAM,KAAK,GAAG,KAAK,KAAK;CAC1B;CACA,MAAM,OAAO,MAAM,QAAQ,gBAAgB;EAAE;EAAW,OAAO;CAAM,CAAC;CACtE,IAAI,CAAC,MACH,OAAO;CACT,IAAI,YAAY,QAAQ,KAAK,YAAY,QAAQ,IAC/C,OAAO;CACT,OAAO;EAAE,GAAG,eAAe,IAAI;EAAI;CAAM;AAC3C;;AA6BA,MAAa,WAAW"}
|