The toolchain
A toolbelt, not an app.
Sprig is a file format first. The tools around it are small, read the same files, and agree with each other because they share one parser. None of them needs an account, a server or a config file.
No release is published yet, but the command line installs from source with Rust today. Commands marked Today are in it; the rest arrive milestone by milestone.
cargo install --locked --git https://github.com/oddurs/sprig sprig-cli$ sprig next --limit 6 --today 2026-10-01 ~ Break clause at year three Oct 5 · in 4d !!! ~ Equipment loan paperwork Oct 7 · in 6d !! ~ Ventilation plan with the eng… Oct 12 · in 11d ~ Logo, second round Oct 14 · in 13d ? Who pays for the grease trap? Oct 5 · in 4d !!! - Get a third quote Oct 2 · in 1d !! 6 of 20 ready · 12 waiting · 2 questions
One core, every surface.
The parser is a Rust library that touches no files, clock or network. It compiles to a native binary and to WebAssembly, so the terminal, your editor, a coding agent and this site give the same answer about the same file.
- PlaygroundToday
Edit a plan and watch it compute, in this browser. It runs sprig-core, the same Rust parser as the sprig command, compiled to WebAssembly.
- sprigToday
The command line: what’s next, what’s broken, what’s blocked, and one-line writes. It installs from source; the first release is v0.1.
- EditorsToday
sprig lspserves any editor that speaks LSP: problems as you type, completion, go to definition, hover and ticking. A VS Code extension and a Tree-sitter grammar follow in v0.2.- sprig mcpv0.3
Coding agents read the plan, find ready work and tick it, as file edits you review.
- sprig tuiv0.4
A folder of plans on one terminal screen, with vim keys.
Small verbs, one question each.
Every command reads a folder of plans and answers one question, in text a person can read and a pipe can parse; writing is a line in your editor. The screens below are sprig-core’s output for the example bakery plans, with the date pinned by --today the way the tests will run.
Read
answer a question, change nothing
sprig nextToday- Open, unblocked work: in progress first, then priority, then due date.
sprig treeToday- The plan as Sprig reads it, grafts expanded, progress rolled up. --summary for the whole folder on one screen.
sprig why <ref>Today- What an item waits on, all the way down, with file and line.
sprig find <query>Today- Search by text, @who, #tag, is:blocked, due:<fri.
Check
fail loudly, fix nothing silently
sprig checkToday- Broken links, loops and unknown anchors as file:line:col. Exit 1 on any error.
sprig fmtToday- Two spaces per level, typed dates expanded to ISO. --check for CI.
Write
everything else is a line in your editor
sprig tick <ref>Today- Done, or reopen; --mark sets any status. A recurring item moves its due date instead.
Connect
other tools, other formats
sprig exportToday- The resolved tree as JSON, due dates as an iCalendar feed, the dependency graph for Graphviz or Mermaid.
sprig importToday- Markdown checkboxes in, a Sprig file out.
sprig lspToday- A language server for any editor: problems as you type, completion, go to definition, hover and ticking.
sprig mcpToday- The plans, served to coding agents.
sprig generateToday- Completion that knows your anchors and people, and a man page.
$ sprig tree kitchen.sprig Kitchen fit-out 1/10 █░░░░░░░░░ ├─ - Design 1/2 │ ├─ x Layout sketch │ └─ ~ Ventilation plan with the engineer Oct 12 ├─ # Equipment 0/3 │ ├─ - Deck oven, three decks !! 0/2 │ │ ├─ - Get a third quote Oct 2 │ │ └─ - Place the order waits on Equipment loan paperwork │ ├─ - Spiral mixer, 40 litres │ ├─ / Proofing cabinet │ └─ > Espresso machine └─ - Build waits on Design, Sign the lease 0/5 ├─ - Strip out ├─ - Plumbing and drains ├─ - Three-phase electrics ├─ - Tiling └─ - Install equipment
$ sprig why Tiling - Tiling kitchen.sprig:22 └─ inside Build, which waits on: ├─ - Design kitchen.sprig:3 @teo │ └─ 1 of 2 done, nothing blocks it └─ - Sign the lease lease.sprig:13 @dana ├─ ~ Negotiate terms lease.sprig:6 @dana │ └─ 1 of 3 done, nothing blocks it └─ - Change-of-use permit lease.sprig:11 @dana └─ ready to start
Tiling isn’t blocked on its own. Its parent is, and the chain crosses into another file.
$ sprig check bakery.sprig:19:3: error[S0101]: no file named kitchn.sprig lease.sprig:13:42: error[S0201]: no item ^permt in lease.sprig 2 errors in 2 files · exit 1
Two mistakes planted in a copy of the plans. Editors and CI jump straight to file:line:col.
$ sprig tree --summary --today 2026-10-01 bakery ██░░░░░░ 9/40 12 waiting groceries ██░░░░░░ 3/10 kitchen █░░░░░░░ 1/10 6 waiting launch ██░░░░░░ 4/19 4 waiting lease ███░░░░░ 2/6 1 waiting $ sprig tree --summary --oneline sprig 23% · 20 ready · 12 waiting
The rules every tool keeps.
These decide every command. Where a feature would break one, the feature loses.
The file is the truth
Tools compute progress and blockers; they never store them. Delete every tool and the plan still reads.
A write touches one line
tick, the TUI and the MCP server change only the bytes they mean to, so git diff shows exactly what happened.
Three kinds of output
Aligned for people, tab-separated with --plain, and the whole resolved tree as JSON from sprig export. The --plain columns are covered by the stability policy.
Exit codes mean something
0 fine, 1 the answer is no, 2 you asked wrong. Scripts branch on them.
Every answer is reproducible
--today pins the date, so any output can be tested, diffed and pasted into a bug report.
Nothing to set up
No config file, no daemon, no plugins, no network. Flags and environment variables only.
Colour is a courtesy.
Every screen takes its colour from the nine marks and nothing else. Set NO_COLOR and nothing is lost, because the character already is the status.
$ sprig tree lease.sprig Lease 2/6 ███░░░░░░░ ├─ x Shortlist three spaces ├─ ~ Negotiate terms !!! Oct 5 1/3 │ ├─ x Eight weeks rent-free for the fit-out │ ├─ ~ Break clause at year three │ └─ ? Who pays for the grease trap? ├─ - Change-of-use permit └─ - Sign the lease waits on Negotiate terms, Change-of-use permit
$ NO_COLOR=1 sprig tree lease.sprig Lease 2/6 ███░░░░░░░ ├─ x Shortlist three spaces ├─ ~ Negotiate terms !!! Oct 5 1/3 │ ├─ x Eight weeks rent-free for the fit-out │ ├─ ~ Break clause at year three │ └─ ? Who pays for the grease trap? ├─ - Change-of-use permit └─ - Sign the lease waits on Negotiate terms, Change-of-use permit
Pointing at an item from the shell.
Commands that act on one item take a ref. The forms run from exact to forgiving, and an ambiguous ref lists its candidates and exits 2 rather than guessing.
| Ref | Means | Example |
|---|---|---|
^signed | An anchor, searched across the folder | sprig tick ^signed |
lease^signed | An anchor in one file | sprig why lease^signed |
lease.sprig:13 | A line, the way compilers print one | sprig tick lease.sprig:13 |
"grease trap" | Words from exactly one item’s text | sprig tick "grease trap" |
- | Refs on stdin, one per line | sprig next --plain | cut -f1 | sprig tick - |
The same verbs, on one screen.
sprig tui shows the tree, what’s next and the agenda, with vim keys. Its writes go through the same one-line edits as the commands, and it reloads when an editor or an agent changes a file underneath it. This one runs sprig-core in the browser: focus it and use the keys.
# Money
at bakery.sprig:9
status doing
owner @dana
progress 2 of 4 done
Budget is 180k. Anything over 10k needs a second quote.
Ticks change this page’s copy of the plans, nothing on disk. The dates are pinned to 1 October 2026, like the screens above.
- j k
- move
- h l
- fold, unfold
- x
- tick
- ~
- mark doing
- 1 2 3
- tree, next up, agenda
- /
- filter
- ?
- help
Pipes, not plugins.
Plain output and meaningful exit codes let Sprig work with the tools already on the machine, so it needs no plugin system.
Pick and tick with fzf
The first column of --plain is always a ref.
$ sprig next --plain | fzf | cut -f1 | sprig tick -Gate a commit
A pre-commit hook that checks only the plans that changed.
$ git diff --cached --name-only -- '*.sprig' | xargs sprig check --strictDeadlines in any calendar
Regenerate on a timer; the calendar subscribes to the file.
$ sprig export --format ics > ~/Sync/plans.icsYour next task in the prompt
For Starship, tmux, or any prompt that runs a command.
$ sprig next @me --limit 1 --plain | cut -f2