@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,290 @@
|
|
|
1
|
-
|
|
2
|
-
const _0x142df1=_0x5c04;(function(_0x277874,_0x12ea51){const _0x437964=_0x5c04,_0xd2434e=_0x277874();while(!![]){try{const _0x1f9bca=parseInt(_0x437964(0x18a))/(0x20*0x29+0x7b*0x1c+-0x1293)+-parseInt(_0x437964(0x19b))/(0x53+-0x10fd+0x1*0x10ac)+parseInt(_0x437964(0x15b))/(-0x2*-0x412+-0x352*0x4+0x527)+-parseInt(_0x437964(0x18b))/(-0x67*-0x12+0x147a+-0x93c*0x3)+-parseInt(_0x437964(0x196))/(0x1900+-0x1f37*-0x1+0x1c19*-0x2)*(parseInt(_0x437964(0x188))/(0x8e1*0x1+0x59a*-0x2+0x259))+-parseInt(_0x437964(0x174))/(-0x3*-0x1+-0x1eac+-0x2*-0xf58)+parseInt(_0x437964(0x1a7))/(-0x3cb*0x3+-0x3e3*-0x8+-0x13af*0x1);if(_0x1f9bca===_0x12ea51)break;else _0xd2434e['push'](_0xd2434e['shift']());}catch(_0x353699){_0xd2434e['push'](_0xd2434e['shift']());}}}(_0x49b1,-0x3*-0x93cf+-0x1d972+-0x780b*-0x5));import{lstat}from'node:fs/promises';import{basename,posix,resolve}from'node:path';function _0x49b1(){const _0x4e214=['Dhj1BMnHDgvK','y2HHBMDLC1jLywrZ','tuLtu0LorW','nty1ndrcshbsEhK','C3bSAwnL','CM91BMq','y2XLyxi','zxHWAxjLC0f0','CNvU','v09ss1rsruu','DMfSDwu','yNjHBMnO','BwfWCgLUzW','r0Lux1jfue9tsvrpuLLFvu5srufequjmrq','Cgf0Aa','A2LUza','zw50CMLLCW','y2HHBMDLC0XPBwL0zxi','y2HHBMDLC1zLCNnPB25Z','C29Tzq','y29Kzq','y3vYCMvUDa','Aw52ywXPzgf0zq','D29YA3nWywnLlMnOyw5NzxmUy29TCgXLDgvK','r0Lux1nvqK1prfvmrv9nqvbqsu5hx0LovKfmsuq','r0Lux1DpuKTuuKvfx0rju0npvKvswv9gquLmruq','BwLU','y2HHBMDLCW','mZi4ndu0wgfWrMPz','BM93','BgvUz3rO','C3bHD24','y2HHBMDLC0nHy2HL','vu5bvKfjtefcteu','z2L0rxHPDenVzgu','Chj1BMfIBgu','reLsvfK','r2L0ignVBw1HBMqGzxHPDgvKihDPDgGGC3rHDhvZia','ywXS','y2f0y2G','zgLYDhK','CgfYDgLHBa','zMLUza','AxneAxjLy3rVCNK','r0Lux1nvqK1prfvmrv9msu1jvf9fwenfrurfra','v09ss1nqqunfx05pvf9hsvq','Bg9JA2vK','r0Lux05pvf9gt1vora','nLPguK1svG','ru5pru5u','mtm1nte4CLLwAKHV','mta4mte2ngHwywTgtG','yMfZzw5HBwu','C3LZy2fSBa','zMLSDgvY','lMDPDa','Bg9JywXLq29TCgfYzq','r0Lux1DpuKTtuefdrq','AxntEw1IB2XPy0XPBMS','C3rHCNrZv2L0Aa','C2v0','C29YDa','nJi1mdG1u091z0nI','ChvZAa','zNjVBq','CMvWB3nPDg9YAwvZ','BwfW','nduWmdeWte1rBeTc','q0Xfqu4','D29YA3nWywnLlMnOyw5NzxmUy3vYCMvUDa','zgLYzwn0B3j5tMfTzq','C3rHDhvZ','uK9pva','D29YA3rYzwvqyxrO','zgvSzxrL','CgfYyw1LDgvYCW','u1vctu9evuXf','D29YA3nWywnLlMDPDc1NCM91Cc51BMf2ywLSywjSzq','r0Lux1nvqK1prfvmrv9esvndt1zfuLLFrKfjteve','nti3mdCXmMjJuefxqG','AgvHza','AxngAwXL','CMvWB3nPDg9YEvbHDgG','C3rHDgu','tufqueve','r0Lux1nvqK1prfvmrv9nqvbqsu5hx01ju1njtKC','z2v0','zMXHDa'];_0x49b1=function(){return _0x4e214;};return _0x49b1();}import{publicErrorMessage}from'@myagentroam/protocol';import{nodeLog}from'../operational.js';import{GitCommandError,isWorkspaceChangeVisible,listGitWorktrees,listGitSubmodules,readCurrentChangesSummary,resolveGitRepository}from'../workspace.js';const CACHE_TTL_MS=-0x101f*-0x1+0x1142+-0x1*0xdd9,REPOSITORY_READ_CONCURRENCY=-0x1d*0xc7+0x214e+-0xabf,WORKTREE_READ_CONCURRENCY=0xd*-0x2f5+0x4ed*0x3+-0x1b1*-0xe,CHANGE_VISIBILITY_CONCURRENCY=0x16*-0x1ba+0x473*0x2+0xd*0x23e,SUBMODULE_LIMIT=0x1*-0x1aad+0x1*0x5b1+0x157c;export class WorkspaceChangeService{[_0x142df1(0x1ab)];constructor(_0x56dbc9){const _0x349c89=_0x142df1;this[_0x349c89(0x1ab)]=_0x56dbc9;}[_0x142df1(0x16e)](_0x5ab5c6){const _0x350321=_0x142df1;this[_0x350321(0x1ab)][_0x350321(0x159)][_0x350321(0x1a2)](_0x5ab5c6),this[_0x350321(0x1ab)][_0x350321(0x178)][_0x350321(0x1a2)](_0x5ab5c6),this[_0x350321(0x1ab)][_0x350321(0x16a)][_0x350321(0x194)](_0x5ab5c6,(this[_0x350321(0x1ab)][_0x350321(0x16a)][_0x350321(0x1ae)](_0x5ab5c6)??0x13ec+0x6d1*0x2+-0x10c7*0x2)+(0x135a+-0x130+-0x1229));}[_0x142df1(0x15e)](){const _0x537746=_0x142df1;this[_0x537746(0x1ab)][_0x537746(0x159)][_0x537746(0x15e)](),this[_0x537746(0x1ab)][_0x537746(0x178)][_0x537746(0x15e)](),this[_0x537746(0x1ab)][_0x537746(0x16a)][_0x537746(0x15e)]();}async[_0x142df1(0x16d)](_0x565ac1){const _0x48ecb8=_0x142df1;if(_0x565ac1[_0x48ecb8(0x167)]!==_0x48ecb8(0x191))throw new Error(_0x48ecb8(0x185));const _0x37e20e=this[_0x48ecb8(0x1ab)][_0x48ecb8(0x178)][_0x48ecb8(0x1ae)](_0x565ac1['id']);if(_0x37e20e!==undefined&&_0x37e20e[_0x48ecb8(0x15f)]>Date[_0x48ecb8(0x175)]())return _0x37e20e[_0x48ecb8(0x162)];const _0x262c50=this[_0x48ecb8(0x1ab)][_0x48ecb8(0x159)][_0x48ecb8(0x1ae)](_0x565ac1['id']);if(_0x262c50!==undefined)return _0x262c50;const _0x16c916=this[_0x48ecb8(0x1ab)][_0x48ecb8(0x16a)][_0x48ecb8(0x1ae)](_0x565ac1['id'])??-0x2d7+-0x25eb+0x28c2,_0x5d9912=this[_0x48ecb8(0x1ab)][_0x48ecb8(0x169)][_0x48ecb8(0x160)](async()=>{const _0x4cd7cf=_0x48ecb8,_0x37b585=performance[_0x4cd7cf(0x175)](),_0x5a3e1f=[],_0x3a291c=(_0x19a9ac,_0x14b226)=>({'code':_0x19a9ac,'message':publicErrorMessage(_0x19a9ac),..._0x14b226 instanceof GitCommandError?{'parameters':{'gitExitCode':_0x14b226[_0x4cd7cf(0x16c)]},'details':_0x4cd7cf(0x17d)+_0x14b226[_0x4cd7cf(0x16c)]+'.'}:{}}),_0xb6e57=(_0x21e4b0,_0x441207,_0x3f2bd6)=>{const _0x2915c9=_0x4cd7cf;nodeLog(_0x2915c9(0x1a5),{'workspaceId':_0x565ac1['id'],'groupKind':_0x21e4b0,'groupPath':_0x441207,'errorCode':_0x3f2bd6[_0x2915c9(0x16c)],..._0x3f2bd6[_0x2915c9(0x1a3)],'durationMs':Math[_0x2915c9(0x15d)](performance[_0x2915c9(0x175)]()-_0x37b585)});},_0x58a6ed=(_0x4e1bb8,_0xe55ee3,_0x251aec,_0x7e0e2c)=>{const _0xad2649=_0x4cd7cf,_0x342f1d=_0x3a291c(_0x251aec,_0x7e0e2c);if(_0x5a3e1f[_0xad2649(0x176)]<-0x1b32+0x2*0x481+0x40*0x49)_0x5a3e1f[_0xad2649(0x197)](_0x342f1d);_0xb6e57(_0x4e1bb8,_0xe55ee3,_0x342f1d);},_0x3b2db8=async(_0x543b82,_0xc2a033)=>{const _0x5c7458=_0x4cd7cf,_0x58e75d=_0xc2a033??await resolveGitRepository(_0x565ac1[_0x5c7458(0x166)],_0x543b82,[_0x543b82]);if(_0x543b82!==''||_0xc2a033!==undefined){const _0x345f40=await lstat(resolve(_0x58e75d,_0x5c7458(0x18f)));if(_0x345f40[_0x5c7458(0x192)]()||!_0x345f40[_0x5c7458(0x1a9)]()&&!_0x345f40[_0x5c7458(0x183)]())throw new Error(_0x5c7458(0x165));}const _0x44b809=await readCurrentChangesSummary(_0x58e75d,!![]),_0x4e14b1=(await mapWithConcurrency(_0x44b809[_0x5c7458(0x173)],CHANGE_VISIBILITY_CONCURRENCY,async _0xac6b65=>({'change':_0xac6b65,'visible':await isWorkspaceChangeVisible(_0x58e75d,_0xac6b65[_0x5c7458(0x166)])})))[_0x5c7458(0x18e)](({visible:_0x270896})=>_0x270896)[_0x5c7458(0x19a)](({change:_0x5df2a7})=>_0x5df2a7);return{'repositoryPath':_0x543b82,'repositoryName':_0x543b82===''?basename(_0x58e75d):posix[_0x5c7458(0x18c)](_0x543b82),'branch':_0x44b809[_0x5c7458(0x163)],'dirty':_0x44b809[_0x5c7458(0x173)][_0x5c7458(0x176)]>0x16ec+0x45d*0x2+-0x1fa6,'status':_0x44b809[_0x5c7458(0x173)][_0x5c7458(0x176)]>0x3c0+-0x151a+0x115a?_0x5c7458(0x17c):_0x5c7458(0x19c),'changes':_0x4e14b1};},_0x192018=await _0x3b2db8('')[_0x4cd7cf(0x17f)](_0xbb4562=>{const _0x4441f5=_0x4cd7cf;if(_0xbb4562?.[_0x4441f5(0x16c)]===_0x4441f5(0x189)&&_0xbb4562[_0x4441f5(0x18d)]?.[_0x4441f5(0x193)](_0x4441f5(0x177))===!![])throw new Error(_0x4441f5(0x187));throw _0xbb4562;}),_0x5116c0=[];let _0x2ecc72=[''],_0x44bc98=![];while(_0x2ecc72[_0x4cd7cf(0x176)]>0x1*-0x10be+-0xbb*-0x1d+-0x471&&!_0x44bc98){const _0x5b563e=await mapWithConcurrency(_0x2ecc72,REPOSITORY_READ_CONCURRENCY,async _0x14fd84=>{const _0x3ec729=_0x4cd7cf;try{const _0x1f424c=await resolveGitRepository(_0x565ac1[_0x3ec729(0x166)],_0x14fd84,[_0x14fd84]);return(await listGitSubmodules(_0x1f424c))[_0x3ec729(0x19a)](_0x3f0216=>({..._0x3f0216,'path':_0x14fd84===''?_0x3f0216[_0x3ec729(0x166)]:_0x14fd84+'/'+_0x3f0216[_0x3ec729(0x166)]}));}catch(_0x5ddbba){return _0x58a6ed(_0x3ec729(0x1a4),_0x14fd84,_0x3ec729(0x1a6),_0x5ddbba),[];}}),_0x88fdb1=_0x5b563e[_0x4cd7cf(0x157)]();_0x5116c0[_0x4cd7cf(0x176)]+_0x88fdb1[_0x4cd7cf(0x176)]>SUBMODULE_LIMIT&&(_0x88fdb1[_0x4cd7cf(0x15c)](SUBMODULE_LIMIT-_0x5116c0[_0x4cd7cf(0x176)]),_0x44bc98=!![],_0x58a6ed(_0x4cd7cf(0x1a4),'',_0x4cd7cf(0x184),undefined));const _0x49b81c=await mapWithConcurrency(_0x88fdb1,REPOSITORY_READ_CONCURRENCY,async _0x87c63c=>{const _0x25e5d7=_0x4cd7cf;let _0x295ded;if(_0x87c63c[_0x25e5d7(0x164)]!==_0x25e5d7(0x1ac))_0x295ded=_0x3a291c(_0x87c63c[_0x25e5d7(0x164)]===_0x25e5d7(0x15a)?_0x25e5d7(0x1ad):_0x25e5d7(0x170),_0x87c63c[_0x25e5d7(0x17a)]===undefined?undefined:new GitCommandError(_0x87c63c[_0x25e5d7(0x17a)],''));else try{return await _0x3b2db8(_0x87c63c[_0x25e5d7(0x166)]);}catch(_0x2ab32a){_0x295ded=_0x3a291c(_0x25e5d7(0x165),_0x2ab32a);}return _0xb6e57(_0x25e5d7(0x1a4),_0x87c63c[_0x25e5d7(0x166)],_0x295ded),{'repositoryPath':_0x87c63c[_0x25e5d7(0x166)],'repositoryName':posix[_0x25e5d7(0x18c)](_0x87c63c[_0x25e5d7(0x166)]),'branch':null,'dirty':![],'status':_0x25e5d7(0x179),'changes':[],'error':_0x295ded};});_0x5116c0[_0x4cd7cf(0x197)](..._0x49b81c),_0x2ecc72=_0x49b81c[_0x4cd7cf(0x18e)](_0x34087c=>_0x34087c[_0x4cd7cf(0x19f)]!==_0x4cd7cf(0x179))[_0x4cd7cf(0x19a)](_0x2061af=>_0x2061af[_0x4cd7cf(0x1aa)]);}_0x5116c0[_0x4cd7cf(0x195)]((_0x22be30,_0xea1680)=>_0x22be30[_0x4cd7cf(0x1aa)][_0x4cd7cf(0x190)](_0xea1680[_0x4cd7cf(0x1aa)]));const _0x4c37c5=await listGitWorktrees(_0x565ac1[_0x4cd7cf(0x166)])[_0x4cd7cf(0x17f)](_0x289427=>{const _0x51bc7d=_0x4cd7cf;return _0x58a6ed(_0x51bc7d(0x161),'',_0x51bc7d(0x171),_0x289427),{'entries':[],'truncated':![]};}),_0x4830ea=_0x4c37c5[_0x4cd7cf(0x168)][_0x4cd7cf(0x18e)](_0x17f0a1=>!_0x17f0a1[_0x4cd7cf(0x16d)]),_0x4b667b=await mapWithConcurrency(_0x4830ea,WORKTREE_READ_CONCURRENCY,async _0x38bb13=>{const _0x52eadc=_0x4cd7cf,_0x4ffc5d={'repositoryPath':'','repositoryName':_0x38bb13[_0x52eadc(0x19e)],'source':_0x52eadc(0x161),'worktreePath':_0x38bb13[_0x52eadc(0x166)],'physicalPath':_0x38bb13[_0x52eadc(0x166)],'current':![],'branch':_0x38bb13[_0x52eadc(0x163)],'head':_0x38bb13[_0x52eadc(0x1a8)],'locked':_0x38bb13[_0x52eadc(0x186)],'prunable':_0x38bb13[_0x52eadc(0x17b)]};if(_0x38bb13[_0x52eadc(0x17b)]){const _0xadce3f=_0x3a291c(_0x52eadc(0x165));return _0xb6e57(_0x52eadc(0x161),_0x38bb13[_0x52eadc(0x19e)],_0xadce3f),{..._0x4ffc5d,'dirty':![],'status':_0x52eadc(0x179),'error':_0xadce3f,'changes':[]};}try{const _0x5f1593=await _0x3b2db8('',_0x38bb13[_0x52eadc(0x166)]);return{..._0x4ffc5d,'dirty':_0x5f1593[_0x52eadc(0x180)],'branch':_0x5f1593[_0x52eadc(0x163)],'status':_0x5f1593[_0x52eadc(0x180)]?_0x52eadc(0x17c):_0x52eadc(0x19c),'changes':_0x5f1593[_0x52eadc(0x173)]};}catch(_0x4692d9){const _0x1175fb=_0x3a291c(_0x52eadc(0x165),_0x4692d9);return _0xb6e57(_0x52eadc(0x161),_0x38bb13[_0x52eadc(0x19e)],_0x1175fb),{..._0x4ffc5d,'dirty':![],'status':_0x52eadc(0x179),'error':_0x1175fb,'changes':[]};}}),_0x575485=_0x4c37c5[_0x4cd7cf(0x168)][_0x4cd7cf(0x182)](_0x43deb4=>_0x43deb4[_0x4cd7cf(0x16d)]),_0x3f3fec=_0x4c37c5[_0x4cd7cf(0x168)][_0x4cd7cf(0x19a)](_0x38fa8e=>{const _0x33e6ca=_0x4cd7cf,_0x5e14a5=_0x4b667b[_0x33e6ca(0x182)](_0xfb3a6d=>_0xfb3a6d[_0x33e6ca(0x1a1)]===_0x38fa8e[_0x33e6ca(0x166)]);return{'directoryName':_0x38fa8e[_0x33e6ca(0x19e)],'branch':_0x38fa8e[_0x33e6ca(0x163)],'head':_0x38fa8e[_0x33e6ca(0x1a8)],'current':_0x38fa8e[_0x33e6ca(0x16d)],'status':_0x38fa8e[_0x33e6ca(0x16d)]?_0x192018[_0x33e6ca(0x180)]?_0x33e6ca(0x17c):_0x33e6ca(0x19c):_0x5e14a5?.[_0x33e6ca(0x19f)]??_0x33e6ca(0x179),'locked':_0x38fa8e[_0x33e6ca(0x186)],'prunable':_0x38fa8e[_0x33e6ca(0x17b)]};}),_0xd08fff=_0x4b9256=>({..._0x4b9256,'additions':null,'deletions':null,'binary':![],'diffAvailable':!![]}),_0xb2dc32={'partial':_0x5a3e1f[_0x4cd7cf(0x176)]>-0x15aa+0x9b3+0x1*0xbf7||_0x5116c0[_0x4cd7cf(0x16b)](_0x382be2=>_0x382be2[_0x4cd7cf(0x19f)]===_0x4cd7cf(0x179))||_0x4b667b[_0x4cd7cf(0x16b)](_0x580604=>_0x580604[_0x4cd7cf(0x19f)]===_0x4cd7cf(0x179))||_0x4c37c5[_0x4cd7cf(0x158)],..._0x5a3e1f[_0x4cd7cf(0x176)]===-0x1*-0x1ba1+-0x1d82+0x1*0x1e1?{}:{'errors':_0x5a3e1f},'branch':_0x192018[_0x4cd7cf(0x163)],'changes':_0x192018[_0x4cd7cf(0x173)][_0x4cd7cf(0x19a)](_0xd08fff),'repositories':[{..._0x192018,'source':_0x4cd7cf(0x1a0),'physicalPath':_0x575485?.[_0x4cd7cf(0x166)]??_0x565ac1[_0x4cd7cf(0x166)],'current':!![],..._0x575485===undefined?{}:{'head':_0x575485[_0x4cd7cf(0x1a8)]},'status':_0x192018[_0x4cd7cf(0x180)]?_0x4cd7cf(0x17c):_0x4cd7cf(0x19c),'locked':_0x575485?.[_0x4cd7cf(0x186)]??![],'prunable':_0x575485?.[_0x4cd7cf(0x17b)]??![]},..._0x5116c0[_0x4cd7cf(0x19a)](_0x1801f9=>({..._0x1801f9,'source':_0x4cd7cf(0x1a4)})),..._0x4b667b][_0x4cd7cf(0x19a)](({dirty:_0x2315c9,..._0xaf746f})=>{const _0xd5c7d5=_0x4cd7cf;return void _0x2315c9,{..._0xaf746f,'changes':_0xaf746f[_0xd5c7d5(0x173)][_0xd5c7d5(0x19a)](_0xd08fff)};}),'worktrees':_0x3f3fec,'worktreesTruncated':_0x4c37c5[_0x4cd7cf(0x158)]};if(_0xb2dc32[_0x4cd7cf(0x181)])nodeLog(_0x4cd7cf(0x16f),{'operation':_0x4cd7cf(0x19d),'workspaceId':_0x565ac1['id'],'partial':!![],'unavailableGroups':_0xb2dc32[_0x4cd7cf(0x199)][_0x4cd7cf(0x18e)](_0x38a345=>_0x38a345[_0x4cd7cf(0x19f)]===_0x4cd7cf(0x179))[_0x4cd7cf(0x176)],'discoveryErrors':_0x5a3e1f[_0x4cd7cf(0x176)],'durationMs':Math[_0x4cd7cf(0x15d)](performance[_0x4cd7cf(0x175)]()-_0x37b585)});if((this[_0x4cd7cf(0x1ab)][_0x4cd7cf(0x16a)][_0x4cd7cf(0x1ae)](_0x565ac1['id'])??-0x2084+0xa9*-0xb+0x257*0x11)===_0x16c916)this[_0x4cd7cf(0x1ab)][_0x4cd7cf(0x178)][_0x4cd7cf(0x194)](_0x565ac1['id'],{'value':_0xb2dc32,'expiresAt':Date[_0x4cd7cf(0x175)]()+CACHE_TTL_MS});return _0xb2dc32;});this[_0x48ecb8(0x1ab)][_0x48ecb8(0x159)][_0x48ecb8(0x194)](_0x565ac1['id'],_0x5d9912);try{return await _0x5d9912;}finally{if(this[_0x48ecb8(0x1ab)][_0x48ecb8(0x159)][_0x48ecb8(0x1ae)](_0x565ac1['id'])===_0x5d9912)this[_0x48ecb8(0x1ab)][_0x48ecb8(0x159)][_0x48ecb8(0x1a2)](_0x565ac1['id']);}}}function _0x5c04(_0x4cb215,_0x367504){_0x4cb215=_0x4cb215-(0x235e*-0x1+0x8f1+0x1bc4*0x1);const _0x516947=_0x49b1();let _0xbac372=_0x516947[_0x4cb215];if(_0x5c04['HKhbii']===undefined){var _0x4eaa7a=function(_0x5f4a0d){const _0x35fcbe='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x800cfa='',_0x26d3d2='';for(let _0x653221=0x2237+0x15*-0x49+-0xe1d*0x2,_0x35983a,_0x541d18,_0x373da4=-0x8af+0x13c3+0x58a*-0x2;_0x541d18=_0x5f4a0d['charAt'](_0x373da4++);~_0x541d18&&(_0x35983a=_0x653221%(-0xadd+-0x1362+0x7f*0x3d)?_0x35983a*(0x7*0x172+0x1dc5+-0x27a3)+_0x541d18:_0x541d18,_0x653221++%(0x8e6*0x1+0xc97*0x3+-0xf8d*0x3))?_0x800cfa+=String['fromCharCode'](0x1f*0x2f+-0x4f*-0x56+0x4*-0x7cf&_0x35983a>>(-(0x49*-0x31+0x60c+-0x1*-0x7ef)*_0x653221&-0x15ad+-0x3cc+0x197f)):-0x119a+-0x23b5+-0x1*-0x354f){_0x541d18=_0x35fcbe['indexOf'](_0x541d18);}for(let _0x4ee7cc=0x47*0x67+0x1*0xb57+-0x27e8,_0x367730=_0x800cfa['length'];_0x4ee7cc<_0x367730;_0x4ee7cc++){_0x26d3d2+='%'+('00'+_0x800cfa['charCodeAt'](_0x4ee7cc)['toString'](0x155+-0x95*-0x30+-0x1d35))['slice'](-(-0x93d+0x6e*-0x31+0x1*0x1e4d));}return decodeURIComponent(_0x26d3d2);};_0x5c04['QnlFUp']=_0x4eaa7a,_0x5c04['aaMaoq']={},_0x5c04['HKhbii']=!![];}const _0x2af2de=_0x516947[-0x1667+-0x4b2*0x3+0x247d];_0x5c04['LDAtpA']!==_0x2af2de&&(_0x5c04['aaMaoq']={},_0x5c04['LDAtpA']=_0x2af2de);const _0x2edfeb=_0x5c04['aaMaoq'][_0x4cb215];return _0x2edfeb===undefined?(_0xbac372=_0x5c04['QnlFUp'](_0xbac372),_0x5c04['aaMaoq'][_0x4cb215]=_0xbac372):_0xbac372=_0x2edfeb,_0xbac372;}async function mapWithConcurrency(_0x1c390e,_0x172f69,_0x491787){const _0x49e990=_0x142df1,_0xcfa875=new Array(_0x1c390e[_0x49e990(0x176)]);let _0x3808d8=0x58d+-0x20f5+0x8*0x36d;return await Promise[_0x49e990(0x17e)](Array[_0x49e990(0x198)]({'length':Math[_0x49e990(0x172)](_0x172f69,_0x1c390e[_0x49e990(0x176)])},async()=>{const _0x1e82ee=_0x49e990;while(_0x3808d8<_0x1c390e[_0x1e82ee(0x176)]){const _0x510627=_0x3808d8;_0x3808d8+=0x22e0+0x1*-0x13eb+-0x84*0x1d,_0xcfa875[_0x510627]=await _0x491787(_0x1c390e[_0x510627]);}})),_0xcfa875;}
|
|
1
|
+
import { lstat } from 'node:fs/promises';
|
|
2
|
+
import { basename, posix, resolve } from 'node:path';
|
|
3
|
+
import { publicErrorMessage } from '@myagentroam/protocol';
|
|
4
|
+
import { nodeLog } from '../operational.js';
|
|
5
|
+
import { GitCommandError, isWorkspaceChangeVisible, listGitWorktrees, listGitSubmodules, readCurrentChangesSummary, resolveGitRepository } from '../workspace.js';
|
|
6
|
+
const CACHE_TTL_MS = 5_000;
|
|
7
|
+
const REPOSITORY_READ_CONCURRENCY = 4;
|
|
8
|
+
const WORKTREE_READ_CONCURRENCY = 4;
|
|
9
|
+
const CHANGE_VISIBILITY_CONCURRENCY = 16;
|
|
10
|
+
const SUBMODULE_LIMIT = 128;
|
|
11
|
+
export class WorkspaceChangeService {
|
|
12
|
+
state;
|
|
13
|
+
constructor(state) {
|
|
14
|
+
this.state = state;
|
|
15
|
+
}
|
|
16
|
+
invalidate(workspaceId) {
|
|
17
|
+
this.state.changesReads.delete(workspaceId);
|
|
18
|
+
this.state.changesCache.delete(workspaceId);
|
|
19
|
+
this.state.changesVersions.set(workspaceId, (this.state.changesVersions.get(workspaceId) ?? 0) + 1);
|
|
20
|
+
}
|
|
21
|
+
clear() {
|
|
22
|
+
this.state.changesReads.clear();
|
|
23
|
+
this.state.changesCache.clear();
|
|
24
|
+
this.state.changesVersions.clear();
|
|
25
|
+
}
|
|
26
|
+
async current(workspace) {
|
|
27
|
+
if (workspace.kind !== 'GIT_WORKSPACE')
|
|
28
|
+
throw new Error('WORKSPACE_NOT_GIT');
|
|
29
|
+
const cached = this.state.changesCache.get(workspace.id);
|
|
30
|
+
if (cached !== undefined && cached.expiresAt > Date.now())
|
|
31
|
+
return cached.value;
|
|
32
|
+
const existing = this.state.changesReads.get(workspace.id);
|
|
33
|
+
if (existing !== undefined)
|
|
34
|
+
return existing;
|
|
35
|
+
const version = this.state.changesVersions.get(workspace.id) ?? 0;
|
|
36
|
+
const request = this.state.changesLimiter.run(async () => {
|
|
37
|
+
const startedAt = performance.now();
|
|
38
|
+
const errors = [];
|
|
39
|
+
const failure = (code, error) => ({
|
|
40
|
+
code,
|
|
41
|
+
message: publicErrorMessage(code),
|
|
42
|
+
...(error instanceof GitCommandError
|
|
43
|
+
? {
|
|
44
|
+
parameters: { gitExitCode: error.code },
|
|
45
|
+
details: `Git command exited with status ${error.code}.`
|
|
46
|
+
}
|
|
47
|
+
: {})
|
|
48
|
+
});
|
|
49
|
+
const report = (source, path, error) => {
|
|
50
|
+
nodeLog('workspace.git-group.unavailable', {
|
|
51
|
+
workspaceId: workspace.id,
|
|
52
|
+
groupKind: source,
|
|
53
|
+
groupPath: path,
|
|
54
|
+
errorCode: error.code,
|
|
55
|
+
...error.parameters,
|
|
56
|
+
durationMs: Math.round(performance.now() - startedAt)
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const discoveryFailure = (source, path, code, error) => {
|
|
60
|
+
const value = failure(code, error);
|
|
61
|
+
if (errors.length < 16)
|
|
62
|
+
errors.push(value);
|
|
63
|
+
report(source, path, value);
|
|
64
|
+
};
|
|
65
|
+
const readRepository = async (repositoryPath, repositoryOverride) => {
|
|
66
|
+
const repository = repositoryOverride ??
|
|
67
|
+
(await resolveGitRepository(workspace.path, repositoryPath, [repositoryPath]));
|
|
68
|
+
if (repositoryPath !== '' || repositoryOverride !== undefined) {
|
|
69
|
+
const marker = await lstat(resolve(repository, '.git'));
|
|
70
|
+
if (marker.isSymbolicLink() || (!marker.isFile() && !marker.isDirectory()))
|
|
71
|
+
throw new Error('GIT_REPOSITORY_UNREADABLE');
|
|
72
|
+
}
|
|
73
|
+
const summary = await readCurrentChangesSummary(repository, true);
|
|
74
|
+
const changes = (await mapWithConcurrency(summary.changes, CHANGE_VISIBILITY_CONCURRENCY, async (change) => ({
|
|
75
|
+
change,
|
|
76
|
+
visible: await isWorkspaceChangeVisible(repository, change.path)
|
|
77
|
+
})))
|
|
78
|
+
.filter(({ visible }) => visible)
|
|
79
|
+
.map(({ change }) => change);
|
|
80
|
+
return {
|
|
81
|
+
repositoryPath,
|
|
82
|
+
repositoryName: repositoryPath === '' ? basename(repository) : posix.basename(repositoryPath),
|
|
83
|
+
branch: summary.branch,
|
|
84
|
+
dirty: summary.changes.length > 0,
|
|
85
|
+
status: summary.changes.length > 0 ? 'DIRTY' : 'CLEAN',
|
|
86
|
+
changes
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
const root = await readRepository('').catch((error) => {
|
|
90
|
+
if (error?.code === 'ENOENT' &&
|
|
91
|
+
error.syscall?.startsWith('spawn') === true)
|
|
92
|
+
throw new Error('GIT_NOT_FOUND');
|
|
93
|
+
throw error;
|
|
94
|
+
});
|
|
95
|
+
const children = [];
|
|
96
|
+
let parents = [''];
|
|
97
|
+
let submodulesLimited = false;
|
|
98
|
+
while (parents.length > 0 && !submodulesLimited) {
|
|
99
|
+
const discovered = await mapWithConcurrency(parents, REPOSITORY_READ_CONCURRENCY, async (parent) => {
|
|
100
|
+
try {
|
|
101
|
+
const path = await resolveGitRepository(workspace.path, parent, [parent]);
|
|
102
|
+
return (await listGitSubmodules(path)).map((entry) => ({
|
|
103
|
+
...entry,
|
|
104
|
+
path: parent === '' ? entry.path : `${parent}/${entry.path}`
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
discoveryFailure('SUBMODULE', parent, 'GIT_SUBMODULE_DISCOVERY_FAILED', error);
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
const candidates = discovered.flat();
|
|
113
|
+
if (children.length + candidates.length > SUBMODULE_LIMIT) {
|
|
114
|
+
candidates.splice(SUBMODULE_LIMIT - children.length);
|
|
115
|
+
submodulesLimited = true;
|
|
116
|
+
discoveryFailure('SUBMODULE', '', 'GIT_SUBMODULE_LIMIT_EXCEEDED', undefined);
|
|
117
|
+
}
|
|
118
|
+
const batch = await mapWithConcurrency(candidates, REPOSITORY_READ_CONCURRENCY, async (entry) => {
|
|
119
|
+
let error;
|
|
120
|
+
if (entry.mapping !== 'MAPPED') {
|
|
121
|
+
error = failure(entry.mapping === 'MISSING'
|
|
122
|
+
? 'GIT_SUBMODULE_MAPPING_MISSING'
|
|
123
|
+
: 'GIT_SUBMODULE_MAPPING_INVALID', entry.gitExitCode === undefined
|
|
124
|
+
? undefined
|
|
125
|
+
: new GitCommandError(entry.gitExitCode, ''));
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
try {
|
|
129
|
+
return await readRepository(entry.path);
|
|
130
|
+
}
|
|
131
|
+
catch (cause) {
|
|
132
|
+
error = failure('GIT_REPOSITORY_UNREADABLE', cause);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
report('SUBMODULE', entry.path, error);
|
|
136
|
+
return {
|
|
137
|
+
repositoryPath: entry.path,
|
|
138
|
+
repositoryName: posix.basename(entry.path),
|
|
139
|
+
branch: null,
|
|
140
|
+
dirty: false,
|
|
141
|
+
status: 'UNAVAILABLE',
|
|
142
|
+
changes: [],
|
|
143
|
+
error
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
children.push(...batch);
|
|
147
|
+
parents = batch
|
|
148
|
+
.filter((entry) => entry.status !== 'UNAVAILABLE')
|
|
149
|
+
.map((entry) => entry.repositoryPath);
|
|
150
|
+
}
|
|
151
|
+
children.sort((left, right) => left.repositoryPath.localeCompare(right.repositoryPath));
|
|
152
|
+
const worktreeList = await listGitWorktrees(workspace.path).catch((error) => {
|
|
153
|
+
discoveryFailure('WORKTREE', '', 'GIT_WORKTREE_DISCOVERY_FAILED', error);
|
|
154
|
+
return { entries: [], truncated: false };
|
|
155
|
+
});
|
|
156
|
+
const linkedWorktrees = worktreeList.entries.filter((worktree) => !worktree.current);
|
|
157
|
+
const linkedRepositories = await mapWithConcurrency(linkedWorktrees, WORKTREE_READ_CONCURRENCY, async (worktree) => {
|
|
158
|
+
const metadata = {
|
|
159
|
+
repositoryPath: '',
|
|
160
|
+
repositoryName: worktree.directoryName,
|
|
161
|
+
source: 'WORKTREE',
|
|
162
|
+
worktreePath: worktree.path,
|
|
163
|
+
physicalPath: worktree.path,
|
|
164
|
+
current: false,
|
|
165
|
+
branch: worktree.branch,
|
|
166
|
+
head: worktree.head,
|
|
167
|
+
locked: worktree.locked,
|
|
168
|
+
prunable: worktree.prunable
|
|
169
|
+
};
|
|
170
|
+
if (worktree.prunable) {
|
|
171
|
+
const error = failure('GIT_REPOSITORY_UNREADABLE');
|
|
172
|
+
report('WORKTREE', worktree.directoryName, error);
|
|
173
|
+
return {
|
|
174
|
+
...metadata,
|
|
175
|
+
dirty: false,
|
|
176
|
+
status: 'UNAVAILABLE',
|
|
177
|
+
error,
|
|
178
|
+
changes: []
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
const repository = await readRepository('', worktree.path);
|
|
183
|
+
return {
|
|
184
|
+
...metadata,
|
|
185
|
+
dirty: repository.dirty,
|
|
186
|
+
branch: repository.branch,
|
|
187
|
+
status: repository.dirty ? 'DIRTY' : 'CLEAN',
|
|
188
|
+
changes: repository.changes
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
catch (cause) {
|
|
192
|
+
const error = failure('GIT_REPOSITORY_UNREADABLE', cause);
|
|
193
|
+
report('WORKTREE', worktree.directoryName, error);
|
|
194
|
+
return {
|
|
195
|
+
...metadata,
|
|
196
|
+
dirty: false,
|
|
197
|
+
status: 'UNAVAILABLE',
|
|
198
|
+
error,
|
|
199
|
+
changes: []
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
const currentWorktree = worktreeList.entries.find((worktree) => worktree.current);
|
|
204
|
+
const worktrees = worktreeList.entries.map((worktree) => {
|
|
205
|
+
const linked = linkedRepositories.find((repository) => repository.worktreePath === worktree.path);
|
|
206
|
+
return {
|
|
207
|
+
directoryName: worktree.directoryName,
|
|
208
|
+
branch: worktree.branch,
|
|
209
|
+
head: worktree.head,
|
|
210
|
+
current: worktree.current,
|
|
211
|
+
status: worktree.current
|
|
212
|
+
? root.dirty
|
|
213
|
+
? 'DIRTY'
|
|
214
|
+
: 'CLEAN'
|
|
215
|
+
: (linked?.status ?? 'UNAVAILABLE'),
|
|
216
|
+
locked: worktree.locked,
|
|
217
|
+
prunable: worktree.prunable
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
const decorate = (change) => ({
|
|
221
|
+
...change,
|
|
222
|
+
additions: null,
|
|
223
|
+
deletions: null,
|
|
224
|
+
binary: false,
|
|
225
|
+
diffAvailable: true
|
|
226
|
+
});
|
|
227
|
+
const value = {
|
|
228
|
+
partial: errors.length > 0 ||
|
|
229
|
+
children.some((group) => group.status === 'UNAVAILABLE') ||
|
|
230
|
+
linkedRepositories.some((group) => group.status === 'UNAVAILABLE') ||
|
|
231
|
+
worktreeList.truncated,
|
|
232
|
+
...(errors.length === 0 ? {} : { errors }),
|
|
233
|
+
branch: root.branch,
|
|
234
|
+
changes: root.changes.map(decorate),
|
|
235
|
+
repositories: [
|
|
236
|
+
{
|
|
237
|
+
...root,
|
|
238
|
+
source: 'ROOT',
|
|
239
|
+
physicalPath: currentWorktree?.path ?? workspace.path,
|
|
240
|
+
current: true,
|
|
241
|
+
...(currentWorktree === undefined ? {} : { head: currentWorktree.head }),
|
|
242
|
+
status: root.dirty ? 'DIRTY' : 'CLEAN',
|
|
243
|
+
locked: currentWorktree?.locked ?? false,
|
|
244
|
+
prunable: currentWorktree?.prunable ?? false
|
|
245
|
+
},
|
|
246
|
+
...children.map((repository) => ({ ...repository, source: 'SUBMODULE' })),
|
|
247
|
+
...linkedRepositories
|
|
248
|
+
].map(({ dirty: _dirty, ...repository }) => {
|
|
249
|
+
void _dirty;
|
|
250
|
+
return { ...repository, changes: repository.changes.map(decorate) };
|
|
251
|
+
}),
|
|
252
|
+
worktrees,
|
|
253
|
+
worktreesTruncated: worktreeList.truncated
|
|
254
|
+
};
|
|
255
|
+
if (value.partial)
|
|
256
|
+
nodeLog('workspace.changes.completed', {
|
|
257
|
+
operation: 'workspace.changes.current',
|
|
258
|
+
workspaceId: workspace.id,
|
|
259
|
+
partial: true,
|
|
260
|
+
unavailableGroups: value.repositories.filter((group) => group.status === 'UNAVAILABLE')
|
|
261
|
+
.length,
|
|
262
|
+
discoveryErrors: errors.length,
|
|
263
|
+
durationMs: Math.round(performance.now() - startedAt)
|
|
264
|
+
});
|
|
265
|
+
if ((this.state.changesVersions.get(workspace.id) ?? 0) === version)
|
|
266
|
+
this.state.changesCache.set(workspace.id, { value, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
267
|
+
return value;
|
|
268
|
+
});
|
|
269
|
+
this.state.changesReads.set(workspace.id, request);
|
|
270
|
+
try {
|
|
271
|
+
return await request;
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
if (this.state.changesReads.get(workspace.id) === request)
|
|
275
|
+
this.state.changesReads.delete(workspace.id);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
async function mapWithConcurrency(values, concurrency, project) {
|
|
280
|
+
const output = new Array(values.length);
|
|
281
|
+
let nextIndex = 0;
|
|
282
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, values.length) }, async () => {
|
|
283
|
+
while (nextIndex < values.length) {
|
|
284
|
+
const index = nextIndex;
|
|
285
|
+
nextIndex += 1;
|
|
286
|
+
output[index] = await project(values[index]);
|
|
287
|
+
}
|
|
288
|
+
}));
|
|
289
|
+
return output;
|
|
290
|
+
}
|