| 360 | } |
| 361 | |
| 362 | function* walkClaudeCodeProjects(ctx: WalkContext): Generator<{ path: string; type: MemoryType }> { |
| 363 | const root = join(HOME, ".claude", "projects"); |
| 364 | if (!existsSync(root)) return; |
| 365 | let projectDirs: string[]; |
| 366 | try { |
| 367 | projectDirs = readdirSync(root); |
| 368 | } catch { |
| 369 | return; |
| 370 | } |
| 371 | for (const dir of projectDirs) { |
| 372 | const fullDir = join(root, dir); |
| 373 | let entries: string[]; |
| 374 | try { |
| 375 | entries = readdirSync(fullDir); |
| 376 | } catch { |
| 377 | continue; |
| 378 | } |
| 379 | for (const entry of entries) { |
| 380 | if (!entry.endsWith(".jsonl")) continue; |
| 381 | const fullPath = join(fullDir, entry); |
| 382 | try { |
| 383 | const st = statSync(fullPath); |
| 384 | if (st.mtimeMs < ctx.windowStartMs) continue; |
| 385 | } catch { |
| 386 | continue; |
| 387 | } |
| 388 | yield { path: fullPath, type: "transcript" }; |
| 389 | } |
| 390 | } |
| 391 | } |
| 392 | |
| 393 | function* walkCodexSessions(ctx: WalkContext): Generator<{ path: string; type: MemoryType }> { |
| 394 | const root = join(HOME, ".codex", "sessions"); |