Method as a system
The method is not in someone's head — it is installed as Skills and read by the agent.
Status: Beta
CommandMate builds the engineering discipline into the workflow: a contract before the work, verification gates after it, evidence throughout. Any coding agent turns your requirement into a verified result.
Vibe Engineering — the AI does the building; the system, not your expertise, guarantees the engineering.
npx commandmate@latest
From install to your first session in 60 seconds.
macOS / Linux / Windows (WSL2) · Node.js v22+ · npm · git · tmux
Four beats, and the same four every time. What makes the result reliable is the loop, not how much software engineering the person driving it happens to carry in their head.
It starts where every task starts: one sentence describing what should be true when this is done. Nothing about the agent, the branch or the tooling yet.
“shout() should return the greeting uppercased.
npm run test:shout currently fails.”
Before the work starts, the sentence is written down as a contract: what may be touched, and which gates decide that it is finished. Two files, both in the repository, both readable by a human.
.commandmate/verify.yaml
version: 1
gates:
- id: unit
command: npm test
timeoutSec: 120
.commandmate/tasks/fix-shout.yaml
title: "shout() uppercases the greeting"
scope:
allow: ["src/greet.js"]
deny: ["test/**", ".commandmate/**"]
verify:
gates: [issue-shout]
success:
requireWorkEvidence: true
requireScopeClean: true
The contract is handed to whichever coding agent you want to use, in a Git worktree of its own. Several tasks can run at once because none of them shares a working directory, and you can watch any of them from a browser.
$ commandmate send wt-shout \
--contract .commandmate/tasks/fix-shout.yaml >task-id.txt
Task created: 4d1f8b2a-6c07-4a5e-9f3b-27ac91e0d4c8
Message sent.
When the agent stops, the gates you declared run for real and the process exit code
is the answer — 0 passed, 20 a gate failed,
21 nothing was actually done. Not the agent's own opinion of its work.
$ commandmate wait wt-shout --verify
GATE work-evidence PASS (commits=0, uncommitted=1)
GATE scope PASS (exit=0, 0.1s)
GATE unit PASS (exit=0, 0.1s)
RESULT passed
$ echo $?
0
The method is not in someone's head — it is installed as Skills and read by the agent.
Gates you declared decide whether the work is done, and the exit code is the verdict.
One worktree and one contract per task, across seven agent CLIs and local models.
When an agent needs you, it reaches you — badge, toast, tab title, push — and you answer from your phone.
Runs 100% locally. No external server, no cloud relay, no account required — the only network traffic is the agent CLI's own API calls.
Two ways in. Take Track A to see it working, Track B once you keep coming back.
Track A
One command, nothing installed first. There is nothing else to type — it runs all four steps below for you.
npx commandmate@latest
Node.js, npm, git and tmux. Stops with an install hint if one is missing.
Repository root, additional browsable directories, port, external access, database path.
Then waits until it actually answers.
At http://localhost:3000, once the server is ready.
Step 2 is first-run only. Run it again later and it goes straight to the UI.
Track B
Track A runs the server out of npm's cache, where a later npx can swap the
files under it. A global install gives a long-running server somewhere stable to live.
npm install -g commandmate
First run only, and skipped entirely if you already have a .env.
commandmate init
Keeps serving after you close the terminal.
commandmate start --daemon
Either track leaves a server running in the background. commandmate status
tells you whether one is up, and commandmate stop shuts it down.
Use a sample repository with two bugs left in on purpose to work through the core of CommandMate in about fifteen minutes. You fork the sample repository before you start, so nothing you do can touch the original repository (upstream). You hand the agent a contract before the work and let the verification gates judge it afterwards, and you read the verdict off the real exit code.
The sample repository — fork this one first:
https://github.com/Kewton/commandmate-tutorial.git
Fork it on GitHub, then paste your fork's URL into
Repositories → Add Repository → Clone URL and follow the
tutorial.
It ships its own .commandmate/verify.yaml and two task contracts, so the
gates are real from the first command. No install, no dependencies.
Twenty seconds each, recorded against a throwaway repository with a stubbed agent. The gates in the first one are executed for real, so the exit codes on screen are the ones that run produced.
The comparison worth drawing is between two ways of working, not between products.
| Dimension | Vibe coding | Vibe Engineering with CommandMate |
|---|---|---|
| What "done" means | The agent says it's done | A verification run says so — exit 0 / 20 / 21 |
| Scope of change | Whatever the agent touched | Declared in the contract, enforced by the scope gate |
| Method | In someone's head |
Installed as Skills from the Catalog (cmate-task-contract,
cmate-verify, …)
|
| Evidence | A chat transcript |
Commits, gate logs, verify history, report metrics
|
| Parallel work | Terminal tabs | One worktree and one contract per task |
| When it stops | You notice, eventually | Waiting is surfaced: badge, toast, tab title, push |
| Which agent | Locked to one | Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity, local models |
The same sessions in your browser, whichever screen you are on.
One command opens a way in and prints a QR code carrying a one-time pairing code. There
is no LAN address to look up, no CM_BIND to widen, and no token to retype
on a phone keyboard.
commandmate remote
Tailscale or cloudflared — one of them has to be installed and usable,
or remote stops on a dependency error. Tailscale Serve is the preferred
route, and stays inside your tailnet.
A Cloudflare Quick Tunnel is a URL on the open internet, so it is created only after
you approve it — --yes when nobody is there to ask. Tailscale being
unusable never publishes you instead.
The pairing code works once and expires in ten minutes by default;
--pairing-expires sets that window. No long-lived token travels in the
QR code.
CM_BIND keeps its 127.0.0.1 default — remote adds one way
in and changes nothing else. commandmate remote stop takes down what
CommandMate opened, and leaves the server up.
Nothing is exposed until you run it, and the session closes itself — eight hours by
default, --expires to change it. commandmate remote status
reports the provider, the URL and what is left of both windows, and Auto-Yes stays off
unless you turn it on.
The Quick Tunnel is a quick way in rather than a permanent address. Every flag, every exit code and the longer-lived Tailscale route are in the CLI operations guide.
npx commandmate@latest