v0.7.2.md
docs/release-notes/v0.7.2.md
Tesserae v0.7.2 — discovery and compile no longer hang
<!-- translations:start -->
한국어 · 中文 · 日本語 · Русский · Español · Français · Deutsch
<!-- translations:end -->
Released 2026-06-12 · PyPI · GitHub release · pip install --upgrade tesserae==0.7.2
A bugfix release that removes three ways Tesserae could stall on machines with large agent-session histories: session discovery that never returned, CLI-agent subprocesses that wedged forever on timeout, and concurrent compiles stacking onto the same project state.
1. tesserae sessions discover returns — even with tens of GB of history
Discovery used to fully JSON-parse every transcript of every project under every account root before filtering. On a machine with ~57 GB of Claude Code / Codex history that meant the command effectively never returned.
Three fixes, multiplied together:
- Marker pre-filter — a transcript can only belong to the focused project if the project path appears literally in the file, so foreign transcripts are now screened with a raw byte scan (~50× faster than parsing) before any JSON work.
- Symlinked account roots are deduplicated —
~/.claudepointing at~/.claude-personal1no longer causes every transcript to be scanned twice. - mtime-keyed scan cache — screen results persist in
~/.cache/tesserae/discovery_scan.sqlite(override withTESSERAE_DISCOVERY_CACHE), so repeat runs only re-read new or changed transcripts.
Measured on the motivating machine: never returns → 3m16s cold → 1m26s warm, 4,048 sessions found. tesserae refresh and session import share the same path and speed up equally.
2. CLI-agent timeouts can no longer wedge a compile
codex exec / claude -p calls used subprocess.run(capture_output=True, timeout=...), which kills only the direct child on timeout and then drains the output pipes with no timeout. The agent CLIs spawn their own children that inherit those pipes, so a timeout could leave a compile blocked at 0% CPU indefinitely (observed: ~2 days) behind orphaned grandchildren.
LLM CLI calls now run in their own process group, and a timeout kills the whole group with a bounded drain — a timeout always means dead, never wedged.
3. One compile per project at a time
ProjectWiki.compile now holds an exclusive lock on .tesserae/compile.lock. A hook-triggered refresh that fires while a compile is already running fails fast with a clear message naming the holder pid, instead of silently stacking onto the same .tesserae state. Set TESSERAE_COMPILE_LOCK_WAIT=<seconds> to wait for the lock instead. The lock is flock(2)-based, so a crashed compile never leaves a stale lock behind.
4. tesserae --version
The root help now leads with the installed version, and tesserae --version (also -V / version) prints it directly.
Upgrading from v0.7.1
Drop-in. No config changes. The first sessions discover / refresh after upgrading pays a one-time screening pass to populate the scan cache; runs after that are fast.