@bbigbang/core 0.1.0

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.
Files changed (175) hide show
  1. package/dist/config.js +380 -0
  2. package/dist/execution/executionDispatcher.js +3810 -0
  3. package/dist/main.js +90 -0
  4. package/dist/nodeEventHistory.js +206 -0
  5. package/dist/scheduler/dreamLogic.js +50 -0
  6. package/dist/scheduler/dreamScheduler.js +65 -0
  7. package/dist/services/agentFileAccessService.js +1913 -0
  8. package/dist/services/agentRuntimeCleanupBroker.js +62 -0
  9. package/dist/services/agentSkillsBroker.js +118 -0
  10. package/dist/services/agentSkillsService.js +83 -0
  11. package/dist/services/agentWorkspaceBroker.js +937 -0
  12. package/dist/services/agentWorkspaceService.js +70 -0
  13. package/dist/services/appVersion.js +14 -0
  14. package/dist/services/auth.js +586 -0
  15. package/dist/services/claudeControlBroker.js +154 -0
  16. package/dist/services/claudeTranscriptBroker.js +100 -0
  17. package/dist/services/claudeTranscriptService.js +359 -0
  18. package/dist/services/codexAppServerBroker.js +155 -0
  19. package/dist/services/codexTranscriptBroker.js +98 -0
  20. package/dist/services/codexTranscriptService.js +961 -0
  21. package/dist/services/droidMissionBroker.js +124 -0
  22. package/dist/services/droidMissionImporter.js +630 -0
  23. package/dist/services/droidModelOptions.js +165 -0
  24. package/dist/services/hubServerRegistrationService.js +268 -0
  25. package/dist/services/libraryManifest.js +43 -0
  26. package/dist/services/libraryScaffold.js +26 -0
  27. package/dist/services/libraryService.js +2263 -0
  28. package/dist/services/memoryService.js +386 -0
  29. package/dist/services/missionEvidence.js +377 -0
  30. package/dist/services/missionService.js +2361 -0
  31. package/dist/services/missionTrace.js +158 -0
  32. package/dist/services/nativeMissionBriefParser.js +120 -0
  33. package/dist/services/nativeMissionOrchestrator.js +2045 -0
  34. package/dist/services/nativeMissionReportGenerator.js +227 -0
  35. package/dist/services/nativeMissionValidationRunner.js +452 -0
  36. package/dist/services/nativeMissionWorkerBroker.js +190 -0
  37. package/dist/services/nodeRegistry.js +34 -0
  38. package/dist/services/nodeStateReconciler.js +97 -0
  39. package/dist/services/panelMediaScanner.js +119 -0
  40. package/dist/services/persistentRuntimeJsonlClient.js +153 -0
  41. package/dist/services/platformAgentPolicy.js +180 -0
  42. package/dist/services/platformAgentService.js +2041 -0
  43. package/dist/services/projectAccessResolver.js +93 -0
  44. package/dist/services/projectService.js +392 -0
  45. package/dist/services/resourceSpaceService.js +140 -0
  46. package/dist/services/scenarioRuntimeService.js +1130 -0
  47. package/dist/services/suggestedPlannerService.js +868 -0
  48. package/dist/services/workbenchGitBroker.js +161 -0
  49. package/dist/services/workbenchGitService.js +69 -0
  50. package/dist/services/workbenchInspectBroker.js +65 -0
  51. package/dist/services/workbenchNodePathService.js +79 -0
  52. package/dist/services/workbenchRegistryService.js +240 -0
  53. package/dist/services/workbenchRootService.js +181 -0
  54. package/dist/services/workbenchTerminalBroker.js +378 -0
  55. package/dist/services/workspaceRunOwnership.js +60 -0
  56. package/dist/services/workspaceScaffold.js +105 -0
  57. package/dist/services/workspaceSessionRuntimeService.js +576 -0
  58. package/dist/services/workspaceSessionService.js +245 -0
  59. package/dist/services/workspaceToolActionRunner.js +1582 -0
  60. package/dist/services/workspaceToolErrors.js +10 -0
  61. package/dist/services/workspaceToolExecutionUtils.js +895 -0
  62. package/dist/services/workspaceToolLatestStateProjector.js +91 -0
  63. package/dist/services/workspaceToolManifest.js +572 -0
  64. package/dist/services/workspaceToolMutationQueue.js +43 -0
  65. package/dist/services/workspaceToolPanelProjection.js +460 -0
  66. package/dist/services/workspaceToolPromotion.js +255 -0
  67. package/dist/services/workspaceToolPromotionState.js +224 -0
  68. package/dist/services/workspaceToolPublishDiagnostics.js +189 -0
  69. package/dist/services/workspaceToolPublishIdentityResolver.js +146 -0
  70. package/dist/services/workspaceToolReadModel.js +378 -0
  71. package/dist/services/workspaceToolRunLedger.js +239 -0
  72. package/dist/services/workspaceToolService.js +3067 -0
  73. package/dist/services/workspaceToolSnapshotPanelSync.js +293 -0
  74. package/dist/services/workspaceToolTerminalLifecycle.js +283 -0
  75. package/dist/services/workspaceToolTypes.js +1 -0
  76. package/dist/services/workspaceToolUploadMaterializer.js +228 -0
  77. package/dist/web/actionCardRoutes.js +129 -0
  78. package/dist/web/actionCards.js +469 -0
  79. package/dist/web/activationContext.js +684 -0
  80. package/dist/web/agentChannelGuards.js +48 -0
  81. package/dist/web/agentMentionCooldowns.js +32 -0
  82. package/dist/web/agentReminders.js +1668 -0
  83. package/dist/web/agentRuntimePresence.js +197 -0
  84. package/dist/web/agentSelfState.js +494 -0
  85. package/dist/web/agentTaskLinks.js +26 -0
  86. package/dist/web/agentVisibility.js +79 -0
  87. package/dist/web/assets.js +95 -0
  88. package/dist/web/channelActivationPrompt.js +395 -0
  89. package/dist/web/channelMemoryNotes.js +127 -0
  90. package/dist/web/channelMentions.js +10 -0
  91. package/dist/web/channelMessageSequences.js +19 -0
  92. package/dist/web/channelSubscriptions.js +26 -0
  93. package/dist/web/clearedTaskRoots.js +10 -0
  94. package/dist/web/collaborationPromptGuidance.js +36 -0
  95. package/dist/web/collaborationSurfaceState.js +140 -0
  96. package/dist/web/contextBundleRanking.js +154 -0
  97. package/dist/web/contextBundleResolver.js +488 -0
  98. package/dist/web/conversationBuiltinSkillRoots.js +50 -0
  99. package/dist/web/conversationControls.js +232 -0
  100. package/dist/web/conversationHandoffs.js +612 -0
  101. package/dist/web/conversationManager.js +2511 -0
  102. package/dist/web/conversationSummaries.js +876 -0
  103. package/dist/web/conversationSurfaceKinds.js +17 -0
  104. package/dist/web/conversationTargets.js +173 -0
  105. package/dist/web/directActivationPrompt.js +122 -0
  106. package/dist/web/directReplyTargets.js +69 -0
  107. package/dist/web/directThreadResolver.js +129 -0
  108. package/dist/web/dmTaskHandoffPrompt.js +120 -0
  109. package/dist/web/dmTaskThreadStatusProjection.js +229 -0
  110. package/dist/web/ftsQuery.js +33 -0
  111. package/dist/web/internalAgentRouter.js +11341 -0
  112. package/dist/web/libraryCuratorScheduler.js +58 -0
  113. package/dist/web/libraryDocumentPromptGuidance.js +8 -0
  114. package/dist/web/messageCheckpoints.js +19 -0
  115. package/dist/web/nodeWsHandler.js +2495 -0
  116. package/dist/web/notificationRounds.js +1061 -0
  117. package/dist/web/panelActionMessages.js +108 -0
  118. package/dist/web/panelActivationPrompt.js +18 -0
  119. package/dist/web/panelAudit.js +273 -0
  120. package/dist/web/panelLifecycle.js +222 -0
  121. package/dist/web/panelMediaPolicy.js +43 -0
  122. package/dist/web/panelPathPolicy.js +63 -0
  123. package/dist/web/panelPreviews.js +175 -0
  124. package/dist/web/panelQueryHandles.js +2749 -0
  125. package/dist/web/panelRoutes.js +2147 -0
  126. package/dist/web/panels.js +904 -0
  127. package/dist/web/peerInboxAggregates.js +1247 -0
  128. package/dist/web/planApprovalState.js +92 -0
  129. package/dist/web/platformAgentScheduler.js +66 -0
  130. package/dist/web/proactiveOpportunities.js +452 -0
  131. package/dist/web/promptContextSections.js +242 -0
  132. package/dist/web/promptHistorySanitizer.js +26 -0
  133. package/dist/web/promptSlashCommands.js +158 -0
  134. package/dist/web/rollingConversationSummary.js +453 -0
  135. package/dist/web/routeHelpers.js +11 -0
  136. package/dist/web/routes/handoff.js +288 -0
  137. package/dist/web/routes/history.js +345 -0
  138. package/dist/web/routes/memory.js +258 -0
  139. package/dist/web/routes/selfState.js +171 -0
  140. package/dist/web/routes/workspace.js +154 -0
  141. package/dist/web/runSurfaceWatermarks.js +431 -0
  142. package/dist/web/runtimeCapabilities.js +48 -0
  143. package/dist/web/sameAgentHandoffs.js +494 -0
  144. package/dist/web/server.js +15567 -0
  145. package/dist/web/sharedCollaborationCapsules.js +163 -0
  146. package/dist/web/soloSessionRelay.js +42 -0
  147. package/dist/web/soloWsHandler.js +138 -0
  148. package/dist/web/suggestedPlannerScheduler.js +56 -0
  149. package/dist/web/surfaceActivationPolicy.js +108 -0
  150. package/dist/web/surfaceCollaborators.js +61 -0
  151. package/dist/web/surfaceSystemStatus.js +263 -0
  152. package/dist/web/targetParticipants.js +77 -0
  153. package/dist/web/taskEvents.js +49 -0
  154. package/dist/web/taskLifecycleMessages.js +165 -0
  155. package/dist/web/taskLoops.js +732 -0
  156. package/dist/web/taskMemoryNotes.js +224 -0
  157. package/dist/web/taskNumbers.js +16 -0
  158. package/dist/web/taskOwnerGuards.js +49 -0
  159. package/dist/web/taskParticipantResolver.js +42 -0
  160. package/dist/web/taskParticipants.js +97 -0
  161. package/dist/web/taskSourceDetails.js +20 -0
  162. package/dist/web/taskStateViews.js +210 -0
  163. package/dist/web/taskStatusTransitions.js +9 -0
  164. package/dist/web/taskThreadFollowups.js +599 -0
  165. package/dist/web/taskThreadRuntimeClosure.js +685 -0
  166. package/dist/web/taskUpdateDelivery.js +104 -0
  167. package/dist/web/threadReplyContentHeuristics.js +30 -0
  168. package/dist/web/threadRoots.js +61 -0
  169. package/dist/web/threadTaskBindings.js +365 -0
  170. package/dist/web/uiPanelPromptGuidance.js +27 -0
  171. package/dist/web/workspaceMemoryHints.js +143 -0
  172. package/dist/web/workspaceToolPromptGuidance.js +30 -0
  173. package/dist/web/wsHandler.js +397 -0
  174. package/dist/web/wsSink.js +116 -0
  175. package/package.json +54 -0
