CommandCodeAI / CommandCodeAI/command-code

[BUG] TUI status bar and spinner stack lines instead of redrawing in place

未关闭
#623 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 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:

  1. **`

  2. TERM is mis

  3. TERM is misreported

  4. TERM is misreported. If it

  5. TERM is misreported. If it's dumb,

  6. TERM is misreported. If it's dumb, unknown, or unset,

  7. TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as uns

  8. TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported

  9. TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm

  10. TERM is misreported. If it's dumb, unknown, or unset, cursor control is treated as unsupported. Fix: export TERM=xterm-

  11. 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

  12. 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.

  13. stdout isn't a real

  14. 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.

  15. stdout isn't a real TTY. If

  16. 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.

  17. stdout isn't a real TTY. If cmd is

  18. 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.

  19. stdout isn't a real TTY. If cmd is started through a pipe, `

  20. 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.

  21. stdout isn't a real TTY. If cmd is started through a pipe, tee, a p

  22. 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.

  23. stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures

  24. 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.

  25. stdout isn't a real TTY. If cmd is started through a pipe, tee, a pager, or a wrapper that captures output, red

  26. 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.

  27. 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

  28. 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.

  29. 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

  30. 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.

  31. 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.

  32. 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.

  33. 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.

  34. 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.

  35. 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.

  36. 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.

  37. 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.

  38. 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.

  39. 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.

  40. 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.

  41. 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.

  42. 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.

  43. 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.

  44. 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.

  45. 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.

  46. 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.

  47. 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.

  48. 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.

  49. 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.

  50. 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.

  51. 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.

  52. 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.

  53. 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.

  54. 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.

  55. 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.

  56. Stale LINES/COLUMNS. If those env vars are set from an old resize, the renderer computes a wrong viewport. unset LINES COLUMNS and restart.

  57. 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

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 TUI 状态栏和 spinner renderer 开始,然后跟踪其 ANSI 光标控制路径,以及对 TERM 和 stdout 是否为 TTY 的检查。在报告的命令代码终端设置中重现堆叠输出,并将其与直接的 TTY 输出进行比较。当受支持的终端能够原地重绘,而管道、捕获的输出和不受支持的终端保留有意的换行行为时,即视为完成。

由索引模型根据 Issue 内容生成。

评估

领域
cli
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
48/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。