50 lines
1.8 KiB
Bash
Executable file
50 lines
1.8 KiB
Bash
Executable file
#!/bin/sh
|
|
# rclaude <host> [dir]
|
|
#
|
|
# Remote, durable Claude Code session. Two layers of resilience stacked:
|
|
#
|
|
# 1. tmux on <host> 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 <host> + <dir> always lands you back where you
|
|
# were: tmux reattaches if alive, claude --continue picks up the conversation
|
|
# from ~/.claude/projects/<encoded-cwd>/ 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 <host> [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}\""
|