@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
|
@@ -1,2 +1,150 @@
|
|
|
1
|
-
|
|
2
|
-
const _0x33ff72=_0x1f54;function _0x1f54(_0x4ec6f9,_0x4946ea){_0x4ec6f9=_0x4ec6f9-(-0x5*-0x509+0x32f+-0x1a77);const _0x32d818=_0x41d0();let _0x270899=_0x32d818[_0x4ec6f9];if(_0x1f54['JVlZNi']===undefined){var _0x135f05=function(_0x1dd6d5){const _0x36a922='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1eec45='',_0x1c2500='';for(let _0x380068=-0x1ab1+-0x4c0*-0x2+0x1131,_0x33ad79,_0x1835cf,_0x35c803=0x1fe6*-0x1+-0x14b9+0x349f;_0x1835cf=_0x1dd6d5['charAt'](_0x35c803++);~_0x1835cf&&(_0x33ad79=_0x380068%(-0xf*0x281+0x14f8+-0x3*-0x589)?_0x33ad79*(-0x63c+-0x1*-0x117+0x565)+_0x1835cf:_0x1835cf,_0x380068++%(-0x6b9+0xce9*0x3+-0x1ffe))?_0x1eec45+=String['fromCharCode'](-0x437+0x1324+-0x2*0x6f7&_0x33ad79>>(-(0x576+-0x1*-0x10eb+-0x165f)*_0x380068&0x1cf9*-0x1+-0x18e9+0x35e8)):0x3*0x6e3+-0x3*0xf9+-0x6*0x2f5){_0x1835cf=_0x36a922['indexOf'](_0x1835cf);}for(let _0x1a18af=0x9eb+-0x1*0x1322+0x937*0x1,_0x4eef18=_0x1eec45['length'];_0x1a18af<_0x4eef18;_0x1a18af++){_0x1c2500+='%'+('00'+_0x1eec45['charCodeAt'](_0x1a18af)['toString'](0x18e5+0x3*0xcec+-0x3f99))['slice'](-(-0x5*-0x14e+0x1d1b*0x1+-0x239f));}return decodeURIComponent(_0x1c2500);};_0x1f54['eEmvRr']=_0x135f05,_0x1f54['ascbJv']={},_0x1f54['JVlZNi']=!![];}const _0x5d818d=_0x32d818[0x35d*0x2+-0x1*-0x1e4d+-0x2507];_0x1f54['mMzslQ']!==_0x5d818d&&(_0x1f54['ascbJv']={},_0x1f54['mMzslQ']=_0x5d818d);const _0x5009aa=_0x1f54['ascbJv'][_0x4ec6f9];return _0x5009aa===undefined?(_0x270899=_0x1f54['eEmvRr'](_0x270899),_0x1f54['ascbJv'][_0x4ec6f9]=_0x270899):_0x270899=_0x5009aa,_0x270899;}(function(_0x53f636,_0x2608e1){const _0x4c8c13=_0x1f54,_0x11c172=_0x53f636();while(!![]){try{const _0x49e10b=parseInt(_0x4c8c13(0x1fe))/(0xa13*0x1+-0x107f+-0x149*-0x5)*(-parseInt(_0x4c8c13(0x1f0))/(-0xf47+0x2271+0x994*-0x2))+-parseInt(_0x4c8c13(0x20f))/(-0xef*0x1+-0x1cbc+0x1dae*0x1)+-parseInt(_0x4c8c13(0x1f2))/(-0xc17*-0x3+0x1*-0x17db+-0x2e*0x45)+-parseInt(_0x4c8c13(0x203))/(0x44d*-0x1+-0x11*0x1e6+0x2498)*(parseInt(_0x4c8c13(0x1ec))/(0xd4*-0x1a+0xe2f+-0x6f*-0x11))+-parseInt(_0x4c8c13(0x1e5))/(-0x2ad*-0x1+0x2189*-0x1+-0x1*-0x1ee3)*(-parseInt(_0x4c8c13(0x205))/(0x1f40+0x101*-0x11+-0xe27))+-parseInt(_0x4c8c13(0x1ef))/(0x1d*-0x14e+-0x829+0x2e08)*(-parseInt(_0x4c8c13(0x1fd))/(-0x2*0x4ae+-0x1d*0x1+0x983*0x1))+parseInt(_0x4c8c13(0x1e8))/(0x91d*-0x1+-0x29c*-0x2+-0x12*-0x38)*(parseInt(_0x4c8c13(0x20c))/(0x1*-0x17fa+0x22cf+-0xac9));if(_0x49e10b===_0x2608e1)break;else _0x11c172['push'](_0x11c172['shift']());}catch(_0x24d8b7){_0x11c172['push'](_0x11c172['shift']());}}}(_0x41d0,0xda6fc+-0xde052+-0x16d*-0x5a3));import{tmpdir}from'node:os';import{isAbsolute,win32}from'node:path';import{listWorkspaceFiles,mutateWorkspaceFile,normalizeFilePreviewPath,readAllowedFileContentRange,readWorkspaceFileContentRange,readAllowedTextFile,readWorkspaceTextFile,writeWorkspaceTextFile,WorkspaceFileIndex}from'../workspace.js';const INDEX_CACHE_LIMIT=-0x22df+-0x32+0x2319*0x1;export class WorkspaceFileService{[_0x33ff72(0x210)];[_0x33ff72(0x20a)];[_0x33ff72(0x204)];[_0x33ff72(0x1ea)]=new Map();constructor(_0x2922de,_0x177eb0,_0x3c301e){const _0x405064=_0x33ff72;this[_0x405064(0x210)]=_0x2922de,this[_0x405064(0x20a)]=_0x177eb0,this[_0x405064(0x204)]=_0x3c301e;}async[_0x33ff72(0x209)](_0x4b3788,_0x34d592){const _0x3591d9=_0x33ff72;if(_0x34d592[_0x3591d9(0x1eb)]!==undefined&&typeof _0x34d592[_0x3591d9(0x1eb)]!==_0x3591d9(0x1fc)||_0x34d592[_0x3591d9(0x1fa)]!==undefined&&typeof _0x34d592[_0x3591d9(0x1fa)]!==_0x3591d9(0x1fc)||_0x34d592[_0x3591d9(0x223)]!==undefined&&(!Number[_0x3591d9(0x21d)](_0x34d592[_0x3591d9(0x223)])||_0x34d592[_0x3591d9(0x223)]<-0x1a09+0x1*-0x10fb+0x2b05||_0x34d592[_0x3591d9(0x223)]>-0x198f+0x1775+-0x9*-0x52))throw new Error(_0x3591d9(0x1f6));return listWorkspaceFiles(_0x4b3788[_0x3591d9(0x1eb)],typeof _0x34d592[_0x3591d9(0x1eb)]===_0x3591d9(0x1fc)?_0x34d592[_0x3591d9(0x1eb)]:'.',typeof _0x34d592[_0x3591d9(0x1fa)]===_0x3591d9(0x1fc)?_0x34d592[_0x3591d9(0x1fa)]:undefined,typeof _0x34d592[_0x3591d9(0x223)]===_0x3591d9(0x216)?_0x34d592[_0x3591d9(0x223)]:undefined);}async[_0x33ff72(0x1ed)](_0x2624e0,_0x812e52,_0x1a0287=_0x2624e0[_0x33ff72(0x1eb)]){const _0x5bc91b=_0x33ff72;if(typeof _0x812e52[_0x5bc91b(0x1eb)]!==_0x5bc91b(0x1fc)||_0x812e52[_0x5bc91b(0x20d)]!==undefined&&(!Number[_0x5bc91b(0x21d)](_0x812e52[_0x5bc91b(0x20d)])||_0x812e52[_0x5bc91b(0x20d)]<0x62+-0x184+-0x122*-0x1)||_0x812e52[_0x5bc91b(0x223)]!==undefined&&(!Number[_0x5bc91b(0x21d)](_0x812e52[_0x5bc91b(0x223)])||_0x812e52[_0x5bc91b(0x223)]<0xa7c+0x20ff+-0x73f*0x6||_0x812e52[_0x5bc91b(0x223)]>(-0x1614+0xd*0x8b+0x1105)*(0x170c+-0x858+-0xab4)))throw new Error(_0x5bc91b(0x1f8));const _0xedf4e=typeof _0x812e52[_0x5bc91b(0x20d)]===_0x5bc91b(0x216)?_0x812e52[_0x5bc91b(0x20d)]:0x13ff+0x2406+-0x1*0x3805,_0x5698d2=typeof _0x812e52[_0x5bc91b(0x223)]===_0x5bc91b(0x216)?_0x812e52[_0x5bc91b(0x223)]:(-0x2*-0xb9c+-0x13*-0x77+-0x31*0x9d)*(-0x474+0x1301*0x1+0xa8d*-0x1),_0x241a13=normalizeFilePreviewPath(_0x812e52[_0x5bc91b(0x1eb)]);if(_0x1a0287!==_0x2624e0[_0x5bc91b(0x1eb)]&&isFilePreviewAbsolutePath(_0x241a13))throw new Error(_0x5bc91b(0x1f3));return isFilePreviewAbsolutePath(_0x241a13)?readAllowedTextFile(_0x241a13,this[_0x5bc91b(0x208)](),_0xedf4e,_0x5698d2):readWorkspaceTextFile(_0x1a0287,_0x241a13,_0xedf4e,_0x5698d2);}async[_0x33ff72(0x217)](_0x138200,_0x4bbdd7,_0xe4e39=_0x138200[_0x33ff72(0x1eb)]){const _0x2e9113=_0x33ff72;if(typeof _0x4bbdd7[_0x2e9113(0x1eb)]!==_0x2e9113(0x1fc)||_0x4bbdd7[_0x2e9113(0x20d)]!==undefined&&(!Number[_0x2e9113(0x21d)](_0x4bbdd7[_0x2e9113(0x20d)])||_0x4bbdd7[_0x2e9113(0x20d)]<-0xf60*0x1+0x27a*0x3+-0x9*-0xe2)||_0x4bbdd7[_0x2e9113(0x223)]!==undefined&&(!Number[_0x2e9113(0x21d)](_0x4bbdd7[_0x2e9113(0x223)])||_0x4bbdd7[_0x2e9113(0x223)]<0xb94+0x1492*0x1+0x2025*-0x1||_0x4bbdd7[_0x2e9113(0x223)]>(0xf4e+0x3b*-0x2+-0x3*0x448)*(-0x1*0x1733+-0x1f*-0x136+-0xa57)))throw new Error(_0x2e9113(0x1f8));const _0x5424fc=normalizeFilePreviewPath(_0x4bbdd7[_0x2e9113(0x1eb)]);if(_0xe4e39!==_0x138200[_0x2e9113(0x1eb)]&&isFilePreviewAbsolutePath(_0x5424fc))throw new Error(_0x2e9113(0x1f3));const _0x2e2424=typeof _0x4bbdd7[_0x2e9113(0x20d)]===_0x2e9113(0x216)?_0x4bbdd7[_0x2e9113(0x20d)]:0x6d0+-0x1b*-0x1f+-0x1d*0x59,_0x4520e6=typeof _0x4bbdd7[_0x2e9113(0x223)]===_0x2e9113(0x216)?_0x4bbdd7[_0x2e9113(0x223)]:(-0x19db+0x1220+0x9bb)*(0x577+0x1897+0x1d*-0xe6);return isFilePreviewAbsolutePath(_0x5424fc)?readAllowedFileContentRange(_0x5424fc,this[_0x2e9113(0x208)](),_0x2e2424,_0x4520e6):readWorkspaceFileContentRange(_0xe4e39,_0x5424fc,_0x2e2424,_0x4520e6);}async[_0x33ff72(0x215)](_0x4c3174,_0x34a9e6){const _0x287f63=_0x33ff72;if(typeof _0x34a9e6[_0x287f63(0x1eb)]!==_0x287f63(0x1fc)||typeof _0x34a9e6[_0x287f63(0x1f5)]!==_0x287f63(0x1fc)||typeof _0x34a9e6[_0x287f63(0x219)]!==_0x287f63(0x1fc))throw new Error(_0x287f63(0x222));const _0x14881e=_0x34a9e6[_0x287f63(0x1eb)],_0x457fdb=_0x34a9e6[_0x287f63(0x1f5)],_0x3ebee4=_0x34a9e6[_0x287f63(0x219)];return this[_0x287f63(0x21a)](_0x4c3174['id'],async()=>{const _0x521e75=_0x287f63,_0x19d6ae=await writeWorkspaceTextFile(_0x4c3174[_0x521e75(0x1eb)],_0x14881e,_0x457fdb,_0x3ebee4);return this[_0x521e75(0x211)](_0x4c3174['id']),this[_0x521e75(0x204)](_0x4c3174['id']),_0x19d6ae;});}async[_0x33ff72(0x1e6)](_0xf0f80,_0x5373d9){const _0x59f859=_0x33ff72;if(typeof _0x5373d9[_0x59f859(0x20b)]!==_0x59f859(0x1fc)||_0x5373d9[_0x59f859(0x1fa)]!==undefined&&typeof _0x5373d9[_0x59f859(0x1fa)]!==_0x59f859(0x1fc)||_0x5373d9[_0x59f859(0x1f1)]!==undefined&&typeof _0x5373d9[_0x59f859(0x1f1)]!==_0x59f859(0x218)||_0x5373d9[_0x59f859(0x223)]!==undefined&&(!Number[_0x59f859(0x21d)](_0x5373d9[_0x59f859(0x223)])||_0x5373d9[_0x59f859(0x223)]<0x119e+-0x63b+-0x2f*0x3e||_0x5373d9[_0x59f859(0x223)]>0x8c3*-0x2+0x1*-0x74b+0x1*0x1999))throw new Error(_0x59f859(0x214));return this[_0x59f859(0x20e)](_0xf0f80)[_0x59f859(0x1e6)](_0x5373d9[_0x59f859(0x20b)],typeof _0x5373d9[_0x59f859(0x1fa)]===_0x59f859(0x1fc)?_0x5373d9[_0x59f859(0x1fa)]:undefined,typeof _0x5373d9[_0x59f859(0x223)]===_0x59f859(0x216)?_0x5373d9[_0x59f859(0x223)]:undefined,_0x5373d9[_0x59f859(0x1f1)]===!![]);}async[_0x33ff72(0x207)](_0x1552a3,_0x57c732){const _0x1ab717=_0x33ff72,_0x1bf140=_0x57c732[_0x1ab717(0x202)];if(_0x1bf140!==_0x1ab717(0x1fb)&&_0x1bf140!==_0x1ab717(0x21e)&&_0x1bf140!==_0x1ab717(0x206)&&_0x1bf140!==_0x1ab717(0x213)||typeof _0x57c732[_0x1ab717(0x1eb)]!==_0x1ab717(0x1fc)||_0x1bf140===_0x1ab717(0x206)&&typeof _0x57c732[_0x1ab717(0x201)]!==_0x1ab717(0x1fc))throw new Error(_0x1ab717(0x21f));const _0x26dddb=_0x57c732[_0x1ab717(0x1eb)],_0x489958=typeof _0x57c732[_0x1ab717(0x201)]===_0x1ab717(0x1fc)?_0x57c732[_0x1ab717(0x201)]:undefined;return this[_0x1ab717(0x21a)](_0x1552a3['id'],async()=>{const _0x2a34c2=_0x1ab717,_0x121b32=await mutateWorkspaceFile(_0x1552a3[_0x2a34c2(0x1eb)],_0x1bf140===_0x2a34c2(0x206)?{'action':_0x1bf140,'path':_0x26dddb,'destination':_0x489958}:{'action':_0x1bf140,'path':_0x26dddb});return this[_0x2a34c2(0x211)](_0x1552a3['id']),this[_0x2a34c2(0x204)](_0x1552a3['id']),_0x121b32;});}async[_0x33ff72(0x21a)](_0x19751a,_0x3cd419){const _0x4c213c=_0x33ff72,_0x2d4a2c=this[_0x4c213c(0x1ea)][_0x4c213c(0x21c)](_0x19751a)??Promise[_0x4c213c(0x1ee)](),_0x14e12c=_0x2d4a2c[_0x4c213c(0x200)](_0x3cd419,_0x3cd419),_0x2ca780=_0x14e12c[_0x4c213c(0x200)](()=>undefined,()=>undefined);this[_0x4c213c(0x1ea)][_0x4c213c(0x212)](_0x19751a,_0x2ca780);try{return await _0x14e12c;}finally{if(this[_0x4c213c(0x1ea)][_0x4c213c(0x21c)](_0x19751a)===_0x2ca780)this[_0x4c213c(0x1ea)][_0x4c213c(0x1f9)](_0x19751a);}}[_0x33ff72(0x20e)](_0x4e8f92){const _0x2404b9=_0x33ff72;let _0x5b7841=this[_0x2404b9(0x210)][_0x2404b9(0x1f4)][_0x2404b9(0x21c)](_0x4e8f92['id']);if(_0x5b7841===undefined){if(this[_0x2404b9(0x210)][_0x2404b9(0x1f4)][_0x2404b9(0x221)]>=INDEX_CACHE_LIMIT){const _0x5940f2=this[_0x2404b9(0x210)][_0x2404b9(0x1f4)][_0x2404b9(0x1ff)]()[_0x2404b9(0x1e7)]()[_0x2404b9(0x1e9)];_0x5940f2!==undefined&&(_0x5940f2[0x2441+0x1109+-0x3549*0x1][_0x2404b9(0x211)](),this[_0x2404b9(0x210)][_0x2404b9(0x1f4)][_0x2404b9(0x1f9)](_0x5940f2[0xd*0x13+0x1cda*-0x1+-0x1be3*-0x1]));}_0x5b7841=new WorkspaceFileIndex(_0x4e8f92[_0x2404b9(0x1eb)]);}return this[_0x2404b9(0x210)][_0x2404b9(0x1f4)][_0x2404b9(0x1f9)](_0x4e8f92['id']),this[_0x2404b9(0x210)][_0x2404b9(0x1f4)][_0x2404b9(0x212)](_0x4e8f92['id'],_0x5b7841),_0x5b7841;}[_0x33ff72(0x211)](_0x429a80){const _0x2bdde7=_0x33ff72;if(_0x429a80!==undefined){this[_0x2bdde7(0x210)][_0x2bdde7(0x1f4)][_0x2bdde7(0x21c)](_0x429a80)?.[_0x2bdde7(0x211)](),this[_0x2bdde7(0x210)][_0x2bdde7(0x1f4)][_0x2bdde7(0x1f9)](_0x429a80);return;}for(const _0x81900b of this[_0x2bdde7(0x210)][_0x2bdde7(0x1f4)][_0x2bdde7(0x1f7)]())_0x81900b[_0x2bdde7(0x211)]();this[_0x2bdde7(0x210)][_0x2bdde7(0x1f4)][_0x2bdde7(0x220)]();}[_0x33ff72(0x208)](){const _0x47c98b=_0x33ff72;return[...new Set([...this[_0x47c98b(0x20a)](),tmpdir()])];}}function _0x41d0(){const _0x3e917a=['ywXSB3DLzfjVB3rZ','CxvLCNK','mJrUBvzLBuG','B2zMC2v0','Aw5KzxG','mtC1mZa0n3LXyvboqq','C3rHDgu','zgLZCg9Zzq','C2v0','revmrvrf','rKLmrv9trufsq0HFteLnsvrFrvHdruveruq','D3jPDgu','BNvTyMvY','CMvHzenVBNrLBNq','yM9VBgvHBG','zxHWzwn0zwrszxzPC2LVBG','C2vYAwfSAxPLtxv0yxrPB24','AxnbyNnVBhv0zq','z2v0','AxnjBNrLz2vY','q1jfqvrfx0rjuKvdve9swq','rKLmrv9nvvrbveLptL9jtLzbteLe','y2XLyxi','C2L6zq','rKLmrv9xuKLurv9jtLzbteLe','BgLTAxq','n3b4uMjIAW','C2vHCMnO','BMv4Da','mti2ntmXmtn5wurkCeO','DMfSDwu','Bxv0yxrPB25uywLSCW','Cgf0Aa','mZi2mdK0nNnhBKPqtG','CMvHza','CMvZB2X2zq','otKYmtG3DxLUB2n2','mZrjyxD5shu','Aw5JBhvKzurPCMvJDg9YAwvZ','mJy4mZKWohDfu3jHqq','rKLmrv9qqvrix0vtq0fqrq','zMLSzuLUzgv4zxm','y29UDgvUDa','reLsrunut1jzx0nvuLnpuL9jtLzbteLe','DMfSDwvZ','rKLmrv9squ5hrv9jtLzbteLe','zgvSzxrL','y3vYC29Y','q1jfqvrfx0zjteu','C3rYAw5N','mtbTt3jQBum','mta5odj3tKTmuM0','zw50CMLLCW','DgHLBG','zgvZDgLUyxrPB24','ywn0Aw9U','nwPmExzisW','B25jBNzHBgLKyxrLza','nJKZnZuYugrpDNbr','tu9wrq','Bxv0yxrL','ChjLDMLLD1jVB3rZ','BgLZDa'];_0x41d0=function(){return _0x3e917a;};return _0x41d0();}function isFilePreviewAbsolutePath(_0x4079e9){const _0x12606a=_0x33ff72;return isAbsolute(_0x4079e9)||win32[_0x12606a(0x21b)](_0x4079e9);}
|
|
1
|
+
import { tmpdir } from 'node:os';
|
|
2
|
+
import { isAbsolute, win32 } from 'node:path';
|
|
3
|
+
import { listWorkspaceFiles, mutateWorkspaceFile, normalizeFilePreviewPath, readAllowedFileContentRange, readWorkspaceFileContentRange, readAllowedTextFile, readWorkspaceTextFile, writeWorkspaceTextFile, WorkspaceFileIndex } from '../workspace.js';
|
|
4
|
+
const INDEX_CACHE_LIMIT = 8;
|
|
5
|
+
export class WorkspaceFileService {
|
|
6
|
+
state;
|
|
7
|
+
allowedRoots;
|
|
8
|
+
onInvalidated;
|
|
9
|
+
mutationTails = new Map();
|
|
10
|
+
constructor(state, allowedRoots, onInvalidated) {
|
|
11
|
+
this.state = state;
|
|
12
|
+
this.allowedRoots = allowedRoots;
|
|
13
|
+
this.onInvalidated = onInvalidated;
|
|
14
|
+
}
|
|
15
|
+
async list(workspace, input) {
|
|
16
|
+
if ((input.path !== undefined && typeof input.path !== 'string') ||
|
|
17
|
+
(input.cursor !== undefined && typeof input.cursor !== 'string') ||
|
|
18
|
+
(input.limit !== undefined &&
|
|
19
|
+
(!Number.isInteger(input.limit) ||
|
|
20
|
+
input.limit < 1 ||
|
|
21
|
+
input.limit > 200)))
|
|
22
|
+
throw new Error('DIRECTORY_CURSOR_INVALID');
|
|
23
|
+
return listWorkspaceFiles(workspace.path, typeof input.path === 'string' ? input.path : '.', typeof input.cursor === 'string' ? input.cursor : undefined, typeof input.limit === 'number' ? input.limit : undefined);
|
|
24
|
+
}
|
|
25
|
+
async read(workspace, input, workspacePath = workspace.path) {
|
|
26
|
+
if (typeof input.path !== 'string' ||
|
|
27
|
+
(input.offset !== undefined &&
|
|
28
|
+
(!Number.isInteger(input.offset) || input.offset < 0)) ||
|
|
29
|
+
(input.limit !== undefined &&
|
|
30
|
+
(!Number.isInteger(input.limit) ||
|
|
31
|
+
input.limit < 1 ||
|
|
32
|
+
input.limit > 512 * 1024)))
|
|
33
|
+
throw new Error('FILE_RANGE_INVALID');
|
|
34
|
+
const offset = typeof input.offset === 'number' ? input.offset : 0;
|
|
35
|
+
const limit = typeof input.limit === 'number' ? input.limit : 512 * 1024;
|
|
36
|
+
const path = normalizeFilePreviewPath(input.path);
|
|
37
|
+
if (workspacePath !== workspace.path && isFilePreviewAbsolutePath(path))
|
|
38
|
+
throw new Error('FILE_PATH_ESCAPE');
|
|
39
|
+
return isFilePreviewAbsolutePath(path)
|
|
40
|
+
? readAllowedTextFile(path, this.previewRoots(), offset, limit)
|
|
41
|
+
: readWorkspaceTextFile(workspacePath, path, offset, limit);
|
|
42
|
+
}
|
|
43
|
+
async readContent(workspace, input, workspacePath = workspace.path) {
|
|
44
|
+
if (typeof input.path !== 'string' ||
|
|
45
|
+
(input.offset !== undefined &&
|
|
46
|
+
(!Number.isInteger(input.offset) || input.offset < 0)) ||
|
|
47
|
+
(input.limit !== undefined &&
|
|
48
|
+
(!Number.isInteger(input.limit) ||
|
|
49
|
+
input.limit < 1 ||
|
|
50
|
+
input.limit > 512 * 1024)))
|
|
51
|
+
throw new Error('FILE_RANGE_INVALID');
|
|
52
|
+
const path = normalizeFilePreviewPath(input.path);
|
|
53
|
+
if (workspacePath !== workspace.path && isFilePreviewAbsolutePath(path))
|
|
54
|
+
throw new Error('FILE_PATH_ESCAPE');
|
|
55
|
+
const offset = typeof input.offset === 'number' ? input.offset : 0;
|
|
56
|
+
const limit = typeof input.limit === 'number' ? input.limit : 512 * 1024;
|
|
57
|
+
return isFilePreviewAbsolutePath(path)
|
|
58
|
+
? readAllowedFileContentRange(path, this.previewRoots(), offset, limit)
|
|
59
|
+
: readWorkspaceFileContentRange(workspacePath, path, offset, limit);
|
|
60
|
+
}
|
|
61
|
+
async write(workspace, input) {
|
|
62
|
+
if (typeof input.path !== 'string' ||
|
|
63
|
+
typeof input.content !== 'string' ||
|
|
64
|
+
typeof input.expectedRevision !== 'string')
|
|
65
|
+
throw new Error('FILE_WRITE_INVALID');
|
|
66
|
+
const path = input.path;
|
|
67
|
+
const content = input.content;
|
|
68
|
+
const expectedRevision = input.expectedRevision;
|
|
69
|
+
return this.serializeMutation(workspace.id, async () => {
|
|
70
|
+
const result = await writeWorkspaceTextFile(workspace.path, path, content, expectedRevision);
|
|
71
|
+
this.dispose(workspace.id);
|
|
72
|
+
this.onInvalidated(workspace.id);
|
|
73
|
+
return result;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async search(workspace, input) {
|
|
77
|
+
if (typeof input.query !== 'string' ||
|
|
78
|
+
(input.cursor !== undefined && typeof input.cursor !== 'string') ||
|
|
79
|
+
(input.includeDirectories !== undefined && typeof input.includeDirectories !== 'boolean') ||
|
|
80
|
+
(input.limit !== undefined &&
|
|
81
|
+
(!Number.isInteger(input.limit) ||
|
|
82
|
+
input.limit < 1 ||
|
|
83
|
+
input.limit > 200)))
|
|
84
|
+
throw new Error('FILE_SEARCH_LIMIT_EXCEEDED');
|
|
85
|
+
return this.index(workspace).search(input.query, typeof input.cursor === 'string' ? input.cursor : undefined, typeof input.limit === 'number' ? input.limit : undefined, input.includeDirectories === true);
|
|
86
|
+
}
|
|
87
|
+
async mutate(workspace, input) {
|
|
88
|
+
const action = input.action;
|
|
89
|
+
if ((action !== 'CREATE_FILE' &&
|
|
90
|
+
action !== 'CREATE_DIRECTORY' &&
|
|
91
|
+
action !== 'MOVE' &&
|
|
92
|
+
action !== 'DELETE') ||
|
|
93
|
+
typeof input.path !== 'string' ||
|
|
94
|
+
(action === 'MOVE' && typeof input.destination !== 'string'))
|
|
95
|
+
throw new Error('FILE_MUTATION_INVALID');
|
|
96
|
+
const path = input.path;
|
|
97
|
+
const destination = typeof input.destination === 'string' ? input.destination : undefined;
|
|
98
|
+
return this.serializeMutation(workspace.id, async () => {
|
|
99
|
+
const result = await mutateWorkspaceFile(workspace.path, action === 'MOVE' ? { action, path, destination: destination } : { action, path });
|
|
100
|
+
this.dispose(workspace.id);
|
|
101
|
+
this.onInvalidated(workspace.id);
|
|
102
|
+
return result;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async serializeMutation(workspaceId, operation) {
|
|
106
|
+
const previous = this.mutationTails.get(workspaceId) ?? Promise.resolve();
|
|
107
|
+
const result = previous.then(operation, operation);
|
|
108
|
+
const tail = result.then(() => undefined, () => undefined);
|
|
109
|
+
this.mutationTails.set(workspaceId, tail);
|
|
110
|
+
try {
|
|
111
|
+
return await result;
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
if (this.mutationTails.get(workspaceId) === tail)
|
|
115
|
+
this.mutationTails.delete(workspaceId);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
index(workspace) {
|
|
119
|
+
let index = this.state.fileIndexes.get(workspace.id);
|
|
120
|
+
if (index === undefined) {
|
|
121
|
+
if (this.state.fileIndexes.size >= INDEX_CACHE_LIMIT) {
|
|
122
|
+
const oldest = this.state.fileIndexes.entries().next().value;
|
|
123
|
+
if (oldest !== undefined) {
|
|
124
|
+
oldest[1].dispose();
|
|
125
|
+
this.state.fileIndexes.delete(oldest[0]);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
index = new WorkspaceFileIndex(workspace.path);
|
|
129
|
+
}
|
|
130
|
+
this.state.fileIndexes.delete(workspace.id);
|
|
131
|
+
this.state.fileIndexes.set(workspace.id, index);
|
|
132
|
+
return index;
|
|
133
|
+
}
|
|
134
|
+
dispose(workspaceId) {
|
|
135
|
+
if (workspaceId !== undefined) {
|
|
136
|
+
this.state.fileIndexes.get(workspaceId)?.dispose();
|
|
137
|
+
this.state.fileIndexes.delete(workspaceId);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
for (const index of this.state.fileIndexes.values())
|
|
141
|
+
index.dispose();
|
|
142
|
+
this.state.fileIndexes.clear();
|
|
143
|
+
}
|
|
144
|
+
previewRoots() {
|
|
145
|
+
return [...new Set([...this.allowedRoots(), tmpdir()])];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function isFilePreviewAbsolutePath(path) {
|
|
149
|
+
return isAbsolute(path) || win32.isAbsolute(path);
|
|
150
|
+
}
|
|
@@ -1,2 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { lstat, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
const MAR_TEMP_DIRECTORY = '/.mar/';
|
|
7
|
+
const BLOCK_BEGIN = '# BEGIN MyAgentRoam';
|
|
8
|
+
const BLOCK_END = '# END MyAgentRoam';
|
|
9
|
+
const LEGACY_BLOCK_BEGIN = '# BEGIN MyAgentRoam Skills';
|
|
10
|
+
const LEGACY_BLOCK_END = '# END MyAgentRoam Skills';
|
|
11
|
+
export async function ensureWorkspaceGitExclude(workspace) {
|
|
12
|
+
await mutateGitExclude(workspace, (entries) => entries.add(MAR_TEMP_DIRECTORY));
|
|
13
|
+
}
|
|
14
|
+
export async function updateWorkspaceSkillGitExclude(workspace, name, add) {
|
|
15
|
+
await mutateGitExclude(workspace, (entries) => {
|
|
16
|
+
entries.add(MAR_TEMP_DIRECTORY);
|
|
17
|
+
for (const root of ['.agents', '.claude']) {
|
|
18
|
+
const line = `/${root}/skills/${name}/`;
|
|
19
|
+
if (add)
|
|
20
|
+
entries.add(line);
|
|
21
|
+
else
|
|
22
|
+
entries.delete(line);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export async function rewriteWorkspaceGitExclude(workspace, names) {
|
|
27
|
+
await mutateGitExclude(workspace, (entries) => {
|
|
28
|
+
entries.clear();
|
|
29
|
+
entries.add(MAR_TEMP_DIRECTORY);
|
|
30
|
+
for (const name of names)
|
|
31
|
+
for (const root of ['.agents', '.claude'])
|
|
32
|
+
entries.add(`/${root}/skills/${name}/`);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export async function hasBrokenWorkspaceSkillGitExclude(workspace, names) {
|
|
36
|
+
if (!(await exists(path.join(workspace, '.git'))))
|
|
37
|
+
return false;
|
|
38
|
+
try {
|
|
39
|
+
const exclude = await resolveGitExclude(workspace);
|
|
40
|
+
const content = await readFile(exclude, 'utf8');
|
|
41
|
+
return names
|
|
42
|
+
.flatMap((name) => [`/.agents/skills/${name}/`, `/.claude/skills/${name}/`])
|
|
43
|
+
.some((entry) => !content.includes(entry));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function mutateGitExclude(workspace, mutate) {
|
|
50
|
+
if (!(await exists(path.join(workspace, '.git'))))
|
|
51
|
+
return;
|
|
52
|
+
const exclude = await resolveGitExclude(workspace);
|
|
53
|
+
await mkdir(path.dirname(exclude), { recursive: true });
|
|
54
|
+
let content = '';
|
|
55
|
+
try {
|
|
56
|
+
const excludeStat = await lstat(exclude);
|
|
57
|
+
if (!excludeStat.isFile() || excludeStat.isSymbolicLink())
|
|
58
|
+
throw new Error('WORKSPACE_SKILL_GIT_EXCLUDE_FAILED');
|
|
59
|
+
content = await readFile(exclude, 'utf8');
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (!isMissing(error))
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
const pattern = managedBlockPattern();
|
|
66
|
+
const existing = [...content.matchAll(pattern)].map((match) => match[0]).join('\n');
|
|
67
|
+
const entries = new Set(existing.split(/\r?\n/u).filter((line) => line.startsWith('/.')));
|
|
68
|
+
mutate(entries);
|
|
69
|
+
const block = `${BLOCK_BEGIN}\n${[...entries].sort().join('\n')}\n${BLOCK_END}\n`;
|
|
70
|
+
const next = content.replace(pattern, '').replace(/\s*$/u, '\n') + block;
|
|
71
|
+
const staging = path.join(path.dirname(exclude), `.mar-git-exclude-${randomUUID()}.tmp`);
|
|
72
|
+
try {
|
|
73
|
+
await writeFile(staging, next, { encoding: 'utf8', flag: 'wx' });
|
|
74
|
+
await rename(staging, exclude);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
await rm(staging, { force: true });
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function resolveGitExclude(workspace) {
|
|
82
|
+
try {
|
|
83
|
+
const result = await promisify(execFile)('git', ['-C', workspace, 'rev-parse', '--git-path', 'info/exclude', '--git-common-dir'], { timeout: 5_000, windowsHide: true });
|
|
84
|
+
const [excludeOutput, commonOutput] = result.stdout.trim().split(/\r?\n/u);
|
|
85
|
+
if (!excludeOutput || !commonOutput)
|
|
86
|
+
throw new Error();
|
|
87
|
+
const exclude = path.resolve(workspace, excludeOutput);
|
|
88
|
+
const common = path.resolve(workspace, commonOutput);
|
|
89
|
+
const relative = path.relative(common, exclude);
|
|
90
|
+
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
91
|
+
throw new Error();
|
|
92
|
+
return exclude;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
throw new Error('WORKSPACE_SKILL_GIT_EXCLUDE_FAILED');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function exists(value) {
|
|
99
|
+
try {
|
|
100
|
+
await lstat(value);
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (isMissing(error))
|
|
105
|
+
return false;
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function isMissing(error) {
|
|
110
|
+
return (error instanceof Error && 'code' in error && error.code === 'ENOENT');
|
|
111
|
+
}
|
|
112
|
+
function escapeRegExp(value) {
|
|
113
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
114
|
+
}
|
|
115
|
+
function managedBlockPattern() {
|
|
116
|
+
const current = `${escapeRegExp(BLOCK_BEGIN)}\\r?\\n[\\s\\S]*?${escapeRegExp(BLOCK_END)}(?:\\r?\\n)?`;
|
|
117
|
+
const legacy = `${escapeRegExp(LEGACY_BLOCK_BEGIN)}\\r?\\n[\\s\\S]*?${escapeRegExp(LEGACY_BLOCK_END)}(?:\\r?\\n)?`;
|
|
118
|
+
return new RegExp(`(?:${current}|${legacy})`, 'gu');
|
|
119
|
+
}
|
|
@@ -1,2 +1,176 @@
|
|
|
1
|
-
|
|
2
|
-
function _0x45ee(){const _0xaf3f8f=['CMvVCMrLCG','mJbwq1jQvgi','uvvfvuvFsu5wquXjra','revmrvrfx1fvrvvf','uKvpuKrfuL9rvuvvrq','rurjvf9rvuvvrq','zxHLy3v0zq','AxnbCNjHEq','BwLZC2LVBJO','y29UDgvUDa','CMvVCMrLCLnLC3nPB25rDwv1zq','C3rHCNrZv2L0Aa','z2v0','yxvKAxrszwnLAxb0','mJuZmZeZA1ber0nW','zgvSzxrLuxvLDwvjDgvT','CgvUzgLUzW','otm2CMfLq2z3','vw50AxrSzwqGC2vZC2LVBG','mJi3otLRCwXUtKu','AxnjBNrLz2vY','Cgf1C2vpCLjLC3vTzq','B3b0Aw9UCW','uKvtvu1fx1fvrvvf','mZK4nZGWmhDIzfHktG','DxbKyxrLuhjLCgfYzwrjBNb1Da','zxHWzwn0zwrwzxjZAw9U','zgvSzxrL','Cgf1C2vK','x19Yzxf1zxn0vxnLCKLK','y29VCMrPBMf0B3i','v09ss1nqqunfx05pvf9gt1vora','ChjLCgfYzuLUChv0','D29YA3nWywnLswq','uefvu0vFuvvfvuu','CMvZDw1Lqwz0zxjdB21Tyw5KuNvU','mJyWnJKXovLktMveAW','z2v0qwDLBNrtzxnZAw9U','y3vZDg9TvgL0Bgu','yxr0ywnOBwvUDfbHDgHZ','u0vtu0LptL9ot1rFrK9vtKq','DMvYC2LVBG','CMvZDw1L','ChjLC2vUDa','CMvXDwLYzvnLC3nPB24','mJa4mdm1mgfJAvPYsa','z2v0uxvLDwvjDgvT','CNvUDgLTzq','C3rYAw5N','DxbKyxrL','C25HChnOB3q','CxvLDwvjDgvTswrZ','mti0mZeWnJDYvfHUA2i','AxrLBuLKCW','zMXHDe1HCa','CNvUBMvYvgL0Bgu','zw1PDa','Cgf1C2u','DhjPBq','y2XPzw50twvZC2fNzuLK','CMvXDwLYzuL0zw0','mLfAAwL4zW','odeWntCWAuvmqKvx','mtbgtu1JrwW','BgvUz3rO','C2vZC2LVBLf1zxvL','C29Tzq','rvHfq1vurv9rvuvvrq','uvvfvuvFsvrftv9jtLzbteLe','C2vZC2LVBKLK','Cgf1C2vtzxnZAw9UuxvLDwu','DxbKyxrLuxvLDwvjDgvT','zxHLy3v0zvf1zxvLsxrLBq','CNvUBMvY','B3bLCMf0Aw9UCW','CxvLDwvjDgvTswq','y29SBgfIB3jHDgLVBK1Vzgu','y3jLyxrLzef0'];_0x45ee=function(){return _0xaf3f8f;};return _0x45ee();}function _0x5546(_0xfa5c0d,_0x2bf5e4){_0xfa5c0d=_0xfa5c0d-(0x361*0x5+0x2402+-0x345c);const _0xb412f7=_0x45ee();let _0x5c89d1=_0xb412f7[_0xfa5c0d];if(_0x5546['WZLtit']===undefined){var _0x41b762=function(_0x35911a){const _0x130ec8='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5640f2='',_0x34f634='';for(let _0x4fb6b2=0x1267+0x11*0x16f+-0x2*0x1563,_0x115e83,_0x5337bd,_0x28f1da=-0x2*-0x805+0x2424+-0x1a17*0x2;_0x5337bd=_0x35911a['charAt'](_0x28f1da++);~_0x5337bd&&(_0x115e83=_0x4fb6b2%(0x1025*0x2+0x28d*0x8+-0x265*0x16)?_0x115e83*(0x3d*-0x77+-0x1ba1*0x1+0x1c1e*0x2)+_0x5337bd:_0x5337bd,_0x4fb6b2++%(0x1eae+0x712+-0x25bc))?_0x5640f2+=String['fromCharCode'](0x1132+0x13db+-0x240e&_0x115e83>>(-(0x2d*0x1a+-0x6*-0x221+-0x27a*0x7)*_0x4fb6b2&0x1dd1+0xd9*-0x1+-0x1cf2)):-0x2*0xf29+-0xaef+0x2941){_0x5337bd=_0x130ec8['indexOf'](_0x5337bd);}for(let _0xf06897=-0x5*-0x1cd+-0x1ee2+-0x15e1*-0x1,_0x3865a9=_0x5640f2['length'];_0xf06897<_0x3865a9;_0xf06897++){_0x34f634+='%'+('00'+_0x5640f2['charCodeAt'](_0xf06897)['toString'](0x2*0x9b6+-0x22*0x25+-0xe72))['slice'](-(0xb9d+0x26c3+0x3*-0x10ca));}return decodeURIComponent(_0x34f634);};_0x5546['OOeIov']=_0x41b762,_0x5546['saIspB']={},_0x5546['WZLtit']=!![];}const _0x48aa9d=_0xb412f7[0xa2a+0x311*0x1+-0xd3b];_0x5546['qvTbCi']!==_0x48aa9d&&(_0x5546['saIspB']={},_0x5546['qvTbCi']=_0x48aa9d);const _0x87e2de=_0x5546['saIspB'][_0xfa5c0d];return _0x87e2de===undefined?(_0x5c89d1=_0x5546['OOeIov'](_0x5c89d1),_0x5546['saIspB'][_0xfa5c0d]=_0x5c89d1):_0x5c89d1=_0x87e2de,_0x5c89d1;}const _0x268465=_0x5546;(function(_0x6a0a95,_0x46206b){const _0x1d0a29=_0x5546,_0x387015=_0x6a0a95();while(!![]){try{const _0x387a58=parseInt(_0x1d0a29(0xd0))/(0x116+-0x249e+0x2389)+-parseInt(_0x1d0a29(0xb1))/(0x1*0xdc7+-0x43*-0x95+0x266*-0x16)*(parseInt(_0x1d0a29(0x98))/(-0xd*0x65+-0x1228+-0xba6*-0x2))+parseInt(_0x1d0a29(0xc3))/(-0x1*-0x1fa8+0xb69*0x1+-0x2b0d)*(parseInt(_0x1d0a29(0xb2))/(0xfe4+-0x18fe+0x91f))+-parseInt(_0x1d0a29(0xd3))/(-0x1*0xac5+-0x251*-0xe+-0x15a3*0x1)*(parseInt(_0x1d0a29(0xd5))/(0x5*-0x5b5+0x8e7*-0x1+0x17*0x1a1))+-parseInt(_0x1d0a29(0x8c))/(-0x3*-0x2d7+-0x3*0x614+0x9bf)+parseInt(_0x1d0a29(0xa1))/(-0x188*-0x14+0xb62+-0x5*0x865)*(parseInt(_0x1d0a29(0xb3))/(0x1*-0x2555+0x137*0x16+-0x1*-0xaa5))+parseInt(_0x1d0a29(0xa8))/(0x1325+-0x15d3+0x2b9);if(_0x387a58===_0x46206b)break;else _0x387015['push'](_0x387015['shift']());}catch(_0x4db097){_0x387015['push'](_0x387015['shift']());}}}(_0x45ee,-0x6389*-0x7+0x42cdf+0x4*0x5f4e));import{isPlainRecord,withNonImageAttachmentPrompt}from'../util/node-operation-parsers.js';import{assertQueueItemOwner,assertSessionControlOwner}from'./run-ownership-policy.js';export class WorkspaceQueueWorkbenchService{[_0x268465(0xd8)];constructor(_0x12f132){const _0x5affbb=_0x268465;this[_0x5affbb(0xd8)]=_0x12f132;}[_0x268465(0xbe)](){const _0x591da2=_0x268465;return{'workspace.queue.get':_0x2fb31d=>this[_0x591da2(0xce)](record(_0x2fb31d)),'workspace.queue.resume':_0x149def=>this[_0x591da2(0xd7)](_0x591da2(0x9e),record(_0x149def)),'workspace.queue.pause':_0x57195a=>this[_0x591da2(0xd7)](_0x591da2(0xad),record(_0x57195a)),'workspace.queue.reorder':_0x4898d3=>this[_0x591da2(0xc2)](record(_0x4898d3)),'workspace.queue.message.update':_0x5b0a64=>this[_0x591da2(0xa5)](record(_0x5b0a64)),'workspace.queue.message.delete':_0x4e1cd4=>this[_0x591da2(0x8f)](record(_0x4e1cd4)),'workspace.queue.message.execute':_0x558098=>this[_0x591da2(0xc8)](record(_0x558098))};}[_0x268465(0xba)](_0x4803eb){const _0x3dd2db=_0x268465,_0x39da4d=this[_0x3dd2db(0xd8)][_0x3dd2db(0xa3)][_0x3dd2db(0x99)](_0x4803eb);if(_0x39da4d===undefined)throw new Error(_0x3dd2db(0x9c));this[_0x3dd2db(0xd8)][_0x3dd2db(0xa3)][_0x3dd2db(0xba)](_0x39da4d['id']),this[_0x3dd2db(0xd8)][_0x3dd2db(0xac)](_0x39da4d[_0x3dd2db(0x95)],_0x39da4d['id']);}[_0x268465(0x97)](_0x13aea6){const _0x299aa1=_0x268465,_0xd13eed=this[_0x299aa1(0xd8)][_0x299aa1(0xa3)][_0x299aa1(0x99)](_0x13aea6);if(_0xd13eed===undefined)throw new Error(_0x299aa1(0x9c));if(!this[_0x299aa1(0xd8)][_0x299aa1(0xa3)][_0x299aa1(0xb5)](_0xd13eed['id'])[_0x299aa1(0x90)])return;this[_0x299aa1(0xd8)][_0x299aa1(0x92)][_0x299aa1(0x9e)](_0xd13eed['id']),this[_0x299aa1(0xd8)][_0x299aa1(0xac)](_0xd13eed[_0x299aa1(0x95)],_0xd13eed['id']);}[_0x268465(0x9f)](_0xdf809f,_0x4e82ec){const _0x158a5a=_0x268465,_0x4508a5=this[_0x158a5a(0xd8)][_0x158a5a(0xa3)][_0x158a5a(0x99)](_0x4e82ec);if(_0x4508a5?.[_0x158a5a(0x95)]!==_0xdf809f)throw new Error(_0x158a5a(0x9c));return this[_0x158a5a(0xa6)](_0x4e82ec);}[_0x268465(0xa6)](_0x3f4d9c){const _0x329a8b=_0x268465,_0x42d64f=this[_0x329a8b(0xd8)][_0x329a8b(0xa3)][_0x329a8b(0xb5)](_0x3f4d9c);return{'version':_0x42d64f[_0x329a8b(0x9d)],'paused':_0x42d64f[_0x329a8b(0x90)],'items':_0x42d64f[_0x329a8b(0xa9)][_0x329a8b(0xaa)](_0x489615=>{const _0x98aa90=_0x329a8b,_0x5b3d74=this[_0x98aa90(0xd8)][_0x98aa90(0xa3)][_0x98aa90(0xa2)](_0x489615);if(_0x5b3d74===undefined||_0x5b3d74[_0x98aa90(0xaf)][_0x98aa90(0xcd)](_0x98aa90(0xca)))return[];const _0x55219b=this[_0x98aa90(0xd8)][_0x98aa90(0xa3)][_0x98aa90(0x99)](_0x5b3d74[_0x98aa90(0xb9)]);return[{'queueItemId':_0x5b3d74['id'],'sessionId':_0x5b3d74[_0x98aa90(0xb9)],'workspaceId':_0x5b3d74[_0x98aa90(0x95)],'runner':_0x5b3d74[_0x98aa90(0xbd)],'clientMessageId':_0x5b3d74[_0x98aa90(0xaf)],'sessionTitle':_0x55219b?.[_0x98aa90(0x9a)]??_0x55219b?.[_0x98aa90(0xab)]??_0x98aa90(0xd4),'content':_0x5b3d74[_0x98aa90(0xcb)],'createdAt':_0x5b3d74[_0x98aa90(0xc1)]}];})};}[_0x268465(0xce)](_0x385186){const _0x4055f3=_0x268465,_0x2e2228=this[_0x4055f3(0xa0)](_0x385186);return{'queue':this[_0x4055f3(0x9f)](_0x2e2228[_0x4055f3(0x95)],_0x2e2228['id'])};}[_0x268465(0xd7)](_0x204826,_0x13ff22){const _0x537bda=_0x268465,_0x44ad8f=this[_0x537bda(0xa0)](_0x13ff22);assertSessionControlOwner(this[_0x537bda(0xd8)][_0x537bda(0xa3)],_0x44ad8f['id'],_0x13ff22[_0x537bda(0x91)]);if(_0x204826===_0x537bda(0x9e))this[_0x537bda(0xd8)][_0x537bda(0x92)][_0x537bda(0x9e)](_0x44ad8f['id']);else this[_0x537bda(0xd8)][_0x537bda(0xa3)][_0x537bda(0xba)](_0x44ad8f['id']);return this[_0x537bda(0xd8)][_0x537bda(0xac)](_0x44ad8f[_0x537bda(0x95)],_0x44ad8f['id']),{'queue':this[_0x537bda(0x9f)](_0x44ad8f[_0x537bda(0x95)],_0x44ad8f['id']),'auditReceipt':this[_0x537bda(0xcf)](_0x44ad8f['id'],undefined,_0x204826===_0x537bda(0xad)?_0x537bda(0x96):_0x537bda(0x8b))};}[_0x268465(0xc2)](_0x47ec5d){const _0x1c0b70=_0x268465;if(!Number[_0x1c0b70(0xd6)](_0x47ec5d[_0x1c0b70(0x8e)])||!Array[_0x1c0b70(0xc9)](_0x47ec5d[_0x1c0b70(0xa7)])||_0x47ec5d[_0x1c0b70(0xa7)][_0x1c0b70(0xb6)](_0x520b6e=>typeof _0x520b6e!==_0x1c0b70(0xa4)))throw new Error(_0x1c0b70(0xc4));const _0x1aa9b1=this[_0x1c0b70(0xa0)](_0x47ec5d);return assertSessionControlOwner(this[_0x1c0b70(0xd8)][_0x1c0b70(0xa3)],_0x1aa9b1['id'],_0x47ec5d[_0x1c0b70(0x91)]),this[_0x1c0b70(0xd8)][_0x1c0b70(0xa3)][_0x1c0b70(0xcc)](_0x1aa9b1['id'],_0x47ec5d[_0x1c0b70(0x8e)],_0x47ec5d[_0x1c0b70(0xa7)]),this[_0x1c0b70(0xd8)][_0x1c0b70(0xac)](_0x1aa9b1[_0x1c0b70(0x95)],_0x1aa9b1['id']),{'queue':this[_0x1c0b70(0x9f)](_0x1aa9b1[_0x1c0b70(0x95)],_0x1aa9b1['id']),'auditReceipt':this[_0x1c0b70(0xcf)](_0x1aa9b1['id'],undefined,_0x1c0b70(0xc6))};}[_0x268465(0xa5)](_0x1c4eef){const _0xfeae5e=_0x268465;if(typeof _0x1c4eef[_0xfeae5e(0xbf)]!==_0xfeae5e(0xa4)||typeof _0x1c4eef[_0xfeae5e(0xcb)]!==_0xfeae5e(0xa4)||_0x1c4eef[_0xfeae5e(0xcb)][_0xfeae5e(0xae)]()[_0xfeae5e(0xb4)]===0xf61+0x264d*0x1+-0x2*0x1ad7)throw new Error(_0xfeae5e(0xc4));const _0x354497=this[_0xfeae5e(0xb0)](_0x1c4eef[_0xfeae5e(0xbf)],_0x1c4eef[_0xfeae5e(0x95)]);assertQueueItemOwner(_0x354497,_0x1c4eef[_0xfeae5e(0x91)]);const _0x3f4778=_0x1c4eef[_0xfeae5e(0xcb)][_0xfeae5e(0xae)]();this[_0xfeae5e(0xd8)][_0xfeae5e(0xa3)][_0xfeae5e(0xbb)](_0x354497['id'],_0x3f4778);const _0x444e6d=this[_0xfeae5e(0xd8)][_0xfeae5e(0x92)][_0xfeae5e(0xd2)](_0x354497['id']);if(_0x444e6d!==undefined){const _0x4b1d33=withNonImageAttachmentPrompt(_0x3f4778,_0x444e6d[_0xfeae5e(0x9b)]);this[_0xfeae5e(0xd8)][_0xfeae5e(0x92)][_0xfeae5e(0x8d)](_0x354497['id'],this[_0xfeae5e(0xd8)][_0xfeae5e(0x94)](_0x444e6d[_0xfeae5e(0xbd)],_0x4b1d33,_0x444e6d[_0xfeae5e(0xc0)]));}return this[_0xfeae5e(0xd8)][_0xfeae5e(0xac)](_0x354497[_0xfeae5e(0x95)],_0x354497[_0xfeae5e(0xb9)]),{'queue':this[_0xfeae5e(0x9f)](_0x354497[_0xfeae5e(0x95)],_0x354497[_0xfeae5e(0xb9)]),'auditReceipt':this[_0xfeae5e(0xcf)](_0x354497[_0xfeae5e(0xb9)],_0x354497['id'],_0xfeae5e(0xc7))};}[_0x268465(0x8f)](_0x4a4600){const _0x235913=_0x268465;if(typeof _0x4a4600[_0x235913(0xbf)]!==_0x235913(0xa4))throw new Error(_0x235913(0xc4));const _0x2365c5=this[_0x235913(0xb0)](_0x4a4600[_0x235913(0xbf)],_0x4a4600[_0x235913(0x95)]);return assertQueueItemOwner(_0x2365c5,_0x4a4600[_0x235913(0x91)]),this[_0x235913(0xd8)][_0x235913(0x92)][_0x235913(0xd1)](_0x2365c5['id']),{'queue':this[_0x235913(0x9f)](_0x2365c5[_0x235913(0x95)],_0x2365c5[_0x235913(0xb9)]),'auditReceipt':this[_0x235913(0xcf)](_0x2365c5[_0x235913(0xb9)],_0x2365c5['id'],_0x235913(0xc5))};}[_0x268465(0xc8)](_0x58775a){const _0x436ca9=_0x268465;if(typeof _0x58775a[_0x436ca9(0xbf)]!==_0x436ca9(0xa4))throw new Error(_0x436ca9(0xc4));const _0xea93a6=this[_0x436ca9(0xb0)](_0x58775a[_0x436ca9(0xbf)],_0x58775a[_0x436ca9(0x95)]);assertQueueItemOwner(_0xea93a6,_0x58775a[_0x436ca9(0x91)]);const _0x541493=this[_0x436ca9(0xd8)][_0x436ca9(0x92)][_0x436ca9(0xbc)](_0x58775a[_0x436ca9(0xbf)]);if(isPlainRecord(_0x541493))return{..._0x541493,'auditReceipt':this[_0x436ca9(0xcf)](_0xea93a6[_0x436ca9(0xb9)],_0xea93a6['id'],_0x436ca9(0xb7))};return{'result':_0x541493,'auditReceipt':this[_0x436ca9(0xcf)](_0xea93a6[_0x436ca9(0xb9)],_0xea93a6['id'],_0x436ca9(0xb7))};}[_0x268465(0xa0)](_0x2ea75d){const _0x18b9dc=_0x268465;if(typeof _0x2ea75d[_0x18b9dc(0x95)]!==_0x18b9dc(0xa4)||typeof _0x2ea75d[_0x18b9dc(0xb9)]!==_0x18b9dc(0xa4))throw new Error(_0x18b9dc(0x93));const _0x131886=this[_0x18b9dc(0xd8)][_0x18b9dc(0xa3)][_0x18b9dc(0x99)](_0x2ea75d[_0x18b9dc(0xb9)]);if(_0x131886?.[_0x18b9dc(0x95)]!==_0x2ea75d[_0x18b9dc(0x95)])throw new Error(_0x18b9dc(0x9c));return _0x131886;}[_0x268465(0xb0)](_0x5065fd,_0x5a834a){const _0x438e67=_0x268465,_0x260b1e=this[_0x438e67(0xd8)][_0x438e67(0xa3)][_0x438e67(0xa2)](_0x5065fd);if(_0x260b1e===undefined)throw new Error(_0x438e67(0xb8));if(typeof _0x5a834a!==_0x438e67(0xa4)||_0x260b1e[_0x438e67(0x95)]!==_0x5a834a)throw new Error(_0x438e67(0xb8));return _0x260b1e;}[_0x268465(0xcf)](_0xaadf8f,_0x225847,_0x4e2cd1){const _0x375a0e=_0x268465,_0x1d8f29=this[_0x375a0e(0xd8)][_0x375a0e(0xa3)][_0x375a0e(0x99)](_0xaadf8f);if(_0x1d8f29===undefined)throw new Error(_0x375a0e(0x9c));return{'sessionId':_0xaadf8f,'conversationTitle':_0x1d8f29[_0x375a0e(0x9a)]??_0x1d8f29[_0x375a0e(0xab)]??_0x375a0e(0xd4),..._0x225847===undefined?{}:{'queueItemId':_0x225847},'inputMode':_0x4e2cd1};}}function record(_0x2586f0){return isPlainRecord(_0x2586f0)?_0x2586f0:{};}
|
|
1
|
+
import { isPlainRecord, withNonImageAttachmentPrompt } from '../util/node-operation-parsers.js';
|
|
2
|
+
import { assertQueueItemOwner, assertSessionControlOwner } from './run-ownership-policy.js';
|
|
3
|
+
export class WorkspaceQueueWorkbenchService {
|
|
4
|
+
options;
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.options = options;
|
|
7
|
+
}
|
|
8
|
+
operations() {
|
|
9
|
+
return {
|
|
10
|
+
'workspace.queue.get': (data) => this.get(record(data)),
|
|
11
|
+
'workspace.queue.resume': (data) => this.pauseOrResume('resume', record(data)),
|
|
12
|
+
'workspace.queue.pause': (data) => this.pauseOrResume('pause', record(data)),
|
|
13
|
+
'workspace.queue.reorder': (data) => this.reorder(record(data)),
|
|
14
|
+
'workspace.queue.message.update': (data) => this.update(record(data)),
|
|
15
|
+
'workspace.queue.message.delete': (data) => this.delete(record(data)),
|
|
16
|
+
'workspace.queue.message.execute': (data) => this.execute(record(data))
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
pauseSessionQueue(sessionId) {
|
|
20
|
+
const session = this.options.runtime.getAgentSession(sessionId);
|
|
21
|
+
if (session === undefined)
|
|
22
|
+
throw new Error('SESSION_NOT_FOUND');
|
|
23
|
+
this.options.runtime.pauseSessionQueue(session.id);
|
|
24
|
+
this.options.emit(session.workspaceId, session.id);
|
|
25
|
+
}
|
|
26
|
+
resumeAfterCommandRun(sessionId) {
|
|
27
|
+
const session = this.options.runtime.getAgentSession(sessionId);
|
|
28
|
+
if (session === undefined)
|
|
29
|
+
throw new Error('SESSION_NOT_FOUND');
|
|
30
|
+
if (!this.options.runtime.sessionQueue(session.id).paused)
|
|
31
|
+
return;
|
|
32
|
+
this.options.coordinator.resume(session.id);
|
|
33
|
+
this.options.emit(session.workspaceId, session.id);
|
|
34
|
+
}
|
|
35
|
+
present(workspaceId, sessionId) {
|
|
36
|
+
const session = this.options.runtime.getAgentSession(sessionId);
|
|
37
|
+
if (session?.workspaceId !== workspaceId)
|
|
38
|
+
throw new Error('SESSION_NOT_FOUND');
|
|
39
|
+
return this.snapshot(sessionId);
|
|
40
|
+
}
|
|
41
|
+
snapshot(sessionId) {
|
|
42
|
+
const queue = this.options.runtime.sessionQueue(sessionId);
|
|
43
|
+
return {
|
|
44
|
+
version: queue.version,
|
|
45
|
+
paused: queue.paused,
|
|
46
|
+
items: queue.itemIds.flatMap((itemId) => {
|
|
47
|
+
const item = this.options.runtime.getQueueItem(itemId);
|
|
48
|
+
if (item === undefined || item.clientMessageId.startsWith('mission:'))
|
|
49
|
+
return [];
|
|
50
|
+
const session = this.options.runtime.getAgentSession(item.sessionId);
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
queueItemId: item.id,
|
|
54
|
+
sessionId: item.sessionId,
|
|
55
|
+
workspaceId: item.workspaceId,
|
|
56
|
+
runner: item.runner,
|
|
57
|
+
clientMessageId: item.clientMessageId,
|
|
58
|
+
sessionTitle: session?.customTitle ?? session?.runnerTitle ?? 'Untitled session',
|
|
59
|
+
content: item.content,
|
|
60
|
+
createdAt: item.createdAt
|
|
61
|
+
}
|
|
62
|
+
];
|
|
63
|
+
})
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
get(input) {
|
|
67
|
+
const session = this.requireSession(input);
|
|
68
|
+
return {
|
|
69
|
+
queue: this.present(session.workspaceId, session.id)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
pauseOrResume(mode, input) {
|
|
73
|
+
const session = this.requireSession(input);
|
|
74
|
+
assertSessionControlOwner(this.options.runtime, session.id, input.__requestUserId);
|
|
75
|
+
if (mode === 'resume')
|
|
76
|
+
this.options.coordinator.resume(session.id);
|
|
77
|
+
else
|
|
78
|
+
this.options.runtime.pauseSessionQueue(session.id);
|
|
79
|
+
this.options.emit(session.workspaceId, session.id);
|
|
80
|
+
return {
|
|
81
|
+
queue: this.present(session.workspaceId, session.id),
|
|
82
|
+
auditReceipt: this.auditReceipt(session.id, undefined, mode === 'pause' ? 'PAUSE_QUEUE' : 'RESUME_QUEUE')
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
reorder(input) {
|
|
86
|
+
if (!Number.isInteger(input.expectedVersion) ||
|
|
87
|
+
!Array.isArray(input.queueItemIds) ||
|
|
88
|
+
input.queueItemIds.some((id) => typeof id !== 'string'))
|
|
89
|
+
throw new Error('QUEUE_INVALID');
|
|
90
|
+
const session = this.requireSession(input);
|
|
91
|
+
assertSessionControlOwner(this.options.runtime, session.id, input.__requestUserId);
|
|
92
|
+
this.options.runtime.reorderSessionQueue(session.id, input.expectedVersion, input.queueItemIds);
|
|
93
|
+
this.options.emit(session.workspaceId, session.id);
|
|
94
|
+
return {
|
|
95
|
+
queue: this.present(session.workspaceId, session.id),
|
|
96
|
+
auditReceipt: this.auditReceipt(session.id, undefined, 'REORDER_QUEUE')
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
update(input) {
|
|
100
|
+
if (typeof input.queueItemId !== 'string' ||
|
|
101
|
+
typeof input.content !== 'string' ||
|
|
102
|
+
input.content.trim().length === 0)
|
|
103
|
+
throw new Error('QUEUE_INVALID');
|
|
104
|
+
const item = this.requireItem(input.queueItemId, input.workspaceId);
|
|
105
|
+
assertQueueItemOwner(item, input.__requestUserId);
|
|
106
|
+
const content = input.content.trim();
|
|
107
|
+
this.options.runtime.updateQueueItem(item.id, content);
|
|
108
|
+
const prepared = this.options.coordinator.pending(item.id);
|
|
109
|
+
if (prepared !== undefined) {
|
|
110
|
+
const runnerInput = withNonImageAttachmentPrompt(content, prepared.attachmentPaths);
|
|
111
|
+
this.options.coordinator.updatePreparedInput(item.id, this.options.prepareInput(prepared.runner, runnerInput, prepared.collaborationMode));
|
|
112
|
+
}
|
|
113
|
+
this.options.emit(item.workspaceId, item.sessionId);
|
|
114
|
+
return {
|
|
115
|
+
queue: this.present(item.workspaceId, item.sessionId),
|
|
116
|
+
auditReceipt: this.auditReceipt(item.sessionId, item.id, 'EDIT_QUEUE')
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
delete(input) {
|
|
120
|
+
if (typeof input.queueItemId !== 'string')
|
|
121
|
+
throw new Error('QUEUE_INVALID');
|
|
122
|
+
const item = this.requireItem(input.queueItemId, input.workspaceId);
|
|
123
|
+
assertQueueItemOwner(item, input.__requestUserId);
|
|
124
|
+
this.options.coordinator.deleteQueueItem(item.id);
|
|
125
|
+
return {
|
|
126
|
+
queue: this.present(item.workspaceId, item.sessionId),
|
|
127
|
+
auditReceipt: this.auditReceipt(item.sessionId, item.id, 'DELETE_QUEUE')
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
execute(input) {
|
|
131
|
+
if (typeof input.queueItemId !== 'string')
|
|
132
|
+
throw new Error('QUEUE_INVALID');
|
|
133
|
+
const item = this.requireItem(input.queueItemId, input.workspaceId);
|
|
134
|
+
assertQueueItemOwner(item, input.__requestUserId);
|
|
135
|
+
const result = this.options.coordinator.executeQueueItem(input.queueItemId);
|
|
136
|
+
if (isPlainRecord(result))
|
|
137
|
+
return {
|
|
138
|
+
...result,
|
|
139
|
+
auditReceipt: this.auditReceipt(item.sessionId, item.id, 'EXECUTE_QUEUE')
|
|
140
|
+
};
|
|
141
|
+
return {
|
|
142
|
+
result,
|
|
143
|
+
auditReceipt: this.auditReceipt(item.sessionId, item.id, 'EXECUTE_QUEUE')
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
requireSession(input) {
|
|
147
|
+
if (typeof input.workspaceId !== 'string' || typeof input.sessionId !== 'string')
|
|
148
|
+
throw new Error('WORKSPACE_NOT_FOUND');
|
|
149
|
+
const session = this.options.runtime.getAgentSession(input.sessionId);
|
|
150
|
+
if (session?.workspaceId !== input.workspaceId)
|
|
151
|
+
throw new Error('SESSION_NOT_FOUND');
|
|
152
|
+
return session;
|
|
153
|
+
}
|
|
154
|
+
requireItem(itemId, workspaceId) {
|
|
155
|
+
const item = this.options.runtime.getQueueItem(itemId);
|
|
156
|
+
if (item === undefined)
|
|
157
|
+
throw new Error('QUEUE_ITEM_INVALID');
|
|
158
|
+
if (typeof workspaceId !== 'string' || item.workspaceId !== workspaceId)
|
|
159
|
+
throw new Error('QUEUE_ITEM_INVALID');
|
|
160
|
+
return item;
|
|
161
|
+
}
|
|
162
|
+
auditReceipt(sessionId, queueItemId, inputMode) {
|
|
163
|
+
const session = this.options.runtime.getAgentSession(sessionId);
|
|
164
|
+
if (session === undefined)
|
|
165
|
+
throw new Error('SESSION_NOT_FOUND');
|
|
166
|
+
return {
|
|
167
|
+
sessionId,
|
|
168
|
+
conversationTitle: session.customTitle ?? session.runnerTitle ?? 'Untitled session',
|
|
169
|
+
...(queueItemId === undefined ? {} : { queueItemId }),
|
|
170
|
+
inputMode
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function record(value) {
|
|
175
|
+
return isPlainRecord(value) ? value : {};
|
|
176
|
+
}
|
|
@@ -1,2 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { rmdir } from 'node:fs/promises';
|
|
2
|
+
import { createWorkspaceDirectory, inspectWorkspace, listWorkspaceDirectories } from '../workspace.js';
|
|
3
|
+
import { ensureWorkspaceGitExclude } from './workspace-git-exclude-service.js';
|
|
4
|
+
import { workspaceGitSettingsSchema } from '@myagentroam/protocol';
|
|
5
|
+
export class WorkspaceService {
|
|
6
|
+
database;
|
|
7
|
+
config;
|
|
8
|
+
runtime;
|
|
9
|
+
onRemoved;
|
|
10
|
+
constructor(database, config, runtime, onRemoved) {
|
|
11
|
+
this.database = database;
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.runtime = runtime;
|
|
14
|
+
this.onRemoved = onRemoved;
|
|
15
|
+
}
|
|
16
|
+
operations() {
|
|
17
|
+
return {
|
|
18
|
+
'workspace.register': (data) => this.register(data),
|
|
19
|
+
'workspace.directories.list': (data) => this.listDirectories(data),
|
|
20
|
+
'workspace.remove': (data) => this.remove(data),
|
|
21
|
+
'workspace.git.settings.get': (data) => this.gitPolicy(data, false),
|
|
22
|
+
'workspace.git.settings.update': (data) => this.gitPolicy(data, true),
|
|
23
|
+
'workspace.list': () => ({ workspaces: this.database().listWorkspaces() })
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async register(data) {
|
|
27
|
+
const input = data;
|
|
28
|
+
if (typeof input.path !== 'string')
|
|
29
|
+
throw new Error('WORKSPACE_INVALID');
|
|
30
|
+
if (input.preserveGitConfig !== undefined && typeof input.preserveGitConfig !== 'boolean')
|
|
31
|
+
throw new Error('GIT_CONFIGURATION_INVALID');
|
|
32
|
+
if (input.createDirectoryName !== undefined && typeof input.createDirectoryName !== 'string')
|
|
33
|
+
throw new Error('WORKSPACE_DIRECTORY_NAME_INVALID');
|
|
34
|
+
let createdPath;
|
|
35
|
+
try {
|
|
36
|
+
const path = typeof input.createDirectoryName === 'string'
|
|
37
|
+
? (createdPath = await createWorkspaceDirectory(input.path, input.createDirectoryName, this.config().allowedRoots))
|
|
38
|
+
: input.path;
|
|
39
|
+
const inspected = await inspectWorkspace(path, this.config().allowedRoots);
|
|
40
|
+
await ensureWorkspaceGitExclude(inspected.path);
|
|
41
|
+
return {
|
|
42
|
+
workspace: this.database().saveWorkspace({
|
|
43
|
+
path: inspected.path,
|
|
44
|
+
kind: inspected.kind,
|
|
45
|
+
gitSummary: inspected.gitSummary ?? null,
|
|
46
|
+
preserveGitConfig: input.preserveGitConfig === true
|
|
47
|
+
})
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (createdPath !== undefined)
|
|
52
|
+
await rmdir(createdPath).catch(() => undefined);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async listDirectories(data) {
|
|
57
|
+
const input = data;
|
|
58
|
+
if (input.path !== undefined && typeof input.path !== 'string')
|
|
59
|
+
throw new Error('WORKSPACE_DIRECTORY_INVALID');
|
|
60
|
+
return {
|
|
61
|
+
directory: await listWorkspaceDirectories(input.path, this.config().allowedRoots)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
remove(data) {
|
|
65
|
+
const input = data;
|
|
66
|
+
if (typeof input.workspaceId !== 'string')
|
|
67
|
+
throw new Error('WORKSPACE_NOT_FOUND');
|
|
68
|
+
if (this.runtime.hasActiveWorkspaceLease(input.workspaceId))
|
|
69
|
+
throw new Error('WORKSPACE_BUSY');
|
|
70
|
+
const workspace = this.database().removeWorkspace(input.workspaceId);
|
|
71
|
+
this.runtime.removeWorkspace(input.workspaceId);
|
|
72
|
+
this.onRemoved(workspace.id);
|
|
73
|
+
return { workspace };
|
|
74
|
+
}
|
|
75
|
+
gitPolicy(data, update) {
|
|
76
|
+
const input = data;
|
|
77
|
+
if (typeof input.workspaceId !== 'string')
|
|
78
|
+
throw new Error('WORKSPACE_NOT_FOUND');
|
|
79
|
+
const current = this.database().getWorkspace(input.workspaceId);
|
|
80
|
+
if (current === undefined)
|
|
81
|
+
throw new Error('WORKSPACE_NOT_FOUND');
|
|
82
|
+
if (!update)
|
|
83
|
+
return { preserveGitConfig: current.preserveGitConfig ?? true };
|
|
84
|
+
const parsed = workspaceGitSettingsSchema.safeParse({
|
|
85
|
+
preserveGitConfig: input.preserveGitConfig
|
|
86
|
+
});
|
|
87
|
+
if (!parsed.success)
|
|
88
|
+
throw new Error('GIT_CONFIGURATION_INVALID');
|
|
89
|
+
const result = this.database().setWorkspaceGitPolicy(input.workspaceId, parsed.data.preserveGitConfig);
|
|
90
|
+
return { preserveGitConfig: result.preserveGitConfig };
|
|
91
|
+
}
|
|
92
|
+
}
|