Skip to content

Command queue: prepare the next commands while one runs - #357

Closed
raiseCatError wants to merge 36 commits into
feature/input-awarenessfrom
feature/command-queue
Closed

raiseCatError wants to merge 36 commits into
feature/input-awarenessfrom
feature/command-queue

Conversation

@raiseCatError

@raiseCatError raiseCatError commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Commands can be reviewed and queued while a foreground program keeps its input. The queue dispatches one entry at a time through the same persistent real shell, preserving cwd, variables and native multiline semantics. Dispatch requires authenticated readiness; failure/interruption pauses work, explicit conditions control continuation, and edits withdraw approval for the changed entry. Queue composition and direct program replies retain separate ownership.

The additive stabilization fixes catchable startup termination and frontend cleanup. SIGTERM/SIGHUP handlers precede host-probe/journal waits; stopped probe completion cannot create a journal, and saves already underway retain durability. Stop removes only the frontend's instance-owned exit callback, preventing retention across session switches while preserving unrelated listeners. Controlled regressions fail before correction and pass afterward; assertions and deadlines are unchanged.

The reattach fixture waits for the complete final-size native pager frame and prompt before a single quit key, retaining original deadlines and strict cleanup. Bounded failure-only observations distinguish repaint from quit completion. Controlled native less read/WINCH evidence establishes a signal/input hazard; it does not reconstruct historical CI failures.

Native completion retains fragmented readiness within a bounded initialization buffer and recognizes the complete LF/CRLF marker without resetting existing budgets. A real-PTY regression fails before correction and passes afterward, including naturally fragmented reads. This independently confirmed framing fix does not establish the historical Copy recovery failure cause.

Published head: 5ab9892060fb0aed2d89f34842a9739c6e860163. Focused lifecycle, clean exact-head canonical build/full runtime/ranking/cleanup/diff verification pass. Comprehensive candidate CI 38528656051 passes every required job, including Fedora/timing; actual PR CI 38529888852 passes applicable platform/runtime/aggregate gates. Attempts: 1/1.

Shared acceptance, exact ancestry, remaining gates and retained historical failures are tracked in #359 and the durable handoff. Historical macOS/Ubuntu failures remain unattributed; new passes do not explain them. Native pager input during concurrent resize remains a physical QA limitation. Forced SIGKILL can bypass detached-helper cleanup while trusted configuration blocks it. No release/master merge or frontend integration occurs here.

Physical QA remains unperformed in Ghostty/Terminal.app across zsh, Bash and Fish: foreground reader ownership, multiline/state persistence, exact-once queue dispatch, failure/interruption/approval/edit conditions and repeated frontend switches. Automated/headless results do not claim this validation.

Refs #356
Refs #359

…order in the same shell

While a command runs, Enter adds the composer's command to the session's queue (Ctrl+Q always queues,
Ctrl+S sends the line to the running program). Entries run one at a time through the session's own
shell, each only after the previous command reached its prompt, so directory, variables, functions
and options carry over. A failure, Ctrl+C or a shell switch pauses the rest with the reason;
/queue resume continues and /queue clear drops them, and nothing runs twice.

- The queue belongs to the session service (in-process client alike): it keeps running while no
  window is attached, and the exec event says which command came from the queue, so a window that
  attaches later shows "from queue" for it too.
- Input ownership first: a program known to wait for input, or one that left a question open on
  its line ("Password: ", "Continue? [y/N] ") before any probe looked, gets Enter; a reply is never
  queued or run as a command. After Ctrl+C or Ctrl+Z, typing goes to the shell prompt as type-ahead.
- Ctrl+Q during single-key input composes an entry the program never sees; Enter adds it.
- /queue opens a manager to edit, reorder, remove, pause and clear; the queue line by the composer
  shows what runs next or why it waits. Settings, Setup, Ask and settings export know about it.
- Live tests over zsh, Bash and Fish: ordering and state, failure and interrupt pauses, prompts,
  hidden replies, multi-line entries, detach and reattach, narrow/NO_COLOR/Safe glyphs. A live
  start that never becomes ready now ends its sandbox instead of hanging the test file.
Entry previews, pause reasons and the panel's block preview show control characters visibly (␛, ·)
instead of writing them to the terminal: a pasted OSC 52 or screen clear inside a queued command
can no longer act on the host terminal.
…the rest of the command

Typing after a stop goes to the shell prompt only for two seconds. A program that survives the
signal (a REPL, a remote shell, a trap) gets the ordinary routing again, so later typing queues as
usual and is never written into that program's input unasked.
…er-read files so shards do not stack them

These files take 17 to 68 seconds each but counted as 1, so a shard could run several heavy PTY files together on a 4-core runner and starve the timing-sensitive Fish and alternate-screen tests (17 to 24 second budgets), which then failed only on Ubuntu from this branch up.
…xt command only once the last one completed

With the queue, Enter while a command runs and nothing asks a question queues the next command. These tests typed their answer as soon as the command's own echo contained the prompt text (it does), or typed the next command before the previous one had completed, so on a slower runner the answer or command was queued instead of sent. They now wait for the program's own prompt (the second occurrence of its text, or NMSh's waiting headline) and for the previous completion.
…he command text NMSh echoes

In Classic wording NMSh's live line reads "Running read -P 'Name: ' x…", so waiting for "Name: " (or a second copy of it) was satisfied by NMSh's own line before Fish drew anything, and the answer was typed too early. The prompt is now produced by printf inside the command, so the text only appears when the shell prints it.
…ng command or the type-ahead window early

The first test queued five commands behind sleep 3 and the Ctrl+C test typed 0.6 seconds after a 2 second type-ahead window; on a loaded macOS runner either margin was lost and the typing was treated as type-ahead or the queue had already started.
…outing

# Conflicts:
#	src/session/SessionProtocol.ts
…outing

# Conflicts:
#	tests/inputAwarenessLive.test.ts
# Conflicts:
#	src/session/SocketSessionClient.ts
@raiseCatError

Copy link
Copy Markdown
Owner Author

Integrated, not merged here: this head (5ab98920) is part of the release line that shipped in v0.20.0 through the authoritative release PR #392 (merge commit 65e4de55). Closing because its changes reached master by that route; the branch is kept for history.

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.

1 participant