CommandCodeAI / CommandCodeAI/command-code
[BUG] TUI status bar and spinner stack lines instead of redrawing in place
還沒有人認領這個 Issue。
- 主要語言
- 沒有語言資料
- 星號
- 4k
- 分支
- 350
- PR 合併指標
- 30 天內沒有已合併 PR
描述
Summary
When running command-code in the terminal, the TUI status bar ("Thinking..." spinner / live progress indicator) fails to redraw on a single line. Instead of using ANSI cursor movement to overwrite the previous output, each frame and status update is printed as a brand-new line, resulting in massive line-stacking and terminal log spam.
✻ Thinking… (25 lines) [ctrl+o to expand]
✻ Thinking… (27 lines) [ctrl+o to expand]
✻ Thinking… (27 lines) [ctrl+o to expand]
✻ Thinking… (27 lines) [ctrl+o to expand]
✻ Thinking… (27 lines) [ctrl+o to expand]
✻ Thinking… (27 lines) [ctrl+o to expand]
✻ Thinking… (27 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (29 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (31 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thinking… (33 lines) [ctrl+o to expand]
✻ Thought for 7 seconds [ctrl+o to expand]
⠶ That
⠶ That's the TUI's
⠶ That's the TUI's status bar
⠶ That's the TUI's status bar ("H
⠶ That's the TUI's status bar ("Honing
⠶ That's the TUI's status bar ("Honing…" spinner) and the live
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line.
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies on ANSI cursor control;
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies on ANSI cursor control; when that's
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies on ANSI cursor control; when that's unavailable, the
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies on ANSI cursor control; when that's unavailable, the renderer falls back
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies on ANSI cursor control; when that's unavailable, the renderer falls back to newline output and
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies on ANSI cursor control; when that's unavailable, the renderer falls back to newline output and you get exactly
⠶ That's the TUI's status bar ("Honing…" spinner) and the live thinking indicator failing to redraw in place — instead of the terminal cursor moving back to overwrite the same line, each repaint is emitted
as a brand-new line. The redraw logic relies on ANSI cursor control; when that's unavailable, the renderer falls back to newline output and you get exactly this stacking.
○ Visualizing… esc to interrupt • 1m 12s • ↓ 11.7k
The usual culprits,
The usual culprits, in order of likelihood:
-
**`
-
TERM is mis
-
TERM is misreported
-
TERM is misreported. If it
-
TERM is misreported. If it's dumb,
-
TERM is misreported. If it's dumb, unknown, or unset,
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as uns
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, `
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a p
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, red
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to new
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-256color (or tmux-256color inside tmux) and restart cmd.
-
stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, redraws degrade to newline printing. Run it directly in a terminal.
-
Stale LINES/COLUMNS. If those env vars are set from an old resize, the renderer computes a wrong viewport. unset LINES COLUMNS and restart.
-
Terminal emulator quirks. Old or minimal terminals (or IDE panels that don't implement cursor addressing) cause exactly this. iTerm2, Ghostty, Alacritty, and VS Code's integrated terminal all handle it
fine.
Check with echo $TERM and st
Check with echo $TERM and stty size first — a wrong TER
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior.
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is the right
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is the right place since it'd be
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is the right place since it'd be a rendering bug.
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is the right place since it'd be a rendering bug.
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is the right place since it'd be a rendering bug.
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is the right place since it'd be a rendering bug.
Check with echo $TERM and stty size first — a wrong TERM is the classic cause of this specific stacking behavior. If TERM looks right, try a different terminal emulator; if it persists there, /feedback or
the GitHub tracker is the right place since it'd be a rendering bug.
◇ Conjuring… esc to interrupt • 1m 17s • ↓ 12.1k
────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ○ Conjuring… esc to interrupt • 1m 17s • ↓ 12.1k
Expected Behavior
The TUI status bar and thinking indicator should update in-place on a single line using ANSI cursor movements, cleanly repainting the spinner without creating new lines in the terminal output.
Actual Behavior
Every time the spinner or thinking indicator repaints, it appends a new line to standard output. This creates dozens of repeated lines (e.g., ✻ Thinking… (29 lines) / ⠶ That's the TUI's status bar...) overflowing the terminal buffer.
Steps to reproduce the issue
Install command-code globally: npm i -g command-code@latest
Run command-code in a terminal window.
Initiate a prompt or action that triggers the live spinner / thinking output.
Observe that each animation frame prints on a new line rather than refreshing in place.
Command Code Version
OS: macOS (Darwin arm64)
Operating System
macOS
Terminal/IDE
Default macOS Terminal / iTerm2
Shell
zsh
Session file (optional)
No response
Fix prompt (optional)
Possible Cause / Notes
It seems the TUI renderer fails to detect proper TTY cursor control capabilities or lacks an ANSI cursor fallback check, forcing the redraw logic to fall back to newline printing (\n) instead of carriage returns (\r / ANSI control sequences).
Additional context
No response
貢獻指南
這個儲存庫沒有索引到貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
從 TUI 狀態列和 spinner renderer 開始,接著追蹤其 ANSI 游標控制路徑,以及對 TERM 和 stdout 是否為 TTY 的檢查。在回報的命令碼終端設定中重現堆疊輸出,並將其與直接的 TTY 輸出比較。當支援的終端能夠原地重繪,而管線、擷取的輸出和不支援的終端保留刻意的換行行為時,即表示完成。
由索引模型根據 Issue 內容生成。
評估
- 領域
- cli
- Issue 類型
- 缺陷
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 活躍度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 48/100