zidane 7.2.4 → 8.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +34 -6
- package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
- package/dist/acp-DQDhi2dj.js.map +1 -0
- package/dist/acp-cli.d.ts +1 -1
- package/dist/acp-cli.js +9 -66
- package/dist/acp-cli.js.map +1 -1
- package/dist/acp.d.ts +10 -590
- package/dist/acp.d.ts.map +1 -1
- package/dist/acp.js +3 -3
- package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
- package/dist/agent-DSLNmBp0.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -2
- package/dist/aliasing-lVFbm81n.js +217 -0
- package/dist/aliasing-lVFbm81n.js.map +1 -0
- package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
- package/dist/anthropic-CD00LhUP.js.map +1 -0
- package/dist/artifacts-CV2hUKnL.js.map +1 -1
- package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
- package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
- package/dist/call-tool-dHlbGOIY.js +70 -0
- package/dist/call-tool-dHlbGOIY.js.map +1 -0
- package/dist/chat/pure.d.ts +372 -6
- package/dist/chat/pure.d.ts.map +1 -1
- package/dist/chat/pure.js +35 -244
- package/dist/chat/pure.js.map +1 -1
- package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
- package/dist/chat-JPJJ8uu5.js.map +1 -0
- package/dist/chat.d.ts +4 -6
- package/dist/chat.js +23 -12
- package/dist/cli-shared-C-YCaglL.js +159 -0
- package/dist/cli-shared-C-YCaglL.js.map +1 -0
- package/dist/client-core-BQSyDALT.d.ts +2115 -0
- package/dist/client-core-BQSyDALT.d.ts.map +1 -0
- package/dist/codemode-worker.d.ts +1 -0
- package/dist/codemode-worker.js +155 -0
- package/dist/codemode-worker.js.map +1 -0
- package/dist/codemode.d.ts +352 -0
- package/dist/codemode.d.ts.map +1 -0
- package/dist/codemode.js +5 -0
- package/dist/connection-Dr-Js4yZ.d.ts +28 -0
- package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
- package/dist/connection-loop-gdh22LTI.js +112 -0
- package/dist/connection-loop-gdh22LTI.js.map +1 -0
- package/dist/context-segments-BHKlagL6.js +1016 -0
- package/dist/context-segments-BHKlagL6.js.map +1 -0
- package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
- package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
- package/dist/contexts/daytona.d.ts +19 -8
- package/dist/contexts/daytona.d.ts.map +1 -1
- package/dist/contexts/daytona.js +1 -440
- package/dist/contexts/docker.d.ts +36 -7
- package/dist/contexts/docker.d.ts.map +1 -1
- package/dist/contexts/docker.js +1 -456
- package/dist/contexts/e2b.d.ts +68 -13
- package/dist/contexts/e2b.d.ts.map +1 -1
- package/dist/contexts/e2b.js +1 -382
- package/dist/contexts/sandbox.d.ts +1 -1
- package/dist/contexts/sandbox.js +5 -0
- package/dist/contexts/sandbox.js.map +1 -1
- package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
- package/dist/contexts-d7UolYot.js.map +1 -0
- package/dist/contexts.d.ts +3 -3
- package/dist/contexts.js +1 -1
- package/dist/cred-keys-GpBg71cP.js +105 -0
- package/dist/cred-keys-GpBg71cP.js.map +1 -0
- package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
- package/dist/credentials-JttEuRON.js.map +1 -0
- package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
- package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
- package/dist/daemon-cli.d.ts +1 -1
- package/dist/daemon-cli.js +3 -2
- package/dist/daemon-cli.js.map +1 -1
- package/dist/daytona-DG3omipZ.js +513 -0
- package/dist/daytona-DG3omipZ.js.map +1 -0
- package/dist/defaults-Cx3zvDOV.js +23 -0
- package/dist/defaults-Cx3zvDOV.js.map +1 -0
- package/dist/dispatcher-BMlu2BmZ.js +4941 -0
- package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
- package/dist/docker-BZhMMJUp.js +727 -0
- package/dist/docker-BZhMMJUp.js.map +1 -0
- package/dist/e2b-CEVOdRib.js +480 -0
- package/dist/e2b-CEVOdRib.js.map +1 -0
- package/dist/edit-utils-EGosADZq.js +234 -0
- package/dist/edit-utils-EGosADZq.js.map +1 -0
- package/dist/environment-8wsKE2Ln.js +214 -0
- package/dist/environment-8wsKE2Ln.js.map +1 -0
- package/dist/eval-BNcvle_J.js +1595 -0
- package/dist/eval-BNcvle_J.js.map +1 -0
- package/dist/eval.d.ts +2 -2
- package/dist/eval.js +1 -1489
- package/dist/executor-Cx5-8yqi.js +621 -0
- package/dist/executor-Cx5-8yqi.js.map +1 -0
- package/dist/extension-authoring-DyGGmq9V.js +385 -0
- package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
- package/dist/extensions.d.ts +2 -2
- package/dist/extensions.js +3 -3
- package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
- package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
- package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
- package/dist/format-C2NQEVUH.js.map +1 -0
- package/dist/format-bytes-C7tfc3Zm.js +55 -0
- package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
- package/dist/headless-C_rNUuYC.js +960 -0
- package/dist/headless-C_rNUuYC.js.map +1 -0
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -413
- package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
- package/dist/history-search-CcYzF8-0.js.map +1 -0
- package/dist/history-search-worker.d.ts +1 -1
- package/dist/history-search-worker.js +1 -1
- package/dist/host-D7NrI03V.js +378 -0
- package/dist/host-D7NrI03V.js.map +1 -0
- package/dist/host-signals-BcP5QKUD.js +118 -0
- package/dist/host-signals-BcP5QKUD.js.map +1 -0
- package/dist/identity-CwfO8K-t.js +26 -0
- package/dist/identity-CwfO8K-t.js.map +1 -0
- package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
- package/dist/index-BGe1fQT7.d.ts.map +1 -0
- package/dist/index-BVQsIKGn.d.ts +448 -0
- package/dist/index-BVQsIKGn.d.ts.map +1 -0
- package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
- package/dist/index-CHABJd-L.d.ts.map +1 -0
- package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
- package/dist/index-D6a7qXpg.d.ts.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +27 -23
- package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
- package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
- package/dist/ipc/remote.d.ts +313 -0
- package/dist/ipc/remote.d.ts.map +1 -0
- package/dist/ipc/remote.js +4 -0
- package/dist/ipc.d.ts +6 -964
- package/dist/ipc.js +403 -4
- package/dist/ipc.js.map +1 -0
- package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
- package/dist/isolation-D9L650W5.d.ts.map +1 -0
- package/dist/json-rpc--HXQti1E.js +350 -0
- package/dist/json-rpc--HXQti1E.js.map +1 -0
- package/dist/links-j8rED1sR.js +603 -0
- package/dist/links-j8rED1sR.js.map +1 -0
- package/dist/local-terminal-D8QThwo_.js +252 -0
- package/dist/local-terminal-D8QThwo_.js.map +1 -0
- package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
- package/dist/logger-Gtqlayx8.js.map +1 -0
- package/dist/logs-view-CWG8aUAG.js.map +1 -1
- package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
- package/dist/mcp-_wecH9Qe.js.map +1 -0
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +2 -2
- package/dist/media-sniff-UKijEaiQ.js.map +1 -1
- package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
- package/dist/messages-BqiwcD2Q.js.map +1 -0
- package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
- package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
- package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
- package/dist/openai-compat-CFrpH7uq.js.map +1 -0
- package/dist/orchestration-BCGmB8Ps.js +511 -0
- package/dist/orchestration-BCGmB8Ps.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -2
- package/dist/output/stream-json.d.ts.map +1 -1
- package/dist/output/stream-json.js +1 -1
- package/dist/output/terminal.d.ts +1 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +13 -7
- package/dist/output/terminal.js.map +1 -1
- package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
- package/dist/plugins-DS7mahzZ.js.map +1 -0
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +1 -2
- package/dist/prelude-Cxo4t74B.js +517 -0
- package/dist/prelude-Cxo4t74B.js.map +1 -0
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -2
- package/dist/project-root-B8zADr4o.js +167 -0
- package/dist/project-root-B8zADr4o.js.map +1 -0
- package/dist/project-user-paths-BSgtrRxl.js +58 -0
- package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
- package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
- package/dist/prompts-DYcvqShf.d.ts.map +1 -0
- package/dist/protocol-DnhqqSmE.js +13 -0
- package/dist/protocol-DnhqqSmE.js.map +1 -0
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +1 -2
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/arcee.js +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/baseten.js +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/cerebras.js +3 -2
- package/dist/providers/cerebras.js.map +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai-compat.js +1 -2
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +15 -12
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +3 -2
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +3 -3
- package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
- package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/registry-D6ShBWJU.js +5234 -0
- package/dist/registry-D6ShBWJU.js.map +1 -0
- package/dist/remote-hosts-BtA_9ZGp.js +97 -0
- package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
- package/dist/restate.d.ts +2 -3
- package/dist/restate.d.ts.map +1 -1
- package/dist/restate.js +631 -572
- package/dist/restate.js.map +1 -1
- package/dist/run-summary-CklLiZ4y.js +288 -0
- package/dist/run-summary-CklLiZ4y.js.map +1 -0
- package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
- package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
- package/dist/session/sqlite.d.ts +1 -2
- package/dist/session/sqlite.d.ts.map +1 -1
- package/dist/session/sqlite.js +1 -616
- package/dist/session-factory-BUGY5P40.js +1576 -0
- package/dist/session-factory-BUGY5P40.js.map +1 -0
- package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
- package/dist/session-xh9JXu6i.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/settings-keys-Ckf29NeM.js +677 -0
- package/dist/settings-keys-Ckf29NeM.js.map +1 -0
- package/dist/shell-path-Dqaoow2J.js +412 -0
- package/dist/shell-path-Dqaoow2J.js.map +1 -0
- package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
- package/dist/skills-DKqZJm4X.js.map +1 -0
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js +1 -2
- package/dist/source-mPExaUm8.js +381 -0
- package/dist/source-mPExaUm8.js.map +1 -0
- package/dist/sqlite-DV1DQzN2.js +698 -0
- package/dist/sqlite-DV1DQzN2.js.map +1 -0
- package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
- package/dist/src-BRMYRJib.js.map +1 -0
- package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
- package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
- package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
- package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
- package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
- package/dist/timeout-DEaqslLO.d.ts.map +1 -1
- package/dist/todo-edits-Dn251YUP.js +1790 -0
- package/dist/todo-edits-Dn251YUP.js.map +1 -0
- package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
- package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
- package/dist/tool-state-Dku6YqAB.js +989 -0
- package/dist/tool-state-Dku6YqAB.js.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -2
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +1 -2
- package/dist/tools/prompts.d.ts +1 -1
- package/dist/tools/prompts.js +7 -7
- package/dist/tools/prompts.js.map +1 -1
- package/dist/tools/web-search.d.ts +1 -2
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +2 -2
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools-_DnT3AGM.js +578 -0
- package/dist/tools-_DnT3AGM.js.map +1 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -2
- package/dist/tui.d.ts +534 -517
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +34933 -27242
- package/dist/tui.js.map +1 -1
- package/dist/turn-operations-B8sokwi5.js +333 -0
- package/dist/turn-operations-B8sokwi5.js.map +1 -0
- package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
- package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
- package/dist/types-C7ZFOztE.d.ts +132 -0
- package/dist/types-C7ZFOztE.d.ts.map +1 -0
- package/dist/types-CH5XpIHw.js +114 -0
- package/dist/types-CH5XpIHw.js.map +1 -0
- package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
- package/dist/types-Cu0ZGDu9.js.map +1 -0
- package/dist/types-IqegbJEE.d.ts +624 -0
- package/dist/types-IqegbJEE.d.ts.map +1 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.js +1 -1
- package/dist/url-D8HCl65b.js +1259 -0
- package/dist/url-D8HCl65b.js.map +1 -0
- package/dist/wasm-BVT-j5cl.js +33 -0
- package/dist/wasm-BVT-j5cl.js.map +1 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
- package/dist/ws-CIHMvlSh.js +952 -0
- package/dist/ws-CIHMvlSh.js.map +1 -0
- package/dist/ws-client-N7NxzvQp.js +230 -0
- package/dist/ws-client-N7NxzvQp.js.map +1 -0
- package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
- package/dist/xai-CvJTeLrI.js.map +1 -0
- package/dist/xdg-zweed0-t.js +117 -0
- package/dist/xdg-zweed0-t.js.map +1 -0
- package/docs/ACP.md +52 -0
- package/docs/ARCHITECTURE.md +103 -6
- package/docs/ARTIFACTS.md +8 -4
- package/docs/CHAT.md +165 -14
- package/docs/EXECUTION_CONTEXT.md +8 -0
- package/docs/EXTENSIONS.md +123 -2
- package/docs/HEADLESS.md +2 -0
- package/docs/IPC.md +775 -64
- package/docs/MACHINES.md +456 -0
- package/docs/PANELS.md +3 -0
- package/docs/README.md +4 -0
- package/docs/RESTATE.md +3 -2
- package/docs/RUN_IN_BACKGROUND.md +10 -2
- package/docs/SERVER.md +1085 -0
- package/docs/SKILL.md +6 -1
- package/docs/TERMINAL.md +75 -0
- package/docs/TUI.md +65 -14
- package/package.json +58 -26
- package/scripts/eval.ts +4 -0
- package/dist/acp-D-tVyUjw.js.map +0 -1
- package/dist/agent-D0zZnGbt.js.map +0 -1
- package/dist/anthropic-C2aole0G.js.map +0 -1
- package/dist/approvals-DKaJZYlm.js.map +0 -1
- package/dist/atomic-write-B7zr1ddF.js.map +0 -1
- package/dist/auth-BG2rVKSt.js.map +0 -1
- package/dist/completion-core-BRo86R_L.js.map +0 -1
- package/dist/contexts/daytona.js.map +0 -1
- package/dist/contexts/docker.js.map +0 -1
- package/dist/contexts/e2b.js.map +0 -1
- package/dist/contexts-CRE9pw07.js.map +0 -1
- package/dist/eval.js.map +0 -1
- package/dist/format-BF745pLL.js.map +0 -1
- package/dist/glob-DluQFSw1.js +0 -270
- package/dist/glob-DluQFSw1.js.map +0 -1
- package/dist/headless.js.map +0 -1
- package/dist/history-search-C4bk1Wz_.js.map +0 -1
- package/dist/index-BgN1T3lk.d.ts.map +0 -1
- package/dist/index-C37_ppWv.d.ts.map +0 -1
- package/dist/index-C6NEd5y_.d.ts.map +0 -1
- package/dist/ipc-zVSyo6K1.js +0 -331
- package/dist/ipc-zVSyo6K1.js.map +0 -1
- package/dist/ipc.d.ts.map +0 -1
- package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
- package/dist/json-rpc-rSWMUh9b.js +0 -192
- package/dist/json-rpc-rSWMUh9b.js.map +0 -1
- package/dist/logger--C1VQjwJ.js.map +0 -1
- package/dist/mcp-CgNd-f3F.js.map +0 -1
- package/dist/messages-2jcOA_5R.js.map +0 -1
- package/dist/openai-compat-Dy56weK8.js.map +0 -1
- package/dist/output-cap-C9zukcCj.js +0 -100
- package/dist/output-cap-C9zukcCj.js.map +0 -1
- package/dist/panels-B6gRk4bf.js +0 -789
- package/dist/panels-B6gRk4bf.js.map +0 -1
- package/dist/plugins-gbI7SBA6.js.map +0 -1
- package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
- package/dist/run-summary-BU_NgwUT.js +0 -269
- package/dist/run-summary-BU_NgwUT.js.map +0 -1
- package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
- package/dist/session/sqlite.js.map +0 -1
- package/dist/session-BqRP1hS7.js.map +0 -1
- package/dist/shell-path-h5czzllR.js +0 -1549
- package/dist/shell-path-h5czzllR.js.map +0 -1
- package/dist/skills-BC3dodWp.js.map +0 -1
- package/dist/src-CkNQKFKr.js.map +0 -1
- package/dist/todo-edits-UOwgxGKu.js +0 -528
- package/dist/todo-edits-UOwgxGKu.js.map +0 -1
- package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
- package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
- package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
- package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
- package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
- package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
- package/dist/turn-operations-DrbJlpq9.js.map +0 -1
- package/dist/types-CWgENVLY.js.map +0 -1
- package/dist/xai-CazjStOK.js.map +0 -1
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
import { i as writeJsonFileAtomic, t as OWNER_ONLY } from "./atomic-write-Ijgf2Mhc.js";
|
|
2
|
+
import { n as JsonRpcRemoteError, t as JsonRpcConnectionClosedError } from "./json-rpc--HXQti1E.js";
|
|
3
|
+
import { $t as MachineErrorCode, en as isValidMachineName, tn as machineCredentialKey } from "./tool-formatters-IQFDrdrs.js";
|
|
4
|
+
import { n as displayHostUrl } from "./url-D8HCl65b.js";
|
|
5
|
+
import { t as createHostRegistry } from "./registry-D6ShBWJU.js";
|
|
6
|
+
import { ir as MachineLinkLostError } from "./chat-JPJJ8uu5.js";
|
|
7
|
+
import { m as writeCredentialEntry, r as readCredentialEntry } from "./credentials-JttEuRON.js";
|
|
8
|
+
import { f as HostIdentityError } from "./types-CH5XpIHw.js";
|
|
9
|
+
import { x as ZIDANE_VERSION } from "./settings-keys-Ckf29NeM.js";
|
|
10
|
+
import { t as keepHostConnected } from "./connection-loop-gdh22LTI.js";
|
|
11
|
+
import { n as connectWsClient, t as HostAuthError } from "./ws-client-N7NxzvQp.js";
|
|
12
|
+
import { createMachineExecutor, shareableRoot } from "./executor-Cx5-8yqi.js";
|
|
13
|
+
import { n as machineIdentity } from "./identity-CwfO8K-t.js";
|
|
14
|
+
import { closeSync, existsSync, linkSync, mkdirSync, openSync, readFileSync, realpathSync, renameSync, rmSync, statSync, utimesSync, writeSync } from "node:fs";
|
|
15
|
+
import { isAbsolute, join } from "node:path";
|
|
16
|
+
import { randomBytes } from "node:crypto";
|
|
17
|
+
import process from "node:process";
|
|
18
|
+
//#region src/ipc/machine/agent.ts
|
|
19
|
+
/** A registration the host refused for good (its name taken, another protocol). */
|
|
20
|
+
var MachineRegisterError = class extends Error {
|
|
21
|
+
forGood;
|
|
22
|
+
constructor(message, forGood) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.forGood = forGood;
|
|
25
|
+
this.name = "MachineRegisterError";
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
function normalizeRoots(roots, zidaneDataDir) {
|
|
29
|
+
if (roots.length === 0) throw new Error("Share at least one folder (--root).");
|
|
30
|
+
return roots.map((root) => {
|
|
31
|
+
const entry = typeof root === "string" ? { path: root } : root;
|
|
32
|
+
const real = shareableRoot(entry.path, zidaneDataDir);
|
|
33
|
+
if (!statSync(real).isDirectory()) throw new Error(`Root ${entry.path} is not a folder.`);
|
|
34
|
+
return {
|
|
35
|
+
path: real,
|
|
36
|
+
...entry.label ? { label: entry.label } : {}
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** The host id this machine pinned for `url` (the first host that answered there). */
|
|
41
|
+
function pinnedHosts(dataDir) {
|
|
42
|
+
const file = join(dataDir, "machine-hosts.json");
|
|
43
|
+
const read = () => {
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
46
|
+
} catch {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
get: (url) => read()[url],
|
|
52
|
+
set: (url, hostId) => writeJsonFileAtomic(file, {
|
|
53
|
+
...read(),
|
|
54
|
+
[url]: hostId
|
|
55
|
+
}, {
|
|
56
|
+
ensureDir: true,
|
|
57
|
+
mode: 384
|
|
58
|
+
})
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function startMachineAgent(options) {
|
|
62
|
+
if (!isValidMachineName(options.name)) throw new Error(`"${options.name}" is not a valid machine name: 1 to 64 letters, digits, ".", "-" or "_".`);
|
|
63
|
+
mkdirSync(options.dataDir, {
|
|
64
|
+
recursive: true,
|
|
65
|
+
mode: 448
|
|
66
|
+
});
|
|
67
|
+
const dataDir = realpathSync.native(options.dataDir);
|
|
68
|
+
const roots = normalizeRoots(options.roots, options.credentialsDataDir);
|
|
69
|
+
const machineId = machineIdentity(dataDir);
|
|
70
|
+
const pins = pinnedHosts(dataDir);
|
|
71
|
+
const url = options.hostUrl;
|
|
72
|
+
let client = null;
|
|
73
|
+
let status = "connecting";
|
|
74
|
+
const executor = createMachineExecutor({
|
|
75
|
+
roots,
|
|
76
|
+
dataDir,
|
|
77
|
+
...options.terminalGraceMs !== void 0 ? { terminalGraceMs: options.terminalGraceMs } : {},
|
|
78
|
+
...options.sandbox ? { sandbox: options.sandbox } : {},
|
|
79
|
+
...options.credentialsDataDir ? { credentialsDataDir: options.credentialsDataDir } : {},
|
|
80
|
+
notify: (method, params) => {
|
|
81
|
+
if (!client) return false;
|
|
82
|
+
try {
|
|
83
|
+
client.notify(method, params);
|
|
84
|
+
return true;
|
|
85
|
+
} catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const register = {
|
|
91
|
+
machineId,
|
|
92
|
+
name: options.name,
|
|
93
|
+
roots,
|
|
94
|
+
capabilities: {
|
|
95
|
+
shell: true,
|
|
96
|
+
terminals: typeof globalThis.Bun !== "undefined",
|
|
97
|
+
background: true,
|
|
98
|
+
worktrees: true,
|
|
99
|
+
stream: true,
|
|
100
|
+
sandboxed: executor.sandbox.on
|
|
101
|
+
},
|
|
102
|
+
version: options.appVersion ?? ZIDANE_VERSION,
|
|
103
|
+
protocolVersion: 1
|
|
104
|
+
};
|
|
105
|
+
const loop = keepHostConnected({
|
|
106
|
+
minDelayMs: options.minDelayMs ?? 1e3,
|
|
107
|
+
maxDelayMs: options.maxDelayMs ?? 3e4,
|
|
108
|
+
async connect({ signal, onClose }) {
|
|
109
|
+
const expectHostId = pins.get(url);
|
|
110
|
+
const connected = await connectWsClient({
|
|
111
|
+
url,
|
|
112
|
+
token: options.token,
|
|
113
|
+
signal,
|
|
114
|
+
onClose,
|
|
115
|
+
appVersion: register.version,
|
|
116
|
+
...options.heartbeatMs !== void 0 ? { heartbeatMs: options.heartbeatMs } : {},
|
|
117
|
+
...expectHostId ? { expectHostId } : {},
|
|
118
|
+
serve: {
|
|
119
|
+
request: (method, params) => executor.handle(method, params),
|
|
120
|
+
notification: (method, params) => void executor.handle(method, params).catch(() => void 0)
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
try {
|
|
124
|
+
await connected.request("machine.register", register);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
connected.close();
|
|
127
|
+
const code = err instanceof JsonRpcRemoteError ? err.code : void 0;
|
|
128
|
+
throw new MachineRegisterError(`${displayHostUrl(url)} refused this machine: ${err.message}`, code === MachineErrorCode.NameTaken || code === MachineErrorCode.VersionSkew || code === MachineErrorCode.IdBound);
|
|
129
|
+
}
|
|
130
|
+
if (!expectHostId && connected.hello.hostId) pins.set(url, connected.hello.hostId);
|
|
131
|
+
return connected;
|
|
132
|
+
},
|
|
133
|
+
classify: (err) => {
|
|
134
|
+
if (err instanceof HostIdentityError) return "identity";
|
|
135
|
+
if (err instanceof HostAuthError || err instanceof MachineRegisterError && err.forGood) return "auth";
|
|
136
|
+
return "retry";
|
|
137
|
+
},
|
|
138
|
+
update: (patch) => {
|
|
139
|
+
if (patch.client !== void 0) client = patch.client;
|
|
140
|
+
if (patch.status) {
|
|
141
|
+
status = patch.status;
|
|
142
|
+
options.onStatus?.(patch.status, patch.error);
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
onConnected: () => executor.linkUp(),
|
|
146
|
+
onDisconnected: () => executor.linkLost()
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
machineId,
|
|
150
|
+
status: () => status,
|
|
151
|
+
retry: () => loop.retry(),
|
|
152
|
+
async stop() {
|
|
153
|
+
loop.stop();
|
|
154
|
+
await executor.close();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/ipc/machine/reverse.ts
|
|
160
|
+
/** The server refused to lend itself (`allowAsMachine` off, a name taken here): for good. A busy server is retried. */
|
|
161
|
+
var AttachRefusedError = class extends Error {
|
|
162
|
+
constructor(message) {
|
|
163
|
+
super(message);
|
|
164
|
+
this.name = "AttachRefusedError";
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
function connectionOver(client) {
|
|
168
|
+
return {
|
|
169
|
+
async request(method, params) {
|
|
170
|
+
try {
|
|
171
|
+
return await client.request("machine.call", {
|
|
172
|
+
method,
|
|
173
|
+
params: params ?? {}
|
|
174
|
+
});
|
|
175
|
+
} catch (err) {
|
|
176
|
+
if (err instanceof JsonRpcConnectionClosedError) throw new MachineLinkLostError();
|
|
177
|
+
throw err instanceof JsonRpcRemoteError ? new Error(err.message) : err;
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
notify: (method, params) => client.notify("machine.call", {
|
|
181
|
+
method,
|
|
182
|
+
params: params ?? {}
|
|
183
|
+
}),
|
|
184
|
+
close: () => client.close()
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function startServerMachine(options) {
|
|
188
|
+
let attached;
|
|
189
|
+
const where = displayHostUrl(options.url);
|
|
190
|
+
const detach = () => {
|
|
191
|
+
attached?.closed();
|
|
192
|
+
attached = void 0;
|
|
193
|
+
};
|
|
194
|
+
const loop = keepHostConnected({
|
|
195
|
+
...options.minDelayMs !== void 0 ? { minDelayMs: options.minDelayMs } : {},
|
|
196
|
+
...options.maxDelayMs !== void 0 ? { maxDelayMs: options.maxDelayMs } : {},
|
|
197
|
+
async connect({ signal, onClose }) {
|
|
198
|
+
const client = await connectWsClient({
|
|
199
|
+
url: options.url,
|
|
200
|
+
token: options.token,
|
|
201
|
+
expectHostId: options.expectHostId,
|
|
202
|
+
signal,
|
|
203
|
+
onClose,
|
|
204
|
+
...options.appVersion ? { appVersion: options.appVersion } : {},
|
|
205
|
+
...options.heartbeatMs !== void 0 ? { heartbeatMs: options.heartbeatMs } : {}
|
|
206
|
+
});
|
|
207
|
+
const early = [];
|
|
208
|
+
let current;
|
|
209
|
+
client.onSignal((s) => {
|
|
210
|
+
if (s.kind !== "machine:notification") return;
|
|
211
|
+
if (current) current.notification(s.method, s.params);
|
|
212
|
+
else if (early.length < 1024) early.push({
|
|
213
|
+
method: s.method,
|
|
214
|
+
params: s.params
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
try {
|
|
218
|
+
const params = await client.request("machine.attach", { hostId: options.localHostId });
|
|
219
|
+
detach();
|
|
220
|
+
current = options.machines.attach(params, connectionOver(client));
|
|
221
|
+
attached = current;
|
|
222
|
+
for (const { method, params: p } of early.splice(0)) current.notification(method, p);
|
|
223
|
+
options.onState("connected", void 0, params.name);
|
|
224
|
+
} catch (err) {
|
|
225
|
+
client.close();
|
|
226
|
+
if (err instanceof JsonRpcConnectionClosedError || err instanceof JsonRpcRemoteError && err.code === MachineErrorCode.Busy) throw new Error(`${where} can't lend itself right now: ${err.message}`);
|
|
227
|
+
throw new AttachRefusedError(`${where} refused to be a machine: ${err.message}`);
|
|
228
|
+
}
|
|
229
|
+
return client;
|
|
230
|
+
},
|
|
231
|
+
classify: (err) => err instanceof HostIdentityError ? "identity" : err instanceof HostAuthError || err instanceof AttachRefusedError ? "auth" : "retry",
|
|
232
|
+
update: (patch) => {
|
|
233
|
+
if (!patch.status || patch.status === "connected") return;
|
|
234
|
+
options.onState(patch.status === "auth-refused" && patch.error?.includes("refused to be a machine") ? "refused" : patch.status, patch.error);
|
|
235
|
+
},
|
|
236
|
+
onDisconnected: detach
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
retry: () => loop.retry(),
|
|
240
|
+
stop() {
|
|
241
|
+
loop.stop();
|
|
242
|
+
detach();
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function processAlive(pid) {
|
|
247
|
+
try {
|
|
248
|
+
process.kill(pid, 0);
|
|
249
|
+
return true;
|
|
250
|
+
} catch (err) {
|
|
251
|
+
return err.code === "EPERM";
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function readRecord(file) {
|
|
255
|
+
try {
|
|
256
|
+
const mtimeMs = statSync(file).mtimeMs;
|
|
257
|
+
const raw = JSON.parse(readFileSync(file, "utf8"));
|
|
258
|
+
return {
|
|
259
|
+
mtimeMs,
|
|
260
|
+
...typeof raw.pid === "number" && typeof raw.nonce === "string" ? { record: {
|
|
261
|
+
pid: raw.pid,
|
|
262
|
+
nonce: raw.nonce
|
|
263
|
+
} } : {}
|
|
264
|
+
};
|
|
265
|
+
} catch (err) {
|
|
266
|
+
if (err.code === "ENOENT") return void 0;
|
|
267
|
+
try {
|
|
268
|
+
return { mtimeMs: statSync(file).mtimeMs };
|
|
269
|
+
} catch {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function createShareLock(file, options = {}) {
|
|
275
|
+
const pid = options.pid ?? process.pid;
|
|
276
|
+
const alive = options.alive ?? processAlive;
|
|
277
|
+
const now = options.now ?? Date.now;
|
|
278
|
+
const staleMs = options.staleMs ?? 3e4;
|
|
279
|
+
const nonce = randomBytes(12).toString("hex");
|
|
280
|
+
let holding = false;
|
|
281
|
+
const create = () => {
|
|
282
|
+
let fd;
|
|
283
|
+
try {
|
|
284
|
+
fd = openSync(file, "wx", 384);
|
|
285
|
+
} catch {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
try {
|
|
289
|
+
writeSync(fd, JSON.stringify({
|
|
290
|
+
pid,
|
|
291
|
+
nonce
|
|
292
|
+
}));
|
|
293
|
+
} finally {
|
|
294
|
+
closeSync(fd);
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
};
|
|
298
|
+
const ours = () => readRecord(file)?.record?.nonce === nonce;
|
|
299
|
+
const stale = (found) => now() - found.mtimeMs > staleMs || found.record !== void 0 && !alive(found.record.pid);
|
|
300
|
+
/** Move a stale lock aside; `true` when the record moved is the one judged stale. */
|
|
301
|
+
const evict = (judged) => {
|
|
302
|
+
const aside = `${file}.${nonce}.stale`;
|
|
303
|
+
try {
|
|
304
|
+
renameSync(file, aside);
|
|
305
|
+
} catch {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
const moved = readRecord(aside);
|
|
309
|
+
const same = moved?.record?.nonce === judged.record?.nonce && moved?.mtimeMs === judged.mtimeMs;
|
|
310
|
+
if (!same) try {
|
|
311
|
+
linkSync(aside, file);
|
|
312
|
+
} catch {}
|
|
313
|
+
rmSync(aside, { force: true });
|
|
314
|
+
return same;
|
|
315
|
+
};
|
|
316
|
+
return {
|
|
317
|
+
acquire() {
|
|
318
|
+
if (holding) {
|
|
319
|
+
if (ours()) {
|
|
320
|
+
try {
|
|
321
|
+
const at = new Date(now());
|
|
322
|
+
utimesSync(file, at, at);
|
|
323
|
+
} catch {}
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
holding = false;
|
|
327
|
+
}
|
|
328
|
+
if (create()) {
|
|
329
|
+
holding = true;
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
const found = readRecord(file);
|
|
333
|
+
if (found && !stale(found)) return false;
|
|
334
|
+
if (found && !evict(found)) return false;
|
|
335
|
+
holding = create();
|
|
336
|
+
return holding;
|
|
337
|
+
},
|
|
338
|
+
held: () => holding,
|
|
339
|
+
release() {
|
|
340
|
+
const mine = holding && ours();
|
|
341
|
+
if (mine) rmSync(file, { force: true });
|
|
342
|
+
holding = false;
|
|
343
|
+
return mine;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
//#endregion
|
|
348
|
+
//#region src/ipc/machine/links.ts
|
|
349
|
+
const POLL_MS = 2e3;
|
|
350
|
+
const CONFIG_FILE = "machine-links.json";
|
|
351
|
+
const STATUS_FILE = "machine-links-status.json";
|
|
352
|
+
const LOCK_FILE = "machine-links.lock";
|
|
353
|
+
const MAX_ROOTS = 32;
|
|
354
|
+
function readJson(file, fallback) {
|
|
355
|
+
try {
|
|
356
|
+
return existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : fallback;
|
|
357
|
+
} catch {
|
|
358
|
+
return fallback;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function readConfig(file) {
|
|
362
|
+
const raw = readJson(file, {});
|
|
363
|
+
return {
|
|
364
|
+
version: 1,
|
|
365
|
+
shares: Array.isArray(raw.shares) ? raw.shares.filter((s) => !!s && typeof s.hostId === "string" && typeof s.name === "string" && Array.isArray(s.roots) && s.roots.every((r) => typeof r === "string")) : [],
|
|
366
|
+
uses: Array.isArray(raw.uses) ? raw.uses.filter((u) => typeof u === "string") : []
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* A share's name and roots, as a client sent them: every root absolute,
|
|
371
|
+
* existing, and not (by its real path) zidane's data dir, inside it, or a
|
|
372
|
+
* credentials folder (`./executor`'s `shareableRoot`).
|
|
373
|
+
*/
|
|
374
|
+
function checkShareInput(input, zidaneDataDir) {
|
|
375
|
+
if (!isValidMachineName(input.name)) throw new Error(`"${input.name}" is not a valid machine name: 1 to 64 letters, digits, ".", "-" or "_".`);
|
|
376
|
+
if (!Array.isArray(input.roots) || input.roots.length === 0) throw new Error("Share at least one folder.");
|
|
377
|
+
if (input.roots.length > MAX_ROOTS) throw new Error(`Share at most ${MAX_ROOTS} folders.`);
|
|
378
|
+
for (const root of input.roots) {
|
|
379
|
+
if (typeof root !== "string" || !isAbsolute(root)) throw new Error(`${String(root)} is not an absolute folder path.`);
|
|
380
|
+
shareableRoot(root, zidaneDataDir);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function startMachineLinks(options) {
|
|
384
|
+
const { dataDir, machines } = options;
|
|
385
|
+
const configFile = join(dataDir, CONFIG_FILE);
|
|
386
|
+
const statusFile = join(dataDir, STATUS_FILE);
|
|
387
|
+
const lock = createShareLock(join(dataDir, LOCK_FILE));
|
|
388
|
+
const hosts = createHostRegistry({
|
|
389
|
+
dataDir,
|
|
390
|
+
probe: async () => ({
|
|
391
|
+
ok: false,
|
|
392
|
+
error: "unreachable",
|
|
393
|
+
message: "not probed here"
|
|
394
|
+
})
|
|
395
|
+
});
|
|
396
|
+
const instance = `${(options.hostId ?? "local").slice(0, 40)}-${randomBytes(4).toString("hex")}`;
|
|
397
|
+
const pacing = {
|
|
398
|
+
...options.minDelayMs !== void 0 ? { minDelayMs: options.minDelayMs } : {},
|
|
399
|
+
...options.maxDelayMs !== void 0 ? { maxDelayMs: options.maxDelayMs } : {},
|
|
400
|
+
...options.heartbeatMs !== void 0 ? { heartbeatMs: options.heartbeatMs } : {}
|
|
401
|
+
};
|
|
402
|
+
const shares = /* @__PURE__ */ new Map();
|
|
403
|
+
const uses = /* @__PURE__ */ new Map();
|
|
404
|
+
let holder = false;
|
|
405
|
+
let closed = false;
|
|
406
|
+
let lastPublished = "";
|
|
407
|
+
const ownStatus = () => ({
|
|
408
|
+
shares: [...shares.values()].map((s) => s.status),
|
|
409
|
+
uses: [...uses.values()].map((u) => u.status)
|
|
410
|
+
});
|
|
411
|
+
/** Shares as the holder reports them (another process may run them). */
|
|
412
|
+
const status = () => {
|
|
413
|
+
const own = ownStatus();
|
|
414
|
+
if (holder) return own;
|
|
415
|
+
const config = readConfig(configFile);
|
|
416
|
+
const published = readJson(statusFile, {});
|
|
417
|
+
const known = new Map((published.shares ?? []).map((s) => [s.hostId, s]));
|
|
418
|
+
return {
|
|
419
|
+
shares: config.shares.map((s) => known.get(s.hostId) ?? {
|
|
420
|
+
hostId: s.hostId,
|
|
421
|
+
name: s.name,
|
|
422
|
+
roots: s.roots,
|
|
423
|
+
state: "connecting",
|
|
424
|
+
detail: "waiting for the zidane process that shares this computer"
|
|
425
|
+
}),
|
|
426
|
+
uses: own.uses
|
|
427
|
+
};
|
|
428
|
+
};
|
|
429
|
+
const publish = () => {
|
|
430
|
+
if (closed) return;
|
|
431
|
+
const snapshot = status();
|
|
432
|
+
const text = JSON.stringify(snapshot);
|
|
433
|
+
if (holder) try {
|
|
434
|
+
writeJsonFileAtomic(statusFile, { shares: snapshot.shares }, OWNER_ONLY);
|
|
435
|
+
} catch {}
|
|
436
|
+
if (text === lastPublished) return;
|
|
437
|
+
lastPublished = text;
|
|
438
|
+
options.onChange(snapshot);
|
|
439
|
+
};
|
|
440
|
+
const entry = (hostId) => {
|
|
441
|
+
const found = hosts.get(hostId);
|
|
442
|
+
if (!found) throw new Error(`No saved server "${hostId}": add it on the Hosts page first.`);
|
|
443
|
+
return found;
|
|
444
|
+
};
|
|
445
|
+
function runShare(config) {
|
|
446
|
+
const status = {
|
|
447
|
+
hostId: config.hostId,
|
|
448
|
+
name: config.name,
|
|
449
|
+
roots: config.roots,
|
|
450
|
+
state: "connecting"
|
|
451
|
+
};
|
|
452
|
+
const share = {
|
|
453
|
+
config,
|
|
454
|
+
status
|
|
455
|
+
};
|
|
456
|
+
shares.set(config.hostId, share);
|
|
457
|
+
const set = (state, detail) => {
|
|
458
|
+
share.status = {
|
|
459
|
+
...status,
|
|
460
|
+
state,
|
|
461
|
+
...detail && state !== "connected" ? { detail } : {}
|
|
462
|
+
};
|
|
463
|
+
publish();
|
|
464
|
+
};
|
|
465
|
+
try {
|
|
466
|
+
const server = entry(config.hostId);
|
|
467
|
+
const cred = readCredentialEntry(dataDir, machineCredentialKey(config.hostId));
|
|
468
|
+
const token = cred?.kind === "apikey" ? cred.value : void 0;
|
|
469
|
+
if (!token) throw new Error(`No machine token saved for ${server.name}.`);
|
|
470
|
+
share.agent = startMachineAgent({
|
|
471
|
+
hostUrl: server.url,
|
|
472
|
+
token,
|
|
473
|
+
name: config.name,
|
|
474
|
+
roots: config.roots,
|
|
475
|
+
dataDir: join(dataDir, "machine"),
|
|
476
|
+
credentialsDataDir: dataDir,
|
|
477
|
+
...options.settings ? { sandbox: options.settings() } : {},
|
|
478
|
+
...pacing,
|
|
479
|
+
...options.appVersion ? { appVersion: options.appVersion } : {},
|
|
480
|
+
onStatus: (state, detail) => set(state, detail)
|
|
481
|
+
});
|
|
482
|
+
} catch (err) {
|
|
483
|
+
set("refused", err.message);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function runUse(hostId) {
|
|
487
|
+
const use = { status: {
|
|
488
|
+
hostId,
|
|
489
|
+
state: "connecting"
|
|
490
|
+
} };
|
|
491
|
+
uses.set(hostId, use);
|
|
492
|
+
const set = (state, detail, machineName) => {
|
|
493
|
+
use.status = {
|
|
494
|
+
hostId,
|
|
495
|
+
state,
|
|
496
|
+
...detail && state !== "connected" ? { detail } : {},
|
|
497
|
+
...machineName ?? use.status.machineName ? { machineName: machineName ?? use.status.machineName } : {}
|
|
498
|
+
};
|
|
499
|
+
publish();
|
|
500
|
+
};
|
|
501
|
+
try {
|
|
502
|
+
const server = entry(hostId);
|
|
503
|
+
const token = hosts.token(hostId);
|
|
504
|
+
if (!token) throw new Error(`No token saved for ${server.name}: add it again.`);
|
|
505
|
+
use.link = startServerMachine({
|
|
506
|
+
machines,
|
|
507
|
+
url: server.url,
|
|
508
|
+
token,
|
|
509
|
+
expectHostId: hostId,
|
|
510
|
+
localHostId: instance,
|
|
511
|
+
...pacing,
|
|
512
|
+
...options.appVersion ? { appVersion: options.appVersion } : {},
|
|
513
|
+
onState: set
|
|
514
|
+
});
|
|
515
|
+
} catch (err) {
|
|
516
|
+
set("refused", err.message);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
const stopShare = async (hostId) => {
|
|
520
|
+
const share = shares.get(hostId);
|
|
521
|
+
shares.delete(hostId);
|
|
522
|
+
await share?.agent?.stop();
|
|
523
|
+
};
|
|
524
|
+
/** Bring the running links in line with the saved config. */
|
|
525
|
+
function reconcile() {
|
|
526
|
+
if (closed) return;
|
|
527
|
+
const config = readConfig(configFile);
|
|
528
|
+
holder = lock.acquire();
|
|
529
|
+
if (!holder) for (const hostId of [...shares.keys()]) stopShare(hostId);
|
|
530
|
+
else {
|
|
531
|
+
const wanted = new Map(config.shares.map((s) => [s.hostId, s]));
|
|
532
|
+
for (const [hostId, share] of shares) {
|
|
533
|
+
const want = wanted.get(hostId);
|
|
534
|
+
if (!want || JSON.stringify(want) !== JSON.stringify(share.config)) stopShare(hostId);
|
|
535
|
+
}
|
|
536
|
+
for (const share of config.shares) if (!shares.has(share.hostId)) runShare(share);
|
|
537
|
+
}
|
|
538
|
+
const wantedUses = new Set(config.uses);
|
|
539
|
+
for (const [hostId, use] of uses) if (!wantedUses.has(hostId)) {
|
|
540
|
+
use.link?.stop();
|
|
541
|
+
uses.delete(hostId);
|
|
542
|
+
}
|
|
543
|
+
for (const hostId of config.uses) if (!uses.has(hostId)) runUse(hostId);
|
|
544
|
+
publish();
|
|
545
|
+
}
|
|
546
|
+
const writeConfig = (mutate) => {
|
|
547
|
+
const config = readConfig(configFile);
|
|
548
|
+
mutate(config);
|
|
549
|
+
writeJsonFileAtomic(configFile, config, OWNER_ONLY);
|
|
550
|
+
reconcile();
|
|
551
|
+
return status();
|
|
552
|
+
};
|
|
553
|
+
reconcile();
|
|
554
|
+
const timer = setInterval(reconcile, options.pollMs ?? POLL_MS);
|
|
555
|
+
timer.unref?.();
|
|
556
|
+
return {
|
|
557
|
+
status,
|
|
558
|
+
startShare(input) {
|
|
559
|
+
checkShareInput(input, dataDir);
|
|
560
|
+
const server = entry(input.hostId);
|
|
561
|
+
const token = input.token?.trim();
|
|
562
|
+
if (token) writeCredentialEntry(dataDir, machineCredentialKey(input.hostId), {
|
|
563
|
+
kind: "apikey",
|
|
564
|
+
value: token
|
|
565
|
+
});
|
|
566
|
+
else if (readCredentialEntry(dataDir, machineCredentialKey(input.hostId))?.kind !== "apikey") throw new Error(`No machine token for ${server.name}: create one there (zidane server token create --scope machine) or let this window create it.`);
|
|
567
|
+
return writeConfig((config) => {
|
|
568
|
+
config.shares = [...config.shares.filter((s) => s.hostId !== input.hostId), {
|
|
569
|
+
hostId: input.hostId,
|
|
570
|
+
name: input.name,
|
|
571
|
+
roots: [...input.roots]
|
|
572
|
+
}];
|
|
573
|
+
});
|
|
574
|
+
},
|
|
575
|
+
stopShare(hostId) {
|
|
576
|
+
return writeConfig((config) => {
|
|
577
|
+
config.shares = config.shares.filter((s) => s.hostId !== hostId);
|
|
578
|
+
});
|
|
579
|
+
},
|
|
580
|
+
setUse(hostId, enabled) {
|
|
581
|
+
if (enabled) {
|
|
582
|
+
const server = entry(hostId);
|
|
583
|
+
if (!hosts.token(hostId)) throw new Error(`No token saved for ${server.name}: add it again.`);
|
|
584
|
+
}
|
|
585
|
+
return writeConfig((config) => {
|
|
586
|
+
config.uses = enabled ? [.../* @__PURE__ */ new Set([...config.uses, hostId])] : config.uses.filter((u) => u !== hostId);
|
|
587
|
+
});
|
|
588
|
+
},
|
|
589
|
+
async close() {
|
|
590
|
+
if (closed) return;
|
|
591
|
+
closed = true;
|
|
592
|
+
clearInterval(timer);
|
|
593
|
+
for (const use of uses.values()) use.link?.stop();
|
|
594
|
+
uses.clear();
|
|
595
|
+
await Promise.all([...shares.keys()].map(stopShare));
|
|
596
|
+
if (lock.release()) rmSync(statusFile, { force: true });
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
//#endregion
|
|
601
|
+
export { startMachineLinks };
|
|
602
|
+
|
|
603
|
+
//# sourceMappingURL=links-j8rED1sR.js.map
|