Skip to main content
Version: 0.5

How to use gest

What is gest?

gest is a local-first work tracker built for AI-assisted development. You describe a feature; an agent breaks it into pieces; gest stores those pieces — and the relationships between them — in a single SQLite database on your machine. No server, no account, no cloud service to sign up for.

Every command speaks JSON, so agents and scripts read the work queue, claim work, and write back results through the same CLI you use by hand. The data lives locally (or in a sync mirror you can commit alongside your code), so everything is diffable and travels with your repo.

The three things gest tracks

  • An artifact is a design document — a spec, an ADR, an RFC, a brainstorm. Stored as Markdown with YAML frontmatter.
  • A task is a unit of work — a thing to build, fix, or check. Tasks have a priority and a phase.
  • An iteration is an execution plan — a group of tasks with a phased dependency graph that agents walk from start to finish.

Every artifact, task, and iteration has a short 8-character ID (e.g. xtnsuxns). You'll see these everywhere: the CLI prints them, commands take them, agents pass them around.

How we build gest with gest

gest itself is just a CLI and a database — it doesn't ship any agent integration. But to actually drive the workflow, we (the gest maintainers) use three Claude Code skills that live in the gest repo alongside the source, and this page walks through the same three skills.

Each skill is a text file: a prompt that tells an agent what to do, what gest commands to run, and when to hand off to the next skill. You can grab the skills from the repo to use as-is, adapt the prompts for whichever agent you prefer, or ignore skills entirely and run the CLI commands by hand — gest doesn't care.

  • /brainstorm turns a rough idea into a spec artifact. You describe the problem in your own words; the skill asks clarifying questions, proposes approaches with trade-offs, and saves the agreed direction.
  • /plan turns a spec into a plan. It decomposes the spec into tasks, groups them into phases that can run in parallel, and wraps the result in an iteration.
  • /orchestrate runs the plan. It walks each phase, spins up a separate worktree per task in the phase, and dispatches an agent into each worktree. Tasks in the same phase run at the same time.

A worked example

Let's walk through a real feature that's being tracked in the gest repo right now: giving the gest CLI proper exit codes. Today every error exits with 1, so scripts wrapping gest can't tell "no tasks available" apart from "bad flag" without reading error messages. We'd like each error category to exit with a distinct, standards-based code.

Step 1: Start with an idea

Open Claude Code and run /brainstorm with a rough description of the problem:

/brainstorm every gest CLI error exits with 1, scripts can't branch on category

The skill reads the relevant parts of the codebase, asks clarifying questions ("should we use BSD sysexits.h, or invent our own scheme?"), and once the direction is clear, saves a spec artifact. Under the hood, it runs:

cat spec.md | gest artifact create "Exit Code Taxonomy (sysexits.h)" \
--tag spec --tag cli -q
xtnsuxns

That's the spec's ID. You can view the spec with gest artifact show xtnsuxns (or in the built-in web dashboard at gest serve).

The brainstorm raised an architectural call big enough to warrant an ADR of its own — narrowing one enum variant and adding new ones. The skill writes the ADR the same way:

cat adr.md | gest artifact create \
"ADR-DRAFT: Exit Code Contract for the gest CLI" \
--tag adr --tag cli -q
prsooyor

Step 2: Plan the work

Pass the spec's ID to /plan:

/plan xtnsuxns

The skill reads the spec, decides whether the work is one issue or many, and — for work big enough to split — batches the tasks via newline-delimited JSON. Each task gets a phase number: tasks in the same phase can run in parallel; tasks in a later phase wait for earlier ones.

cat <<'EOF' | gest task create --batch -q
{"title":"Audit cli::Error construction sites","phase":1,"priority":1,"tags":["cli"],"links":["child-of:xtnsuxns"]}
{"title":"Update agent profile docs for new exit codes","phase":1,"priority":2,"tags":["docs","cli"],"links":["child-of:xtnsuxns"]}
{"title":"Refactor cli::Error: add variants, exit_code, ExitCode main","phase":2,"priority":0,"tags":["cli"],"links":["child-of:xtnsuxns"]}
EOF
qzkwulpt
sxyqyqlr
ywnqunto

