DOCUMENTATION

How CodeRook works

The desktop application, the command line and this website are three doors into the same thing: one account, the same projects, the same rules about what gets sent.

How it works

A project is a folder on your machine connected to a project on your account. A version is everything in that folder at one moment — not a list of edits since last time, but the complete set of files.

That distinction is why restoring is safe. Going back to version 4 does not mean undoing 5 through 12: version 4 already names every file it had, so it can be written out on its own. Nothing depends on the versions around it.

Nothing is sent twice

Files are stored by the digest of their contents, so one that appears in fifty versions is stored once. Saving sends only what the service does not already have.

Your folder stays yours

CodeRook writes the files a version holds and nothing else. Dependencies, local credentials and your git repository are never touched.

It knows what it gave you

The exact copy placed in your folder is remembered, which is how a file you edited is told apart from one left behind by somebody else’s change.

Getting started

  1. Create an account, or sign in with Google or GitHub.
  2. Install the desktop application from the download page, or the command line with npm install --global @coderook/cli. The package is named for the host; the command it installs is cbx.
  3. Point it at a folder — open it in the application, or run cbx sign-in and then cbx status inside it. Either way you are shown what would be sent before anything leaves the machine.
  4. Settle the rules once: what belongs in the project and what does not. cbx ignore --suggest names the dependency folders, virtual environments and build output it can see, and what each is costing you.
  5. Save your first version — the Save button, or cbx submit -m "First pass".

Choosing what gets sent

CodeRook reads .gitignore. Not a format of its own: the same file git already reads, so a project that is set up needs nothing new, and a rule added for one is understood by both.

# .gitignore
node_modules/
__pycache__/
.venv/
*.log
dist/

# bring one thing back out of an ignored folder
!dist/release-notes.md

Nested .gitignore files apply to their own directory downwards, and a ! rule can reach into a folder that is otherwise excluded. Personal exclusions you would rather not share go in .git/info/exclude, which is never uploaded.

Files that look like credentials — .env, .pem, .key — are pointed out before anything is sent, wherever they sit in the tree. They are not silently dropped either: an incomplete project that looked backed up is its own kind of disaster.

A key that gets past that is refused by the service itself, not only by the app you are using — the same answer whether it came from git push, the command line or the website. If you publish one on purpose, everybody outside the project sees that file with the value covered over: same name, same size, same variable names, asterisks where the key was. Only the owner and the project's admins can download it intact, through the Download with secrets button or a signed-in client. The security page sets out who counts, what covering does and does not reach, and how it was tested.

Saving a version

You see every changed file and its diff before anything leaves the machine, and choose which belong in this version. A note is optional; the version is complete either way.

cbx status                  # what is here that is not saved
cbx submit -m "First pass"  # send it as a version

If the connection drops after the service has taken the version but before your machine hears so, running the same command again finds the version that was made rather than making a second one.

Catching up

get brings your folder up to date. It writes the files the version changed and leaves everything else exactly as it is — including work you have not saved yet.

If a file you are editing would be written over, it stops and names it rather than proceeding. Saving first is the way through that loses nothing.

cbx get             # bring this folder up to date
cbx get --replace   # exact copy, discarding local changes

When two people save at once

Nobody is told to try again, and nobody’s upload is thrown away. What happens depends only on whether the two changes actually disagree.

Different files

Combined. Neither of you is asked anything.

Same file, different parts

Combined line by line. Still nobody is asked.

The same lines

Your upload is kept as a merge and the project is left alone until somebody decides. Both sides exist the whole time; neither is overwritten while the question is open.

cbx merges            # uploads waiting on a decision
cbx merge M-1         # look at one
cbx merge M-1 --mine  # keep your side, or --theirs, or --both

On the website and in the desktop application a waiting merge shows both sides of every disagreeing file, line by line, with the agreement between them folded away. Picking a side is one answer; the other is to write the file yourself, which is the right one whenever the result is some of both.

Before a long upload the command line asks whether it is walking into one of these, so you hear about it in the first second rather than after everything has been sent.

The command line

The same engine as the desktop application — the same scanner, the same rules, the same uploads — with a terminal in front of it. A project moved by one is understood by the other.

