qwen-code/packages/cli
tanzhenxin c87d2798bd
fix(cli): dispatch queued slash commands through the slash path (#3523)
* fix(cli): dispatch queued slash commands through the slash path

When the agent was responding and the user queued a message, the drain
path joined all queued messages with `\n\n` and submitted them as one
prompt. Any slash command in that blob (e.g. `/model`) no longer started
with `/`, so it was sent to the model as plain text instead of opening
the command's dialog.

The mid-turn tool-result drain had the same problem: it drained the
entire queue into the tool-result payload, so a slash command queued
during tool execution was injected as context for the model rather than
executed as a command.

Queue draining now splits into segments — consecutive plain-text
messages are still batched into one submission, while slash commands
are submitted alone so their `/` prefix survives. The mid-turn drain
only takes leading plain-text messages and leaves slash commands
queued for the normal idle drain. The idle drain is gated on open
dialogs so a queued `/model` does not cause the following queued
prompt to be sent to the model while the picker is still open, and a
re-entry lock plus a nonce close the race between state commits and
the async dialog-open.

* fix(cli): defer queued slash commands until idle

* fix(cli): drop queued messages on cancel instead of auto-submitting

Cancel's contract is now "abort and redirect" in both cancel paths:
restore the most recent queued segment into the buffer for editing and
drop the rest, so forgotten follow-ups cannot auto-submit once the turn
settles. Previously the non-tool path left queued plain-text segments
in place for the idle drain to fire, and the tool-executing path
cleared only the buffer — both surprised users with belated message
dispatches after they had already cancelled.

* refactor(cli): batch plain prompts in idle drain

Idle drain now runs in two phases: drain all plain-text prompts into one
turn (drainQueue), then pop slash commands one-by-one (popNextSegment).
Mirrors the mid-turn behavior so queue handling is consistent across
mid-turn and idle contexts.

popAllMessages now drains the entire queue joined with \n\n for Ctrl+C
cancel and ESC/Up edit-restore. Drop the unused options parameter from
useMessageQueue and the extractFirstSegment helper.

---------

Co-authored-by: 愚远 <zhenxing.tzx@alibaba-inc.com>
2026-04-24 17:11:00 +08:00
..
src fix(cli): dispatch queued slash commands through the slash path (#3523) 2026-04-24 17:11:00 +08:00
index.ts feat(core): detect tool validation retry loops and inject stop directive (#3178) 2026-04-18 10:24:46 +08:00
package.json chore: bump version to 0.15.1 (#3541) 2026-04-23 11:06:07 +08:00
test-setup.ts fix: prevent bogus shell permission rules in tests 2026-03-20 17:55:33 +08:00
tsconfig.json Merge pull request #2428 from qqqys/feat/mcp_reconnect_error 2026-04-01 16:53:36 +08:00
vitest.config.ts refactor(core): Unify package exports and improve dev experience 2026-02-01 11:59:05 +08:00