diff --git a/src/renderer/utils/sessionTitleParser.ts b/src/renderer/utils/sessionTitleParser.ts index 48f45092..45a80946 100644 --- a/src/renderer/utils/sessionTitleParser.ts +++ b/src/renderer/utils/sessionTitleParser.ts @@ -20,9 +20,9 @@ export interface ParsedSessionTitle { const PROVISION_RE = /^agent_teams_ui\s+\[Agent Team:\s*["\u201C]([^"\u201D]+)["\u201D]\s*\|\s*Project:\s*["\u201C]([^"\u201D]+)["\u201D]\s*\|\s*Lead:\s*["\u201C]([^"\u201D]+)["\u201D]\]/; -// Matches: Team Start [Agent Team: ...] or Team Start (resume) [Agent Team: ...] +// Matches: Team Start [Agent Team: ...] (after stripping optional "(resume)" prefix) const LAUNCH_RE = - /^Team Start(?:\s*\(resume\))?\s+\[Agent Team:\s*["\u201C]([^"\u201D]+)["\u201D]\s*\|\s*Project:\s*["\u201C]([^"\u201D]+)["\u201D]\s*\|\s*Lead:\s*["\u201C]([^"\u201D]+)["\u201D]\]/; + /^Team Start\s+\[Agent Team:\s*["\u201C]([^"\u201D]+)["\u201D]\s*\|\s*Project:\s*["\u201C]([^"\u201D]+)["\u201D]\s*\|\s*Lead:\s*["\u201C]([^"\u201D]+)["\u201D]\]/; // Matches one or more [Image #N] prefixes const IMAGE_PREFIX_RE = /^(?:\[Image\s+#\d+\]\s*)+/; @@ -33,7 +33,7 @@ export function parseSessionTitle(firstMessage: string | undefined): ParsedSessi } // New team provisioning: agent_teams_ui [Agent Team: ...] - const provisionMatch = firstMessage.match(PROVISION_RE); + const provisionMatch = PROVISION_RE.exec(firstMessage); if (provisionMatch) { return { kind: 'team-new', @@ -43,8 +43,9 @@ export function parseSessionTitle(firstMessage: string | undefined): ParsedSessi }; } - // Team resume/launch: Team Start [Agent Team: ...] - const launchMatch = firstMessage.match(LAUNCH_RE); + // Team resume/launch: Team Start [Agent Team: ...] or Team Start (resume) [...] + const launchMsg = firstMessage.replace(/^(Team Start)\s*\(resume\)/, '$1'); + const launchMatch = LAUNCH_RE.exec(launchMsg); if (launchMatch) { return { kind: 'team-resume', diff --git a/test/main/services/team/BranchStatusService.test.ts b/test/main/services/team/BranchStatusService.test.ts index 59b91429..07a83572 100644 --- a/test/main/services/team/BranchStatusService.test.ts +++ b/test/main/services/team/BranchStatusService.test.ts @@ -1,9 +1,13 @@ +import * as path from 'path'; + import { afterEach, describe, expect, it, vi } from 'vitest'; import { BranchStatusService } from '@main/services/team/BranchStatusService'; import type { ProjectBranchChangeEvent } from '@shared/types'; +const REPO = path.normalize('/repo'); + interface Deferred { promise: Promise; resolve: (value: T) => void; @@ -33,16 +37,16 @@ describe('BranchStatusService', () => { const events: ProjectBranchChangeEvent[] = []; const service = new BranchStatusService((event) => events.push(event), { getBranch }); - await service.setTracking('/repo', true); - expect(events).toEqual([{ projectPath: '/repo', branch: 'main' }]); + await service.setTracking(REPO, true); + expect(events).toEqual([{ projectPath: REPO, branch: 'main' }]); await vi.advanceTimersByTimeAsync(20_000); expect(events).toHaveLength(1); await vi.advanceTimersByTimeAsync(20_000); expect(events).toEqual([ - { projectPath: '/repo', branch: 'main' }, - { projectPath: '/repo', branch: 'feature/refactor' }, + { projectPath: REPO, branch: 'main' }, + { projectPath: REPO, branch: 'feature/refactor' }, ]); service.dispose(); @@ -54,15 +58,15 @@ describe('BranchStatusService', () => { const getBranch = vi.fn().mockResolvedValue('main'); const service = new BranchStatusService(() => undefined, { getBranch }); - await service.setTracking('/repo', true); - await service.setTracking('/repo', true); + await service.setTracking(REPO, true); + await service.setTracking(REPO, true); expect(getBranch).toHaveBeenCalledTimes(1); - await service.setTracking('/repo', false); + await service.setTracking(REPO, false); await vi.advanceTimersByTimeAsync(20_000); expect(getBranch).toHaveBeenCalledTimes(2); - await service.setTracking('/repo', false); + await service.setTracking(REPO, false); await vi.advanceTimersByTimeAsync(40_000); expect(getBranch).toHaveBeenCalledTimes(2); @@ -79,11 +83,11 @@ describe('BranchStatusService', () => { const events: ProjectBranchChangeEvent[] = []; const service = new BranchStatusService((event) => events.push(event), { getBranch }); - const firstEnable = service.setTracking('/repo', true); + const firstEnable = service.setTracking(REPO, true); await Promise.resolve(); - await service.setTracking('/repo', false); - const secondEnable = service.setTracking('/repo', true); + await service.setTracking(REPO, false); + const secondEnable = service.setTracking(REPO, true); await Promise.resolve(); first.resolve('main'); @@ -92,7 +96,7 @@ describe('BranchStatusService', () => { second.resolve('feature/refactor'); await secondEnable; - expect(events).toEqual([{ projectPath: '/repo', branch: 'feature/refactor' }]); + expect(events).toEqual([{ projectPath: REPO, branch: 'feature/refactor' }]); service.dispose(); });