diff --git a/src/main/services/team/TeamTranscriptProjectResolver.ts b/src/main/services/team/TeamTranscriptProjectResolver.ts index 4099ce1d..271eae47 100644 --- a/src/main/services/team/TeamTranscriptProjectResolver.ts +++ b/src/main/services/team/TeamTranscriptProjectResolver.ts @@ -204,37 +204,37 @@ export class TeamTranscriptProjectResolver { ); } - private async listSessionDirIds(projectDir: string): Promise { + private async readProjectDirEntries(projectDir: string): Promise { try { - const dirEntries = await fs.readdir(projectDir, { withFileTypes: true }); - return dirEntries - .filter((entry) => entry.isDirectory() && isSessionDirectoryName(entry.name)) - .map((entry) => entry.name); + return await fs.readdir(projectDir, { withFileTypes: true }); } catch { logger.debug(`Cannot read transcript project dir: ${projectDir}`); - return []; + return null; } } - private async listTeamRootSessionIds(projectDir: string, teamName: string): Promise { - let dirEntries: Dirent[]; - try { - dirEntries = await fs.readdir(projectDir, { withFileTypes: true }); - } catch { - logger.debug(`Cannot read transcript project dir: ${projectDir}`); + private async listSessionDirIds(projectDir: string): Promise { + const dirEntries = await this.readProjectDirEntries(projectDir); + if (!dirEntries) { return []; } - const rootJsonlEntries = dirEntries.filter( - (entry) => entry.isFile() && entry.name.endsWith('.jsonl') - ); + return dirEntries + .filter((entry) => entry.isDirectory() && isSessionDirectoryName(entry.name)) + .map((entry) => entry.name); + } + + private async collectRootJsonlSessionIds( + rootJsonlEntries: Dirent[], + projectDir: string, + teamName: string + ): Promise { const discovered = new Set(); let nextIndex = 0; - const worker = async (): Promise => { + const scanNextRootEntry = async (): Promise => { while (nextIndex < rootJsonlEntries.length) { - const index = nextIndex++; - const entry = rootJsonlEntries[index]; + const entry = rootJsonlEntries[nextIndex++]; const filePath = path.join(projectDir, entry.name); if (!(await this.fileBelongsToTeam(filePath, teamName))) { continue; @@ -245,13 +245,25 @@ export class TeamTranscriptProjectResolver { await Promise.all( Array.from({ length: Math.min(ROOT_DISCOVERY_CONCURRENCY, rootJsonlEntries.length) }, () => - worker() + scanNextRootEntry() ) ); return [...discovered]; } + private async listTeamRootSessionIds(projectDir: string, teamName: string): Promise { + const dirEntries = await this.readProjectDirEntries(projectDir); + if (!dirEntries) { + return []; + } + + const rootJsonlEntries = dirEntries.filter( + (entry) => entry.isFile() && entry.name.endsWith('.jsonl') + ); + return this.collectRootJsonlSessionIds(rootJsonlEntries, projectDir, teamName); + } + private async fileBelongsToTeam(filePath: string, teamName: string): Promise { const stream = createReadStream(filePath, { encoding: 'utf8' }); const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });