Skip to content

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

git -C ~/.scrubjay/scrubjay-data pull
grep -i <keyword> ~/.scrubjay/scrubjay-data/logs/*.log

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)

~/.scrubjay/scrubjay/bin/claude-register-host.sh --host <name>

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.