Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
6d5fa82
feat(tui): remove tool group borders and collapse completed tool results
Jun 11, 2026
a0b018c
fix(tui): gate collapse on compact mode and fix innerWidth calculation
Jun 13, 2026
9948cbe
fix(tui): address review feedback on collapse and visual alignment
Jun 22, 2026
ea80b74
feat(tui): unify tool output with semantic summaries
Jun 22, 2026
89faa9c
test(tui): add buildToolSummary unit tests and fix stale comment
Jun 22, 2026
4146279
fix(tui): address audit findings for unified tool output
Jun 23, 2026
3275994
fix(tui): address inline review findings
Jun 23, 2026
500200c
fix(tui): remove unused compactMode import in HistoryItemDisplay
Jun 23, 2026
089ffaf
ci: trigger re-run with updated merge ref
Jun 23, 2026
810c713
docs(tui): design — remove global compact mode, add Ctrl+O transcript…
Jun 23, 2026
5058715
Merge commit 'refs/tmp/pr5661' into feat/ctrl-o-detail-expand
Jun 23, 2026
3169f52
feat(tui): remove global compact mode toggle (on top of #5661 partiti…
Jun 24, 2026
dce2562
Merge remote-tracking branch 'origin/main' into feat/ctrl-o-detail-ex…
Jun 24, 2026
69b28e2
feat(tui): Ctrl+O opens a frozen alt-screen transcript full-detail view
Jun 24, 2026
1e13262
Merge branch 'main' into feat/ctrl-o-detail-expand
wenshao Jun 24, 2026
da01d09
fix(tui): repaint normal buffer when transcript closes (no duplicate …
Jun 24, 2026
43fece8
Merge remote-tracking branch 'fork/feat/ctrl-o-detail-expand' into fe…
Jun 24, 2026
b7b699e
Merge branch 'main' into feat/ctrl-o-detail-expand
wenshao Jun 25, 2026
5fdf29e
Merge branch 'main' into feat/ctrl-o-detail-expand
Jun 25, 2026
af07564
docs(tui): rebase ctrl-o design doc to #5661's type-based partition
Jun 26, 2026
c16341f
docs(tui): fix factual nits from cross-audit of the ctrl-o design doc
Jun 26, 2026
03dc348
Merge branch 'main' into feat/ctrl-o-detail-expand
Jun 26, 2026
0e5ccd6
fix(tui): don't let fullDetail be bypassed by compact early returns
Jun 26, 2026
42a6aa8
docs(tui): resolve open design decisions from source evidence
Jun 26, 2026
631bc64
docs(tui): align design doc status/scope with current PR (audit follo…
Jun 26, 2026
488a9fa
docs(tui): scope mouse click-to-expand out as a follow-up
Jun 26, 2026
25361c0
feat(tui): isTTY guard for AlternateScreen + transcript shortcut/i18n…
Jun 26, 2026
f2b924a
docs(tui): mark isTTY guard + i18n cleanup as implemented in status t…
Jun 26, 2026
0e74be3
fix(i18n): add TranscriptView strings to all locales
Jun 26, 2026
fe35052
docs(ctrl-o): add before/after transcript capture evidence
Jun 26, 2026
372a3ae
docs(ctrl-o): design §4.9 — full tool detail passthrough in transcript
Jun 26, 2026
fef75e9
docs(ctrl-o): adopt plan Y for §4.9 and address transcript-detail audit
Jun 26, 2026
c97c447
docs(ctrl-o): tighten §4.9 per second audit (no 2nd truncation, neste…
Jun 26, 2026
07392fd
Merge remote-tracking branch 'origin/main' into feat/ctrl-o-detail-ex…
Jun 29, 2026
f29b3e5
fix(ctrl-o): address PR review findings on transcript view
Jun 29, 2026
12000e3
fix(ctrl-o): second review round — web-shell compactMode + anti-deadl…
Jun 29, 2026
9204da8
fix(ctrl-o): regenerate vscode settings schema for re-added ui.compac…
Jun 29, 2026
ad71f3d
Merge remote-tracking branch 'origin/main' into feat/ctrl-o-detail-ex…
Jun 29, 2026
a12d549
chore(ctrl-o): reset MCP/acp-bridge files to main (drop stale merge d…
Jun 29, 2026
ff72770
docs(ctrl-o): update compact-mode docs for transcript model; drop orp…
Jun 29, 2026
23281e3
feat(ctrl-o)!: §4.9 full tool-detail passthrough in transcript
Jun 29, 2026
e30ff19
fix(ctrl-o): address review — repaint race, suppressOnRestore parity,…
Jun 29, 2026
7be4007
test(ctrl-o): cover detailedDisplay resume derivation + message.parts…
Jun 29, 2026
4dbf68c
fix(ctrl-o): address review — plain-text detail, shared placeholder c…
Jun 29, 2026
b1b59cd
Merge origin/main into feat/ctrl-o-detail-expand
Jun 30, 2026
e549d2d
Merge origin/main into feat/ctrl-o-detail-expand
Jun 30, 2026
b5096db
fix(tui): guard transcript non-TTY output + clear detailedDisplay on …
Jun 30, 2026
c28f29e
test(tui): report a TTY stdout in ScrollableList mouse-scroll tests
Jun 30, 2026
255458b
Merge origin/main into feat/ctrl-o-detail-expand
Jun 30, 2026
69040bb
fix(tui): address Ctrl+O transcript review — q-guard, callback churn,…
Jun 30, 2026
7184565
fix(tui): escape ANSI in transcript detailedDisplay + gate its extrac…
Jun 30, 2026
1568db8
fix(tui): gate resume-path detailedDisplay on isCollapsibleTool (matc…
Jul 1, 2026
151347d
fix(tui): strip bare C0 control bytes from transcript detailedDisplay…
Jul 1, 2026
3b719df
test(tui): memoize HistoryItemDisplay, add ErrorBoundary tests + TAB/…
Jul 1, 2026
94e4ba2
refactor(tui): review cleanups — gate sanitize memo, drop dead code, …
Jul 1, 2026
d3e7d18
test(tui): remove orphaned no-op CompactModeProvider stubs
Jul 1, 2026
b05db46
fix(tui): strip bidi overrides, sanitize error fallbacks, share filters
Jul 1, 2026
9e9055d
fix(tui): harden compaction guard to always clear detailedDisplay
Jul 1, 2026
2ed723d
fix(core): sanitize mime/uri in getToolResponseDisplayText media plac…
Jul 1, 2026
8b492e9
Merge origin/main into feat/ctrl-o-detail-expand
Jul 1, 2026
3d93b23
test(tui): report a TTY stdout in BaseSelectionList mouse integration…
Jul 1, 2026
85fc9be
docs(core): fix JSDoc placement + note ErrorBoundary fallback is un-t…
Jul 1, 2026
d3b39ba
fix(tui): share terminal-sanitize pipeline; guard AlternateScreen writes
Jul 1, 2026
67635c6
Merge origin/main into feat/ctrl-o-detail-expand
Jul 9, 2026
052047b
Merge origin/main into feat/ctrl-o-detail-expand
Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
527 changes: 527 additions & 0 deletions docs/design/ctrl-o-detail-expand/design.md

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion docs/developers/daemon/19-observability.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ A **second** SIGTERM/SIGINT intentionally triggers `bridge.killAllSync()` + `pro
"runtime": {
"perf": {
"eventLoop": { "meanMs": 1.2, "p50Ms": 1.0, "p99Ms": 9.5, "maxMs": 25 },
"promptQueueWait": { "count": 3, "meanMs": 12.5, "maxMs": 35, "lastMs": 4 },
"promptQueueWait": {
"count": 3,
"meanMs": 12.5,
"maxMs": 35,
"lastMs": 4
},
"pipe": {
"inbound": { "count": 42, "totalBytes": 100000, "maxBytes": 12000 },
"outbound": { "count": 41, "totalBytes": 90000, "maxBytes": 11000 }
Expand Down
2 changes: 1 addition & 1 deletion docs/users/configuration/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Settings are organized into categories. Most settings should be placed within th
| `ui.showCitations` | boolean | Show citations for generated text in the chat. | `false` |
| `ui.history.collapseOnResume` | boolean | Whether to collapse history by default when resuming a session. Can be toggled via `/history collapse-on-resume` and `/history expand-on-resume`. | `false` |
| `ui.history.collapsePreviewCount` | number | Number of most recent user turns to keep visible when `ui.history.collapseOnResume` is enabled. `0` collapses all restored history by default; `-1` shows all restored history. | `0` |
| `ui.compactMode` | boolean | Hide tool output and thinking for a cleaner view. Toggle with `Ctrl+O` during a session or via the Settings dialog. Tool approval prompts are never hidden, even in compact mode. The setting persists across sessions. | `false` |
| `ui.compactMode` | boolean | Retired in the terminal UI. The CLI now always shows the compact, type-based tool view in the main transcript; press `Ctrl+O` to open the full-detail transcript instead of toggling a mode. Still honored by the web shell. | `false` |
| `ui.shellOutputMaxLines` | number | Max number of shell output lines shown inline. Set to `0` to disable the cap and show full output. Hidden lines are surfaced via the `+N lines` indicator. Errors, `!`-prefix user-initiated commands, confirming tools, and focused embedded shells always show full output. | `5` |
| `ui.enableWelcomeBack` | boolean | Show welcome back dialog when returning to a project with conversation history. When enabled, Qwen Code will automatically detect if you're returning to a project with a previously generated project summary (`.qwen/PROJECT_SUMMARY.md`) and show a dialog allowing you to continue your previous conversation or start fresh. If you choose **Start new chat session**, that choice is remembered for the current project until the project summary changes. This feature integrates with the `/summary` command and quit confirmation dialog. | `true` |
| `ui.accessibility.enableLoadingPhrases` | boolean | Enable loading phrases (disable for accessibility). | `true` |
Expand Down
42 changes: 19 additions & 23 deletions docs/users/features/tool-use-summaries.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
# Tool-Use Summaries

Qwen Code can generate a short, git-commit-subject-style label after each tool batch completes, summarizing what the batch accomplished. The label appears inline in the transcript and replaces the generic `Tool × N` header in compact mode.
Qwen Code can generate a short, git-commit-subject-style label after each tool batch completes, summarizing what the batch accomplished. The label appears inline: for a completed tool group in the main view it replaces the generic `Tool × N` header; when the group is force-expanded (in the `Ctrl+O` full-detail transcript, or for error / user-initiated batches) it appears as a dim `● <label>` line below the group.

This is a UX aid for parallel tool calls: when the model fans out into several `Read` + `Grep` + `Bash` calls at once, the summary tells you the intent at a glance instead of forcing you to scan the tool list.

The feature is enabled by default and runs silently in the background. It requires a configured [fast model](./followup-suggestions#fast-model).

## What You See

### Full mode (default)
### Main view (completed group)

The summary appears as a dim badge line directly below the tool group:
In the main transcript, a completed collapsible batch folds into a single labeled row — the summary replaces the generic `Tool × N` header:

```
╭──────────────────────────────────────────────╮
│ ✓ ReadFile a.txt │
│ ✓ ReadFile b.txt │
│ ✓ ReadFile c.txt │
│ ✓ ReadFile d.txt │
│✓ Read 4 text files │
╰──────────────────────────────────────────────╯

● Read 4 text files
```

### Compact mode (`Ctrl+O` or `ui.compactMode: true`)
The full per-tool output is a keystroke away: press `Ctrl+O` to open the full-detail transcript.

### Full-detail transcript (`Ctrl+O`) and force-expanded groups

The label replaces the generic `Tool × N` header in the compact one-liner:
When a group is force-expanded — in the `Ctrl+O` transcript, or for error / user-initiated batches in the main view — each tool renders individually and the summary appears as a dim badge line below the group:

```
╭──────────────────────────────────────────────╮
│✓ Read txt files · 4 tools │
│Press Ctrl+O to show full tool output │
│ ✓ ReadFile a.txt │
│ ✓ ReadFile b.txt │
│ ✓ ReadFile c.txt │
│ ✓ ReadFile d.txt │
╰──────────────────────────────────────────────╯
```

The individual tool calls are still a keystroke away (`Ctrl+O` to toggle to full mode).
● Read 4 text files
```

## How It Works

Expand Down Expand Up @@ -123,31 +122,28 @@ These settings can be configured in `settings.json`:

Three points that tend to trip up a first read of this feature:

1. **One generation per batch, shared by both display modes.** The fast-model call happens exactly once in `handleCompletedTools` when a tool batch finalizes. Toggling `Ctrl+O` afterwards does **not** trigger a new call — both modes read from the same `tool_use_summary` history entry that was captured the first time. You can flip compact mode on and off freely without extra cost.
1. **One generation per batch, shared by both display modes.** The fast-model call happens exactly once in `handleCompletedTools` when a tool batch finalizes. Opening the `Ctrl+O` transcript afterwards does **not** trigger a new call — both the main view and the full-detail transcript read from the same `tool_use_summary` history entry that was captured the first time.
2. **No backfill on toggle or on session resume.** A `tool_group` that completed before the feature was enabled (or before you flipped the setting on, or in a resumed session — `ChatRecordingService` does not persist summary entries) will never get a label. There is no "sweep existing history" pass. If you turn this setting on mid-session, only _future_ batches will show a label; older groups keep the default rendering with no indicator that a label is missing.
3. **Main-agent batches only.** The trigger lives in the main session's turn loop (`useGeminiStream`), so:
- ✅ Shell, MCP, file operations, and the `Task` / subagent tool _call itself_ (as it appears in the main batch) are summarized.
- ❌ A subagent's **internal** tool batches (run through `packages/core/src/agents/runtime/`) are not summarized.

An outer batch that _contains_ a `Task` tool will still be labeled, but the fast model sees only the subagent tool call and its aggregated output — not the individual tool calls inside the subagent. Expect labels like `Ran research-agent` or `Delegated file search` rather than `Searched 14 files`. This is intentional — summarizing subagent internals would multiply the fast-model cost and surface noise that never shows up in the primary UI.

## Recommended pairing: enable compact mode
## Display behavior

For batches of 3+ parallel tool calls, pairing this feature with `ui.compactMode: true` produces the cleanest transcript. The compact view folds the whole batch into a single labeled row (`✓ Read txt files · 4 tools`) instead of showing every tool line plus the trailing summary. Details remain one keystroke away via `Ctrl+O`.
The main view already folds a completed collapsible batch into a single labeled row (`✓ Read 4 text files`) — the summary does the work of the old per-tool list. For full per-tool detail, press `Ctrl+O` to open the full-detail transcript, where each tool renders individually with the summary as a trailing `● <label>` line below the group.

```json
{
"fastModel": "qwen3-coder-flash",
"ui": {
"compactMode": true
},
"experimental": {
"emitToolUseSummaries": true
}
}
```

In full mode (the default), the summary renders as a trailing `● <label>` line below the tool group — useful for large or heterogeneous batches, but for small same-type batches (e.g. `Read × 3`) the label can read as a restatement of the visible tool lines. If that matches your usual workflow, either turn compact mode on as above, or turn the summary off entirely via `experimental.emitToolUseSummaries: false`.
For small same-type batches (e.g. `Read × 3`) the expanded `● <label>` line can read as a restatement of the visible tool lines; if that matches your usual workflow you can turn the summary off entirely via `experimental.emitToolUseSummaries: false`.

## Monitoring

Expand All @@ -174,5 +170,5 @@ If you do not want the extra cost, turn the feature off via `experimental.emitTo

## Related

- [Compact Mode](../configuration/settings#ui) — toggle with `Ctrl+O`; the summary replaces the generic tool-group header when compact mode is on.
- [Full-detail transcript](../configuration/settings#ui) — press `Ctrl+O` to open the frozen full-detail transcript; the summary replaces the generic tool-group header for completed groups in the main view.
- [Followup Suggestions](./followup-suggestions) — another fast-model-driven UX enhancement that shares the same `fastModel` setting.
2 changes: 1 addition & 1 deletion docs/users/reference/keyboard-shortcuts.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This document lists the available keyboard shortcuts in Qwen Code.
| `Ctrl+C` | Cancel the ongoing request and clear the input. Press twice to exit the application. |
| `Ctrl+D` | Exit the application if the input is empty. Press twice to confirm. |
| `Ctrl+L` | Clear the screen. |
| `Ctrl+O` | Toggle compact mode (hide/show tool output and thinking). |
| `Ctrl+O` | Open/close the full-detail transcript view (a scrollable, frozen snapshot showing every tool's complete output and full thinking). Press again, or `Esc`/`q`, to close. |
| `Ctrl+S` | Allows long responses to print fully, disabling truncation. Use your terminal's scrollback to view the entire output. |
| `Ctrl+T` | Toggle the display of tool descriptions. |
| `Ctrl+B` | While a foreground shell command is running: promote it to a background task. The child keeps running, the agent's turn unblocks, and the shell appears in `/tasks` + the Background tasks dialog. No-op when no shell is executing — Ctrl+B then falls through to its prompt-area binding (cursor-left). |
Expand Down
8 changes: 6 additions & 2 deletions packages/cli/src/config/keyBindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export enum Command {
EXIT = 'exit',
SHOW_MORE_LINES = 'showMoreLines',
RETRY_LAST = 'retryLast',
TOGGLE_COMPACT_MODE = 'toggleCompactMode',
TOGGLE_RENDER_MODE = 'toggleRenderMode',
/**
* Promote the running foreground shell command to a background task.
Expand All @@ -80,6 +79,9 @@ export enum Command {
// Thinking expansion
TOGGLE_THINKING_EXPANDED = 'toggleThinkingExpanded',

Comment thread
chiga0 marked this conversation as resolved.
// Transcript full-detail screen (Ctrl+O)
TOGGLE_TRANSCRIPT = 'toggleTranscript',

// Scroll commands
SCROLL_UP = 'scrollUp',
SCROLL_DOWN = 'scrollDown',
Expand Down Expand Up @@ -225,7 +227,6 @@ export const defaultKeyBindings: KeyBindingConfig = {
[Command.EXIT]: [{ key: 'd', ctrl: true }],
[Command.SHOW_MORE_LINES]: [{ key: 's', ctrl: true }],
[Command.RETRY_LAST]: [{ key: 'y', ctrl: true }],
[Command.TOGGLE_COMPACT_MODE]: [{ key: 'o', ctrl: true }],
[Command.TOGGLE_RENDER_MODE]: [{ key: 'm', meta: true }],
[Command.PROMOTE_SHELL_TO_BACKGROUND]: [{ key: 'b', ctrl: true }],

Expand All @@ -243,6 +244,9 @@ export const defaultKeyBindings: KeyBindingConfig = {
// Thinking expansion
[Command.TOGGLE_THINKING_EXPANDED]: [{ key: 't', meta: true }],

// Transcript full-detail screen
[Command.TOGGLE_TRANSCRIPT]: [{ key: 'o', ctrl: true }],
Comment thread
chiga0 marked this conversation as resolved.

// Scroll commands
[Command.SCROLL_UP]: [{ key: 'up', shift: true }],
[Command.SCROLL_DOWN]: [{ key: 'down', shift: true }],
Expand Down
22 changes: 8 additions & 14 deletions packages/cli/src/config/settingsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1003,19 +1003,13 @@ const SETTINGS_SCHEMA = {
category: 'UI',
requiresRestart: false,
default: false,
description:
'Hide tool output and thinking for a cleaner view (toggle with Ctrl+O).',
showInDialog: true,
},
compactInline: {
type: 'boolean',
label: 'Compact Inline',
category: 'UI',
requiresRestart: true,
default: false,
description:
'Compact tool display within each group instead of merging across groups. Requires compactMode to be enabled.',
showInDialog: true,
// Retired from the TUI (compact tool output is now always-on there, and
// Ctrl+O opens the transcript instead of toggling this). Kept as a
// hidden, schema-only setting so the web shell's independent compact
// toggle can still persist via the daemon settings routes (mirrors
// `voiceModel`). Not shown in the TUI settings dialog.
description: 'Compact view (web shell only; not used by the TUI).',
showInDialog: false,
},
useTerminalBuffer: {
type: 'boolean',
Expand Down Expand Up @@ -3117,7 +3111,7 @@ const SETTINGS_SCHEMA = {
requiresRestart: false,
default: true,
description:
'Generate a short LLM-based label after each tool batch completes. In compact mode the label replaces the generic `Tool × N` header; in full mode it appears as a dim `● <label>` line below the tool group. Requires a fast model to be configured; runs in parallel with the next API call so latency is hidden. Currently affects interactive CLI rendering only — SDK / non-interactive emission of the `tool_use_summary` message is not yet wired (the message factory is exported for a follow-up PR). Can be overridden with QWEN_CODE_EMIT_TOOL_USE_SUMMARIES=0 or =1.',
'Generate a short LLM-based label after each tool batch completes. For a completed tool group the label replaces the generic `Tool × N` header; when the group is force-expanded it appears as a dim `● <label>` line below the tool group. Requires a fast model to be configured; runs in parallel with the next API call so latency is hidden. Currently affects interactive CLI rendering only — SDK / non-interactive emission of the `tool_use_summary` message is not yet wired (the message factory is exported for a follow-up PR). Can be overridden with QWEN_CODE_EMIT_TOOL_USE_SUMMARIES=0 or =1.',
showInDialog: true,
},
},
Expand Down
Loading
Loading