Release 0.7.3 — fix Claude run logs collapsing to a single page#16
Conversation
Claude Code's fullscreen TUI (alternate-screen renderer, a research preview) repaints in place, so the pane capture the Log tab emulates collapsed to the final frame — while line-oriented CLIs like codex showed in full. Force Claude's classic inline/scrollback renderer via CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 in the profile env, which overrides any tui setting and keeps output in native scrollback so the capture scrolls normally and the whole session is reconstructable. As defense-in-depth, LogView now detects an alternate-screen switch — scanning the live stream and, on cold open, the tail-seek-skipped prefix — and the dashboard flags such a capture as showing only the final frame, pointing at the agent's full JSONL transcript. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
WalkthroughThe PR adds alternate-screen detection to log capture, propagates that state into the dashboard, sets the Claude profile environment override, and updates 0.7.3 version metadata. ChangesAlt-screen log capture and release updates
Sequence Diagram(s)sequenceDiagram
participant LogView
participant dashboard_poll_worker as dashboard poll worker
participant RichLogPane as RichLog pane
LogView->>dashboard_poll_worker: altscreen_seen in snapshot
dashboard_poll_worker->>RichLogPane: render fullscreen note
dashboard_poll_worker->>RichLogPane: include transcript path when present
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/test_profile.py`:
- Around line 63-64: The negative assertion in the profile test only covers
codex and gemini, leaving the built-in copilot profile unchecked. Update the
assertion loop in the test that iterates over profiles[name].env to include
copilot in the set so the “Claude only” contract is enforced across all built-in
profiles.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 47cb1101-b07c-4c0a-949b-42d2a1d19dc4
⛔ Files ignored due to path filters (11)
docs/images/dashboard.pngis excluded by!**/*.pngdocs/images/dashboard.svgis excluded by!**/*.svgdocs/images/demo.gifis excluded by!**/*.gifdocs/images/settings-scm.pngis excluded by!**/*.pngdocs/images/settings-scm.svgis excluded by!**/*.svgdocs/images/settings.svgis excluded by!**/*.svgdocs/images/start-run-modal.pngis excluded by!**/*.pngdocs/images/start-run-modal.svgis excluded by!**/*.svgdocs/images/sweep-decision.pngis excluded by!**/*.pngdocs/images/sweep-decision.svgis excluded by!**/*.svguv.lockis excluded by!**/*.lock
📒 Files selected for processing (11)
.claude-plugin/marketplace.jsonCHANGELOG.mdmodule.yamlpyproject.tomlsrc/automator/__init__.pysrc/automator/data/profiles/claude.tomlsrc/automator/data/skills/bmad-auto-setup/assets/module.yamlsrc/automator/tui/data.pysrc/automator/tui/screens/dashboard.pytests/test_profile.pytests/test_tui_data.py
🤖 Augment PR SummarySummary: Patch release 0.7.3 to prevent Claude Code’s fullscreen/alternate-screen rendering from collapsing captured run logs to a single screen in the TUI. Changes:
Technical Notes: Detection is best-effort and aims to warn when a pane capture is likely only the final frame due to fullscreen repaint semantics. 🤖 Was this summary useful? React with 👍 or 👎 |
| # cold-opened fullscreen log is still flagged; the tail is covered by | ||
| # the per-chunk scan below. | ||
| if self._offset > 0 and not self.altscreen_seen: | ||
| self._scan_prefix_for_altscreen(self._offset) |
There was a problem hiding this comment.
LogView.read_new() can end up scanning the entire skipped prefix up to self._offset, which could be very large and effectively defeats the max_bytes cap (and may stall the poll worker on huge logs). Since the enter marker is typically at session start, consider bounding this prefix scan to a smaller region to reduce worst-case I/O.
Severity: medium
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
There was a problem hiding this comment.
Addressed in 6e3ce94, with a deviation worth flagging.
The core concern is valid: the cold-open prefix scan read [0, self._offset) — up to nearly the whole file on a large finished log (worst case ~28 MB on the biggest captures here), defeating the max_bytes cap.
I did not bound it to the session start, though. In the one real fullscreen pane log we have, the alternate-screen enter marker sits at ~3.9 MB mid-stream (3.9 MB of classic output precedes it), so a start-only window would miss exactly what the scan exists to catch. Instead the scan is now capped at _ALTSCREEN_PREFIX_SCAN_CAP = 8 MiB: bounded worst-case I/O, while still covering a realistic multi-MB preamble. A marker past the cap on an oversized log is missed only on cold open — live-watching reads from offset 0 and still catches it. Added test_log_view_altscreen_prefix_scan_is_capped to pin the boundary.
Address PR #16 review feedback: - The cold-open altscreen prefix scan read [0, offset) — up to nearly the whole file on a large finished log — defeating the max_bytes cap (worst case ~28 MB on the biggest captures). Bound it to _ALTSCREEN_PREFIX_SCAN_CAP (8 MiB), which still covers a realistic multi-MB classic preamble before a TUI enters the alternate screen (the one real sample switches at ~3.9 MB). A marker past the cap in an oversized log is missed only on cold open; live-watching reads from offset 0 and still catches it. (The reviewer's suggested start-only bound would have missed that mid-stream marker.) - Include the fourth built-in profile, copilot, in the negative env assertion so the "Claude only" CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN contract is fully covered. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
augment review |
| # huge finished log doesn't trigger a near-whole-file read that would defeat | ||
| # max_bytes. 8 MiB comfortably covers a multi-MB classic preamble before a TUI | ||
| # switches to the alternate screen (observed ~3.9 MB); a marker past the cap in an | ||
| # oversized log is missed only on cold open — live-watching reads from offset 0 and |
There was a problem hiding this comment.
src/automator/tui/data.py:347: The comment says “live-watching reads from offset 0”, but LogView.read_new() tail-seeks to max(0, size - max_bytes) on first open, so a viewer attaching after the log grows past max_bytes won’t necessarily read from 0. Consider clarifying this since it affects when an altscreen marker could still be missed due to the prefix scan cap.
Severity: low
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
There was a problem hiding this comment.
You're right, the comment overstated it — corrected in 8200a2f. read_new() tail-seeks to max(0, size - max_bytes) on first open, so attaching to an already-large log does not read from 0. Reworded: a beyond-cap marker is missed only when the log already exceeds max_bytes at first open; a view attached while the log was still small reads the whole stream from offset 0 and catches it regardless.
| pos = 0 | ||
| while pos < end: | ||
| f.seek(pos) | ||
| buf = f.read(min(window, end - pos) + overlap) |
There was a problem hiding this comment.
src/automator/tui/data.py:488: _scan_prefix_for_altscreen() reads min(window, end - pos) + overlap, which can pull up to overlap bytes past end, so _ALTSCREEN_PREFIX_SCAN_CAP isn’t a strict ceiling and markers just beyond the cap may still be detected. If the cap is intended to be strict, consider limiting the read to end (or documenting that a small over-read is intentional for boundary detection).
Severity: low
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
There was a problem hiding this comment.
Good catch — fixed in 8200a2f. The over-read was up to overlap (7) bytes; the read is now min(window + overlap, end - pos), so the scan stops strictly at end while each non-final window still reads window + overlap to catch a marker straddling an internal boundary (the final window's leading boundary is already covered by the previous window's overlap).
Address PR #16 round-2 review feedback (both low severity): - _scan_prefix_for_altscreen read min(window, end-pos) + overlap, over-reading up to `overlap` bytes past `end`, so _ALTSCREEN_PREFIX_SCAN_CAP wasn't a strict ceiling. Read min(window + overlap, end - pos) instead — strict at `end` while the previous window's overlap still covers the internal boundary. - The cap comment claimed "live-watching reads from offset 0"; read_new tail-seeks to max(0, size - max_bytes) on first open, so attaching to an already-large log doesn't read from 0. Reworded: a beyond-cap marker is missed only when the log already exceeds max_bytes at first open; a view attached while it was still small reads the whole stream from 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
augment review |
|
@CodeRabbit review |
✅ Action performedReview finished.
|
Summary
Patch release 0.7.3. Fixes the TUI Log tab showing only a single page for Claude runs while codex logs displayed in full.
Root cause: Claude Code's new fullscreen TUI (an opt-in research preview) draws on the terminal's alternate screen (
?1049h) and repaints in place. The Log tab emulates the tmux pane capture through pyte, which has no alternate-screen buffer, so every fullscreen repaint overwrote one screen and the view collapsed to the final frame. Line-oriented CLIs like codex scroll into history normally, so they were unaffected.Fix:
claudeprofile now forces the classic inline/scrollback renderer viaCLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1in[env]— the documented override that beats anytuisetting (user/project/local/seeded) and keeps output in native scrollback, so the capture scrolls and the whole session is reconstructable.LogViewdetects an alternate-screen switch (scanning the live stream and, on cold open, the tail-seek-skipped prefix) and the dashboard flags such a capture as showing only the final frame, pointing at the agent's full JSONL transcript.Verified
claudeprofile forces the classic renderer; fourLogViewalt-screen cases (live detection, cold-open-past-tail-seek, truncation-reset, negative).trunk checkclean.Release prep
Version stamped to 0.7.3 across
__init__.py/pyproject.toml/module.yaml/marketplace/uv.lock, CHANGELOG curated, anddocs/imagesregenerated (TUI changed since v0.7.2).🤖 Generated with Claude Code
Summary by CodeRabbit