From 6892585a2d754099320f951c91b977744b3a3d03 Mon Sep 17 00:00:00 2001 From: Natalie Date: Sun, 17 May 2026 22:36:01 -0700 Subject: [PATCH] =?UTF-8?q?feat(@scripts):=20=E2=9C=A8=20add=20safe=20shel?= =?UTF-8?q?l=20quoting=20and=20session=20filtering?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- bin/rclaude | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/bin/rclaude b/bin/rclaude index 3b0a059..f9f6187 100755 --- a/bin/rclaude +++ b/bin/rclaude @@ -607,6 +607,36 @@ scan_hosts() { done } +# POSIX single-quote escape: wraps 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 :. +# 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 → exact host match (col 1) +# match → 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 # ---------------------------------------------------------------------------