Skip to content

feat(expose): render agent previews in their real colors - #133

Merged
TraderSamwise merged 2 commits into
masterfrom
feat/expose-color
Jun 15, 2026
Merged

feat(expose): render agent previews in their real colors#133
TraderSamwise merged 2 commits into
masterfrom
feat/expose-color

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Summary

Exposé tiles previously rendered all captured agent output in a uniform dim grey because the capture stripped every escape sequence. This makes the previews show the agents' real colors.

Changes (src/tmux/expose.ts)

  • Capture with color — pass includeEscapes: true to captureTarget so tmux emits SGR via -e.
  • Color-preserving sanitizersanitizeLine now keeps SGR sequences (\x1b[…m) and strips everything else dangerous (non-SGR CSI/cursor moves, OSC, stray escapes, control bytes). Security posture is unchanged: a rogue pane still can't inject cursor moves or break tile borders.
  • ANSI-aware tile body — body lines truncate via truncateAnsi and pad by visible width via stripAnsi, so colored lines don't bleed into borders. Removed the old uniform-grey BODY_STYLE.

Covers both per-project Exposé (Ctrl-A g) and cross-project Exposé from the meta dashboard, since they share tilePreview/drawTile.

Verification

yarn typecheck, yarn lint, yarn test (1180 passed), yarn build all green.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved tmux preview rendering to preserve color and text styling while maintaining safe, properly-aligned display.
    • Fixed text truncation and padding calculation in previews for accurate content visualization.

Capture pane output with -e (includeEscapes) and keep SGR color/style
sequences through sanitization, stripping only non-color escapes (cursor
moves, OSC, stray control bytes) so a rogue pane still can't hijack the
host terminal or misalign tile borders. Body lines now truncate and pad
by visible width via truncateAnsi/stripAnsi. Covers both per-project and
cross-project (meta dashboard) Exposé.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app Ready Ready Preview, Comment Jun 15, 2026 7:43am

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@TraderSamwise, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 18 minutes and 45 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 25f1684e-ec71-408e-a579-7e8939d30c86

📥 Commits

Reviewing files that changed from the base of the PR and between 780dd66 and c129a86.

📒 Files selected for processing (2)
  • src/tmux/expose.ts
  • src/tui/render/text.ts
📝 Walkthrough

Walkthrough

src/tmux/expose.ts is updated to preserve SGR color/style escape sequences in tile previews. sanitizeLine now retains only ESC[...m sequences while stripping other control bytes. Preview rendering switches to truncateAnsi with visible-length padding via stripAnsi. Tmux capture calls now pass includeEscapes: true.

Changes

ANSI Color Preservation in Tile Previews

Layer / File(s) Summary
SGR-preserving sanitizeLine and ANSI-aware preview rendering
src/tmux/expose.ts
Adds stripAnsi import; rewrites sanitizeLine to keep only SGR m sequences and strip all other escape/control sequences; updates tile preview line rendering to use truncateAnsi for truncation and stripAnsi for visible-length right-padding.
Enable includeEscapes in tmux capture
src/tmux/expose.ts
Changes the tmux capture call for each target window to pass includeEscapes: true, supplying raw SGR sequences to the updated sanitizer and renderer.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • TraderSamwise/aimux#118: Both PRs modify ANSI truncation and padding behavior in preview rendering to correctly handle SGR escape/reset sequences at padding boundaries.
  • TraderSamwise/aimux#122: Introduced the Exposé tile/capture preview UI in src/tmux/expose.ts that this PR refines with SGR-preserving sanitization and ANSI-aware rendering.

Poem

🐇 A rabbit peeked at colors bright,
Escaped sequences hidden from sight.
"Keep the m!" the bunny said,
Strip the rest, but spare the red.
Now tiles glow with ANSI flair,
Padded right — with visible care! 🎨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(expose): render agent previews in their real colors' directly and clearly summarizes the main change: displaying agent previews with original colors instead of uniform styling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/expose-color

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@src/tmux/expose.ts`:
- Around line 44-53: The regex patterns in the `stripAnsi` and `truncateAnsi`
functions use `[0-9;]*` for ANSI parameter bytes, but `sanitizeLine` uses
`[0-9;:?]*` to preserve colon-separated SGR sequences like `\x1b[38:2:255:0:0m`,
causing a mismatch that leads to incorrect sequence counting during truncation
and padding. Update the regex patterns in `stripAnsi` and `truncateAnsi` to
include `:` and `?` in the parameter byte character class (changing `[0-9;]*` to
`[0-9;:?]*`) to align with the `sanitizeLine` implementation and correctly
handle all valid SGR syntax.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 06887b5f-6064-47f3-86e9-9621569218de

📥 Commits

Reviewing files that changed from the base of the PR and between e549358 and 780dd66.

📒 Files selected for processing (1)
  • src/tmux/expose.ts

Comment thread src/tmux/expose.ts
- Keep only pure SGR (\x1b[…m with [0-9;:] params); previously any kept
  sequence ending in m (incl. ?-param private-mode forms) survived.
- Strip a trailing incomplete CSI left by a capture-boundary cut.
- stripAnsi/truncateAnsi now accept colon-separated SGR (\x1b[38:2:r:g:bm)
  so visible-width truncation/padding stays correct and borders align.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@TraderSamwise

Copy link
Copy Markdown
Owner Author

Sub-agent review — additional findings (handled in c129a86)

Two issues beyond the CodeRabbit thread, both fixed:

  1. sanitizeLine keep-predicate too loose (src/tmux/expose.ts) — the old predicate m.endsWith("m") retained any matched CSI ending in m, including non-SGR forms with ? params or intermediate bytes. Tightened to /^\x1b\[[0-9;:]*m$/, so only pure SGR color/style sequences survive; everything else is stripped.

  2. Truncated CSI at the capture boundary (src/tmux/expose.ts) — a pane capture can cut a color sequence mid-write, leaving a trailing \x1b[… with no final byte that none of the existing passes removed. Added a \x1b\[[0-9;:?]*[ -/]*$ pass to strip a trailing incomplete CSI. (Note: the sub-agent's suggested blanket \x1b strip was rejected — it would have destroyed the ESC inside the SGR sequences we intentionally keep.)

yarn typecheck, yarn lint, yarn test (1226 passed), yarn build all green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant