Portable shell helpers and config, shared across servers.
Currently ships:
bin/site-tmux— attach to (or create) a per-"site" tmux session in its working directory, and ensure aclaude remote-controlwindow is running in that session.tmux/tmux.conf→~/.tmux.conf— small set of tmux options.
The site→directory map is per-machine and lives outside this repo, so the same script works unchanged on any server.
The goal is one source of truth for your shell tooling that follows you to every server, without copy-paste drift. The design choices that make that work:
- Git, not scp. The repo is the canonical copy. New machine →
clone+install.sh. Changed something → commit once,--updateeverywhere. No "which box has the latest version?" guessing, and full history/rollback for free. - Symlinks, not copies.
install.shlinks the repo's files into place (~/.local/bin/site-tmux,~/.tmux.conf) instead of copying them. So agit pulltakes effect instantly — the live file is the repo file. Nothing to re-copy, no stale duplicates. - Machine-agnostic code, per-machine config. The script is identical on every host; only
the
site=dirmap in~/.config/site-tmux/sites.confdiffers. That file stays outside the repo (gitignored), so machine-specific paths never leak into a public repo and updates never clobber your local setup. - Safe to adopt and re-run.
install.shis idempotent and backs up any real file it would replace to*.bak, so installing (or re-installing) never destroys existing config. ~/dotfiles, not a fixed path. Cloning to~/dotfilesresolves correctly for whatever user runs it (/root/dotfilesfor root,/home/you/dotfilesotherwise) — the same install command is portable across hosts and users.
Net effect: fix a bug or add a tmux tweak once, push it, and every server picks it up with a
single site-tmux --update — while each box keeps its own project paths.
git clone https://github.com/jsifalda/dotfiles ~/dotfiles
~/dotfiles/install.shinstall.sh is idempotent: it symlinks bin/site-tmux → ~/.local/bin/site-tmux and
tmux/tmux.conf → ~/.tmux.conf (backing up any real file it would replace to *.bak),
and seeds a per-machine ~/.config/site-tmux/sites.conf from the example.
Then edit this machine's site map:
$EDITOR ~/.config/site-tmux/sites.conf# site=dir (one per line; ~ expands to $HOME)
obsidian-vault-api=/root/obsidian-vault-api
vaults=/root/vaultsMake sure ~/.local/bin is on your PATH.
Remote Control lists each device as <hostname>:<site>:<hash>, so by default it shows the raw
server hostname (e.g. ubuntu-4gb-nbg1-2:…). To show a friendlier label, add a reserved
@prefix line to this machine's sites.conf:
@prefix=mybox # → device shows as mybox:home:… mybox:vaults:…It applies to every site on the machine. The override is Claude-only: site-tmux launches
remote-control inside its own UTS namespace and sets that namespace's hostname, so the bridge
reports mybox while the real system hostname is unchanged. Needs root + unshare (otherwise the
line is ignored and the default hostname is used). Already-running bridges keep their old label
until respawned (tmux kill-window -t <site>:claude-rc then site-tmux <site>).
site-tmux # 'home' session in $HOME
site-tmux obsidian-vault-api # session in the mapped directory
site-tmux anything-else # unknown site → falls back to $HOMEThe claude remote-control window uses remain-on-exit on, so if it exits it stays
visible as a dead pane (with its log) instead of vanishing. Re-running site-tmux <site>
detects that dead claude window and respawns it.
site-tmux --update # git pull + re-run install.sh
# or: cd ~/dotfiles && git pull && ./install.shBecause the files are symlinked, a git pull applies changes to site-tmux instantly;
--update just runs the pull and reinstall for you (also re-links if files were added).
Your per-machine sites.conf is never touched by updates.