No description
Find a file
Natalie 77cd1c74b1 rclaude: pre-flight remote dir existence; loud error instead of silent ssh-close
Catches typos and Claude-instruction-style aliases (@proj/@apps/@pkg) that
look like paths but only resolve in the assistant's mental model, not in any
shell. Without the check the cd inside the tmux command failed silently, the
pane died, the session closed, ssh exited — surfaced to the user as a bare
'Connection to <host> closed.'
2026-04-26 00:10:02 -07:00
bin rclaude: pre-flight remote dir existence; loud error instead of silent ssh-close 2026-04-26 00:10:02 -07:00
.gitignore initial: remote-run + tssh + installer 2026-04-25 22:13:25 -07:00
install.sh install.sh: pick first on-PATH target dir, allow TARGET= override 2026-04-25 22:14:08 -07:00
README.md rclaude: support local tmux mode (host=local|localhost|hostname) 2026-04-25 23:39:21 -07:00

session-tools

Resilient remote-execution wrappers for SSH/tmux patterns across the lilith host fleet (plum, apricot, black, quinn-vps, ...).

The premise: a bare ssh host cmd dies the moment the transport hiccups, killing whatever was running on the remote. These wrappers run commands inside a detached tmux session on the remote so the work survives the SSH drop.

Tools

  • bin/remote-run <host> <cmd...> — One-shot command runner. Spawns a detached tmux session on <host>, streams stdout/stderr back to your terminal, propagates the exit code. If the local ssh dies mid-run, the tmux session continues; reattach with ssh <host> tmux ls then ssh <host> tmux attach -t <session>.

  • bin/tssh <host> — Interactive shell wrapper. Auto-attaches to (or creates) a per-user tmux session on <host> named claude-$(whoami). Detach with Ctrl-b d; transport drops don't kill the shell.

  • bin/rclaude <host> [dir] — Durable Claude Code session, local or remote. Stacks two resilience layers: tmux survives terminal/transport drops, and claude --continue resumes the per-directory session from ~/.claude/projects/ after anything kills the host itself. Re-running with the same <host> + <dir> always lands back in the same conversation. <host> can be any ssh target, or local/localhost/the local hostname to skip ssh and use a local tmux session (still detachable for terminal/network resilience). Defaults to --dangerously-skip-permissions; override with RCLAUDE_PERMS=default.

Install

On every host that should have these on $PATH:

git clone http://forge.black.local/lilith/session-tools.git ~/Code/@scripts/session-tools
~/Code/@scripts/session-tools/install.sh

Symlinks bin/remote-run and bin/tssh into ~/bin. Pulls future updates via plain git pull — symlinks track the repo automatically.

When to use what

Scenario Use
Interactive shell on a remote tssh <host>
One-off command (build, test, query) remote-run <host> "<cmd>"
Claude Code session on a remote rclaude <host> [dir]
Long-running job (>1h, must survive reboot) systemd --user unit on the remote, not ssh

Per-host shims (optional)

If a particular host gets used a lot, drop a one-liner into ~/bin/:

# ~/bin/apricot-run
#!/bin/sh
exec remote-run apricot "$@"