Three IDs come back — one per task, in the order they were created. /plan then wraps those tasks in an iteration, names it, and prints the plan as ASCII with iteration graph:

gest iteration create "Exit Code Taxonomy (sysexits.h)" -q
gest iteration graph yzyomkzz
Exit Code Taxonomy (sysexits.h)
4 phases · 8 tasks

◆ Phase 1 ──
├─╮
○ │ qzkwulpt [P1] Audit cli::Error construction site… ○ open ! blocking
│ ○ sxyqyqlr [P2] Update agent profile documentation… ○ open
├─╯

◆ Phase 2 ──
⊗ ywnqunto [P0] Refactor cli::Error: add variants,… ⊗ blocked ! blocking blocked-by qzkwulpt

◆ Phase 3 ──
├─╮─╮─╮
⊗ │ │ │ pkpopvny [P1] Fix additional cli::Error miscateg… ⊗ blocked
│ ⊗ │ │ tnlzoutr [P0] Fix detach: replace Io misuse with… ⊗ blocked
│ │ ⊗ │ nlumrswo [P0] Fix iteration advance: replace Edi… ⊗ blocked
│ │ │ ⊗ osnqmnyn [P0] Fix iteration next: replace proces… ⊗ blocked
├─╯─╯─╯

◆ Phase 4 ──
⊗ sotpkmsx [P0] Add integration test coverage for … ⊗ blocked

Each ◆ Phase N ── line is a checkpoint. Tasks under Phase 1 run first and can go in parallel; everything in Phase 2 waits for Phase 1 to finish, and so on. The blocked-by labels on later tasks point back at the tasks they depend on.

Step 3: Run the plan

Pass the iteration's ID to /orchestrate:

/orchestrate yzyomkzz

For each phase, /orchestrate looks at the unblocked tasks and dispatches one agent per task. If the phase has more than one task — like Phase 1 above (qzkwulpt and sxyqyqlr) — it creates a separate worktree for each agent, so they can edit the code without stepping on each other. Every agent calls iteration next --claim; gest hands out a different task atomically, so there's no risk of two agents picking up the same one:

# agent A # agent B
gest iteration next yzyomkzz --claim \ gest iteration next yzyomkzz --claim \
--agent agent-a --json --agent agent-b --json
// agent A // agent B
{"id":"qzkwulpt...","title":"Audit cli::Error...", {"id":"sxyqyqlr...","title":"Update agent profile...",
"status":"inprogress","phase":1,"priority":1, "status":"inprogress","phase":1,"priority":2,
"assigned_to":"agent-a"} "assigned_to":"agent-b"}

Once every task in the phase is done, /orchestrate moves on to Phase 2; then Phase 3; and so on until the iteration is complete. You can check progress at any time — same JSON that powers the web dashboard:

gest iteration status yzyomkzz --json
{
"id": "yzyomkzzxrlprqmppxllvouxlooyxxnw",
"title": "Exit Code Taxonomy (sysexits.h)",
"status": "active",
"phases": 4,
"total_tasks": 8,
"open": 8,
"in_progress": 0,
"done": 0,
"progress": 0
}

Step 4: Ship it

As each agent finishes its task, it commits the work to your repo. When the whole iteration is done, a separate /changelog pass reads the new commits and turns them into release notes in your CHANGELOG.md. The first brick of this exit-code work — iteration next returning 2 when no tasks are available — already shipped in v0.5.4, and you can read it in the real CHANGELOG:

## [v0.5.4] - 2026-04-14

### Changed

- `iteration next` returns proper error codes (exit 2 when no tasks are
available) instead of calling `process::exit` directly

Where to go next

  • Install gest — one command on macOS or Linux.
  • Quick start — the shortest path from zero to a working gest project, by hand (no agent required).
  • Core concepts — deeper reference for artifacts, tasks, iterations, phases, links, and storage.
  • CLI reference — every flag on every gest command.

Output captured from commit eb5a2ba. IDs are shown as 8-character short forms; internally they are 32-character lowercase alphanumeric.