Skip to content

[Bug]: Last line of AI response is clipped by the zsh shell integration (content survives — visible when the chat is reopened in the TUI) #3367

@whisky0809

Description

@whisky0809

Bug Description

When using forge's zsh shell integration (the response is streamed directly into the shell's scrollback rather than into the standalone TUI), the final line of the AI response is intermittently not painted. The response looks like it ends mid-sentence, immediately followed by the next zsh prompt.

The content itself is not truncated — opening the same chat in forge's TUI shows the full message intact, including the line that was clipped in the shell output. So the bug is specifically in the zsh shell integration's render path, not in the model output or in how the message is stored.

This is consistent with a final-flush / final-line interaction between the integration's printed output and the shell prompt being redrawn over the last row.

Example of how it appears in the terminal — the response ends with If you're on a and the zsh (Powerlevel10k) prompt comes right after:

│ Note: For the Nerd Font icons to actually render, you'll need a Nerd Font installed and set as your terminal font. If you're on a

  ~ ❯                                                                                                  user@host  12:39:01 PM

Reopening the same chat in the forge TUI shows the line continues normally (…If you're on a Mac… or similar) — the message stored in the conversation is complete.

Steps to Reproduce

  1. Use the forge zsh shell integration in a zsh session (Powerlevel10k prompt here).
  2. Ask a question that produces a response long enough to wrap near the bottom of the viewport, or whose final line lands on the row immediately above where the next prompt will be drawn.
  3. Wait for streaming to finish — observe the rendered last line in the shell scrollback.
  4. Open the same chat in the forge TUI and compare — the previously-clipped trailing line is fully present.

Reproduces intermittently — not on every response, but several times across a session. It seems most likely to occur when the tail of the response is short (one line / a Note: callout) and lands right against where the next zsh prompt will be repainted.

Expected Behavior

The full final line of every AI response should be flushed to the shell's scrollback before the next zsh prompt is drawn, matching the complete message that the TUI displays when the chat is reopened.

Actual Behavior

The last visible line of the response is clipped (cut mid-sentence) in the shell scrollback. Reopening the chat in the forge TUI shows the message is actually stored in full, confirming the loss is in the live shell-integration render layer, not in the message data.

Forge Version

forge 2.12.16

Installation Method

Other / unsure — installed binary under ~/.local/bin/forge.

Operating System & Version

Ubuntu (Linux 6.8.0-117-generic), TERM=xterm-256color, shell: zsh with Powerlevel10k prompt (p10k uses zle widgets that redraw the prompt region, which is likely relevant to the interaction).

AI Provider

OpenRouter

Model

owl-alpha (via OpenRouter)

Configuration

No relevant non-default forge.yaml configuration.

Additional Notes

Because the message survives intact and only the shell-integration render is incomplete, plausible causes (for whoever picks this up):

  • The integration's last streamed chunk is missing a trailing newline / final flush before the shell regains control and Powerlevel10k repaints the prompt over the last printed row.
  • Off-by-one in the line-count accounting that p10k uses for its multi-line / right-prompt redraw, when the integration's final write doesn't end on a clean line boundary.
  • ANSI cursor-up / clear-to-EOL escapes from the streaming output overlapping the prompt-redraw region.

Easy first thing to try: ensure the shell integration prints a trailing newline (or a \r\n + small flush delay) before yielding back to the shell so the prompt repaint can't overwrite the response's last row.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions