fix: liveness, session names, project identity, search ordering and load time (v1.6.0) - #69
Open
Mr-Godot wants to merge 3 commits into
Open
fix: liveness, session names, project identity, search ordering and load time (v1.6.0)#69Mr-Godot wants to merge 3 commits into
Mr-Godot wants to merge 3 commits into
Conversation
…butions, fix search ordering and silent failures P1 lib/scanner/live-sessions.ts: read ~/.claude/sessions/*.json (pid + status), filter by process.kill(pid,0) liveness, memoized 1s. Read-only. P2 active-detector: drop the mtime heuristic that marked months-dead sessions 'working'. isActive stays true only for 'working' so waiting sessions do not bypass the hidden-project filter, readmit stubs, or pin the 5s poll. The 3s active poll no longer runs a full 454-file scan. P3 stats-parser: cache per-session contributions keyed on a fingerprint that includes the subagent directory, killing the 11.1s re-parse per stats request. persistSummaryCache now skips the write when nothing changed. P4 search: stop swallowing provider failures into an empty result, log the real driver error, coalesce concurrent refreshes, yield during indexing, and stop the retry storm on a rejected search query. P5 search: order hits newest-first (ORDER BY ts DESC, sid tiebreak), make the representative row the most recent matching block so date and snippet agree, and apply the limit as a session count server-side.
…lation G liveness gaps: the 3s poll now applies the same busy-mtime rule as the scan, so a killed-while-busy session can no longer be flipped back to 'working'. Forced search refresh no longer no-ops behind an in-flight non-forced pass. P6 names: drop the ~/.claude/sessions/*.json name tier entirely (it contributed 163 duplicates, 1 wrong value, 15 derived junk names like 'agents-0a', and 0 unique correct values). The durable name is the JSONL custom-title. Fixes firstUserMessage for string-typed content and skips injected turns. SUMMARY_CACHE_VERSION 4 -> 5 to evict poisoned entries. P7 identity: resolve each project from its recorded cwd into a new realPath field (projectPath keeps its lookup meaning), disambiguate same-basename projects, flag dead paths instead of hiding them, and return 409 from the launch handler rather than spawning into a directory that no longer exists. P8 UI: shared EmptyState, honest loading affordance that keeps previous rows, suppressed stale-filter flash, surfaced search index staleness, and an unset theme preference now resolves to dark in both the pre-paint script and the provider. Also fixes a pre-existing data-loss bug: getCacheDir() ignored CLAUDE_HOME, so the e2e suite wrote to the real ~/.claude-dashboard and pruned the live search index to its 3 fixture sessions. All dashboard paths now derive from getDashboardDir(), which honours CLAUDE_HOME.
PR Size Analysis
This label helps reviewers prioritize PRs by size. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the issues that were blocking release, found by a 7-track investigation swarm with adversarial critics on each proposed fix.
What was actually wrong
Search returning 1 result was not a search bug.
getCacheDir()ignoredCLAUDE_HOME, so runningnpm run e2epointed the scanner at fixtures but left every cache path aimed at the real~/.claude-dashboard. It indexed the 3 fixture sessions and pruned all 443 real ones. Fixed at the code level viagetDashboardDir(), plus a fail-fast guard inplaywright.config.ts.False "active" sessions came from inferring liveness by transcript mtime. Measured drift between mtime and the last real message reaches 174 days, and an external process touches these files hourly without appending. Liveness now comes from Claude Code's own process registry (
~/.claude/sessions/*.json), gated on the recorded pid actually running.waiting(live but idle) is now distinct fromworking./renameshowingagents-0acame from the registry's auto-derived placeholder names, and from that registry only existing while a process is alive. The whole tier is deleted; the durable name is the transcript's own title entry. Measured contribution of the removed tier: 163 duplicates, 1 wrong value, 15 junk, 0 unique correct values.Slow loads were an uncached full re-parse of the ~1 GB corpus on every stats request, plus a 3s liveness poll that triggered a full scan of every session file.
Measured on the live corpus (411 sessions, ~1 GB)
Also fixed
Verification
node:fs,better-sqlite3,readdirSync,process.kill,os.homedir— zero hits.claude-dashboard;~/.clauderemains read-only, with a regression test spying on write calls during a full scan plus a liveness pollKnown gaps
subagentFingerprintcost is asserted rather than measured (warm stats at 9ms suggests it is fine)