↑ subaud · local-first · MIT

Docs

Install casebook, then run it.

The reference for the binary and the page: installing it four ways, every command, casebook serve, configuration and paths, and the keyboard. The agent's side has its own page, agent, and so do rules, apply and the data format. For a walk through a first triage, see the guide.

install

Install.

casebook runs on macOS and Linux, on Apple silicon and x86-64. It needs git and gh, signed in. The binary is built in the tackle monorepo and published at https://tackle.tools/dl/casebook/.

The installer

$ curl -fsSL https://casebook.tools/install.sh | sh

It reads the latest version, downloads the archive for your platform from tackle.tools/dl/casebook/, verifies it against its .sha256 and refuses to install on a mismatch, installs to ~/.local/bin, and runs casebook version once. CASEBOOK_VERSION=X.Y.Z pins a version and CASEBOOK_INSTALL_DIR picks another directory. Run it again, or casebook update, to upgrade.

kempt, on macOS

casebook's kempt manifest sets up everything at once: the binary from tackle.tools, the Claude Code hooks (PostToolUse journaling, SessionStart briefing, the Stop settled signal), the channel registered in ~/.claude.json and in pi's ~/.pi/agent/channels.json, and a launchd job that runs a full sync every 30 minutes. It needs kempt 0.5.3 or later, and -packages casebook is required.

$ kempt plan  -manifest https://raw.githubusercontent.com/schuettc/tackle/main/cmd/casebook/kempt.toml -packages casebook
$ kempt apply -manifest https://raw.githubusercontent.com/schuettc/tackle/main/cmd/casebook/kempt.toml -packages casebook

kempt shows the plan before it changes anything. The sync job logs to ~/.local/state/casebook/sync.log.

pi-casebook

For pi sessions, install the extension from npm. It needs the casebook binary and does nothing without it.

$ pi install npm:pi-casebook

Then, on each machine

$ casebook init
$ casebook hooks install
$ casebook sync

commands

Every command.

Item keys look like repo:owner/name, pr:owner/name#12, issue:owner/name#7, branch:owner/name@feat/x and worktree:laptop:/Users/you/GitHub/name-wt. Flags can go anywhere among the arguments, and --json prints machine-readable output where it is offered.

Observe

casebook sync [--no-github] [--no-push] [--json]Record, observe, rebuild the views, commit and push. It files the spooled journal, scans the clones and worktrees under your roots, refreshes GitHub (skipped with --no-github, which uses the cache), and renders README.md, CONTRIBUTIONS.md and MACHINES.md. --no-push commits locally only. When another sync is running it skips and says so.
casebook attention [--kind K] [--repo owner/name] [--json]What needs you: items that are new, due, drifted or in conflict, and items a policy flags. --kind takes repo, pr, issue, branch or worktree.
casebook show <key> [--json]One item: its decision, observation, flags and its last ten history entries.
casebook history <key> [--json]Every journaled action and decision commit for an item.
casebook doctor [--json]Check the config, the casebook repo, gh, the hooks and each owner's reachability. Exits 1 when a check fails.
casebook serve [--no-open] [--port N] [--stop]Open the page, starting the local server when it is not running. See casebook serve.

Decide

casebook decide <key> <disposition> [--until C] [--note N]Record a decision: one commit, pushed at once. --by names who decided (default: this agent session, or your GitHub login). --no-push commits locally only. Offline, the commit is queued for the next sync.
casebook decide --from <file>Record every filled-in entry of a triage worksheet (- reads stdin). Entries left blank are skipped; the bad ones are listed and the command exits 1.
casebook triage [--kind K] [--repo R] [--out FILE]Write a worksheet of the attention list: one [[item]] per item with its status, flags, current decision and allowed dispositions as comments. Default casebook-triage.toml; - writes to stdout.
casebook validateCheck every decision file and policy.toml.

Dispositions are keep, archive, close, delete, merge, wait, watch and ignore; each kind allows some of them, and wait and watch need --until. Both lists, and the until forms, are on the rules page.

Setup

casebook init [<remote>] [--no-create] [--machine M] [--user U] [--root DIR]...Set up this machine: write the config and clone the casebook repo. With no remote it uses <your login>/casebook-data, created as a private repo when missing; a public repo is refused. --machine defaults to the short host name, --user to gh's login, and --root (repeatable) to ~/GitHub plus ~/dotfiles when it exists. Safe to run again.
casebook hooks install | uninstall | status [--json]Manage the global git hook shims. install points the global core.hooksPath at casebook's shims and remembers the previous value, which the shims chain to; uninstall restores it.
casebook hooks adopt [<repo> | --all]Chain casebook into a repo that sets its own core.hooksPath (husky, lefthook). The repo's previous value is kept in its git config and still runs. --all adopts every such clone in this machine's snapshot.
casebook hooks release [<repo> | --all]Undo an adopt: restore the repo's own core.hooksPath.

Plumbing

Called by hooks and harnesses rather than by you.

