mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 08:02:24 +00:00
fix(cli): the advertised wait idiom fails in one of its own end states
`tty7 wait`'s headline example is
tty7 wait %3 && tty7 capture %3 --plain
and `exit` is one of the three states `--until` waits for by default. Run
it that way and the pane is gone by the time capture runs: wait reports
`exit` and succeeds, `&&` proceeds, and capture answers that nothing is
running. An agent following the documented pattern gets no output for a
command that produced some.
The example is right for an agent — `waiting` and `done` leave the pane
alive. It is wrong for a plain command, which finishes by the shell
exiting. Spell both out in `wait`'s long help, and say plainly that
`exit` is the end state with nothing left to read.
Verified against a live server: `wait --until free` blocks for the
command (5s for a 4s sleep), and the capture after it finds the marker.
Also: a server running one pane had `doctor` say "1 panes" on its first
line. It is the first thing a new user runs. Every other count in the
tree is already plural-aware — the GUI routes these through `t_plural`
with "one"/"other" branches, and the CLI's other count (`closed N panes`)
handles the single case separately — so this was the last one.
This commit is contained in:
@@ -95,7 +95,18 @@ pub enum Command {
|
||||
|
||||
#[command(
|
||||
about = "Block until a pane's agent needs input, finishes its turn, or the pane \
|
||||
exits — the orchestration primitive: `tty7 wait %3 && tty7 capture %3 --plain`"
|
||||
exits — the orchestration primitive: `tty7 wait %3 && tty7 capture %3 \
|
||||
--plain`",
|
||||
long_about = "Block until a pane's agent needs input, finishes its turn, or the \
|
||||
pane exits — the orchestration primitive:\n\n \
|
||||
tty7 wait %3 && tty7 capture %3 --plain\n\n\
|
||||
That pairs with an agent, whose pane is still alive in `waiting` and \
|
||||
`done`. For a plain command, wait for `free` instead:\n\n \
|
||||
tty7 wait %3 --until free && tty7 capture %3 --plain\n\n\
|
||||
`exit` is the one end state with nothing left to read: the pane's \
|
||||
output goes with the pane, and the workspace keeps only a leaf the \
|
||||
GUI can revive into a fresh shell. Capture before the shell exits, \
|
||||
or run the command under `tty7 run`, which streams it."
|
||||
)]
|
||||
Wait(WaitArgs),
|
||||
|
||||
|
||||
@@ -1517,8 +1517,11 @@ fn doctor(ctx: &Context, backend: &mut dyn Backend) -> Result<Outcome> {
|
||||
rows.push(vec![
|
||||
"status".to_string(),
|
||||
format!(
|
||||
"pid {}, up {}s, {} panes",
|
||||
status.pid, status.uptime_secs, status.panes
|
||||
"pid {}, up {}s, {} pane{}",
|
||||
status.pid,
|
||||
status.uptime_secs,
|
||||
status.panes,
|
||||
if status.panes == 1 { "" } else { "s" }
|
||||
),
|
||||
]);
|
||||
let routes = match backend.control(ControlRequest::Routes)? {
|
||||
@@ -3853,6 +3856,45 @@ mod tests {
|
||||
assert!(out.contains("set (/cfg/tty7)"), "{out}");
|
||||
}
|
||||
|
||||
/// A server running one pane said "1 panes".
|
||||
///
|
||||
/// The count comes straight off the status reply, so every fresh server
|
||||
/// says it — `doctor` is the first thing a new user runs, and the first
|
||||
/// line it shows them was ungrammatical.
|
||||
#[test]
|
||||
fn doctor_counts_one_pane_in_the_singular() {
|
||||
use tty7_core::daemon::control::ServerStatus;
|
||||
|
||||
let status = |panes: u64| ServerStatus {
|
||||
pid: 4242,
|
||||
uptime_secs: 61,
|
||||
panes,
|
||||
control_version: CONTROL_VERSION,
|
||||
protocol_version: PROTOCOL_VERSION,
|
||||
build: "26.7.5".into(),
|
||||
socket: "127.0.0.1:5555".into(),
|
||||
};
|
||||
let line = |panes: u64| {
|
||||
let mut backend = mock();
|
||||
backend.replies.push_back(ReplyOk::Status(status(panes)));
|
||||
backend.replies.push_back(ReplyOk::Routes(Vec::new()));
|
||||
human(run_cli(
|
||||
&["tty7", "doctor"],
|
||||
&Context::default(),
|
||||
&mut backend,
|
||||
))
|
||||
};
|
||||
|
||||
assert!(
|
||||
line(1).contains("1 pane\n") || line(1).contains("1 pane "),
|
||||
"{}",
|
||||
line(1)
|
||||
);
|
||||
assert!(!line(1).contains("1 panes"), "{}", line(1));
|
||||
assert!(line(0).contains("0 panes"), "{}", line(0));
|
||||
assert!(line(2).contains("2 panes"), "{}", line(2));
|
||||
}
|
||||
|
||||
/// Missing hooks are the reason a perfectly healthy-looking agent never
|
||||
/// reports and `tty7 wait` sits there until it times out. `doctor` is the
|
||||
/// verb people run when something is not working, so it is where that has
|
||||
|
||||
Reference in New Issue
Block a user