Commit graph

14 commits

Author SHA1 Message Date
Shaojin Wen
e2f7661ef1
feat(cli): Ctrl+B promote keybind (#3831 PR-3 of 3) (#3969)
* feat(cli): Ctrl+B promote keybind — wire UI to PR-2's promoteAbortController (#3831 PR-3 of 3)

Final piece of the foreground → background promote feature. PR-1
(#3842) landed the `signal.reason` foundation; PR-2 (#3894) wired
`shell.ts` to detect a `{ kind: 'background' }` abort, snapshot
output, register a `BackgroundShellEntry`, and stash the promote
`AbortController` on `TrackedExecutingToolCall`. This PR exposes
the user-visible surface: pressing Ctrl+B during an in-flight
foreground shell command transfers ownership to a background task
the user can inspect via `/tasks` or stop via `task_stop`.

## Changes

- `keyBindings.ts`: new `Command.PROMOTE_SHELL_TO_BACKGROUND` bound to
  `Ctrl+B`. JSDoc explains the no-shell-running no-op semantics.

- `useReactToolScheduler.ts`: project `promoteAbortController` from
  the core's `ExecutingToolCall` through `TrackedExecutingToolCall`
  so the React layer (AppContainer keypress handler) can find it
  by callId without re-plumbing through the scheduler.

- `AppContainer.tsx`: `handleGlobalKeypress` gains a
  `PROMOTE_SHELL_TO_BACKGROUND` branch that walks
  `pendingToolCallsRef.current` (the ref, not the destructured
  array — keeps the deps list stable so the handler isn't re-bound
  on every tool-call status update), finds the executing tool call
  with a defined `promoteAbortController`, calls
  `.abort({ kind: 'background' })`, and returns early.
  No-op when no foreground shell is executing — Ctrl+B then falls
  through to the input layer's existing cursor-left binding.

- `keyboard-shortcuts.md`: documents Ctrl+B with explicit
  fall-through behavior so the conflict with the prompt-area
  cursor-left binding is intentional + understandable.

## Tests

- `keyMatchers.test.ts` (+1): Ctrl+B positive / bare-b + meta+b +
  Ctrl+other negatives.
- `AppContainer.test.tsx` (+2):
  - **Ctrl+B promotes** — pendingToolCalls includes an executing
    shell with a stubbed `AbortController` + spy; firing Ctrl+B
    asserts `abort({ kind: 'background' })` is called once.
  - **Ctrl+B no-op** — empty `pendingToolCalls` + Ctrl+B must NOT
    throw (pins the safety contract for the typing-mid-prompt
    case where the input layer's own Ctrl+B should still fire).
- 37/37 keyMatchers + 58/58 AppContainer pass; tsc + ESLint clean.

## E2E (manual, PR description guidance)

The unit / integration tests cover the keybind → abort wiring and
the promote handler's downstream behavior (PR-2's tests). Real-PTY
E2E is intentionally manual since headless test infrastructure
doesn't drive a real shell child + Ctrl+B keystroke; documented in
the PR description checklist.

Closes the 3-PR sequence for #3831 (Phase D part b of #3634).

* fix(cli): #3969 review wave — broadcast comment + debug log + redundancy

5 #3969 review threads addressed:

- **AppContainer.tsx Ctrl+B handler**: documented the
  KeypressContext.broadcast caveat (after `return`, the same Ctrl+B
  is still dispatched to text-buffer cursor-left + DebugProfiler;
  visible cursor-left side effect is cosmetic) so future readers
  understand why the prompt cursor moves on a successful promote.
  Added `debugLogger.debug` calls on both branches (matched callId
  on success; streamingState + pendingToolCalls.length on no-op
  fall-through) so "Ctrl+B doesn't work" reports are debuggable.

- **useReactToolScheduler.ts TrackedExecutingToolCall**: dropped
  the redundant `pid?` and `promoteAbortController?` declarations
  — both come through the `& ExecutingToolCall` intersection
  unchanged. Fixed the JSDoc that wrote `{ kind: 'background',
  shellId }`: callers don't generate `shellId` (it's optional on
  the abort-reason union and `handlePromotedForeground` produces
  it downstream). The corresponding executing branch in
  `toolCallsUpdateHandler` no longer projects pid /
  promoteAbortController explicitly — `...coreTc` already spreads
  them; the explicit-undefined clearing in the non-executing
  branch is also dropped (those fields aren't on coreTc when
  status !== 'executing', so `...coreTc` doesn't carry them).

- **AppContainer.test.tsx**: replaced two `as unknown as Key`
  double-casts with direct `: Key` annotations on the literal —
  the object already conforms to the Key interface, double-cast
  was bypassing type safety needlessly.

Tests: 37/37 keyMatchers + 58/58 AppContainer pass; tsc + ESLint
clean. No behavior change beyond the new debug log lines.

* fix(cli): #3969 wave — tool-name guard + non-shell test + defensive clear

3 #3969 review threads addressed; 1 deferred:

- AppContainer.tsx: Ctrl+B `find()` predicate now also checks
  `tc.request.name === ToolNames.SHELL` before matching the executing
  tool call. Defense-in-depth — today only the shell tool wires
  `promoteAbortController`, but a future copy-paste / type confusion
  that adds the property to a non-shell tool would otherwise let
  Ctrl+B mistakenly fire `abort({kind:'background'})` on a tool
  whose service has no promote-handoff handler.

- useReactToolScheduler.ts: re-added explicit `pid: undefined` and
  `promoteAbortController: undefined` to the non-executing return.
  Previously dropped on the assumption that `...coreTc` doesn't
  carry these fields when the status isn't `executing` — true today,
  but the explicit clearing is defense-in-depth against a future
  core change that adds either field to a non-executing status type
  (would surface as a stuck PID display or a Ctrl+B handler that
  matches a no-longer-executing tool call).

- AppContainer.test.tsx: replaced the placeholder "no-op when no
  pending tool calls" framing on the empty-array case (it does
  exercise the `executing-status` predicate but NOT the tool-name
  guard) with TWO tests:
    1. existing empty-array no-throw test (renamed for clarity)
    2. NEW: executing non-shell tool with a hostile-shape
       `promoteAbortController` — asserts `abortSpy` is NOT called.
       This is the regression test for the new tool-name guard above.

Tests: 61/61 AppContainer.test.tsx pass; tsc + ESLint clean.

Deferred to follow-up (replied + tracked):
- `debugLogger.debug` is file-only; success-path "agent unblocks +
  next message says 'promoted to bg_xxx'" is the user-visible signal.
  Adding a synthetic history item or stderr line for the gap between
  keypress and agent message conflicts with Ink rendering and is
  better as a focused UX PR.

* test(cli): pin inheritance of pid + promoteAbortController via type assertions

#3969 review: the earlier "redundant declaration" review removed the
explicit `pid?: number` and `promoteAbortController?: AbortController`
from `TrackedExecutingToolCall`, relying on the `& ExecutingToolCall`
intersection to inherit them. Current review flags the type-safety
regression: if core renames or removes either field, the React-side
build won't catch it locally — Ctrl+B handler silently breaks at
runtime.

Compromise: keep the type minimal (no re-declaration noise the prior
review flagged) but add compile-time `extends keyof ExecutingToolCall`
assertions that fail loudly + locally if either field disappears.
The assertions are evaluated at compile time and zero-cost at
runtime; the dummy `const` pins them so they aren't dead code.

61/61 AppContainer tests pass; tsc clean.
2026-05-11 14:03:38 +08:00
ChiGao
7f0c9791b7
feat(cli): expand TUI markdown rendering (#3680)
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
SDK Python / SDK Python (3.10) (push) Waiting to run
SDK Python / SDK Python (3.11) (push) Waiting to run
SDK Python / SDK Python (3.12) (push) Waiting to run
* feat(cli): expand markdown rendering in tui

* fix(cli): render finalized mermaid images synchronously

* fix(cli): harden markdown rendering paths

* fix(cli): preserve mermaid source fallbacks

* test(cli): make mermaid image renderer mock cross-platform

* fix(cli): run windows mmdc shims through shell

* fix(cli): address markdown rendering review comments

* fix(cli): validate mermaid render timeout

* feat(cli): expose rendered markdown source blocks

* fix(cli): align mermaid source copy controls

* fix(cli): make markdown render toggle visible

* fix(cli): keep markdown render toggle quiet

* fix(cli): generalize markdown render mode

* fix(cli): broaden render mode and copy latex blocks

* fix(cli): align rendered copy source indices

* fix(cli): support copying inline latex expressions

* feat(cli): document markdown render controls

* test(cli): cover markdown render controls

* fix(cli): tighten markdown render fallbacks

* fix(cli): bound mermaid renderer cache

* fix(cli): address markdown render review feedback

* fix(cli): address markdown render review comments

* test(cli): strengthen render mode shortcut coverage

* fix(cli): address mermaid image review comments

* fix(cli): stabilize renderer output truncation

* test(cli): flush fake renderer stderr before exit

* fix(cli): address markdown renderer review feedback

* docs(cli): clarify mermaid image limits

* fix(cli): refresh mermaid images on height resize

* fix(cli): address markdown render review

* chore: revert unrelated review formatting churn

* fix(cli): avoid mermaid regex codeql alert

* fix(cli): silence mermaid operator codeql alert

* fix(cli): render inline math in markdown tables

* fix(cli): harden markdown visual renderers

* fix(cli): strip c1 controls from mermaid previews

---------

Co-authored-by: 秦奇 <gary.gq@alibaba-inc.com>
2026-05-07 16:24:13 +08:00
Shaojin Wen
746f67f436
refactor: rename verboseMode to compactMode for better UX clarity (#3075)
The "Compact Mode" label is more intuitive than "Verbose Mode" for users,
as it directly describes the default compact view experience. This change
inverts the boolean semantics (compactMode=false means show full output)
and exposes the setting in the /settings dialog (showInDialog: true).

- Rename ui.verboseMode → ui.compactMode with inverted default (false)
- Rename VerboseModeContext → CompactModeContext (file and exports)
- Rename TOGGLE_VERBOSE_MODE → TOGGLE_COMPACT_MODE in key bindings
- Update all consumer components with inverted logic
- Update i18n keys across 6 locales (verbose → compact)
- Update VS Code settings schema
- Add ui.compactMode documentation to settings.md
- Fix Ctrl+O description in keyboard-shortcuts.md
2026-04-10 11:55:50 +08:00
易良
c353fbbfa3
feat(cli): add Ctrl+Y shortcut to retry failed requests (#2011)
* feat: add Ctrl+Y shortcut to retry failed requests

- Add Ctrl+Y keyboard shortcut for retrying the last failed request
- Add isNetworkError() to detect transient network failures (ECONNREFUSED, ETIMEDOUT, etc.)
- Add DashScope 1305 error code to rate limit detection
- Add error hint \"Press Ctrl+Y to retry\" in error messages
- Support user-defined error codes for retry via config
- Add retryLastPrompt() hook in useGeminiStream
- Update keyboard shortcuts documentation

* feat: improve Ctrl+Y retry feature with tests, docs, and rate limit config

- Add comprehensive tests for Ctrl+Y retry shortcut in InputPrompt
- Add unit tests for retryLastPrompt in useGeminiStream hook
- Add detailed JSDoc comments for retryLastPrompt function and Ctrl+Y shortcut
- Extend isRateLimitError to support custom error codes via retryErrorCodes config
- Fix rate limit retry log variable reference (RATE_LIMIT_RETRY_OPTIONS → maxRateLimitRetries)
- Add Eclipse IDE files to .gitignore

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* refactor(ui): consolidate retry countdown as inline hint in error messages

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* feat(cli): enhance error handling with improved retry mechanism

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

- Modify ErrorMessage component to remove dim color from hint text

- Update useGeminiStream hook to improve retry countdown behavior with option to preserve or clear hints

- Adjust tests to match new error handling implementation

* feat: add Ctrl+Y shortcut to retry the last failed request

When a request errors out, the error message shows an inline hint
"(Press Ctrl+Y to retry.)" in secondary color. Pressing Ctrl+Y
re-submits the same prompt, commits the error text to history
(without the hint), and clears the hint from the UI.

- Add retryLastPrompt action wired to Ctrl+Y via keyBindings and InputPrompt
- Track last submitted prompt and error state in useGeminiStream refs
- Show retry hint inline with error text in ErrorMessage component,
  wrapping naturally on narrow terminals while preserving hint color
- Expose retryLastPrompt through UIActionsContext
- Add keyboard shortcut entry in KeyboardShortcuts display
- Add i18n strings for hint and no-retry-available message
- Document Ctrl+Y in keyboard-shortcuts.md

* docs(configuration): Update model provider configuration document

* chore: remove YOLO mode code from core

* fix: prevent Ctrl+Y hint from overriding auto-retry countdown

When an auto-retry countdown is active (retryCountdownTimerRef is set),
handleErrorEvent should not overwrite it with the Ctrl+Y hint. The auto-retry
hint ("retrying in Xs...") and manual retry hint ("Press Ctrl+Y to retry.")
are mutually exclusive:

- Auto-retry errors (e.g., rate limits): show countdown hint
- Other errors: show Ctrl+Y hint

Also removed retryErrorCodes from ContentGeneratorConfig as it's not part
of the minimal Ctrl+Y feature scope.

* simplify: remove complex options from clearRetryCountdown

Revert clearRetryCountdown to simplest form without options parameter.
The function now just clears the timer and pending item without any
automatic history commit logic.

* fix: restore pendingRetryCountdownItem as separate state from pendingRetryErrorItem

Auto-retry countdown and manual retry hint are now independent:
- pendingRetryErrorItem: displays error message with optional hint
- pendingRetryCountdownItem: displays separate countdown line for auto-retry

This ensures both can be shown simultaneously without overriding each other.

* fix: restore RetryCountdownMessage rendering in HistoryItemDisplay

The retry_countdown type should be rendered as a separate message,
not inline in ErrorMessage. This allows auto-retry countdown and
manual retry hint to coexist properly.

* fix(cli): properly commit retry error item to history before clearing

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): remove trailing period from retry hint translations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

Remove unnecessary period from 'Press Ctrl+Y to retry' translation strings in both en.js and zh.js locales. Also update the corresponding usage in useGeminiStream hook.

* chore(sdk-java): add Eclipse project configuration files

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

Add .project configuration files for client and qwencode modules to support Eclipse IDE development environment.

* feat(cli): add retry countdown hint to error message

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* Revert "chore(sdk-java): add Eclipse project configuration files"

This reverts commit da83b5e571.

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-02 17:59:18 +08:00
LaZzyMan
c8297300d9 Merge branch 'main' into feat/image-attachment 2026-02-05 11:09:34 +08:00
LaZzyMan
3296785b23 feat use tab on windows instead of shift+tab 2026-02-02 19:48:07 +08:00
LaZzyMan
1050163804 fix paste image on windows 2026-02-02 17:07:39 +08:00
tanzhenxin
b804b1f48a feat: Redesign CLI welcome screen and improve visual consistency 2026-01-16 11:48:31 +08:00
pomelo-nwu
5742a69d8a feat: update docs 2025-12-15 19:40:14 +08:00
joeytoday
f417ace1b0 docs: update various documentation for clarity, formatting, and link corrections 2025-12-12 18:20:31 +08:00
joeytoday
9fd4f58c16 docs: Add detailed documentation for Qwen Code's approval modes and usage
- Introduced a comprehensive guide on the four permission modes: Plan, Default, Auto-Edit, and YOLO, including their use cases and risk levels.
- Updated the overview and quickstart documentation for clarity and consistency.
- Removed the outdated CLI reference document and integrated relevant content into the updated documentation.
- Improved command creation examples and best practices for custom commands.
2025-12-11 21:12:32 +08:00
joeytoday
0ae3a2247d docs: update sandbox title, enhance overview, and add CLI reference documentation 2025-12-11 14:54:37 +08:00
joeytoday
70b5aee381 docs: Add documentation for Sub Agents feature and update user guides
- Introduced a new documentation file for Sub Agents, detailing their purpose, benefits, configuration, and usage examples.
- Updated the overview and quickstart guides to improve clarity and remove outdated information.
- Created a comprehensive command reference document for Qwen Code, detailing slash commands, at commands, and exclamation commands for better user guidance.
- Enhanced the formatting and organization of existing documentation for improved readability and usability.
2025-12-09 14:05:26 +08:00
pomelo-nwu
bfe8133ea3 feat: refactor docs 2025-12-05 10:51:57 +08:00