Reference — useful commands¶
Day-to-day this all runs from hooks; reach for these when you want to do something by hand.
Paths assume the default ~/.scrubjay/ layout from Onboarding (if you cloned
elsewhere, adjust, or run bin/* from inside the repo). For the in-session /sj* commands, see
Slash commands.
Apply / refresh config now¶
Normally automatic at session start/end:
~/.scrubjay/scrubjay/bin/claude-sync.sh # re-apply data-repo config into ~/.claude
~/.scrubjay/scrubjay/bin/claude-sync.sh --force # also back up + replace real (non-symlink) files
~/.scrubjay/scrubjay/bin/claude-index-chats.sh # rebuild this host's chats.index.json
Pull the latest from your other machines¶
The SessionStart hook does both for you:
git -C ~/.scrubjay/scrubjay-data pull # config, rules, memory, templates, logs
git -C ~/.scrubjay/scrubjay pull # the scripts & hooks themselves
Check this machine is actually syncing¶
Every subsystem is best-effort and hook-invoked with its output discarded, so a machine can be degraded — relaying nothing, publishing memory nowhere — while each session still looks fine. This checks the wiring rather than the last attempt, and exits non-zero if anything is wrong.
~/.scrubjay/scrubjay/bin/sj-doctor.sh # everything (or /sjdoctor in a session)
~/.scrubjay/scrubjay/bin/sj-doctor.sh memory # just one subsystem — skips the other probes
~/.scrubjay/scrubjay/bin/sj-doctor.sh --list # what can be checked
Read-only: it never writes, pushes or installs. Each failure comes with a fix: hint. On the
peer-to-peer backends the usual finding is that this host's key isn't in the receiver's
authorized_keys yet — which a human with root on the receiver has to fix, by design.
Recover a session that ended badly¶
Everything that records a session — its catalogue row, the transcript relay, the readable rendering
— hangs off the session-end hook. A kill -9, a closed terminal, a dropped SSH connection or a
power cut skips it, and nothing else notices: the relay breadcrumb is written by the ship that never
ran, so there is no failure to report. The transcript itself is safe on disk the whole time; what is
missing is every trace that the session happened.
The start of your next session sweeps these up automatically, and says so when it does. To look, or to sweep now:
~/.scrubjay/scrubjay/bin/sj-doctor.sh sessions # anything stranded? (read-only)
~/.scrubjay/scrubjay/bin/sj-reconcile.sh --dry-run # …and exactly which sessions
~/.scrubjay/scrubjay/bin/sj-reconcile.sh # catalogue + archive them now
~/.scrubjay/scrubjay/bin/sj-reconcile.sh --all # including the pre-scrubjay back catalogue
The automatic pass only considers sessions untouched for 30 minutes (a live session in another
terminal is still writing) and modified in the last 14 days, and it does at most 25 per run so a
backlog cannot slow a session's startup. --all lifts every one of those limits.
A recovered session is dated when it died, not when it was recovered, so it sorts into the
catalogue where it belongs. The one thing that cannot be recovered is a /sjlog essence — the row
falls back to the session's first prompt, exactly as the automatic path does.
Find a past chat across every machine¶
Keep a written artefact (a note)¶
/sjnote from inside a session is the usual way; the script is also usable directly, and reads
the body from stdin.
~/.scrubjay/scrubjay/bin/sj-note.sh --topic "fsl impact on document b" < analysis.md
~/.scrubjay/scrubjay/bin/sj-note.sh --from /tmp/…/scratchpad/briefing.md # promote an existing file
ls ~/.scrubjay/scrubjay-memory/*/notes/ # what's kept, this machine
Notes land in <memory>/<project>/notes/ and publish immediately. They are not loaded into
future sessions — read them back with /sjrecall, /sjbrowse note, or sj_list(type="note").
Continue another machine's chat here¶
Stage it, then resume with Claude Code's own picker — see handoff.md.
~/.scrubjay/scrubjay/bin/sj-resume.sh --list # what's resumable, from other machines
cd <the project dir on this machine>
~/.scrubjay/scrubjay/bin/sj-resume.sh <sid8> # stage it (rewrites the other host's paths)
claude --resume <sid> # …or /resume inside a session here
Register the current machine (first-time onboarding)¶
Toggle behaviour¶
Set in ~/.config/scrubjay/config (persistent) or inline before a command (one-off) — no file
editing needed:
| Env var | Effect |
|---|---|
SCRUBJAY_TRANSCRIPT_BACKEND=off |
pause session shipping (other values: local, rsync-wg, git) |
SCRUBJAY_NOSYNC=1 |
skip the start-of-session pull + sync entirely |
SCRUBJAY_SYNC_NOPULL=1 |
sync at start but don't git pull first |
SCRUBJAY_NOSHIP=1 |
end the session without shipping its transcript |
SCRUBJAY_LOG_NOGIT=1 |
append the log line but don't commit/push it |
SCRUBJAY_NORECONCILE=1 |
don't sweep for sessions that ended without a clean exit |
Re-home the scrubjay clones¶
Move the machinery (e.g. out of ~/code into ~/.scrubjay):
mkdir -p ~/.scrubjay
mv ~/code/scrubjay ~/code/scrubjay-data ~/code/scrubjay-chats ~/.scrubjay/
# repoint the machine-local pointer at the new location
cat > ~/.config/scrubjay/config <<'EOF'
: "${SCRUBJAY_DATA:=$HOME/.scrubjay/scrubjay-data}"
: "${SCRUBJAY_CHATS:=$HOME/.scrubjay/scrubjay-chats}"
: "${SCRUBJAY_TRANSCRIPT_BACKEND:=git}"
EOF
~/.scrubjay/scrubjay/bin/claude-sync.sh # rebuild the ~/.claude symlinks at the new path
claude-sync.sh recomputes the app location from its own path and re-links every scope, so
nothing else needs touching. Confirm with
readlink -e ~/.claude/{CLAUDE.md,commands,agents,hooks} (no dangling links). The pinned host
name in ~/.config/scrubjay/host is unaffected. This is machine-local — nothing to commit.