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,74 +0,0 @@
|
|
|
1
|
-
const DEFAULT_TERMINAL_ATTACH_CHECKPOINT_TIMEOUT_MS = 2000;
|
|
2
|
-
|
|
3
|
-
function finiteNonNegativeInteger(value) {
|
|
4
|
-
const parsed = Number(value);
|
|
5
|
-
return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : null;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function finitePositiveInteger(value) {
|
|
9
|
-
const parsed = Number(value);
|
|
10
|
-
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : null;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async function captureTerminalAttachCheckpoint(session, options = {}) {
|
|
14
|
-
if (session?.finalCheckpoint) {
|
|
15
|
-
return { ...session.finalCheckpoint };
|
|
16
|
-
}
|
|
17
|
-
if (
|
|
18
|
-
!session
|
|
19
|
-
|| !session.screenWorker
|
|
20
|
-
|| session.stateProofAvailable === false
|
|
21
|
-
|| typeof session.runtimeEpoch !== 'string'
|
|
22
|
-
|| !session.runtimeEpoch
|
|
23
|
-
) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const timeoutMs = Number.isFinite(options.timeoutMs)
|
|
28
|
-
? Math.max(1, Math.floor(options.timeoutMs))
|
|
29
|
-
: DEFAULT_TERMINAL_ATTACH_CHECKPOINT_TIMEOUT_MS;
|
|
30
|
-
const state = await session.screenWorker.getState({ timeoutMs }).catch(() => null);
|
|
31
|
-
const outputSeq = finiteNonNegativeInteger(state?.outputSeq);
|
|
32
|
-
const stateRevision = finiteNonNegativeInteger(state?.stateRevision);
|
|
33
|
-
const currentOutputSeq = finiteNonNegativeInteger(session.outputSeq);
|
|
34
|
-
const currentStateRevision = finiteNonNegativeInteger(session.stateRevision);
|
|
35
|
-
const cols = finitePositiveInteger(state?.cols);
|
|
36
|
-
const rows = finitePositiveInteger(state?.rows);
|
|
37
|
-
const requireCurrentCut = options.requireCurrentCut === true;
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
!state
|
|
41
|
-
|| state.runtimeEpoch !== session.runtimeEpoch
|
|
42
|
-
|| outputSeq === null
|
|
43
|
-
|| stateRevision === null
|
|
44
|
-
|| currentOutputSeq === null
|
|
45
|
-
|| currentStateRevision === null
|
|
46
|
-
|| stateRevision < outputSeq
|
|
47
|
-
|| outputSeq > currentOutputSeq
|
|
48
|
-
|| stateRevision > currentStateRevision
|
|
49
|
-
|| (requireCurrentCut && outputSeq !== currentOutputSeq)
|
|
50
|
-
|| (requireCurrentCut && stateRevision !== currentStateRevision)
|
|
51
|
-
|| cols === null
|
|
52
|
-
|| rows === null
|
|
53
|
-
|| typeof state.renderOutput !== 'string'
|
|
54
|
-
) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
runtimeEpoch: state.runtimeEpoch,
|
|
60
|
-
renderOutput: state.renderOutput,
|
|
61
|
-
outputSeq,
|
|
62
|
-
stateRevision,
|
|
63
|
-
cols,
|
|
64
|
-
rows,
|
|
65
|
-
previewText: typeof state.previewText === 'string' ? state.previewText : '',
|
|
66
|
-
previewSnapshot: state.previewSnapshot || null,
|
|
67
|
-
title: typeof state.title === 'string' ? state.title : '',
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
module.exports = {
|
|
72
|
-
DEFAULT_TERMINAL_ATTACH_CHECKPOINT_TIMEOUT_MS,
|
|
73
|
-
captureTerminalAttachCheckpoint,
|
|
74
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const DEFAULT_TERMINAL_EXIT_DATA_FLUSH_MS = 250;
|
|
2
|
-
|
|
3
|
-
function delay(ms) {
|
|
4
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
function acceptTerminalExitData(session) {
|
|
8
|
-
if (!session || session.exitDataClosed === true) return false;
|
|
9
|
-
if (session.exitFinalizing === true) {
|
|
10
|
-
session.exitDataGeneration = (session.exitDataGeneration || 0) + 1;
|
|
11
|
-
}
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function waitForTerminalExitDataQuiescence(session, options = {}) {
|
|
16
|
-
const isCurrent = typeof options.isCurrent === 'function' ? options.isCurrent : () => true;
|
|
17
|
-
const flushMs = Number.isFinite(options.flushMs)
|
|
18
|
-
? Math.max(1, Math.floor(options.flushMs))
|
|
19
|
-
: DEFAULT_TERMINAL_EXIT_DATA_FLUSH_MS;
|
|
20
|
-
session.exitFinalizing = true;
|
|
21
|
-
session.exitDataGeneration = session.exitDataGeneration || 0;
|
|
22
|
-
|
|
23
|
-
for (;;) {
|
|
24
|
-
const observedGeneration = session.exitDataGeneration;
|
|
25
|
-
await delay(flushMs);
|
|
26
|
-
if (!isCurrent()) return false;
|
|
27
|
-
if (session.exitDataGeneration !== observedGeneration) continue;
|
|
28
|
-
// This synchronous cut closes late-data admission before the reducer is
|
|
29
|
-
// drained and its final checkpoint is captured.
|
|
30
|
-
session.exitDataClosed = true;
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
module.exports = {
|
|
36
|
-
DEFAULT_TERMINAL_EXIT_DATA_FLUSH_MS,
|
|
37
|
-
acceptTerminalExitData,
|
|
38
|
-
waitForTerminalExitDataQuiescence,
|
|
39
|
-
};
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const net = require('net');
|
|
3
|
-
const os = require('os');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const { nativePtyHostSocketPath } = require('./native-pty-host-path');
|
|
6
|
-
|
|
7
|
-
function canUseUnixSocket(socketPath) {
|
|
8
|
-
return process.platform !== 'win32' && typeof socketPath === 'string' && socketPath.length > 0;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function socketExists(socketPath) {
|
|
12
|
-
try {
|
|
13
|
-
fs.accessSync(socketPath);
|
|
14
|
-
return true;
|
|
15
|
-
} catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function probeUnixSocket(socketPath, timeoutMs = 120) {
|
|
21
|
-
if (!canUseUnixSocket(socketPath)) {
|
|
22
|
-
return Promise.resolve({ active: false, code: 'unsupported' });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return new Promise(resolve => {
|
|
26
|
-
const socket = net.createConnection(socketPath);
|
|
27
|
-
let settled = false;
|
|
28
|
-
const finish = result => {
|
|
29
|
-
if (settled) return;
|
|
30
|
-
settled = true;
|
|
31
|
-
clearTimeout(timer);
|
|
32
|
-
socket.destroy();
|
|
33
|
-
resolve(result);
|
|
34
|
-
};
|
|
35
|
-
const timer = setTimeout(() => finish({ active: false, code: 'timeout' }), timeoutMs);
|
|
36
|
-
if (typeof timer.unref === 'function') timer.unref();
|
|
37
|
-
socket.once('connect', () => finish({ active: true }));
|
|
38
|
-
socket.once('error', error => finish({ active: false, code: error && error.code ? error.code : 'error' }));
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async function cleanupStaleNativePtySocket(options = {}) {
|
|
43
|
-
const socketPath = options.socketPath || nativePtyHostSocketPath(options.configDir);
|
|
44
|
-
if (!canUseUnixSocket(socketPath) || !socketExists(socketPath)) {
|
|
45
|
-
return { socketPath, removed: false, active: false };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const probe = await probeUnixSocket(socketPath, options.timeoutMs);
|
|
49
|
-
if (probe.active) {
|
|
50
|
-
return { socketPath, removed: false, active: true };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
fs.unlinkSync(socketPath);
|
|
55
|
-
return { socketPath, removed: true, active: false, code: probe.code };
|
|
56
|
-
} catch (error) {
|
|
57
|
-
if (error && error.code === 'ENOENT') {
|
|
58
|
-
return { socketPath, removed: false, active: false, code: probe.code };
|
|
59
|
-
}
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function cleanupTerminalRuntime(options = {}) {
|
|
65
|
-
if (process.env.FARMING_SKIP_TERMINAL_RUNTIME_CLEANUP === '1') {
|
|
66
|
-
return { skipped: true };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const configDir = options.configDir || process.env.FARMING_CONFIG_DIR || path.join(os.homedir(), '.farming');
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
nativeSocket: await cleanupStaleNativePtySocket({ ...options, configDir }),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
module.exports = {
|
|
77
|
-
cleanupStaleNativePtySocket,
|
|
78
|
-
cleanupTerminalRuntime,
|
|
79
|
-
probeUnixSocket,
|
|
80
|
-
};
|
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const EventEmitter = require('events');
|
|
4
|
-
const { Worker } = require('worker_threads');
|
|
5
|
-
|
|
6
|
-
const APPEND_FLUSH_INTERVAL_MS = 16;
|
|
7
|
-
const MAX_PENDING_APPEND_BYTES = 128 * 1024;
|
|
8
|
-
const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
9
|
-
const DEFAULT_STATE_REQUEST_HARD_TIMEOUT_MS = 5000;
|
|
10
|
-
const PACKAGED_WORKER_FILE = 'terminal-screen-worker-thread.pkg.js';
|
|
11
|
-
const SOURCE_WORKER_FILE = 'terminal-screen-worker-thread.js';
|
|
12
|
-
|
|
13
|
-
function byteLength(value) {
|
|
14
|
-
return Buffer.byteLength(String(value || ''), 'utf8');
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function resolveWorkerFile() {
|
|
18
|
-
const wantsPackagedWorker = process.pkg || process.env.FARMING_PACKAGED_RUNTIME === '1';
|
|
19
|
-
if (!wantsPackagedWorker) return SOURCE_WORKER_FILE;
|
|
20
|
-
|
|
21
|
-
const packagedWorkerPath = path.join(__dirname, PACKAGED_WORKER_FILE);
|
|
22
|
-
return fs.existsSync(packagedWorkerPath)
|
|
23
|
-
? PACKAGED_WORKER_FILE
|
|
24
|
-
: SOURCE_WORKER_FILE;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
class TerminalScreenWorker extends EventEmitter {
|
|
28
|
-
constructor(options = {}) {
|
|
29
|
-
super();
|
|
30
|
-
this.nextRequestId = 1;
|
|
31
|
-
this.pendingRequests = new Map();
|
|
32
|
-
this.pendingAppendEntries = [];
|
|
33
|
-
this.pendingAppendBytes = 0;
|
|
34
|
-
this.pendingAppendWaiters = [];
|
|
35
|
-
this.appendFlushTimer = null;
|
|
36
|
-
this.stateRequestInFlight = null;
|
|
37
|
-
this.requestTimeoutMs = Number.isFinite(options.requestTimeoutMs)
|
|
38
|
-
? Math.max(1, Math.floor(options.requestTimeoutMs))
|
|
39
|
-
: DEFAULT_REQUEST_TIMEOUT_MS;
|
|
40
|
-
this.stateRequestHardTimeoutMs = Number.isFinite(options.stateRequestHardTimeoutMs)
|
|
41
|
-
? Math.max(1, Math.floor(options.stateRequestHardTimeoutMs))
|
|
42
|
-
: Math.min(this.requestTimeoutMs, DEFAULT_STATE_REQUEST_HARD_TIMEOUT_MS);
|
|
43
|
-
this.failed = false;
|
|
44
|
-
this.disposed = false;
|
|
45
|
-
const workerFile = resolveWorkerFile();
|
|
46
|
-
const WorkerClass = options.WorkerClass || Worker;
|
|
47
|
-
const workerData = { ...options };
|
|
48
|
-
delete workerData.WorkerClass;
|
|
49
|
-
delete workerData.requestTimeoutMs;
|
|
50
|
-
delete workerData.stateRequestHardTimeoutMs;
|
|
51
|
-
this.worker = new WorkerClass(path.join(__dirname, workerFile), {
|
|
52
|
-
workerData,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
this.worker.on('message', (message) => {
|
|
56
|
-
if (!message || typeof message !== 'object') {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (message.type === 'preview') {
|
|
61
|
-
this.emit('preview', {
|
|
62
|
-
previewText: message.previewText || '',
|
|
63
|
-
title: message.title || '',
|
|
64
|
-
cols: message.cols || 0,
|
|
65
|
-
rows: message.rows || 0,
|
|
66
|
-
previewSnapshot: message.previewSnapshot || null,
|
|
67
|
-
});
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (message.type === 'response' && message.requestId) {
|
|
72
|
-
const pending = this.pendingRequests.get(message.requestId);
|
|
73
|
-
if (!pending) return;
|
|
74
|
-
this.pendingRequests.delete(message.requestId);
|
|
75
|
-
clearTimeout(pending.timer);
|
|
76
|
-
if (message.error) {
|
|
77
|
-
pending.reject(new Error(message.error));
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
pending.resolve(message.payload);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (message.type === 'error') {
|
|
85
|
-
this.emit('error', new Error(message.message || 'Unknown worker error'));
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
this.worker.on('error', (error) => {
|
|
90
|
-
this.handleWorkerFailure(error);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.worker.on('exit', (code) => {
|
|
94
|
-
if (this.disposed) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
this.handleWorkerFailure(new Error(`Terminal screen worker exited unexpectedly with code ${code}`));
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
handleWorkerFailure(error) {
|
|
103
|
-
if (this.disposed) return;
|
|
104
|
-
const failure = error instanceof Error ? error : new Error(String(error));
|
|
105
|
-
const shouldEmit = !this.failed;
|
|
106
|
-
this.failed = true;
|
|
107
|
-
if (this.appendFlushTimer) {
|
|
108
|
-
clearTimeout(this.appendFlushTimer);
|
|
109
|
-
this.appendFlushTimer = null;
|
|
110
|
-
}
|
|
111
|
-
this.pendingAppendEntries = [];
|
|
112
|
-
this.pendingAppendBytes = 0;
|
|
113
|
-
this.pendingAppendWaiters.splice(0).forEach(({ reject }) => reject(failure));
|
|
114
|
-
this.pendingRequests.forEach(({ reject, timer }) => {
|
|
115
|
-
clearTimeout(timer);
|
|
116
|
-
reject(failure);
|
|
117
|
-
});
|
|
118
|
-
this.pendingRequests.clear();
|
|
119
|
-
if (shouldEmit && this.listenerCount('error') > 0) {
|
|
120
|
-
this.emit('error', failure);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
handlePostMessageFailure(error) {
|
|
125
|
-
this.handleWorkerFailure(error);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
postWorkerMessage(message, options = {}) {
|
|
129
|
-
try {
|
|
130
|
-
this.worker.postMessage(message);
|
|
131
|
-
return true;
|
|
132
|
-
} catch (error) {
|
|
133
|
-
if (options.throwOnError) throw error;
|
|
134
|
-
this.handlePostMessageFailure(error);
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
flushAppend() {
|
|
140
|
-
if (this.appendFlushTimer) {
|
|
141
|
-
clearTimeout(this.appendFlushTimer);
|
|
142
|
-
this.appendFlushTimer = null;
|
|
143
|
-
}
|
|
144
|
-
if (this.disposed || this.failed || this.pendingAppendEntries.length === 0) {
|
|
145
|
-
this.pendingAppendEntries = [];
|
|
146
|
-
this.pendingAppendBytes = 0;
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const entries = this.pendingAppendEntries;
|
|
151
|
-
const waiters = this.pendingAppendWaiters;
|
|
152
|
-
this.pendingAppendEntries = [];
|
|
153
|
-
this.pendingAppendBytes = 0;
|
|
154
|
-
this.pendingAppendWaiters = [];
|
|
155
|
-
this.request('append', { entries }, { flushAppend: false }).then(
|
|
156
|
-
state => waiters.forEach(({ resolve }) => resolve(state)),
|
|
157
|
-
error => waiters.forEach(({ reject }) => reject(error)),
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
request(type, payload = {}, options = {}) {
|
|
162
|
-
if (this.disposed) {
|
|
163
|
-
return Promise.reject(new Error('Terminal screen worker is disposed'));
|
|
164
|
-
}
|
|
165
|
-
if (this.failed) {
|
|
166
|
-
return Promise.reject(new Error('Terminal screen worker is not available'));
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (options.flushAppend !== false) {
|
|
170
|
-
this.flushAppend();
|
|
171
|
-
}
|
|
172
|
-
if (this.failed) {
|
|
173
|
-
return Promise.reject(new Error('Terminal screen worker is not available'));
|
|
174
|
-
}
|
|
175
|
-
const requestId = this.nextRequestId;
|
|
176
|
-
this.nextRequestId += 1;
|
|
177
|
-
|
|
178
|
-
return new Promise((resolve, reject) => {
|
|
179
|
-
const requestTimeoutMs = Number.isFinite(options.timeoutMs)
|
|
180
|
-
? Math.max(1, Math.floor(options.timeoutMs))
|
|
181
|
-
: this.requestTimeoutMs;
|
|
182
|
-
const timer = setTimeout(() => {
|
|
183
|
-
this.pendingRequests.delete(requestId);
|
|
184
|
-
const error = new Error(`Terminal screen worker request timed out: ${type}`);
|
|
185
|
-
error.code = 'ETIMEDOUT';
|
|
186
|
-
reject(error);
|
|
187
|
-
}, requestTimeoutMs);
|
|
188
|
-
if (typeof timer.unref === 'function') timer.unref();
|
|
189
|
-
|
|
190
|
-
this.pendingRequests.set(requestId, { resolve, reject, timer });
|
|
191
|
-
try {
|
|
192
|
-
this.postWorkerMessage({
|
|
193
|
-
requestId,
|
|
194
|
-
type,
|
|
195
|
-
...payload,
|
|
196
|
-
}, { throwOnError: true });
|
|
197
|
-
} catch (error) {
|
|
198
|
-
this.pendingRequests.delete(requestId);
|
|
199
|
-
clearTimeout(timer);
|
|
200
|
-
this.handlePostMessageFailure(error);
|
|
201
|
-
reject(error);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
append(data, stateRevision, outputSeq = null) {
|
|
207
|
-
if (this.disposed || this.failed) {
|
|
208
|
-
return Promise.reject(new Error('Terminal screen worker is not available'));
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const text = String(data || '');
|
|
212
|
-
if (!text) return;
|
|
213
|
-
if (!Number.isFinite(stateRevision)) {
|
|
214
|
-
this.handlePostMessageFailure(new Error('Terminal screen append requires a finite state revision'));
|
|
215
|
-
return Promise.reject(new Error('Terminal screen append requires a finite state revision'));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (
|
|
219
|
-
this.pendingAppendEntries.length > 0 &&
|
|
220
|
-
this.pendingAppendBytes + byteLength(text) > MAX_PENDING_APPEND_BYTES
|
|
221
|
-
) {
|
|
222
|
-
this.flushAppend();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return new Promise((resolve, reject) => {
|
|
226
|
-
this.pendingAppendEntries.push({ data: text, stateRevision, outputSeq });
|
|
227
|
-
this.pendingAppendBytes += byteLength(text);
|
|
228
|
-
this.pendingAppendWaiters.push({ resolve, reject });
|
|
229
|
-
if (byteLength(text) > MAX_PENDING_APPEND_BYTES) {
|
|
230
|
-
this.flushAppend();
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
if (this.appendFlushTimer) return;
|
|
234
|
-
this.appendFlushTimer = setTimeout(() => {
|
|
235
|
-
this.flushAppend();
|
|
236
|
-
}, APPEND_FLUSH_INTERVAL_MS);
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
resize(cols, rows, stateRevision) {
|
|
241
|
-
return this.request('resize', { cols, rows, stateRevision });
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
setRuntimeEpoch(runtimeEpoch, cols, rows) {
|
|
245
|
-
return this.request('set-runtime-epoch', { runtimeEpoch, cols, rows });
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
clear(stateRevision, outputSeq = null) {
|
|
249
|
-
return this.request('clear', { stateRevision, outputSeq });
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
getState(options = {}) {
|
|
253
|
-
if (!this.stateRequestInFlight) {
|
|
254
|
-
const request = this.request('get-state', {
|
|
255
|
-
// A full checkpoint can satisfy callers that only need metadata too,
|
|
256
|
-
// while the reverse would make coalescing unsafe.
|
|
257
|
-
includeRenderOutput: true,
|
|
258
|
-
}, {
|
|
259
|
-
// Caller deadlines are deliberately softer than this shared deadline.
|
|
260
|
-
// A timed-out caller may stop waiting, but the single-flight itself
|
|
261
|
-
// must never poison every later checkpoint for the generic 30s worker
|
|
262
|
-
// request timeout. Crossing this hard deadline means the authoritative
|
|
263
|
-
// reducer can no longer prove progress, so fail it closed.
|
|
264
|
-
timeoutMs: this.stateRequestHardTimeoutMs,
|
|
265
|
-
});
|
|
266
|
-
const sharedRequest = request.catch((error) => {
|
|
267
|
-
if (error && error.code === 'ETIMEDOUT') {
|
|
268
|
-
this.handleWorkerFailure(error);
|
|
269
|
-
}
|
|
270
|
-
throw error;
|
|
271
|
-
}).finally(() => {
|
|
272
|
-
if (this.stateRequestInFlight === sharedRequest) {
|
|
273
|
-
this.stateRequestInFlight = null;
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
this.stateRequestInFlight = sharedRequest;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const sharedRequest = this.stateRequestInFlight;
|
|
280
|
-
const timeoutMs = Number.isFinite(options.timeoutMs)
|
|
281
|
-
? Math.max(1, Math.floor(options.timeoutMs))
|
|
282
|
-
: null;
|
|
283
|
-
if (timeoutMs === null) return sharedRequest;
|
|
284
|
-
|
|
285
|
-
return new Promise((resolve, reject) => {
|
|
286
|
-
const timer = setTimeout(() => {
|
|
287
|
-
const error = new Error('Terminal screen worker request timed out: get-state');
|
|
288
|
-
error.code = 'ETIMEDOUT';
|
|
289
|
-
reject(error);
|
|
290
|
-
}, timeoutMs);
|
|
291
|
-
if (typeof timer.unref === 'function') timer.unref();
|
|
292
|
-
sharedRequest.then(
|
|
293
|
-
(state) => {
|
|
294
|
-
clearTimeout(timer);
|
|
295
|
-
resolve(state);
|
|
296
|
-
},
|
|
297
|
-
(error) => {
|
|
298
|
-
clearTimeout(timer);
|
|
299
|
-
reject(error);
|
|
300
|
-
},
|
|
301
|
-
);
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
async dispose() {
|
|
306
|
-
if (this.disposed) {
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
try {
|
|
311
|
-
await this.request('dispose');
|
|
312
|
-
} catch {
|
|
313
|
-
// best effort
|
|
314
|
-
}
|
|
315
|
-
if (this.appendFlushTimer) {
|
|
316
|
-
clearTimeout(this.appendFlushTimer);
|
|
317
|
-
this.appendFlushTimer = null;
|
|
318
|
-
}
|
|
319
|
-
this.pendingAppendEntries = [];
|
|
320
|
-
this.pendingAppendBytes = 0;
|
|
321
|
-
this.pendingAppendWaiters.splice(0).forEach(({ reject }) => {
|
|
322
|
-
reject(new Error('Terminal screen worker is disposed'));
|
|
323
|
-
});
|
|
324
|
-
this.disposed = true;
|
|
325
|
-
this.pendingRequests.forEach(({ reject, timer }) => {
|
|
326
|
-
clearTimeout(timer);
|
|
327
|
-
reject(new Error('Terminal screen worker disposed'));
|
|
328
|
-
});
|
|
329
|
-
this.pendingRequests.clear();
|
|
330
|
-
await this.worker.terminate();
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
module.exports = TerminalScreenWorker;
|
|
335
|
-
module.exports.resolveWorkerFile = resolveWorkerFile;
|
|
336
|
-
module.exports.DEFAULT_REQUEST_TIMEOUT_MS = DEFAULT_REQUEST_TIMEOUT_MS;
|
|
337
|
-
module.exports.DEFAULT_STATE_REQUEST_HARD_TIMEOUT_MS = DEFAULT_STATE_REQUEST_HARD_TIMEOUT_MS;
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
const TERMINAL_STATE_VERSION = 1;
|
|
2
|
-
const MAX_SERIALIZED_TERMINAL_STATE_BYTES = 32 * 1024 * 1024;
|
|
3
|
-
const MAX_REPLAY_EVENT_BYTES = 8 * 1024 * 1024;
|
|
4
|
-
|
|
5
|
-
function finitePositiveInteger(value, fallback) {
|
|
6
|
-
const parsed = Math.floor(Number(value));
|
|
7
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function normalizeReplayEvent(replayEvent) {
|
|
11
|
-
const events = Array.isArray(replayEvent?.events) ? replayEvent.events : [];
|
|
12
|
-
if (events.length !== 1) {
|
|
13
|
-
throw new Error('Serialized terminal state requires exactly one replay event');
|
|
14
|
-
}
|
|
15
|
-
const event = events[0] || {};
|
|
16
|
-
const data = typeof event.data === 'string' ? event.data : '';
|
|
17
|
-
if (Buffer.byteLength(data, 'utf8') > MAX_REPLAY_EVENT_BYTES) {
|
|
18
|
-
throw new Error('Serialized terminal replay event exceeds the size limit');
|
|
19
|
-
}
|
|
20
|
-
return {
|
|
21
|
-
events: [{
|
|
22
|
-
data,
|
|
23
|
-
cols: finitePositiveInteger(event.cols, 80),
|
|
24
|
-
rows: finitePositiveInteger(event.rows, 30),
|
|
25
|
-
}],
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function normalizeTerminalStateEntry(entry) {
|
|
30
|
-
if (!entry || typeof entry !== 'object') {
|
|
31
|
-
throw new Error('Serialized terminal state entry must be an object');
|
|
32
|
-
}
|
|
33
|
-
const id = typeof entry.id === 'string' ? entry.id.trim() : '';
|
|
34
|
-
if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,199}$/.test(id)) {
|
|
35
|
-
throw new Error('Serialized terminal state has an invalid session id');
|
|
36
|
-
}
|
|
37
|
-
const metadata = entry.metadata && typeof entry.metadata === 'object' && !Array.isArray(entry.metadata)
|
|
38
|
-
? { ...entry.metadata }
|
|
39
|
-
: {};
|
|
40
|
-
const processDetails = entry.processDetails && typeof entry.processDetails === 'object'
|
|
41
|
-
? entry.processDetails
|
|
42
|
-
: {};
|
|
43
|
-
const processLaunchConfig = entry.processLaunchConfig && typeof entry.processLaunchConfig === 'object'
|
|
44
|
-
? entry.processLaunchConfig
|
|
45
|
-
: {};
|
|
46
|
-
return {
|
|
47
|
-
id,
|
|
48
|
-
metadata: {
|
|
49
|
-
...metadata,
|
|
50
|
-
agentId: id,
|
|
51
|
-
},
|
|
52
|
-
processDetails: {
|
|
53
|
-
cwd: typeof processDetails.cwd === 'string' ? processDetails.cwd : '',
|
|
54
|
-
title: typeof processDetails.title === 'string' ? processDetails.title : '',
|
|
55
|
-
},
|
|
56
|
-
processLaunchConfig: {
|
|
57
|
-
command: typeof processLaunchConfig.command === 'string' ? processLaunchConfig.command : '',
|
|
58
|
-
args: Array.isArray(processLaunchConfig.args)
|
|
59
|
-
? processLaunchConfig.args.filter(arg => typeof arg === 'string')
|
|
60
|
-
: [],
|
|
61
|
-
category: typeof processLaunchConfig.category === 'string' ? processLaunchConfig.category : '',
|
|
62
|
-
},
|
|
63
|
-
replayEvent: normalizeReplayEvent(entry.replayEvent),
|
|
64
|
-
timestamp: Number.isFinite(Number(entry.timestamp))
|
|
65
|
-
? Math.max(0, Math.floor(Number(entry.timestamp)))
|
|
66
|
-
: Date.now(),
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function serializeTerminalState(entries) {
|
|
71
|
-
const state = (Array.isArray(entries) ? entries : []).map(normalizeTerminalStateEntry);
|
|
72
|
-
const ids = new Set();
|
|
73
|
-
for (const entry of state) {
|
|
74
|
-
if (ids.has(entry.id)) {
|
|
75
|
-
throw new Error(`Serialized terminal state contains duplicate session id ${entry.id}`);
|
|
76
|
-
}
|
|
77
|
-
ids.add(entry.id);
|
|
78
|
-
}
|
|
79
|
-
const serialized = JSON.stringify({
|
|
80
|
-
version: TERMINAL_STATE_VERSION,
|
|
81
|
-
state,
|
|
82
|
-
});
|
|
83
|
-
if (Buffer.byteLength(serialized, 'utf8') > MAX_SERIALIZED_TERMINAL_STATE_BYTES) {
|
|
84
|
-
throw new Error('Serialized terminal state exceeds the size limit');
|
|
85
|
-
}
|
|
86
|
-
return serialized;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function deserializeTerminalState(serialized) {
|
|
90
|
-
if (typeof serialized !== 'string' || !serialized) return [];
|
|
91
|
-
if (Buffer.byteLength(serialized, 'utf8') > MAX_SERIALIZED_TERMINAL_STATE_BYTES) {
|
|
92
|
-
throw new Error('Serialized terminal state exceeds the size limit');
|
|
93
|
-
}
|
|
94
|
-
let parsed;
|
|
95
|
-
try {
|
|
96
|
-
parsed = JSON.parse(serialized);
|
|
97
|
-
} catch {
|
|
98
|
-
throw new Error('Serialized terminal state is not valid JSON');
|
|
99
|
-
}
|
|
100
|
-
if (!parsed || typeof parsed !== 'object' || parsed.version !== TERMINAL_STATE_VERSION || !Array.isArray(parsed.state)) {
|
|
101
|
-
throw new Error('Serialized terminal state has an unsupported format or version');
|
|
102
|
-
}
|
|
103
|
-
const state = parsed.state.map(normalizeTerminalStateEntry);
|
|
104
|
-
const ids = new Set();
|
|
105
|
-
for (const entry of state) {
|
|
106
|
-
if (ids.has(entry.id)) {
|
|
107
|
-
throw new Error(`Serialized terminal state contains duplicate session id ${entry.id}`);
|
|
108
|
-
}
|
|
109
|
-
ids.add(entry.id);
|
|
110
|
-
}
|
|
111
|
-
return state;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function terminalReplayText(entry) {
|
|
115
|
-
const normalized = normalizeTerminalStateEntry(entry);
|
|
116
|
-
return normalized.replayEvent.events[0].data;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
module.exports = {
|
|
120
|
-
MAX_REPLAY_EVENT_BYTES,
|
|
121
|
-
MAX_SERIALIZED_TERMINAL_STATE_BYTES,
|
|
122
|
-
TERMINAL_STATE_VERSION,
|
|
123
|
-
deserializeTerminalState,
|
|
124
|
-
normalizeTerminalStateEntry,
|
|
125
|
-
serializeTerminalState,
|
|
126
|
-
terminalReplayText,
|
|
127
|
-
};
|