The command is cbx, and the split it names is the one git and GitHub have. CBX is the engine: content-defined chunking, whole-snapshot versions, the .cbx format. CodeRook is the host it talks to. So you install a package called @coderook/cli and the thing you type is cbx — the same way installing git does not give you a command called GitHub.

npm install --global @coderook/cli

cbx sign-in
cbx projects           # everything on your account
cbx clone my-project   # fetch one into a new folder
cbx doctor             # check the service, config and sign-in

coderook still works as another name for the same program, so anything written before the rename keeps running.

Set CODEROOK_TOKEN and it needs nothing on disk, which is what makes it usable from continuous integration.

Lines of work are here too, so a terminal is not stuck saving to the default. Switching says where the next save goes and nothing else — no files move and nothing is fetched, so run cbx get afterwards to bring that line’s files into the folder.

cbx tracks              # the lines this project has
cbx track spike --new   # start one and switch to it
cbx track main          # switch back
cbx submit --track spike -m "Try the other encoder"

The line is remembered per folder rather than per account, so two checkouts of one project can sit on different lines. A name that does not exist is refused rather than created quietly, because a line called mian puts work somewhere nobody will look for it.

It will also tell you what a folder is carrying that probably is not the work — dependency directories, virtual environments, build output — with how much each is costing you. The desktop offers this when a folder is added; the command line asks for it.

cbx ignore --suggest           # list them
cbx ignore --suggest --apply  # add the confident ones

An issue can be filed with its labels and the save it is about in one go. “It broke” and “it broke in v41” are different reports, and the second is the one somebody can act on.

cbx issues                                    # what is open
cbx issues --new "Installer will not run" \
  --labels bug,windows --version 41

A project can also tell something else when things happen here — a build box, a chat room, a status page. The signing secret is made by the service and shown once, when the hook is added; no route hands it back afterwards, so check the signature on what arrives and nobody else can post to your endpoint.

cbx hooks                                     # where it tells
cbx hooks --add https://example.com/coderook
cbx hooks --add https://example.com/builds \
  --events version.published

Releases and downloads

A release is not a separate thing you create. Every save is a commit; giving one a name makes it a version, and only versions are offered to anybody outside the project. So publishing is one command, and it does not upload anything — the files are already there.

cbx release v1.0              # name the newest save
cbx notes 41 --edit           # what changed, in your editor
cbx releases                  # what has been published

A version can also carry files that were never in the project: an installer, a signed binary, a changelog. Attach them from wherever they were built.

cbx attach ./release/Installer-1.0.exe
cbx attach ./release/app.dmg 41   # onto version 41

Large files go up in parts, so a 95 MB installer works the same way a text file does. Attaching to a commit is not publishing: the download exists and nobody outside the project can reach it until that commit is named.

An action that keeps files can do this itself. Turn it on once and every passing run hands what it built to the version it ran against.

cbx actions                        # what each one keeps
cbx actions --ship "Windows installer"

Worth being deliberate about, because attaching is publishing: anything an action ships onto a public version is a download anybody can take, from the moment the run passes. It is off until you say otherwise, and the same switch sits on the Actions screen for anyone who would rather click it.

If you already use git

Installing the command line also installs a git remote helper, so git talks to CodeRook directly — both ways. Nothing here is a CodeRook command wearing git’s clothes: the operations are the same ones cbx performs, reached from git.

git clone coderook://my-project
git remote add coderook coderook://my-project
git push coderook main
git fetch

Each commit becomes a version, oldest first, keeping its message. Later pushes send only what is new. Branches become lines, and a branch pushed for the first time starts from the commit it forked at rather than from wherever the project happens to be. Tags become releases — a release is a version with a name on it, which is what a tag is too.

Cloning reverses it, and works on any project — including one that has never been near git. A project built entirely from the desktop app clones into an ordinary git history, with the messages, dates and authors it was saved with.

It exists so that every editor’s built-in git panel works with CodeRook without a plugin. If you are not already living in git, cbx push is the simpler tool and this is not an upgrade on it.

The same operation, said either way

Eleven of the commands have a git equivalent. These are the same operation reached from two places, not two things that resemble each other.

