hausfold

scruff

Commands

Every verb, the flags that matter, and what each of the six exit codes means for what you do next.

scruff --help is the exhaustive list and it prints to stderr. This page is the same surface, grouped by what you are trying to do.

Lanes

scrufflist every live and parked lane, across all repos
scruff <name>resume one: rebuild its checkout, reopen its agent. <repo>/<name> to qualify · --pick to choose the session instead of the newest
scruff focus <name>go to the window a lane is already running in. Falls back to resume without a focus hook
scruff new [name]a lane on this repo, path on stdout · --open [agent] / --agent <id> / --cmd '<command>'
… --prompt '<task>'open it on a first turn instead of a blank pane · --prompt-file <file|-> for a brief · --image <file>
scruff child <repo>a lane on another repo, as a child of this pane
scruff spawn <repo> <name>a named lane for a spawner with no pane of its own. Opened through [hooks] open, so exit 3 means the lane exists and nothing put a window on it. <name> is optional with a --prompt and a namer configured

The tree

scruff park [label]set the working tree aside as a wip: commit on this branch
scruff unparkput the last parked commit's changes back, uncommitted

Cleanup

scruff reapsweep every landed lane nobody is standing in
scruff reapedwhat scruff has reaped, why, and the SHA to get it back
scruff drop <name>retire a lane whose work will never land (closed PR, archived repo). Recorded, undoable
scruff reship [name]push a branch that outran its merged PR, and open the follow-up

Machines

scruff --jsonthe listing, machine-readable. Same as scruff list --json
scruff watch --jsonlifecycle events on stdout, one NDJSON object per line
scruff heartbeat [path]hold the occupancy lease on a lane, so reap spares it · --pid N (0 for TTL-only) · --release
scruff hook createopen a lane from a client's hook: JSON on stdin, path on stdout
scruff hook removeretire one without losing work: JSON on stdin
scruff hook notifyclient events into a trill banner for the lane. Exit 0 always, silent no-op without trill

Runtimes

scruff runtime up <name> --backend <id>stand up a lane's isolation backend. --backend is required, always
scruff runtime enter <name> --backend <id>drop into it interactively
scruff runtime down <name> --backend <id>tear it down
scruff runtime eject tartprint the built-in backend as an adapter file to edit

Maintenance

scruff doctorwhere the base lives, and what a move would cost
scruff doctor --migrate-basemove the base to ~/.cache/scruff. Refuses with exit 2 while any lane is occupied, repairs every checkout, leaves the old path a symlink
scruff --versionprint the version

Exit codes

Six, and they are a frozen contract. Each one means a different next move:

what to do
0success, including "nothing to do"report what happened
1usage or precondition errorfix the invocation
2refused for safety: occupied, dirty, or not provably landedthis is scruff working. Don't force it, ask why
3degraded: it completed, but a signal was unavailablereport the caveat
4conflict founda finding, not an error. Somebody resolves it
5the registry is locked by another scruffanother scruff is mid-operation. Retry shortly

2 versus 1 is the distinction the whole table exists for: a wrapper script has to be able to tell "you asked wrong" apart from "I declined to destroy something".

On this page