Repository navigation
Queue composer, unfinished command lines and owner-side reply hold (stacked on #514) - #541
Draft
raiseCatError wants to merge 6 commits into
Draft
raiseCatError wants to merge 6 commits into
raiseCatError wants to merge 6 commits into
Conversation
Queue Mode (#473, #426): an explicit per-window choice that Enter queues a line while a command runs, shown as typed and run once, in order, with no approval step. Ctrl+Q on an empty line or /queue mode [on|off] toggles it; Settings > Queue > Start in Queue Mode sets how windows start (off by default). Input ownership is unchanged: the look before typing is drawn, Enter to a program NMSh sees waiting, hidden input and the held state when a look cannot tell all behave as before. At the prompt a Queue Mode line is added after entries already waiting instead of running ahead of them; only a paused queue gives the prompt back. Unfinished command lines: zsh and Bash print PS2 as a private marker. A continuation prompt the submission's own line breaks do not explain means the shell waits for the rest of a line NMSh sent whole (an unclosed quote, or zsh history expansion turning `!"` into an open quote). The session cancels it with the adapter's sequence (zsh: Ctrl+C then Enter; Bash: Ctrl+C), the prompt carries `incomplete`, the frontend explains it and gives the line back, and the queue pauses before what follows. Previously the line waited at an invisible PS2 forever and typing for it was held as "Can't tell whether echo is reading your typing". Program names: a line of several commands is called "the command", never its first word, which may have finished long ago.
This was referenced Nov 11, 2026
…input An Enter pressed before NMSh can see that the running command reads (an echoing terminal is no evidence, see #514) reaches the queue as a command, and in Queue Mode without approval. The session service now holds every entry queued since the command was submitted as soon as the command is first reported asking for input, before any frontend hears of it, so the next dispatch can never overtake the hold. Hidden input also hides the held text. Adds a deterministic dispatcher test for a reader that ends right after it was seen, and a live zsh test of #514's controlled race with Queue Mode on (the fixture files are byte-identical copies of #514's). Refs #426 Refs #473
… functions and substitutions Complete multi-line constructs (quoted and unquoted heredocs, a quote inside a heredoc, multi-line strings, escaped newlines, a function, a multi-line command substitution, blank lines in an if block, ! in single quotes) run untouched on zsh and Bash; five unfinished lines are cancelled with nothing run, and the next command after each runs normally. Refs #473
A standing "Enter queues" mode cannot be made safe: on macOS nothing reports that a program reads with no prompt, so no setting can tell a reply from a command, and it would weaken #514's boundary for every command. Ctrl+Q on an empty line while a command runs now opens the queue composer for that command only: each line entered in it is queued as typed, without approval, until Esc, a second Ctrl+Q on the empty line, or the end of that command. Plain Enter keeps #514's rules. Hidden input closes the composer before anything is drawn: its first key is looked at like the composer's, and a request reported while it is empty closes it. A line already begun in it stays a queued command. Removes the Start in Queue Mode setting and /queue mode. The owner-side hold on late-detected readers stays. Documents the remaining limit: a reader NMSh never sees before it ends. Refs #426 Refs #473
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Queue several commands while one runs, unfinished command lines, accurate program names, and an owner-side hold for late-detected readers.
Stacked on #514: this branch merges #514's head
416bc51a, so #514 must merge first. The diff againstdevincludes #514 until then.What changed and why
Queue composer (replaces the earlier standing "Queue Mode")
A standing "Enter queues" mode can't be made safe. On macOS nothing reports that a program reads with no prompt, so no setting can tell a reply from a command, and such a mode would weaken #514 for every command. It was removed, together with its setting and
/queue mode.Owner-side hold for late-detected readers
When the running command is first reported asking for input, the session service holds every entry queued since that command was submitted, before any dispatch, and hides their text if the input is hidden. Entries come from Ctrl+Q, the composer, or anything routed before the reader was visible. This closes the timing gap where a frontend's hold request could arrive after the next entry had already been dispatched (
QueueDispatcher.onInputRequest, wired inSessionServiceandInProcessSessionClient).Unfinished command lines
zsh and Bash draw PS2 as a private marker. When the shell asks for more continuation lines than the submission's own line breaks explain, the session cancels the line (nothing ran), explains why (including zsh's
!"history expansion), and gives the line back unless you're already typing. A queue pauses before the next entry.Names
A line of several commands is called "the command", not its first word.
Limits that remain (documented in
docs/design/input-awareness.md)dev(not changed here): an unclosed quote leaves Fish waiting, and following submissions are absorbed until Ctrl+C. Fish has no continuation marker.Automated verification (head
a053031e)queueComposer,queueReplyHold,inputQuarantine,inputOwnership*,incompleteSubmission, …). Adversarial cases:queueComposerLive: zsh, Bash and Fish run composed lines once, in order, without approval. The Fish run first timed out with 0 frontend output bytes at load 20 and passed on rerun; both logs are kept.queueComposerRaceLive: Hold ambiguous program input for explicit recovery #514's controlled race, 0 ms and 300 ms. The reply is never run.incompleteSubmissionon zsh and Bash 5.3: heredocs, a quote inside a heredoc, multi-line strings, escaped newlines, functions, multi-line$( ), and blank lines inifall run. Five unfinished forms are cancelled with nothing run.npm run verifywill run once, sequentially, on the pinned integration candidate. Hosted CI: earlier Ubuntu failures were the runner's apt mirror DNS outage (Temporary failure resolving 'azure.archive.ubuntu.com'); no NMSh test ran on Ubuntu.Needs human testing (Rex, Ghostty, Terminal.app)
sleep 15, then Ctrl+Q on an empty line. The composer should say "Queueing". Type three lines with Enter; they should run after sleep, in order, with no approval.sleep 5again and type a line with plain Enter: the "Can't tell…" choice appears and nothing is queued.sudo -k truewith the composer opened first: typing the password closes the composer, and the password is never drawn.echo "Finished!"in zsh: it is cancelled and explained, the line is returned, and nothing hangs.Refs #426
Refs #473