feat(@scripts): add tmux config sync for session-tools

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-05-17 03:43:38 -07:00
parent 9065abdca6
commit 9c3c38a6db
2 changed files with 67 additions and 6 deletions

View file

@ -114,6 +114,24 @@ list_all_on() {
list_disk_on "$1" list_disk_on "$1"
} }
# Push the canonical session-tools tmux fragment to <host> and ensure
# ~/.tmux.conf sources it. Idempotent; runs on every launch so config changes
# in the repo propagate without re-running install.sh on each host. Silent
# no-op if the repo fragment can't be located.
sync_tmux_conf() {
_host=$1
_self=$(resolve_self)
_repo=$(cd "$(dirname "$_self")/.." 2>/dev/null && pwd)
_frag="$_repo/tmux.conf"
[ -f "$_frag" ] || return 0
_remote_cmd='mkdir -p ~/.tmux.d && cat > ~/.tmux.d/session-tools.conf && { grep -q "session-tools.conf" ~/.tmux.conf 2>/dev/null || printf "source-file ~/.tmux.d/session-tools.conf\n" >> ~/.tmux.conf; } && tmux source-file ~/.tmux.conf 2>/dev/null || true'
if is_local "$_host"; then
sh -c "$_remote_cmd" < "$_frag" 2>/dev/null || true
else
ssh -o BatchMode=yes -o ConnectTimeout=5 "$_host" "$_remote_cmd" < "$_frag" 2>/dev/null || true
fi
}
# All hosts to scan for list/resume. # All hosts to scan for list/resume.
scan_hosts() { scan_hosts() {
printf "local\n" printf "local\n"
@ -139,9 +157,11 @@ cmd_list() {
} }
# Resume strategy: # Resume strategy:
# - matches a tmux row → ssh+tmux attach (preserves the live conversation) # - 1 match → attach directly
# - matches a disk row → re-exec self with `<host> <cwd>` so the normal # - 2+ matches → single-key picker (1-9 then a-z, max 35)
# launch path spins up a fresh tmux + claude --continue in that dir # - matches a tmux row → ssh+tmux attach (preserves the live conversation)
# - matches a disk row → re-exec self with `<host> <cwd>` so the normal
# launch path spins up a fresh tmux + claude --continue
cmd_resume() { cmd_resume() {
_pattern=${1:-} _pattern=${1:-}
_matches=$(scan_hosts | while IFS= read -r h; do list_all_on "$h"; done) _matches=$(scan_hosts | while IFS= read -r h; do list_all_on "$h"; done)
@ -155,9 +175,43 @@ cmd_resume() {
exit 1 exit 1
fi fi
if [ "$_count" -gt 1 ]; then if [ "$_count" -gt 1 ]; then
echo "multiple matches; refine pattern:" >&2 _keys="123456789abcdefghijklmnopqrstuvwxyz"
printf '%s\n' "$_matches" | awk -F'\t' '{printf " %-10s %-6s %s\n", $1, $2, $3}' >&2 if [ "$_count" -gt 35 ]; then
exit 1 echo "too many matches ($_count); refine pattern" >&2
exit 1
fi
if [ ! -t 0 ] || [ ! -t 2 ]; then
echo "multiple matches and no tty for picker; refine pattern:" >&2
printf '%s\n' "$_matches" | awk -F'\t' '{printf " %-10s %-6s %s\n", $1, $2, $3}' >&2
exit 1
fi
_i=0
printf '%s\n' "$_matches" | while IFS= read -r _line; do
_i=$((_i + 1))
_k=$(printf %s "$_keys" | cut -c"$_i")
printf ' [%s] %s\n' "$_k" \
"$(printf %s "$_line" | awk -F'\t' '{printf "%-10s %-4s %s", $1, $2, $3}')" >&2
done
_last_key=$(printf %s "$_keys" | cut -c"$_count")
printf 'select [1-%s]: ' "$_last_key" >&2
_old=$(stty -g 2>/dev/null || true)
stty -icanon -echo min 1 time 0 2>/dev/null || true
_key=$(dd bs=1 count=1 2>/dev/null </dev/tty || true)
[ -n "$_old" ] && stty "$_old" 2>/dev/null || true
printf '%s\n' "$_key" >&2
_idx=0
_c=1
while [ "$_c" -le "$_count" ]; do
if [ "$(printf %s "$_keys" | cut -c"$_c")" = "$_key" ]; then
_idx=$_c; break
fi
_c=$((_c + 1))
done
if [ "$_idx" -eq 0 ]; then
echo "rclaude: invalid selection: '$_key'" >&2
exit 1
fi
_matches=$(printf '%s\n' "$_matches" | sed -n "${_idx}p")
fi fi
_host=$(printf '%s\n' "$_matches" | awk -F'\t' 'NR==1{print $1}') _host=$(printf '%s\n' "$_matches" | awk -F'\t' 'NR==1{print $1}')
_kind=$(printf '%s\n' "$_matches" | awk -F'\t' 'NR==1{print $2}') _kind=$(printf '%s\n' "$_matches" | awk -F'\t' 'NR==1{print $2}')
@ -281,6 +335,7 @@ if is_local "$host"; then
echo "rclaude: local directory not found: $dir" >&2 echo "rclaude: local directory not found: $dir" >&2
exit 1 exit 1
fi fi
sync_tmux_conf local
exec tmux new-session -s "$session" "$(build_inner "$dir")" exec tmux new-session -s "$session" "$(build_inner "$dir")"
fi fi
@ -298,5 +353,6 @@ if ! ssh -o BatchMode=yes -o ConnectTimeout=5 "$host" "test -d ${dir}" 2>/dev/nu
exit 1 exit 1
fi fi
sync_tmux_conf "$host"
inner=$(build_inner "$dir") inner=$(build_inner "$dir")
exec ssh -t "$host" "tmux new-session -s '${session}' \"${inner}\"" exec ssh -t "$host" "tmux new-session -s '${session}' \"${inner}\""

View file

@ -10,3 +10,8 @@ set -ga terminal-overrides ",*256col*:Tc"
# Larger scrollback for when you need tmux copy mode # Larger scrollback for when you need tmux copy mode
set -g history-limit 50000 set -g history-limit 50000
# Mouse wheel scrolls tmux scrollback (auto-enters copy mode) instead of being
# passed as arrow keys to the inner app (which would scroll Claude history etc.)
# Hold Option on macOS to bypass tmux and use native terminal selection.
set -g mouse on