Written in Rust. One static binary per platform: no Node, no Python, nothing to keep in sync before it starts.
Shape every level, down to the loop.
The built-in harness is only the default assembly. Pull any level out, slide your own in, and it is still a first-class citizen of the orrery CLI.
curl -fsSL https://getorrery.dev/install.sh | shChecks the release's sha256 before it writes anything. Read it first: install.sh
irm https://getorrery.dev/install.ps1 | iexIn PowerShell. Checks the release's sha256 before it writes anything. Read it first: install.ps1
Start with the model. A local Qwen is just another extension.
[providers] = anthropic ollama · qwen3Hand it your tools. Jira and Linear sit next to read, edit and bash.
[tools] = read · edit · bash + jira · linearChoose what it reads first: a map of the whole repo, not only open files.
[context] = open files repo mapLet it remember between sessions, in your own pgvector.
[memory] = this session pgvectorSay what it may do without asking. pnpm test is always yes.
[permissions] = ask every time allow pnpm testAdd your own slash commands. /ship means what your team means.
[commands] = /help · /cost /shipDraw it anywhere. Your phone client is a first-class client.
[ui] = TUI your phone clientSplit the work. A planner hands off, a reviewer checks.
[orchestration] = one agent planner + reviewerAnd the loop itself. Plan, act, verify, or a flow of your own.
[harness] flow = plan · act · verify your own flowEvery level of the harness is a part you can change. Here they are, one by one.
orrery run -p "ship it"Underneath, extensions. One plugs into many levels at once. The rest is up to you.
[extensions] = anything you can buildWrite extensions in the language you already know. Same contract, same grants.
runtime = native · wasm · node · python · processA harness you can own, all the way down.
Providers, tools, memory, permissions, the UI, the loop. Ours is built from the same parts, so you can swap any of them.
Write an extension in Rust, Go or any Wasm language, in Node or Python, or as a plain process. Same manifest, same grants.
Any model, local or remote, on your own keys. Every tool call passes one policy, asks before it acts, and lands in the audit log.
Small parts. Real workflows.
Grow the harness from inside it
Missing an agent? Describe it. /agents create runs a built-in agent creator: it infers the fields, asks only what it must, and writes the agent file. Commands and the UI do the same for every level: whatever they set up lands as a key in config.toml.
› /agents create a reviewer that reads the diff and never edits ✻ Creating the agent…● agents.create reviewer ⎿ tools git.*, lsp.* ⎿ edits never · asks before any write ⎿ model inherits ollama/qwen3:8b › /agents reviewer ready · fresh context
Any provider, on its own wire
Anthropic, OpenAI, Gemini, Ollama and vLLM, each through its own extension, and anything that speaks the OpenAI API: OpenRouter, Groq, LM Studio. Sign in or paste a key; a key in the file is only the variable's name. Switch the model mid-session with /model.
$ orrery providers add ollama --model qwen3:8b --use✓ ollama set up · qwen3:8b · in use$ orrery providers add gemini --api-key '$GEMINI_API_KEY'✓ gemini set up · 3 models › /model gemini-2.5-pro● this session now runs on gemini/gemini-2.5-pro [providers.gemini]apiKey = "$GEMINI_API_KEY"
Steer it while it works
Type while the agent is busy and press Enter: the line joins the run in flight and lands in its next step. A script does the same over the control API, to steer now or queue for after the current task.
● Write test/webhooks/retry.test.ts ⎿ Wrote 61 lines · jest↳ steer: use vitest, not jest● Switching the suite to vitest.● Update test/webhooks/retry.test.ts +4 −4 › Turn running · enter steers
Agents that create agents
Sub-agents ship as an extension on core's run and agent APIs. Each starts with a fresh context or a fork of the conversation, under the caps you set; core keeps the tree, its limits and its log.
● spawn reviewer context: fork● spawn tests context: fresh ⎿ 2 of 3 children · depth 1 of 2✻ reviewer: 2 comments on retry.ts✓ tests: 6/6 passing [extensions.subagents]max_children = 3max_depth = 2
Pick up where you left off
A session outlives a turn and the terminal. orrery --continue opens this folder's latest one, --resume a named one, and /cost says what each prompt cost. Attach the same session from the desktop app, the browser or your phone.
$ orrery session list a41f 12 turns default ~/payments 9c02 4 turns reviewer ~/payments$ orrery --continue↺ a41f · stripe-retry · turn 12 › /cost 12 prompts · 361k tok · $1.93
One key in config.toml, or one command. Same result.
Whatever a command or a flow sets up is a key in config.toml, and writing the key by hand does exactly the same thing. No hidden state: copy the file and you have the setup.
Ours and yours load the same way.
A provider, a tool, a memory, a client that draws the UI: each is a package with an orrery.toml that says what it offers and what it may touch. The built-in harness is made of these, and a shortcut only ours could take would be a bug.
orrery-extension. It shows up in the gallery overnight and installs by source: orrery install npm:…. Unpinned, and the gallery says so.orrery publish opens a pull request to the signed index. Once merged it takes a bare name: orrery install <name>, checked against its sha256.Five read verbs over gitoxide; commit, push and pr through your own git and gh, asked by default.
$WORKSPACE/**write$WORKSPACE/.git/**spawngit, ghClaude on Anthropic's own wire, with an API key or a sign-in.
api.anthropic.comcredsanthropicModels on your own machine. One port, no key.
localhost:11434spawn_agents: hand a brief to child agents, bounded by the run's tree.
nothingSample listing. Which modules a change touches, from your build graph.
readspawnnetorrery install buildgraphexample · [N]/moSample listing. Jira issues as tools through a bundled MCP server.
netcredsspawnunpinnedorrery install npm:@example/orrery-ext-jiraexample · [N]/moCustomizable is not the same as unsafe.
What a harness does is yours. What it may touch is decided by the kernel's policy, for every harness alike.
Trust a folder first
A new workspace asks before its config or extensions run anything.
Grants, declared and enforced
An extension has no capability except through the kernel. Its manifest lists what it asks for; you see the grants on install and the diff on every upgrade.
Consent, asked once
Allow once, always, or deny, by rule. Every attached screen sees the same prompt; the first answer settles it everywhere.
A signed registry
Verified extensions resolve through a signed index: the hash is checked again in CI and the grants diffed before a maintainer merges. A revoked version is refused on the next fetch, with the reason.
Run it on every machine.
Your computers and cloud instances on one list, every session followed and answered from the browser, your phone, the ADE or a terminal. Your machines dial out; nothing opens a port.
Build an extension. Bring your harness.
The code
Harness, ADE and Cloud in one repository. Issues and pull requests welcome.
Write an extension
Rust, TypeScript or WASM. A worked example and a conformance fixture for every kind.
Publish it
orrery publish checks the manifest, runs orrery ext test and opens the pull request.
Follow along
Every release, straight from the commit history.