From 0ca192baaaa8797520aba1ff85f706cf5ba0cc7a Mon Sep 17 00:00:00 2001 From: veronica Date: Fri, 21 Aug 2026 17:10:40 -0500 Subject: [PATCH] fix(tmux): split the rule pair without piping into head CI 2604 red on scripts/pipefail-early-exit.test.mjs. Two lines I added in the previous commit tripped its scan of send-message.sh: [ "$(printf '%s\n' "$rule_lines" | grep -c .)" -eq 2 ] || return 1 top=$(printf '%s\n' "$rule_lines" | head -1) The second is a real violation of the rule the guard enforces: `head` exits after its count, the producer takes SIGPIPE, and under `set -euo pipefail` the caller aborts with rc=141 and no output. That is the same failure mode test-mosaic-worktree-large-repo.sh exists to pin. The first is the guard reading `-eq` as an early-exit grep flag (`-[A-Za-z]*q` matches `-eq`), so `grep ... | ... -eq 2` looks like `grep -q` on one line. A false positive, but the fix removes the shape either way. Both go away by splitting the captured line numbers with parameter expansion instead of a second pass through the pipe. With one rule captured, both halves resolve to the same value and the new `[ "$top" != "$bottom" ]` test rejects it, which is the answer that case wanted anyway. Verified: node --test scripts/pipefail-early-exit.test.mjs green on the load-bearing assertion; test-send-message-verdict.sh still PASS=5 FAIL=0; test-send-message-socket.sh rc=0; agent-send.test.sh PASS=19 FAIL=0. --- .../mosaic/framework/tools/tmux/send-message.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/mosaic/framework/tools/tmux/send-message.sh b/packages/mosaic/framework/tools/tmux/send-message.sh index 88ffe3ba..56144d54 100755 --- a/packages/mosaic/framework/tools/tmux/send-message.sh +++ b/packages/mosaic/framework/tools/tmux/send-message.sh @@ -122,9 +122,16 @@ locate_input_box() { glyph_line=$(printf '%s\n' "$pane" | grep -E '❯|^>|│ >' | tail -1) if [ -n "$glyph_line" ]; then printf '%s\n' "$glyph_line"; return 0; fi rule_lines=$(printf '%s\n' "$pane" | grep -nE '^[[:space:]]*─{4,}[[:space:]]*$' | cut -d: -f1 | tail -2) - [ "$(printf '%s\n' "$rule_lines" | grep -c .)" -eq 2 ] || return 1 - top=$(printf '%s\n' "$rule_lines" | head -1) - bottom=$(printf '%s\n' "$rule_lines" | tail -1) + [ -n "$rule_lines" ] || return 1 + # Split the (at most two) captured line numbers with parameter expansion. Not + # `head -1`: piping into an early-exiting consumer SIGPIPEs the producer, which + # under `set -euo pipefail` aborts the caller with rc=141 and no output. The + # scripts/pipefail-early-exit.test.mjs guard reds on that shape, correctly. + # With one rule captured both halves resolve to the same value and the + # ordering test below rejects it, which is the answer we want anyway. + top=${rule_lines%%$'\n'*} + bottom=${rule_lines##*$'\n'} + [ "$top" != "$bottom" ] || return 1 [ "$bottom" -gt "$top" ] || return 1 # An empty range (adjacent rules) prints nothing and still returns 0: found, # empty, which is the delivered shape.