qwen-code/docs/users
Shaojin Wen d71f2fab70
feat(cli): cap inline shell output with configurable line limit (#3508)
* feat(cli): cap inline shell output with configurable line limit

Long-running shell commands (npm install, find /, build logs) currently
fill the viewport with the full visible PTY buffer (up to availableHeight,
~24 lines on a typical terminal). The output dominates the screen and
pushes prior context off the top.

This caps inline ANSI shell output to a small window (default 5 lines,
matching Claude Code's ShellProgressMessage). The hidden line count is
already surfaced via the existing `+N lines` indicator in
`ShellStatsBar`, so users still know how much was elided.

The cap applies only when nothing in the existing escape-hatch set is
true:
  - `forceShowResult` (errors, !-prefix user-initiated commands,
    tools awaiting confirmation, agents pending confirmation)
  - `isThisShellFocused` (ctrl+f focus on a running embedded PTY shell)
  - `ui.shellOutputMaxLines = 0` (user opt-out)

Also adds a new `ui.shellOutputMaxLines` setting (default 5) so users
can adjust or disable the cap. The SettingsDialog renders it
automatically via the existing `type: 'number'` schema path.

Notes on scope:
  - Only the `'ansi'` display branch is capped. `'string'`, `'diff'`,
    `'todo'`, `'plan'`, `'task'` renderers are untouched.
  - `AnsiOutputDisplay` is only produced by shell tools (`shell.ts`,
    `shellCommandProcessor.ts`), so other tool outputs are unaffected.
  - The `+N lines` count is bounded by the headless xterm buffer height
    (~30 rows) — a pre-existing limitation of the buffer-based stats,
    not introduced here.

Tests:
  - 4 new ToolMessage tests cover cap default, forceShowResult bypass,
    settings disable (cap=0), and custom cap value.
  - The existing `MockAnsiOutputText` / `MockShellStatsBar` mocks were
    extended to print `availableTerminalHeight` / `displayHeight` so
    the cap behavior is asserted at the prop level.

* fix(cli): apply shell output cap to completed string display too

Initial PR caught only the streaming ANSI branch. AI shell tools emit
the final completed result through `shell.ts:returnDisplayMessage =
result.output`, which is a plain string. That string went through
`StringResultRenderer` with the unmodified `availableHeight`, so the
cap was effectively bypassed for the steady-state display the user
actually sees most of the time.

Verified manually in tmux: a `seq 1 30` invocation by the AI now
collapses to "first 26 lines hidden ... 27 28 29 30" instead of
listing all 30 rows. `!`-prefix `seq 1 30` still expands fully via
the existing `isUserInitiated → forceShowResult` bypass.

Changes:
  - Detect shell tool by name (matches existing `SHELL_COMMAND_NAME` /
    `SHELL_NAME` checks already used in this file)
  - Rename `ansiAvailableHeight` → `shellCapHeight` since it now
    governs the string branch as well
  - Pass `shellCapHeight` to `StringResultRenderer`; the value
    falls back to `availableHeight` for non-shell tools so other
    tools' string output is unaffected
  - Two new tests: shell completed string is capped; non-shell
    string is not
  - Two existing tests updated to use `name="Shell"` so they actually
    exercise the cap path (would previously have passed by accident
    since the original code didn't check tool name)

Also picks up the auto-regenerated VSCode IDE companion settings
schema entry for `ui.shellOutputMaxLines`.

* fix(cli): symmetrize ANSI/string row counts and clamp shell cap input

Addresses two non-blocking review observations on #3508.

Off-by-one between paths:
  MaxSizedBox reserves one row for its overflow banner when content
  exceeds maxHeight (visibleContentHeight = max - 1). The ANSI path
  pre-slices to N in AnsiOutputText so MaxSizedBox sees exactly N
  rows and renders all N — plus the separate ShellStatsBar line.
  The string path passes the raw cap and lets MaxSizedBox handle
  overflow, so it shows N-1 content rows + the banner.

  Result with cap=5: ANSI showed 5+stats, string showed 4+banner.
  Pass shellCapHeight + 1 to StringResultRenderer when capping so
  both paths render N visible content rows. Verified in tmux: the
  completed Shell tool box now reports `... first 25 lines hidden ...`
  followed by lines 26-30 (was 26 + lines 27-30).

Setting validation:
  Schema accepts any number; the dialog only rejects NaN. Negatives
  silently disabled the cap (only 0 is documented as off) and
  fractional values produced fractional slice counts. Added
  Math.max(0, Math.floor(value || 0)) at the use site so:
   - negatives → 0 → cap disabled (matches the documented opt-out)
   - fractions → floor → whole-row cap
   - non-numeric (raw settings.json edits) → 0 → cap disabled
  Schema-level minimum/integer constraints aren't supported by the
  current settings infrastructure (no other number setting uses
  them either), so the guard lives at the use site.

Tests:
  - Updated string-cap test to assert lines 26-30 visible (catches
    the +1 fix; was lines 27-30 before)
  - New parameterized test covers -1, 1.5, and a non-numeric value
2026-04-22 14:37:13 +08:00
..
configuration feat(cli): cap inline shell output with configurable line limit (#3508) 2026-04-22 14:37:13 +08:00
extension Merge pull request #2628 from QwenLM/feat/channels-telegram 2026-04-01 16:19:08 +08:00
features feat(arena): add comparison summary for agent results (#3394) 2026-04-22 05:31:19 +08:00
ide-integration update documentation 2025-12-19 18:16:59 +08:00
reference refactor: rename verboseMode to compactMode for better UX clarity (#3075) 2026-04-10 11:55:50 +08:00
support docs: update authentication methods to reflect OAuth discontinuation (#3325) 2026-04-17 15:34:18 +08:00
_meta.ts docs move extension to user and hide create docs 2026-01-21 19:57:26 +08:00
common-workflow.md docs: updated all links, click and open in vscode, new showcase video in overview 2025-12-17 11:10:31 +08:00
integration-github-action.md docs: updated all links, click and open in vscode, new showcase video in overview 2025-12-17 11:10:31 +08:00
integration-jetbrains.md docs(integration): use CDN URLs for images and fix formatting 2026-03-16 14:12:48 +08:00
integration-vscode.md fix: docs 2026-01-14 10:30:03 +08:00
integration-zed.md docs(integration): use CDN URLs for images and fix formatting 2026-03-16 14:12:48 +08:00
overview.md docs: update authentication methods to reflect OAuth discontinuation (#3325) 2026-04-17 15:34:18 +08:00
quickstart.md docs: update authentication methods to reflect OAuth discontinuation (#3325) 2026-04-17 15:34:18 +08:00