work that outlives the session

Work that outlives
the session that started it.

Run many coding-agent sessions at once and the files survive when one ends. They're still on disk. What dies is what you were about to do next, what you already ruled out and why, and what you're still waiting on. threadline keeps that on disk instead of in a context window.

install
❯cargo install --path . && ./hooks/install.sh

Merges 3 hooks into ~/.claude/settings.json, backs it up first. Read it here.

plain JSONL no server, no binary required to read it never pushes local only injected automatically nothing to remember
threadline board
5 open threads   ▸ orders-api-upgrade 6h verify LIVE login collisions   sideproject-balance 2d overnight run finishes ~03:00   solar-srec-check 9d SREC block availability   threadline show <id> · threadline board --all

what gets lost

Killing ten terminals should cost nothing.

Sessions attach to a thread and detach. A thread persists until you close it, so ending the terminal that happened to be open on it loses nothing.

A session finds its way back to a thread by worktree root + branch, the weakest key that actually works. A bare directory identifies nothing (every session launches from ~/Projects), and a repository alone would merge every open ticket on it into one thread. Parallel git worktrees separate for free.

Both views below are injected automatically when a session starts. You don't ask for them, and you don't have to remember to save anything.

a thread

A unit of work. Not a conversation.

Resuming an existing thread briefs you warm instead of cold, right down to the reason a fix got held.

"Get Ruby 2.2 to production without a weekend outage" is a thread.
The four terminal sessions spent on it are not.
warm resume
▸ orders-api-upgrade active · 6h · work-mbp   next Verify LIVE login collisions before shipping the held login fix   ⚠ block 23 live collisions seen; unclear if the fix worsens them   ⧗ wait reply from the client (human, 4d)   ↳ last held the login fix: staging audit was stale   git wip/shutdown-07-31 · dirty · 2 unpushed   4 other threads open · threadline board

three fields that matter

Everything else can be reconstructed from git.

These three can't, because they only ever existed in a context window.

↳

decide

What got ruled out, and why. The most expensive thing lost when a session dies, because the next one otherwise re-explores a dead end already paid for.

threadline decide "held the login fix" "staging audit was stale"

→

next_action

The literal next thing to do. Not a summary of the goal, a command or a step. If a cold session couldn't act on it, rewrite it.

threadline set next_action "verify LIVE login collisions"

⧗

wait

Anything blocking on someone or something outside this machine. Paired with block for what's blocking inside it.

threadline wait human "reply from the client"

design

The file format is the product.

An agent with only Read and Write can maintain the store correctly with no binary installed.

The log is truth, the projection is a cache

Every change is one appended line. thread.json is a replay of that log and is safe to delete at any moment. Nothing ever trusts it as input.

The exit path is a stamp, not a flush

A Claude Code SessionEnd hook gets killed mid-execution after roughly 1.5 seconds, measured across 11 runs and three signals. So threadline writes continuously while you work and does one append on the way out.

anything slower would simply not happen

Separation is by root, never by filter

Work threads live in a different store than personal ones, and the sync tool is never handed the work root's path. A filter that fails open leaks; a path that was never handed over cannot.

93 tests: unit, projection properties, and the real binary. One exists only because adversarial validation found a bug no test covered: a single stray byte that could silently erase a whole thread. A gate you haven't watched fail is not a gate.

dashboard

Zero changes to tend, for free.

threadline writes each live session's next action to ~/.claude/tend-note/<session-id>, which is tend's existing note convention. If you already run tend, its cards grow a thread line with no changes to tend at all.

The note refreshes on session start and on the heartbeat, so it can lag up to a minute behind a set next_action. Set THREADLINE_NO_DASHBOARD=1 to turn it off.

install

Build it, wire the hooks, check the doctor.

Requires a Rust toolchain. install.sh is idempotent, never removes an existing hook, and prints the exact command to undo itself.

install
❯cargo install --path . ❯./hooks/install.sh ❯threadline doctor
  1. 1
    Clone the repo and run cargo install --path ..
  2. 2
    Run ./hooks/install.sh to merge the 3 hooks into ~/.claude/settings.json.
  3. 3
    Run threadline doctor to confirm the wiring, then just work. The board or a warm brief shows up on its own.

The first set next_action or decide with no thread starts one, named after what you wrote.