Skip to content

Input awareness: show when a command is waiting for you - #348

Closed
raiseCatError wants to merge 34 commits into
release/v0.18.0from
feature/input-awareness
Closed

raiseCatError wants to merge 34 commits into
release/v0.18.0from
feature/input-awareness

Conversation

@raiseCatError

@raiseCatError raiseCatError commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Input awareness keeps replies with the persistent foreground shell, including authenticated Fish reader handover, hidden/key input and detach/reattach. Native multiline grouping remains zsh/Bash braces or Fish begin/end. Startup follows the current foreground owner while preserving ordinary journal durability, renderer-entry ordering and owned terminal-mode/Kitty restoration. Stopped prompt, exec and raw events cannot restart frontend work.

Restored NMSh command/status presentation respects NO_COLOR without changing raw program SGR or stored transcript bytes. Authoritative cwd reaches command snapshots before asynchronous context collection. Live session polls preserve selected ID/query/draft/focus. Socket helpers validate private owned runtime directories; held lifecycle requests drain EOF without exposing withheld output.

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: 6aba63bd78f467af8aeaf60421faef05c608646b. Focused lifecycle, clean exact-head canonical build/full runtime/ranking/cleanup/diff verification pass. Comprehensive candidate CI 38525959028 passes every required job, including Fedora/timing; actual PR CI 38527326783 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: hidden/function/key reads, immediate typing after read/interrupt, fullscreen modes/resize/selection, detach/reattach and repeated frontend/session switches. Automated/headless results do not claim this validation.

Refs #356
Refs #359

…ing the way it reads

A command that waits for an answer no longer looks like any other running command. InputWatch, beside the PTY
(session service or in-process), decides from positive evidence only:
- the terminal's line settings (stty): echo off with line input is a hidden read; line input off with a prompt
  left open is single-key input (e2fsck's Fix<y>?); both confirmed;
- on Linux, the kernel's report of a blocked read of the terminal (confirmed), or of a block elsewhere (veto);
- otherwise a question-shaped line left open, quiet output and an idle foreground group: "probably".
Programs that own the terminal, builds, sleep, network waits, progress rewrites, statuses and log streams are
never reported.

One state reaches every surface: the live activity rows show the attention line and the open question (no
extra rows, no PTY resize), the window title, /sessions, /resume, and one sticky cross-session notice per
wait. A new input-state message and the "input" notice kind go only to frontends that list the feature.

Hidden and single-key input goes straight to the program key by key (never shown, kept or logged), which
also fixes the stray Enter that answered the next single-key question with its default and the password
drawn in the composer. Keys typed after the question but before detection are handed over; a line reply
left unsent when the command ends is discarded, never run. Waiting time is measured apart from wall-clock
duration, carried with the completing prompt, and recorded on the transcript record.
The pause stood in for a Fish keystroke loss that was the test typing
ahead: a bare /Completed/ matched the previous command's row, so the
next command was typed while read -s still ran. The loss itself is
fixed on the release branch.
…me counted once

CI found it on macOS: after a reattach, the completion row read
'5.7s · 7.6s waiting for input (3 prompts)'. Reattaching resizes the
PTY; the waiting program wakes for SIGWINCH and one look sees it
running, so the wait closed and was found again, restarting at the old
prompt time and counted as a new prompt. A new wait now never starts
before the previous one ended, and a prompt is counted once per stretch
of output or input.

The live tests expect what each platform can know: on Linux (first run
in CI) the kernel confirms an ordinary line read and names the program
python3; macOS infers it and says Python.
@raiseCatError
raiseCatError force-pushed the feature/input-awareness branch from f25c1f3 to 6fd2964 Compare October 10, 2026 05:38
zsh and bash 'read -t' wait in select/pselect6/ppoll, not read(), so the
kernel's report never confirms them; the discard test now accepts either
certainty, and the syscall test pins timed reads as waits.
…wn start

When the evidence for a waiting program lapsed for a look (a slow probe, a resize while a window
detaches) and returned with nothing written or typed in between, the watcher reopened it as a new
wait starting at the lapse. Other windows and /sessions then showed a fresh wait, and macOS CI saw
the start move across a detach. Now the same prompt keeps its start, and the time that closing it
added is taken back, so it is still counted once.
@raiseCatError

Copy link
Copy Markdown
Owner Author

Integrated, not merged here: this head (6aba63bd) 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