casebook channelThe MCP channel an agent session runs over stdio. See the agent page.
casebook settled --session ID [--shown IDS]Tell the server an agent's turn ended, so its queued page messages go out. --shown lists the delivery ids the agent was shown. --harness claude reads the session from a Claude Code Stop hook payload on stdin instead. Never fails, never prints.
casebook brief [--cwd DIR] [--max N]A session-start briefing on the repo at --cwd, at most N items (default 8). Silent when there is nothing to say.
casebook record --harness claude|piJournal a harness's shell command from its JSON payload on stdin. Only the verb and targets are kept. Never fails.
casebook hook <git-hook-name>Called by the git hook shims. Never fails, prints or waits.

Other

casebook updateUpdate casebook to the latest release from tackle.tools/dl/casebook/.
casebook versionPrint the version, commit and build date.
casebook help [<command>] · casebook manUsage for all commands or one; a roff man page.
casebook commands --jsonThe machine-readable command index.

casebook serve

The server and the page.

One casebook serve runs per machine. It owns the page's working state, builds the live index of your items, and is the only thing the agent's channel talks to.

startcasebook serve starts it in the background and opens the page; when it is running, it opens the running one. Any agent tool call also starts it. --no-open skips the browser; --port N picks a port, otherwise it reuses the last one or takes a free one.
stopcasebook serve --stop, or 8 hours with no traffic. An open page counts as traffic, so it never idles out under you.
networkBound to 127.0.0.1 only. Each start makes a new token, set as an HttpOnly cookie when the page loads; every write also needs a same-origin request.
liveThe page follows a server-sent event stream and falls back to polling when it drops; the ● live pill says which. The index rebuilds when the local casebook repo moves (a sync from launchd, pi or the command line) and after each decision.
restartsIf serve stops while a tab is open, the next one reopens the page in a new tab and the old tab says it continued there. Deliveries that were in flight to an agent are marked interrupted, and each attached session is told serve restarted.
offlineDecisions are committed locally and pushed when the remote is back; the bar shows offline · N queued meanwhile.

The three sections

attention lists what needs you, in the views waiting on you (incoming pull requests and issues with no reply from you), new (undecided), due (due, drift and conflict), proposed (a proposal is pending) and board (the same items in lanes). An open item shows its facts, body, any pending proposal with accept, change… and reject, its decide buttons, evidence from casebook and the agent, and its history. rules is described on the rules page, and to apply on the apply page.

Every view has its own address, such as #/attention/waiting, #/item/<key>, #/rules/<id> and #/apply/<job>, so reload and back work as you expect.

configuration

Configuration and paths.

Per-machine settings live in ~/.config/casebook/config.toml, written by casebook init with mode 0600. Settings every machine shares live in the casebook repo instead: policy.toml, described on the format page.

keydefaultmeaning
machinethe short host namethis machine's name in keys, journal paths and snapshots
usergh's loginyour GitHub login
casebook_repo~/.local/share/casebook/repothe local clone of the casebook repo
casebook_remoteset by initits remote
roots~/GitHub, plus ~/dotfilesdirectories scanned for clones and worktrees
ownersyour account and its orgsthe GitHub owners to observe
sync_interval30mhow old an observation may be before a plan is refused

Paths

pathwhat
~/.config/casebook/config.tomlthe machine's settings
~/.config/casebook/hooks/the git hook shims
~/.local/share/casebook/repo/the clone of casebook-data
~/.local/state/casebook/casebook.dbserve's working state: sessions, threads, messages, deliveries, proposals, evidence, progress, jobs (SQLite, 0600)
~/.local/state/casebook/live/serve.jsonthe running server's address, token and PID (0600, in a 0700 directory)
~/.local/state/casebook/github.jsonthe GitHub observation cache
~/.local/state/casebook/seen.jsondecisions seen satisfied, for drift detection
~/.local/state/casebook/spool/journal events waiting for the next sync
~/.local/state/casebook/hooks.jsonthe hook install record

Environment

variableeffect
CASEBOOK_HOMEan absolute path that replaces all three base directories: config, data and state go under $CASEBOOK_HOME/config, /data and /state
XDG_CONFIG_HOME, XDG_DATA_HOME, XDG_STATE_HOMEhonoured when set to absolute paths
CASEBOOK_DISABLEset to anything, the git hook shims record nothing
CASEBOOK_VERSION, CASEBOOK_INSTALL_DIRthe installer's version pin and install directory
CASEBOOK_BINpi-casebook's path to the binary (default ~/.local/bin/casebook)

keyboard

Keyboard.

Press ? on the page for the keys that work where you are. A section's own keys work only while it is shown.

keyswhereaction
j ↓ · k ↑listsnext, previous
o ↵listsopen
x · ⇧xAttention, To applyselect, select a range
/lists with a search fieldsearch
? · Esceverywhereshow the keys; close a sheet or leave a field
g a · g r · g peverywherego to attention, rules, to apply
.everywherefocus the composer
↵ · ⌘↵the composersend; add to the batch
dAttentiondecide the selection
a · rAttentionaccept, reject the open item's proposal
aRulesactivate the open draft
a · pTo applyapprove the open plan; pause or resume the open job