farming-code 2.2.29 → 2.2.32
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/README.md +25 -66
- package/README.zh_cn.md +15 -66
- package/THIRD_PARTY_NOTICES.md +7 -0
- package/backend/acp/{client-services.js → client-services.cjs} +132 -134
- package/backend/acp/packaged-claude-acp.cjs +37 -0
- package/backend/acp/packaged-codex-acp.cjs +37 -0
- package/backend/acp/patch-decisions.cjs +182 -0
- package/backend/acp/permission-security.cjs +131 -0
- package/backend/{acp-checkpoint-store.js → acp-checkpoint-store.cjs} +90 -59
- package/backend/{acp-runtime.js → acp-runtime.cjs} +1219 -1125
- package/backend/acp-session-state.cjs +622 -0
- package/backend/acp-transcript.cjs +525 -0
- package/backend/agent-env.cjs +257 -0
- package/backend/agent-extension-discovery.cjs +452 -0
- package/backend/agent-extension-inventory.cjs +116 -0
- package/backend/agent-json-stream.cjs +283 -0
- package/backend/agent-lifecycle-journal.cjs +185 -0
- package/backend/{agent-manager.js → agent-manager.cjs} +3116 -4275
- package/backend/agent-order-transaction.cjs +85 -0
- package/backend/agent-order.cjs +159 -0
- package/backend/agent-provider-session.cjs +98 -0
- package/backend/agent-runtime-binding.cjs +179 -0
- package/backend/agent-session-history.cjs +1022 -0
- package/backend/agent-session-inventory.cjs +291 -0
- package/backend/async-cache.cjs +104 -0
- package/backend/atomic-json-store.cjs +67 -0
- package/backend/auth.cjs +261 -0
- package/backend/authoritative-inventory-cache.cjs +383 -0
- package/backend/business-health.cjs +68 -0
- package/backend/chat-runtime.cjs +50 -0
- package/backend/claude-settings.cjs +132 -0
- package/backend/cli-agents.cjs +435 -0
- package/backend/codex-context-window.cjs +196 -0
- package/backend/codex-models.cjs +228 -0
- package/backend/codex-session-archive.cjs +82 -0
- package/backend/codex-session-history.cjs +590 -0
- package/backend/{codex-terminal-profile.js → codex-terminal-profile.cjs} +149 -155
- package/backend/codex-transcript-sanitizer.cjs +130 -0
- package/backend/codex-transcript.cjs +2107 -0
- package/backend/command-runner-child.cjs +105 -0
- package/backend/config-manager.cjs +1263 -0
- package/backend/control-api.cjs +439 -0
- package/backend/data/LICENSE.cua +21 -0
- package/backend/executable-discovery.cjs +204 -0
- package/backend/farming-agent-bootstrap.cjs +81 -0
- package/backend/farming-agent-bootstrap.zh_cn.md +6 -2
- package/backend/{farming-app-cli.js → farming-app-cli.cjs} +441 -493
- package/backend/farming-cli.cjs +414 -0
- package/backend/farming-net-pass.cjs +319 -0
- package/backend/farming-net-registry.cjs +123 -0
- package/backend/farming-net-server.cjs +309 -0
- package/backend/farming-session-store.cjs +651 -0
- package/backend/git-worktree-info.cjs +181 -0
- package/backend/haiku-token.cjs +828 -0
- package/backend/index-html.cjs +96 -0
- package/backend/input-parts.cjs +68 -0
- package/backend/input-routing.cjs +40 -0
- package/backend/{local-session-engine.js → local-session-engine.cjs} +276 -282
- package/backend/main-agent-skills.cjs +309 -0
- package/backend/main-page-session.cjs +132 -0
- package/backend/native-pty-controller-generation.cjs +139 -0
- package/backend/{native-pty-host-client.js → native-pty-host-client.cjs} +338 -346
- package/backend/native-pty-host-identity.cjs +125 -0
- package/backend/native-pty-host-path.cjs +68 -0
- package/backend/{native-pty-host.js → native-pty-host.cjs} +480 -569
- package/backend/native-session-engine.cjs +296 -0
- package/backend/network.cjs +57 -0
- package/backend/npm-update-helper.cjs +399 -0
- package/backend/packaged-node-pty.cjs +120 -0
- package/backend/preview-session-manager.cjs +89 -0
- package/backend/provider-adapters.cjs +492 -0
- package/backend/provider-home-configuration.cjs +211 -0
- package/backend/provider-session-id.cjs +79 -0
- package/backend/provider-session-service.cjs +333 -0
- package/backend/qr-share-tickets.cjs +119 -0
- package/backend/resource-broadcast-protocol.cjs +50 -0
- package/backend/review-diff-router.cjs +202 -0
- package/backend/review-diff-service.cjs +1267 -0
- package/backend/review-session-router.cjs +93 -0
- package/backend/review-session-service.cjs +470 -0
- package/backend/review-session-store.cjs +161 -0
- package/backend/review-state-router.cjs +132 -0
- package/backend/review-state-store.cjs +299 -0
- package/backend/run-history-store.cjs +97 -0
- package/backend/runtime-dependency-manager.cjs +893 -0
- package/backend/runtime-executable-invocation.cjs +37 -0
- package/backend/runtime-observation.cjs +96 -0
- package/backend/server-process-identity.cjs +70 -0
- package/backend/server.cjs +3356 -0
- package/backend/session-engine-bridge.cjs +144 -0
- package/backend/session-engine-router.cjs +105 -0
- package/backend/session-engine.cjs +64 -0
- package/backend/session-stream-protocol.cjs +181 -0
- package/backend/shell-busy-integration.cjs +442 -0
- package/backend/slash-command-discovery.cjs +423 -0
- package/backend/storage-layout.cjs +263 -0
- package/backend/system-monitor.cjs +96 -0
- package/backend/terminal-attach-checkpoint.cjs +73 -0
- package/backend/terminal-exit-quiescence.cjs +57 -0
- package/backend/{terminal-reducer-flow-control.js → terminal-reducer-flow-control.cjs} +45 -22
- package/backend/terminal-runtime-cleanup.cjs +99 -0
- package/backend/{terminal-screen-state.js → terminal-screen-state.cjs} +100 -108
- package/backend/{terminal-screen-worker-pool.js → terminal-screen-worker-pool.cjs} +89 -79
- package/backend/{terminal-screen-worker-thread.js → terminal-screen-worker-thread.cjs} +64 -65
- package/backend/terminal-screen-worker.cjs +352 -0
- package/backend/terminal-state-serialization.cjs +147 -0
- package/backend/{terminal-status.js → terminal-status.cjs} +137 -187
- package/backend/theme-manager.cjs +185 -0
- package/backend/update-service.cjs +675 -0
- package/backend/usage-forecast.cjs +95 -0
- package/backend/{usage-history-client.js → usage-history-client.cjs} +144 -94
- package/backend/usage-history-smoke.cjs +85 -0
- package/backend/usage-history-worker.cjs +60 -0
- package/backend/{usage-monitor.js → usage-monitor.cjs} +363 -390
- package/backend/workspace-directory.cjs +239 -0
- package/backend/workspace-discovery.cjs +271 -0
- package/backend/{workspace-file-router.js → workspace-file-router.cjs} +213 -282
- package/backend/{workspace-file-service.js → workspace-file-service.cjs} +1139 -1318
- package/backend/workspace-root-registry.cjs +192 -0
- package/bin/farming +1 -1
- package/config/farming.deploy.env.example +1 -1
- package/config/farming.install.env.example +1 -1
- package/dist/acp/codex-acp-1.1.4.mjs +405 -8
- package/dist/assets/App-BCkdpWB6.css +1 -0
- package/dist/assets/App-CRjKpaGp.js +697 -0
- package/dist/assets/CodeSelect-Ci8sKZPU.js +1 -0
- package/dist/assets/CodeSelect-T2eNzrOc.css +1 -0
- package/dist/assets/{FileEditorMarkdownPreview-Cs9cLv8a.js → FileEditorMarkdownPreview-V06QHlAg.js} +55 -55
- package/dist/assets/FileEditorPane-BX-Wjg9U.js +2 -0
- package/dist/assets/IconGlyphs-YhV7tqd4.js +1 -0
- package/dist/assets/ProjectFilesSection-BDT2_r0o.js +12 -0
- package/dist/assets/ReviewPage-BqAs5sG1.js +3 -0
- package/dist/assets/code-dark-B7eM_9G9.css +1 -0
- package/dist/assets/{cssMode-Bdg5RpcJ.js → cssMode-ADdAlxTO.js} +1 -1
- package/dist/assets/{editor.api2-D74ufkbr.js → editor.api2-BFLAr0YF.js} +162 -162
- package/dist/assets/file-icons-BpeqWkIB.js +1 -0
- package/dist/assets/{freemarker2-DfMDJfnE.js → freemarker2-C90q5jrp.js} +1 -1
- package/dist/assets/{handlebars-BEdPtzMT.js → handlebars-BwUQcEDq.js} +1 -1
- package/dist/assets/{html-B1fPb1QD.js → html-1s3uPKfh.js} +1 -1
- package/dist/assets/{htmlMode-CY2ZjHxH.js → htmlMode-xtKD99de.js} +1 -1
- package/dist/assets/{index-CQNaZc3l.js → index-C8MchCem.js} +3 -3
- package/dist/assets/{javascript-BV2OsWA0.js → javascript-Ph7ijyny.js} +1 -1
- package/dist/assets/{jsonMode-zd07aeuX.js → jsonMode-D-jGAnFH.js} +1 -1
- package/dist/assets/linkComputer-CbGyI_qx.js +1 -0
- package/dist/assets/{liquid-BParI24X.js → liquid-0IamE_cI.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-BzredkoV.js → lspLanguageFeatures-BxnQunWF.js} +1 -1
- package/dist/assets/main-CLKXa6hf.css +1 -0
- package/dist/assets/{mdx-vGzUJN98.js → mdx-DdNmfivn.js} +1 -1
- package/dist/assets/{monaco.contribution-BmaeBQEc.js → monaco.contribution-B43jsUs1.js} +2 -2
- package/dist/assets/{python-CUwdLgsI.js → python-IAt4X5TS.js} +1 -1
- package/dist/assets/{razor-BScebUxU.js → razor-DRkFYW0S.js} +1 -1
- package/dist/assets/review-C8-oPKXk.css +1 -0
- package/dist/assets/{tsMode-DzUAibXK.js → tsMode-_d_4U2gf.js} +1 -1
- package/dist/assets/{typescript-D9EOeM7N.js → typescript-C7zcMq9l.js} +1 -1
- package/dist/assets/{workers-DAiomYZM.js → workers-D0nOyJzf.js} +1 -1
- package/dist/assets/workspace-editor-model-DND_Y-Bj.js +1 -0
- package/dist/assets/workspace-editor-monaco-BPWhgcIB.js +4 -0
- package/dist/assets/workspace-editor-monaco-N641qPjX.js +1 -0
- package/dist/assets/workspace-view-state-k1bTlJ_Z.js +13 -0
- package/dist/assets/{xml-wWl1dhkQ.js → xml-BR-HvxT8.js} +1 -1
- package/dist/assets/{yaml-Dc2WDaOZ.js → yaml-YtFQwh4q.js} +1 -1
- package/dist/index.html +2 -1
- package/extensions/browser/backend/agent-browser-runtime.cjs +1040 -0
- package/extensions/browser/backend/agent-capability.cjs +85 -0
- package/extensions/browser/backend/browser-mcp-server.cjs +655 -0
- package/extensions/browser/backend/browser-resource-manager.cjs +1486 -0
- package/extensions/browser/backend/browser-resource-store.cjs +228 -0
- package/extensions/browser/backend/browser-router.cjs +203 -0
- package/extensions/browser/backend/executable-discovery.cjs +248 -0
- package/extensions/browser/backend/farming-browser-client.cjs +116 -0
- package/extensions/browser/backend/index.cjs +32 -0
- package/extensions/browser/backend/managed-chromium-installer.cjs +833 -0
- package/extensions/browser/bin/farming-browser +16 -7
- package/extensions/computer/backend/agent-capability.cjs +72 -0
- package/extensions/computer/backend/computer-constants.cjs +59 -0
- package/extensions/computer/backend/computer-mcp-server.cjs +182 -0
- package/extensions/computer/backend/computer-resource-manager.cjs +1219 -0
- package/extensions/computer/backend/computer-resource-store.cjs +190 -0
- package/extensions/computer/backend/computer-router.cjs +257 -0
- package/extensions/computer/backend/cua-tools.json +3067 -0
- package/extensions/computer/backend/farming-computer-client.cjs +84 -0
- package/extensions/computer/backend/index.cjs +35 -0
- package/extensions/computer/backend/isolated-browser-provider.cjs +157 -0
- package/extensions/computer/bin/farming-computer +131 -0
- package/frontend/farming-net/app.js +255 -262
- package/frontend/ghostty-loader.js +24 -20
- package/frontend/reading-anchor.js +210 -193
- package/frontend/runtime-paths.js +24 -26
- package/frontend/session-bridge.js +90 -111
- package/frontend/session-modal-bridge.js +184 -302
- package/frontend/skin-bridge.js +20 -23
- package/frontend/skins/crt/app.js +7686 -7901
- package/frontend/skins/crt/effects.js +7 -6
- package/frontend/skins/crt/index.html +6 -6
- package/frontend/skins/crt/styles/markdown.css +4 -4
- package/frontend/terminal-bridge.js +174 -181
- package/frontend/terminal-replay.js +320 -345
- package/frontend/theme-loader.js +55 -71
- package/index.html +1 -0
- package/package.json +64 -37
- package/shared/backend-connection-status.js +38 -69
- package/shared/browser-protocol.js +235 -110
- package/shared/websocket-liveness.js +40 -0
- package/backend/acp/packaged-claude-acp.js +0 -13
- package/backend/acp/packaged-codex-acp.js +0 -13
- package/backend/acp/patch-decisions.js +0 -153
- package/backend/acp/permission-security.js +0 -108
- package/backend/acp-session-state.js +0 -644
- package/backend/acp-transcript.js +0 -512
- package/backend/agent-env.js +0 -250
- package/backend/agent-json-stream.js +0 -268
- package/backend/agent-lifecycle-journal.js +0 -133
- package/backend/agent-memory-report.js +0 -583
- package/backend/agent-order.js +0 -166
- package/backend/agent-provider-session.js +0 -76
- package/backend/agent-runtime-binding.js +0 -174
- package/backend/agent-session-history.js +0 -953
- package/backend/async-cache.js +0 -94
- package/backend/atomic-json-store.js +0 -37
- package/backend/auth.js +0 -251
- package/backend/bundle-update-helper.js +0 -113
- package/backend/chat-runtime.js +0 -28
- package/backend/claude-settings.js +0 -121
- package/backend/cli-agents.js +0 -486
- package/backend/codex-context-window.js +0 -189
- package/backend/codex-models.js +0 -226
- package/backend/codex-rollout-follower.js +0 -326
- package/backend/codex-session-archive.js +0 -65
- package/backend/codex-session-history.js +0 -647
- package/backend/codex-transcript-sanitizer.js +0 -115
- package/backend/codex-transcript.js +0 -2564
- package/backend/command-runner-child.js +0 -67
- package/backend/config-manager.js +0 -1133
- package/backend/control-api.js +0 -455
- package/backend/executable-discovery.js +0 -216
- package/backend/farming-agent-bootstrap.js +0 -49
- package/backend/farming-cli.js +0 -457
- package/backend/farming-net-pass.js +0 -285
- package/backend/farming-net-registry.js +0 -112
- package/backend/farming-net-server.js +0 -298
- package/backend/farming-session-store.js +0 -677
- package/backend/git-worktree-info.js +0 -181
- package/backend/haiku-token.js +0 -772
- package/backend/index-html.js +0 -62
- package/backend/input-parts.js +0 -54
- package/backend/input-routing.js +0 -24
- package/backend/json-cli-runtime.js +0 -275
- package/backend/main-agent-skills.js +0 -305
- package/backend/main-page-session.js +0 -122
- package/backend/native-pty-controller-generation.js +0 -106
- package/backend/native-pty-host-identity.js +0 -86
- package/backend/native-pty-host-path.js +0 -42
- package/backend/native-session-engine.js +0 -268
- package/backend/network.js +0 -23
- package/backend/npm-update-helper.js +0 -374
- package/backend/packaged-node-pty.js +0 -99
- package/backend/preview-session-manager.js +0 -68
- package/backend/provider-adapters.js +0 -399
- package/backend/provider-session-id.js +0 -47
- package/backend/provider-session-service.js +0 -345
- package/backend/qr-share-tickets.js +0 -100
- package/backend/review-diff-router.js +0 -180
- package/backend/review-diff-service.js +0 -1270
- package/backend/review-session-router.js +0 -74
- package/backend/review-session-service.js +0 -446
- package/backend/review-session-store.js +0 -151
- package/backend/review-state-router.js +0 -116
- package/backend/review-state-store.js +0 -286
- package/backend/run-history-store.js +0 -67
- package/backend/runtime-dependency-manager.js +0 -759
- package/backend/runtime-executable-invocation.js +0 -20
- package/backend/runtime-observation.js +0 -81
- package/backend/server-process-identity.js +0 -47
- package/backend/server.js +0 -3267
- package/backend/session-engine-bridge.js +0 -129
- package/backend/session-engine-router.js +0 -66
- package/backend/session-engine.js +0 -39
- package/backend/session-stream-protocol.js +0 -185
- package/backend/shell-busy-integration.js +0 -472
- package/backend/slash-command-discovery.js +0 -433
- package/backend/storage-layout.js +0 -190
- package/backend/system-monitor.js +0 -77
- package/backend/terminal-attach-checkpoint.js +0 -74
- package/backend/terminal-exit-quiescence.js +0 -39
- package/backend/terminal-runtime-cleanup.js +0 -80
- package/backend/terminal-screen-worker.js +0 -337
- package/backend/terminal-state-serialization.js +0 -127
- package/backend/theme-manager.js +0 -163
- package/backend/update-service.js +0 -1545
- package/backend/usage-forecast.js +0 -86
- package/backend/usage-history-scanner.ts +0 -2718
- package/backend/usage-history-smoke.js +0 -64
- package/backend/usage-history-worker.js +0 -34
- package/backend/workspace-directory.js +0 -232
- package/backend/workspace-discovery.js +0 -311
- package/backend/workspace-root-registry.js +0 -166
- package/dist/assets/App-BKNUILuL.css +0 -1
- package/dist/assets/App-Ex2oVVXO.js +0 -693
- package/dist/assets/FileEditorPane-CNtuGjQ3.js +0 -2
- package/dist/assets/IconGlyphs-BClgag6E.js +0 -1
- package/dist/assets/ProjectFilesSection-Cf2BEcAN.js +0 -12
- package/dist/assets/ReviewPage-BRuxFaH5.js +0 -3
- package/dist/assets/code-dark-BEZTQwYZ.css +0 -1
- package/dist/assets/file-icons-BOlcJ0ZF.js +0 -1
- package/dist/assets/main-DK9Sy7-c.css +0 -1
- package/dist/assets/review-BcnwQtJv.css +0 -1
- package/dist/assets/workspace-editor-model-CSGCl21x.js +0 -1
- package/dist/assets/workspace-editor-monaco-CJNwbpCy.js +0 -4
- package/dist/assets/workspace-editor-monaco-CO9w8YV0.js +0 -1
- package/dist/assets/workspace-view-state-BjKPYp0E.js +0 -7
- package/extensions/browser/backend/agent-browser-runtime.js +0 -1041
- package/extensions/browser/backend/agent-capability.js +0 -55
- package/extensions/browser/backend/browser-mcp-server.js +0 -621
- package/extensions/browser/backend/browser-resource-manager.js +0 -1309
- package/extensions/browser/backend/browser-resource-store.js +0 -190
- package/extensions/browser/backend/browser-router.js +0 -133
- package/extensions/browser/backend/executable-discovery.js +0 -224
- package/extensions/browser/backend/farming-browser-client.js +0 -83
- package/extensions/browser/backend/index.js +0 -7
- package/extensions/browser/frontend/BrowserSidebarPortals.tsx +0 -360
- package/extensions/browser/frontend/BrowserViewer.tsx +0 -500
- package/extensions/browser/frontend/browser-resource-state.ts +0 -60
- package/extensions/browser/frontend/browser.css +0 -567
- package/extensions/browser/frontend/types.ts +0 -31
- package/extensions/browser/frontend/useBrowserResources.ts +0 -158
- package/frontend/vendor/ghostty-web/index.d.ts +0 -1842
- package/shared/backend-connection-status.d.ts +0 -37
- package/shared/browser-protocol.d.ts +0 -5
- /package/dist/assets/{api-w2x5QfxB.js → api-ByCV9MEr.js} +0 -0
- /package/dist/assets/{core-vPkV8P_m.js → core-Czwdx12k.js} +0 -0
- /package/dist/assets/{fsharp-DNZNZyEE.js → fsharp-BjPpkoJe.js} +0 -0
- /package/dist/assets/{go-_kPJjNc_.js → go-BkIDmSUP.js} +0 -0
- /package/dist/assets/{graphql-4HCNVt5g.js → graphql-CCJTpqi1.js} +0 -0
- /package/dist/assets/{hcl-C87ymY0o.js → hcl-s4z8lUFg.js} +0 -0
- /package/dist/assets/{ini-BYrrGNTc.js → ini-CyUW1I7Z.js} +0 -0
- /package/dist/assets/{java-B211rJbk.js → java-CFCcGRiM.js} +0 -0
- /package/dist/assets/{julia-DVPsRtBm.js → julia-DQyH_EYb.js} +0 -0
- /package/dist/assets/{kotlin-BYyNerjp.js → kotlin-B8hA5O51.js} +0 -0
- /package/dist/assets/{less-EC9UblGE.js → less-DaVdaas0.js} +0 -0
- /package/dist/assets/{lexon-B1yuUdqW.js → lexon-DLBhPd3y.js} +0 -0
- /package/dist/assets/{lua-Bo6GFzxT.js → lua-gB1c_cif.js} +0 -0
- /package/dist/assets/{m3-C-Y9cBVI.js → m3-C2T3z3gB.js} +0 -0
- /package/dist/assets/{markdown-BHu-wLbe.js → markdown-CKq-Euj1.js} +0 -0
- /package/dist/assets/{mips-Dkds26rX.js → mips-Bcs5qIDX.js} +0 -0
- /package/dist/assets/{msdax-PU4g-8_g.js → msdax-CBP48FHF.js} +0 -0
- /package/dist/assets/{mysql-fPpuGpS7.js → mysql-c7tiPcFj.js} +0 -0
- /package/dist/assets/{objective-c-Wy1e5JUf.js → objective-c-D4BZkeEV.js} +0 -0
- /package/dist/assets/{pascal-BIXwvrqU.js → pascal-CJDZg0MN.js} +0 -0
- /package/dist/assets/{pascaligo-DwR0AtL_.js → pascaligo-Bygi8Ynl.js} +0 -0
- /package/dist/assets/{perl-CGHAl8my.js → perl-aS8bkf7E.js} +0 -0
- /package/dist/assets/{pgsql-B91M73E2.js → pgsql-CzNAYFYl.js} +0 -0
- /package/dist/assets/{php-C70ttrCx.js → php-DOtoEFTT.js} +0 -0
- /package/dist/assets/{pla-BNrXaRh0.js → pla-DugRnao1.js} +0 -0
- /package/dist/assets/{postiats-Dv2IAZR9.js → postiats-DsXwusKh.js} +0 -0
- /package/dist/assets/{powerquery-CkY5Wq7J.js → powerquery-DL3o72oD.js} +0 -0
- /package/dist/assets/{powershell-uGIYLU3C.js → powershell-C1qHekys.js} +0 -0
- /package/dist/assets/{protobuf-CavfmJu-.js → protobuf-DHgsc-cH.js} +0 -0
- /package/dist/assets/{pug-Drqnyitx.js → pug-FZXlE_Iu.js} +0 -0
- /package/dist/assets/{qrcode-7uGsTEmi.js → qrcode-DJDTdjL7.js} +0 -0
- /package/dist/assets/{qsharp-C7yF-Dti.js → qsharp-bLyhI3DT.js} +0 -0
- /package/dist/assets/{r-HXLGP0_-.js → r-DjFGXbAa.js} +0 -0
- /package/dist/assets/{redis-C4y6mf2p.js → redis-DSoZ_V6u.js} +0 -0
- /package/dist/assets/{redshift-DdQrFPrv.js → redshift-CzkdCsrg.js} +0 -0
- /package/dist/assets/{restructuredtext-CBrf2PNj.js → restructuredtext-B_XPrGCQ.js} +0 -0
- /package/dist/assets/{ruby-CVtMoX2B.js → ruby-Cry2RneJ.js} +0 -0
- /package/dist/assets/{rust-Ckq4sbMP.js → rust-CWzdbFq1.js} +0 -0
- /package/dist/assets/{sb-er66OpE3.js → sb-DmofU59h.js} +0 -0
- /package/dist/assets/{scala-BdWZz-hH.js → scala-BUC2l-vN.js} +0 -0
- /package/dist/assets/{scheme-kTV_s2kP.js → scheme-CNIB_72f.js} +0 -0
- /package/dist/assets/{scss-Bymy2VJQ.js → scss-DcL4-NbX.js} +0 -0
- /package/dist/assets/{shell-bwEP1LQ1.js → shell-CgAGvSSA.js} +0 -0
- /package/dist/assets/{solidity-DCddeBgL.js → solidity-DSkt6O_P.js} +0 -0
- /package/dist/assets/{sophia-BMN3AQig.js → sophia--5ytcjDN.js} +0 -0
- /package/dist/assets/{sparql-CSXOLjzi.js → sparql-C1Srr7cD.js} +0 -0
- /package/dist/assets/{sql-COg8ewmK.js → sql-2k_O5fj7.js} +0 -0
- /package/dist/assets/{st-CIaZtBS_.js → st-DCCCPqfz.js} +0 -0
- /package/dist/assets/{swift-DXiOhUHu.js → swift-Dd8mAfOt.js} +0 -0
- /package/dist/assets/{systemverilog-BTDE6Dr2.js → systemverilog-B0-aZYXu.js} +0 -0
- /package/dist/assets/{tcl-B0zy9NvV.js → tcl-CZAZwPVX.js} +0 -0
- /package/dist/assets/{twig-D594l4Z1.js → twig-D-Ag0tdS.js} +0 -0
- /package/dist/assets/{typespec-XKVjaPqo.js → typespec-B7kTFp0Z.js} +0 -0
- /package/dist/assets/{useWorkspaceMenuKeyboard-Bpy_s69Z.js → useWorkspaceMenuKeyboard-uYZpDxhU.js} +0 -0
- /package/dist/assets/{vb-B2wYoKRV.js → vb-20w1JPum.js} +0 -0
- /package/dist/assets/{wgsl-D0Yf2LbK.js → wgsl-CLJfqFt0.js} +0 -0
- /package/dist/assets/{workspace-working-copy-C3FSR3N6.js → workspace-working-copy-Cfz07cOd.js} +0 -0
|
@@ -1,116 +1,143 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
// Generated by scripts/build-backend-runtime.ts. Do not edit.
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var native_pty_host_client_exports = {};
|
|
31
|
+
__export(native_pty_host_client_exports, {
|
|
32
|
+
NativePtyHostClient: () => NativePtyHostClient,
|
|
33
|
+
buildCleanEnvExecCommand: () => buildCleanEnvExecCommand,
|
|
34
|
+
nativeHostSpawnCommand: () => nativeHostSpawnCommand
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(native_pty_host_client_exports);
|
|
37
|
+
var import_native_pty_host_path = require("./native-pty-host-path.cjs");
|
|
38
|
+
var import_native_pty_host_identity = require("./native-pty-host-identity.cjs");
|
|
39
|
+
var import_native_pty_controller_generation = require("./native-pty-controller-generation.cjs");
|
|
40
|
+
var import_provider_session_id = require("./provider-session-id.cjs");
|
|
41
|
+
var storageLayout = __toESM(require("./storage-layout.cjs"));
|
|
42
|
+
var import_terminal_state_serialization = require("./terminal-state-serialization.cjs");
|
|
43
|
+
var import_terminal_runtime_cleanup = require("./terminal-runtime-cleanup.cjs");
|
|
44
|
+
const { EventEmitter } = require("events");
|
|
45
|
+
const { spawn } = require("child_process");
|
|
46
|
+
const crypto = require("crypto");
|
|
47
|
+
const fs = require("fs");
|
|
48
|
+
const net = require("net");
|
|
49
|
+
const path = require("path");
|
|
25
50
|
const DEFAULT_CONNECT_RETRIES = 300;
|
|
26
51
|
const DEFAULT_CONNECT_RETRY_MS = 50;
|
|
27
|
-
const DEFAULT_REQUEST_TIMEOUT_MS =
|
|
28
|
-
const DEFAULT_HOST_ROTATION_TIMEOUT_MS =
|
|
29
|
-
const PACKAGED_NATIVE_PTY_HOST_ENV =
|
|
30
|
-
const RECONNECT_RETRYABLE_METHODS = new Set([
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
53
|
+
const DEFAULT_HOST_ROTATION_TIMEOUT_MS = 1e4;
|
|
54
|
+
const PACKAGED_NATIVE_PTY_HOST_ENV = "FARMING_RUN_NATIVE_PTY_HOST";
|
|
55
|
+
const RECONNECT_RETRYABLE_METHODS = /* @__PURE__ */ new Set([
|
|
56
|
+
"ping",
|
|
57
|
+
"createSession",
|
|
58
|
+
"claimSessionController",
|
|
59
|
+
"renewSessionController",
|
|
60
|
+
"resizeSession",
|
|
61
|
+
"killSession",
|
|
62
|
+
"getSessionAttachCheckpoint",
|
|
63
|
+
"getSessionState",
|
|
64
|
+
"getSessionPreview",
|
|
65
|
+
"recoverSessions",
|
|
66
|
+
"serializeTerminalState",
|
|
67
|
+
"updateSessionMetadata"
|
|
43
68
|
]);
|
|
44
|
-
const PACKAGED_NATIVE_HOST_ENV_KEYS = new Set([
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
const PACKAGED_NATIVE_HOST_ENV_KEYS = /* @__PURE__ */ new Set([
|
|
70
|
+
"CLICOLOR",
|
|
71
|
+
"COLORTERM",
|
|
72
|
+
"FARMING_CLI_BIN_DIR",
|
|
73
|
+
"FARMING_CONFIG_DIR",
|
|
74
|
+
"FARMING_EFFECTIVE_NODE_HEAP_MB",
|
|
75
|
+
"FARMING_NATIVE_PTY_HOST_IDLE_EXIT_MS",
|
|
76
|
+
"FARMING_NATIVE_PTY_HOST_OWNER_PID",
|
|
77
|
+
"FARMING_NATIVE_PTY_HOST_SOCKET",
|
|
78
|
+
"FARMING_NATIVE_PTY_SCREEN_WORKERS",
|
|
79
|
+
"FARMING_NODE_BIN",
|
|
80
|
+
"FARMING_NODE_LD",
|
|
81
|
+
"FARMING_NODE_LIBRARY_PATH",
|
|
82
|
+
"FARMING_PACKAGED_RUNTIME",
|
|
83
|
+
"FARMING_RUN_NATIVE_PTY_HOST",
|
|
84
|
+
"HOME",
|
|
85
|
+
"LANG",
|
|
86
|
+
"LC_ALL",
|
|
87
|
+
"LC_CTYPE",
|
|
88
|
+
"LOGNAME",
|
|
89
|
+
"NODE_OPTIONS",
|
|
90
|
+
"PATH",
|
|
91
|
+
"SHELL",
|
|
92
|
+
"TEMP",
|
|
93
|
+
"TERM",
|
|
94
|
+
"TMP",
|
|
95
|
+
"TMPDIR",
|
|
96
|
+
"USER"
|
|
72
97
|
]);
|
|
73
|
-
|
|
98
|
+
function errorCode(error) {
|
|
99
|
+
if (!error || typeof error !== "object" || !("code" in error)) return "";
|
|
100
|
+
const code = error.code;
|
|
101
|
+
return code === void 0 || code === null ? "" : String(code);
|
|
102
|
+
}
|
|
103
|
+
function errorStack(error) {
|
|
104
|
+
if (error && typeof error === "object" && "stack" in error && error.stack) {
|
|
105
|
+
return String(error.stack);
|
|
106
|
+
}
|
|
107
|
+
return String(error);
|
|
108
|
+
}
|
|
74
109
|
function delay(ms) {
|
|
75
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
110
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
76
111
|
}
|
|
77
|
-
|
|
78
112
|
function isConnectRetryable(error) {
|
|
79
|
-
const code = error
|
|
80
|
-
return code ===
|
|
113
|
+
const code = errorCode(error);
|
|
114
|
+
return code === "ENOENT" || code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT";
|
|
81
115
|
}
|
|
82
|
-
|
|
83
116
|
function isRequestRetryable(method, options = {}) {
|
|
84
|
-
return options.ensureConnected !== false &&
|
|
85
|
-
options.retryOnDisconnect !== false &&
|
|
86
|
-
RECONNECT_RETRYABLE_METHODS.has(method);
|
|
117
|
+
return options.ensureConnected !== false && options.retryOnDisconnect !== false && RECONNECT_RETRYABLE_METHODS.has(method);
|
|
87
118
|
}
|
|
88
|
-
|
|
89
119
|
function quoteShellArg(arg) {
|
|
90
120
|
return `'${String(arg).replace(/'/g, `'\\''`)}'`;
|
|
91
121
|
}
|
|
92
|
-
|
|
93
122
|
function buildCleanEnvExecCommand(env, command, args = []) {
|
|
94
|
-
const parts = [
|
|
123
|
+
const parts = ["/usr/bin/env", "-i"];
|
|
95
124
|
Object.entries(env || {}).forEach(([key, value]) => {
|
|
96
125
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) return;
|
|
97
|
-
if (value ===
|
|
126
|
+
if (value === void 0 || value === null) return;
|
|
98
127
|
parts.push(`${key}=${String(value)}`);
|
|
99
128
|
});
|
|
100
129
|
parts.push(command, ...args);
|
|
101
|
-
return parts.map(quoteShellArg).join(
|
|
130
|
+
return parts.map(quoteShellArg).join(" ");
|
|
102
131
|
}
|
|
103
|
-
|
|
104
132
|
function packagedNativeHostEnv(env = {}) {
|
|
105
133
|
const next = {};
|
|
106
134
|
Object.entries(env).forEach(([key, value]) => {
|
|
107
135
|
if (!PACKAGED_NATIVE_HOST_ENV_KEYS.has(key)) return;
|
|
108
|
-
if (value ===
|
|
136
|
+
if (value === void 0 || value === null) return;
|
|
109
137
|
next[key] = value;
|
|
110
138
|
});
|
|
111
139
|
return next;
|
|
112
140
|
}
|
|
113
|
-
|
|
114
141
|
function redactCommandArg(arg) {
|
|
115
142
|
const value = String(arg);
|
|
116
143
|
const match = value.match(/^([A-Za-z_][A-Za-z0-9_]*)=/);
|
|
@@ -121,256 +148,258 @@ function redactCommandArg(arg) {
|
|
|
121
148
|
}
|
|
122
149
|
return value;
|
|
123
150
|
}
|
|
124
|
-
|
|
125
151
|
function hostConnectErrorMessage(error, spawned, logPath) {
|
|
126
|
-
const
|
|
127
|
-
const
|
|
152
|
+
const rawCode = errorCode(error);
|
|
153
|
+
const code = rawCode ? ` ${rawCode}` : "";
|
|
154
|
+
const logHint = logPath ? ` See ${logPath}.` : "";
|
|
128
155
|
if (spawned) {
|
|
129
156
|
return `Native PTY host failed to start or connect${code}. Check that Farming can run its native PTY host on this machine.${logHint}`;
|
|
130
157
|
}
|
|
131
158
|
return `Native PTY host is not reachable${code}.${logHint}`;
|
|
132
159
|
}
|
|
133
|
-
|
|
134
160
|
function runtimeIdentityLabel(value) {
|
|
135
|
-
const identity = normalizeNativePtyHostRuntimeIdentity(value);
|
|
136
|
-
if (!identity) return
|
|
137
|
-
const version = identity.version ? `v${identity.version} ` :
|
|
161
|
+
const identity = (0, import_native_pty_host_identity.normalizeNativePtyHostRuntimeIdentity)(value);
|
|
162
|
+
if (!identity) return "legacy/unknown";
|
|
163
|
+
const version = identity.version ? `v${identity.version} ` : "";
|
|
138
164
|
return `${version}protocol ${identity.protocolVersion} build ${identity.buildId.slice(0, 12)}`;
|
|
139
165
|
}
|
|
140
|
-
|
|
141
166
|
function nativeHostSpawnCommand(hostScript, env) {
|
|
142
167
|
const nodeBin = env.FARMING_NODE_BIN || process.execPath;
|
|
143
|
-
const ldPath = env.FARMING_NODE_LD ||
|
|
144
|
-
const libraryPath = env.FARMING_NODE_LIBRARY_PATH ||
|
|
145
|
-
const isPackagedRuntime = env.FARMING_PACKAGED_RUNTIME ===
|
|
168
|
+
const ldPath = env.FARMING_NODE_LD || "";
|
|
169
|
+
const libraryPath = env.FARMING_NODE_LIBRARY_PATH || "";
|
|
170
|
+
const isPackagedRuntime = env.FARMING_PACKAGED_RUNTIME === "1";
|
|
146
171
|
if (isPackagedRuntime) {
|
|
147
|
-
env[PACKAGED_NATIVE_PTY_HOST_ENV] =
|
|
172
|
+
env[PACKAGED_NATIVE_PTY_HOST_ENV] = "1";
|
|
148
173
|
const hostEnv = packagedNativeHostEnv(env);
|
|
149
174
|
const command = ldPath && libraryPath ? ldPath : nodeBin;
|
|
150
|
-
const args = ldPath && libraryPath
|
|
151
|
-
? ['--library-path', libraryPath, nodeBin]
|
|
152
|
-
: [];
|
|
175
|
+
const args = ldPath && libraryPath ? ["--library-path", libraryPath, nodeBin] : [];
|
|
153
176
|
return { command, args, env: hostEnv };
|
|
154
177
|
}
|
|
155
178
|
if (ldPath && libraryPath) {
|
|
156
179
|
return {
|
|
157
180
|
command: ldPath,
|
|
158
|
-
args: [
|
|
181
|
+
args: ["--library-path", libraryPath, nodeBin, hostScript]
|
|
159
182
|
};
|
|
160
183
|
}
|
|
161
184
|
return {
|
|
162
185
|
command: nodeBin,
|
|
163
|
-
args: [hostScript]
|
|
186
|
+
args: [hostScript]
|
|
164
187
|
};
|
|
165
188
|
}
|
|
166
|
-
|
|
167
189
|
class NativePtyHostClient extends EventEmitter {
|
|
190
|
+
configDir;
|
|
191
|
+
socketPath;
|
|
192
|
+
hostScript;
|
|
193
|
+
preserveHostOnDisconnect;
|
|
194
|
+
connectRetries;
|
|
195
|
+
connectRetryMs;
|
|
196
|
+
requestTimeoutMs;
|
|
197
|
+
hostLogPath;
|
|
198
|
+
expectedRuntimeIdentity;
|
|
199
|
+
controllerIdentity;
|
|
200
|
+
controllerIdentityReady;
|
|
201
|
+
hostRotationTimeoutMs;
|
|
202
|
+
connectedHostInfo;
|
|
203
|
+
connectedSocketPath;
|
|
204
|
+
runtimeRotationInfo;
|
|
205
|
+
socket;
|
|
206
|
+
socketGeneration;
|
|
207
|
+
buffer;
|
|
208
|
+
nextRequestId;
|
|
209
|
+
pending;
|
|
210
|
+
connecting;
|
|
211
|
+
disposed;
|
|
212
|
+
hostChild;
|
|
213
|
+
hostStartError;
|
|
214
|
+
hostLogStream;
|
|
215
|
+
suppressedDisconnectSockets;
|
|
168
216
|
constructor(options = {}) {
|
|
169
217
|
super();
|
|
170
|
-
this.configDir = options.configDir || process.env.FARMING_CONFIG_DIR ||
|
|
171
|
-
this.socketPath = options.socketPath || nativePtyHostSocketPath(this.configDir);
|
|
172
|
-
this.hostScript = options.hostScript || path.join(__dirname,
|
|
218
|
+
this.configDir = options.configDir || process.env.FARMING_CONFIG_DIR || "";
|
|
219
|
+
this.socketPath = options.socketPath || (0, import_native_pty_host_path.nativePtyHostSocketPath)(this.configDir);
|
|
220
|
+
this.hostScript = options.hostScript || path.join(__dirname, "native-pty-host.cjs");
|
|
173
221
|
this.preserveHostOnDisconnect = options.preserveHostOnDisconnect === true;
|
|
174
222
|
this.connectRetries = options.connectRetries || DEFAULT_CONNECT_RETRIES;
|
|
175
223
|
this.connectRetryMs = options.connectRetryMs || DEFAULT_CONNECT_RETRY_MS;
|
|
176
224
|
this.requestTimeoutMs = options.requestTimeoutMs || DEFAULT_REQUEST_TIMEOUT_MS;
|
|
177
225
|
this.hostLogPath = options.hostLogPath || this.defaultHostLogPath();
|
|
178
|
-
this.expectedRuntimeIdentity = options.expectedRuntimeIdentity || nativePtyHostRuntimeIdentity();
|
|
179
|
-
this.controllerIdentity = options.controllerIdentity
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
:
|
|
185
|
-
|
|
186
|
-
generation: 0,
|
|
187
|
-
};
|
|
226
|
+
this.expectedRuntimeIdentity = options.expectedRuntimeIdentity || (0, import_native_pty_host_identity.nativePtyHostRuntimeIdentity)();
|
|
227
|
+
this.controllerIdentity = options.controllerIdentity ? {
|
|
228
|
+
id: String(options.controllerIdentity.id || ""),
|
|
229
|
+
generation: (0, import_native_pty_controller_generation.positiveGeneration)(options.controllerIdentity.generation)
|
|
230
|
+
} : {
|
|
231
|
+
id: crypto.randomUUID(),
|
|
232
|
+
generation: 0
|
|
233
|
+
};
|
|
188
234
|
this.controllerIdentityReady = null;
|
|
189
235
|
this.hostRotationTimeoutMs = options.hostRotationTimeoutMs || DEFAULT_HOST_ROTATION_TIMEOUT_MS;
|
|
190
236
|
this.connectedHostInfo = null;
|
|
191
|
-
this.connectedSocketPath =
|
|
237
|
+
this.connectedSocketPath = "";
|
|
192
238
|
this.runtimeRotationInfo = null;
|
|
193
239
|
this.socket = null;
|
|
194
240
|
this.socketGeneration = 0;
|
|
195
|
-
this.buffer =
|
|
241
|
+
this.buffer = "";
|
|
196
242
|
this.nextRequestId = 1;
|
|
197
|
-
this.pending = new Map();
|
|
243
|
+
this.pending = /* @__PURE__ */ new Map();
|
|
198
244
|
this.connecting = null;
|
|
199
245
|
this.disposed = false;
|
|
200
246
|
this.hostChild = null;
|
|
201
247
|
this.hostStartError = null;
|
|
202
248
|
this.hostLogStream = null;
|
|
203
|
-
this.suppressedDisconnectSockets = new WeakSet();
|
|
249
|
+
this.suppressedDisconnectSockets = /* @__PURE__ */ new WeakSet();
|
|
204
250
|
}
|
|
205
|
-
|
|
206
251
|
defaultHostLogPath() {
|
|
207
252
|
const root = this.configDir || path.dirname(this.socketPath);
|
|
208
253
|
return storageLayout.nativePtyHostLogFile(root);
|
|
209
254
|
}
|
|
210
|
-
|
|
211
255
|
openHostLogStream(spawnCommand) {
|
|
212
256
|
try {
|
|
213
257
|
fs.mkdirSync(path.dirname(this.hostLogPath), { recursive: true });
|
|
214
|
-
const stream = fs.createWriteStream(this.hostLogPath, { flags:
|
|
258
|
+
const stream = fs.createWriteStream(this.hostLogPath, { flags: "a" });
|
|
215
259
|
stream.write([
|
|
216
|
-
`[${new Date().toISOString()}] Starting native PTY host`,
|
|
260
|
+
`[${(/* @__PURE__ */ new Date()).toISOString()}] Starting native PTY host`,
|
|
217
261
|
` command: ${spawnCommand.command}`,
|
|
218
|
-
` args: ${spawnCommand.args.map(redactCommandArg).join(
|
|
262
|
+
` args: ${spawnCommand.args.map(redactCommandArg).join(" ")}`,
|
|
219
263
|
` socket: ${this.socketPath}`,
|
|
220
264
|
` ownerPid: ${process.pid}`,
|
|
221
|
-
|
|
222
|
-
].join(
|
|
265
|
+
""
|
|
266
|
+
].join("\n"));
|
|
223
267
|
return stream;
|
|
224
268
|
} catch (error) {
|
|
225
|
-
this.emit(
|
|
269
|
+
this.emit("host-error", error);
|
|
226
270
|
return null;
|
|
227
271
|
}
|
|
228
272
|
}
|
|
229
|
-
|
|
230
273
|
closeHostLogStream() {
|
|
231
274
|
if (!this.hostLogStream) return;
|
|
232
275
|
this.hostLogStream.end();
|
|
233
276
|
this.hostLogStream = null;
|
|
234
277
|
}
|
|
235
|
-
|
|
236
278
|
writeHostLog(label, chunk) {
|
|
237
279
|
if (!this.hostLogStream) return;
|
|
238
|
-
|
|
280
|
+
const text = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : chunk.toString();
|
|
281
|
+
this.hostLogStream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${label}: ${text}`);
|
|
239
282
|
}
|
|
240
|
-
|
|
241
283
|
canConnectWithoutStartingHost() {
|
|
242
|
-
if (process.platform ===
|
|
284
|
+
if (process.platform === "win32") return true;
|
|
243
285
|
return fs.existsSync(this.socketPath) || this.privateSocketCandidates().length > 0;
|
|
244
286
|
}
|
|
245
|
-
|
|
246
287
|
privateSocketCandidates() {
|
|
247
|
-
if (process.platform ===
|
|
288
|
+
if (process.platform === "win32") return [];
|
|
248
289
|
const directory = path.dirname(this.socketPath);
|
|
249
|
-
const pattern = nativePtyHostPrivateSocketNamePattern(this.socketPath);
|
|
290
|
+
const pattern = (0, import_native_pty_host_path.nativePtyHostPrivateSocketNamePattern)(this.socketPath);
|
|
250
291
|
try {
|
|
251
|
-
return fs.readdirSync(directory)
|
|
252
|
-
.filter(name => pattern.test(name))
|
|
253
|
-
.map(name => path.join(directory, name));
|
|
292
|
+
return fs.readdirSync(directory).filter((name) => pattern.test(name)).map((name) => path.join(directory, name));
|
|
254
293
|
} catch (error) {
|
|
255
|
-
if (error
|
|
294
|
+
if (errorCode(error) === "ENOENT") return [];
|
|
256
295
|
throw error;
|
|
257
296
|
}
|
|
258
297
|
}
|
|
259
|
-
|
|
260
298
|
connectedPrivateSocketPath(hostInfo = {}) {
|
|
261
|
-
if (process.platform ===
|
|
262
|
-
if (typeof hostInfo.privateSocketPath ===
|
|
299
|
+
if (process.platform === "win32") return "";
|
|
300
|
+
if (typeof hostInfo.privateSocketPath === "string" && hostInfo.privateSocketPath) {
|
|
263
301
|
return hostInfo.privateSocketPath;
|
|
264
302
|
}
|
|
265
303
|
if (!this.connectedSocketPath || this.connectedSocketPath !== this.socketPath) {
|
|
266
304
|
return this.connectedSocketPath;
|
|
267
305
|
}
|
|
268
|
-
|
|
269
306
|
let publicIdentity;
|
|
270
307
|
try {
|
|
271
308
|
const stat = fs.statSync(this.socketPath, { bigint: true });
|
|
272
309
|
publicIdentity = { dev: stat.dev, ino: stat.ino };
|
|
273
310
|
} catch (error) {
|
|
274
|
-
if (error
|
|
311
|
+
if (errorCode(error) === "ENOENT") return "";
|
|
275
312
|
throw error;
|
|
276
313
|
}
|
|
277
|
-
|
|
278
314
|
const matching = this.privateSocketCandidates().filter((candidate) => {
|
|
279
315
|
try {
|
|
280
316
|
const stat = fs.statSync(candidate, { bigint: true });
|
|
281
317
|
return stat.dev === publicIdentity.dev && stat.ino === publicIdentity.ino;
|
|
282
318
|
} catch (error) {
|
|
283
|
-
if (error
|
|
319
|
+
if (errorCode(error) === "ENOENT") return false;
|
|
284
320
|
throw error;
|
|
285
321
|
}
|
|
286
322
|
});
|
|
287
|
-
return matching.length === 1 ? matching[0] :
|
|
323
|
+
return matching.length === 1 ? matching[0] : "";
|
|
288
324
|
}
|
|
289
|
-
|
|
290
325
|
async resolveConnectSocketPath() {
|
|
291
|
-
if (process.platform ===
|
|
326
|
+
if (process.platform === "win32" || fs.existsSync(this.socketPath)) {
|
|
292
327
|
return this.socketPath;
|
|
293
328
|
}
|
|
294
329
|
const active = [];
|
|
295
330
|
for (const candidate of this.privateSocketCandidates()) {
|
|
296
|
-
const probe = await probeUnixSocket(candidate);
|
|
331
|
+
const probe = await (0, import_terminal_runtime_cleanup.probeUnixSocket)(candidate);
|
|
297
332
|
if (probe.active) active.push(candidate);
|
|
298
333
|
}
|
|
299
334
|
if (active.length > 1) {
|
|
300
|
-
const error = new Error(
|
|
301
|
-
error.code =
|
|
335
|
+
const error = new Error("Multiple live native PTY hosts were found for this Farming config");
|
|
336
|
+
error.code = "FARMING_NATIVE_HOST_AMBIGUOUS";
|
|
302
337
|
error.socketPaths = active;
|
|
303
338
|
throw error;
|
|
304
339
|
}
|
|
305
340
|
return active[0] || this.socketPath;
|
|
306
341
|
}
|
|
307
|
-
|
|
308
342
|
restorePublicSocketPath(connectedPath) {
|
|
309
|
-
if (
|
|
310
|
-
process.platform === 'win32'
|
|
311
|
-
|| !connectedPath
|
|
312
|
-
|| connectedPath === this.socketPath
|
|
313
|
-
|| fs.existsSync(this.socketPath)
|
|
314
|
-
) {
|
|
343
|
+
if (process.platform === "win32" || !connectedPath || connectedPath === this.socketPath || fs.existsSync(this.socketPath)) {
|
|
315
344
|
return;
|
|
316
345
|
}
|
|
317
346
|
try {
|
|
318
347
|
fs.linkSync(connectedPath, this.socketPath);
|
|
319
348
|
} catch (error) {
|
|
320
|
-
if (
|
|
349
|
+
if (errorCode(error) !== "EEXIST") throw error;
|
|
321
350
|
}
|
|
322
351
|
}
|
|
323
|
-
|
|
324
352
|
spawnHost() {
|
|
325
353
|
if (this.disposed) return;
|
|
326
354
|
if (this.hostChild && this.hostChild.exitCode === null && this.hostChild.signalCode === null) return;
|
|
327
355
|
this.hostStartError = null;
|
|
328
356
|
const env = {
|
|
329
357
|
...process.env,
|
|
330
|
-
FARMING_CONFIG_DIR: this.configDir || process.env.FARMING_CONFIG_DIR ||
|
|
358
|
+
FARMING_CONFIG_DIR: this.configDir || process.env.FARMING_CONFIG_DIR || "",
|
|
331
359
|
FARMING_NATIVE_PTY_HOST_SOCKET: this.socketPath,
|
|
332
|
-
FARMING_NATIVE_PTY_HOST_OWNER_PID: this.preserveHostOnDisconnect ?
|
|
360
|
+
FARMING_NATIVE_PTY_HOST_OWNER_PID: this.preserveHostOnDisconnect ? "" : String(process.pid)
|
|
333
361
|
};
|
|
334
362
|
const spawnCommand = nativeHostSpawnCommand(this.hostScript, env);
|
|
335
363
|
this.closeHostLogStream();
|
|
336
364
|
this.hostLogStream = this.openHostLogStream(spawnCommand);
|
|
337
365
|
const child = spawn(spawnCommand.command, spawnCommand.args, {
|
|
338
366
|
detached: false,
|
|
339
|
-
stdio: [
|
|
367
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
340
368
|
env: spawnCommand.env || env,
|
|
341
|
-
windowsHide: true
|
|
369
|
+
windowsHide: true
|
|
342
370
|
});
|
|
343
371
|
this.hostChild = child;
|
|
344
|
-
if (this.preserveHostOnDisconnect && typeof child.unref ===
|
|
372
|
+
if (this.preserveHostOnDisconnect && typeof child.unref === "function") {
|
|
345
373
|
child.unref();
|
|
346
374
|
}
|
|
347
375
|
if (child.stdout) {
|
|
348
|
-
child.stdout.on(
|
|
376
|
+
child.stdout.on("data", (chunk) => this.writeHostLog("stdout", chunk));
|
|
349
377
|
}
|
|
350
378
|
if (child.stderr) {
|
|
351
|
-
child.stderr.on(
|
|
379
|
+
child.stderr.on("data", (chunk) => this.writeHostLog("stderr", chunk));
|
|
352
380
|
}
|
|
353
|
-
child.once(
|
|
381
|
+
child.once("error", (error) => {
|
|
354
382
|
this.hostStartError = error;
|
|
355
|
-
this.writeHostLog(
|
|
383
|
+
this.writeHostLog("error", `${errorStack(error)}
|
|
384
|
+
`);
|
|
356
385
|
if (this.hostChild === child) {
|
|
357
386
|
this.hostChild = null;
|
|
358
387
|
}
|
|
359
388
|
this.closeHostLogStream();
|
|
360
|
-
this.emit(
|
|
389
|
+
this.emit("host-error", error);
|
|
361
390
|
});
|
|
362
|
-
child.once(
|
|
363
|
-
this.writeHostLog(
|
|
391
|
+
child.once("exit", (code, signal) => {
|
|
392
|
+
this.writeHostLog("exit", `code=${code == null ? "" : code} signal=${signal || ""}
|
|
393
|
+
`);
|
|
364
394
|
if (this.hostChild === child) {
|
|
365
395
|
this.hostChild = null;
|
|
366
396
|
}
|
|
367
397
|
this.closeHostLogStream();
|
|
368
398
|
if (!this.disposed && !this.socket) {
|
|
369
|
-
this.emit(
|
|
399
|
+
this.emit("host-exit", { code, signal });
|
|
370
400
|
}
|
|
371
401
|
});
|
|
372
402
|
}
|
|
373
|
-
|
|
374
403
|
async connectOnce() {
|
|
375
404
|
const connectedPath = await this.resolveConnectSocketPath();
|
|
376
405
|
return new Promise((resolve, reject) => {
|
|
@@ -379,9 +408,9 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
379
408
|
socket.destroy();
|
|
380
409
|
reject(error);
|
|
381
410
|
};
|
|
382
|
-
socket.once(
|
|
383
|
-
socket.once(
|
|
384
|
-
socket.off(
|
|
411
|
+
socket.once("error", onError);
|
|
412
|
+
socket.once("connect", () => {
|
|
413
|
+
socket.off("error", onError);
|
|
385
414
|
this.restorePublicSocketPath(connectedPath);
|
|
386
415
|
this.connectedSocketPath = connectedPath;
|
|
387
416
|
this.attachSocket(socket);
|
|
@@ -389,21 +418,17 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
389
418
|
});
|
|
390
419
|
});
|
|
391
420
|
}
|
|
392
|
-
|
|
393
421
|
async ensureConnected(options = {}) {
|
|
394
422
|
if (this.disposed) {
|
|
395
|
-
throw new Error(
|
|
423
|
+
throw new Error("Native pty host client is disposed");
|
|
396
424
|
}
|
|
397
425
|
if (this.socket && !this.socket.destroyed) return;
|
|
398
426
|
if (this.connecting) return this.connecting;
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
this.connecting = null;
|
|
403
|
-
});
|
|
427
|
+
this.connecting = this.connectWithRetries(options).finally(() => {
|
|
428
|
+
this.connecting = null;
|
|
429
|
+
});
|
|
404
430
|
return this.connecting;
|
|
405
431
|
}
|
|
406
|
-
|
|
407
432
|
async connectWithRetries(options = {}) {
|
|
408
433
|
await this.ensureControllerIdentity();
|
|
409
434
|
const allowHostStart = options.startHost !== false;
|
|
@@ -411,43 +436,43 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
411
436
|
let rotatedMismatchedHost = false;
|
|
412
437
|
let pendingRotationInfo = null;
|
|
413
438
|
let lastError = null;
|
|
414
|
-
|
|
415
439
|
for (let attempt = 0; attempt < this.connectRetries; attempt += 1) {
|
|
416
440
|
if (this.disposed) {
|
|
417
|
-
throw new Error(
|
|
441
|
+
throw new Error("Native pty host client is disposed");
|
|
418
442
|
}
|
|
419
443
|
try {
|
|
420
444
|
await this.connectOnce();
|
|
421
|
-
const hostInfo = await this.request(
|
|
422
|
-
|
|
445
|
+
const hostInfo = await this.request(
|
|
446
|
+
"ping",
|
|
447
|
+
{},
|
|
448
|
+
{ ensureConnected: false, timeoutMs: 3e3 }
|
|
449
|
+
);
|
|
450
|
+
if (!(0, import_native_pty_host_identity.nativePtyHostRuntimeIdentityMatches)(this.expectedRuntimeIdentity, hostInfo?.runtimeIdentity)) {
|
|
423
451
|
if (rotatedMismatchedHost) {
|
|
424
452
|
const error = new Error(
|
|
425
|
-
`Native PTY host runtime still mismatches after rotation: expected `
|
|
426
|
-
`${runtimeIdentityLabel(this.expectedRuntimeIdentity)}, got ${runtimeIdentityLabel(hostInfo?.runtimeIdentity)}`
|
|
453
|
+
`Native PTY host runtime still mismatches after rotation: expected ${runtimeIdentityLabel(this.expectedRuntimeIdentity)}, got ${runtimeIdentityLabel(hostInfo?.runtimeIdentity)}`
|
|
427
454
|
);
|
|
428
|
-
error.code =
|
|
455
|
+
error.code = "FARMING_NATIVE_HOST_RUNTIME_MISMATCH";
|
|
429
456
|
throw error;
|
|
430
457
|
}
|
|
431
458
|
const serializedTerminalState = await this.rotateMismatchedHost(hostInfo);
|
|
432
459
|
pendingRotationInfo = {
|
|
433
460
|
rotatedAt: Date.now(),
|
|
434
|
-
previous: normalizeNativePtyHostRuntimeIdentity(hostInfo?.runtimeIdentity),
|
|
435
|
-
current: normalizeNativePtyHostRuntimeIdentity(this.expectedRuntimeIdentity),
|
|
461
|
+
previous: (0, import_native_pty_host_identity.normalizeNativePtyHostRuntimeIdentity)(hostInfo?.runtimeIdentity),
|
|
462
|
+
current: (0, import_native_pty_host_identity.normalizeNativePtyHostRuntimeIdentity)(this.expectedRuntimeIdentity),
|
|
436
463
|
previousPid: Number(hostInfo?.pid) || null,
|
|
437
|
-
serializedTerminalState: typeof serializedTerminalState ===
|
|
438
|
-
? serializedTerminalState
|
|
439
|
-
: '',
|
|
464
|
+
serializedTerminalState: typeof serializedTerminalState === "string" ? serializedTerminalState : ""
|
|
440
465
|
};
|
|
441
466
|
rotatedMismatchedHost = true;
|
|
442
467
|
spawned = true;
|
|
443
468
|
continue;
|
|
444
469
|
}
|
|
445
|
-
await this.requestOnce(
|
|
446
|
-
identity: this.controllerIdentity
|
|
470
|
+
await this.requestOnce("registerController", {
|
|
471
|
+
identity: this.controllerIdentity
|
|
447
472
|
}, {
|
|
448
473
|
ensureConnected: false,
|
|
449
474
|
retryOnDisconnect: false,
|
|
450
|
-
timeoutMs:
|
|
475
|
+
timeoutMs: 3e3
|
|
451
476
|
});
|
|
452
477
|
this.connectedHostInfo = hostInfo || null;
|
|
453
478
|
if (pendingRotationInfo) {
|
|
@@ -456,10 +481,10 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
456
481
|
return;
|
|
457
482
|
} catch (error) {
|
|
458
483
|
lastError = error;
|
|
459
|
-
if (error
|
|
484
|
+
if (errorCode(error) === "FARMING_NATIVE_HOST_RUNTIME_MISMATCH") {
|
|
460
485
|
throw error;
|
|
461
486
|
}
|
|
462
|
-
if (error
|
|
487
|
+
if (errorCode(error) === "FARMING_NATIVE_HOST_AMBIGUOUS") {
|
|
463
488
|
throw error;
|
|
464
489
|
}
|
|
465
490
|
if (this.hostStartError) {
|
|
@@ -475,86 +500,81 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
475
500
|
await delay(this.connectRetryMs);
|
|
476
501
|
}
|
|
477
502
|
}
|
|
478
|
-
|
|
479
503
|
if (this.hostStartError) {
|
|
480
|
-
const wrapped = new Error(
|
|
504
|
+
const wrapped = new Error(
|
|
505
|
+
hostConnectErrorMessage(this.hostStartError, spawned, this.hostLogPath)
|
|
506
|
+
);
|
|
481
507
|
wrapped.code = this.hostStartError.code;
|
|
482
508
|
wrapped.socketPath = this.socketPath;
|
|
483
509
|
wrapped.hostLogPath = this.hostLogPath;
|
|
484
510
|
wrapped.cause = this.hostStartError;
|
|
485
511
|
throw wrapped;
|
|
486
512
|
}
|
|
487
|
-
|
|
488
513
|
if (lastError && isConnectRetryable(lastError)) {
|
|
489
|
-
const wrapped = new Error(
|
|
490
|
-
|
|
514
|
+
const wrapped = new Error(
|
|
515
|
+
hostConnectErrorMessage(lastError, spawned, this.hostLogPath)
|
|
516
|
+
);
|
|
517
|
+
wrapped.code = errorCode(lastError);
|
|
491
518
|
wrapped.socketPath = this.socketPath;
|
|
492
519
|
wrapped.hostLogPath = this.hostLogPath;
|
|
493
520
|
wrapped.cause = lastError;
|
|
494
521
|
throw wrapped;
|
|
495
522
|
}
|
|
496
|
-
|
|
497
|
-
throw lastError || new Error('Failed to connect to native pty host');
|
|
523
|
+
throw lastError || new Error("Failed to connect to native pty host");
|
|
498
524
|
}
|
|
499
|
-
|
|
500
525
|
async ensureControllerIdentity() {
|
|
501
526
|
if (this.controllerIdentity.generation > 0) {
|
|
502
527
|
return this.controllerIdentity;
|
|
503
528
|
}
|
|
504
529
|
if (!this.controllerIdentityReady) {
|
|
505
530
|
const configRoot = this.configDir || path.dirname(this.socketPath);
|
|
506
|
-
this.controllerIdentityReady = allocateNativePtyControllerGeneration(configRoot)
|
|
507
|
-
.
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
throw error;
|
|
514
|
-
});
|
|
531
|
+
this.controllerIdentityReady = (0, import_native_pty_controller_generation.allocateNativePtyControllerGeneration)(configRoot).then((generation) => {
|
|
532
|
+
this.controllerIdentity.generation = generation;
|
|
533
|
+
return this.controllerIdentity;
|
|
534
|
+
}).catch((error) => {
|
|
535
|
+
this.controllerIdentityReady = null;
|
|
536
|
+
throw error;
|
|
537
|
+
});
|
|
515
538
|
}
|
|
516
539
|
return this.controllerIdentityReady;
|
|
517
540
|
}
|
|
518
|
-
|
|
519
|
-
async waitForHostRelease(privateSocketPath = '') {
|
|
541
|
+
async waitForHostRelease(privateSocketPath = "") {
|
|
520
542
|
const deadline = Date.now() + this.hostRotationTimeoutMs;
|
|
521
|
-
if (process.platform ===
|
|
543
|
+
if (process.platform === "win32") {
|
|
522
544
|
await delay(Math.min(250, this.hostRotationTimeoutMs));
|
|
523
545
|
return;
|
|
524
546
|
}
|
|
525
547
|
while (Date.now() < deadline) {
|
|
526
|
-
const childReleased = !this.hostChild ||
|
|
527
|
-
this.hostChild.exitCode !== null ||
|
|
528
|
-
this.hostChild.signalCode !== null;
|
|
548
|
+
const childReleased = !this.hostChild || this.hostChild.exitCode !== null || this.hostChild.signalCode !== null;
|
|
529
549
|
const privateReleased = !privateSocketPath || !fs.existsSync(privateSocketPath);
|
|
530
550
|
if (!fs.existsSync(this.socketPath) && privateReleased && childReleased) return;
|
|
531
551
|
await delay(50);
|
|
532
552
|
}
|
|
533
|
-
const error = new Error(
|
|
534
|
-
|
|
553
|
+
const error = new Error(
|
|
554
|
+
"Timed out waiting for the previous native PTY host to stop"
|
|
555
|
+
);
|
|
556
|
+
error.code = "FARMING_NATIVE_HOST_RUNTIME_MISMATCH";
|
|
535
557
|
throw error;
|
|
536
558
|
}
|
|
537
|
-
|
|
538
|
-
async resumePreparedHostRotation(preparationToken = '') {
|
|
559
|
+
async resumePreparedHostRotation(preparationToken = "") {
|
|
539
560
|
if (!this.socket || this.socket.destroyed) {
|
|
540
561
|
await this.connectOnce();
|
|
541
|
-
await this.requestOnce(
|
|
542
|
-
identity: this.controllerIdentity
|
|
562
|
+
await this.requestOnce("registerController", {
|
|
563
|
+
identity: this.controllerIdentity
|
|
543
564
|
}, {
|
|
544
565
|
ensureConnected: false,
|
|
545
566
|
retryOnDisconnect: false,
|
|
546
|
-
timeoutMs:
|
|
567
|
+
timeoutMs: 1e3
|
|
547
568
|
});
|
|
548
569
|
}
|
|
549
|
-
return this.requestOnce(
|
|
550
|
-
preparationToken
|
|
570
|
+
return this.requestOnce("resumeTerminalState", {
|
|
571
|
+
preparationToken
|
|
551
572
|
}, {
|
|
552
573
|
ensureConnected: false,
|
|
553
574
|
retryOnDisconnect: false,
|
|
554
|
-
timeoutMs:
|
|
575
|
+
timeoutMs: 1e3
|
|
555
576
|
});
|
|
556
577
|
}
|
|
557
|
-
|
|
558
578
|
async requirePreparedHostRotationResume(preparationToken, actual, primaryError) {
|
|
559
579
|
if (!preparationToken) return;
|
|
560
580
|
try {
|
|
@@ -563,106 +583,93 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
563
583
|
const recoveryError = new Error(
|
|
564
584
|
`Cannot confirm recovery of incompatible native PTY host (${actual}) after aborting rotation`
|
|
565
585
|
);
|
|
566
|
-
recoveryError.code =
|
|
586
|
+
recoveryError.code = "FARMING_NATIVE_HOST_ROTATION_RECOVERY_FAILED";
|
|
567
587
|
recoveryError.cause = new AggregateError(
|
|
568
588
|
[primaryError, resumeError].filter(Boolean),
|
|
569
|
-
|
|
589
|
+
"Native PTY rotation failed and the prepared host could not be resumed"
|
|
570
590
|
);
|
|
571
591
|
throw recoveryError;
|
|
572
592
|
}
|
|
573
593
|
}
|
|
574
|
-
|
|
575
594
|
async rotateMismatchedHost(hostInfo) {
|
|
576
595
|
const expected = runtimeIdentityLabel(this.expectedRuntimeIdentity);
|
|
577
596
|
const actual = runtimeIdentityLabel(hostInfo && hostInfo.runtimeIdentity);
|
|
578
597
|
console.warn(`Rotating native PTY host runtime: expected ${expected}, connected to ${actual}`);
|
|
579
|
-
this.emit(
|
|
598
|
+
this.emit("host-runtime-mismatch", {
|
|
580
599
|
expected: this.expectedRuntimeIdentity,
|
|
581
600
|
actual: hostInfo && hostInfo.runtimeIdentity || null,
|
|
582
|
-
pid: Number(hostInfo && hostInfo.pid) || null
|
|
601
|
+
pid: Number(hostInfo && hostInfo.pid) || null
|
|
583
602
|
});
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
identity: this.controllerIdentity,
|
|
603
|
+
await this.requestOnce("registerController", {
|
|
604
|
+
identity: this.controllerIdentity
|
|
587
605
|
}, {
|
|
588
606
|
ensureConnected: false,
|
|
589
607
|
retryOnDisconnect: false,
|
|
590
|
-
timeoutMs:
|
|
608
|
+
timeoutMs: 3e3
|
|
591
609
|
});
|
|
592
|
-
|
|
593
|
-
let
|
|
594
|
-
let preparationToken = '';
|
|
610
|
+
let serializedTerminalState = "";
|
|
611
|
+
let preparationToken = "";
|
|
595
612
|
try {
|
|
596
|
-
const preparation = await this.requestOnce(
|
|
613
|
+
const preparation = await this.requestOnce("serializeTerminalState", {}, {
|
|
597
614
|
ensureConnected: false,
|
|
598
615
|
retryOnDisconnect: false,
|
|
599
|
-
timeoutMs: Math.min(
|
|
616
|
+
timeoutMs: Math.min(5e3, this.hostRotationTimeoutMs)
|
|
600
617
|
});
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
) {
|
|
608
|
-
preparationToken = preparation.preparationToken;
|
|
609
|
-
serializedTerminalState = preparation.serializedTerminalState;
|
|
610
|
-
} else if (typeof preparation === 'string') {
|
|
611
|
-
const recovered = await this.requestOnce('recoverSessions', {}, {
|
|
618
|
+
const preparationRecord = preparation && typeof preparation === "object" ? preparation : null;
|
|
619
|
+
if (preparationRecord && typeof preparationRecord.preparationToken === "string" && preparationRecord.preparationToken && typeof preparationRecord.serializedTerminalState === "string") {
|
|
620
|
+
preparationToken = preparationRecord.preparationToken;
|
|
621
|
+
serializedTerminalState = preparationRecord.serializedTerminalState;
|
|
622
|
+
} else if (typeof preparation === "string") {
|
|
623
|
+
const recovered = await this.requestOnce("recoverSessions", {}, {
|
|
612
624
|
ensureConnected: false,
|
|
613
625
|
retryOnDisconnect: false,
|
|
614
|
-
timeoutMs: Math.min(
|
|
626
|
+
timeoutMs: Math.min(3e3, this.hostRotationTimeoutMs)
|
|
615
627
|
});
|
|
616
628
|
if (Array.isArray(recovered) && recovered.length === 0) {
|
|
617
629
|
serializedTerminalState = preparation;
|
|
618
630
|
} else {
|
|
619
|
-
throw new Error(
|
|
631
|
+
throw new Error("The old native PTY host cannot commit a transactional terminal checkpoint");
|
|
620
632
|
}
|
|
621
633
|
} else {
|
|
622
|
-
throw new Error(
|
|
634
|
+
throw new Error("The native PTY host returned an invalid rotation checkpoint");
|
|
623
635
|
}
|
|
624
636
|
} catch (error) {
|
|
625
637
|
if (preparationToken) {
|
|
626
638
|
await this.requirePreparedHostRotationResume(preparationToken, actual, error);
|
|
627
639
|
} else {
|
|
628
|
-
await this.resumePreparedHostRotation(
|
|
640
|
+
await this.resumePreparedHostRotation("").catch(() => {
|
|
641
|
+
});
|
|
629
642
|
}
|
|
630
|
-
const recovered = await this.requestOnce(
|
|
643
|
+
const recovered = await this.requestOnce("recoverSessions", {}, {
|
|
631
644
|
ensureConnected: false,
|
|
632
645
|
retryOnDisconnect: false,
|
|
633
|
-
timeoutMs: Math.min(
|
|
646
|
+
timeoutMs: Math.min(3e3, this.hostRotationTimeoutMs)
|
|
634
647
|
}).catch(() => null);
|
|
635
648
|
if (Array.isArray(recovered) && recovered.length === 0) {
|
|
636
|
-
serializedTerminalState =
|
|
637
|
-
preparationToken =
|
|
649
|
+
serializedTerminalState = "";
|
|
650
|
+
preparationToken = "";
|
|
638
651
|
} else {
|
|
639
652
|
const mismatchError = new Error(
|
|
640
653
|
`Cannot rotate incompatible native PTY host (${actual}) without a committed terminal checkpoint`
|
|
641
654
|
);
|
|
642
|
-
mismatchError.code =
|
|
655
|
+
mismatchError.code = "FARMING_NATIVE_HOST_RUNTIME_MISMATCH";
|
|
643
656
|
mismatchError.cause = error;
|
|
644
657
|
throw mismatchError;
|
|
645
658
|
}
|
|
646
659
|
}
|
|
647
|
-
|
|
648
660
|
let unresumableCodex;
|
|
649
661
|
try {
|
|
650
|
-
unresumableCodex = deserializeTerminalState(serializedTerminalState).find(entry => {
|
|
651
|
-
const metadata = entry.metadata
|
|
652
|
-
const provider = String(metadata.providerSessionProvider || metadata.provider ||
|
|
653
|
-
return provider ===
|
|
654
|
-
&& metadata.terminalInputReceived === true
|
|
655
|
-
&& (
|
|
656
|
-
metadata.providerSessionTemporary === true
|
|
657
|
-
|| isTemporaryProviderSessionId(metadata.providerSessionId)
|
|
658
|
-
);
|
|
662
|
+
unresumableCodex = (0, import_terminal_state_serialization.deserializeTerminalState)(serializedTerminalState).find((entry) => {
|
|
663
|
+
const metadata = entry.metadata;
|
|
664
|
+
const provider = String(metadata.providerSessionProvider || metadata.provider || "").trim();
|
|
665
|
+
return provider === "codex" && metadata.terminalInputReceived === true && (metadata.providerSessionTemporary === true || (0, import_provider_session_id.isTemporaryProviderSessionId)(metadata.providerSessionId));
|
|
659
666
|
});
|
|
660
667
|
} catch (error) {
|
|
661
668
|
await this.requirePreparedHostRotationResume(preparationToken, actual, error);
|
|
662
669
|
const mismatchError = new Error(
|
|
663
670
|
`Cannot rotate incompatible native PTY host (${actual}) with an invalid terminal checkpoint`
|
|
664
671
|
);
|
|
665
|
-
mismatchError.code =
|
|
672
|
+
mismatchError.code = "FARMING_NATIVE_HOST_RUNTIME_MISMATCH";
|
|
666
673
|
mismatchError.cause = error;
|
|
667
674
|
throw mismatchError;
|
|
668
675
|
}
|
|
@@ -674,23 +681,22 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
674
681
|
const mismatchError = new Error(
|
|
675
682
|
`Cannot rotate incompatible native PTY host (${actual}) while Codex session ${unresumableCodex.id} has user input but no exact resume id`
|
|
676
683
|
);
|
|
677
|
-
mismatchError.code =
|
|
684
|
+
mismatchError.code = "FARMING_NATIVE_HOST_UNRESUMABLE_SESSION";
|
|
678
685
|
mismatchError.cause = unresumableError;
|
|
679
686
|
throw mismatchError;
|
|
680
687
|
}
|
|
681
|
-
|
|
682
688
|
const privateSocketPath = this.connectedPrivateSocketPath(hostInfo);
|
|
683
689
|
const socket = this.socket;
|
|
684
690
|
if (socket) this.suppressedDisconnectSockets.add(socket);
|
|
685
691
|
let shutdownUncertain = false;
|
|
686
692
|
try {
|
|
687
|
-
await this.requestOnce(
|
|
693
|
+
await this.requestOnce("shutdownHost", {
|
|
688
694
|
controller: this.controllerIdentity,
|
|
689
|
-
preparationToken
|
|
695
|
+
preparationToken
|
|
690
696
|
}, {
|
|
691
697
|
ensureConnected: false,
|
|
692
698
|
retryOnDisconnect: false,
|
|
693
|
-
timeoutMs: Math.min(
|
|
699
|
+
timeoutMs: Math.min(5e3, this.hostRotationTimeoutMs)
|
|
694
700
|
});
|
|
695
701
|
} catch (error) {
|
|
696
702
|
if (!isConnectRetryable(error)) {
|
|
@@ -698,7 +704,7 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
698
704
|
const mismatchError = new Error(
|
|
699
705
|
`Cannot rotate incompatible native PTY host (${actual}); stop the old host and restart Farming`
|
|
700
706
|
);
|
|
701
|
-
mismatchError.code =
|
|
707
|
+
mismatchError.code = "FARMING_NATIVE_HOST_RUNTIME_MISMATCH";
|
|
702
708
|
mismatchError.cause = error;
|
|
703
709
|
throw mismatchError;
|
|
704
710
|
}
|
|
@@ -706,12 +712,11 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
706
712
|
} finally {
|
|
707
713
|
if (this.socket === socket) {
|
|
708
714
|
this.socket = null;
|
|
709
|
-
this.buffer =
|
|
715
|
+
this.buffer = "";
|
|
710
716
|
}
|
|
711
717
|
if (socket && !socket.destroyed) socket.destroy();
|
|
712
718
|
this.connectedHostInfo = null;
|
|
713
719
|
}
|
|
714
|
-
|
|
715
720
|
try {
|
|
716
721
|
await this.waitForHostRelease(privateSocketPath || this.connectedSocketPath);
|
|
717
722
|
} catch (error) {
|
|
@@ -719,27 +724,23 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
719
724
|
try {
|
|
720
725
|
await this.resumePreparedHostRotation(preparationToken);
|
|
721
726
|
} catch {
|
|
722
|
-
// The old host may have exited after the release timeout. Do not
|
|
723
|
-
// start a second host until the socket and child are actually gone.
|
|
724
727
|
}
|
|
725
728
|
}
|
|
726
729
|
const mismatchError = new Error(
|
|
727
730
|
`Cannot confirm shutdown of incompatible native PTY host (${actual}); restart Farming after the old host exits`
|
|
728
731
|
);
|
|
729
|
-
mismatchError.code =
|
|
732
|
+
mismatchError.code = "FARMING_NATIVE_HOST_RUNTIME_MISMATCH";
|
|
730
733
|
mismatchError.cause = error;
|
|
731
734
|
throw mismatchError;
|
|
732
735
|
}
|
|
733
736
|
this.spawnHost();
|
|
734
737
|
return serializedTerminalState;
|
|
735
738
|
}
|
|
736
|
-
|
|
737
739
|
consumeRuntimeRotation() {
|
|
738
740
|
const rotation = this.runtimeRotationInfo;
|
|
739
741
|
this.runtimeRotationInfo = null;
|
|
740
742
|
return rotation;
|
|
741
743
|
}
|
|
742
|
-
|
|
743
744
|
attachSocket(socket) {
|
|
744
745
|
if (this.socket && this.socket !== socket) {
|
|
745
746
|
this.socket.destroy();
|
|
@@ -747,28 +748,26 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
747
748
|
const generation = this.socketGeneration + 1;
|
|
748
749
|
this.socketGeneration = generation;
|
|
749
750
|
this.socket = socket;
|
|
750
|
-
this.buffer =
|
|
751
|
-
|
|
752
|
-
socket.on(
|
|
753
|
-
socket.on(
|
|
754
|
-
socket.on('error', error => {
|
|
751
|
+
this.buffer = "";
|
|
752
|
+
socket.on("data", (chunk) => this.handleData(chunk, socket, generation));
|
|
753
|
+
socket.on("close", () => this.handleDisconnect(socket, generation));
|
|
754
|
+
socket.on("error", (error) => {
|
|
755
755
|
if (this.socket !== socket || this.socketGeneration !== generation) return;
|
|
756
|
-
this.emit(
|
|
756
|
+
this.emit("host-error", error);
|
|
757
757
|
});
|
|
758
758
|
}
|
|
759
|
-
|
|
760
759
|
handleDisconnect(socket, generation = this.socketGeneration) {
|
|
761
760
|
if (socket && this.socket && this.socket !== socket) {
|
|
762
761
|
return;
|
|
763
762
|
}
|
|
764
763
|
if (generation !== this.socketGeneration) return;
|
|
765
764
|
this.socket = null;
|
|
766
|
-
this.buffer =
|
|
765
|
+
this.buffer = "";
|
|
767
766
|
this.connectedHostInfo = null;
|
|
768
|
-
this.connectedSocketPath =
|
|
767
|
+
this.connectedSocketPath = "";
|
|
769
768
|
if (this.disposed) return;
|
|
770
|
-
const error = new Error(
|
|
771
|
-
error.code =
|
|
769
|
+
const error = new Error("Native pty host disconnected");
|
|
770
|
+
error.code = "ECONNRESET";
|
|
772
771
|
this.pending.forEach(({ reject, timer }) => {
|
|
773
772
|
clearTimeout(timer);
|
|
774
773
|
reject(error);
|
|
@@ -777,33 +776,30 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
777
776
|
if (socket && this.suppressedDisconnectSockets.has(socket)) {
|
|
778
777
|
return;
|
|
779
778
|
}
|
|
780
|
-
this.emit(
|
|
779
|
+
this.emit("host-disconnect");
|
|
781
780
|
}
|
|
782
|
-
|
|
783
781
|
resetSocketAfterRequestError() {
|
|
784
782
|
const socket = this.socket;
|
|
785
783
|
this.socket = null;
|
|
786
|
-
this.buffer =
|
|
784
|
+
this.buffer = "";
|
|
787
785
|
if (socket && !socket.destroyed) {
|
|
788
786
|
this.suppressedDisconnectSockets.add(socket);
|
|
789
787
|
socket.destroy();
|
|
790
788
|
}
|
|
791
789
|
}
|
|
792
|
-
|
|
793
790
|
handleData(chunk, socket = this.socket, generation = this.socketGeneration) {
|
|
794
791
|
if (!socket || socket !== this.socket || generation !== this.socketGeneration) return;
|
|
795
|
-
this.buffer += chunk.toString(
|
|
796
|
-
let newline = this.buffer.indexOf(
|
|
792
|
+
this.buffer += Buffer.isBuffer(chunk) ? chunk.toString("utf8") : chunk;
|
|
793
|
+
let newline = this.buffer.indexOf("\n");
|
|
797
794
|
while (newline >= 0) {
|
|
798
795
|
const line = this.buffer.slice(0, newline);
|
|
799
796
|
this.buffer = this.buffer.slice(newline + 1);
|
|
800
797
|
if (line.trim()) {
|
|
801
798
|
this.handleMessage(line);
|
|
802
799
|
}
|
|
803
|
-
newline = this.buffer.indexOf(
|
|
800
|
+
newline = this.buffer.indexOf("\n");
|
|
804
801
|
}
|
|
805
802
|
}
|
|
806
|
-
|
|
807
803
|
handleMessage(line) {
|
|
808
804
|
let message;
|
|
809
805
|
try {
|
|
@@ -811,26 +807,21 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
811
807
|
} catch {
|
|
812
808
|
return;
|
|
813
809
|
}
|
|
814
|
-
|
|
815
810
|
if (message.event) {
|
|
816
811
|
this.emit(message.event, message.payload || {});
|
|
817
812
|
return;
|
|
818
813
|
}
|
|
819
|
-
|
|
820
814
|
if (!message.id) return;
|
|
821
815
|
const pending = this.pending.get(message.id);
|
|
822
816
|
if (!pending) return;
|
|
823
817
|
this.pending.delete(message.id);
|
|
824
818
|
clearTimeout(pending.timer);
|
|
825
|
-
|
|
826
819
|
if (message.ok === false) {
|
|
827
|
-
pending.reject(new Error(message.error ||
|
|
820
|
+
pending.reject(new Error(message.error || "Native pty host request failed"));
|
|
828
821
|
return;
|
|
829
822
|
}
|
|
830
|
-
|
|
831
823
|
pending.resolve(message.result);
|
|
832
824
|
}
|
|
833
|
-
|
|
834
825
|
async request(method, params = {}, options = {}) {
|
|
835
826
|
const retryOnDisconnect = isRequestRetryable(method, options);
|
|
836
827
|
try {
|
|
@@ -841,36 +832,40 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
841
832
|
return this.requestOnce(method, params, {
|
|
842
833
|
...options,
|
|
843
834
|
ensureConnected: false,
|
|
844
|
-
retryOnDisconnect: false
|
|
835
|
+
retryOnDisconnect: false
|
|
845
836
|
});
|
|
846
837
|
}
|
|
847
838
|
}
|
|
848
|
-
|
|
849
839
|
async requestOnce(method, params = {}, options = {}) {
|
|
850
840
|
if (options.ensureConnected !== false) {
|
|
851
841
|
await this.ensureConnected({ startHost: options.startHost });
|
|
852
842
|
}
|
|
853
843
|
if (!this.socket || this.socket.destroyed) {
|
|
854
|
-
throw new Error(
|
|
844
|
+
throw new Error("Native pty host is not connected");
|
|
855
845
|
}
|
|
856
|
-
|
|
846
|
+
const socket = this.socket;
|
|
857
847
|
const id = this.nextRequestId;
|
|
858
848
|
this.nextRequestId += 1;
|
|
859
849
|
const timeoutMs = options.timeoutMs || this.requestTimeoutMs;
|
|
860
|
-
const payload = `${JSON.stringify({ id, method, params })}
|
|
861
|
-
|
|
850
|
+
const payload = `${JSON.stringify({ id, method, params })}
|
|
851
|
+
`;
|
|
862
852
|
return new Promise((resolve, reject) => {
|
|
863
853
|
const timer = setTimeout(() => {
|
|
864
854
|
this.pending.delete(id);
|
|
865
|
-
const error = new Error(
|
|
866
|
-
|
|
855
|
+
const error = new Error(
|
|
856
|
+
`Native pty host request timed out: ${method}`
|
|
857
|
+
);
|
|
858
|
+
error.code = "ETIMEDOUT";
|
|
867
859
|
this.resetSocketAfterRequestError();
|
|
868
860
|
reject(error);
|
|
869
861
|
}, timeoutMs);
|
|
870
|
-
if (typeof timer.unref ===
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
862
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
863
|
+
this.pending.set(id, {
|
|
864
|
+
resolve: (value) => resolve(value),
|
|
865
|
+
reject,
|
|
866
|
+
timer
|
|
867
|
+
});
|
|
868
|
+
socket.write(payload, (error) => {
|
|
874
869
|
if (!error) return;
|
|
875
870
|
const pending = this.pending.get(id);
|
|
876
871
|
if (!pending) return;
|
|
@@ -883,29 +878,24 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
883
878
|
});
|
|
884
879
|
});
|
|
885
880
|
}
|
|
886
|
-
|
|
887
881
|
terminateSpawnedHost() {
|
|
888
882
|
const child = this.hostChild;
|
|
889
883
|
this.hostChild = null;
|
|
890
884
|
if (!child || child.killed) return;
|
|
891
|
-
|
|
892
885
|
try {
|
|
893
|
-
child.kill(
|
|
886
|
+
child.kill("SIGTERM");
|
|
894
887
|
} catch {
|
|
895
888
|
return;
|
|
896
889
|
}
|
|
897
|
-
|
|
898
890
|
const timer = setTimeout(() => {
|
|
899
891
|
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
900
892
|
try {
|
|
901
|
-
child.kill(
|
|
893
|
+
child.kill("SIGKILL");
|
|
902
894
|
} catch {
|
|
903
|
-
// ignore shutdown races
|
|
904
895
|
}
|
|
905
896
|
}, 1500);
|
|
906
|
-
if (typeof timer.unref ===
|
|
897
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
907
898
|
}
|
|
908
|
-
|
|
909
899
|
disconnect(options = {}) {
|
|
910
900
|
const preserveHost = options.preserveHost === true || this.preserveHostOnDisconnect;
|
|
911
901
|
this.disposed = true;
|
|
@@ -913,7 +903,7 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
913
903
|
this.socket.destroy();
|
|
914
904
|
this.socket = null;
|
|
915
905
|
}
|
|
916
|
-
const error = new Error(
|
|
906
|
+
const error = new Error("Native pty host client disconnected");
|
|
917
907
|
this.pending.forEach(({ reject, timer }) => {
|
|
918
908
|
clearTimeout(timer);
|
|
919
909
|
reject(error);
|
|
@@ -927,7 +917,9 @@ class NativePtyHostClient extends EventEmitter {
|
|
|
927
917
|
this.closeHostLogStream();
|
|
928
918
|
}
|
|
929
919
|
}
|
|
930
|
-
|
|
931
|
-
module.exports =
|
|
932
|
-
|
|
933
|
-
|
|
920
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
921
|
+
0 && (module.exports = {
|
|
922
|
+
NativePtyHostClient,
|
|
923
|
+
buildCleanEnvExecCommand,
|
|
924
|
+
nativeHostSpawnCommand
|
|
925
|
+
});
|