Skip to content

perf(coding-agent): composer is on screen from the first paint — no slide-up on load - #901

Open
santhreal wants to merge 1 commit into
mainfrom
perf/instant-first-frame-composer
Open

perf(coding-agent): composer is on screen from the first paint — no slide-up on load#901
santhreal wants to merge 1 commit into
mainfrom
perf/instant-first-frame-composer

Conversation

@santhreal

Copy link
Copy Markdown
Owner

What

Cold launch used to reserve eight blank rows at the bottom of the screen where the composer would live, then leave them empty while InteractiveMode.init finished (slash-command discovery, recent-session reads). When init completed, the real zone mounted into the reserved space and the prompt appeared late — reading as the composer sliding up into place.

The first frame now paints a static resting composer (StaticComposerFrame) into those rows: the real hairline bytes from ComposerHairline, the shared ghost placeholder (COMPOSER_PLACEHOLDER, moved to composer-chrome as the one owner), clipped to width, exactly the resting zone's row count. When the mode finishes initializing, the real zone mounts into the same rows — the handover changes text, never position. Nothing slides; nothing animates.

Why

Startup should feel literal: what you see at frame one is the product. An empty hole where the input obviously belongs reads as loading, and on slower disks (Windows cold caches) that hole sat there for seconds.

Testing

  • New: packages/coding-agent/test/the-first-frame-paints-the-composer-instantly.test.ts — closes the class "the first-frame composer drifts from the mounted one": exact reserved row count, real hairline bytes (same owner), shared ghost placeholder, time-invariance (no animation), narrow-width clipping.
  • Existing composer contracts stay green in the sandbox: hairline (whisper bytes + time-invariance), zone mount order, accents, footline-on, welcome-dismiss distance, pinned-composer scrollback.
  • bun run check:ts, bun run check:tools clean.

  • bun check passes
  • Tested locally
  • CHANGELOG updated (if user-facing)

…up on load

The first frame reserved eight blank rows where the composer would
live and left them empty until InteractiveMode.init finished (slash
command discovery, recent-session reads), so the prompt arrived late
and read as sliding up into place. The first frame now paints the
resting composer through a static component shared with the mounted
zone: real hairline bytes, the same ghost placeholder, the exact
resting row count. The handover swaps text, never position.
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 60176336-8cb1-4d83-8723-967d75d89460


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.

❤️ Share

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

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