PID Files, One Store, and Terminal Panes That Stay Put
If you’ve ever restarted the claude-view server and found ghost sessions lingering in your dashboard, or watched a session flicker between “active” and “unknown” because the process scanner missed a heartbeat — v0.36.0 fixes the root cause.
PID files as the single source of truth
Previous versions detected Claude Code sessions by scanning the process tree — looking for specific process signatures, checking parent-child relationships, cross-referencing tmux session names. It worked, but it was fragile. Process tree scanning races with process startup and teardown, and different OS versions report process metadata inconsistently.
v0.36.0 flips the model. Claude Code writes a PID file when it starts and removes it when it exits. The oracle now reads these files instead of scanning /proc or ps. This is the same pattern used by PostgreSQL, nginx, and most Unix daemons — because it works.
The oracle runs on a two-tier refresh cycle: PID file checks every 2 seconds (cheap — just stat calls), full system reconciliation every 10 seconds (for cleanup and edge cases). The result is faster detection with lower CPU usage.
One store to rule them all
The server previously maintained two separate session stores: CliSessionStore for CLI-discovered sessions and the main LiveSessionStore for everything else. This dual-store architecture meant ownership data, tmux bindings, and lifecycle events had to be synchronized between two maps — a constant source of subtle state bugs.
v0.36.0 collapses both into a single unified store. Every session — whether discovered via CLI, spawned by the SDK, or posted by tmux — lives in one map with one lifecycle. The SessionEvent enum was simplified from multiple variants to just SessionUpsert and SessionRemove, making the event flow easier to reason about.
A side effect: server restarts now properly reconcile tmux ownership. The startup path queries tmux for active sessions and reconciles against PID files, so ghost sessions from the previous server lifetime are cleaned up immediately rather than lingering until the next full scan.
Terminal panes, redesigned
The Live Monitor’s terminal panes got a Zed-inspired overhaul. Chrome has been stripped down to the minimum — no redundant borders, no wasted header space. Each session gets exactly one terminal panel (the duplicate CLI panel bug is gone), with keyboard shortcuts for zoom and layout management.
Sessions also show their lifecycle state visually. A new “Spawning” status with a pulsing blue indicator appears the moment a session is detected via PID file, before the first JSONL output arrives. You see the session boot in real time instead of it appearing fully formed after a delay.
Under the hood
The closed session ring switched from an unbounded HashMap to a bounded VecDeque(100). Previously, every session that exited stayed in memory indefinitely for “recently closed” lookups. Now only the last 100 are kept, with constant-time insertion and bounded memory.
The dockview layout persistence was also hardened — saves now flush on unload, visibilitychange (hidden), and React unmount, covering all the ways a browser tab can close without the layout being saved.
Update now
npx claude-view@latestOpen the Live Monitor and watch a new Claude Code session boot — you’ll see it appear as “Spawning” with a blue dot before any output arrives.