CodeRookgit
cbx submitgit push coderook main
cbx getgit pull
cbx clone ledgergit clone coderook://ledger
cbx statusgit status
cbx versionsgit log
cbx tracksgit branch
cbx track maingit checkout main
cbx promote 41 --name v1.0git tag -a v1.0
cbx releasesgit tag -l
cbx notes 41git notes --ref=coderook show
cbx notes 41 --editgit notes --ref=coderook edit

What has no git equivalent

Most of the command line, and for two different reasons worth keeping apart.

Git never had the idea. Issues, labels, collaborators, watching, tokens, automations and their runs, projects themselves. These are the things a forge grew around git rather than anything git does — on GitHub you would reach for gh, not git. Git is a version control tool; deciding who may read something is a different product.

CodeRook has an idea git does not. This set is the more interesting one. cbx mark hides, pins or labels a single save, and git has no per-commit state at all beyond the commit. cbx held and cbx review are a save waiting on somebody’s approval, which on GitHub is a pull request and in git is nothing. cbx take-down removes a published version’s files while its row stays; git cannot do that without rewriting history and breaking every clone. And cbx undo looks like git reset but is not — reset is a local opinion, and this is a published statement about where the project stands.

So git covers moving files and naming versions. Everything about deciding — what is offered, what is held back, who can see it, what is wrong with it — is CodeRook’s, and that is most of what the command line is for.

What it will not do, said here rather than left to be discovered: a push that is not a fast-forward is refused before anything is uploaded, so you pull and merge in git as you would anywhere; force pushes and branch deletion are refused, because a published version cannot be unpublished; submodules are skipped and named; and the executable bit is not carried, so a script cloned back needs chmod +x. A round trip returns the same files, not the same commit ids — a commit id covers its author and timestamps, and CodeRook records who published a version rather than the original stamps.

Claude Code and Codex

One command, and Claude Code knows what CodeRook is and how to drive it. Run it in a terminal, not inside Claude Code — it is the command line writing a file that Claude Code reads afterwards.

$ cbx skill

It writes ~/.claude/skills/coderook/SKILL.md, and from then on every project on that machine has it. Inside Claude Code the skill is called /coderook, not cbx cbx is the command line, and the skill is the thing that teaches Claude how to use it.

After that you ask for what you want in ordinary words — save this to CodeRook, what have I changed?, what versions does this project have? — and it works out which commands to run. Calling it by name with /coderook works too.

cbx skill --project writes it beside your code instead of into your home folder, so it travels with the repository and everybody who clones it has it as well.

Sign in once per machine with cbx sign-in, or set CODEROOK_TOKEN in automation. It will not save anything without asking first, and it never deletes.

Or install it as a plugin

If you would rather not install the command line first, CodeRook publishes a plugin marketplace of its own. These two go inside Claude Code — they start with a slash because that is where they are typed, unlike cbx skill above.

/plugin marketplace add https://coderook.com/marketplace.json
/plugin install coderook@coderook

That fetches the same package and brings the skill with it. The marketplace is a plain file on this site rather than a git repository — there is nothing to clone, and no second account anywhere. A plugin install puts the package in Claude Code’s own folder rather than on your PATH; the skill handles that by falling back to npx, but a global install is quicker if you run commands yourself too.

A structured connection instead

The skill teaches Claude the command line, which needs no configuration at all. If you would rather it had structured tools there is an MCP server as well — and that is what Codex uses, since it takes integrations that way.

# Claude Code
claude mcp add --scope user coderook -- npx -y @coderook/cli mcp

# Codex, in ~/.codex/config.toml
[mcp_servers.coderook]
command = "npx"
args = ["-y", "@coderook/cli", "mcp"]

It offers five things and every one of them reads: your projects, a project’s versions, the files in a version, one file’s contents at a version, and what has changed in a local folder. It cannot save a version, delete anything, or sign in or out — an assistant that goes wrong can waste your time but not your work. A project whose owner has turned off machine reading is refused, which is the same switch the AI page describes.

Bundles

A .cbx bundle is a whole project as a single file: every version, every file, deduplicated and compressed. It is how you move a project onto a machine that is not online, hand it to somebody, or keep a copy somewhere that is not us.

cbx bundle . my-project.cbx
cbx inspect my-project.cbx   # what is inside, without unpacking
cbx unbundle my-project.cbx ./restored