emacs: fix pm-sidebar render runaway (overlay leak + render debounce)
pm-sidebar--render rebuilt the buffer with erase-buffer but never deleted
the overlays the previous render created (visibility indicators, magit
highlight/selection). erase-buffer only collapses overlays to point 1, so
they accumulated every refresh; the leaked overlays anchor markers near
point 1, turning every insert into O(stale-markers) and growing RSS without
bound until the single-threaded daemon pegged a core and wedged (observed
23GB+ RSS, unrecoverable without a daemon restart).
- render: remove-overlays before erase-buffer (stops the leak)
- handle + window-size-change: coalesce renders behind a 0.2s timer so an
SSE burst (snapshot replay, status churn, resize storm) collapses into
one render instead of one full rebuild per event
- proc-filter: walk lines with a running index + one trailing substring
(was O(n^2) substring-per-line), use string-replace, and cap the
accumulator to guard a non-terminating line
Add ERT coverage: overlay cleanup, render coalescing, quit cancels the
render timer, chunked-SSE parsing, accumulator cap.
agent: add `pm agent serve` daemon for live session tracking
A headless daemon (stdlib threaded HTTP + SSE, ephemeral WAL SQLite) that
ingests best-effort hook events from Claude/Codex/Cursor and broadcasts live
session state to observers (the Emacs sidebar, curl).
- serve/{server,store,status,fallback}: HTTP+SSE server, WAL store, pure
status-derivation, and a Tier-2 transcript fallback poller. Status vocab:
working / waiting_response / waiting_permission / idle / unknown, with
openui-style activity-gating and a pid-liveness cleanup backstop.
- install-hooks: a shared stdlib reporter installed for Claude (settings.json),
Codex (a --profile pm config, since isaac regenerates ~/.codex/hooks.json),
and Cursor (~/.cursor/hooks.json, incl. shell/MCP approval). Skips the
Claude-hook double-report Cursor triggers.
- transcript: shared title library (custom-title > ai-title > synthetic >
first prompt) that also parses Codex rollouts natively; the fallback fills
source-reader titles (e.g. Cursor) for sessions it cannot parse.
- config [serve], opt-in WAL in sqlite_db, systemd unit, tests.
emacs: fix pm-sidebar render runaway (overlay leak + render debounce)
pm-sidebar--render rebuilt the buffer with erase-buffer but never deleted
the overlays the previous render created (visibility indicators, magit
highlight/selection). erase-buffer only collapses overlays to point 1, so
they accumulated every refresh; the leaked overlays anchor markers near
point 1, turning every insert into O(stale-markers) and growing RSS without
bound until the single-threaded daemon pegged a core and wedged (observed
23GB+ RSS, unrecoverable without a daemon restart).
- render: remove-overlays before erase-buffer (stops the leak)
- handle + window-size-change: coalesce renders behind a 0.2s timer so an
SSE burst (snapshot replay, status churn, resize storm) collapses into
one render instead of one full rebuild per event
- proc-filter: walk lines with a running index + one trailing substring
(was O(n^2) substring-per-line), use string-replace, and cap the
accumulator to guard a non-terminating line
Add ERT coverage: overlay cleanup, render coalescing, quit cancels the
render timer, chunked-SSE parsing, accumulator cap.