Skip to content

feat(tui): run read-only slash commands while a response is streaming - #512

Merged
qwen-code-dev-bot merged 2 commits into
mainfrom
issue/511-streaming-readonly-commands
Aug 3, 2026
Merged

feat(tui): run read-only slash commands while a response is streaming#512
qwen-code-dev-bot merged 2 commits into
mainfrom
issue/511-streaming-readonly-commands

Conversation

@qwen-code-dev-bot

Copy link
Copy Markdown
Owner

Closes #511

Executes the self-discovery issue #511 (behavior-level reference: Qwen Code
v0.21.3 shipped the same affordance in QwenLM/qwen-code#8130; behavior only —
no code, prose, or assets copied).

Summary

While a turn is in flight the interactive composer was fully locked: the user
could neither type nor inspect state without waiting for completion or
cancelling the turn. Long responses made the shell effectively single-tasking.

  • The composer stays editable during streaming (submitting/disabled
    remain locked). Typing mid-stream preserves the streaming mode, so the
    affordance stays truthful — the band keeps reading ✦ streaming, never an
    editable-prompt marker.
  • A bounded, code-defined allowlist runs immediately mid-turn: the six
    secret-safe runtime commands (/status, /model, /settings, /tools,
    /capabilities, /continuity) plus /help (incl. the /? alias). They
    dispatch through the existing palette path and render their existing
    redacted output as an in-place notice.
  • Prompts and non-allowlisted commands (/clear, /exit, /attach, /ask,
    /goal, overlays…) are rejected with an explicit, non-destructive notice;
    the typed draft is preserved and submits once the turn settles.
  • Turn serialization is untouched: submitWhileBusy never queues, interrupts,
    or reorders a run; pure busySubmitDecision classifies the mid-turn submit
    (run-command / ignored / rejected) for unit testing.

Non-goals (per the execution issue)

  • No changes to streaming, provider calls, retries, or turn serialization.
  • /clear and /exit are not allowlisted mid-stream; overlays (/stats,
    /lsp, /tasks, /mission, /activity) stay gated.
  • No new commands, no desktop-surface changes, no settings changes.

Reviewer Test Plan

  • Interactive run in tmux against a slow-streaming fake provider: while the
    response streams, run /status — redacted output appears in place and the
    turn completes undisturbed (receipt captures bound to the head SHA are on
    the issue).
  • Type a plain prompt mid-stream — explicit rejection notice; the draft stays
    in the composer and is submittable after the turn settles.
  • npm run typecheck, npm test (3017 tests incl. 9 new), integration
    vitest (483), and npm run smoke all green.

While a turn is in flight the composer was fully locked: a user could
neither type nor inspect state without waiting for completion or
cancelling the turn (Issue #511).

- The composer stays editable during `streaming`; `submitting` and
  `disabled` remain locked, and the streaming mode is preserved while
  a mid-stream draft is typed so the affordance stays truthful.
- New bounded allowlist (slash-command.ts): the six secret-safe runtime
  commands (/status, /model, /settings, /tools, /capabilities,
  /continuity) plus /help run immediately mid-turn via the existing
  palette path; pure `busySubmitDecision` classifies a mid-turn submit
  (run-command / ignored / rejected).
- Prompts and non-allowlisted commands are rejected with an explicit,
  non-destructive notice; the typed draft is preserved and submits once
  the turn settles. Turn serialization is untouched: nothing is queued,
  interrupted, or reordered, and command output renders as an in-place
  notice under the streaming entry.
- Unit tests cover allowlist membership, the busy-submit matrix
  (including the /? alias and argument carry-over), and the truthful
  streaming affordance with a mid-stream draft.
Extend the Interactive REPL section: the read-only commands run
immediately while a response streams, and anything else typed
mid-stream waits with the draft preserved (Issue #511).
@qwen-code-dev-bot

Copy link
Copy Markdown
Owner Author

Independent self-review (head bb30916)

Reviewed the full diff against the acceptance criteria in #511, independent of implementation.

Findings: 0 Critical, 0 High, 1 Minor (non-blocking).

  • Minor: after a turn settles, the composer mode is set to focused even when the preserved mid-stream draft contains newlines (the marker reads "edit" rather than "multiline"). Purely cosmetic — submission behavior is identical — and the pre-existing terminal transitions were left untouched.

Verified against acceptance criteria:

  • Allowlisted commands run immediately mid-stream with their existing redacted output; the turn continues undisturbed and completes: proven by the tmux E2E receipt (real interactive run against a slow-streaming fake provider; /status rendered in place while deltas kept arriving, then the turn completed with the full text).
  • Prompts and non-allowlisted commands are rejected with an explicit, non-destructive notice; the draft is preserved and submittable once the turn settles (receipt capture shows the draft intact in the composer after ✓ completed). submitting/disabled gating is unchanged (editable() and submitAllowed still lock them).
  • Allowlisted output renders as separate notice entries; the streaming entry updates in place at its own index, so ordering and the single-line turn indicator stay coherent (✦ streaming throughout; no interleaving observed).
  • Redaction unchanged: mid-stream commands dispatch through the existing palette path (formatRuntimeSlashCommandsafeValue/redactSecrets); the rejection notice is static text. /help opens the existing modal shortcut panel, which carries no secrets by construction.
  • Turn serialization: submitWhileBusy never calls queuePrompt, never advances the turn state, and never touches submitChain — nothing is queued, interrupted, or reordered. The allowlist is a fixed code-defined set; untrusted content cannot extend it.
  • Tests: allowlist membership + exclusions, busySubmitDecision matrix (alias /?, argument carry-over, prompts, /clear//exit//quit//goal//attach/unknown, empty input), and the truthful streaming affordance with a mid-stream draft. Full suite green: 171 files / 3017 tests, integration vitest 483, smoke 54, typecheck, audit 0.
  • No protected governance paths touched; no new dependencies.

@qwen-code-dev-bot
qwen-code-dev-bot merged commit 0b08548 into main Aug 3, 2026
2 checks passed
@qwen-code-dev-bot
qwen-code-dev-bot deleted the issue/511-streaming-readonly-commands branch August 3, 2026 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TUI: run read-only slash commands while a response is streaming

1 participant