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.

CratePathcrates.ioWhat it is
oakvcs-corecore/oakvcs-coreThe 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-clicli/oakvcs-cliThe 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:

PlatformDownload
macOS, Apple Siliconoak-darwin-arm64
macOS, Inteloak-darwin-x86_64
Linux x86_64oak-linux-x86_64
Linux ARM64oak-linux-arm64
Windows x86_64oak-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 checkout
    

    Add --json to 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 owners and oak group). OAK_ALLOW_PARTIAL_CLONE=1 is 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.