Git for AI coding sessions. Version your Claude Code / Codex sessions and carry them across machines — commit where you are, continue where you're going. Then search, review, summarize, and open them like any other engineering history.
Laptop Desktop
──────── ────────
working in Claude Code
$ threadline commit -m "auth refactor"
$ threadline push ──────▶ ☁️ (encrypted R2) ──────▶ $ threadline pull
$ claude -r <session>
...continue exactly where you left off
Your AI coding sessions are real engineering work — the context, the decisions, the dead ends. They shouldn't be stuck on one laptop. threadline treats them like a git repo: content-addressed commits, history, push/pull, merge — synced through your own end-to-end-encrypted storage. No server to run, no account, no cloud middleman.
brew install rclone # the sync engine
pip install git+https://github.com/armaan-25/threadline.git # the toolOr from source (for hacking on it):
git clone https://github.com/armaan-25/threadline.git
cd threadline && pip install -e .Requires Python 3.9+. Pulls in rich and keyring.
Point it at your own Cloudflare R2 bucket once (encrypted client-side — the cloud only ever sees ciphertext). See Configure storage.
threadline is private by default — nothing syncs until you pick a conversation to carry.
# wire up a project (Claude/Codex hooks) — syncs nothing yet
threadline setup --mode repo --r2-remote threadline-crypt
# pick the conversation you want on your other machine — only this one uploads
threadline pick "auth refactor"
# on another machine, pull it down and resume:
threadline clone <project> ~/.claude/projects/<slug> --remote threadline-crypt:
claude -r <session-id>Once you've picked a conversation, its future turns keep syncing automatically. Everything you don't pick stays local.
Prefer to drive it by hand? It's a git-shaped CLI:
threadline init my-project
threadline add .
threadline commit -m "before the big refactor"
threadline push
threadline logA polished, git-shaped terminal experience. Run bare threadline for the splash:
╭─────────────────────────────────────────────────╮
│ │
│ ●───●───●──▶ threadline │
│ │
│ git for your AI coding sessions v0.5.0 │
│ │
╰─────────────────────────────────────────────────╯
get started
threadline setup turn on auto-sync for this project
threadline log your session history
threadline open <query> jump back into a session
threadline status sync state at a glance
──────────────────────────────────────────────────
docs github.com/armaan-25/threadline · threadline <cmd> -h
Colorized throughout, with a git-style commit graph, honest sync state, and highlighted search.
Every commit records lightweight, useful context — no config required:
$ threadline log
myapp 2 sessions
│
● auth refactor: OAuth callback 71632737e
│ “add OAuth login to the API”
│ myapp · mac.lan · claude · claude-opus-4-8 · ⎇ main
│ Jul 01 · 8:01 PM · 6 files
│
● scaffold API routes 81e752fcd
│ myapp · mac.lan · claude · claude-opus-4-8
│ Jul 01 · 6:22 PM · 3 files ● unpushed
│
A git-style graph: commit message · session prompt · project · machine · provider · model · branch · timestamp — with honest sync state (unpushed commits are flagged). An engineering timeline of your AI work.
| Command | What it does |
|---|---|
setup --mode repo |
Wire Claude/Codex hooks (private by default — syncs nothing until you pick) |
pick <query> |
Select a local conversation to sync — shares just that one |
init <name> |
Start a session repo in the current directory |
add / commit -m |
Stage and snapshot session files |
push / pull |
Sync commits through your encrypted remote |
clone <name> [dest] |
Materialize a session repo on another machine |
log [--oneline] [-n N] |
The session history (git-style graph; compact + limited views) |
timeline |
A visual lifecycle of the current session |
search <query> |
Find sessions by prompt, metadata, or transcript content |
review [commit] |
Structured review: goal, files, provider, branch |
summarize [--ai] |
Turn a session into shareable Markdown docs |
diff [a] [b] |
Compare two sessions/commits (files + event deltas) |
fork <name> |
Branch a session into an independent variant |
open <query> [--no-pull] |
Pull latest and reopen a session (--no-pull skips the sync on large repos) |
status |
Current project, branch, last sync, pending changes |
export [commit] |
Write a Markdown summary of a session |
restore |
Re-materialize the working tree from the latest commit |
status, log, search, and review support --json for scripting. Run bare threadline for a command menu, or threadline --version.
A session repo lives in a .threadline/ directory (like .git) with content-addressed blob / tree / commit objects and linear, fast-forward history. Diverged machines auto-merge session transcripts (union of turns, de-duplicated) and record a real two-parent merge commit.
Sync is just rclone: because objects are immutable, a push/pull is an incremental copy of the object store plus one refs/head pointer. Over an rclone crypt remote on Cloudflare R2, filenames and contents are encrypted on your machine — the bucket only holds ciphertext, and there's no server to run.
Create an R2 bucket + S3 API token, then two rclone remotes (use the same two passphrases on every machine — they're the only way to decrypt):
rclone config create threadline-r2 s3 \
provider=Cloudflare region=auto \
access_key_id=<KEY> secret_access_key=<SECRET> \
endpoint=https://<ACCOUNT_ID>.r2.cloudflarestorage.com \
no_check_bucket=true
rclone config create threadline-crypt crypt \
remote=threadline-r2:<BUCKET> \
password="$(rclone obscure '<PASSPHRASE_1>')" \
password2="$(rclone obscure '<PASSPHRASE_2>')"Then set the default so you can drop the --remote flag:
export THREADLINE_RCLONE_REMOTE=threadline-crypt:Any remote that isn't an http(s):// URL is treated as an rclone target. (An http(s):// remote points at an optional threadline server — handy on a trusted LAN, no encryption.)
setup --mode repo writes two Claude Code hooks:
- SessionStart →
threadline pull(fast-forward / auto-merge from the remote before you start) - Stop →
threadline add . && commit && pushafter each turn (fire-and-forget; failures are recorded, never block the session)
Check it's working anytime with threadline status — a stale or FAILED last-sync line is your signal.
| Provider | Sessions | Auto-sync |
|---|---|---|
| Claude Code | per-project (~/.claude/projects/<slug>/) |
SessionStart + Stop hooks |
| Codex | global, date-partitioned (~/.codex/sessions/) |
via Codex notify (chained, non-destructive) |
Both share the same engine, encrypted remote, and commands; metadata (model, project from the session's cwd, machine) is captured per provider. Set it up with --provider codex:
threadline setup --mode repo --provider codex --r2-remote threadline-cryptBecause the session format is just timestamped JSONL, new agents are mostly a matter of a provider entry — not a new engine.
threadline does one thing: help you continue an AI coding session across machines. It is not a deployment tracker, a replay engine, an AI-memory platform, or a web app. Small, focused, terminal-first.
./scripts/selftest.sh # full regression (no network/R2 needed)