#!/bin/sh # rclaude [dir] # # Remote, durable Claude Code session. Two layers of resilience stacked: # # 1. tmux on survives transport drops (network, lid close, ssh kill) # 2. `claude --continue` resumes the per-directory session from disk after # anything kills the host itself (reboot, crash, OOM) # # Re-running with the same + always lands you back where you # were: tmux reattaches if alive, claude --continue picks up the conversation # from ~/.claude/projects// otherwise. # # Permission mode: --dangerously-skip-permissions is on by default — these # are remote sessions on hosts you own. Override with RCLAUDE_PERMS=default # (or any other --permission-mode value) if you want prompts back. # # Usage: # rclaude apricot # remote home dir # rclaude apricot ~/Code/@projects/foo # specific dir # rclaude apricot @proj/lilith # alias from project-paths.md # # works if remote shell expands it set -eu if [ $# -lt 1 ]; then echo "usage: $0 [dir] (dir defaults to remote \$HOME)" >&2 exit 2 fi host=$1 dir=${2:-\~} # tmux session name unique per (user, dir) so multiple Claude sessions on the # same host don't collide. Slug is the path with non-alnum collapsed. slug=$(printf %s "$dir" | sed -e 's|^[~/]*||' -e 's|[^A-Za-z0-9]|-|g') [ -z "$slug" ] && slug=home session="claude-$(whoami)-${slug}" perms=${RCLAUDE_PERMS:-bypass} case $perms in bypass) flag="--dangerously-skip-permissions" ;; *) flag="--permission-mode $perms" ;; esac # cd then exec claude. exec replaces the shell so the tmux pane dies cleanly # when claude exits (instead of leaving a stray shell behind). inner="cd ${dir} && exec claude --continue ${flag}" exec ssh -t "$host" "tmux new-session -A -s '${session}' \"${inner}\""