(stateDir: string, shortId: string)
| 433 | export function listRunsForThread(stateDir: string, shortId: string): RunRecord[] { |
| 434 | return listRuns(stateDir).filter(r => r.shortId === shortId); |
| 435 | } |
| 436 | |
| 437 | export function getLatestRun(stateDir: string, shortId: string): RunRecord | null { |
| 438 | const runs = listRunsForThread(stateDir, shortId); |
| 439 | return runs.length > 0 ? runs[0] : null; |
| 440 | } |
| 441 | |
| 442 | /** Remove all run records for a thread, along with each run's captured |
| 443 | * detached-runner output (`logs/detached-<runId>.log` — it can contain |
| 444 | * prompts and results, so a local delete must reach it). Called by |
| 445 | * `delete` so the ledger can't hold orphaned records for a thread whose |
| 446 | * mapping, log, and PID file are gone — bare `follow` selects from run |
| 447 | * records and would otherwise attach to (or hang on) a deleted thread's |
| 448 | * stale run. */ |
| 449 | export function removeRunsForThread(stateDir: string, shortId: string): void { |
| 450 | for (const r of listRunsForThread(stateDir, shortId)) { |
| 451 | for (const path of [ |
| 452 | runFilePath(stateDir, r.runId), |
| 453 | join(stateDir, "logs", `detached-${r.runId}.log`), |
no test coverage detected