Skip to content

fix(terminal): render startup inline images#10478

Open
KimHyeongRae0 wants to merge 4 commits intowarpdotdev:masterfrom
KimHyeongRae0:fix/10020-inline-images-startup
Open

fix(terminal): render startup inline images#10478
KimHyeongRae0 wants to merge 4 commits intowarpdotdev:masterfrom
KimHyeongRae0:fix/10020-inline-images-startup

Conversation

@KimHyeongRae0
Copy link
Copy Markdown

@KimHyeongRae0 KimHyeongRae0 commented May 8, 2026

Description

Fixes inline image protocol routing during shell startup and early output.

Completed iTerm2 and Kitty image actions previously bypassed the early-output path, and block-level routing could send images received before preexec into the prompt/header grid. That made startup or background image output parse successfully but not render like normal command output.

This change:

  • Routes image completions received before preexec to the output grid, while preserving the hidden WarpInput bootstrap behavior.
  • Starts the ScriptExecution block when its first visible content is an image completion.
  • Sends image completions through EarlyOutputHandler so background image output creates a renderable background block.
  • Treats image placements as visible grid content so image-only startup output is not hidden as an empty bootstrap block.
  • Keeps non-moving Kitty image placements visible even when they leave the cursor at the origin.
  • Adds unit coverage for the startup, hidden-bootstrap, and early-output routing paths.

Linked Issue

Closes #10020

  • The linked issue is labeled ready-to-implement.
  • Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes).

Testing

  • cargo fmt -- --check
  • git diff --check
  • cargo clippy -p warp --all-targets --tests -- -D warnings
  • cargo test -p warp test_non_moving_kitty_image_keeps_finished_grid_visible
  • cargo test -p warp test_image_completion
  • cargo test -p warp test_iterm_image
  • cargo test -p warp test_kitty_image
  • Manual GUI validation with the target/debug/warp-oss binary built by ./script/run --dont-open

Manual GUI validation passed on macOS with a temporary zsh startup script running fastfetch --logo-type kitty-direct. Warp rendered the startup image output as a normal output block, including the WARP_INLINE_IMAGE_STARTUP_TEST_BEGIN / WARP_INLINE_IMAGE_STARTUP_TEST_END markers and the emitted image.

Screenshots / Videos

No screenshot or video is attached because this update is being made from the GitHub CLI/API environment, which does not provide GitHub's browser-based PR attachment upload flow. The manual GUI validation above is the end-to-end visual check: a local warp-oss build launched with the temporary startup script, and the terminal rendered the fastfetch Kitty-direct image between the startup markers instead of dropping it.

Agent Mode

  • Warp Agent Mode - This PR was created via Warp AI Agent Mode

CHANGELOG-BUG-FIX: Render inline image protocols emitted during shell startup instead of dropping them.

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 8, 2026

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @KimHyeongRae0 on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 8, 2026
@KimHyeongRae0
Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 8, 2026

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @KimHyeongRae0 on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 8, 2026

The cla-bot has been summoned, and re-checked this pull request!

@KimHyeongRae0
Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label May 8, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 8, 2026

The cla-bot has been summoned, and re-checked this pull request!

@KimHyeongRae0 KimHyeongRae0 marked this pull request as ready for review May 8, 2026 15:53
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@KimHyeongRae0

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I reviewed this pull request and requested human review from: @warpdotdev/oss-maintainers.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR reroutes completed inline image actions during startup and early-output phases so image-only output can create/render output or background blocks instead of being dropped into prompt/header handling.

Concerns

  • The production change covers both iTerm and Kitty image completions, but the added regression coverage only exercises iTerm images.

Verdict

Found: 0 critical, 0 important, 1 suggestions

Approve with nits

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

}

#[test]
fn test_iterm_image_early_output_routes_to_background_block() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 [SUGGESTION] Add at least one Kitty image completion test for the startup/early-output routes; the production changes also route handle_completed_kitty_action, but the new coverage only exercises iTerm images, leaving Kitty's response and metadata path unverified.

@oz-for-oss oz-for-oss Bot requested review from a team and kevinchevalier and removed request for a team May 8, 2026 16:00
@KimHyeongRae0
Copy link
Copy Markdown
Author

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 8, 2026

@KimHyeongRae0

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR routes completed iTerm2/Kitty image actions through startup and early-output paths so startup/background inline images can render in output blocks, and adds focused unit coverage for those paths.

Concerns

  • Image-only Kitty placements that use the no-cursor-move policy can still be hidden because should_show_as_empty_when_finished short-circuits on finished_len() == 0 before the new visible-image check can keep the block visible.
  • This is a user-visible terminal rendering behavior change, but the PR includes no screenshot or recording. Manual testing is required for changes that can be manually tested. Please include screenshots or a screen recording that show it working end to end, or justify why visual evidence is not possible.

Verdict

Found: 0 critical, 2 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

pub fn should_show_as_empty_when_finished(&self) -> bool {
self.finished_len() == 0
|| !self.has_visible_chars()
|| !self.has_visible_content()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ [IMPORTANT] Image-only Kitty placements with C=1 do not move the cursor, so finished_len() == 0 remains true and this grid is still hidden before has_visible_content() can preserve it; include visible images in the zero-length case or otherwise account for non-moving placements.

@KimHyeongRae0
Copy link
Copy Markdown
Author

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 9, 2026

@KimHyeongRae0

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR routes completed inline image actions through the startup and early-output paths so image-only shell startup/background output can render as normal output. I found no security-specific concerns in the changed code.

Concerns

  • The ScriptExecution path starts the block before the image handler has validated that the completion creates visible content, so disabled/invalid iTerm images and non-display Kitty actions can create a startup block despite no renderable placement.
  • The early-output Kitty path similarly starts and inserts a background block for any Kitty action, including StoreOnly, QuerySupport, Delete, unknown IDs, and zero-sized placements, which bypasses the existing pending-block guard that only promotes meaningful background output.

Verdict

Found: 0 critical, 2 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread app/src/terminal/model/blocks.rs Outdated

fn handle_completed_iterm_image(&mut self, image: ITermImage) {
delegate_to_block!(self.handle_completed_iterm_image(image))
if self.bootstrap_stage == BootstrapStage::ScriptExecution && !self.active_block().started()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ [IMPORTANT] This starts the ScriptExecution block before the image handler confirms the completion produced a visible placement; disabled/invalid iTerm images and non-display Kitty actions can now create a startup block with no renderable content. Gate block startup on a successfully accepted visible placement instead.

Comment thread app/src/terminal/model/early_output.rs Outdated
) -> Option<KittyResponse> {
let session_id = self.block_list.active_block().session_id();
self.with_background_output(|block| {
if !block.started() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ [IMPORTANT] Kitty StoreOnly, QuerySupport, Delete, zero-sized, or unknown-id actions also reach this path, so starting the background block here can insert and announce a background block even when no output will render. Start/promote the block only after a visible placement succeeds.

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

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inline image protocols (Kitty graphics, iTerm2) are silently dropped during shell initialization, but render correctly post-init

1 participant