@@ -0,0 +1,937 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { PassThrough } from 'node:stream';
3
+ export class AgentWorkspaceBroker {
4
+ pending = new Map();
5
+ nodeRegistry;
6
+ timeoutMs;
7
+ libraryMirrorTimeoutMs;
8
+ constructor(params) {
9
+ this.nodeRegistry = params.nodeRegistry;
10
+ this.timeoutMs = params.timeoutMs ?? 5_000;
11
+ this.libraryMirrorTimeoutMs = params.libraryMirrorTimeoutMs ?? Math.max(this.timeoutMs, 60_000);
12
+ }
13
+ listDirectory(nodeId, workspaceRoot, relativePath, options) {
14
+ const requestId = randomUUID();
15
+ const timeoutMs = typeof options?.timeoutMs === 'number' && Number.isFinite(options.timeoutMs) && options.timeoutMs > 0
16
+ ? options.timeoutMs
17
+ : this.timeoutMs;
18
+ return new Promise((resolve, reject) => {
19
+ const timer = setTimeout(() => {
20
+ this.pending.delete(requestId);
21
+ reject(new Error('Workspace request timed out.'));
22
+ }, timeoutMs);
23
+ this.pending.set(requestId, {
24
+ kind: 'list',
25
+ nodeId,
26
+ resolve,
27
+ reject,
28
+ timer,
29
+ });
30
+ const sent = this.nodeRegistry.send(nodeId, {
31
+ type: 'workspace.list.request',
32
+ requestId,
33
+ workspaceRoot,
34
+ relativePath,
35
+ ...(options?.runId?.trim() ? { runId: options.runId.trim() } : {}),
36
+ ...(options?.scaffold === false ? { scaffold: false } : {}),
37
+ ...(options?.agentName?.trim() ? { agentName: options.agentName.trim() } : {}),
38
+ ...(options?.cursor ? { cursor: options.cursor } : {}),
39
+ ...(typeof options?.limit === 'number' ? { limit: options.limit } : {}),
40
+ });
41
+ if (!sent) {
42
+ clearTimeout(timer);
43
+ this.pending.delete(requestId);
44
+ reject(new Error('Agent node is offline.'));
45
+ }
46
+ });
47
+ }
48
+ readFile(nodeId, workspaceRoot, relativePath, options) {
49
+ const requestId = randomUUID();
50
+ return new Promise((resolve, reject) => {
51
+ const timer = setTimeout(() => {
52
+ this.pending.delete(requestId);
53
+ reject(new Error('Workspace request timed out.'));
54
+ }, this.timeoutMs);
55
+ this.pending.set(requestId, {
56
+ kind: 'read',
57
+ nodeId,
58
+ resolve,
59
+ reject,
60
+ timer,
61
+ });
62
+ const sent = this.nodeRegistry.send(nodeId, {
63
+ type: 'workspace.read.request',
64
+ requestId,
65
+ workspaceRoot,
66
+ relativePath,
67
+ ...(options?.runId?.trim() ? { runId: options.runId.trim() } : {}),
68
+ ...(options?.scaffold === false ? { scaffold: false } : {}),
69
+ ...(options?.agentName?.trim() ? { agentName: options.agentName.trim() } : {}),
70
+ ...(typeof options?.offset === 'number' ? { offset: options.offset } : {}),
71
+ ...(typeof options?.limit === 'number' ? { limit: options.limit } : {}),
72
+ });
73
+ if (!sent) {
74
+ clearTimeout(timer);
75
+ this.pending.delete(requestId);
76
+ reject(new Error('Agent node is offline.'));
77
+ }
78
+ });
79
+ }
80
+ archiveDirectory(nodeId, workspaceRoot, relativePath, options) {
81
+ const requestId = randomUUID();
82
+ const timeoutMs = typeof options?.timeoutMs === 'number' && Number.isFinite(options.timeoutMs) && options.timeoutMs > 0
83
+ ? options.timeoutMs
84
+ : Math.max(this.timeoutMs, 60_000);
85
+ return new Promise((resolve, reject) => {
86
+ const timer = setTimeout(() => {
87
+ this.pending.delete(requestId);
88
+ reject(new Error('Workspace archive request timed out.'));
89
+ }, timeoutMs);
90
+ this.pending.set(requestId, {
91
+ kind: 'archive',
92
+ nodeId,
93
+ resolve,
94
+ reject,
95
+ timer,
96
+ });
97
+ const sent = this.nodeRegistry.send(nodeId, {
98
+ type: 'workspace.archive.request',
99
+ requestId,
100
+ workspaceRoot,
101
+ relativePath,
102
+ ...(typeof options?.maxBytes === 'number' ? { maxBytes: options.maxBytes } : {}),
103
+ });
104
+ if (!sent) {
105
+ clearTimeout(timer);
106
+ this.pending.delete(requestId);
107
+ reject(new Error('Agent node is offline.'));
108
+ }
109
+ });
110
+ }
111
+ extractDirectoryArchive(nodeId, workspaceRoot, relativePath, archiveBase64, options) {
112
+ const requestId = randomUUID();
113
+ const timeoutMs = typeof options?.timeoutMs === 'number' && Number.isFinite(options.timeoutMs) && options.timeoutMs > 0
114
+ ? options.timeoutMs
115
+ : Math.max(this.timeoutMs, 60_000);
116
+ return new Promise((resolve, reject) => {
117
+ const timer = setTimeout(() => {
118
+ this.pending.delete(requestId);
119
+ reject(new Error('Workspace extract request timed out.'));
120
+ }, timeoutMs);
121
+ this.pending.set(requestId, {
122
+ kind: 'extract',
123
+ nodeId,
124
+ resolve,
125
+ reject,
126
+ timer,
127
+ });
128
+ const sent = this.nodeRegistry.send(nodeId, {
129
+ type: 'workspace.extract.request',
130
+ requestId,
131
+ workspaceRoot,
132
+ relativePath,
133
+ archiveBase64,
134
+ ...(options?.overwrite === true ? { overwrite: true } : {}),
135
+ ...(typeof options?.maxBytes === 'number' ? { maxBytes: options.maxBytes } : {}),
136
+ });
137
+ if (!sent) {
138
+ clearTimeout(timer);
139
+ this.pending.delete(requestId);
140
+ reject(new Error('Agent node is offline.'));
141
+ }
142
+ });
143
+ }
144
+ readExactPath(nodeId, absolutePath, options = {}) {
145
+ const requestId = randomUUID();
146
+ return new Promise((resolve, reject) => {
147
+ const timer = setTimeout(() => {
148
+ this.pending.delete(requestId);
149
+ reject(new Error('Workspace request timed out.'));
150
+ }, this.timeoutMs);
151
+ this.pending.set(requestId, {
152
+ kind: 'read-path',
153
+ nodeId,
154
+ resolve,
155
+ reject,
156
+ timer,
157
+ });
158
+ const sent = this.nodeRegistry.send(nodeId, {
159
+ type: 'fs.read_path.request',
160
+ requestId,
161
+ absolutePath,
162
+ ...(options.allowedRoot ? { allowedRoot: options.allowedRoot } : {}),
163
+ ...(options.trustedRoot ? { trustedRoot: options.trustedRoot } : {}),
164
+ ...(options.cursor ? { cursor: options.cursor } : {}),
165
+ ...(typeof options.offset === 'number' ? { offset: options.offset } : {}),
166
+ ...(typeof options.limit === 'number' ? { limit: options.limit } : {}),
167
+ ...(typeof options.maxPreviewBytes === 'number' ? { maxPreviewBytes: options.maxPreviewBytes } : {}),
168
+ ...(options.rawContentBase64 ? { rawContentBase64: true } : {}),
169
+ });
170
+ if (!sent) {
171
+ clearTimeout(timer);
172
+ this.pending.delete(requestId);
173
+ reject(new Error('Agent node is offline.'));
174
+ }
175
+ });
176
+ }
177
+ suggestPaths(nodeId, query, options = {}) {
178
+ const requestId = randomUUID();
179
+ return new Promise((resolve, reject) => {
180
+ const timer = setTimeout(() => {
181
+ this.pending.delete(requestId);
182
+ reject(new Error('Workspace request timed out.'));
183
+ }, this.timeoutMs);
184
+ this.pending.set(requestId, {
185
+ kind: 'path-suggest',
186
+ nodeId,
187
+ resolve,
188
+ reject,
189
+ timer,
190
+ });
191
+ const sent = this.nodeRegistry.send(nodeId, {
192
+ type: 'fs.path_suggest.request',
193
+ requestId,
194
+ query,
195
+ ...(typeof options.limit === 'number' ? { limit: options.limit } : {}),
196
+ });
197
+ if (!sent) {
198
+ clearTimeout(timer);
199
+ this.pending.delete(requestId);
200
+ reject(new Error('Agent node is offline.'));
201
+ }
202
+ });
203
+ }
204
+ fetchHttpText(nodeId, url, options = {}) {
205
+ const requestId = randomUUID();
206
+ const timeoutMs = typeof options.timeoutMs === 'number' && Number.isFinite(options.timeoutMs) && options.timeoutMs > 0
207
+ ? options.timeoutMs
208
+ : this.timeoutMs;
209
+ return new Promise((resolve, reject) => {
210
+ const timer = setTimeout(() => {
211
+ this.pending.delete(requestId);
212
+ reject(new Error('HTTP fetch request timed out.'));
213
+ }, timeoutMs);
214
+ this.pending.set(requestId, {
215
+ kind: 'http-fetch-text',
216
+ nodeId,
217
+ resolve,
218
+ reject,
219
+ timer,
220
+ });
221
+ const sent = this.nodeRegistry.send(nodeId, {
222
+ type: 'http.fetch_text.request',
223
+ requestId,
224
+ url,
225
+ ...(typeof options.maxBytes === 'number' ? { maxBytes: options.maxBytes } : {}),
226
+ ...(typeof options.authProfile === 'string' && options.authProfile.trim() ? { authProfile: options.authProfile.trim() } : {}),
227
+ ...(typeof options.ifNoneMatch === 'string' && options.ifNoneMatch.trim() ? { ifNoneMatch: options.ifNoneMatch.trim() } : {}),
228
+ ...(typeof options.ifModifiedSince === 'string' && options.ifModifiedSince.trim() ? { ifModifiedSince: options.ifModifiedSince.trim() } : {}),
229
+ ...(typeof options.ifRange === 'string' && options.ifRange.trim() ? { ifRange: options.ifRange.trim() } : {}),
230
+ ...(typeof options.rangeStart === 'number' && Number.isInteger(options.rangeStart) && options.rangeStart >= 0 ? { rangeStart: options.rangeStart } : {}),
231
+ ...(typeof options.rangeLength === 'number' && Number.isInteger(options.rangeLength) && options.rangeLength > 0 ? { rangeLength: options.rangeLength } : {}),
232
+ });
233
+ if (!sent) {
234
+ clearTimeout(timer);
235
+ this.pending.delete(requestId);
236
+ reject(new Error('Agent node is offline.'));
237
+ }
238
+ });
239
+ }
240
+ proxyWorkspaceService(nodeId, url, options = {}) {
241
+ const requestId = randomUUID();
242
+ const timeoutMs = typeof options.timeoutMs === 'number' && Number.isFinite(options.timeoutMs) && options.timeoutMs > 0
243
+ ? options.timeoutMs
244
+ : this.timeoutMs;
245
+ return new Promise((resolve, reject) => {
246
+ const timer = setTimeout(() => {
247
+ this.pending.delete(requestId);
248
+ reject(new Error('Workspace service proxy request timed out.'));
249
+ }, timeoutMs);
250
+ this.pending.set(requestId, {
251
+ kind: 'workspace-service-proxy',
252
+ nodeId,
253
+ resolve,
254
+ reject,
255
+ timer,
256
+ });
257
+ const sent = this.nodeRegistry.send(nodeId, {
258
+ type: 'workspace.service_proxy.request',
259
+ requestId,
260
+ url,
261
+ ...(options.method ? { method: options.method } : {}),
262
+ ...(options.headers ? { headers: options.headers } : {}),
263
+ ...(typeof options.body === 'string' ? { body: options.body } : {}),
264
+ ...(typeof options.maxBytes === 'number' ? { maxBytes: options.maxBytes } : {}),
265
+ });
266
+ if (!sent) {
267
+ clearTimeout(timer);
268
+ this.pending.delete(requestId);
269
+ reject(new Error('Agent node is offline.'));
270
+ }
271
+ });
272
+ }
273
+ streamExactPath(nodeId, absolutePath, options = {}) {
274
+ const requestId = randomUUID();
275
+ const stream = new PassThrough();
276
+ stream.on('error', () => {
277
+ // Keep broker-created streams from surfacing as unhandled errors before
278
+ // Fastify has attached its own response pipeline listeners.
279
+ });
280
+ return new Promise((resolve, reject) => {
281
+ const timer = setTimeout(() => {
282
+ this.failStreamRequest(requestId, new Error('Workspace stream request timed out.'));
283
+ }, Math.min(this.timeoutMs, 2_000));
284
+ this.pending.set(requestId, {
285
+ kind: 'read-path-stream',
286
+ nodeId,
287
+ resolve,
288
+ reject,
289
+ timer,
290
+ stream,
291
+ started: false,
292
+ });
293
+ const sent = this.nodeRegistry.send(nodeId, {
294
+ type: 'fs.read_path.stream.request',
295
+ requestId,
296
+ absolutePath,
297
+ ...(options.allowedRoot ? { allowedRoot: options.allowedRoot } : {}),
298
+ });
299
+ if (!sent) {
300
+ clearTimeout(timer);
301
+ this.pending.delete(requestId);
302
+ stream.destroy();
303
+ reject(new Error('Agent node is offline.'));
304
+ }
305
+ });
306
+ }
307
+ writeFile(nodeId, workspaceRoot, relativePath, content, mode, options) {
308
+ const requestId = randomUUID();
309
+ return new Promise((resolve, reject) => {
310
+ const timer = setTimeout(() => {
311
+ this.pending.delete(requestId);
312
+ reject(new Error('Workspace write request timed out.'));
313
+ }, this.timeoutMs);
314
+ this.pending.set(requestId, {
315
+ kind: 'write',
316
+ nodeId,
317
+ resolve,
318
+ reject,
319
+ timer,
320
+ });
321
+ const sent = this.nodeRegistry.send(nodeId, {
322
+ type: 'workspace.write.request',
323
+ requestId,
324
+ workspaceRoot,
325
+ relativePath,
326
+ content,
327
+ mode,
328
+ ...(options?.contentEncoding ? { contentEncoding: options.contentEncoding } : {}),
329
+ ...(options?.scaffold === false ? { scaffold: false } : {}),
330
+ ...(options?.agentName?.trim() ? { agentName: options.agentName.trim() } : {}),
331
+ });
332
+ if (!sent) {
333
+ clearTimeout(timer);
334
+ this.pending.delete(requestId);
335
+ reject(new Error('Agent node is offline.'));
336
+ }
337
+ });
338
+ }
339
+ deleteFile(nodeId, workspaceRoot, relativePath) {
340
+ const requestId = randomUUID();
341
+ return new Promise((resolve, reject) => {
342
+ const timer = setTimeout(() => {
343
+ this.pending.delete(requestId);
344
+ reject(new Error('Workspace delete request timed out.'));
345
+ }, this.timeoutMs);
346
+ this.pending.set(requestId, {
347
+ kind: 'delete-file',
348
+ nodeId,
349
+ resolve,
350
+ reject,
351
+ timer,
352
+ });
353
+ const sent = this.nodeRegistry.send(nodeId, {
354
+ type: 'workspace.delete_file.request',
355
+ requestId,
356
+ workspaceRoot,
357
+ relativePath,
358
+ });
359
+ if (!sent) {
360
+ clearTimeout(timer);
361
+ this.pending.delete(requestId);
362
+ reject(new Error('Agent node is offline.'));
363
+ }
364
+ });
365
+ }
366
+ deletePath(nodeId, workspaceRoot, relativePath, options) {
367
+ const requestId = randomUUID();
368
+ return new Promise((resolve, reject) => {
369
+ const timer = setTimeout(() => {
370
+ this.pending.delete(requestId);
371
+ reject(new Error('Workspace delete request timed out.'));
372
+ }, this.timeoutMs);
373
+ this.pending.set(requestId, {
374
+ kind: 'delete-path',
375
+ nodeId,
376
+ resolve,
377
+ reject,
378
+ timer,
379
+ });
380
+ const sent = this.nodeRegistry.send(nodeId, {
381
+ type: 'workspace.delete_path.request',
382
+ requestId,
383
+ workspaceRoot,
384
+ relativePath,
385
+ ...(options?.recursive === true ? { recursive: true } : {}),
386
+ });
387
+ if (!sent) {
388
+ clearTimeout(timer);
389
+ this.pending.delete(requestId);
390
+ reject(new Error('Agent node is offline.'));
391
+ }
392
+ });
393
+ }
394
+ resetWorkspace(nodeId, workspaceRoot, options) {
395
+ const requestId = randomUUID();
396
+ return new Promise((resolve, reject) => {
397
+ const timer = setTimeout(() => {
398
+ this.pending.delete(requestId);
399
+ reject(new Error('Workspace reset timed out.'));
400
+ }, this.timeoutMs);
401
+ this.pending.set(requestId, {
402
+ kind: 'reset',
403
+ nodeId,
404
+ resolve,
405
+ reject,
406
+ timer,
407
+ });
408
+ const sent = this.nodeRegistry.send(nodeId, {
409
+ type: 'workspace.reset.request',
410
+ requestId,
411
+ workspaceRoot,
412
+ ...(options?.agentName?.trim() ? { agentName: options.agentName.trim() } : {}),
413
+ });
414
+ if (!sent) {
415
+ clearTimeout(timer);
416
+ this.pending.delete(requestId);
417
+ reject(new Error('Agent node is offline.'));
418
+ }
419
+ });
420
+ }
421
+ applyLibraryMirror(nodeId, workspaceRoot, mirror) {
422
+ const requestId = randomUUID();
423
+ return new Promise((resolve, reject) => {
424
+ const timer = setTimeout(() => {
425
+ this.pending.delete(requestId);
426
+ reject(new Error('Library mirror apply timed out.'));
427
+ }, this.libraryMirrorTimeoutMs);
428
+ this.pending.set(requestId, {
429
+ kind: 'library-mirror-apply',
430
+ nodeId,
431
+ resolve,
432
+ reject,
433
+ timer,
434
+ });
435
+ const sent = this.nodeRegistry.send(nodeId, {
436
+ type: 'library.mirror.apply.request',
437
+ requestId,
438
+ workspaceRoot,
439
+ shared: mirror.shared,
440
+ personal: mirror.personal,
441
+ });
442
+ if (!sent) {
443
+ clearTimeout(timer);
444
+ this.pending.delete(requestId);
445
+ reject(new Error('Agent node is offline.'));
446
+ }
447
+ });
448
+ }
449
+ snapshotLibraryMirror(nodeId, workspaceRoot) {
450
+ const requestId = randomUUID();
451
+ return new Promise((resolve, reject) => {
452
+ const timer = setTimeout(() => {
453
+ this.pending.delete(requestId);
454
+ reject(new Error('Library mirror snapshot timed out.'));
455
+ }, this.libraryMirrorTimeoutMs);
456
+ this.pending.set(requestId, {
457
+ kind: 'library-mirror-snapshot',
458
+ nodeId,
459
+ resolve,
460
+ reject,
461
+ timer,
462
+ });
463
+ const sent = this.nodeRegistry.send(nodeId, {
464
+ type: 'library.mirror.snapshot.request',
465
+ requestId,
466
+ workspaceRoot,
467
+ });
468
+ if (!sent) {
469
+ clearTimeout(timer);
470
+ this.pending.delete(requestId);
471
+ reject(new Error('Agent node is offline.'));
472
+ }
473
+ });
474
+ }
475
+ deleteLibraryPath(nodeId, libraryRoot, relativePath, options) {
476
+ const requestId = randomUUID();
477
+ return new Promise((resolve, reject) => {
478
+ const timer = setTimeout(() => {
479
+ this.pending.delete(requestId);
480
+ reject(new Error('Library authority delete timed out.'));
481
+ }, this.timeoutMs);
482
+ this.pending.set(requestId, {
483
+ kind: 'library-authority-delete',
484
+ nodeId,
485
+ resolve,
486
+ reject,
487
+ timer,
488
+ });
489
+ const sent = this.nodeRegistry.send(nodeId, {
490
+ type: 'library.authority.delete.request',
491
+ requestId,
492
+ libraryRoot,
493
+ relativePath,
494
+ ...(options?.recursive ? { recursive: true } : {}),
495
+ ...(options?.agentName?.trim() ? { agentName: options.agentName.trim() } : {}),
496
+ });
497
+ if (!sent) {
498
+ clearTimeout(timer);
499
+ this.pending.delete(requestId);
500
+ reject(new Error('Agent node is offline.'));
501
+ }
502
+ });
503
+ }
504
+ renameLibraryPath(nodeId, libraryRoot, relativePath, nextRelativePath, options) {
505
+ const requestId = randomUUID();
506
+ return new Promise((resolve, reject) => {
507
+ const timer = setTimeout(() => {
508
+ this.pending.delete(requestId);
509
+ reject(new Error('Library authority rename timed out.'));
510
+ }, this.timeoutMs);
511
+ this.pending.set(requestId, {
512
+ kind: 'library-authority-rename',
513
+ nodeId,
514
+ resolve,
515
+ reject,
516
+ timer,
517
+ });
518
+ const sent = this.nodeRegistry.send(nodeId, {
519
+ type: 'library.authority.rename.request',
520
+ requestId,
521
+ libraryRoot,
522
+ relativePath,
523
+ nextRelativePath,
524
+ ...(options?.agentName?.trim() ? { agentName: options.agentName.trim() } : {}),
525
+ });
526
+ if (!sent) {
527
+ clearTimeout(timer);
528
+ this.pending.delete(requestId);
529
+ reject(new Error('Agent node is offline.'));
530
+ }
531
+ });
532
+ }
533
+ handleWorkspaceListResponse(msg) {
534
+ const pending = this.pending.get(msg.requestId);
535
+ if (!pending || pending.kind !== 'list')
536
+ return;
537
+ this.pending.delete(msg.requestId);
538
+ clearTimeout(pending.timer);
539
+ if (msg.error || !msg.entries) {
540
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
541
+ return;
542
+ }
543
+ pending.resolve({
544
+ path: msg.relativePath,
545
+ entries: msg.entries,
546
+ directoryPage: msg.directoryPage ?? {
547
+ nextCursor: null,
548
+ hasMore: false,
549
+ limit: msg.entries.length,
550
+ },
551
+ });
552
+ }
553
+ handleWorkspaceReadResponse(msg) {
554
+ const pending = this.pending.get(msg.requestId);
555
+ if (!pending || pending.kind !== 'read')
556
+ return;
557
+ this.pending.delete(msg.requestId);
558
+ clearTimeout(pending.timer);
559
+ if (msg.error || msg.content === undefined || !msg.mimeType || msg.size === undefined) {
560
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
561
+ return;
562
+ }
563
+ const result = {
564
+ path: msg.relativePath,
565
+ content: msg.content,
566
+ mimeType: msg.mimeType,
567
+ size: msg.size,
568
+ modifiedAt: msg.modifiedAt ?? null,
569
+ };
570
+ if (msg.offset !== undefined)
571
+ result.offset = msg.offset;
572
+ if (msg.limit !== undefined)
573
+ result.limit = msg.limit;
574
+ if (msg.nextOffset !== undefined)
575
+ result.nextOffset = msg.nextOffset;
576
+ if (msg.hasMore !== undefined)
577
+ result.hasMore = msg.hasMore;
578
+ pending.resolve(result);
579
+ }
580
+ handleWorkspaceArchiveResponse(msg) {
581
+ const pending = this.pending.get(msg.requestId);
582
+ if (!pending || pending.kind !== 'archive')
583
+ return;
584
+ this.pending.delete(msg.requestId);
585
+ clearTimeout(pending.timer);
586
+ if (msg.error || msg.archiveBase64 === undefined || msg.byteSize === undefined || msg.fileCount === undefined) {
587
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
588
+ return;
589
+ }
590
+ pending.resolve({
591
+ path: msg.relativePath,
592
+ archiveBase64: msg.archiveBase64,
593
+ byteSize: msg.byteSize,
594
+ fileCount: msg.fileCount,
595
+ });
596
+ }
597
+ handleWorkspaceExtractResponse(msg) {
598
+ const pending = this.pending.get(msg.requestId);
599
+ if (!pending || pending.kind !== 'extract')
600
+ return;
601
+ this.pending.delete(msg.requestId);
602
+ clearTimeout(pending.timer);
603
+ if (msg.error || !msg.ok || msg.byteSize === undefined || msg.fileCount === undefined) {
604
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
605
+ return;
606
+ }
607
+ pending.resolve({
608
+ path: msg.relativePath,
609
+ byteSize: msg.byteSize,
610
+ fileCount: msg.fileCount,
611
+ });
612
+ }
613
+ handleWorkspaceDeleteFileResponse(msg) {
614
+ const pending = this.pending.get(msg.requestId);
615
+ if (!pending || pending.kind !== 'delete-file')
616
+ return;
617
+ this.pending.delete(msg.requestId);
618
+ clearTimeout(pending.timer);
619
+ if (msg.error || !msg.ok) {
620
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
621
+ return;
622
+ }
623
+ pending.resolve();
624
+ }
625
+ handleWorkspaceDeletePathResponse(msg) {
626
+ const pending = this.pending.get(msg.requestId);
627
+ if (!pending || pending.kind !== 'delete-path')
628
+ return;
629
+ this.pending.delete(msg.requestId);
630
+ clearTimeout(pending.timer);
631
+ if (msg.error || !msg.ok) {
632
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
633
+ return;
634
+ }
635
+ pending.resolve();
636
+ }
637
+ handleFsReadPathResponse(msg) {
638
+ const pending = this.pending.get(msg.requestId);
639
+ if (!pending || pending.kind !== 'read-path')
640
+ return;
641
+ this.pending.delete(msg.requestId);
642
+ clearTimeout(pending.timer);
643
+ if (msg.error || !msg.kind) {
644
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
645
+ return;
646
+ }
647
+ if (msg.kind === 'directory') {
648
+ pending.resolve({
649
+ absolutePath: msg.absolutePath,
650
+ kind: 'directory',
651
+ entries: msg.entries ?? [],
652
+ directoryPage: msg.directoryPage ?? {
653
+ nextCursor: null,
654
+ hasMore: false,
655
+ limit: msg.entries?.length ?? 0,
656
+ },
657
+ modifiedAt: msg.modifiedAt ?? null,
658
+ });
659
+ return;
660
+ }
661
+ if (msg.kind === 'file') {
662
+ if (msg.content === undefined || !msg.mimeType || msg.size === undefined) {
663
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
664
+ return;
665
+ }
666
+ const result = {
667
+ absolutePath: msg.absolutePath,
668
+ kind: 'file',
669
+ content: msg.content,
670
+ mimeType: msg.mimeType,
671
+ size: msg.size,
672
+ modifiedAt: msg.modifiedAt ?? null,
673
+ };
674
+ if (msg.offset !== undefined)
675
+ result.offset = msg.offset;
676
+ if (msg.limit !== undefined)
677
+ result.limit = msg.limit;
678
+ if (msg.nextOffset !== undefined)
679
+ result.nextOffset = msg.nextOffset;
680
+ if (msg.hasMore !== undefined)
681
+ result.hasMore = msg.hasMore;
682
+ if (msg.rawContentBase64 !== undefined)
683
+ result.rawContentBase64 = msg.rawContentBase64;
684
+ pending.resolve(result);
685
+ return;
686
+ }
687
+ pending.resolve({
688
+ absolutePath: msg.absolutePath,
689
+ kind: msg.kind,
690
+ modifiedAt: msg.modifiedAt ?? null,
691
+ });
692
+ }
693
+ handleFsPathSuggestResponse(msg) {
694
+ const pending = this.pending.get(msg.requestId);
695
+ if (!pending || pending.kind !== 'path-suggest')
696
+ return;
697
+ clearTimeout(pending.timer);
698
+ this.pending.delete(msg.requestId);
699
+ if (msg.error) {
700
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
701
+ return;
702
+ }
703
+ pending.resolve({
704
+ query: msg.query,
705
+ suggestions: msg.suggestions ?? [],
706
+ });
707
+ }
708
+ handleHttpFetchTextResponse(msg) {
709
+ const pending = this.pending.get(msg.requestId);
710
+ if (!pending || pending.kind !== 'http-fetch-text')
711
+ return;
712
+ clearTimeout(pending.timer);
713
+ this.pending.delete(msg.requestId);
714
+ if (msg.error || msg.status === undefined) {
715
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
716
+ return;
717
+ }
718
+ if (msg.notModified || msg.status === 304) {
719
+ pending.resolve({
720
+ url: msg.url,
721
+ content: msg.content ?? '',
722
+ status: msg.status,
723
+ contentType: msg.contentType ?? null,
724
+ size: msg.size ?? 0,
725
+ ...(msg.partialContent !== undefined ? { partialContent: msg.partialContent } : {}),
726
+ ...(msg.rangeStart !== undefined ? { rangeStart: msg.rangeStart } : {}),
727
+ ...(msg.rangeEnd !== undefined ? { rangeEnd: msg.rangeEnd } : {}),
728
+ ...(msg.totalSize !== undefined ? { totalSize: msg.totalSize ?? null } : {}),
729
+ ...(msg.hasMore !== undefined ? { hasMore: msg.hasMore } : {}),
730
+ notModified: true,
731
+ etag: msg.etag ?? null,
732
+ lastModified: msg.lastModified ?? null,
733
+ });
734
+ return;
735
+ }
736
+ if (msg.content === undefined || msg.size === undefined) {
737
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
738
+ return;
739
+ }
740
+ pending.resolve({
741
+ url: msg.url,
742
+ content: msg.content,
743
+ status: msg.status,
744
+ contentType: msg.contentType ?? null,
745
+ size: msg.size,
746
+ ...(msg.partialContent !== undefined ? { partialContent: msg.partialContent } : {}),
747
+ ...(msg.rangeStart !== undefined ? { rangeStart: msg.rangeStart } : {}),
748
+ ...(msg.rangeEnd !== undefined ? { rangeEnd: msg.rangeEnd } : {}),
749
+ ...(msg.totalSize !== undefined ? { totalSize: msg.totalSize ?? null } : {}),
750
+ ...(msg.hasMore !== undefined ? { hasMore: msg.hasMore } : {}),
751
+ etag: msg.etag ?? null,
752
+ lastModified: msg.lastModified ?? null,
753
+ });
754
+ }
755
+ handleWorkspaceServiceProxyResponse(msg) {
756
+ const pending = this.pending.get(msg.requestId);
757
+ if (!pending || pending.kind !== 'workspace-service-proxy')
758
+ return;
759
+ clearTimeout(pending.timer);
760
+ this.pending.delete(msg.requestId);
761
+ if (msg.error || msg.status === undefined || msg.body === undefined || msg.size === undefined) {
762
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
763
+ return;
764
+ }
765
+ pending.resolve({
766
+ url: msg.url,
767
+ method: msg.method,
768
+ status: msg.status,
769
+ body: msg.body,
770
+ contentType: msg.contentType ?? null,
771
+ size: msg.size,
772
+ });
773
+ }
774
+ handleFsReadPathStreamStart(msg) {
775
+ const pending = this.pending.get(msg.requestId);
776
+ if (!pending || pending.kind !== 'read-path-stream')
777
+ return;
778
+ pending.started = true;
779
+ clearTimeout(pending.timer);
780
+ pending.timer = this.createStreamIdleTimer(msg.requestId);
781
+ pending.resolve({
782
+ absolutePath: msg.absolutePath,
783
+ mimeType: msg.mimeType,
784
+ size: msg.size,
785
+ modifiedAt: msg.modifiedAt ?? null,
786
+ stream: pending.stream,
787
+ });
788
+ }
789
+ handleFsReadPathStreamChunk(msg) {
790
+ const pending = this.pending.get(msg.requestId);
791
+ if (!pending || pending.kind !== 'read-path-stream')
792
+ return;
793
+ clearTimeout(pending.timer);
794
+ pending.timer = this.createStreamIdleTimer(msg.requestId);
795
+ pending.stream.write(Buffer.from(msg.chunk, 'base64'));
796
+ }
797
+ handleFsReadPathStreamEnd(msg) {
798
+ const pending = this.pending.get(msg.requestId);
799
+ if (!pending || pending.kind !== 'read-path-stream')
800
+ return;
801
+ this.pending.delete(msg.requestId);
802
+ clearTimeout(pending.timer);
803
+ if (msg.error) {
804
+ const error = new Error(this.formatErrorMessage(msg.errorCode, msg.error));
805
+ if (pending.started) {
806
+ pending.stream.destroy(error);
807
+ }
808
+ else {
809
+ pending.stream.destroy();
810
+ pending.reject(error);
811
+ }
812
+ return;
813
+ }
814
+ pending.stream.end();
815
+ }
816
+ handleWorkspaceResetResponse(msg) {
817
+ const pending = this.pending.get(msg.requestId);
818
+ if (!pending || pending.kind !== 'reset')
819
+ return;
820
+ this.pending.delete(msg.requestId);
821
+ clearTimeout(pending.timer);
822
+ if (msg.error || !msg.ok) {
823
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
824
+ return;
825
+ }
826
+ pending.resolve();
827
+ }
828
+ handleLibraryMirrorApplyResponse(msg) {
829
+ const pending = this.pending.get(msg.requestId);
830
+ if (!pending || pending.kind !== 'library-mirror-apply')
831
+ return;
832
+ this.pending.delete(msg.requestId);
833
+ clearTimeout(pending.timer);
834
+ if (msg.error || !msg.ok) {
835
+ pending.reject(new Error(msg.error ?? 'library mirror apply failed'));
836
+ return;
837
+ }
838
+ pending.resolve();
839
+ }
840
+ handleLibraryMirrorSnapshotResponse(msg) {
841
+ const pending = this.pending.get(msg.requestId);
842
+ if (!pending || pending.kind !== 'library-mirror-snapshot')
843
+ return;
844
+ this.pending.delete(msg.requestId);
845
+ clearTimeout(pending.timer);
846
+ if (msg.error) {
847
+ pending.reject(new Error(msg.error));
848
+ return;
849
+ }
850
+ pending.resolve({
851
+ shared: msg.shared ?? null,
852
+ personal: msg.personal ?? null,
853
+ });
854
+ }
855
+ handleLibraryAuthorityDeleteResponse(msg) {
856
+ const pending = this.pending.get(msg.requestId);
857
+ if (!pending || pending.kind !== 'library-authority-delete')
858
+ return;
859
+ this.pending.delete(msg.requestId);
860
+ clearTimeout(pending.timer);
861
+ if (msg.error || !msg.ok) {
862
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
863
+ return;
864
+ }
865
+ pending.resolve();
866
+ }
867
+ handleLibraryAuthorityRenameResponse(msg) {
868
+ const pending = this.pending.get(msg.requestId);
869
+ if (!pending || pending.kind !== 'library-authority-rename')
870
+ return;
871
+ this.pending.delete(msg.requestId);
872
+ clearTimeout(pending.timer);
873
+ if (msg.error || !msg.ok) {
874
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
875
+ return;
876
+ }
877
+ pending.resolve();
878
+ }
879
+ handleWorkspaceWriteResponse(msg) {
880
+ const pending = this.pending.get(msg.requestId);
881
+ if (!pending || pending.kind !== 'write')
882
+ return;
883
+ this.pending.delete(msg.requestId);
884
+ clearTimeout(pending.timer);
885
+ if (msg.error || !msg.ok) {
886
+ pending.reject(new Error(this.formatErrorMessage(msg.errorCode, msg.error)));
887
+ return;
888
+ }
889
+ pending.resolve();
890
+ }
891
+ rejectPendingForNode(nodeId) {
892
+ for (const [requestId, pending] of this.pending.entries()) {
893
+ if (pending.nodeId !== nodeId)
894
+ continue;
895
+ clearTimeout(pending.timer);
896
+ const error = new Error(`Agent node disconnected: ${nodeId}`);
897
+ if (pending.kind === 'read-path-stream') {
898
+ if (pending.started) {
899
+ pending.stream.destroy(error);
900
+ }
901
+ else {
902
+ pending.stream.destroy();
903
+ pending.reject(error);
904
+ }
905
+ }
906
+ else {
907
+ pending.reject(error);
908
+ }
909
+ this.pending.delete(requestId);
910
+ }
911
+ }
912
+ createStreamIdleTimer(requestId) {
913
+ return setTimeout(() => {
914
+ this.failStreamRequest(requestId, new Error('Workspace stream request timed out.'));
915
+ }, this.timeoutMs);
916
+ }
917
+ failStreamRequest(requestId, error) {
918
+ const pending = this.pending.get(requestId);
919
+ if (!pending || pending.kind !== 'read-path-stream')
920
+ return;
921
+ this.pending.delete(requestId);
922
+ clearTimeout(pending.timer);
923
+ if (pending.started) {
924
+ pending.stream.destroy(error);
925
+ }
926
+ else {
927
+ pending.stream.destroy();
928
+ pending.reject(error);
929
+ }
930
+ }
931
+ formatErrorMessage(errorCode, error) {
932
+ if (errorCode) {
933
+ return `${errorCode}:${error ?? 'workspace request failed'}`;
934
+ }
935
+ return error ?? 'workspace request failed';
936
+ }
937
+ }