claude-rc/README.md
Natalie a49ea98efd feat(@scripts): add claude-rc manager and crc launcher
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-06-07 11:20:35 -07:00

82 lines
3 KiB
Markdown

# claude-rc
Run **Claude Code Remote Control** (`claude rc`) servers so projects are
drivable from [claude.ai/code](https://claude.ai/code) and the Claude mobile app
— either as always-on, reboot-surviving services, or as ad-hoc throwaways.
Two tools:
| Tool | Purpose | Persistence |
|------|---------|-------------|
| `claude-rc` | central **manager** of always-on servers, supervised by `systemd --user` from a registry | survives reboot (linger) + crash (`Restart=always`) |
| `crc` | **ad-hoc** headless launcher for one dir on one host | survives terminal drops; dies on reboot |
Both run `claude rc` **headless** — detached, logged, with `--spawn` and
`--permission-mode` preset so it never blocks on the interactive spawn-mode
prompt.
## Why no tmux
The obvious approach — park `claude rc` in a tmux session — is a trap: a shared
user tmux server can be restarted out from under you (e.g. by another
supervisor) and your sessions vanish. `claude rc` needs no TTY (it connects fine
with stdin closed), so **systemd alone** gives boot-persistence + crash-restart,
and `crc` uses a plain logged background process. No tmux anywhere.
## Install
```sh
./install.sh # symlink bin/*, install the unit, seed registry
sudo loginctl enable-linger "$USER" # once, so units start at boot (Linux)
claude-rc sync # bring up everything in the registry
```
Requires `claude` (Claude Code) on `$PATH` and a logged-in subscription account.
## Manager — `claude-rc`
Registry (`~/.config/claude-rc/projects`) is the single source of truth:
```
name=dir # dir relative to $HOME, or absolute, or ~/...
```
Each entry → a systemd template instance `claude-rc@<name>.service` running
`claude rc --name <name>` in `<dir>`.
```sh
claude-rc list # registry + unit state + dir
claude-rc status [name] # state + claude.ai/code URL
claude-rc url <name> # just the URL
claude-rc add <name> <dir> # register + enable --now
claude-rc rm <name> # disable + unregister
claude-rc sync # reconcile units to the registry
claude-rc logs <name> [-f] # journal
claude-rc restart|stop|start <name>
```
Defaults (override via env in a unit drop-in):
- `CLAUDE_RC_SPAWN=worktree` — isolated git worktree per spawned session.
- `CLAUDE_RC_PERM=bypassPermissions` — spawned sessions skip permission prompts.
## Ad-hoc — `crc`
```sh
crc <host> <dir> # launch headless; prints the URL. host=local for here
crc <host> <dir> --status | --log | --stop
crc <host> <dir> --spawn same-dir --perm default -- <extra claude rc args>
```
`host` is any ssh target, or `local`. State lives under
`~/.local/state/claude-rc/` on the target. Re-running reports the existing
server instead of duplicating it.
## Layout
```
bin/claude-rc manager (runs on the host; drive remotely over ssh)
bin/crc ad-hoc headless launcher
units/claude-rc@.service systemd --user template
projects.example registry seed
install.sh symlinks + unit install + registry seed
```