* Scans all project directories using filesystem metadata only (no JSONL parsing). * Returns a list of session file info sorted by mtime descending. * Yields to the event loop between project directories to keep the UI responsive.
()
| 2753 | * Yields to the event loop between project directories to keep the UI responsive. |
| 2754 | */ |
| 2755 | async function scanAllSessions(): Promise<LiteSessionInfo[]> { |
| 2756 | const projectsDir = getProjectsDir() |
| 2757 | |
| 2758 | let dirents: Awaited<ReturnType<typeof readdir>> |
| 2759 | try { |
| 2760 | dirents = await readdir(projectsDir, { withFileTypes: true }) |
| 2761 | } catch { |
| 2762 | return [] |
| 2763 | } |
| 2764 | |
| 2765 | const projectDirs = dirents |
| 2766 | .filter(dirent => dirent.isDirectory()) |
| 2767 | .map(dirent => join(projectsDir, dirent.name)) |
| 2768 | |
| 2769 | const allSessions: LiteSessionInfo[] = [] |
| 2770 | |
| 2771 | for (let i = 0; i < projectDirs.length; i++) { |
| 2772 | const sessionFiles = await getSessionFilesWithMtime(projectDirs[i]!) |
| 2773 | for (const [sessionId, fileInfo] of sessionFiles) { |
| 2774 | allSessions.push({ |
| 2775 | sessionId, |
| 2776 | path: fileInfo.path, |
| 2777 | mtime: fileInfo.mtime, |
| 2778 | size: fileInfo.size, |
| 2779 | }) |
| 2780 | } |
| 2781 | // Yield to event loop every 10 project directories |
| 2782 | if (i % 10 === 9) { |
| 2783 | await new Promise<void>(resolve => setImmediate(resolve)) |
| 2784 | } |
| 2785 | } |
| 2786 | |
| 2787 | // Sort by mtime descending (most recent first) |
| 2788 | allSessions.sort((a, b) => b.mtime - a.mtime) |
| 2789 | return allSessions |
| 2790 | } |
| 2791 | |
| 2792 | // ============================================================================ |
| 2793 | // Main Function |
no test coverage detected