fix(tmux): explicit transport-only dispatch and safe remote quoting (#1496)

This commit is contained in:
2026-09-08 12:41:25 -05:00
parent 67eaf6fb47
commit 69f10a4062
71 changed files with 6564 additions and 316 deletions
+20 -7
View File
@@ -20,7 +20,7 @@
# Reliable submission into an interactive REPL (Claude Code / Codex) is fiddly:
# a trailing Enter is often swallowed and the message sits as an unsubmitted
# DRAFT. tools/tmux/send-message.sh already solves that for a LOCAL pane via
# bracketed-paste + Enter-flush + draft-detection. For REMOTE targets this
# checked bracketed paste + one Enter (transport only). For REMOTE targets this
# wrapper SHIPS send-message.sh over ssh (stdin) and runs it there, so the
# reliable send-keys happens local to the target pane — sidestepping the
# ssh->nested-tmux Enter/C-m swallow entirely. No mosaic install needed on
@@ -57,8 +57,8 @@
# byte-for-byte identical to the classic format. Consumers MUST
# treat an absent class as 'actionable' (fail-safe: agent sees it).
# -S SRC_LABEL override source label "<host>:<session>" (default: auto)
# -r N Enter-flush attempts passed through (default 2)
# -v verbose: print pane tail after delivery
# -r N Legacy compatibility option; no automatic extra Enter
# -v verbose: transport metadata only, no private pane contents
# -h help
#
# PREAMBLE GRAMMAR (for consumers / daemons mirroring this producer)
@@ -67,7 +67,8 @@
# group 3 = class (absent => actionable) group 4 = message body
#
# EXIT CODES (passed through from send-message.sh, except 4)
# 0 delivered/queued · 1 target not found · 2 still draft · 3 usage error
# 0 transport dispatched; application acceptance unknown · 1 target not found
# 2 transport failed/partial/uncertain · 3 usage error
# 4 agent-send refusal: local target session exists on multiple socket
# servers and no -L / MOSAIC_TMUX_SOCKET disambiguated it (B1)
set -uo pipefail
@@ -106,6 +107,7 @@ while getopts "L:s:H:n:m:f:S:r:C:vh" o; do
esac
done
[[ "$RETRIES" =~ ^[0-9]+$ ]] || { echo 'ERROR: -r requires a nonnegative integer' >&2; exit 3; }
[ -n "$DST_SESSION" ] || { echo "ERROR: -s DST_SESSION is required" >&2; usage 3; }
[ -x "$SENDER" ] || { echo "ERROR: send-message.sh not found beside this script" >&2; exit 3; }
@@ -201,7 +203,10 @@ if [ -z "$SOCKET_NAME" ] && [ -z "$SSH_TARGET" ]; then
# '=' forces exact session-name matching: tmux target syntax otherwise
# accepts an unambiguous PREFIX, so a session named X-old on a socket
# would count as a false hit for target X (codex PR #1466).
tmux -L "$sname" has-session -t "$DST_TARGET" 2>/dev/null && hits="$hits$sname"$'\n'
# Silence BOTH streams: has-session writes nothing to stdout, but a stub
# (test fake) may — leaked probe stdout polluted this tool's stdout and
# broke callers that read it (measured 2026-09-07, agent-send.test #9b).
tmux -L "$sname" has-session -t "$DST_TARGET" >/dev/null 2>&1 && hits="$hits$sname"$'\n'
done
hit_count=$(printf '%s' "$hits" | grep -c . || true)
if [ "$hit_count" -gt 1 ]; then
@@ -224,6 +229,14 @@ if [ -z "$SSH_TARGET" ]; then
exec "$SENDER" "${socket_args[@]}" -t "$DST_TARGET" -b "$B64" -r "$RETRIES" $vflag
else
# Remote pane: ship the sender over ssh and run it local to the target.
ssh -o ConnectTimeout=10 "$SSH_TARGET" \
"bash -s -- ${socket_args[*]@Q} -t '$DST_TARGET' -b '$B64' -r '$RETRIES' $vflag" < "$SENDER"
# SSH passes a command string through the remote login shell. Quote EACH
# argument with POSIX single-quote escaping before that shell parses it.
remote_args=(bash -s -- "${socket_args[@]}" -t "$DST_TARGET" -b "$B64" -r "$RETRIES")
[ "$VERBOSE" = 0 ] || remote_args+=(-v)
remote_command=""
for arg in "${remote_args[@]}"; do
escaped=${arg//\'/\'\\\'\'}
remote_command+=" '$escaped'"
done
ssh -o ConnectTimeout=10 "$SSH_TARGET" "$remote_command" < "$SENDER"
fi