fix(ci): refactor transcript project discovery

This commit is contained in:
777genius 2026-04-18 13:22:20 +03:00
parent d2ef5965e2
commit 1ee5dd38a5

View file

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