@hyperdrive.bot/fleet-server 0.3.159 → 0.3.161
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/dist/server/server/agent/agent-manager.d.ts +29 -0
- package/dist/server/server/agent/agent-manager.js +69 -5
- package/dist/server/server/agent/agent-timeline-store.d.ts +10 -0
- package/dist/server/server/agent/agent-timeline-store.js +54 -6
- package/dist/server/server/agent/blocker-log.d.ts +3 -1
- package/dist/server/server/agent/blocker-log.js +17 -5
- package/dist/server/server/agent/card-move-log.d.ts +3 -1
- package/dist/server/server/agent/card-move-log.js +21 -14
- package/dist/server/server/agent/import-sessions.js +1 -1
- package/dist/server/server/agent/jsonl-card-index.d.ts +53 -0
- package/dist/server/server/agent/jsonl-card-index.js +138 -0
- package/dist/server/server/agent/lifecycle-command.d.ts +18 -1
- package/dist/server/server/agent/lifecycle-command.js +21 -2
- package/dist/server/server/agent/mcp-shared.d.ts +1 -0
- package/dist/server/server/agent/provider-snapshot-manager.d.ts +9 -0
- package/dist/server/server/agent/provider-snapshot-manager.js +38 -1
- package/dist/server/server/agent/structured-generation-providers.d.ts +2 -1
- package/dist/server/server/agent/structured-generation-providers.js +21 -8
- package/dist/server/server/fleet/decision-service.d.ts +8 -0
- package/dist/server/server/fleet/decision-service.js +24 -1
- package/dist/server/server/fleet/fleet-controls.js +2 -1
- package/dist/server/server/fleet/fleet-reader.d.ts +12 -0
- package/dist/server/server/fleet/fleet-reader.js +48 -2
- package/dist/server/server/schedule/service.d.ts +4 -0
- package/dist/server/server/schedule/service.js +26 -5
- package/dist/server/server/schedule/store.d.ts +51 -0
- package/dist/server/server/schedule/store.js +184 -16
- package/dist/server/server/session/agent-updates/agent-updates-service.d.ts +16 -1
- package/dist/server/server/session/agent-updates/agent-updates-service.js +59 -2
- package/dist/server/server/session/provider/provider-catalog-session.d.ts +8 -0
- package/dist/server/server/session/provider/provider-catalog-session.js +21 -1
- package/dist/server/server/session.d.ts +16 -0
- package/dist/server/server/session.js +115 -19
- package/dist/server/server/websocket-server.d.ts +5 -0
- package/dist/server/server/websocket-server.js +10 -0
- package/dist/server/server/workspace-directory.d.ts +4 -1
- package/dist/server/server/workspace-directory.js +3 -2
- package/dist/server/web-ui/_expo/static/js/web/{index-1420ca2d21c343afea2c8e2da752cd54.js → index-6a8adbad019c19e5bd71cf06dc31528b.js} +6 -6
- package/dist/server/web-ui/_expo/static/js/web/index-6a8adbad019c19e5bd71cf06dc31528b.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-6a8adbad019c19e5bd71cf06dc31528b.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-1420ca2d21c343afea2c8e2da752cd54.js.map.br → index-6a8adbad019c19e5bd71cf06dc31528b.js.map.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-1420ca2d21c343afea2c8e2da752cd54.js.map.gz → index-6a8adbad019c19e5bd71cf06dc31528b.js.map.gz} +0 -0
- package/dist/server/web-ui/index.html +1 -1
- package/dist/server/web-ui/index.html.br +0 -0
- package/dist/server/web-ui/index.html.gz +0 -0
- package/package.json +6 -6
- package/dist/server/web-ui/_expo/static/js/web/index-1420ca2d21c343afea2c8e2da752cd54.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-1420ca2d21c343afea2c8e2da752cd54.js.gz +0 -0
|
@@ -426,6 +426,57 @@ function fileAttachmentErrorMessage(error, fileId) {
|
|
|
426
426
|
return `Attachment file is no longer available: ${fileId}`;
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
|
+
/**
|
|
430
|
+
* Stored-agent payload projection, memoized per record object and shared by
|
|
431
|
+
* every Session in the daemon. AgentStorage replaces a record object on every
|
|
432
|
+
* write (never mutates it), so identity plus the other projection inputs
|
|
433
|
+
* (registered providers, schedule facts) is an exact key. Before this, every
|
|
434
|
+
* agent_state event re-projected the same stored records once per connected
|
|
435
|
+
* client. Payloads are shared: treat them as read-only.
|
|
436
|
+
*/
|
|
437
|
+
const storedAgentPayloadMemo = new WeakMap();
|
|
438
|
+
/**
|
|
439
|
+
* The stored records a workspace descriptor for `workspaceIds` can depend on:
|
|
440
|
+
* records owned by one of those workspaces, running delegated records (they roll
|
|
441
|
+
* up to their delegation root, see WorkspaceDirectory), and the ancestor chain of
|
|
442
|
+
* every delegated record or live agent so the root can be resolved.
|
|
443
|
+
*/
|
|
444
|
+
export function selectRecordsForWorkspaces(records, liveAgents, workspaceIds) {
|
|
445
|
+
const selected = new Set();
|
|
446
|
+
const pendingParentIds = [];
|
|
447
|
+
for (const record of records) {
|
|
448
|
+
const parentId = getParentAgentIdFromLabels(record.labels);
|
|
449
|
+
const owned = record.workspaceId !== undefined && workspaceIds.has(record.workspaceId);
|
|
450
|
+
if (owned || (parentId !== null && record.lastStatus === "running")) {
|
|
451
|
+
selected.add(record);
|
|
452
|
+
if (parentId)
|
|
453
|
+
pendingParentIds.push(parentId);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
for (const agent of liveAgents) {
|
|
457
|
+
const parentId = getParentAgentIdFromLabels(agent.labels);
|
|
458
|
+
if (parentId)
|
|
459
|
+
pendingParentIds.push(parentId);
|
|
460
|
+
}
|
|
461
|
+
if (pendingParentIds.length > 0) {
|
|
462
|
+
const byId = new Map(records.map((record) => [record.id, record]));
|
|
463
|
+
const seen = new Set();
|
|
464
|
+
while (pendingParentIds.length > 0) {
|
|
465
|
+
const id = pendingParentIds.pop();
|
|
466
|
+
if (seen.has(id))
|
|
467
|
+
continue;
|
|
468
|
+
seen.add(id);
|
|
469
|
+
const parent = byId.get(id);
|
|
470
|
+
if (!parent)
|
|
471
|
+
continue;
|
|
472
|
+
selected.add(parent);
|
|
473
|
+
const next = getParentAgentIdFromLabels(parent.labels);
|
|
474
|
+
if (next)
|
|
475
|
+
pendingParentIds.push(next);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return records.filter((record) => selected.has(record));
|
|
479
|
+
}
|
|
429
480
|
/**
|
|
430
481
|
* Session represents a single connected client session.
|
|
431
482
|
* It owns all state management, orchestration logic, and message processing.
|
|
@@ -727,7 +778,7 @@ export class Session {
|
|
|
727
778
|
logger: this.sessionLogger,
|
|
728
779
|
projectRegistry: this.projectRegistry,
|
|
729
780
|
workspaceRegistry: this.workspaceRegistry,
|
|
730
|
-
listAgentPayloads: () => this.listAgentPayloads(),
|
|
781
|
+
listAgentPayloads: (filter) => this.listAgentPayloads(filter),
|
|
731
782
|
listTerminalActivityContributions: () => this.listTerminalActivityContributions(),
|
|
732
783
|
isProviderVisibleToClient: (provider) => this.isProviderVisibleToClient(provider),
|
|
733
784
|
buildWorkspaceDescriptor: (input) => this.buildWorkspaceDescriptor(input),
|
|
@@ -1079,14 +1130,24 @@ export class Session {
|
|
|
1079
1130
|
payload.snooze = storedRecord?.snooze ?? null;
|
|
1080
1131
|
return payload;
|
|
1081
1132
|
}
|
|
1082
|
-
buildStoredAgentPayload(record, registeredProviderIds = new Set(this.providerSnapshotManager.listRegisteredProviderIds())) {
|
|
1133
|
+
buildStoredAgentPayload(record, registeredProviderIds = new Set(this.providerSnapshotManager.listRegisteredProviderIds()), providersKey) {
|
|
1083
1134
|
const nextFireAt = this.scheduleService.peekNextFireAt(record.id);
|
|
1084
1135
|
const hasRoutine = this.scheduleService.peekHasRoutine(record.id);
|
|
1136
|
+
const memoKey = providersKey ?? [...registeredProviderIds].join("\u0000");
|
|
1137
|
+
const memo = storedAgentPayloadMemo.get(record);
|
|
1138
|
+
if (memo &&
|
|
1139
|
+
memo.providersKey === memoKey &&
|
|
1140
|
+
memo.nextFireAt === nextFireAt &&
|
|
1141
|
+
memo.hasRoutine === hasRoutine) {
|
|
1142
|
+
return memo.payload;
|
|
1143
|
+
}
|
|
1085
1144
|
const scheduleOptions = {
|
|
1086
1145
|
...(nextFireAt !== undefined ? { nextFireAt } : {}),
|
|
1087
1146
|
...(hasRoutine !== undefined ? { hasRoutine } : {}),
|
|
1088
1147
|
};
|
|
1089
|
-
|
|
1148
|
+
const payload = buildStoredAgentPayload(record, registeredProviderIds, Object.keys(scheduleOptions).length > 0 ? scheduleOptions : undefined);
|
|
1149
|
+
storedAgentPayloadMemo.set(record, { providersKey: memoKey, nextFireAt, hasRoutine, payload });
|
|
1150
|
+
return payload;
|
|
1090
1151
|
}
|
|
1091
1152
|
isProviderVisibleToClient(provider) {
|
|
1092
1153
|
if (clientSupportsAllProviders(this.appVersion)) {
|
|
@@ -2551,7 +2612,7 @@ export class Session {
|
|
|
2551
2612
|
}
|
|
2552
2613
|
async handleArchiveAgentRequest(agentId, requestId) {
|
|
2553
2614
|
this.sessionLogger.info({ agentId }, `Archiving agent ${agentId}`);
|
|
2554
|
-
const { archivedAt } = await this.archiveAgentForClose(agentId);
|
|
2615
|
+
const { archivedAt, background } = await this.archiveAgentForClose(agentId);
|
|
2555
2616
|
this.emit({
|
|
2556
2617
|
type: "agent_archived",
|
|
2557
2618
|
payload: {
|
|
@@ -2560,6 +2621,8 @@ export class Session {
|
|
|
2560
2621
|
requestId,
|
|
2561
2622
|
},
|
|
2562
2623
|
});
|
|
2624
|
+
// Teardown and the workspace delta finish after the reply; failures are logged.
|
|
2625
|
+
void background;
|
|
2563
2626
|
}
|
|
2564
2627
|
/**
|
|
2565
2628
|
* List background shells -- one agent's, or every agent's when `agentId` is
|
|
@@ -2711,19 +2774,44 @@ export class Session {
|
|
|
2711
2774
|
payload: { agentId, taskId, dismissed, requestId },
|
|
2712
2775
|
});
|
|
2713
2776
|
}
|
|
2777
|
+
/**
|
|
2778
|
+
* Persist the archive and emit the archived agent, then hand back the rest
|
|
2779
|
+
* (process teardown, then the workspace delta) as `background` so the caller
|
|
2780
|
+
* can reply first. Stopping a busy agent and rebuilding its workspace used to
|
|
2781
|
+
* sit in front of the reply.
|
|
2782
|
+
*/
|
|
2714
2783
|
async archiveAgentForClose(agentId) {
|
|
2715
|
-
const { archivedAt, record: archivedRecord } = await archiveAgentCommand({
|
|
2784
|
+
const { archivedAt, record: archivedRecord, teardown, } = await archiveAgentCommand({
|
|
2716
2785
|
agentManager: this.agentManager,
|
|
2717
2786
|
agentStorage: this.agentStorage,
|
|
2718
2787
|
logger: this.sessionLogger,
|
|
2719
|
-
}, agentId);
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2788
|
+
}, agentId, { deferTeardown: true });
|
|
2789
|
+
const payload = this.agentUpdates.hasSubscription()
|
|
2790
|
+
? await this.agentUpdates.emitStoredRecord(archivedRecord)
|
|
2791
|
+
: null;
|
|
2792
|
+
const background = (async () => {
|
|
2793
|
+
const teardownError = await teardown;
|
|
2794
|
+
if (teardownError) {
|
|
2795
|
+
// Surface it: clients otherwise hold an archived record whose process is
|
|
2796
|
+
// still alive, and the only trace would be a daemon log line.
|
|
2797
|
+
this.emit({
|
|
2798
|
+
type: "rpc_error",
|
|
2799
|
+
payload: {
|
|
2800
|
+
requestId: `archive-teardown:${agentId}`,
|
|
2801
|
+
requestType: "archive_agent_request",
|
|
2802
|
+
error: `Archived, but stopping the agent failed: ${teardownError.message}`,
|
|
2803
|
+
code: "archive_teardown_failed",
|
|
2804
|
+
},
|
|
2805
|
+
});
|
|
2806
|
+
await this.emitAgentUpsertFromStorage(agentId);
|
|
2807
|
+
}
|
|
2808
|
+
if (payload?.workspaceId) {
|
|
2723
2809
|
await this.emitWorkspaceUpdateForWorkspaceId(payload.workspaceId);
|
|
2724
2810
|
}
|
|
2725
|
-
}
|
|
2726
|
-
|
|
2811
|
+
})().catch((error) => {
|
|
2812
|
+
this.sessionLogger.error({ err: error, agentId }, "Failed to emit workspace update after archiving agent");
|
|
2813
|
+
});
|
|
2814
|
+
return { agentId, archivedAt, background };
|
|
2727
2815
|
}
|
|
2728
2816
|
async handleDetachAgentRequest(agentId, requestId) {
|
|
2729
2817
|
this.sessionLogger.info({ agentId, requestId }, "Detaching agent from parent");
|
|
@@ -2775,10 +2863,12 @@ export class Session {
|
|
|
2775
2863
|
async handleCloseItemsRequest(msg) {
|
|
2776
2864
|
const archiveResults = await Promise.allSettled(msg.agentIds.map((agentId) => this.archiveAgentForClose(agentId)));
|
|
2777
2865
|
const agents = [];
|
|
2866
|
+
const background = [];
|
|
2778
2867
|
for (let i = 0; i < archiveResults.length; i += 1) {
|
|
2779
2868
|
const result = archiveResults[i];
|
|
2780
2869
|
if (result.status === "fulfilled") {
|
|
2781
|
-
agents.push(result.value);
|
|
2870
|
+
agents.push({ agentId: result.value.agentId, archivedAt: result.value.archivedAt });
|
|
2871
|
+
background.push(result.value.background);
|
|
2782
2872
|
}
|
|
2783
2873
|
else {
|
|
2784
2874
|
this.sessionLogger.warn({ err: result.reason, agentId: msg.agentIds[i], requestId: msg.requestId }, "Failed to archive agent during close_items batch");
|
|
@@ -2805,6 +2895,8 @@ export class Session {
|
|
|
2805
2895
|
requestId: msg.requestId,
|
|
2806
2896
|
},
|
|
2807
2897
|
});
|
|
2898
|
+
// Teardown and the workspace deltas finish after the reply; failures are logged.
|
|
2899
|
+
void Promise.all(background);
|
|
2808
2900
|
}
|
|
2809
2901
|
async unarchiveAgentByHandle(handle) {
|
|
2810
2902
|
const records = await this.agentStorage.list();
|
|
@@ -3585,7 +3677,7 @@ export class Session {
|
|
|
3585
3677
|
this.sessionLogger.warn({ err, agentId: snapshot.id, resumeSessionId }, "resume timeline hydration failed");
|
|
3586
3678
|
}
|
|
3587
3679
|
}
|
|
3588
|
-
await this.agentUpdates.forwardLiveAgent(snapshot);
|
|
3680
|
+
await this.agentUpdates.forwardLiveAgent(snapshot, { immediate: true });
|
|
3589
3681
|
if (createdDirectoryWorkspaceForAgent && trimmedPrompt) {
|
|
3590
3682
|
this.workspaceAutoName.scheduleForDirectory({
|
|
3591
3683
|
workspaceId,
|
|
@@ -3664,8 +3756,8 @@ export class Session {
|
|
|
3664
3756
|
const snapshot = await this.agentManager.resumeAgentFromPersistence(handle, overrides);
|
|
3665
3757
|
await unarchiveAgentState(this.agentStorage, this.agentManager, snapshot.id);
|
|
3666
3758
|
await this.agentManager.hydrateTimelineFromProvider(snapshot.id);
|
|
3667
|
-
await this.agentUpdates.forwardLiveAgent(snapshot);
|
|
3668
|
-
const timelineSize = this.agentManager.
|
|
3759
|
+
await this.agentUpdates.forwardLiveAgent(snapshot, { immediate: true });
|
|
3760
|
+
const timelineSize = this.agentManager.getTimelineSize(snapshot.id);
|
|
3669
3761
|
if (requestId) {
|
|
3670
3762
|
const agentPayload = await this.buildAgentPayload(snapshot);
|
|
3671
3763
|
this.emit({
|
|
@@ -3805,8 +3897,8 @@ export class Session {
|
|
|
3805
3897
|
snapshot = await this.agentManager.resumeAgentFromPersistence(handle, buildConfigOverrides(record), agentId, extractTimestamps(record));
|
|
3806
3898
|
}
|
|
3807
3899
|
await this.agentManager.hydrateTimelineFromProvider(agentId);
|
|
3808
|
-
await this.agentUpdates.forwardLiveAgent(snapshot);
|
|
3809
|
-
const timelineSize = this.agentManager.
|
|
3900
|
+
await this.agentUpdates.forwardLiveAgent(snapshot, { immediate: true });
|
|
3901
|
+
const timelineSize = this.agentManager.getTimelineSize(agentId);
|
|
3810
3902
|
if (requestId) {
|
|
3811
3903
|
this.emit({
|
|
3812
3904
|
type: "status",
|
|
@@ -4855,9 +4947,13 @@ export class Session {
|
|
|
4855
4947
|
const liveAgents = await Promise.all(agentSnapshots.map((agent) => this.buildAgentPayload(agent)));
|
|
4856
4948
|
// Add persisted agents that have not been lazily initialized yet
|
|
4857
4949
|
// (excluding internal agents which are for ephemeral system tasks)
|
|
4858
|
-
const
|
|
4950
|
+
const allRegistryRecords = await this.agentStorage.list();
|
|
4951
|
+
const registryRecords = filter?.workspaceIds
|
|
4952
|
+
? selectRecordsForWorkspaces(allRegistryRecords, agentSnapshots, filter.workspaceIds)
|
|
4953
|
+
: allRegistryRecords;
|
|
4859
4954
|
const liveIds = new Set(agentSnapshots.map((a) => a.id));
|
|
4860
4955
|
const registeredProviderIds = new Set(this.providerSnapshotManager.listRegisteredProviderIds());
|
|
4956
|
+
const providersKey = [...registeredProviderIds].join("\u0000");
|
|
4861
4957
|
const persistedAgents = registryRecords
|
|
4862
4958
|
.filter((record) => !liveIds.has(record.id) && !record.internal)
|
|
4863
4959
|
// Keep raw-record filters ahead of projection; seeded homes can carry thousands of archived agents.
|
|
@@ -4865,7 +4961,7 @@ export class Session {
|
|
|
4865
4961
|
.filter((record) => labelEntries.every(([key, value]) => record.labels?.[key] === value))
|
|
4866
4962
|
.filter((record) => filter?.includeUnavailablePersisted === true ||
|
|
4867
4963
|
isStoredAgentProviderAvailable(record, registeredProviderIds))
|
|
4868
|
-
.map((record) => this.buildStoredAgentPayload(record, registeredProviderIds));
|
|
4964
|
+
.map((record) => this.buildStoredAgentPayload(record, registeredProviderIds, providersKey));
|
|
4869
4965
|
let agents = [...liveAgents, ...persistedAgents];
|
|
4870
4966
|
agents = agents.filter((agent) => this.isProviderVisibleToClient(agent.provider));
|
|
4871
4967
|
if (!includeArchived) {
|
|
@@ -50,6 +50,11 @@ interface WebSocketLike {
|
|
|
50
50
|
on: (event: "message" | "close" | "error", listener: (...args: unknown[]) => void) => void;
|
|
51
51
|
once: (event: "close" | "error", listener: (...args: unknown[]) => void) => void;
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Requests designed to block until something happens (a long-poll). They stay
|
|
55
|
+
* out of the request latency stats and the slow-request log.
|
|
56
|
+
*/
|
|
57
|
+
export declare const LONG_POLL_REQUEST_TYPES: ReadonlySet<string>;
|
|
53
58
|
export declare class MissingDaemonVersionError extends Error {
|
|
54
59
|
constructor();
|
|
55
60
|
}
|
|
@@ -197,6 +197,11 @@ function getBrowserHostCapability(capabilities) {
|
|
|
197
197
|
return parsed.success ? parsed.data : null;
|
|
198
198
|
}
|
|
199
199
|
const SLOW_REQUEST_THRESHOLD_MS = 500;
|
|
200
|
+
/**
|
|
201
|
+
* Requests designed to block until something happens (a long-poll). They stay
|
|
202
|
+
* out of the request latency stats and the slow-request log.
|
|
203
|
+
*/
|
|
204
|
+
export const LONG_POLL_REQUEST_TYPES = new Set(["wait_for_finish_request"]);
|
|
200
205
|
const EXTERNAL_SESSION_DISCONNECT_GRACE_MS = 90000;
|
|
201
206
|
const HELLO_TIMEOUT_MS = 15000;
|
|
202
207
|
const WS_CLOSE_HELLO_TIMEOUT = 4001;
|
|
@@ -1385,6 +1390,11 @@ export class VoiceAssistantWebSocketServer {
|
|
|
1385
1390
|
}
|
|
1386
1391
|
const startMs = performance.now();
|
|
1387
1392
|
await activeConnection.session.handleMessage(message.message);
|
|
1393
|
+
if (LONG_POLL_REQUEST_TYPES.has(message.message.type)) {
|
|
1394
|
+
// Blocking until the agent finishes IS the contract; counting it as request
|
|
1395
|
+
// latency (or as a slow request) reports the design as a regression.
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1388
1398
|
const durationMs = performance.now() - startMs;
|
|
1389
1399
|
this.recordRequestLatency(message.message.type, durationMs);
|
|
1390
1400
|
if (durationMs >= SLOW_REQUEST_THRESHOLD_MS) {
|
|
@@ -21,7 +21,10 @@ export interface WorkspaceDirectoryDeps {
|
|
|
21
21
|
workspaceRegistry: {
|
|
22
22
|
list(): Promise<PersistedWorkspaceRecord[]>;
|
|
23
23
|
};
|
|
24
|
-
|
|
24
|
+
/** With `workspaceIds`, may omit stored agents no descriptor for them depends on. */
|
|
25
|
+
listAgentPayloads(options?: {
|
|
26
|
+
workspaceIds?: ReadonlySet<string>;
|
|
27
|
+
}): Promise<AgentSnapshotPayload[]>;
|
|
25
28
|
listTerminalActivityContributions(): Promise<Array<{
|
|
26
29
|
cwd: string;
|
|
27
30
|
workspaceId?: string;
|
|
@@ -108,8 +108,9 @@ export class WorkspaceDirectory {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
async buildDescriptorMap(options) {
|
|
111
|
+
const requestedWorkspaceIds = options.workspaceIds ? new Set(options.workspaceIds) : null;
|
|
111
112
|
const [agents, persistedWorkspaces, persistedProjects, terminalContributions] = await Promise.all([
|
|
112
|
-
this.deps.listAgentPayloads(),
|
|
113
|
+
this.deps.listAgentPayloads(requestedWorkspaceIds ? { workspaceIds: requestedWorkspaceIds } : undefined),
|
|
113
114
|
this.deps.workspaceRegistry.list(),
|
|
114
115
|
this.deps.projectRegistry.list(),
|
|
115
116
|
this.deps.listTerminalActivityContributions(),
|
|
@@ -120,7 +121,7 @@ export class WorkspaceDirectory {
|
|
|
120
121
|
const archivedProjectIds = new Set(persistedProjects.filter((project) => project.archivedAt).map((project) => project.projectId));
|
|
121
122
|
const activeRecords = persistedWorkspaces.filter((workspace) => !workspace.archivedAt && !archivedProjectIds.has(workspace.projectId));
|
|
122
123
|
const descriptorsByWorkspaceId = new Map();
|
|
123
|
-
const workspaceIds =
|
|
124
|
+
const workspaceIds = requestedWorkspaceIds;
|
|
124
125
|
const activeWorkspaceIds = new Set(activeRecords.map((workspace) => workspace.workspaceId));
|
|
125
126
|
const includedWorkspaces = activeRecords.filter((workspace) => !workspaceIds || workspaceIds.has(workspace.workspaceId));
|
|
126
127
|
const activeRecordsByWorkspaceId = new Map(activeRecords.map((workspace) => [workspace.workspaceId, workspace]));
|