fix(tmux): explicit transport-only dispatch and safe remote quoting (#1496)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user