Repository navigation
Decline attach's restart prompt when nobody answers (#214) - #215
Merged
Merged
Conversation
attach on a dead session asks Restart? [Y/n] and read stdin with no terminal check. EOF read as an empty answer, which restarts, so a caller without a terminal reran the stored command although nobody agreed to it. --force did the same. The prompt now counts only an answer someone gave (decision 0020): - At a terminal, any line but a lone n restarts, as before. - Off a terminal, only y or yes restarts. - EOF never does. With no answer, attach exits 1, keeps the exited record and names -r. A lone n still exits 0, -r still restarts without asking, and --force still answers nothing. The Node tool restarts nothing at EOF either, but it exits 0 there, and off a terminal it restarts on any line but n. The conformance ledger records the three new tests that fail on Node as intended. pty restart's Kill and restart? prompt is unchanged. At EOF it still stops a running session and starts it again, where Node leaves the session running.
Contributor
Author
|
Independent read GO at exact head Read:
Release note (behavior change): Risks (low):
|
This was referenced Nov 4, 2026
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.
Fixes #214. A dead session now restarts from
attach's prompt only when someone answers it. This change departs from Node on purpose, and decision 0020 records it.Before.
attachon a dead session askedRestart? [Y/n]and read stdin with no terminal check. Any line but a lonenrestarted, and so did EOF, which read as an empty answer. A caller with no terminal reran the stored command although nobody agreed to it.--forceonly allows nesting, so it changed nothing here.Now. The prompt counts only an answer someone gave (
ask::ask_consent):nrestarts, an empty line included. This is unchanged.yoryes, in any case, restarts.attachends the prompt line and exits 1. It keeps the exited record and prints:nexits 0,-rrestarts without asking, and--forceanswers nothing.Node, measured. I built the pinned reference (
f005432a) and ran each case without a terminal. Rust before is mainddfcf093:</dev/nullfuture-inputyoryesn-r,</dev/null--force,</dev/null--force,yAt EOF, Node's
readlinequestion never resolves, and the process exits 0 after the prompt. The oldask.rscomment said a closed stdin proceeds "exactly like Node", which was wrong for EOF, and I repeated it on #204. So at EOF, Rust was the one rerunning commands, and this change stops it. The departure from Node is the exit code at EOF, and declining every line buty/yesoff a terminal.Other prompts with the same shape. Only
ask.rshas callers that prompt:attach'sRestart? [Y/n]is changed here.restart'sSession "<name>" is running. Kill and restart? [Y/n](restart.rs:110) is left as it was. Measured with no terminal,pty restart <name> </dev/nullstops a running session and starts it again. Node exits 0 and leaves the session running. A piped empty line restarts on both. That's a parity defect outside this decision, so I'll fix it separately if wanted.The other stdin readers (
metadata patch,operation reserve, readiness, the remote relay) read data, not answers.Release note.
pty attachno longer restarts a dead session when its restart prompt gets no answer. That covers stdin at EOF, and stdin that isn't a terminal unless it givesyoryes. It exits 1 instead, without running the stored command. Any script or seat that relied onattachrestarting a dead session non-interactively must pass-rnow.The repository has no release-notes file, since
release.ymlwrites fixed notes. So this text is here and in decision 0020's migration section, for whoever cuts the next release.Tests.
crates/pty-conformance/tests/attach_no_restart.rs, with no terminal:a_restart_prompt_at_eof_declines:</dev/null.a_restart_prompt_off_a_terminal_needs_a_yes: a piped empty line, then relayed input.a_piped_yes_restartsauto_restart_needs_no_terminal:-rwith</dev/null.force_is_not_an_answer_to_the_restart_prompt:--forceat EOF declines, then--forcewith a pipedyrestarts.default_policy_prompts_and_restartsandauto_restart_relaunches_without_prompting.ask::tests::consent_needs_an_answer_and_off_a_terminal_a_yes: each answer, at a terminal and off one.divergences.tomlrecords the three tests that fail on Node as intended, citing decision 0020. The parity table gets a row, and the README a paragraph.Measured on Linux at
5896ff36, based on mainddfcf093:scripts/conformance-both.sh attach_no_restartagainst the pinned Node build on Node 22.23.2. Node: 10 passed, 3 failed. This branch: 13 passed, 0 failed. Exactly the three ledger entries differ, andcheck-divergences.pymatches them. Its other stale reports are entries for files this run didn't include.attach_no_restartfails the three decline tests and passesa_piped_yes_restartsandauto_restart_needs_no_terminal.cargo test -p pty-conformanceagainst this branch's binary: 693 passed, 0 failed.cargo test -p pty: 363 passed, 1 failed. The failure isinteractive::typing_filters_the_list_and_escape_clears_it, which fails on main in my checkout too: the picker's fuzzy filter matches the checkout path. It passes in CI.pty restartgives the same results as main.