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,183 +1,217 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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 local_session_engine_exports = {};
|
|
31
|
+
__export(local_session_engine_exports, {
|
|
32
|
+
LocalSessionEngine: () => LocalSessionEngine,
|
|
33
|
+
createPtyProcess: () => createPtyProcess,
|
|
34
|
+
extractLatestTerminalTitle: () => extractLatestTerminalTitle,
|
|
35
|
+
normalizeShellSessionOptions: () => normalizeShellSessionOptions
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(local_session_engine_exports);
|
|
38
|
+
var path = __toESM(require("path"));
|
|
39
|
+
var import_terminal_screen_worker_pool = require("./terminal-screen-worker-pool.cjs");
|
|
40
|
+
var sessionEngineModule = __toESM(require("./session-engine.cjs"));
|
|
41
|
+
var shellBusyIntegrationModule = __toESM(require("./shell-busy-integration.cjs"));
|
|
42
|
+
var inputPartsModule = __toESM(require("./input-parts.cjs"));
|
|
43
|
+
var terminalStatusModule = __toESM(require("./terminal-status.cjs"));
|
|
44
|
+
var agentEnvModule = __toESM(require("./agent-env.cjs"));
|
|
45
|
+
var runtimeGenerationModule = __toESM(require("./native-pty-controller-generation.cjs"));
|
|
46
|
+
var storageLayout = __toESM(require("./storage-layout.cjs"));
|
|
47
|
+
var reducerFlowControlModule = __toESM(require("./terminal-reducer-flow-control.cjs"));
|
|
48
|
+
var terminalAttachCheckpointModule = __toESM(require("./terminal-attach-checkpoint.cjs"));
|
|
49
|
+
var terminalExitQuiescenceModule = __toESM(require("./terminal-exit-quiescence.cjs"));
|
|
50
|
+
const { SessionEngine } = sessionEngineModule;
|
|
4
51
|
const {
|
|
5
52
|
applyShellBusyIntegration,
|
|
6
53
|
cleanupShellBusyIntegration,
|
|
7
|
-
parseShellBusyMarkers
|
|
8
|
-
} =
|
|
9
|
-
const { terminalInputToPtyString } =
|
|
10
|
-
const { deriveTerminalStatus } =
|
|
11
|
-
const { normalizeInteractiveTerminalEnv } =
|
|
54
|
+
parseShellBusyMarkers
|
|
55
|
+
} = shellBusyIntegrationModule;
|
|
56
|
+
const { terminalInputToPtyString } = inputPartsModule;
|
|
57
|
+
const { deriveTerminalStatus } = terminalStatusModule;
|
|
58
|
+
const { normalizeInteractiveTerminalEnv } = agentEnvModule;
|
|
12
59
|
const {
|
|
13
60
|
allocateNativePtyRuntimeGeneration,
|
|
14
|
-
formatNativePtyRuntimeEpoch
|
|
15
|
-
} =
|
|
16
|
-
const storageLayout = require('./storage-layout');
|
|
61
|
+
formatNativePtyRuntimeEpoch
|
|
62
|
+
} = runtimeGenerationModule;
|
|
17
63
|
const {
|
|
18
64
|
acknowledgeTerminalReducerData,
|
|
19
65
|
createTerminalReducerFlowControl,
|
|
20
66
|
ensureTerminalReducerFlowControl,
|
|
21
67
|
enqueueTerminalReducerData,
|
|
22
|
-
resetTerminalReducerFlowControl
|
|
23
|
-
} =
|
|
24
|
-
const {
|
|
25
|
-
captureTerminalAttachCheckpoint,
|
|
26
|
-
} = require('./terminal-attach-checkpoint');
|
|
68
|
+
resetTerminalReducerFlowControl
|
|
69
|
+
} = reducerFlowControlModule;
|
|
70
|
+
const { captureTerminalAttachCheckpoint } = terminalAttachCheckpointModule;
|
|
27
71
|
const {
|
|
28
72
|
acceptTerminalExitData,
|
|
29
|
-
waitForTerminalExitDataQuiescence
|
|
30
|
-
} =
|
|
31
|
-
|
|
73
|
+
waitForTerminalExitDataQuiescence
|
|
74
|
+
} = terminalExitQuiescenceModule;
|
|
32
75
|
const CONTROLLED_BASH_PROMPT = [
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
].join(
|
|
38
|
-
|
|
76
|
+
"\\[\\e[90m\\]\u2502\\[\\e[0m\\] ",
|
|
77
|
+
"\\[\\e[34m\\]\\W",
|
|
78
|
+
"\\[\\e[90m\\] \\$ ",
|
|
79
|
+
"\\[\\e[0m\\]"
|
|
80
|
+
].join("");
|
|
39
81
|
const CONTROLLED_ZSH_PROMPT = [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
].join(
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
const CONTROLLED_ANON_ZSH_PROMPT = '%F{8}│ %# %f';
|
|
82
|
+
"%F{8}\u2502%f ",
|
|
83
|
+
"%F{4}%1~",
|
|
84
|
+
"%F{8} %# ",
|
|
85
|
+
"%f"
|
|
86
|
+
].join("");
|
|
87
|
+
const CONTROLLED_ANON_BASH_PROMPT = "\\[\\e[90m\\]\u2502 \\$ \\[\\e[0m\\]";
|
|
88
|
+
const CONTROLLED_ANON_ZSH_PROMPT = "%F{8}\u2502 %# %f";
|
|
48
89
|
const INHERITED_PROMPT_ENV_KEYS = [
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
"PS1",
|
|
91
|
+
"PS2",
|
|
92
|
+
"PS3",
|
|
93
|
+
"PS4",
|
|
94
|
+
"PROMPT",
|
|
95
|
+
"RPROMPT",
|
|
96
|
+
"RPS1",
|
|
97
|
+
"PROMPT_COMMAND"
|
|
57
98
|
];
|
|
58
|
-
|
|
59
99
|
function stripInheritedPromptEnv(env) {
|
|
60
100
|
for (const key of INHERITED_PROMPT_ENV_KEYS) {
|
|
61
101
|
delete env[key];
|
|
62
102
|
}
|
|
63
103
|
}
|
|
64
|
-
|
|
65
104
|
function extractLatestTerminalTitle(data) {
|
|
66
105
|
if (!data) return null;
|
|
67
|
-
|
|
106
|
+
const text = String(data);
|
|
68
107
|
const TITLE_PATTERN = /\x1b\]([012]);([^\x07\x1b]*?)(?:\x07|\x1b\\)/g;
|
|
69
108
|
let match = null;
|
|
70
109
|
let latestTitle = null;
|
|
71
|
-
|
|
72
|
-
while ((match = TITLE_PATTERN.exec(data)) !== null) {
|
|
110
|
+
while ((match = TITLE_PATTERN.exec(text)) !== null) {
|
|
73
111
|
const mode = match[1];
|
|
74
|
-
const title = match[2] ? match[2].trim() :
|
|
75
|
-
if ((mode ===
|
|
112
|
+
const title = match[2] ? match[2].trim() : "";
|
|
113
|
+
if ((mode === "0" || mode === "2") && title) {
|
|
76
114
|
latestTitle = title;
|
|
77
115
|
}
|
|
78
116
|
}
|
|
79
|
-
|
|
80
117
|
return latestTitle;
|
|
81
118
|
}
|
|
82
|
-
|
|
83
119
|
let cachedPty = null;
|
|
84
120
|
let cachedPtyError = null;
|
|
85
|
-
|
|
86
121
|
function loadPtyModule() {
|
|
87
122
|
if (cachedPty) return cachedPty;
|
|
88
123
|
if (cachedPtyError) throw cachedPtyError;
|
|
89
124
|
try {
|
|
90
|
-
|
|
91
|
-
|
|
125
|
+
const packagedNodePtyModule = require("./packaged-node-pty.cjs");
|
|
126
|
+
cachedPty = packagedNodePtyModule.nodePty;
|
|
127
|
+
return packagedNodePtyModule.nodePty;
|
|
92
128
|
} catch (error) {
|
|
93
129
|
cachedPtyError = error;
|
|
94
130
|
throw error;
|
|
95
131
|
}
|
|
96
132
|
}
|
|
97
|
-
|
|
133
|
+
function errorMessage(error) {
|
|
134
|
+
if (error instanceof Error) return error.message;
|
|
135
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
136
|
+
return String(error.message || "");
|
|
137
|
+
}
|
|
138
|
+
return String(error || "");
|
|
139
|
+
}
|
|
98
140
|
function createPtyProcess(command, args, options) {
|
|
99
141
|
try {
|
|
100
142
|
return loadPtyModule().spawn(command, args || [], options);
|
|
101
143
|
} catch (error) {
|
|
102
|
-
const wrapped = new Error(`Farming requires node-pty to start interactive agents. Native PTY is unavailable: ${error
|
|
144
|
+
const wrapped = new Error(`Farming requires node-pty to start interactive agents. Native PTY is unavailable: ${errorMessage(error)}`);
|
|
103
145
|
wrapped.cause = error;
|
|
104
146
|
throw wrapped;
|
|
105
147
|
}
|
|
106
148
|
}
|
|
107
|
-
|
|
108
149
|
function normalizeShellSessionOptions(options) {
|
|
109
150
|
const normalized = {
|
|
110
151
|
...options,
|
|
111
|
-
args: [...
|
|
152
|
+
args: [...options.args || []],
|
|
112
153
|
env: {
|
|
113
|
-
...
|
|
154
|
+
...options.env || process.env
|
|
114
155
|
}
|
|
115
156
|
};
|
|
116
|
-
|
|
117
157
|
normalizeInteractiveTerminalEnv(normalized.env, {
|
|
118
158
|
stripRuntimeShims: false,
|
|
119
|
-
stripNodeOptions: false
|
|
159
|
+
stripNodeOptions: false
|
|
120
160
|
});
|
|
121
|
-
|
|
122
|
-
if (options.category === 'coding') {
|
|
123
|
-
// Run coding agents directly to avoid user shell init side effects
|
|
124
|
-
// (aliases, prompts, startup scripts, TERM mutations) that can break
|
|
125
|
-
// interactive TUI bootstrapping on specific local machines.
|
|
161
|
+
if (options.category === "coding") {
|
|
126
162
|
normalized.command = options.command;
|
|
127
|
-
normalized.args = [...
|
|
163
|
+
normalized.args = [...options.args || []];
|
|
128
164
|
return normalized;
|
|
129
165
|
}
|
|
130
|
-
|
|
131
|
-
if (options.category !== 'other') {
|
|
166
|
+
if (options.category !== "other") {
|
|
132
167
|
return normalized;
|
|
133
168
|
}
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
// interactive shell. Farming's OSC markers observe it without owning PS1.
|
|
138
|
-
// The compact prompt remains an explicit privacy / screenshot mode only.
|
|
139
|
-
const useControlledPrompt = normalized.env.FARMING_SHELL_CONTROLLED_PROMPT === '1'
|
|
140
|
-
|| normalized.env.FARMING_ANONYMIZE_SHELL_PROMPT === '1';
|
|
141
|
-
const useAnonymousPrompt = normalized.env.FARMING_ANONYMIZE_SHELL_PROMPT === '1';
|
|
142
|
-
|
|
169
|
+
const shellName = path.basename(options.command || "");
|
|
170
|
+
const useControlledPrompt = normalized.env.FARMING_SHELL_CONTROLLED_PROMPT === "1" || normalized.env.FARMING_ANONYMIZE_SHELL_PROMPT === "1";
|
|
171
|
+
const useAnonymousPrompt = normalized.env.FARMING_ANONYMIZE_SHELL_PROMPT === "1";
|
|
143
172
|
if (useControlledPrompt) stripInheritedPromptEnv(normalized.env);
|
|
144
|
-
|
|
145
|
-
if (shellName === 'bash') {
|
|
173
|
+
if (shellName === "bash") {
|
|
146
174
|
normalized.args = normalized.args.length > 0 ? normalized.args : [];
|
|
147
175
|
if (useControlledPrompt) {
|
|
148
|
-
normalized.env.FARMING_SHELL_CONTROLLED_PROMPT =
|
|
176
|
+
normalized.env.FARMING_SHELL_CONTROLLED_PROMPT = "1";
|
|
149
177
|
normalized.env.PS1 = useAnonymousPrompt ? CONTROLLED_ANON_BASH_PROMPT : CONTROLLED_BASH_PROMPT;
|
|
150
178
|
}
|
|
151
|
-
normalized.env.BASH_SILENCE_DEPRECATION_WARNING = normalized.env.BASH_SILENCE_DEPRECATION_WARNING ||
|
|
152
|
-
} else if (shellName ===
|
|
179
|
+
normalized.env.BASH_SILENCE_DEPRECATION_WARNING = normalized.env.BASH_SILENCE_DEPRECATION_WARNING || "1";
|
|
180
|
+
} else if (shellName === "zsh") {
|
|
153
181
|
normalized.args = normalized.args.length > 0 ? normalized.args : [];
|
|
154
182
|
if (useControlledPrompt) {
|
|
155
|
-
normalized.env.FARMING_SHELL_CONTROLLED_PROMPT =
|
|
183
|
+
normalized.env.FARMING_SHELL_CONTROLLED_PROMPT = "1";
|
|
156
184
|
normalized.env.PROMPT = useAnonymousPrompt ? CONTROLLED_ANON_ZSH_PROMPT : CONTROLLED_ZSH_PROMPT;
|
|
157
185
|
normalized.env.PS1 = normalized.env.PROMPT;
|
|
158
186
|
}
|
|
159
187
|
}
|
|
160
|
-
|
|
161
188
|
normalized.env.SHELL = normalized.env.SHELL || options.command || shellName;
|
|
162
|
-
|
|
163
|
-
|
|
189
|
+
return {
|
|
190
|
+
...normalized,
|
|
191
|
+
...applyShellBusyIntegration(normalized),
|
|
192
|
+
agentId: normalized.agentId,
|
|
193
|
+
command: normalized.command
|
|
194
|
+
};
|
|
164
195
|
}
|
|
165
|
-
|
|
166
196
|
class LocalSessionEngine extends SessionEngine {
|
|
197
|
+
configDir;
|
|
198
|
+
terminalExitDataFlushMs;
|
|
199
|
+
sessions;
|
|
200
|
+
screenWorkerPool;
|
|
167
201
|
constructor(options = {}) {
|
|
168
202
|
super();
|
|
169
203
|
this.configDir = options.configDir || storageLayout.farmingConfigDir();
|
|
170
|
-
this.
|
|
171
|
-
this.
|
|
204
|
+
this.terminalExitDataFlushMs = options.terminalExitDataFlushMs;
|
|
205
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
206
|
+
this.screenWorkerPool = new import_terminal_screen_worker_pool.TerminalScreenWorkerPool({
|
|
172
207
|
size: 3,
|
|
173
208
|
workerOptions: {
|
|
174
209
|
cols: 80,
|
|
175
210
|
rows: 30,
|
|
176
|
-
previewSnapshot: false
|
|
177
|
-
}
|
|
211
|
+
previewSnapshot: false
|
|
212
|
+
}
|
|
178
213
|
});
|
|
179
214
|
}
|
|
180
|
-
|
|
181
215
|
async createSession(options) {
|
|
182
216
|
const normalized = normalizeShellSessionOptions(options);
|
|
183
217
|
const previewCols = normalized.cols || 80;
|
|
@@ -188,13 +222,12 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
188
222
|
cols: previewCols,
|
|
189
223
|
rows: previewRows,
|
|
190
224
|
runtimeEpoch,
|
|
191
|
-
runtimeGeneration
|
|
225
|
+
runtimeGeneration
|
|
192
226
|
});
|
|
193
|
-
|
|
194
227
|
let ptyProcess;
|
|
195
228
|
try {
|
|
196
229
|
ptyProcess = createPtyProcess(normalized.command, normalized.args || [], {
|
|
197
|
-
name:
|
|
230
|
+
name: "xterm-256color",
|
|
198
231
|
cols: previewCols,
|
|
199
232
|
rows: previewRows,
|
|
200
233
|
cwd: normalized.cwd,
|
|
@@ -202,81 +235,75 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
202
235
|
});
|
|
203
236
|
} catch (error) {
|
|
204
237
|
cleanupShellBusyIntegration(normalized.shellBusyIntegration);
|
|
205
|
-
await screenWorker.dispose().catch(() => {
|
|
238
|
+
await screenWorker.dispose().catch(() => {
|
|
239
|
+
});
|
|
206
240
|
throw error;
|
|
207
241
|
}
|
|
208
|
-
|
|
209
242
|
const session = {
|
|
210
243
|
id: normalized.agentId,
|
|
211
244
|
command: normalized.command,
|
|
212
245
|
args: normalized.args || [],
|
|
213
246
|
cwd: normalized.cwd,
|
|
214
247
|
process: ptyProcess,
|
|
215
|
-
output:
|
|
248
|
+
output: "",
|
|
216
249
|
outputSeq: 0,
|
|
217
250
|
stateRevision: 0,
|
|
218
251
|
runtimeEpoch,
|
|
219
252
|
stateProofAvailable: true,
|
|
220
253
|
reducerFlowControl: createTerminalReducerFlowControl(),
|
|
221
254
|
reducerCommitQueue: Promise.resolve(),
|
|
222
|
-
renderOutput:
|
|
223
|
-
previewText:
|
|
255
|
+
renderOutput: "",
|
|
256
|
+
previewText: "",
|
|
224
257
|
previewSnapshot: null,
|
|
225
258
|
previewCols,
|
|
226
259
|
previewRows,
|
|
227
|
-
title:
|
|
228
|
-
status:
|
|
260
|
+
title: "",
|
|
261
|
+
status: "running",
|
|
229
262
|
terminalBusy: null,
|
|
230
|
-
shellCwd:
|
|
263
|
+
shellCwd: "",
|
|
231
264
|
shellLastExitCode: null,
|
|
232
|
-
shellLastEvent:
|
|
233
|
-
shellCommand:
|
|
234
|
-
shellLastCommand:
|
|
265
|
+
shellLastEvent: "",
|
|
266
|
+
shellCommand: "",
|
|
267
|
+
shellLastCommand: "",
|
|
235
268
|
shellCommandStartedAt: null,
|
|
236
269
|
shellLastCommandStartedAt: null,
|
|
237
270
|
shellLastCommandFinishedAt: null,
|
|
238
271
|
shellLastCommandDurationMs: null,
|
|
239
|
-
shellBusyMarkerPending:
|
|
272
|
+
shellBusyMarkerPending: "",
|
|
240
273
|
shellBusyIntegration: normalized.shellBusyIntegration || null,
|
|
241
274
|
startedAt: Date.now(),
|
|
242
275
|
lastActivityAt: Date.now(),
|
|
243
276
|
screenWorker
|
|
244
277
|
};
|
|
245
|
-
|
|
246
|
-
session.screenWorker.on('preview', ({ previewText, title, cols, rows, previewSnapshot }) => {
|
|
278
|
+
screenWorker.on("preview", ({ previewText, title, cols, rows, previewSnapshot }) => {
|
|
247
279
|
const current = this.sessions.get(session.id);
|
|
248
280
|
if (current !== session) return;
|
|
249
|
-
|
|
250
|
-
current.previewText = previewText || '';
|
|
281
|
+
current.previewText = previewText || "";
|
|
251
282
|
current.previewSnapshot = previewSnapshot || null;
|
|
252
283
|
current.previewCols = cols || current.previewCols;
|
|
253
284
|
current.previewRows = rows || current.previewRows;
|
|
254
|
-
|
|
255
285
|
if (title && title !== current.title) {
|
|
256
286
|
current.title = title;
|
|
257
|
-
this.emit(
|
|
287
|
+
this.emit("session-title", {
|
|
258
288
|
sessionId: current.id,
|
|
259
289
|
title: current.title,
|
|
260
|
-
runtimeEpoch: current.runtimeEpoch
|
|
290
|
+
runtimeEpoch: current.runtimeEpoch
|
|
261
291
|
});
|
|
262
292
|
}
|
|
263
|
-
|
|
264
|
-
this.emit('session-preview', {
|
|
293
|
+
this.emit("session-preview", {
|
|
265
294
|
sessionId: current.id,
|
|
266
295
|
previewText: current.previewText,
|
|
267
296
|
cols: current.previewCols,
|
|
268
297
|
rows: current.previewRows,
|
|
269
298
|
previewSnapshot: current.previewSnapshot,
|
|
270
|
-
runtimeEpoch: current.runtimeEpoch
|
|
299
|
+
runtimeEpoch: current.runtimeEpoch
|
|
271
300
|
});
|
|
272
301
|
});
|
|
273
|
-
|
|
274
|
-
session.screenWorker.on('error', (error) => {
|
|
302
|
+
screenWorker.on("error", (error) => {
|
|
275
303
|
this.failSessionScreenState(session, error);
|
|
276
304
|
});
|
|
277
|
-
|
|
278
305
|
this.sessions.set(session.id, session);
|
|
279
|
-
this.emit(
|
|
306
|
+
this.emit("session-started", {
|
|
280
307
|
sessionId: session.id,
|
|
281
308
|
status: session.status,
|
|
282
309
|
startedAt: session.startedAt,
|
|
@@ -284,21 +311,17 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
284
311
|
outputSeq: session.outputSeq,
|
|
285
312
|
stateRevision: session.stateRevision
|
|
286
313
|
});
|
|
287
|
-
|
|
288
|
-
ptyProcess.onData(data => this.handleSessionData(session.id, data, session));
|
|
289
|
-
|
|
314
|
+
ptyProcess.onData((data) => this.handleSessionData(session.id, data, session));
|
|
290
315
|
ptyProcess.onExit(({ code }) => {
|
|
291
316
|
void this.handleSessionExit(session, code);
|
|
292
317
|
});
|
|
293
|
-
|
|
294
318
|
return {
|
|
295
319
|
sessionId: session.id,
|
|
296
320
|
status: session.status
|
|
297
321
|
};
|
|
298
322
|
}
|
|
299
|
-
|
|
300
323
|
handleSessionExit(session, code) {
|
|
301
|
-
if (this.sessions.get(session.id) !== session || session.status ===
|
|
324
|
+
if (this.sessions.get(session.id) !== session || session.status === "exited") {
|
|
302
325
|
return Promise.resolve();
|
|
303
326
|
}
|
|
304
327
|
if (session.exitFinalizationPromise) return session.exitFinalizationPromise;
|
|
@@ -306,23 +329,22 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
306
329
|
session.exitFinalizationPromise = finalization;
|
|
307
330
|
return finalization;
|
|
308
331
|
}
|
|
309
|
-
|
|
310
332
|
async finalizeSessionExit(session, code) {
|
|
311
333
|
const quiesced = await waitForTerminalExitDataQuiescence(session, {
|
|
312
334
|
flushMs: this.terminalExitDataFlushMs,
|
|
313
|
-
isCurrent: () => this.sessions.get(session.id) === session
|
|
335
|
+
isCurrent: () => this.sessions.get(session.id) === session
|
|
314
336
|
});
|
|
315
337
|
if (!quiesced) return;
|
|
316
|
-
await Promise.resolve(session.reducerCommitQueue).catch(() => {
|
|
338
|
+
await Promise.resolve(session.reducerCommitQueue).catch(() => {
|
|
339
|
+
});
|
|
317
340
|
if (this.sessions.get(session.id) !== session) return;
|
|
318
341
|
const finalCheckpoint = await captureTerminalAttachCheckpoint(session, { requireCurrentCut: true });
|
|
319
342
|
if (this.sessions.get(session.id) !== session) return;
|
|
320
|
-
|
|
321
|
-
session.status = 'exited';
|
|
343
|
+
session.status = "exited";
|
|
322
344
|
session.exitedAt = Date.now();
|
|
323
345
|
resetTerminalReducerFlowControl(
|
|
324
346
|
ensureTerminalReducerFlowControl(session),
|
|
325
|
-
session.process
|
|
347
|
+
session.process
|
|
326
348
|
);
|
|
327
349
|
if (finalCheckpoint) {
|
|
328
350
|
session.finalCheckpoint = Object.freeze({ ...finalCheckpoint });
|
|
@@ -333,48 +355,46 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
333
355
|
session.previewRows = finalCheckpoint.rows;
|
|
334
356
|
session.title = finalCheckpoint.title || session.title;
|
|
335
357
|
} else {
|
|
336
|
-
this.failSessionScreenState(session, new Error(
|
|
358
|
+
this.failSessionScreenState(session, new Error("Unable to capture the exact final Terminal checkpoint"));
|
|
337
359
|
}
|
|
338
360
|
if (session.screenWorker) {
|
|
339
|
-
await session.screenWorker.dispose().catch(() => {
|
|
361
|
+
await session.screenWorker.dispose().catch(() => {
|
|
362
|
+
});
|
|
340
363
|
session.screenWorker = null;
|
|
341
364
|
}
|
|
342
365
|
cleanupShellBusyIntegration(session.shellBusyIntegration);
|
|
343
|
-
|
|
344
|
-
this.emit('session-exited', {
|
|
366
|
+
this.emit("session-exited", {
|
|
345
367
|
sessionId: session.id,
|
|
346
368
|
code,
|
|
347
369
|
exitedAt: session.exitedAt,
|
|
348
370
|
runtimeEpoch: session.runtimeEpoch,
|
|
349
371
|
outputSeq: session.outputSeq,
|
|
350
372
|
stateRevision: session.stateRevision,
|
|
351
|
-
stateProofAvailable: session.stateProofAvailable !== false
|
|
373
|
+
stateProofAvailable: session.stateProofAvailable !== false
|
|
352
374
|
});
|
|
353
375
|
if (finalCheckpoint) {
|
|
354
|
-
this.emit(
|
|
376
|
+
this.emit("session-preview", {
|
|
355
377
|
sessionId: session.id,
|
|
356
378
|
previewText: session.previewText,
|
|
357
379
|
cols: session.previewCols,
|
|
358
380
|
rows: session.previewRows,
|
|
359
381
|
previewSnapshot: session.previewSnapshot,
|
|
360
|
-
runtimeEpoch: session.runtimeEpoch
|
|
382
|
+
runtimeEpoch: session.runtimeEpoch
|
|
361
383
|
});
|
|
362
384
|
}
|
|
363
385
|
}
|
|
364
|
-
|
|
365
386
|
handleSessionData(sessionId, rawData, expectedSession = null) {
|
|
366
387
|
const current = this.sessions.get(sessionId);
|
|
367
|
-
if (!current ||
|
|
388
|
+
if (!current || expectedSession && current !== expectedSession || current.stateProofAvailable === false) return;
|
|
368
389
|
if (!acceptTerminalExitData(current)) {
|
|
369
390
|
current.finalCheckpoint = null;
|
|
370
|
-
this.failSessionScreenState(current, new Error(
|
|
391
|
+
this.failSessionScreenState(current, new Error("PTY emitted data after its final checkpoint cut"));
|
|
371
392
|
return;
|
|
372
393
|
}
|
|
373
|
-
|
|
374
394
|
const busyState = parseShellBusyMarkers(
|
|
375
395
|
rawData,
|
|
376
396
|
current.terminalBusy,
|
|
377
|
-
current.shellBusyMarkerPending
|
|
397
|
+
current.shellBusyMarkerPending
|
|
378
398
|
);
|
|
379
399
|
current.shellBusyMarkerPending = busyState.pending;
|
|
380
400
|
if (busyState.markerSeen) {
|
|
@@ -383,20 +403,20 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
383
403
|
if (busyState.cwd) current.shellCwd = busyState.cwd;
|
|
384
404
|
if (busyState.exitCodeSeen) current.shellLastExitCode = busyState.lastExitCode;
|
|
385
405
|
if (busyState.shellEvent) current.shellLastEvent = busyState.shellEvent;
|
|
386
|
-
if (busyState.shellEvent ===
|
|
387
|
-
if (busyState.commandTextSeen) current.shellCommand = busyState.shellCommand ||
|
|
388
|
-
if (busyState.shellEvent ===
|
|
406
|
+
if (busyState.shellEvent === "start") current.shellCommandStartedAt = markerAt;
|
|
407
|
+
if (busyState.commandTextSeen) current.shellCommand = busyState.shellCommand || "";
|
|
408
|
+
if (busyState.shellEvent === "finish") {
|
|
389
409
|
const commandStartedAt = current.shellCommandStartedAt;
|
|
390
410
|
if (current.shellCommand) current.shellLastCommand = current.shellCommand;
|
|
391
|
-
if (typeof commandStartedAt ===
|
|
411
|
+
if (typeof commandStartedAt === "number") {
|
|
392
412
|
current.shellLastCommandStartedAt = commandStartedAt;
|
|
393
413
|
current.shellLastCommandFinishedAt = markerAt;
|
|
394
414
|
current.shellLastCommandDurationMs = Math.max(0, markerAt - commandStartedAt);
|
|
395
415
|
}
|
|
396
|
-
current.shellCommand =
|
|
416
|
+
current.shellCommand = "";
|
|
397
417
|
current.shellCommandStartedAt = null;
|
|
398
418
|
}
|
|
399
|
-
this.emit(
|
|
419
|
+
this.emit("session-busy-state", {
|
|
400
420
|
sessionId: current.id,
|
|
401
421
|
terminalBusy: current.terminalBusy,
|
|
402
422
|
cwd: current.shellCwd || current.cwd,
|
|
@@ -410,16 +430,15 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
410
430
|
shellLastCommandDurationMs: current.shellLastCommandDurationMs,
|
|
411
431
|
statusMarkerSeen: busyState.statusMarkerSeen,
|
|
412
432
|
busyMarkerSeen: busyState.busyMarkerSeen,
|
|
413
|
-
runtimeEpoch: current.runtimeEpoch
|
|
433
|
+
runtimeEpoch: current.runtimeEpoch
|
|
414
434
|
});
|
|
415
435
|
}
|
|
416
|
-
|
|
417
436
|
const data = busyState.data;
|
|
418
437
|
if (!data) return;
|
|
419
438
|
const reducerDelivery = enqueueTerminalReducerData(
|
|
420
439
|
ensureTerminalReducerFlowControl(current),
|
|
421
440
|
current.process,
|
|
422
|
-
data
|
|
441
|
+
data
|
|
423
442
|
);
|
|
424
443
|
if (reducerDelivery.error) {
|
|
425
444
|
this.failSessionScreenState(current, reducerDelivery.error);
|
|
@@ -429,19 +448,18 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
429
448
|
current.stateRevision += 1;
|
|
430
449
|
const outputSeq = current.outputSeq;
|
|
431
450
|
const stateRevision = current.stateRevision;
|
|
432
|
-
current.output = `${current.output}${data}`.slice(-
|
|
451
|
+
current.output = `${current.output}${data}`.slice(-1e4);
|
|
433
452
|
current.lastActivityAt = Date.now();
|
|
434
|
-
|
|
435
453
|
const fallbackTitle = extractLatestTerminalTitle(data);
|
|
436
454
|
if (fallbackTitle && fallbackTitle !== current.title) {
|
|
437
455
|
current.title = fallbackTitle;
|
|
438
|
-
this.emit(
|
|
456
|
+
this.emit("session-title", {
|
|
439
457
|
sessionId: current.id,
|
|
440
458
|
title: current.title,
|
|
441
|
-
runtimeEpoch: current.runtimeEpoch
|
|
459
|
+
runtimeEpoch: current.runtimeEpoch
|
|
442
460
|
});
|
|
443
461
|
}
|
|
444
|
-
|
|
462
|
+
if (!current.screenWorker) throw new TypeError("Terminal screen worker is unavailable");
|
|
445
463
|
const commit = current.screenWorker.append(data, stateRevision, outputSeq);
|
|
446
464
|
current.reducerCommitQueue = current.reducerCommitQueue.then(() => commit).then(() => {
|
|
447
465
|
const latest = this.sessions.get(current.id);
|
|
@@ -449,112 +467,104 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
449
467
|
const flowError = acknowledgeTerminalReducerData(
|
|
450
468
|
ensureTerminalReducerFlowControl(latest),
|
|
451
469
|
latest.process,
|
|
452
|
-
reducerDelivery.bytes
|
|
470
|
+
reducerDelivery.bytes
|
|
453
471
|
);
|
|
454
472
|
if (flowError) {
|
|
455
473
|
this.failSessionScreenState(latest, flowError);
|
|
456
474
|
return;
|
|
457
475
|
}
|
|
458
|
-
this.emit(
|
|
476
|
+
this.emit("session-output", {
|
|
459
477
|
sessionId: latest.id,
|
|
460
478
|
data,
|
|
461
479
|
runtimeEpoch: latest.runtimeEpoch,
|
|
462
480
|
outputSeq,
|
|
463
|
-
stateRevision
|
|
481
|
+
stateRevision
|
|
464
482
|
});
|
|
465
|
-
this.emit(
|
|
483
|
+
this.emit("session-activity", {
|
|
466
484
|
sessionId: latest.id,
|
|
467
485
|
lastActivityAt: latest.lastActivityAt,
|
|
468
|
-
runtimeEpoch: latest.runtimeEpoch
|
|
486
|
+
runtimeEpoch: latest.runtimeEpoch
|
|
469
487
|
});
|
|
470
|
-
}).catch(error => this.failSessionScreenState(current, error));
|
|
488
|
+
}).catch((error) => this.failSessionScreenState(current, error));
|
|
471
489
|
}
|
|
472
|
-
|
|
473
490
|
failSessionScreenState(session, error) {
|
|
474
491
|
const current = this.sessions.get(session.id);
|
|
475
492
|
if (current !== session || current.stateProofAvailable === false) return;
|
|
476
493
|
current.stateProofAvailable = false;
|
|
477
|
-
const message = error instanceof Error ? error.message : String(error ||
|
|
478
|
-
this.emit(
|
|
494
|
+
const message = error instanceof Error ? error.message : String(error || "unknown reducer failure");
|
|
495
|
+
this.emit("session-error", {
|
|
479
496
|
sessionId: current.id,
|
|
480
497
|
error: `Terminal state reducer failed: ${message}`,
|
|
481
498
|
fatal: true,
|
|
482
|
-
runtimeEpoch: current.runtimeEpoch
|
|
499
|
+
runtimeEpoch: current.runtimeEpoch
|
|
483
500
|
});
|
|
484
501
|
try {
|
|
485
502
|
current.process?.kill();
|
|
486
503
|
} catch {
|
|
487
|
-
// The runtime cannot continue safely without its authoritative reducer.
|
|
488
504
|
}
|
|
489
505
|
}
|
|
490
|
-
|
|
491
506
|
async sendInput(sessionId, input, options = {}) {
|
|
492
507
|
const session = this.sessions.get(sessionId);
|
|
493
|
-
if (!session || !session.process || session.status ===
|
|
494
|
-
throw new Error(
|
|
508
|
+
if (!session || !session.process || session.status === "exited" || session.exitFinalizing === true) {
|
|
509
|
+
throw new Error("Session not available");
|
|
495
510
|
}
|
|
496
|
-
|
|
497
511
|
if (options.expectedRuntimeEpoch && options.expectedRuntimeEpoch !== session.runtimeEpoch) {
|
|
498
|
-
return { status:
|
|
512
|
+
return { status: "input-rejected", reason: "runtime-epoch-mismatch" };
|
|
499
513
|
}
|
|
500
514
|
session.process.write(terminalInputToPtyString(input));
|
|
501
515
|
session.lastActivityAt = Date.now();
|
|
502
|
-
this.emit(
|
|
516
|
+
this.emit("session-activity", {
|
|
503
517
|
sessionId,
|
|
504
518
|
lastActivityAt: session.lastActivityAt,
|
|
505
|
-
runtimeEpoch: session.runtimeEpoch
|
|
519
|
+
runtimeEpoch: session.runtimeEpoch
|
|
506
520
|
});
|
|
507
521
|
return { sent: true };
|
|
508
522
|
}
|
|
509
|
-
|
|
510
|
-
async interruptSession(sessionId, input = '\x03', options = {}) {
|
|
523
|
+
async interruptSession(sessionId, input = "", options = {}) {
|
|
511
524
|
return this.sendInput(sessionId, input, options);
|
|
512
525
|
}
|
|
513
|
-
|
|
514
526
|
async getSessionAttachCheckpoint(sessionId) {
|
|
515
527
|
const session = this.sessions.get(sessionId);
|
|
516
528
|
if (!session) return null;
|
|
517
529
|
const checkpoint = await captureTerminalAttachCheckpoint(session);
|
|
518
530
|
return this.sessions.get(sessionId) === session ? checkpoint : null;
|
|
519
531
|
}
|
|
520
|
-
|
|
521
532
|
async resizeSession(sessionId, cols, rows) {
|
|
522
533
|
const session = this.sessions.get(sessionId);
|
|
523
534
|
if (!session || !session.process || !session.process.resize) {
|
|
524
|
-
return { status:
|
|
535
|
+
return { status: "resize-rejected", reason: "session-unavailable", resized: false };
|
|
525
536
|
}
|
|
526
|
-
if (session.status ===
|
|
527
|
-
return { status:
|
|
537
|
+
if (session.status === "exited" || session.exitFinalizing === true) {
|
|
538
|
+
return { status: "resize-rejected", reason: "session-unavailable", resized: false };
|
|
528
539
|
}
|
|
529
|
-
|
|
530
540
|
if (cols === session.previewCols && rows === session.previewRows) {
|
|
531
541
|
if (this.sessions.get(sessionId) !== session) {
|
|
532
|
-
return { status:
|
|
542
|
+
return { status: "resize-rejected", reason: "session-replaced", resized: false };
|
|
533
543
|
}
|
|
534
544
|
return {
|
|
535
|
-
status:
|
|
545
|
+
status: "resize-committed",
|
|
536
546
|
resized: true,
|
|
537
|
-
unchanged: true
|
|
547
|
+
unchanged: true
|
|
538
548
|
};
|
|
539
549
|
}
|
|
540
|
-
|
|
550
|
+
const resize = session.process.resize;
|
|
541
551
|
try {
|
|
542
|
-
session.process
|
|
552
|
+
resize.call(session.process, cols, rows);
|
|
543
553
|
} catch (error) {
|
|
544
|
-
if (
|
|
545
|
-
session.status =
|
|
554
|
+
if (errorMessage(error).includes("EBADF")) {
|
|
555
|
+
session.status = "exited";
|
|
546
556
|
session.exitedAt = session.exitedAt || Date.now();
|
|
547
|
-
return { status:
|
|
557
|
+
return { status: "resize-rejected", reason: "session-unavailable", resized: false };
|
|
548
558
|
}
|
|
549
559
|
return {
|
|
550
|
-
status:
|
|
551
|
-
reason:
|
|
560
|
+
status: "resize-rejected",
|
|
561
|
+
reason: "pty-resize-failed",
|
|
552
562
|
resized: false,
|
|
553
|
-
error: error instanceof Error ? error.message : String(error ||
|
|
563
|
+
error: error instanceof Error ? error.message : String(error || "unknown PTY resize failure")
|
|
554
564
|
};
|
|
555
565
|
}
|
|
556
566
|
if (this.sessions.get(sessionId) !== session) {
|
|
557
|
-
return { status:
|
|
567
|
+
return { status: "resize-rejected", reason: "session-replaced", resized: false };
|
|
558
568
|
}
|
|
559
569
|
session.stateRevision += 1;
|
|
560
570
|
const stateRevision = session.stateRevision;
|
|
@@ -564,46 +574,39 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
564
574
|
session.previewRows = rows || session.previewRows;
|
|
565
575
|
if (!session.screenWorker) {
|
|
566
576
|
if (this.sessions.get(sessionId) !== session) {
|
|
567
|
-
return { status:
|
|
577
|
+
return { status: "resize-rejected", reason: "session-replaced", resized: false };
|
|
568
578
|
}
|
|
569
579
|
return {
|
|
570
|
-
status:
|
|
580
|
+
status: "resize-committed",
|
|
571
581
|
resized: true,
|
|
572
|
-
unchanged: false
|
|
582
|
+
unchanged: false
|
|
573
583
|
};
|
|
574
584
|
}
|
|
575
|
-
|
|
576
585
|
const reducerCommit = session.screenWorker.resize(cols, rows, stateRevision);
|
|
577
586
|
const publishedCommit = session.reducerCommitQueue.then(() => reducerCommit).then((screenState) => {
|
|
578
587
|
if (this.sessions.get(sessionId) !== session) {
|
|
579
|
-
throw new Error(
|
|
588
|
+
throw new Error("Terminal session was replaced during resize");
|
|
580
589
|
}
|
|
581
|
-
if (
|
|
582
|
-
|
|
583
|
-
screenState.outputSeq !== outputSeq ||
|
|
584
|
-
screenState.stateRevision !== stateRevision
|
|
585
|
-
) {
|
|
586
|
-
throw new Error('Terminal screen resize returned a non-authoritative state cut');
|
|
590
|
+
if (screenState.runtimeEpoch !== runtimeEpoch || screenState.outputSeq !== outputSeq || screenState.stateRevision !== stateRevision) {
|
|
591
|
+
throw new Error("Terminal screen resize returned a non-authoritative state cut");
|
|
587
592
|
}
|
|
588
|
-
session.previewText = screenState.previewText ||
|
|
593
|
+
session.previewText = screenState.previewText || "";
|
|
589
594
|
session.previewSnapshot = screenState.previewSnapshot || session.previewSnapshot;
|
|
590
|
-
session.renderOutput = typeof screenState.renderOutput ===
|
|
591
|
-
? screenState.renderOutput
|
|
592
|
-
: session.renderOutput;
|
|
595
|
+
session.renderOutput = typeof screenState.renderOutput === "string" ? screenState.renderOutput : session.renderOutput;
|
|
593
596
|
session.previewCols = screenState.cols || cols || session.previewCols;
|
|
594
597
|
session.previewRows = screenState.rows || rows || session.previewRows;
|
|
595
598
|
if (screenState.title && screenState.title !== session.title) {
|
|
596
599
|
session.title = screenState.title;
|
|
597
|
-
this.emit(
|
|
600
|
+
this.emit("session-title", {
|
|
598
601
|
sessionId,
|
|
599
602
|
title: session.title,
|
|
600
|
-
runtimeEpoch: session.runtimeEpoch
|
|
603
|
+
runtimeEpoch: session.runtimeEpoch
|
|
601
604
|
});
|
|
602
605
|
}
|
|
603
|
-
this.emit(
|
|
606
|
+
this.emit("session-transition", {
|
|
604
607
|
sessionId,
|
|
605
|
-
kind:
|
|
606
|
-
data:
|
|
608
|
+
kind: "resize",
|
|
609
|
+
data: "",
|
|
607
610
|
runtimeEpoch: screenState.runtimeEpoch,
|
|
608
611
|
outputSeq: screenState.outputSeq,
|
|
609
612
|
stateRevision: screenState.stateRevision,
|
|
@@ -612,83 +615,76 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
612
615
|
});
|
|
613
616
|
return screenState;
|
|
614
617
|
});
|
|
615
|
-
session.reducerCommitQueue = publishedCommit.catch(error => {
|
|
618
|
+
session.reducerCommitQueue = publishedCommit.catch((error) => {
|
|
616
619
|
this.failSessionScreenState(session, error);
|
|
617
620
|
});
|
|
618
621
|
try {
|
|
619
622
|
await publishedCommit;
|
|
620
623
|
} catch {
|
|
621
|
-
return { status:
|
|
624
|
+
return { status: "resize-rejected", reason: "screen-reducer-failed", resized: false };
|
|
622
625
|
}
|
|
623
626
|
if (this.sessions.get(sessionId) !== session) {
|
|
624
|
-
return { status:
|
|
627
|
+
return { status: "resize-rejected", reason: "session-replaced", resized: false };
|
|
625
628
|
}
|
|
626
629
|
return {
|
|
627
|
-
status:
|
|
630
|
+
status: "resize-committed",
|
|
628
631
|
resized: true,
|
|
629
632
|
unchanged: false,
|
|
630
633
|
runtimeEpoch,
|
|
631
634
|
outputSeq,
|
|
632
635
|
stateRevision,
|
|
633
636
|
cols,
|
|
634
|
-
rows
|
|
637
|
+
rows
|
|
635
638
|
};
|
|
636
639
|
}
|
|
637
|
-
|
|
638
640
|
async clearBuffer(sessionId, options = {}) {
|
|
639
641
|
const session = this.sessions.get(sessionId);
|
|
640
|
-
if (!session || session.status ===
|
|
642
|
+
if (!session || session.status === "exited" || session.exitFinalizing === true) {
|
|
641
643
|
return { cleared: false };
|
|
642
644
|
}
|
|
643
645
|
if (options.expectedRuntimeEpoch && options.expectedRuntimeEpoch !== session.runtimeEpoch) {
|
|
644
|
-
return { cleared: false, reason:
|
|
646
|
+
return { cleared: false, reason: "runtime-epoch-mismatch" };
|
|
645
647
|
}
|
|
646
|
-
|
|
647
|
-
session.output = '';
|
|
648
|
+
session.output = "";
|
|
648
649
|
session.stateRevision += 1;
|
|
649
650
|
const stateRevision = session.stateRevision;
|
|
650
651
|
const outputSeq = session.outputSeq;
|
|
651
652
|
const runtimeEpoch = session.runtimeEpoch;
|
|
652
|
-
session.renderOutput =
|
|
653
|
-
session.previewText =
|
|
653
|
+
session.renderOutput = "";
|
|
654
|
+
session.previewText = "";
|
|
654
655
|
session.previewSnapshot = null;
|
|
655
656
|
session.lastActivityAt = Date.now();
|
|
656
|
-
|
|
657
657
|
let exactState = {
|
|
658
|
-
renderOutput:
|
|
658
|
+
renderOutput: "",
|
|
659
659
|
runtimeEpoch,
|
|
660
660
|
outputSeq,
|
|
661
661
|
stateRevision,
|
|
662
662
|
cols: session.previewCols,
|
|
663
|
-
rows: session.previewRows
|
|
663
|
+
rows: session.previewRows
|
|
664
664
|
};
|
|
665
665
|
if (session.screenWorker) {
|
|
666
666
|
const reducerCommit = session.screenWorker.clear(stateRevision, outputSeq);
|
|
667
667
|
const publishedCommit = session.reducerCommitQueue.then(() => reducerCommit).then((screenState) => {
|
|
668
668
|
if (this.sessions.get(sessionId) !== session) {
|
|
669
|
-
throw new Error(
|
|
669
|
+
throw new Error("Terminal session was replaced during clear");
|
|
670
670
|
}
|
|
671
|
-
if (
|
|
672
|
-
|
|
673
|
-
screenState.outputSeq !== outputSeq ||
|
|
674
|
-
screenState.stateRevision !== stateRevision
|
|
675
|
-
) {
|
|
676
|
-
throw new Error('Terminal screen clear returned a non-authoritative state cut');
|
|
671
|
+
if (screenState.runtimeEpoch !== runtimeEpoch || screenState.outputSeq !== outputSeq || screenState.stateRevision !== stateRevision) {
|
|
672
|
+
throw new Error("Terminal screen clear returned a non-authoritative state cut");
|
|
677
673
|
}
|
|
678
|
-
session.renderOutput = typeof screenState.renderOutput ===
|
|
679
|
-
session.previewText = screenState.previewText ||
|
|
674
|
+
session.renderOutput = typeof screenState.renderOutput === "string" ? screenState.renderOutput : "";
|
|
675
|
+
session.previewText = screenState.previewText || "";
|
|
680
676
|
session.previewSnapshot = screenState.previewSnapshot || null;
|
|
681
677
|
session.previewCols = screenState.cols || session.previewCols;
|
|
682
678
|
session.previewRows = screenState.rows || session.previewRows;
|
|
683
679
|
exactState = screenState;
|
|
684
680
|
if (screenState.title && screenState.title !== session.title) {
|
|
685
681
|
session.title = screenState.title;
|
|
686
|
-
this.emit(
|
|
682
|
+
this.emit("session-title", { sessionId, title: session.title, runtimeEpoch: session.runtimeEpoch });
|
|
687
683
|
}
|
|
688
|
-
this.emit(
|
|
684
|
+
this.emit("session-transition", {
|
|
689
685
|
sessionId,
|
|
690
|
-
kind:
|
|
691
|
-
data:
|
|
686
|
+
kind: "clear",
|
|
687
|
+
data: "\x1B[2J\x1B[3J\x1B[H",
|
|
692
688
|
runtimeEpoch: screenState.runtimeEpoch,
|
|
693
689
|
outputSeq: screenState.outputSeq,
|
|
694
690
|
stateRevision: screenState.stateRevision,
|
|
@@ -697,7 +693,7 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
697
693
|
});
|
|
698
694
|
return screenState;
|
|
699
695
|
});
|
|
700
|
-
session.reducerCommitQueue = publishedCommit.catch(error => {
|
|
696
|
+
session.reducerCommitQueue = publishedCommit.catch((error) => {
|
|
701
697
|
this.failSessionScreenState(session, error);
|
|
702
698
|
});
|
|
703
699
|
try {
|
|
@@ -706,20 +702,20 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
706
702
|
return { cleared: false };
|
|
707
703
|
}
|
|
708
704
|
}
|
|
709
|
-
if (this.sessions.get(sessionId) !== session) return { cleared: false, reason:
|
|
710
|
-
this.emit(
|
|
705
|
+
if (this.sessions.get(sessionId) !== session) return { cleared: false, reason: "session-replaced" };
|
|
706
|
+
this.emit("session-preview", {
|
|
711
707
|
sessionId,
|
|
712
708
|
previewText: session.previewText,
|
|
713
709
|
cols: session.previewCols,
|
|
714
710
|
rows: session.previewRows,
|
|
715
711
|
previewSnapshot: session.previewSnapshot,
|
|
716
712
|
title: session.title,
|
|
717
|
-
runtimeEpoch: session.runtimeEpoch
|
|
713
|
+
runtimeEpoch: session.runtimeEpoch
|
|
718
714
|
});
|
|
719
|
-
this.emit(
|
|
715
|
+
this.emit("session-activity", {
|
|
720
716
|
sessionId,
|
|
721
717
|
lastActivityAt: session.lastActivityAt,
|
|
722
|
-
runtimeEpoch: session.runtimeEpoch
|
|
718
|
+
runtimeEpoch: session.runtimeEpoch
|
|
723
719
|
});
|
|
724
720
|
return {
|
|
725
721
|
cleared: true,
|
|
@@ -727,30 +723,26 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
727
723
|
outputSeq: exactState.outputSeq,
|
|
728
724
|
stateRevision: exactState.stateRevision,
|
|
729
725
|
cols: exactState.cols,
|
|
730
|
-
rows: exactState.rows
|
|
726
|
+
rows: exactState.rows
|
|
731
727
|
};
|
|
732
728
|
}
|
|
733
|
-
|
|
734
729
|
async killSession(sessionId) {
|
|
735
730
|
const session = this.sessions.get(sessionId);
|
|
736
731
|
if (!session || !session.process) {
|
|
737
732
|
return;
|
|
738
733
|
}
|
|
739
|
-
|
|
740
|
-
session.status = 'stopping';
|
|
734
|
+
session.status = "stopping";
|
|
741
735
|
session.killRequestedAt = Date.now();
|
|
742
|
-
session.process.kill(
|
|
743
|
-
|
|
736
|
+
session.process.kill("SIGTERM");
|
|
744
737
|
const killTimer = setTimeout(() => {
|
|
745
738
|
const latest = this.sessions.get(sessionId);
|
|
746
|
-
if (latest !== session || latest.status ===
|
|
739
|
+
if (latest !== session || latest.status === "exited" || !latest.process) {
|
|
747
740
|
return;
|
|
748
741
|
}
|
|
749
|
-
latest.process.kill(
|
|
742
|
+
latest.process.kill("SIGKILL");
|
|
750
743
|
}, 1500);
|
|
751
|
-
if (typeof killTimer.unref ===
|
|
744
|
+
if (typeof killTimer.unref === "function") killTimer.unref();
|
|
752
745
|
}
|
|
753
|
-
|
|
754
746
|
async getSessionState(sessionId) {
|
|
755
747
|
const session = this.sessions.get(sessionId);
|
|
756
748
|
if (!session) return null;
|
|
@@ -764,8 +756,7 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
764
756
|
const checkpoint = stateProofAvailable ? await captureTerminalAttachCheckpoint(session) : null;
|
|
765
757
|
if (this.sessions.get(sessionId) !== session) return null;
|
|
766
758
|
const title = checkpoint ? checkpoint.title : fallbackTitle;
|
|
767
|
-
const previewText = checkpoint ? checkpoint.previewText :
|
|
768
|
-
|
|
759
|
+
const previewText = checkpoint ? checkpoint.previewText : stateProofAvailable ? fallbackPreviewText : "";
|
|
769
760
|
return {
|
|
770
761
|
sessionId: session.id,
|
|
771
762
|
status: session.status,
|
|
@@ -774,9 +765,9 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
774
765
|
outputSeq: checkpoint?.outputSeq ?? null,
|
|
775
766
|
stateRevision: checkpoint?.stateRevision ?? null,
|
|
776
767
|
stateProofAvailable,
|
|
777
|
-
renderOutput: checkpoint ? checkpoint.renderOutput :
|
|
768
|
+
renderOutput: checkpoint ? checkpoint.renderOutput : stateProofAvailable ? snapshotOutput : "",
|
|
778
769
|
previewText,
|
|
779
|
-
previewSnapshot: checkpoint ? checkpoint.previewSnapshot :
|
|
770
|
+
previewSnapshot: checkpoint ? checkpoint.previewSnapshot : stateProofAvailable ? fallbackPreviewSnapshot : null,
|
|
780
771
|
previewCols: checkpoint ? checkpoint.cols : fallbackPreviewCols,
|
|
781
772
|
previewRows: checkpoint ? checkpoint.rows : fallbackPreviewRows,
|
|
782
773
|
title,
|
|
@@ -784,8 +775,11 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
784
775
|
startedAt: session.startedAt,
|
|
785
776
|
exitedAt: session.exitedAt || null,
|
|
786
777
|
terminalBusy: session.terminalBusy,
|
|
787
|
-
shellCommand: session.shellCommand ||
|
|
788
|
-
shellLastCommand: session.shellLastCommand ||
|
|
778
|
+
shellCommand: session.shellCommand || "",
|
|
779
|
+
shellLastCommand: session.shellLastCommand || "",
|
|
780
|
+
shellCwd: session.shellCwd || "",
|
|
781
|
+
shellLastEvent: session.shellLastEvent || "",
|
|
782
|
+
shellLastExitCode: session.shellLastExitCode ?? null,
|
|
789
783
|
shellCommandStartedAt: session.shellCommandStartedAt ?? null,
|
|
790
784
|
shellLastCommandStartedAt: session.shellLastCommandStartedAt ?? null,
|
|
791
785
|
shellLastCommandFinishedAt: session.shellLastCommandFinishedAt ?? null,
|
|
@@ -804,23 +798,22 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
804
798
|
shellCommandStartedAt: session.shellCommandStartedAt,
|
|
805
799
|
shellLastCommandStartedAt: session.shellLastCommandStartedAt,
|
|
806
800
|
shellLastCommandFinishedAt: session.shellLastCommandFinishedAt,
|
|
807
|
-
shellLastCommandDurationMs: session.shellLastCommandDurationMs
|
|
801
|
+
shellLastCommandDurationMs: session.shellLastCommandDurationMs
|
|
808
802
|
})
|
|
809
803
|
};
|
|
810
804
|
}
|
|
811
|
-
|
|
812
805
|
async getSessionPreview(sessionId) {
|
|
813
806
|
const session = this.sessions.get(sessionId);
|
|
814
807
|
if (!session) {
|
|
815
|
-
return
|
|
808
|
+
return "";
|
|
816
809
|
}
|
|
817
|
-
const screenState = session.screenWorker
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
810
|
+
const screenState = session.screenWorker ? await session.screenWorker.getState({ includeRenderOutput: false }).catch(() => null) : null;
|
|
811
|
+
if (this.sessions.get(sessionId) !== session) return "";
|
|
812
|
+
return screenState && screenState.previewText || session.previewText;
|
|
813
|
+
}
|
|
814
|
+
consumeRuntimeRotation() {
|
|
815
|
+
return null;
|
|
822
816
|
}
|
|
823
|
-
|
|
824
817
|
dispose() {
|
|
825
818
|
const disposals = [];
|
|
826
819
|
this.sessions.forEach((session) => {
|
|
@@ -830,7 +823,6 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
830
823
|
}
|
|
831
824
|
cleanupShellBusyIntegration(session.shellBusyIntegration);
|
|
832
825
|
} catch {
|
|
833
|
-
// best effort
|
|
834
826
|
}
|
|
835
827
|
});
|
|
836
828
|
this.sessions.clear();
|
|
@@ -838,8 +830,10 @@ class LocalSessionEngine extends SessionEngine {
|
|
|
838
830
|
return Promise.allSettled(disposals);
|
|
839
831
|
}
|
|
840
832
|
}
|
|
841
|
-
|
|
842
|
-
module.exports =
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
833
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
834
|
+
0 && (module.exports = {
|
|
835
|
+
LocalSessionEngine,
|
|
836
|
+
createPtyProcess,
|
|
837
|
+
extractLatestTerminalTitle,
|
|
838
|
+
normalizeShellSessionOptions
|
|
839
|
+
});
|