diff --git a/src/main/services/team/TeamDataService.ts b/src/main/services/team/TeamDataService.ts index 405a7f31..ffc1aa7a 100644 --- a/src/main/services/team/TeamDataService.ts +++ b/src/main/services/team/TeamDataService.ts @@ -256,7 +256,7 @@ async function mapLimitLocal( if (index >= items.length) { return; } - results[index] = await mapper(items[index]!); + results[index] = await mapper(items[index]); } }) ); diff --git a/src/main/services/team/TeamProvisioningService.ts b/src/main/services/team/TeamProvisioningService.ts index a9db5928..d8e3d5b9 100644 --- a/src/main/services/team/TeamProvisioningService.ts +++ b/src/main/services/team/TeamProvisioningService.ts @@ -26006,7 +26006,12 @@ export class TeamProvisioningService { ): { rows: RuntimeTelemetryProcessTableRow[] | null } | null { const cached = this.runtimeProcessRowsForUsageSnapshotByTeam.get(teamName); const nowMs = Date.now(); - if (!cached || cached.expiresAtMs <= nowMs || cached.runId !== runId) { + if ( + !cached || + cached.expiresAtMs <= nowMs || + cached.runId !== runId || + cached.generation !== this.getRuntimeSnapshotCacheGeneration(teamName) + ) { return null; } @@ -26026,7 +26031,10 @@ export class TeamProvisioningService { return { rows: null }; } - const rows = cached.rows.filter((row) => row.runtimeTelemetrySource !== 'windows-host'); + const rows = + this.normalizeRuntimeProcessRowsForTelemetry(cached.rows)?.filter( + (row) => row.runtimeTelemetrySource !== 'windows-host' + ) ?? []; return { rows }; } @@ -26427,14 +26435,10 @@ export class TeamProvisioningService { } private shouldSampleMissingRuntimeUsageStatsWithPidusage(): boolean { - if (!this.isRuntimePidusageTelemetryEnabled()) { - return false; - } - // CPU/RSS telemetry already comes from the enriched process table in the // default path. If this opt-in is enabled, preserve the older fallback for // missing rows across platforms. - return true; + return this.isRuntimePidusageTelemetryEnabled(); } private isRuntimePidusageTelemetryEnabled(): boolean { diff --git a/src/main/services/team/TeamTranscriptProjectResolver.ts b/src/main/services/team/TeamTranscriptProjectResolver.ts index 9f10fc19..b6f583d5 100644 --- a/src/main/services/team/TeamTranscriptProjectResolver.ts +++ b/src/main/services/team/TeamTranscriptProjectResolver.ts @@ -72,12 +72,12 @@ interface TeamTranscriptProjectContextOptions { includeTeamSubagentSessionDiscovery?: boolean; } -type TeamTranscriptFileStat = { +interface TeamTranscriptFileStat { mtimeMs: number; size: number; ctimeMs?: number; isFile: () => boolean; -}; +} type ScannedSessionProjectMatch = Omit & { projectPath?: string; diff --git a/test/main/services/team/TeamProvisioningService.test.ts b/test/main/services/team/TeamProvisioningService.test.ts index 610e8d67..f7b3981f 100644 --- a/test/main/services/team/TeamProvisioningService.test.ts +++ b/test/main/services/team/TeamProvisioningService.test.ts @@ -3514,7 +3514,7 @@ describe('TeamProvisioningService', () => { expect(listRuntimeProcessTableForCurrentPlatform).toHaveBeenCalledTimes(2); }); - it('keeps the short live runtime metadata cache for tracked runs', async () => { + it('reuses process rows through the short liveness cache for tracked runs', async () => { vi.useFakeTimers(); vi.setSystemTime(new Date('2026-05-03T12:00:00.000Z')); const svc = new TeamProvisioningService(); @@ -3533,6 +3533,11 @@ describe('TeamProvisioningService', () => { vi.setSystemTime(new Date('2026-05-03T12:00:03.000Z')); await (svc as any).getLiveTeamAgentRuntimeMetadata('runtime-team'); + expect(listRuntimeProcessTableForCurrentPlatform).toHaveBeenCalledTimes(1); + + vi.setSystemTime(new Date('2026-05-03T12:00:06.000Z')); + await (svc as any).getLiveTeamAgentRuntimeMetadata('runtime-team'); + expect(listRuntimeProcessTableForCurrentPlatform).toHaveBeenCalledTimes(2); });