A desktop control plane for AI-assisted development. Your project's plan lives as a graph of markdown nodes on a git branch. Agent sessions read it, work it, and write their results back through a CLI. You steer the whole effort from a canvas.
Status: early and moving fast. The pieces described below work and are tested, but interfaces, the node taxonomy, and the on-disk format may still change without ceremony.
Agentic development doesn't usually fail inside a session — it fails between them. The plan lives in a chat scrollback, the decisions live in another one, and every new session starts by re-deriving context that already existed yesterday. Session managers multiply the sessions; they don't fix the memory.
ork's bet is that context assembly is the real problem, and that the fix is a durable context graph kept where development artifacts already live: in git. Plans, specs, decisions, research findings, and session close-outs are markdown nodes on a dedicated branch of your own repository — versioned, diffable, greppable, and readable by any agent that can run a CLI.
Three things fall out of that:
- Agents start warm. A session opens with
ork ls, reads the nodes that matter, and knows the plan, the decisions behind it, and what the last session left open. - Decisions survive. A decision node freezes when it's done. Changing
course is a new node with a
supersedesedge — the graph remembers what was believed, and when, and why it changed. - The human sees the whole board. The desktop app renders the graph as a canvas of nested, connected nodes — what's active, what's blocked, what needs you — and every body renders as a document, because the record is the product.
ork init creates an orchestrator branch in your repository — an orphan
branch,
sharing no history with your code — and checks it out as a hidden
worktree under .git/ork/. It
never touches your working tree, your code, or your existing branches. If
the repository already has an orchestrator branch (say, you just cloned a
repo that uses ork), ork init attaches to it instead of creating one.
Every node of the plan is one markdown file with YAML frontmatter on that
branch: a title, a type, a status, edges to other nodes, and a body that
renders as a document in the app. The audit log is git itself —
ork log <ref> is a node's history.
The default taxonomy (each repo can change it in config.yml on the data
branch — re-run ork write-skill after editing it so the skills follow):
- Types —
feature(a unit of buildable work; records which PR and branch realize it),doc,research(read-only sessions),session(close-out records, created byork session close— never by hand),group,decision(frozen once done). - Edges —
relates,implements,supersedes,blocks. - Statuses —
idea,active,done,archived.
A few rules do most of the work:
- A
decisionnode's body freezes when it reachesdone; changing course means a new node with asupersedesedge. There is no delete —archivedis the only removal, and archived nodes stay readable. blockedis never stored. It is derived from incomingblocksedges, andork frontier <ref>computes what is takeable right now: open, unblocked, unclaimed. (A claim is just aclaimedmeta key a session sets when it picks up a node and clears when it releases it.)- Every agent session ends with
ork session close, which writes a close-out record for the next session, attached to the node it worked on. Blank or boilerplate close-outs are refused.
Any agent that can run a shell command can read and write the graph — the
CLI is the whole integration surface, and every command accepts --json.
The packaged workflows target Claude Code:
ork write-skill renders skill files from your repo's live taxonomy into
.claude/skills/, teaching sessions the graph vocabulary and the workflows
on top of it (other agents can use the same files as plain prompt material):
ork— the base skill: reading context, recording work, closing a session.ork-wayfinder— charts an effort too big for one session as a map of decision tickets, worked one at a time until the route is clear.ork-interview— resolves a human-in-the-loop ticket through rounds of questions, sharpening the domain language as it goes.ork-spec— synthesizes a finished map into one build-ready spec, gated by an adversarial review and the owner's explicit sign-off.ork-tickets— cuts an approved spec into thin end-to-end build tickets, sequenced byblocksedges;ork frontieris the work queue.
Together they form a pipeline: chart → interview → spec → tickets → build, with the human ruling on every decision and the graph carrying the context between sessions.
The wayfinder/interview/spec workflow is adapted from Matt Pocock's skills (MIT) — reworked to run natively on the graph. See NOTICE.
A quick tour:
ork ls --tree # the whole plan at a glance
ork show <ref> --body # one node (ULID, unique prefix, or slug fragment)
ork search <query> # substring match over titles and bodies
ork backlinks <ref> # what points at this node, and with which edge type
ork frontier <ref> # children takeable now: open, unblocked, unclaimed
ork log <ref> # a node's git history
ork export # the whole graph as one JSON document
ork create feature "Title" --parent <ref> --body-stdin
ork status <ref> done
ork edge add <ref> blocks <target>
ork bind <ref> --pr 142 --branch feat/x # records metadata; no GitHub calls
ork session close --node <ref> --stdin
ork sync # pull --rebase + push the data branchflowchart LR
you(["you"]) --> app["desktop app"]
agents(["agent sessions"]) --> cli["ork CLI"]
app <-->|WebSocket| daemon["ork daemon"]
cli -->|RPC| daemon
daemon -->|git| orch
subgraph repo["your repository"]
orch[("orchestrator branch")]
end
packages/core # graph library: schema, validation, git-backed store, writer queue
packages/cli # ork — the agent-facing public API (--json everywhere)
packages/daemon # serves the graph over unix socket + loopback TCP; watches; broadcasts
app # Tauri shell + React canvas/editor (xyflow)
spike # early webview experiment
scripts # one-time bootstrap script
All writes — CLI commands and app edits alike — go through one git-backed
store with a serializing writer queue. When the daemon is running it owns
that store: the app talks to it over WebSocket, the CLI over RPC, and it
broadcasts every change to every client. When no daemon is running, the CLI
opens the store directly — so ork works with nothing else installed or
launched, and the graph is just as usable headless as it is under the app.
Prerequisites: Node ≥ 22 (the packages alone run on ≥ 20.19, but the app's
dev server wants 22), git ≥ 2.42 recommended (older versions get a fallback
init path), and Rust stable ≥ 1.85 — only if you're building the desktop
app.
Platforms: developed and tested on macOS; should work on Linux (unix sockets). Windows is untested and unlikely to work yet.
git clone https://github.com/eckhartt/ork.git && cd ork
npm install
npm run build # builds core, cli, daemon
cd packages/cli && npm link # puts a global `ork` on your PATHThen, in any git repository you want a graph for:
ork init # creates (or attaches to) the orchestrator branch
ork create group "My first plan" --status active
ork ls # prints the node you just made
ork write-skill # installs the agent skills into .claude/skills/From there, open a Claude Code session in that repository and ask it to look at the plan — the installed skill teaches it the rest.
The orchestrator branch is an ordinary git branch. ork sync runs
pull --rebase and pushes it to origin; nothing syncs behind your back.
Cloning a repo that uses ork brings the graph along — ork init on the
clone attaches to the existing branch. Concurrent edits from two clones are
ordinary git conflicts on small markdown files; ork is built today for one
human and their agents per repository, not yet for teams racing on one
graph.
cd app && ORK_REPO=<path-to-your-repo> npm run tauri devPoint ORK_REPO at a repository where ork init has run. The app spawns
the daemon as a supervised sidecar and renders the graph as a canvas:
nested containers, drag-to-connect, drill-in navigation, a markdown editor
for node bodies, and frontier/blocked/needs-you accents driven by the same
derived state the CLI reports.
Two terminals:
node packages/daemon/dist/main.js --repo <path-to-your-repo>
# prints {"port":…,"token":…}
cd app && npm run dev
# then open http://localhost:5173/?port=<port>&token=<token>npm install
npm run build # the CLI test suite runs the built dist/, so build first
npm test # all workspaces: core, cli, daemon, appTests are vitest throughout.
Issues and pull requests are welcome. Fair warning about the shape of the
project: this public repository mirrors main from a private working
repository — where ork is developed with ork, plan-graph and all. Accepted
changes are pulled into the working repo and arrive back here in a mirror
push, so your PR may close without a merge commit even though your commits
(and authorship) land on main. Open an issue first for anything larger
than a fix, and expect the taxonomy and on-disk format to still be in
motion.
MIT © 2026 Nicholas Birkbeck. Portions of the generated skill content are adapted from Matt Pocock's skills, MIT © 2026 Matt Pocock — see NOTICE.