Version control for agents
Oak
This repository is the open-source part of Oak, version
control built for you and your agents. It's a Cargo workspace: a reusable VCS
library and the oak command-line client.
Oak doesn't run agents. Bring your own (Claude Code, Codex, Cursor, …) and it
works through the oak CLI. A branch is one unit of work, usually one agent
session. The branch description takes the place of per-commit messages, and
content-addressed lazy mounts let you start on a repo without cloning it.
| Crate | Path | crates.io | What it is |
|---|---|---|---|
oakvcs-core | core/ | oakvcs-core | The VCS foundation: BLAKE3 content hashing, content-defined chunking, diff/merge, the Blob/Manifest/Commit/Tree data model, and an optional client-side local repository (SQLite + git backends). |
oakvcs-cli | cli/ | oakvcs-cli | The oak binary that builds on oakvcs-core. |
Using the library in your own project
oakvcs-core is usable on its own — e.g. to build an Oak integration into
another tool or engine. Pull in just the content-addressed data model and
hashing (no SQLite/git) with default features off:
[dependencies]
oakvcs-core = { version = "0.111.0", default-features = false }
The crate is published as oakvcs-core but imported as oak_core.
Add the default local-repo feature when you also want the on-disk
Repository (SQLite + git) backends. See docs/git-backend.md for hosting Oak repos on GitHub or any git server.
Installing the CLI
Oak is in public beta (v0.113.0). The quickest way in is the prebuilt
oak binary:
curl -fsSL oak.space/install | sh
The sh installer supports macOS (Apple Silicon and Intel) and Linux
(x86_64) — it picks the native binary for the machine it runs on. After
install, oak upgrade updates the binary in place, and on macOS the Oak Mount
app with it.
To run nightly builds of the tip of main instead of tagged releases, switch
your update channel once:
oak upgrade --channel nightly # remembered: oak upgrade and the update notice now follow nightly
oak upgrade --channel stable # back to tagged releases
Nightlies are built on Oak CI and served from oak.space at most once a day
(only when something landed). They're signed with the same release key as
stable and identify themselves in oak --version
(0.106.0 (nightly 20261027.b8d19ad7)).
Linux ARM64 binaries are published too, but the installer doesn't select them yet; download the Linux ARM64 build below for now.
Downloads
Each link serves the latest stable oak for that platform:
| Platform | Download |
|---|---|
| macOS, Apple Silicon | oak-darwin-arm64 |
| macOS, Intel | oak-darwin-x86_64 |
| Linux x86_64 | oak-linux-x86_64 |
| Linux ARM64 | oak-linux-arm64 |
| Windows x86_64 | oak-windows-x86_64.exe |
Add /sha256 or /minisig to a link for its checksum or minisign signature,
and swap latest for a version (v0.113.0) to pin one. Make the file
executable, rename it oak (oak.exe on Windows) and put it on your PATH.
What changed in each release is in docs/ as release-X.Y.Z.md.
Windows (x86_64)
The curl … | sh installer is Unix-only; Windows has a PowerShell
counterpart:
irm https://oak.space/install.ps1 | iex
It installs oak.exe to %USERPROFILE%\.local\bin and adds that directory to
your user PATH. You can also take oak-windows-x86_64.exe from
Downloads, or build from crates.io with
cargo install oakvcs-cli. oak upgrade then updates it in place.
oak mount on Windows uses the Projected File System (ProjFS), an optional
Windows feature. Enable it once per machine from an elevated PowerShell:
Enable-WindowsOptionalFeature -Online -FeatureName Client-ProjFS -NoRestart
(or Settings → Apps → Optional features → "Windows Projected File System"). Everything else — clone, push, pull, commit — works without it.
Prefer to build from crates.io? Install with Cargo instead (works on macOS,
Linux, and Windows — the TLS stack uses rustls + ring, so no C/NASM build
toolchain is required):
cargo install oakvcs-cli # builds and installs the `oak` binary
Shell completion is generated on demand — bash, zsh, fish, elvish, and
powershell are supported. For the current session:
source <(oak completions bash)
Or write the script wherever your shell loads completions from, e.g.
oak completions bash > ~/.local/share/bash-completion/completions/oak.
Teaching your agent to drive Oak
Oak bundles an agent skill in the open Agent
Skills format — a SKILL.md plus
reference files that tell a coding agent how Oak differs from git (branches
off main that stack on request, messageless commits, branch descriptions, mounts, CI on main) so it
stops reaching for git status:
oak skill install # into this repo's .claude/skills/ — commit it
oak skill install --global # into ~/.claude/skills/ for every project
The files are baked into the binary, so the installed skill always documents
the CLI version that wrote it; re-run after oak upgrade to refresh it. The
source of truth is
cli/src/commands/skill/oak-vcs/.
oak skill install (and oak init, when it writes AGENTS.md) also merges
Claude Code hooks into the matching settings.json that run oak watch hook
on SessionStart, UserPromptSubmit, PostToolUse, and SessionEnd. Together with
oak start they make an agent's branch live:
oak start "fix the login redirect" # branch from main, described, pushed, `oak watch` running
oak watch status # watch merges main in as it moves and pushes each commit
oak finish --desc-file desc.md # publish; stops watch and marks the branch idle
oak watch reports merges and conflicts to the agent through the hooks and
marks the branch Active on oak.space while it runs. Turn it off per checkout
with oak config set watch.enabled false (--global for every repo,
OAK_WATCH=0 for one shell, or the Agent sync section of oak.space settings);
watch.auto_pull and watch.auto_push toggle its two halves.
To let people follow uncommitted work from the branch page, turn on
oak config set watch.share_working true. It's off by default because watch
then sends changed text files to the server as they're saved, before any
commit. Ignored files, binary files and credential-shaped names stay local.
Using Oak from an MCP client
oak mcp is an MCP server over stdio, for
agents that reach tools through MCP rather than a shell. Start it in the repo.
With Claude Code:
claude mcp add oak -- oak mcp
The tools are read-only: status, diffs, history, branch triage and review, CI
runs and logs, and findings. oak mcp --allow-write adds
commit, set description, and push. Merging and closing a branch are never
offered, so they stay a deliberate step.
CI on main
An Oak server runs CI natively from workflow files at .oak/workflows/*.yml.
CI runs on main, after a branch merges — never on branch pushes, and it
never holds a merge back. Test locally, merge once you're up to date with
main, and fix main if it breaks. Each workflow file is a service that passes
or fails on its own, and channels publish the newest commit that is good for
the services they wait for. The CLI is the visibility and recovery surface:
oak ci status # each service on main: passing / failing since <commit> / running — exit 0, 1, 3
oak ci runs [--limit N] # recent runs: id, workflow, branch, commit, status, duration
oak ci logs <run-id> # step-by-step logs
oak ci rerun <run-id> # re-dispatch at the same commit, for infra flakes
oak ci cancel RUN_ID --commit HASH --json # exact ordinary push/merge run only
oak ci approve RUN_ID --commit HASH # release a run held because path rules restrict its author
Cancellation requires an explicit run ID and full lowercase commit hash. It rejects manual, protected, release, terminal, moved, and unknown runs before mutation. A successful receipt confirms the control-plane cancellation record; stopping already-running execution remains best effort and is not confirmed.
Working with large monorepos
Two ways to avoid pulling a whole monorepo:
-
Lazy mounts —
oak mount <org>/<repo>puts a working tree on top of the remote and hydrates files on demand (FSKit on macOS, FUSE on Linux, ProjFS on Windows). Best default for very large repos. -
Sparse (partial) clones — Perforce-style, when you want a plain on-disk checkout scoped to a subtree:
oak clone acme/monorepo --path services/api --path libs/shared oak sparse add libs/proto # widen the cone oak sparse disable # back to a full checkoutAdd
--jsonto a named Oak clone for one machine-readable acquisition receipt. It records the requested history and cone, the resulting exact head/manifest, observed object and unique chunk counts, materialization counts, and explicitly unavailable transport/disk measurements. Legacy fallback phases remain visible rather than being folded into a false single-pass claim.Only files under the cone are downloaded and written; the rest of the tree is listed but its content is withheld, and commits carry the out-of-cone paths forward untouched (narrowing never deletes them). The same withhold-content mechanism powers server-side path permissions — directory-level access set on the server as path rules owned by groups (see
oak access,oak ownersandoak group).OAK_ALLOW_PARTIAL_CLONE=1is a separate recovery flag that skips, rather than errors on, blobs a broken server failed to ship.
Every clone first negotiates a bounded metadata integrity profile; merely
being logged in does not trigger object-store probes. If the proof runs out
of its history/tree/path or wall-time budget, the result is inconclusive
(exit 8), not a content failure: Oak never narrows or waives on its own, and
recommends the exact --shallow retry first. When the server issued a
snapshot pin for that inconclusive proof, it also offers the explicit
--allow-unverified-integrity retry, which proceeds without proving
completeness while the pull still verifies transferred hashes. --allow-legacy-scope is the separate, explicit compatibility waiver
for an accessible older server that cannot prove branch/depth/sparse scope.
Use oak doctor --repo ORG/REPO --verify metadata --json for a cheap bounded
diagnostic and the platform-admin oak blob info HASH --repo ORG/REPO --json
for bounded target byte evidence (--depth N --branch NAME selects a wider
explicit history scope).
Building from source
cargo build --workspace # builds oak-core + the oak binary
cargo test -p oakvcs-cli # CLI tests (incl. wiremock HTTP tests)
make build # release build + the CLI release tooling
make release-proof # non-mutating launch/release readiness proof
The CLI depends on oak-core via an in-workspace path, so a plain
cargo build works against the local core/ checkout with no extra setup.
See docs/release-readiness.md for the release
proof and crates.io publish-order checks.
Feedback
oak feedback files a feature request or bug report against Oak from the
terminal and prints back a tracking reference (fb-N). It takes -m, a file,
or stdin, opens $EDITOR with a template when given nothing on a TTY, and
exits rather than blocking when there's no terminal — so an agent can file one
mid-task without stalling:
oak feedback -m "oak diff --print panics on a closed pipe" --json
License
Apache-2.0. See LICENSE.
AI
This repo was written almost entirely using AI with human oversight. If you see anything that needs fixed or would like to contribute, please email [email protected] or reach out on Discord.