refactor(rclaude): remove duplicate cmd_send / sh_quote / filter_targets defs

This commit is contained in:
Natalie 2026-05-18 03:01:09 -07:00
parent 4d1175687b
commit a0cc60d4c3

View file

@ -646,36 +646,6 @@ scan_hosts() {
done
}
# POSIX single-quote escape: wraps <arg> in single quotes and escapes any
# embedded single quotes via the '\'' idiom. Used to build safe remote shell
# commands for ssh — the remote shell re-parses argv, so anything containing
# spaces, $, `, etc. must be quoted before transmission.
sh_quote() {
printf "'%s'" "$(printf %s "$1" | sed "s/'/'\\\\''/g")"
}
# Filter target rows on stdin to those matching <selector>:<pat>.
# Input rows are TSV: host\tkind\tsession\tdetail[\tcwd]
# Only KIND=tmux rows are eligible (we can only send-keys to live sessions).
#
# Selectors:
# all → every tmux row
# host <pat> → exact host match (col 1)
# match <pat> → substring in session name (col 3) OR cwd (col 5, if present).
# The tmux session name already embeds a slugified cwd via
# claude_slug(), so name-substring covers most cwd intents
# (e.g. `--match lilith` hits any session whose cwd contained
# "lilith"). Col 5 is reserved for future enrichment.
filter_targets() {
_sel=$1; _pat=$2
awk -F '\t' -v sel="$_sel" -v pat="$_pat" '
$2 != "tmux" { next }
sel == "all" { print; next }
sel == "host" && $1 == pat { print; next }
sel == "match" && (index($3, pat) > 0 || (NF >= 5 && index($5, pat) > 0)) { print; next }
'
}
# ---------------------------------------------------------------------------
# Subcommands
# ---------------------------------------------------------------------------
@ -1323,74 +1293,6 @@ cmd_version() {
fi
}
cmd_send() {
# Broadcast a prompt to live rclaude tmux sessions matching a selector.
# Useful for batch-prompting agents you have running across hosts.
#
# rclaude send "fix the build" → all live rclaude tmuxes
# rclaude send --on apricot "context update" → only apricot
# rclaude send --match lilith "rebase main" → tmux name or cwd matches
# rclaude send --no-enter "draft only..." → don't press Enter after
# rclaude send --dry-run "..." → show targets, don't send
_selector=all
_pattern=""
_enter=1
_dry=0
_text=""
while [ $# -gt 0 ]; do
case $1 in
--on) shift; _selector=host; _pattern=${1:-}; shift ;;
--on=*) _selector=host; _pattern=${1#--on=}; shift ;;
--match) shift; _selector=match; _pattern=${1:-}; shift ;;
--match=*) _selector=match; _pattern=${1#--match=}; shift ;;
--no-enter) _enter=0; shift ;;
--dry-run|-n) _dry=1; shift ;;
--) shift; _text=$*; break ;;
-h|--help)
cat <<EOF
usage: rclaude send [--on <host>|--match <pat>] [--no-enter] [--dry-run] <text...>
Broadcasts <text> to every live rclaude tmux session matching the selector
via 'tmux send-keys'. Disk-only sessions are skipped (can't send-keys to
something not running).
EOF
return 2 ;;
*)
if [ -z "$_text" ]; then _text=$1
else _text="$_text $1"
fi
shift ;;
esac
done
if [ -z "$_text" ]; then
echo "rclaude send: missing text. See 'rclaude send --help'" >&2
exit 2
fi
_rows=$(scan_hosts | while IFS= read -r _h; do list_tmux_on "$_h"; done)
_targets=$(printf '%s\n' "$_rows" | filter_targets "$_selector" "$_pattern")
if [ -z "$_targets" ]; then
echo "rclaude send: no matching live tmux sessions" >&2
exit 1
fi
_count=$(printf '%s\n' "$_targets" | wc -l | tr -d ' ')
printf 'rclaude send: %s target(s)\n' "$_count" >&2
printf '%s\n' "$_targets" | while IFS=$(printf '\t') read -r _h _kind _name _rest; do
printf ' → %s : %s\n' "$_h" "$_name" >&2
[ "$_dry" = "1" ] && continue
_qtext=$(sh_quote "$_text")
_qname=$(sh_quote "$_name")
if is_local "$_h"; then
tmux send-keys -t "$_name" -l "$_text"
[ "$_enter" = "1" ] && tmux send-keys -t "$_name" Enter
else
ssh -o BatchMode=yes -o ConnectTimeout=5 "$_h" \
"tmux send-keys -t $_qname -l $_qtext"
[ "$_enter" = "1" ] && \
ssh -o BatchMode=yes "$_h" "tmux send-keys -t $_qname Enter"
fi
done
}
cmd_voice() {
# `rclaude voice` — toggle / inspect the rvoice push-to-talk binding.
# rvoice itself is a separate script (bin/rvoice) driven by Hammerspoon.
@ -1465,7 +1367,6 @@ case ${1:-} in
send) shift; cmd_send "$@"; exit ;;
setup|install) shift; cmd_setup "$@"; exit ;;
voice) shift; cmd_voice "$@"; exit ;;
send) shift; cmd_send "$@"; exit ;;
-v|--version) cmd_version; exit ;;
-h|--help|help) cmd_help; exit ;;
esac