Symptom
packages/claude-code-headless/src/terminal/HeadlessTerminal.ts:600-613 gates snapshots on exact equality of plain/recent, which a spinner glyph or elapsed timer defeats every 100 ms. Every snapshot then runs two per-cell markdown walks (snapshotMarkdown, snapshotRecentMarkdown), and ClaudeCodeHeadless.ts:548-611 runs parseClaudeComposerState + snapshotComposerAttributes() (cell walk), the trust/resume/permission/compaction regex detectors, detectSlashPicker(term) + detectAskUserQuestion(term) (live-grid walks), four JSON.stringify keys and extractAssistantInProgress(recent). With ~10 sessions thinking: 60–100 snapshot pipelines/s ≈ 300–500 cell walks/s on the main thread for a spinner glyph. #761 gates the emit in the app's session manager; this issue removes the work at its source.
Expected
- Normalise the spinner glyph set (
ScreenParser.ts:281-284,321) and (Ns · …) timers before the equality gate; for a spinner-only diff run only detectActivity, skip the markdown walks, the attribute walk, the grid walks and the detectors.
- Cap headless
scrollback 10000 → 2000 (HeadlessTerminal.ts:251-256; codex same): nothing reads beyond snapshotRecent(200); up to −12 MB per session.
- Same for codex-headless.
Submodule repos (separate PRs + pin bumps). Estimated −80–90% snapshot pipelines while thinking.
Refs #103, #390. Source: architecture audit 2026-09-03 (scratchpad/arch-perf-audit.md).
Symptom
packages/claude-code-headless/src/terminal/HeadlessTerminal.ts:600-613gates snapshots on exact equality ofplain/recent, which a spinner glyph or elapsed timer defeats every 100 ms. Every snapshot then runs two per-cell markdown walks (snapshotMarkdown,snapshotRecentMarkdown), andClaudeCodeHeadless.ts:548-611runsparseClaudeComposerState+snapshotComposerAttributes()(cell walk), the trust/resume/permission/compaction regex detectors,detectSlashPicker(term)+detectAskUserQuestion(term)(live-grid walks), fourJSON.stringifykeys andextractAssistantInProgress(recent). With ~10 sessions thinking: 60–100 snapshot pipelines/s ≈ 300–500 cell walks/s on the main thread for a spinner glyph. #761 gates the emit in the app's session manager; this issue removes the work at its source.Expected
ScreenParser.ts:281-284,321) and(Ns · …)timers before the equality gate; for a spinner-only diff run onlydetectActivity, skip the markdown walks, the attribute walk, the grid walks and the detectors.scrollback10000 → 2000 (HeadlessTerminal.ts:251-256; codex same): nothing reads beyondsnapshotRecent(200); up to −12 MB per session.Submodule repos (separate PRs + pin bumps). Estimated −80–90% snapshot pipelines while thinking.
Refs #103, #390. Source: architecture audit 2026-09-03 (scratchpad/arch-perf-audit.md).