Search That Always Works, Teams That Survive Restarts
Two problems that show up differently but have the same root cause: data that should be there isn’t. v0.15.0 fixes both — for search and for teams.
Search that finds what you’re looking for
The previous search architecture had a gap. Tantivy’s full-text index is fast and precise for keyword queries, but it only knows about sessions it has indexed. If you searched for something before indexing completed, or used a query that Tantivy couldn’t tokenize well, you got nothing.
v0.15.0 introduces a unified search engine that never gives up empty-handed. The flow:
- SQLite pre-filter — structured filters (project, date range, model) run first against the database to narrow the candidate session IDs
- Tantivy full-text — runs against the pre-filtered set, returns ranked results with snippets
- ripgrep fallback — if Tantivy returns 0 results, grep scans the JSONL files directly for substring matches
The fallback is automatic and transparent. Results from grep are labeled “Substring matches” so you know which engine answered — useful for understanding whether your query hit the full-text index or a literal match.
The frontend sends a single request to /api/search. It doesn’t know or care which engine responded. This follows the project’s one-endpoint principle: backend decides the strategy, frontend renders the result.
The sidecar rewrite
The Node.js sidecar — which brokers communication between the Rust server and Claude Agent SDK sessions — has been rewritten from scratch for Agent SDK v0.2.72.
The old sidecar accumulated debt: a growing list of edge cases, a protocol that had evolved organically, and two bugs that caused real failures in production (a broken resume URL and a pipe deadlock that could freeze a session).
The new sidecar is built around four distinct modules:
- Session registry — a typed map of active sessions with sequenced event emission, so events always arrive in order
- Permission handler — routes
canUseTooldecisions with full context forwarded to the frontend, enabling per-tool approval UI - Event mapper — a pure function that translates all 22 SDK message types to the new typed protocol (27 server events, 8 client messages), with no side effects
- SDK session — manages create/resume lifecycle with a long-lived stream loop and clean shutdown
The resume URL bug (wrong path) and pipe deadlock (read loop not draining stderr) are both fixed. Crash recovery now works reliably.
SSE-driven live data
The live monitor previously fetched session state on a polling interval. Between polls, you could be looking at stale data — a session that had already ended, or a new session that hadn’t appeared yet.
Live data now comes through server-sent events. The Rust server pushes updates as they happen. The browser receives them immediately. The polling loop is gone.
Persistent team browsing
When you opened claude-view after a restart, team data was often missing. The live session store is in-memory, so anything that happened before the restart wasn’t there. Teams showed as empty or incomplete until sessions were re-indexed.
v0.15.0 adds a JSONL fallback layer for teams. When the in-memory store is cold — either because the server just started or a session was closed — claude-view reconstructs team composition and message inbox directly from the JSONL files. The reconstruction is a single-pass scan per session, not a full re-index.
Teams now persist across server restarts. If you were in the middle of a multi-agent session last night, you can open claude-view this morning and still see the full team composition and message history.
Update now
npx claude-view@latestRun a search to see the unified engine in action. Start a multi-agent session, restart the server, and check whether the team is still there.