@myagentroam/node 0.9.62 → 0.9.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +4 -0
- package/dist/capabilities.js +110 -2
- package/dist/claude-agent-sdk.js +330 -2
- package/dist/claude-channel.js +44 -2
- package/dist/codex-app-server.js +510 -2
- package/dist/config.js +106 -2
- package/dist/connector/node-connector-options.js +1 -2
- package/dist/connector/node-operation-router.js +22 -2
- package/dist/connector.js +1736 -2
- package/dist/control-outbound-scheduler.js +153 -2
- package/dist/database.js +639 -2
- package/dist/fake-runner.js +129 -2
- package/dist/git-askpass.js +12 -0
- package/dist/git-execution-helper.js +266 -0
- package/dist/health.js +3 -2
- package/dist/main.js +57 -2
- package/dist/mcp-installation-model.js +1 -2
- package/dist/migrations/v004.js +55 -3
- package/dist/migrations/v005.js +13 -3
- package/dist/migrations/v006.js +90 -3
- package/dist/migrations/v007.js +22 -3
- package/dist/migrations/v008.js +18 -3
- package/dist/migrations/v009.js +70 -4
- package/dist/migrations/v010.js +43 -3
- package/dist/migrations/v011.js +20 -3
- package/dist/migrations/v012.js +8 -0
- package/dist/native-jsonl-reader.js +186 -2
- package/dist/native-session-history.js +1143 -2
- package/dist/opencode-runtime.js +80 -2
- package/dist/opencode-server.js +259 -2
- package/dist/operational.js +122 -2
- package/dist/process-tree.js +18 -2
- package/dist/ripgrep-binary.js +31 -2
- package/dist/rotating-log.js +67 -2
- package/dist/runner/abstract-runner.js +260 -2
- package/dist/runner/claude/managed-run-controller.js +355 -2
- package/dist/runner/claude/tool-normalizer.js +120 -2
- package/dist/runner/claude-code-runner.js +303 -2
- package/dist/runner/codex/composer-image-markers.js +8 -2
- package/dist/runner/codex/conversation-parser.js +913 -2
- package/dist/runner/codex/managed-run-controller.js +494 -2
- package/dist/runner/codex/tool-normalizer.js +214 -2
- package/dist/runner/codex-runner.js +585 -2
- package/dist/runner/fake-test-runner.js +47 -2
- package/dist/runner/mar-agent/conversation-normalizer.js +644 -2
- package/dist/runner/mar-agent/executor-stdio-client-transport.js +139 -2
- package/dist/runner/mar-agent/generated-images.js +41 -2
- package/dist/runner/mar-agent/history-projection.js +106 -2
- package/dist/runner/mar-agent/hosted-conversation-runtime.js +446 -2
- package/dist/runner/mar-agent/managed-run-controller.js +785 -2
- package/dist/runner/mar-agent/mcp-client-pool.js +233 -2
- package/dist/runner/mar-agent/runtime-model-factory.js +326 -2
- package/dist/runner/mar-agent-runner.js +458 -2
- package/dist/runner/opencode/conversation-parser.js +221 -2
- package/dist/runner/opencode/managed-run-controller.js +588 -2
- package/dist/runner/opencode/tool-normalizer.js +80 -2
- package/dist/runner/opencode-runner.js +426 -2
- package/dist/runner/runner-registry.js +87 -2
- package/dist/runner-command-engine.js +71 -2
- package/dist/runner-profiles.js +323 -2
- package/dist/runner-usage.js +190 -2
- package/dist/runtime-command-detector.js +73 -2
- package/dist/runtime-model.js +1 -2
- package/dist/runtime-state.js +1509 -2
- package/dist/service/attachment-domain-state.js +7 -2
- package/dist/service/bubblewrap-sandbox-executor.js +543 -2
- package/dist/service/continuous-run-coordinator.js +425 -2
- package/dist/service/conversation-history-service.js +552 -2
- package/dist/service/conversation-hosting-capability-service.js +61 -2
- package/dist/service/conversation-hosting-enablement-service.js +91 -2
- package/dist/service/conversation-hosting-maintenance-service.js +174 -2
- package/dist/service/conversation-segment-service.js +162 -2
- package/dist/service/conversation-template-node-service.js +992 -2
- package/dist/service/external-session-resume-service.js +152 -2
- package/dist/service/fake-managed-run-service.js +60 -2
- package/dist/service/git-execution-service.js +418 -0
- package/dist/service/git-operation-service.js +57 -0
- package/dist/service/hosted-conversation-node-service.js +1982 -2
- package/dist/service/hosted-conversation-store.js +1405 -2
- package/dist/service/managed-runner-session-service.js +35 -2
- package/dist/service/mar-agent-model-transport-test-service.js +88 -2
- package/dist/service/mcp-installation-verifier.js +87 -2
- package/dist/service/mcp-node-operation-service.js +90 -2
- package/dist/service/mission-mcp-server.js +124 -2
- package/dist/service/mission-mcp-stdio.js +40 -2
- package/dist/service/mission-runtime.js +142 -2
- package/dist/service/native-session-projection-service.js +274 -2
- package/dist/service/native-session-watch-service.js +683 -2
- package/dist/service/node-connection-lifecycle-service.js +88 -2
- package/dist/service/node-control-channel.js +85 -2
- package/dist/service/node-control-message-service.js +109 -2
- package/dist/service/node-request-service.js +62 -2
- package/dist/service/node-run-event-bridge.js +88 -2
- package/dist/service/node-terminal-channel.js +202 -2
- package/dist/service/node-upgrade-coordinator.js +137 -2
- package/dist/service/node-workspace-coordinator.js +97 -2
- package/dist/service/recent-run-projection-service.js +99 -2
- package/dist/service/run-attachment-service.js +321 -2
- package/dist/service/run-domain-state.js +4 -2
- package/dist/service/run-event-service.js +246 -2
- package/dist/service/run-ownership-policy.js +22 -2
- package/dist/service/run-workbench-service.js +120 -2
- package/dist/service/runner-channel-message-service.js +20 -2
- package/dist/service/runner-interaction-service.js +243 -2
- package/dist/service/runner-service.js +69 -2
- package/dist/service/runtime-credential-control-service.js +95 -2
- package/dist/service/session-catalog-service.js +404 -2
- package/dist/service/session-command-service.js +125 -2
- package/dist/service/session-context-service.js +128 -2
- package/dist/service/session-domain-state.js +9 -2
- package/dist/service/session-identity-service.js +86 -2
- package/dist/service/session-lifecycle-service.js +248 -2
- package/dist/service/session-message-service.js +270 -2
- package/dist/service/session-presentation-service.js +43 -2
- package/dist/service/session-query-service.js +82 -2
- package/dist/service/session-watch-slot-coordinator.js +21 -2
- package/dist/service/skill-directory-service.js +238 -2
- package/dist/service/skill-install-service.js +434 -2
- package/dist/service/skill-node-operation-service.js +206 -2
- package/dist/service/terminal-relay-state.js +3 -2
- package/dist/service/terminal-service.js +90 -2
- package/dist/service/web-search-error.js +40 -2
- package/dist/service/workbench-event-service.js +21 -2
- package/dist/service/workbench-manifest-service.js +69 -2
- package/dist/service/workspace-change-service.js +290 -2
- package/dist/service/workspace-content-search-service.js +457 -2
- package/dist/service/workspace-domain-state.js +41 -2
- package/dist/service/workspace-file-service.js +150 -2
- package/dist/service/workspace-git-exclude-service.js +119 -2
- package/dist/service/workspace-queue-workbench-service.js +176 -2
- package/dist/service/workspace-service.js +92 -2
- package/dist/service/workspace-session-service.js +154 -2
- package/dist/service/workspace-upload-service.js +262 -2
- package/dist/service/workspace-watch-controller.js +68 -2
- package/dist/service/workspace-watch-service.js +170 -2
- package/dist/service/workspace-watch-snapshot-service.js +218 -2
- package/dist/service/workspace-workbench-service.js +239 -2
- package/dist/service.js +91 -2
- package/dist/storage.js +32 -2
- package/dist/supervisor.js +136 -2
- package/dist/terminal.js +496 -2
- package/dist/util/git-credential-client.js +32 -0
- package/dist/util/node-operation-data.js +9 -2
- package/dist/util/node-operation-parsers.js +382 -2
- package/dist/util/personal-instructions.js +34 -2
- package/dist/util/runner-error.js +70 -2
- package/dist/util/runner-native-session-parsers.js +510 -2
- package/dist/util/safe-error.js +8 -2
- package/dist/util/secret-environment.js +25 -2
- package/dist/workspace.js +1793 -2
- package/package.json +11 -8
- package/vendor/ripgrep/darwin-arm64/rg +0 -0
- package/vendor/ripgrep/darwin-x64/rg +0 -0
- package/vendor/ripgrep/manifest.json +12 -0
- package/README.md +0 -42
- package/dist/event-buffer.js +0 -2
- package/dist/migrations/v001.js +0 -107
- package/dist/migrations/v002.js +0 -2
- package/dist/migrations/v003.js +0 -2
- package/dist/service/mcp-package-installer.js +0 -2
package/dist/terminal.js
CHANGED
|
@@ -1,2 +1,496 @@
|
|
|
1
|
-
|
|
2
|
-
const _0x3177ad=_0xabde;(function(_0x4bbae7,_0x3f93b3){const _0xd79751=_0xabde,_0x59ed64=_0x4bbae7();while(!![]){try{const _0xaf47de=-parseInt(_0xd79751(0x1a9))/(-0x24c7+0x14d2+0xff6)*(-parseInt(_0xd79751(0x155))/(0x32c+-0x148f+0x1165))+-parseInt(_0xd79751(0x193))/(-0xc98+-0x7e6+0x1481)+parseInt(_0xd79751(0x12e))/(-0x473*-0x7+-0x117c+-0xda5)*(parseInt(_0xd79751(0x1ab))/(-0x26d2+-0x2353*0x1+0x4a2a))+parseInt(_0xd79751(0x177))/(-0xfe9+0xd43+0x2ac)+-parseInt(_0xd79751(0x13b))/(-0x28d*-0x4+0x17f*-0x14+0x13bf)*(parseInt(_0xd79751(0x16c))/(-0x1d5*0x9+-0x2bd+0x1342))+-parseInt(_0xd79751(0x13f))/(-0x2391+-0x1*-0x2108+0xe*0x2f)*(-parseInt(_0xd79751(0x1b7))/(0x1eeb*-0x1+-0x12b4+0x1*0x31a9))+parseInt(_0xd79751(0x176))/(0x1183+0xbcd*-0x1+-0x5ab)*(parseInt(_0xd79751(0x1a6))/(-0x24da+0xe12+0x16d4));if(_0xaf47de===_0x3f93b3)break;else _0x59ed64['push'](_0x59ed64['shift']());}catch(_0x4b1d6a){_0x59ed64['push'](_0x59ed64['shift']());}}}(_0x3a42,0x3*0x6934+-0xb53af+0x10d642*0x1));import{randomUUID}from'node:crypto';import{existsSync}from'node:fs';function _0xabde(_0x161dd8,_0x2ddced){_0x161dd8=_0x161dd8-(-0x696*-0x4+-0x2650+-0x22f*-0x6);const _0x28a78c=_0x3a42();let _0x1edbe1=_0x28a78c[_0x161dd8];if(_0xabde['xlkDDO']===undefined){var _0x2f7c19=function(_0x5b5f0e){const _0x2180cf='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x12b310='',_0x21e0f2='';for(let _0x58916d=0x2181+-0x24da+0x1*0x359,_0x3a2fb1,_0x327bc6,_0x1e44c4=-0x24af+-0x1fb1+0x4460;_0x327bc6=_0x5b5f0e['charAt'](_0x1e44c4++);~_0x327bc6&&(_0x3a2fb1=_0x58916d%(-0x1a56+0x1*0x1e13+0x1*-0x3b9)?_0x3a2fb1*(-0x15b9+0x928*0x1+0xcd1)+_0x327bc6:_0x327bc6,_0x58916d++%(0xc*0x32d+-0x11*-0x167+0x23*-0x1c5))?_0x12b310+=String['fromCharCode'](-0x999+-0xd3*0x1+0xb6b&_0x3a2fb1>>(-(0x463+-0x241c+-0x1*-0x1fbb)*_0x58916d&-0x5eb*0x3+-0x47*-0x7f+0x1172*-0x1)):0x3*0xf3+0x1*0x595+0xd*-0xa6){_0x327bc6=_0x2180cf['indexOf'](_0x327bc6);}for(let _0x28d37e=0xa11*0x1+0xa*0x239+-0x204b*0x1,_0x69cb35=_0x12b310['length'];_0x28d37e<_0x69cb35;_0x28d37e++){_0x21e0f2+='%'+('00'+_0x12b310['charCodeAt'](_0x28d37e)['toString'](-0x7dd+0x1123+-0x936))['slice'](-(-0x1c4c+0xb25+0x1129*0x1));}return decodeURIComponent(_0x21e0f2);};_0xabde['mngfvT']=_0x2f7c19,_0xabde['gaFFEd']={},_0xabde['xlkDDO']=!![];}const _0x56d29c=_0x28a78c[0xf9b+-0x8ad+-0x6ee];_0xabde['lZcMOt']!==_0x56d29c&&(_0xabde['gaFFEd']={},_0xabde['lZcMOt']=_0x56d29c);const _0x314da1=_0xabde['gaFFEd'][_0x161dd8];return _0x314da1===undefined?(_0x1edbe1=_0xabde['mngfvT'](_0x1edbe1),_0xabde['gaFFEd'][_0x161dd8]=_0x1edbe1):_0x1edbe1=_0x314da1,_0x1edbe1;}import{homedir}from'node:os';import{join}from'node:path';import{spawn}from'node-pty';import{terminalDataFrameSchema}from'@myagentroam/protocol';import{terminateProcessTree}from'./process-tree.js';const MAX_FRAME_CHARACTERS=-0x1b287*0x1+0xe98+0x2a3ef,DEFAULT_MAX_TERMINALS=-0x795+-0x3*0x6ec+0x1*0x1c63,DEFAULT_MAX_TERMINALS_PER_WORKSPACE=0x201a+-0x5f3*-0x2+0x2bfb*-0x1,DEFAULT_MAX_REPLAY_BYTES=(0x1f4b*-0x1+0x4*0x987+-0x4d1)*(0x17da+0xee4+-0x22be),DEFAULT_IDLE_TIMEOUT_MS=(0x1dc+-0x2128*0x1+0x1f88)*(-0x38dd+0xc3a4+0x5f99*0x1),MAX_REPLACED_ATTACHMENTS=-0x21c9+0xaaf*0x1+0x1*0x1b1a;export class TerminalManager{[_0x3177ad(0x1c0)];[_0x3177ad(0x169)];[_0x3177ad(0x127)];[_0x3177ad(0x152)];[_0x3177ad(0x13d)];[_0x3177ad(0x149)];[_0x3177ad(0x18d)];[_0x3177ad(0x19b)];[_0x3177ad(0x134)];[_0x3177ad(0x136)];[_0x3177ad(0x142)]=new Map();[_0x3177ad(0x18e)]=new Map();[_0x3177ad(0x12f)]=new Map();[_0x3177ad(0x158)]=new Set();[_0x3177ad(0x17a)]=new Set();[_0x3177ad(0x173)];constructor(_0x28e368={}){const _0x210204=_0x3177ad;this[_0x210204(0x1c0)]=_0x28e368[_0x210204(0x1c0)]??(process[_0x210204(0x1c0)]===_0x210204(0x190)?_0x210204(0x190):_0x210204(0x144)),this[_0x210204(0x169)]=_0x28e368[_0x210204(0x169)]??homedir(),this[_0x210204(0x127)]=_0x28e368[_0x210204(0x127)]??defaultTerminalProfiles(this[_0x210204(0x1c0)]);if(this[_0x210204(0x127)][_0x210204(0x137)]===0xf*0x1e2+0x3*0x2fe+0x31a*-0xc||!this[_0x210204(0x127)][_0x210204(0x133)](_0x1451c0=>_0x1451c0[_0x210204(0x12d)]))throw new Error(_0x210204(0x1b0));this[_0x210204(0x152)]=_0x28e368[_0x210204(0x152)]??DEFAULT_MAX_TERMINALS,this[_0x210204(0x13d)]=_0x28e368[_0x210204(0x13d)]??DEFAULT_MAX_TERMINALS_PER_WORKSPACE,this[_0x210204(0x149)]=_0x28e368[_0x210204(0x149)]??DEFAULT_MAX_REPLAY_BYTES,this[_0x210204(0x18d)]=_0x28e368[_0x210204(0x18d)]??DEFAULT_IDLE_TIMEOUT_MS;if(!Number[_0x210204(0x153)](this[_0x210204(0x152)])||this[_0x210204(0x152)]<0x51*0x6c+-0x26a4*-0x1+-0x48cf||this[_0x210204(0x152)]>0x1123+-0x1a5+-0xf3e||!Number[_0x210204(0x153)](this[_0x210204(0x13d)])||this[_0x210204(0x13d)]<0xb25+0xbd6*-0x1+-0x1*-0xb2||this[_0x210204(0x13d)]>this[_0x210204(0x152)]||!Number[_0x210204(0x153)](this[_0x210204(0x149)])||this[_0x210204(0x149)]<-0x7f8+-0x10dc+0x18d5||this[_0x210204(0x149)]>(-0x5c3+0x1*-0xdca+-0x1*-0x139d)*(0x10*-0x17c+-0x1*0xb51+0x2711)*(-0x21a8+0x2*0x36d+0x1ece)||!Number[_0x210204(0x153)](this[_0x210204(0x18d)])||this[_0x210204(0x18d)]<-0xc91+-0x163+-0x477*-0x4)throw new Error(_0x210204(0x17d));this[_0x210204(0x19b)]=_0x28e368[_0x210204(0x19b)]??Date[_0x210204(0x19b)],this[_0x210204(0x134)]=_0x28e368[_0x210204(0x134)]??nodePtyFactory,this[_0x210204(0x136)]=_0x28e368[_0x210204(0x136)]??((_0x28397c,_0x5e14b7)=>terminateProcessTree(_0x28397c,_0x5e14b7)),this[_0x210204(0x173)]=setInterval(()=>void this[_0x210204(0x1c1)](),Math[_0x210204(0x162)](this[_0x210204(0x18d)],-0x19*-0x10c9+-0x365*0x1a+-0x60ff)),this[_0x210204(0x173)][_0x210204(0x18f)]();}[_0x3177ad(0x175)](){const _0x508937=_0x3177ad;return this[_0x508937(0x127)][_0x508937(0x19c)](({id:_0x115bad,label:_0x174a87,isDefault:_0x1b99f5})=>({'id':_0x115bad,'label':_0x174a87,'isDefault':_0x1b99f5}));}[_0x3177ad(0x1b6)](){const _0x58bc0e=_0x3177ad;return{'maxTerminals':this[_0x58bc0e(0x152)],'maxTerminalsPerWorkspace':this[_0x58bc0e(0x13d)],'maxReplayBytes':this[_0x58bc0e(0x149)],'reconnectWindowMs':this[_0x58bc0e(0x18d)]};}[_0x3177ad(0x147)](_0x12f3f2={}){const _0x30f767=_0x3177ad,_0x19492a=_0x12f3f2[_0x30f767(0x179)]??this[_0x30f767(0x127)][_0x30f767(0x182)](_0x5a2719=>_0x5a2719[_0x30f767(0x12d)])?.['id'];if(typeof _0x19492a!==_0x30f767(0x170))throw new Error(_0x30f767(0x1b0));const _0xb75426=this[_0x30f767(0x127)][_0x30f767(0x182)](_0x41241b=>_0x41241b['id']===_0x19492a);if(_0xb75426===undefined)throw new Error(_0x30f767(0x1b0));const _0x591379=terminalDimension(_0x12f3f2[_0x30f767(0x198)],0x1*0x85a+-0x1*-0x20e6+-0x2928),_0x491e8d=terminalDimension(_0x12f3f2[_0x30f767(0x145)],0x682*0x2+0x23d1*-0x1+0x171d*0x1);if(_0x12f3f2[_0x30f767(0x169)]!==undefined&&typeof _0x12f3f2[_0x30f767(0x169)]!==_0x30f767(0x170))throw new Error(_0x30f767(0x12a));if(_0x12f3f2[_0x30f767(0x1b4)]!==undefined&&_0x12f3f2[_0x30f767(0x1b4)]!==null&&typeof _0x12f3f2[_0x30f767(0x1b4)]!==_0x30f767(0x170))throw new Error(_0x30f767(0x12a));this[_0x30f767(0x199)](_0x12f3f2[_0x30f767(0x1b4)]??null);const _0x370600=this[_0x30f767(0x134)](_0xb75426[_0x30f767(0x12c)],_0xb75426[_0x30f767(0x125)],{'name':_0x30f767(0x122),'cols':_0x491e8d,'rows':_0x591379,'cwd':typeof _0x12f3f2[_0x30f767(0x169)]===_0x30f767(0x170)?_0x12f3f2[_0x30f767(0x169)]:this[_0x30f767(0x169)],'env':{...process.env,..._0x12f3f2[_0x30f767(0x1a7)]}}),_0x42dfef=this[_0x30f767(0x19b)](),_0xc3d2cf={'id':randomUUID(),'workspaceId':_0x12f3f2[_0x30f767(0x1b4)]??null,'profile':_0xb75426,'pty':_0x370600,'createdAt':_0x42dfef,'state':_0x30f767(0x1a1),'updatedAt':_0x42dfef,'exitCode':null,'rows':_0x591379,'cols':_0x491e8d,'sequence':0x0,'replayBytes':0x0,'replay':[],'writerAttachmentId':undefined,'lastUsedAt':_0x42dfef,'detachedAt':_0x42dfef};return this[_0x30f767(0x142)][_0x30f767(0x1ac)](_0xc3d2cf['id'],_0xc3d2cf),_0x370600[_0x30f767(0x16a)](_0xfb7893=>this[_0x30f767(0x1a8)](_0xc3d2cf,_0xfb7893)),_0x370600[_0x30f767(0x13e)](_0x113c56=>this[_0x30f767(0x189)](_0xc3d2cf,_0x113c56[_0x30f767(0x1bc)])),this[_0x30f767(0x1bf)](_0xc3d2cf);}[_0x3177ad(0x1b8)](){const _0x5235b2=_0x3177ad;return[...this[_0x5235b2(0x142)][_0x5235b2(0x186)]()][_0x5235b2(0x19c)](_0x4c5c41=>this[_0x5235b2(0x19a)](_0x4c5c41));}[_0x3177ad(0x14e)](_0x597bc9){const _0x4587ad=_0x3177ad;return this[_0x4587ad(0x19a)](this[_0x4587ad(0x156)](_0x597bc9));}[_0x3177ad(0x124)](_0x57dde2){const _0x3b2ce8=_0x3177ad;if(typeof _0x57dde2[_0x3b2ce8(0x148)]!==_0x3b2ce8(0x170))throw new Error(_0x3b2ce8(0x146));const _0x2d9a29=this[_0x3b2ce8(0x156)](_0x57dde2[_0x3b2ce8(0x148)]);if(_0x2d9a29[_0x3b2ce8(0x12b)]!==_0x3b2ce8(0x1a1))throw new Error(_0x3b2ce8(0x13c));const _0x197183=terminalSequence(_0x57dde2[_0x3b2ce8(0x19d)]),_0x460c08=_0x57dde2[_0x3b2ce8(0x1ad)]===!![];if(_0x57dde2[_0x3b2ce8(0x1ad)]!==undefined&&typeof _0x57dde2[_0x3b2ce8(0x1ad)]!==_0x3b2ce8(0x15e))throw new Error(_0x3b2ce8(0x151));if(_0x57dde2[_0x3b2ce8(0x183)]!==undefined&&typeof _0x57dde2[_0x3b2ce8(0x183)]!==_0x3b2ce8(0x15e))throw new Error(_0x3b2ce8(0x151));if(!_0x460c08&&_0x2d9a29[_0x3b2ce8(0x194)]!==undefined&&_0x57dde2[_0x3b2ce8(0x183)]!==!![])throw new Error(_0x3b2ce8(0x141));if(!_0x460c08&&_0x2d9a29[_0x3b2ce8(0x194)]!==undefined){const _0x48a6fe=_0x2d9a29[_0x3b2ce8(0x194)];this[_0x3b2ce8(0x18e)][_0x3b2ce8(0x18b)](_0x48a6fe),this[_0x3b2ce8(0x12f)][_0x3b2ce8(0x18b)](_0x48a6fe),this[_0x3b2ce8(0x12f)][_0x3b2ce8(0x1ac)](_0x48a6fe,_0x2d9a29['id']);while(this[_0x3b2ce8(0x12f)][_0x3b2ce8(0x171)]>MAX_REPLACED_ATTACHMENTS){const _0x53d475=this[_0x3b2ce8(0x12f)][_0x3b2ce8(0x192)]()[_0x3b2ce8(0x131)]()[_0x3b2ce8(0x15a)];if(_0x53d475===undefined)break;this[_0x3b2ce8(0x12f)][_0x3b2ce8(0x18b)](_0x53d475);}}const _0x349a50=randomUUID();this[_0x3b2ce8(0x18e)][_0x3b2ce8(0x1ac)](_0x349a50,{'terminalId':_0x2d9a29['id'],'readonly':_0x460c08});if(!_0x460c08)_0x2d9a29[_0x3b2ce8(0x194)]=_0x349a50;_0x2d9a29[_0x3b2ce8(0x126)]=this[_0x3b2ce8(0x19b)](),_0x2d9a29[_0x3b2ce8(0x17e)]=_0x2d9a29[_0x3b2ce8(0x126)],_0x2d9a29[_0x3b2ce8(0x172)]=undefined;const _0x491140=_0x2d9a29[_0x3b2ce8(0x184)];return{'attachmentId':_0x349a50,'terminalId':_0x2d9a29['id'],'readonly':_0x460c08,'latestSequence':_0x491140,'frames':this[_0x3b2ce8(0x187)](_0x2d9a29,_0x197183)};}[_0x3177ad(0x15b)](_0x3666eb){const _0x5578d9=_0x3177ad,_0x4ddcae=this[_0x5578d9(0x18e)][_0x5578d9(0x14e)](_0x3666eb[_0x5578d9(0x161)]);if(_0x4ddcae===undefined||_0x4ddcae[_0x5578d9(0x148)]!==_0x3666eb[_0x5578d9(0x148)]){const _0x366da4=this[_0x5578d9(0x12f)][_0x5578d9(0x14e)](_0x3666eb[_0x5578d9(0x161)])===_0x3666eb[_0x5578d9(0x148)]?_0x5578d9(0x135):_0x5578d9(0x138);return this[_0x5578d9(0x12f)][_0x5578d9(0x18b)](_0x3666eb[_0x5578d9(0x161)]),{'active':![],'reason':_0x366da4,'frames':[]};}const _0x3a8b03=this[_0x5578d9(0x142)][_0x5578d9(0x14e)](_0x4ddcae[_0x5578d9(0x148)]);if(_0x3a8b03===undefined||_0x3a8b03[_0x5578d9(0x12b)]!==_0x5578d9(0x1a1))return{'active':![],'reason':_0x5578d9(0x138),'frames':[]};return{'active':!![],'frames':this[_0x5578d9(0x187)](_0x3a8b03,terminalSequence(_0x3666eb[_0x5578d9(0x19d)]))};}[_0x3177ad(0x1b1)](_0x5db947){const _0x570224=_0x3177ad;this[_0x570224(0x12f)][_0x570224(0x18b)](_0x5db947);const _0x25f874=this[_0x570224(0x18e)][_0x570224(0x14e)](_0x5db947);if(_0x25f874===undefined)return;this[_0x570224(0x18e)][_0x570224(0x18b)](_0x5db947);const _0x20a17c=this[_0x570224(0x142)][_0x570224(0x14e)](_0x25f874[_0x570224(0x148)]);if(_0x20a17c?.[_0x570224(0x194)]===_0x5db947)_0x20a17c[_0x570224(0x194)]=undefined;_0x20a17c!==undefined&&!this[_0x570224(0x14b)](_0x20a17c['id'])&&(_0x20a17c[_0x570224(0x172)]=this[_0x570224(0x19b)](),_0x20a17c[_0x570224(0x17e)]=_0x20a17c[_0x570224(0x172)],this[_0x570224(0x1bf)](_0x20a17c));}async[_0x3177ad(0x180)](_0x12183a,_0x435538){const _0x2d6850=_0x3177ad,_0x4eb3e9=terminalDataFrameSchema[_0x2d6850(0x1b2)](_0x435538);if(!_0x4eb3e9[_0x2d6850(0x197)])throw new Error(_0x2d6850(0x1bb));const _0x257198=this[_0x2d6850(0x18e)][_0x2d6850(0x14e)](_0x12183a);if(_0x257198===undefined||_0x257198[_0x2d6850(0x148)]!==_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x148)])throw new Error(_0x2d6850(0x151));const _0x3568f0=this[_0x2d6850(0x156)](_0x257198[_0x2d6850(0x148)]);if(_0x3568f0[_0x2d6850(0x12b)]!==_0x2d6850(0x1a1))throw new Error(_0x2d6850(0x13c));if(_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x196)]===_0x2d6850(0x1ae)||_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x196)]===_0x2d6850(0x19e)||_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x196)]===_0x2d6850(0x132)||_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x196)]===_0x2d6850(0x18a))throw new Error(_0x2d6850(0x1bb));if(_0x257198[_0x2d6850(0x1ad)]||_0x3568f0[_0x2d6850(0x194)]!==_0x12183a)throw new Error(_0x2d6850(0x129));_0x3568f0[_0x2d6850(0x126)]=this[_0x2d6850(0x19b)](),_0x3568f0[_0x2d6850(0x17e)]=_0x3568f0[_0x2d6850(0x126)];if(_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x196)]===_0x2d6850(0x164)){_0x3568f0[_0x2d6850(0x14a)][_0x2d6850(0x1bd)](_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x165)]);return;}if(_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x196)]===_0x2d6850(0x159)){_0x3568f0[_0x2d6850(0x14a)][_0x2d6850(0x159)](_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x145)],_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x198)]),_0x3568f0[_0x2d6850(0x145)]=_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x145)],_0x3568f0[_0x2d6850(0x198)]=_0x4eb3e9[_0x2d6850(0x165)][_0x2d6850(0x198)],this[_0x2d6850(0x1bf)](_0x3568f0);return;}await this[_0x2d6850(0x15f)](_0x3568f0['id']);}async[_0x3177ad(0x15f)](_0x23edad){const _0x10be09=_0x3177ad,_0x2b995f=this[_0x10be09(0x156)](_0x23edad);if(_0x2b995f[_0x10be09(0x12b)]!==_0x10be09(0x1a1))return this[_0x10be09(0x19a)](_0x2b995f);_0x2b995f[_0x10be09(0x12b)]=_0x10be09(0x1b9),_0x2b995f[_0x10be09(0x126)]=this[_0x10be09(0x19b)](),this[_0x10be09(0x160)](_0x2b995f);const _0x315328=this[_0x10be09(0x1bf)](_0x2b995f);try{await this[_0x10be09(0x136)](_0x2b995f[_0x10be09(0x14a)],this[_0x10be09(0x1c0)]);}finally{this[_0x10be09(0x15d)]({'type':_0x10be09(0x132),'terminalId':_0x2b995f['id'],'exitCode':_0x2b995f[_0x10be09(0x1bc)]});}return _0x315328;}async[_0x3177ad(0x185)](){const _0x5beb75=_0x3177ad;if(this[_0x5beb75(0x173)]!==undefined)clearInterval(this[_0x5beb75(0x173)]);this[_0x5beb75(0x173)]=undefined,await Promise[_0x5beb75(0x14c)]([...this[_0x5beb75(0x142)][_0x5beb75(0x186)]()][_0x5beb75(0x123)](_0x1dbc8b=>_0x1dbc8b[_0x5beb75(0x12b)]===_0x5beb75(0x1a1))[_0x5beb75(0x19c)](_0x5ef803=>this[_0x5beb75(0x15f)](_0x5ef803['id'])));}[_0x3177ad(0x166)](_0x42f0c3){const _0x18d899=_0x3177ad;return this[_0x18d899(0x158)][_0x18d899(0x1a5)](_0x42f0c3),()=>this[_0x18d899(0x158)][_0x18d899(0x18b)](_0x42f0c3);}[_0x3177ad(0x1ba)](_0xf32e94){const _0xd80436=_0x3177ad;return this[_0xd80436(0x17a)][_0xd80436(0x1a5)](_0xf32e94),()=>this[_0xd80436(0x17a)][_0xd80436(0x18b)](_0xf32e94);}async[_0x3177ad(0x1c1)](){const _0x50b535=_0x3177ad,_0x203fef=[...this[_0x50b535(0x142)][_0x50b535(0x186)]()][_0x50b535(0x123)](_0x48a89d=>_0x48a89d[_0x50b535(0x12b)]===_0x50b535(0x1a1)&&_0x48a89d[_0x50b535(0x172)]!==undefined&&this[_0x50b535(0x19b)]()-_0x48a89d[_0x50b535(0x172)]>=this[_0x50b535(0x18d)]);await Promise[_0x50b535(0x14c)](_0x203fef[_0x50b535(0x19c)](_0x2b6bfa=>this[_0x50b535(0x15f)](_0x2b6bfa['id'])));}[_0x3177ad(0x1a8)](_0x31c939,_0x487f10){const _0x862a35=_0x3177ad;if(_0x31c939[_0x862a35(0x12b)]!==_0x862a35(0x1a1)||_0x487f10[_0x862a35(0x137)]===0x116+-0x3c1*0x7+0x1931)return;for(const _0x150fee of splitFrameData(_0x487f10)){const _0xd0a5aa={'sequence':++_0x31c939[_0x862a35(0x184)],'data':_0x150fee,'bytes':Buffer[_0x862a35(0x15c)](_0x150fee,_0x862a35(0x14f))};_0x31c939[_0x862a35(0x1a0)][_0x862a35(0x16e)](_0xd0a5aa),_0x31c939[_0x862a35(0x181)]+=_0xd0a5aa[_0x862a35(0x1a4)];while(_0x31c939[_0x862a35(0x181)]>this[_0x862a35(0x149)]&&_0x31c939[_0x862a35(0x1a0)][_0x862a35(0x137)]>0x234e+-0xf7a+-0x13d4){const _0x31c7cb=_0x31c939[_0x862a35(0x1a0)][_0x862a35(0x130)]();if(_0x31c7cb!==undefined)_0x31c939[_0x862a35(0x181)]-=_0x31c7cb[_0x862a35(0x1a4)];}this[_0x862a35(0x15d)]({'type':_0x862a35(0x19e),'terminalId':_0x31c939['id'],'sequence':_0xd0a5aa[_0x862a35(0x184)],'data':_0xd0a5aa[_0x862a35(0x165)]});}}[_0x3177ad(0x189)](_0x4d3d7a,_0x4cfb2d){const _0xeaa307=_0x3177ad;if(_0x4d3d7a[_0xeaa307(0x12b)]!==_0xeaa307(0x1a1))return;_0x4d3d7a[_0xeaa307(0x12b)]=_0xeaa307(0x157),_0x4d3d7a[_0xeaa307(0x1bc)]=_0x4cfb2d,_0x4d3d7a[_0xeaa307(0x126)]=this[_0xeaa307(0x19b)](),this[_0xeaa307(0x160)](_0x4d3d7a),this[_0xeaa307(0x1bf)](_0x4d3d7a),this[_0xeaa307(0x15d)]({'type':_0xeaa307(0x132),'terminalId':_0x4d3d7a['id'],'exitCode':_0x4cfb2d});}[_0x3177ad(0x187)](_0x375538,_0x12a9ad){const _0x319886=_0x3177ad,_0x5e4256=_0x375538[_0x319886(0x1a0)][0x410*0x2+0x950*0x4+0x21*-0x160]?.[_0x319886(0x184)],_0x3a502a=[];_0x5e4256!==undefined&&_0x12a9ad<_0x5e4256-(0x1*-0x371+0x29*-0x39+-0x3*-0x431)&&_0x3a502a[_0x319886(0x16e)]({'type':_0x319886(0x18a),'terminalId':_0x375538['id'],'code':_0x319886(0x1a2)});for(const _0x4140ab of _0x375538[_0x319886(0x1a0)]){_0x4140ab[_0x319886(0x184)]>_0x12a9ad&&_0x3a502a[_0x319886(0x16e)]({'type':_0x319886(0x19e),'terminalId':_0x375538['id'],'sequence':_0x4140ab[_0x319886(0x184)],'data':_0x4140ab[_0x319886(0x165)]});}return _0x3a502a;}[_0x3177ad(0x19a)](_0x19389e){const _0x3fb718=_0x3177ad;return{'id':_0x19389e['id'],'workspaceId':_0x19389e[_0x3fb718(0x1b4)],'profileId':_0x19389e[_0x3fb718(0x188)]['id'],'state':_0x19389e[_0x3fb718(0x12b)],'createdAt':_0x19389e[_0x3fb718(0x163)],'updatedAt':_0x19389e[_0x3fb718(0x126)],'exitCode':_0x19389e[_0x3fb718(0x1bc)],'rows':_0x19389e[_0x3fb718(0x198)],'cols':_0x19389e[_0x3fb718(0x145)],'latestSequence':_0x19389e[_0x3fb718(0x184)]};}[_0x3177ad(0x1bf)](_0x55d394){const _0x1b0451=_0x3177ad,_0x3fab0f=this[_0x1b0451(0x19a)](_0x55d394);for(const _0x21f940 of this[_0x1b0451(0x17a)])_0x21f940(_0x3fab0f);return _0x3fab0f;}[_0x3177ad(0x156)](_0x18826a){const _0x1d3e6f=_0x3177ad,_0xdaf160=this[_0x1d3e6f(0x142)][_0x1d3e6f(0x14e)](_0x18826a);if(_0xdaf160===undefined)throw new Error(_0x1d3e6f(0x146));return _0xdaf160;}[_0x3177ad(0x195)](){const _0x2ecb6d=_0x3177ad;return[...this[_0x2ecb6d(0x142)][_0x2ecb6d(0x186)]()][_0x2ecb6d(0x123)](_0x3a5e6b=>_0x3a5e6b[_0x2ecb6d(0x12b)]===_0x2ecb6d(0x1a1))[_0x2ecb6d(0x137)];}[_0x3177ad(0x199)](_0x26adc5){const _0x51dab0=_0x3177ad;_0x26adc5!==null&&this[_0x51dab0(0x154)](_0x26adc5)>=this[_0x51dab0(0x13d)]&&this[_0x51dab0(0x1be)](_0x15299f=>_0x15299f[_0x51dab0(0x1b4)]===_0x26adc5);if(this[_0x51dab0(0x195)]()>=this[_0x51dab0(0x152)])this[_0x51dab0(0x1be)](()=>!![]);}[_0x3177ad(0x1be)](_0xa6b494){const _0xa2cc8c=_0x3177ad,_0x591abd=[...this[_0xa2cc8c(0x142)][_0xa2cc8c(0x186)]()][_0xa2cc8c(0x123)](_0x5a5511=>_0x5a5511[_0xa2cc8c(0x12b)]===_0xa2cc8c(0x1a1)&&_0xa6b494(_0x5a5511))[_0xa2cc8c(0x17c)]((_0x2c193d,_0x4fc4d6)=>_0x2c193d[_0xa2cc8c(0x17e)]-_0x4fc4d6[_0xa2cc8c(0x17e)]||_0x2c193d[_0xa2cc8c(0x163)]-_0x4fc4d6[_0xa2cc8c(0x163)])[0x2068+-0x1f*0x77+-0x11ff];if(_0x591abd!==undefined)void this[_0xa2cc8c(0x15f)](_0x591abd['id']);}[_0x3177ad(0x154)](_0x4d4eb9){const _0x32893f=_0x3177ad;return[...this[_0x32893f(0x142)][_0x32893f(0x186)]()][_0x32893f(0x123)](_0x45ba59=>_0x45ba59[_0x32893f(0x12b)]===_0x32893f(0x1a1)&&_0x45ba59[_0x32893f(0x1b4)]===_0x4d4eb9)[_0x32893f(0x137)];}[_0x3177ad(0x14b)](_0x1684d8){const _0x4bea15=_0x3177ad;return[...this[_0x4bea15(0x18e)][_0x4bea15(0x186)]()][_0x4bea15(0x133)](_0x438e36=>_0x438e36[_0x4bea15(0x148)]===_0x1684d8);}[_0x3177ad(0x160)](_0x21c4a6){const _0x193641=_0x3177ad;for(const [_0x5b590b,_0x3c73f4]of this[_0x193641(0x18e)]){if(_0x3c73f4[_0x193641(0x148)]===_0x21c4a6['id'])this[_0x193641(0x18e)][_0x193641(0x18b)](_0x5b590b);}for(const [_0x3a480b,_0x3647d6]of this[_0x193641(0x12f)]){if(_0x3647d6===_0x21c4a6['id'])this[_0x193641(0x12f)][_0x193641(0x18b)](_0x3a480b);}_0x21c4a6[_0x193641(0x194)]=undefined,_0x21c4a6[_0x193641(0x172)]=undefined;}[_0x3177ad(0x15d)](_0x342476){const _0x476da6=_0x3177ad;for(const _0x544216 of this[_0x476da6(0x158)])_0x544216(_0x342476);}}function nodePtyFactory(_0x247fa8,_0x4f1b77,_0x29cf85){const _0x364c07=_0x3177ad,_0x4bce22=spawn(_0x247fa8,[..._0x4f1b77],{'name':_0x29cf85[_0x364c07(0x16b)],'cols':_0x29cf85[_0x364c07(0x145)],'rows':_0x29cf85[_0x364c07(0x198)],'cwd':_0x29cf85[_0x364c07(0x169)],'env':_0x29cf85[_0x364c07(0x191)]});return _0x4bce22;}function _0x3a42(){const _0x3190f4=['EhrLCM0TmJu2y29SB3i','zMLSDgvY','yxv0Ag9YAxPLqxr0ywnO','yxjNCW','DxbKyxrLzef0','ChjVzMLSzxm','ug93zxjtAgvSBca3','vevstuLoquXFv1jjvevFrevosuve','vevstuLoquXFt1bftL9jtLzbteLe','C3rHDgu','C2HLBgW','AxnezwzHDwX0','nJe2odr4suLhuxi','CMvWBgfJzwrbDhrHy2HTzw50CW','C2HPzNq','BMv4Da','zxHPDa','C29Tzq','Chr5rMfJDg9YEq','uKvqtefdruq','DgvYBwLUyxrL','BgvUz3rO','su5bq1rjvKu','qZPCv2LUzg93C1XtExn0zw0ZmLXJBwqUzxHL','DhjPBq','mZiWnM5dAxL3CG','vevstuLoquXFq0Xpu0ve','Bwf4vgvYBwLUywXZugvYv29YA3nWywnL','B25fEgL0','nZjiuhrfyvC','ChDZAc5LEgu','vevstuLoquXFqvruqunix0nptKzmsunu','DgvYBwLUywXZ','u3LZDgvTmZi','BgLUDxG','y29SCW','vevstuLoquXFtK9ux0zpvu5e','B3bLBG','DgvYBwLUywXjza','Bwf4uMvWBgf5qNL0zxm','Chr5','AgfZqxr0ywnOBwvUDa','ywXS','vevstuLoquXFreLnru5tsu9ou19jtLzbteLe','z2v0','DxrMoa','C3bSAxq','vevstuLoquXFqvruqunix0LovKfmsuq','Bwf4vgvYBwLUywXZ','AxntywzLsw50zwDLCG','CNvUBMLUz0nVDw50rM9Yv29YA3nWywnL','ndyXntrksgzct0C','CMvXDwLYzvrLCM1PBMfS','rvHjveve','zNjHBwvmAxn0zw5LCNm','CMvZAxPL','DMfSDwu','C3LUy2HYB25PEMvbDhrHy2HTzw50','yNL0zuXLBMD0Aa','zw1PDa','yM9VBgvHBG','y2XVC2u','zgv0ywnOqwXS','yxr0ywnOBwvUDeLK','BwLU','y3jLyxrLzef0','Aw5WDxq','zgf0yq','B25gCMfTzq','AxnjBNrLz2vY','Cg93zxjZAgvSBc5LEgu','y3DK','B25eyxrH','BMfTzq','mtm1mdrHDenVALO','y2HHCKnVzgvbDa','ChvZAa','v2LUzg93C1bVD2vYu2HLBgW','C3rYAw5N','C2L6zq','zgv0ywnOzwrbDa','AwrSzvrPBwvY','vevstuLoquXFuKvqtefzx0LovKfmsuq','yxzHAwXHyMXLuhjVzMLSzxm','mtfJz0jxA1y','nJKYotiYDMnpA2T0','vxnLCIbtAgvSBa','ChjVzMLSzuLK','C3vTBwfYEuXPC3rLBMvYCW','y21KlMv4zq','C29YDa','vevstuLoquXFq09orKLhx0LovKfmsuq','BgfZDfvZzwrbDa','C2XPy2u','ywnJzxb0rNjHBwu','CMvWBgf5qNL0zxm','zMLUza','DgfRzw92zxi','C2vXDwvUy2u','C2H1DgrVD24','DMfSDwvZ','CMvWBgf5rNjHBwvZ','ChjVzMLSzq','zxHPDgvK','zxjYB3i','zgvSzxrL','DJeUma','AwrSzvrPBwvVDxrnCW','yxr0ywnOBwvUDhm','Dw5Yzwy','D2LUmZi','zw52','A2v5CW','mtC2nte0m0nHuvjdza','D3jPDgvYqxr0ywnOBwvUDeLK','CNvUBMLUz0nVDw50','DhLWzq','C3vJy2vZCW','CM93CW','zxzPy3rgB3jozxDuzxjTAw5HBa','C3vTBwfYEq','BM93','BwfW','ywz0zxjtzxf1zw5Jzq','B3v0Chv0','ug93zxjtAgvSBa','CMvWBgf5','uLvotKLorW','vevstuLoquXFuKvqtefzx0Dbua','l2jPBI9IyxnO','yNL0zxm','ywrK','mZC4mJy3nLLWshjjEG','zw52AxjVBM1LBNq','CMvJB3jKt3v0Chv0','mZvtDw9kr0e','BNvTyMvY','otvWzw5vAwe','C2v0','CMvHzg9UBhK','yxr0ywnO','v2LUzg93CYbdB21Tyw5KifbYB21WDa','vevstuLoquXFufjprKLmrv9jtLzbteLe','zgv0ywnO','C2fMzvbHCNnL','zgvMyxvSDa','D29YA3nWywnLswq','v2LUzg93CYbqB3DLCLnOzwXS','BgLTAxrZ','mZm5otGWvw5pEvjm','BgLZDa','q0Xpu0ve','B25tDw1Tyxj5','vevstuLoquXFrLjbtuvFsu5wquXjra','zxHPDenVzgu','D3jPDgu','zxzPy3rmzwfZDfjLy2vUDgX5vxnLza','BM90Awz5u3vTBwfYEq','CgXHDgzVCM0','y2XVC2vfEhbPCMvK'];_0x3a42=function(){return _0x3190f4;};return _0x3a42();}export function defaultTerminalProfiles(_0x24e698,_0x461085=resolveWindowsExecutable){const _0x406c0a=_0x3177ad;if(_0x24e698===_0x406c0a(0x190)){const _0x4ac926=_0x461085(_0x406c0a(0x140)),_0x42f685=_0x4ac926===undefined?_0x461085(_0x406c0a(0x168)):undefined,_0x305593=_0x4ac926===undefined&&_0x42f685===undefined?_0x461085(_0x406c0a(0x17b))??process.env['ComSpec']??_0x406c0a(0x139):undefined;return[{'id':_0x406c0a(0x1b3),'label':_0x4ac926===undefined?_0x42f685===undefined?_0x406c0a(0x1af):_0x406c0a(0x1b5):_0x406c0a(0x128),'shell':_0x4ac926??_0x42f685??_0x305593,'args':[],'isDefault':!![]}];}return[{'id':_0x406c0a(0x1b3),'label':_0x406c0a(0x178),'shell':process.env['SHELL']?.[_0x406c0a(0x13a)]()||_0x406c0a(0x1a3),'args':['-l','-i'],'isDefault':!![]}];}function resolveWindowsExecutable(_0x261724){const _0x37c3f2=_0x3177ad,_0x8237dc=process.env['Path']?.[_0x37c3f2(0x13a)]()||process.env['PATH'];for(const _0x59e566 of _0x8237dc?.[_0x37c3f2(0x150)](';')??[]){const _0x2c971c=join(_0x59e566[_0x37c3f2(0x13a)](),_0x261724);if(_0x59e566[_0x37c3f2(0x13a)]()!==''&&existsSync(_0x2c971c))return _0x2c971c;}if(_0x261724===_0x37c3f2(0x140)){const _0x5ef979=process.env['ProgramFiles'],_0x3230ec=_0x5ef979===undefined?undefined:join(_0x5ef979,_0x37c3f2(0x19f),'7',_0x261724);return _0x3230ec!==undefined&&existsSync(_0x3230ec)?_0x3230ec:undefined;}if(_0x261724===_0x37c3f2(0x168)){const _0x3595e8=process.env['SystemRoot']??process.env['windir'],_0x49af6e=_0x3595e8===undefined?undefined:join(_0x3595e8,_0x37c3f2(0x143),_0x37c3f2(0x16f),_0x37c3f2(0x18c),_0x261724);return _0x49af6e!==undefined&&existsSync(_0x49af6e)?_0x49af6e:undefined;}return process.env['ComSpec']??process.env['COMSPEC'];}function terminalDimension(_0x1e4905,_0x532d4f){const _0x132b1e=_0x3177ad;if(_0x1e4905===undefined)return _0x532d4f;if(typeof _0x1e4905!==_0x132b1e(0x1aa)||!Number[_0x132b1e(0x167)](_0x1e4905)||_0x1e4905<0x1107+-0x2f9*-0x9+0x641*-0x7||_0x1e4905>0x9*-0xdf+0x634+0x58b)throw new Error(_0x132b1e(0x14d));return _0x1e4905;}function terminalSequence(_0x367cdb){const _0x49e5be=_0x3177ad;if(_0x367cdb===undefined)return 0x1c88+0x2b6*-0x2+0x11*-0x15c;if(typeof _0x367cdb!==_0x49e5be(0x1aa)||!Number[_0x49e5be(0x167)](_0x367cdb)||_0x367cdb<-0x3e7*0x3+0x24d5+0x86*-0x30)throw new Error(_0x49e5be(0x174));return _0x367cdb;}function splitFrameData(_0x49920a){const _0x284b46=_0x3177ad;if(_0x49920a[_0x284b46(0x137)]<=MAX_FRAME_CHARACTERS)return[_0x49920a];const _0xb9a205=[];for(let _0x307400=0xa9c+0x1*-0x1f2d+-0x1*-0x1491;_0x307400<_0x49920a[_0x284b46(0x137)];){let _0x17b6b1=Math[_0x284b46(0x162)](_0x49920a[_0x284b46(0x137)],_0x307400+MAX_FRAME_CHARACTERS);if(_0x17b6b1<_0x49920a[_0x284b46(0x137)]&&_0x49920a[_0x284b46(0x16d)](_0x17b6b1-(0x2e5+-0x21+-0x1*0x2c3))>=-0xfc4b*-0x1+0x4de*-0x43+0x121cf&&_0x49920a[_0x284b46(0x16d)](_0x17b6b1-(0x1fad+-0xa1b+0x1591*-0x1))<=-0x9cb4+0x55d5+-0x3e*-0x4b1&&_0x49920a[_0x284b46(0x16d)](_0x17b6b1)>=-0x3211+-0x9a7d+-0x1f*-0xdb2&&_0x49920a[_0x284b46(0x16d)](_0x17b6b1)<=-0x1*0xd5f2+-0xf227*-0x1+-0x13*-0xa4e)_0x17b6b1-=0x1192+-0x6f*0x4+-0xfd5;_0xb9a205[_0x284b46(0x16e)](_0x49920a[_0x284b46(0x17f)](_0x307400,_0x17b6b1)),_0x307400=_0x17b6b1;}return _0xb9a205;}
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { spawn } from 'node-pty';
|
|
6
|
+
import { terminalDataFrameSchema } from '@myagentroam/protocol';
|
|
7
|
+
import { terminateProcessTree } from './process-tree.js';
|
|
8
|
+
const MAX_FRAME_CHARACTERS = 65_536;
|
|
9
|
+
const DEFAULT_MAX_TERMINALS = 10;
|
|
10
|
+
const DEFAULT_MAX_TERMINALS_PER_WORKSPACE = 5;
|
|
11
|
+
const DEFAULT_MAX_REPLAY_BYTES = 512 * 1024;
|
|
12
|
+
const DEFAULT_IDLE_TIMEOUT_MS = 60 * 60_000;
|
|
13
|
+
const MAX_REPLACED_ATTACHMENTS = 1_024;
|
|
14
|
+
/**
|
|
15
|
+
* Owns Node-local PTY/ConPTY processes and their bounded output replay.
|
|
16
|
+
* Browser relay transport intentionally lives outside this class: callers pass
|
|
17
|
+
* only schema-validated TerminalDataFrame values after Server authorization.
|
|
18
|
+
*/
|
|
19
|
+
export class TerminalManager {
|
|
20
|
+
platform;
|
|
21
|
+
cwd;
|
|
22
|
+
profiles;
|
|
23
|
+
maxTerminals;
|
|
24
|
+
maxTerminalsPerWorkspace;
|
|
25
|
+
maxReplayBytes;
|
|
26
|
+
idleTimeoutMs;
|
|
27
|
+
now;
|
|
28
|
+
ptyFactory;
|
|
29
|
+
terminate;
|
|
30
|
+
terminals = new Map();
|
|
31
|
+
attachments = new Map();
|
|
32
|
+
replacedAttachments = new Map();
|
|
33
|
+
frameListeners = new Set();
|
|
34
|
+
summaryListeners = new Set();
|
|
35
|
+
idleTimer;
|
|
36
|
+
constructor(options = {}) {
|
|
37
|
+
this.platform =
|
|
38
|
+
options.platform ??
|
|
39
|
+
(process.platform === 'win32' ? 'win32' : process.platform === 'darwin' ? 'darwin' : 'linux');
|
|
40
|
+
this.cwd = options.cwd ?? homedir();
|
|
41
|
+
this.profiles = options.profiles ?? defaultTerminalProfiles(this.platform);
|
|
42
|
+
if (this.profiles.length === 0 || !this.profiles.some((profile) => profile.isDefault)) {
|
|
43
|
+
throw new Error('TERMINAL_PROFILE_INVALID');
|
|
44
|
+
}
|
|
45
|
+
this.maxTerminals = options.maxTerminals ?? DEFAULT_MAX_TERMINALS;
|
|
46
|
+
this.maxTerminalsPerWorkspace =
|
|
47
|
+
options.maxTerminalsPerWorkspace ?? DEFAULT_MAX_TERMINALS_PER_WORKSPACE;
|
|
48
|
+
this.maxReplayBytes = options.maxReplayBytes ?? DEFAULT_MAX_REPLAY_BYTES;
|
|
49
|
+
this.idleTimeoutMs = options.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
50
|
+
if (!Number.isSafeInteger(this.maxTerminals) ||
|
|
51
|
+
this.maxTerminals < 1 ||
|
|
52
|
+
this.maxTerminals > 64 ||
|
|
53
|
+
!Number.isSafeInteger(this.maxTerminalsPerWorkspace) ||
|
|
54
|
+
this.maxTerminalsPerWorkspace < 1 ||
|
|
55
|
+
this.maxTerminalsPerWorkspace > this.maxTerminals ||
|
|
56
|
+
!Number.isSafeInteger(this.maxReplayBytes) ||
|
|
57
|
+
this.maxReplayBytes < 1 ||
|
|
58
|
+
this.maxReplayBytes > 16 * 1024 * 1024 ||
|
|
59
|
+
!Number.isSafeInteger(this.idleTimeoutMs) ||
|
|
60
|
+
this.idleTimeoutMs < 1_000) {
|
|
61
|
+
throw new Error('TERMINAL_CONFIG_INVALID');
|
|
62
|
+
}
|
|
63
|
+
this.now = options.now ?? Date.now;
|
|
64
|
+
this.ptyFactory = options.ptyFactory ?? nodePtyFactory;
|
|
65
|
+
this.terminate =
|
|
66
|
+
options.terminate ?? ((child, platform) => terminateProcessTree(child, platform));
|
|
67
|
+
this.idleTimer = setInterval(() => void this.closeExpired(), Math.min(this.idleTimeoutMs, 60_000));
|
|
68
|
+
this.idleTimer.unref();
|
|
69
|
+
}
|
|
70
|
+
availableProfiles() {
|
|
71
|
+
return this.profiles.map(({ id, label, isDefault }) => ({ id, label, isDefault }));
|
|
72
|
+
}
|
|
73
|
+
limits() {
|
|
74
|
+
return {
|
|
75
|
+
maxTerminals: this.maxTerminals,
|
|
76
|
+
maxTerminalsPerWorkspace: this.maxTerminalsPerWorkspace,
|
|
77
|
+
maxReplayBytes: this.maxReplayBytes,
|
|
78
|
+
reconnectWindowMs: this.idleTimeoutMs
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
open(input = {}) {
|
|
82
|
+
const profileId = input.profileId ?? this.profiles.find((profile) => profile.isDefault)?.id;
|
|
83
|
+
if (typeof profileId !== 'string')
|
|
84
|
+
throw new Error('TERMINAL_PROFILE_INVALID');
|
|
85
|
+
const profile = this.profiles.find((candidate) => candidate.id === profileId);
|
|
86
|
+
if (profile === undefined)
|
|
87
|
+
throw new Error('TERMINAL_PROFILE_INVALID');
|
|
88
|
+
const rows = terminalDimension(input.rows, 24);
|
|
89
|
+
const cols = terminalDimension(input.cols, 80);
|
|
90
|
+
if (input.cwd !== undefined && typeof input.cwd !== 'string')
|
|
91
|
+
throw new Error('TERMINAL_OPEN_INVALID');
|
|
92
|
+
if (input.workspaceId !== undefined &&
|
|
93
|
+
input.workspaceId !== null &&
|
|
94
|
+
typeof input.workspaceId !== 'string')
|
|
95
|
+
throw new Error('TERMINAL_OPEN_INVALID');
|
|
96
|
+
this.evictForNewTerminal(input.workspaceId ?? null);
|
|
97
|
+
const pty = this.ptyFactory(profile.shell, profile.args, {
|
|
98
|
+
name: 'xterm-256color',
|
|
99
|
+
cols,
|
|
100
|
+
rows,
|
|
101
|
+
cwd: typeof input.cwd === 'string' ? input.cwd : this.cwd,
|
|
102
|
+
env: { ...process.env, ...input.environment }
|
|
103
|
+
});
|
|
104
|
+
const createdAt = this.now();
|
|
105
|
+
const terminal = {
|
|
106
|
+
id: randomUUID(),
|
|
107
|
+
workspaceId: input.workspaceId ?? null,
|
|
108
|
+
profile,
|
|
109
|
+
pty,
|
|
110
|
+
createdAt,
|
|
111
|
+
state: 'RUNNING',
|
|
112
|
+
updatedAt: createdAt,
|
|
113
|
+
exitCode: null,
|
|
114
|
+
rows,
|
|
115
|
+
cols,
|
|
116
|
+
sequence: 0,
|
|
117
|
+
replayBytes: 0,
|
|
118
|
+
replay: [],
|
|
119
|
+
writerAttachmentId: undefined,
|
|
120
|
+
lastUsedAt: createdAt,
|
|
121
|
+
detachedAt: createdAt
|
|
122
|
+
};
|
|
123
|
+
this.terminals.set(terminal.id, terminal);
|
|
124
|
+
pty.onData((data) => this.recordOutput(terminal, data));
|
|
125
|
+
pty.onExit((event) => this.exited(terminal, event.exitCode));
|
|
126
|
+
return this.notifySummary(terminal);
|
|
127
|
+
}
|
|
128
|
+
list() {
|
|
129
|
+
return [...this.terminals.values()].map((terminal) => this.summary(terminal));
|
|
130
|
+
}
|
|
131
|
+
get(terminalId) {
|
|
132
|
+
return this.summary(this.requireTerminal(terminalId));
|
|
133
|
+
}
|
|
134
|
+
/** One attachment may write. A new writer must explicitly take over. */
|
|
135
|
+
authorizeAttach(input) {
|
|
136
|
+
if (typeof input.terminalId !== 'string')
|
|
137
|
+
throw new Error('TERMINAL_NOT_FOUND');
|
|
138
|
+
const terminal = this.requireTerminal(input.terminalId);
|
|
139
|
+
if (terminal.state !== 'RUNNING')
|
|
140
|
+
throw new Error('TERMINAL_CLOSED');
|
|
141
|
+
const afterSequence = terminalSequence(input.afterSequence);
|
|
142
|
+
const readonly = input.readonly === true;
|
|
143
|
+
if (input.readonly !== undefined && typeof input.readonly !== 'boolean')
|
|
144
|
+
throw new Error('TERMINAL_ATTACH_INVALID');
|
|
145
|
+
if (input.takeover !== undefined && typeof input.takeover !== 'boolean')
|
|
146
|
+
throw new Error('TERMINAL_ATTACH_INVALID');
|
|
147
|
+
if (!readonly && terminal.writerAttachmentId !== undefined && input.takeover !== true) {
|
|
148
|
+
throw new Error('TERMINAL_ATTACH_CONFLICT');
|
|
149
|
+
}
|
|
150
|
+
if (!readonly && terminal.writerAttachmentId !== undefined) {
|
|
151
|
+
const replacedAttachmentId = terminal.writerAttachmentId;
|
|
152
|
+
this.attachments.delete(replacedAttachmentId);
|
|
153
|
+
this.replacedAttachments.delete(replacedAttachmentId);
|
|
154
|
+
this.replacedAttachments.set(replacedAttachmentId, terminal.id);
|
|
155
|
+
while (this.replacedAttachments.size > MAX_REPLACED_ATTACHMENTS) {
|
|
156
|
+
const oldest = this.replacedAttachments.keys().next().value;
|
|
157
|
+
if (oldest === undefined)
|
|
158
|
+
break;
|
|
159
|
+
this.replacedAttachments.delete(oldest);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const attachmentId = randomUUID();
|
|
163
|
+
this.attachments.set(attachmentId, { terminalId: terminal.id, readonly });
|
|
164
|
+
if (!readonly)
|
|
165
|
+
terminal.writerAttachmentId = attachmentId;
|
|
166
|
+
terminal.updatedAt = this.now();
|
|
167
|
+
terminal.lastUsedAt = terminal.updatedAt;
|
|
168
|
+
terminal.detachedAt = undefined;
|
|
169
|
+
const latestSequence = terminal.sequence;
|
|
170
|
+
return {
|
|
171
|
+
attachmentId,
|
|
172
|
+
terminalId: terminal.id,
|
|
173
|
+
readonly,
|
|
174
|
+
latestSequence,
|
|
175
|
+
frames: this.replayFrames(terminal, afterSequence)
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
synchronizeAttachment(input) {
|
|
179
|
+
const attachment = this.attachments.get(input.attachmentId);
|
|
180
|
+
if (attachment === undefined || attachment.terminalId !== input.terminalId) {
|
|
181
|
+
const reason = this.replacedAttachments.get(input.attachmentId) === input.terminalId
|
|
182
|
+
? 'REPLACED'
|
|
183
|
+
: 'INACTIVE';
|
|
184
|
+
this.replacedAttachments.delete(input.attachmentId);
|
|
185
|
+
return { active: false, reason, frames: [] };
|
|
186
|
+
}
|
|
187
|
+
const terminal = this.terminals.get(attachment.terminalId);
|
|
188
|
+
if (terminal === undefined || terminal.state !== 'RUNNING') {
|
|
189
|
+
return { active: false, reason: 'INACTIVE', frames: [] };
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
active: true,
|
|
193
|
+
frames: this.replayFrames(terminal, terminalSequence(input.afterSequence))
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
detach(attachmentId) {
|
|
197
|
+
this.replacedAttachments.delete(attachmentId);
|
|
198
|
+
const attachment = this.attachments.get(attachmentId);
|
|
199
|
+
if (attachment === undefined)
|
|
200
|
+
return;
|
|
201
|
+
this.attachments.delete(attachmentId);
|
|
202
|
+
const terminal = this.terminals.get(attachment.terminalId);
|
|
203
|
+
if (terminal?.writerAttachmentId === attachmentId)
|
|
204
|
+
terminal.writerAttachmentId = undefined;
|
|
205
|
+
if (terminal !== undefined && !this.hasAttachment(terminal.id)) {
|
|
206
|
+
terminal.detachedAt = this.now();
|
|
207
|
+
terminal.lastUsedAt = terminal.detachedAt;
|
|
208
|
+
this.notifySummary(terminal);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** Processes data frames from an already-authorized Server relay attachment. */
|
|
212
|
+
async acceptFrame(attachmentId, frame) {
|
|
213
|
+
const parsed = terminalDataFrameSchema.safeParse(frame);
|
|
214
|
+
if (!parsed.success)
|
|
215
|
+
throw new Error('TERMINAL_FRAME_INVALID');
|
|
216
|
+
const attachment = this.attachments.get(attachmentId);
|
|
217
|
+
if (attachment === undefined || attachment.terminalId !== parsed.data.terminalId)
|
|
218
|
+
throw new Error('TERMINAL_ATTACH_INVALID');
|
|
219
|
+
const terminal = this.requireTerminal(attachment.terminalId);
|
|
220
|
+
if (terminal.state !== 'RUNNING')
|
|
221
|
+
throw new Error('TERMINAL_CLOSED');
|
|
222
|
+
if (parsed.data.type === 'attach' ||
|
|
223
|
+
parsed.data.type === 'output' ||
|
|
224
|
+
parsed.data.type === 'exit' ||
|
|
225
|
+
parsed.data.type === 'error') {
|
|
226
|
+
throw new Error('TERMINAL_FRAME_INVALID');
|
|
227
|
+
}
|
|
228
|
+
if (attachment.readonly || terminal.writerAttachmentId !== attachmentId)
|
|
229
|
+
throw new Error('TERMINAL_WRITE_DENIED');
|
|
230
|
+
terminal.updatedAt = this.now();
|
|
231
|
+
terminal.lastUsedAt = terminal.updatedAt;
|
|
232
|
+
if (parsed.data.type === 'input') {
|
|
233
|
+
terminal.pty.write(parsed.data.data);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (parsed.data.type === 'resize') {
|
|
237
|
+
terminal.pty.resize(parsed.data.cols, parsed.data.rows);
|
|
238
|
+
terminal.cols = parsed.data.cols;
|
|
239
|
+
terminal.rows = parsed.data.rows;
|
|
240
|
+
this.notifySummary(terminal);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
await this.close(terminal.id);
|
|
244
|
+
}
|
|
245
|
+
async close(terminalId) {
|
|
246
|
+
const terminal = this.requireTerminal(terminalId);
|
|
247
|
+
if (terminal.state !== 'RUNNING')
|
|
248
|
+
return this.summary(terminal);
|
|
249
|
+
terminal.state = 'CLOSED';
|
|
250
|
+
terminal.updatedAt = this.now();
|
|
251
|
+
this.detachAll(terminal);
|
|
252
|
+
const summary = this.notifySummary(terminal);
|
|
253
|
+
try {
|
|
254
|
+
await this.terminate(terminal.pty, this.platform);
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
this.emit({ type: 'exit', terminalId: terminal.id, exitCode: terminal.exitCode });
|
|
258
|
+
}
|
|
259
|
+
return summary;
|
|
260
|
+
}
|
|
261
|
+
async shutdown() {
|
|
262
|
+
if (this.idleTimer !== undefined)
|
|
263
|
+
clearInterval(this.idleTimer);
|
|
264
|
+
this.idleTimer = undefined;
|
|
265
|
+
await Promise.all([...this.terminals.values()]
|
|
266
|
+
.filter((terminal) => terminal.state === 'RUNNING')
|
|
267
|
+
.map((terminal) => this.close(terminal.id)));
|
|
268
|
+
}
|
|
269
|
+
onFrame(listener) {
|
|
270
|
+
this.frameListeners.add(listener);
|
|
271
|
+
return () => this.frameListeners.delete(listener);
|
|
272
|
+
}
|
|
273
|
+
onSummary(listener) {
|
|
274
|
+
this.summaryListeners.add(listener);
|
|
275
|
+
return () => this.summaryListeners.delete(listener);
|
|
276
|
+
}
|
|
277
|
+
async closeExpired() {
|
|
278
|
+
const expired = [...this.terminals.values()].filter((terminal) => terminal.state === 'RUNNING' &&
|
|
279
|
+
terminal.detachedAt !== undefined &&
|
|
280
|
+
this.now() - terminal.detachedAt >= this.idleTimeoutMs);
|
|
281
|
+
await Promise.all(expired.map((terminal) => this.close(terminal.id)));
|
|
282
|
+
}
|
|
283
|
+
recordOutput(terminal, data) {
|
|
284
|
+
if (terminal.state !== 'RUNNING' || data.length === 0)
|
|
285
|
+
return;
|
|
286
|
+
for (const part of splitFrameData(data)) {
|
|
287
|
+
const frame = {
|
|
288
|
+
sequence: ++terminal.sequence,
|
|
289
|
+
data: part,
|
|
290
|
+
bytes: Buffer.byteLength(part, 'utf8')
|
|
291
|
+
};
|
|
292
|
+
terminal.replay.push(frame);
|
|
293
|
+
terminal.replayBytes += frame.bytes;
|
|
294
|
+
while (terminal.replayBytes > this.maxReplayBytes && terminal.replay.length > 0) {
|
|
295
|
+
const removed = terminal.replay.shift();
|
|
296
|
+
if (removed !== undefined)
|
|
297
|
+
terminal.replayBytes -= removed.bytes;
|
|
298
|
+
}
|
|
299
|
+
this.emit({
|
|
300
|
+
type: 'output',
|
|
301
|
+
terminalId: terminal.id,
|
|
302
|
+
sequence: frame.sequence,
|
|
303
|
+
data: frame.data
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
exited(terminal, exitCode) {
|
|
308
|
+
if (terminal.state !== 'RUNNING')
|
|
309
|
+
return;
|
|
310
|
+
terminal.state = 'EXITED';
|
|
311
|
+
terminal.exitCode = exitCode;
|
|
312
|
+
terminal.updatedAt = this.now();
|
|
313
|
+
this.detachAll(terminal);
|
|
314
|
+
this.notifySummary(terminal);
|
|
315
|
+
this.emit({ type: 'exit', terminalId: terminal.id, exitCode });
|
|
316
|
+
}
|
|
317
|
+
replayFrames(terminal, afterSequence) {
|
|
318
|
+
const first = terminal.replay[0]?.sequence;
|
|
319
|
+
const frames = [];
|
|
320
|
+
if (first !== undefined && afterSequence < first - 1) {
|
|
321
|
+
frames.push({ type: 'error', terminalId: terminal.id, code: 'TERMINAL_REPLAY_GAP' });
|
|
322
|
+
}
|
|
323
|
+
for (const replay of terminal.replay) {
|
|
324
|
+
if (replay.sequence > afterSequence) {
|
|
325
|
+
frames.push({
|
|
326
|
+
type: 'output',
|
|
327
|
+
terminalId: terminal.id,
|
|
328
|
+
sequence: replay.sequence,
|
|
329
|
+
data: replay.data
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return frames;
|
|
334
|
+
}
|
|
335
|
+
summary(terminal) {
|
|
336
|
+
return {
|
|
337
|
+
id: terminal.id,
|
|
338
|
+
workspaceId: terminal.workspaceId,
|
|
339
|
+
profileId: terminal.profile.id,
|
|
340
|
+
state: terminal.state,
|
|
341
|
+
createdAt: terminal.createdAt,
|
|
342
|
+
updatedAt: terminal.updatedAt,
|
|
343
|
+
exitCode: terminal.exitCode,
|
|
344
|
+
rows: terminal.rows,
|
|
345
|
+
cols: terminal.cols,
|
|
346
|
+
latestSequence: terminal.sequence
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
notifySummary(terminal) {
|
|
350
|
+
const summary = this.summary(terminal);
|
|
351
|
+
for (const listener of this.summaryListeners)
|
|
352
|
+
listener(summary);
|
|
353
|
+
return summary;
|
|
354
|
+
}
|
|
355
|
+
requireTerminal(terminalId) {
|
|
356
|
+
const terminal = this.terminals.get(terminalId);
|
|
357
|
+
if (terminal === undefined)
|
|
358
|
+
throw new Error('TERMINAL_NOT_FOUND');
|
|
359
|
+
return terminal;
|
|
360
|
+
}
|
|
361
|
+
runningCount() {
|
|
362
|
+
return [...this.terminals.values()].filter((terminal) => terminal.state === 'RUNNING').length;
|
|
363
|
+
}
|
|
364
|
+
evictForNewTerminal(workspaceId) {
|
|
365
|
+
if (workspaceId !== null &&
|
|
366
|
+
this.runningCountForWorkspace(workspaceId) >= this.maxTerminalsPerWorkspace) {
|
|
367
|
+
this.evictLeastRecentlyUsed((terminal) => terminal.workspaceId === workspaceId);
|
|
368
|
+
}
|
|
369
|
+
if (this.runningCount() >= this.maxTerminals)
|
|
370
|
+
this.evictLeastRecentlyUsed(() => true);
|
|
371
|
+
}
|
|
372
|
+
evictLeastRecentlyUsed(predicate) {
|
|
373
|
+
const candidate = [...this.terminals.values()]
|
|
374
|
+
.filter((terminal) => terminal.state === 'RUNNING' && predicate(terminal))
|
|
375
|
+
.sort((left, right) => left.lastUsedAt - right.lastUsedAt || left.createdAt - right.createdAt)[0];
|
|
376
|
+
if (candidate !== undefined)
|
|
377
|
+
void this.close(candidate.id);
|
|
378
|
+
}
|
|
379
|
+
runningCountForWorkspace(workspaceId) {
|
|
380
|
+
return [...this.terminals.values()].filter((terminal) => terminal.state === 'RUNNING' && terminal.workspaceId === workspaceId).length;
|
|
381
|
+
}
|
|
382
|
+
hasAttachment(terminalId) {
|
|
383
|
+
return [...this.attachments.values()].some((attachment) => attachment.terminalId === terminalId);
|
|
384
|
+
}
|
|
385
|
+
detachAll(terminal) {
|
|
386
|
+
for (const [attachmentId, attachment] of this.attachments) {
|
|
387
|
+
if (attachment.terminalId === terminal.id)
|
|
388
|
+
this.attachments.delete(attachmentId);
|
|
389
|
+
}
|
|
390
|
+
for (const [attachmentId, terminalId] of this.replacedAttachments) {
|
|
391
|
+
if (terminalId === terminal.id)
|
|
392
|
+
this.replacedAttachments.delete(attachmentId);
|
|
393
|
+
}
|
|
394
|
+
terminal.writerAttachmentId = undefined;
|
|
395
|
+
terminal.detachedAt = undefined;
|
|
396
|
+
}
|
|
397
|
+
emit(frame) {
|
|
398
|
+
for (const listener of this.frameListeners)
|
|
399
|
+
listener(frame);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function nodePtyFactory(shell, args, options) {
|
|
403
|
+
const pty = spawn(shell, [...args], {
|
|
404
|
+
name: options.name,
|
|
405
|
+
cols: options.cols,
|
|
406
|
+
rows: options.rows,
|
|
407
|
+
cwd: options.cwd,
|
|
408
|
+
env: options.env
|
|
409
|
+
});
|
|
410
|
+
return pty;
|
|
411
|
+
}
|
|
412
|
+
export function defaultTerminalProfiles(platform, findWindowsExecutable = resolveWindowsExecutable) {
|
|
413
|
+
if (platform === 'win32') {
|
|
414
|
+
const pwsh = findWindowsExecutable('pwsh.exe');
|
|
415
|
+
const powershell = pwsh === undefined ? findWindowsExecutable('powershell.exe') : undefined;
|
|
416
|
+
const commandPrompt = pwsh === undefined && powershell === undefined
|
|
417
|
+
? (findWindowsExecutable('cmd.exe') ??
|
|
418
|
+
process.env['ComSpec'] ??
|
|
419
|
+
'C:\\Windows\\System32\\cmd.exe')
|
|
420
|
+
: undefined;
|
|
421
|
+
return [
|
|
422
|
+
{
|
|
423
|
+
id: 'default',
|
|
424
|
+
label: pwsh === undefined
|
|
425
|
+
? powershell === undefined
|
|
426
|
+
? 'Windows Command Prompt'
|
|
427
|
+
: 'Windows PowerShell'
|
|
428
|
+
: 'PowerShell 7',
|
|
429
|
+
shell: pwsh ?? powershell ?? commandPrompt,
|
|
430
|
+
args: [],
|
|
431
|
+
isDefault: true
|
|
432
|
+
}
|
|
433
|
+
];
|
|
434
|
+
}
|
|
435
|
+
return [
|
|
436
|
+
{
|
|
437
|
+
id: 'default',
|
|
438
|
+
label: 'User Shell',
|
|
439
|
+
shell: process.env['SHELL']?.trim() || '/bin/bash',
|
|
440
|
+
args: ['-l', '-i'],
|
|
441
|
+
isDefault: true
|
|
442
|
+
}
|
|
443
|
+
];
|
|
444
|
+
}
|
|
445
|
+
function resolveWindowsExecutable(command) {
|
|
446
|
+
const pathValue = process.env['Path']?.trim() || process.env['PATH'];
|
|
447
|
+
for (const directory of pathValue?.split(';') ?? []) {
|
|
448
|
+
const candidate = join(directory.trim(), command);
|
|
449
|
+
if (directory.trim() !== '' && existsSync(candidate))
|
|
450
|
+
return candidate;
|
|
451
|
+
}
|
|
452
|
+
if (command === 'pwsh.exe') {
|
|
453
|
+
const programFiles = process.env['ProgramFiles'];
|
|
454
|
+
const candidate = programFiles === undefined ? undefined : join(programFiles, 'PowerShell', '7', command);
|
|
455
|
+
return candidate !== undefined && existsSync(candidate) ? candidate : undefined;
|
|
456
|
+
}
|
|
457
|
+
if (command === 'powershell.exe') {
|
|
458
|
+
const systemRoot = process.env['SystemRoot'] ?? process.env['windir'];
|
|
459
|
+
const candidate = systemRoot === undefined
|
|
460
|
+
? undefined
|
|
461
|
+
: join(systemRoot, 'System32', 'WindowsPowerShell', 'v1.0', command);
|
|
462
|
+
return candidate !== undefined && existsSync(candidate) ? candidate : undefined;
|
|
463
|
+
}
|
|
464
|
+
return process.env['ComSpec'] ?? process.env['COMSPEC'];
|
|
465
|
+
}
|
|
466
|
+
function terminalDimension(value, fallback) {
|
|
467
|
+
if (value === undefined)
|
|
468
|
+
return fallback;
|
|
469
|
+
if (typeof value !== 'number' || !Number.isInteger(value) || value < 1 || value > 1000)
|
|
470
|
+
throw new Error('TERMINAL_DIMENSIONS_INVALID');
|
|
471
|
+
return value;
|
|
472
|
+
}
|
|
473
|
+
function terminalSequence(value) {
|
|
474
|
+
if (value === undefined)
|
|
475
|
+
return 0;
|
|
476
|
+
if (typeof value !== 'number' || !Number.isInteger(value) || value < 0)
|
|
477
|
+
throw new Error('TERMINAL_REPLAY_INVALID');
|
|
478
|
+
return value;
|
|
479
|
+
}
|
|
480
|
+
function splitFrameData(value) {
|
|
481
|
+
if (value.length <= MAX_FRAME_CHARACTERS)
|
|
482
|
+
return [value];
|
|
483
|
+
const chunks = [];
|
|
484
|
+
for (let start = 0; start < value.length;) {
|
|
485
|
+
let end = Math.min(value.length, start + MAX_FRAME_CHARACTERS);
|
|
486
|
+
if (end < value.length &&
|
|
487
|
+
value.charCodeAt(end - 1) >= 0xd800 &&
|
|
488
|
+
value.charCodeAt(end - 1) <= 0xdbff &&
|
|
489
|
+
value.charCodeAt(end) >= 0xdc00 &&
|
|
490
|
+
value.charCodeAt(end) <= 0xdfff)
|
|
491
|
+
end -= 1;
|
|
492
|
+
chunks.push(value.slice(start, end));
|
|
493
|
+
start = end;
|
|
494
|
+
}
|
|
495
|
+
return chunks;
|
|
496
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Only the authenticated Node-local credential broker is addressable by helpers. */
|
|
2
|
+
export async function gitCredentialRequest(path, input) {
|
|
3
|
+
const endpoint = new URL(process.env.MAR_GIT_ENDPOINT ?? '');
|
|
4
|
+
if (endpoint.protocol !== 'http:' ||
|
|
5
|
+
endpoint.hostname !== '127.0.0.1' ||
|
|
6
|
+
!/^[a-f0-9]{64}$/u.test(process.env.MAR_GIT_TOKEN ?? ''))
|
|
7
|
+
throw new Error('GIT_CREDENTIAL_CONTEXT_EXPIRED');
|
|
8
|
+
const response = await fetch(new URL(path, endpoint), {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: {
|
|
11
|
+
authorization: `Bearer ${process.env.MAR_GIT_TOKEN}`,
|
|
12
|
+
'content-type': 'application/json'
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify(input),
|
|
15
|
+
signal: AbortSignal.timeout(10_000),
|
|
16
|
+
redirect: 'error'
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok)
|
|
19
|
+
throw new Error('GIT_CREDENTIAL_CONTEXT_EXPIRED');
|
|
20
|
+
return (await response.json());
|
|
21
|
+
}
|
|
22
|
+
export async function originalGitEnvironment() {
|
|
23
|
+
const result = await gitCredentialRequest('/restore', {});
|
|
24
|
+
const environment = { ...process.env };
|
|
25
|
+
for (const [name, value] of Object.entries(result.restore)) {
|
|
26
|
+
if (value === null)
|
|
27
|
+
delete environment[name];
|
|
28
|
+
else
|
|
29
|
+
environment[name] = value;
|
|
30
|
+
}
|
|
31
|
+
return environment;
|
|
32
|
+
}
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/** Removes relay-only authorization context before strict business input validation. */
|
|
2
|
+
export function nodeOperationData(raw) {
|
|
3
|
+
if (raw === null || typeof raw !== 'object' || Array.isArray(raw))
|
|
4
|
+
return raw;
|
|
5
|
+
const data = { ...raw };
|
|
6
|
+
delete data['__requestUserId'];
|
|
7
|
+
delete data['__workspaceWatchSessionHash'];
|
|
8
|
+
return data;
|
|
9
|
+
}
|