CLI reference
Every command and flag of the wrktr CLI, as wrktr <command> --help describes them.
Global flags
Section titled “Global flags”Every command takes these, before or after the subcommand.
| Flag | |
|---|---|
--project <org>/<name> |
Act on that project on wrktr instead of the clone you’re in. No clone is needed, so name the branch too (--branch, or the command’s branch argument). Commands that act on this machine or your account (login, whoami, token, init, clone, branch new, branch rm, branch ls without --all, skill, daemon) refuse it. |
--json |
Print the result as JSON on stdout, and a failure as JSON on stderr. See JSON output. |
--help, -h |
Help for any command. |
--version, -v |
The CLI’s version and build. |
--log-level <level> |
all, trace, debug, info, warn, error, fatal or none. |
--completions <shell> |
Print a completion script for bash, zsh, fish or sh. |
--wizard |
Build a command interactively. |
Commands
Section titled “Commands”Where a command takes a branch and you leave it out, it uses the branch of the worktree you’re standing in.
Account
Section titled “Account”wrktr setup [<org>/<project>] [<directory>]
Section titled “wrktr setup [<org>/<project>] [<directory>]”Everything a machine needs to work the wrktr way, in one command, and safe to run again: each step it finds done, it skips.
- Signs in (
wrktr login), unless this machine is signed in and its token still works. - Runs the daemon as a login service (
wrktr daemon install), or moves the service to this CLI’s build if it’s on an older one. A daemon you run by hand is left alone. The service is macOS-only; elsewhere it says to runwrktr daemon. - Installs the agent skill (
wrktr skill install). - Given a project, gets you a copy to work in: a clone if it’s yours (one of your organizations’, or a fork you
made before), otherwise a fork into your personal organization (
wrktr fork), cloned into<directory>(the project’s name by default).
wrktr setup # just the machinewrktr setup wrktr/starter # the machine, and your own fork of the starter in ./starterwrktr login
Section titled “wrktr login”Sign this machine in. By default it shows a code and opens the browser to approve it; the token it receives is
saved in ~/.wrktr/config.json, readable only by you.
| Flag | |
|---|---|
--env <prod|dev> |
Which wrktr to sign in to (default prod). Use a separate WRKTR_HOME per environment. |
--api <url> |
The API’s base URL (overrides --env). |
--token <token> |
Use an existing access token, or an op:// 1Password reference, instead of the browser. |
wrktr whoami
Section titled “wrktr whoami”Who the CLI acts as, and the organizations they belong to with their role in each.
wrktr token ls
Section titled “wrktr token ls”Your access tokens: name, prefix, when each was created and last used, and when it expires. Never the values.
wrktr token create --name <name>
Section titled “wrktr token create --name <name>”Mint an access token for CI or another agent. It opens the browser so you can approve it (the page shows
<name>), then prints the token once on stdout, alone, so wrktr token create --name ci | pbcopy captures just
the token. Use it as WRKTR_TOKEN.
wrktr token revoke <id>
Section titled “wrktr token revoke <id>”Revoke a token. Whatever uses it stops working at once. <id> can be the start of an id from token ls.
Projects
Section titled “Projects”wrktr init
Section titled “wrktr init”Create a wrktr project for the repo you’re in and push it, or link the repo to an existing one. It registers the
repo with the daemon and sets up wrktr credential so plain git works with
the remote.
| Flag | |
|---|---|
--name <name> |
The project’s name (defaults to the repo folder’s name). |
--org <org> |
The organization to put it in (defaults to the one it’s linked to, or your own). |
wrktr clone <org>/<project> [<directory>]
Section titled “wrktr clone <org>/<project> [<directory>]”Clone a project (into <directory>, by default the project’s name) and register it with the daemon. Plain git
works in it from then on (see wrktr credential).
wrktr fork <org>/<project> [<directory>]
Section titled “wrktr fork <org>/<project> [<directory>]”Fork a project you can read (a public one, or one of your organizations’) into an organization of yours, by default
your personal one, then clone the fork like wrktr clone does. The fork is a new private project with a copy of the
source’s default branch; it remembers where it came from, and project show names it. The clone has the source as
an upstream remote, so git pull upstream main brings in its later changes.
--org <org>: the organization to fork into.--name <name>: the fork’s name, if not the source’s (needed when that name is taken there).--no-clone: only make the fork on wrktr.
wrktr credential <org>/<project> get
Section titled “wrktr credential <org>/<project> get”git’s credential helper for a wrktr remote: you don’t run it, git does. The remote only takes short-lived tokens,
so instead of a saved password, init and clone set this in the repo’s .git/config, for the remote’s URL only:
[credential "https://…/git/<namespace>/<project>.git"] helper = helper = !wrktr credential <org>/<project>Then git pull, git fetch and git push (and your editor’s git) work as they do anywhere else: each time git
needs to authenticate, it gets a fresh token minted for you. The empty helper = keeps a global helper (such as
the macOS keychain) from storing a token that’s about to expire. store and erase do nothing. Repos set up
before this get it the next time the daemon starts. When you’re not signed in, git fails with the reason instead of
asking for a password.
wrktr project ls [<org>]
Section titled “wrktr project ls [<org>]”Projects, with their default branch and when they last changed: one organization’s, or by default every one you belong to.
wrktr project show [<org>/<name>]
Section titled “wrktr project show [<org>/<name>]”A project: who can see it, its default branch, last push, git remote and id. Defaults to the clone you’re in, or --project.
wrktr project create <org>/<name>
Section titled “wrktr project create <org>/<name>”Create a project on wrktr without a local repo (for one you have locally, use init).
| Flag | |
|---|---|
--import <url> |
Start it as a copy of an HTTPS git remote, such as a GitHub repo, instead of empty. |
--description <text> |
What the project is. |
wrktr project visibility public|private
Section titled “wrktr project visibility public|private”Make the project public, so anyone can read its code, history, branches, reviews and CI, signed in or not, or private
again (its organization’s members only). Owners only. Only members can ever change a project; someone outside it who
runs wrktr clone gets a read-only copy that git pull keeps current and the daemon leaves alone.
Organizations
Section titled “Organizations”People are named by email. <org> defaults to the organization of the clone you’re in, or of --project.
wrktr org ls
Section titled “wrktr org ls”The organizations you belong to, and your role in each.
wrktr org show [<org>]
Section titled “wrktr org show [<org>]”An organization: its name, your role, and its projects.
wrktr org create <slug> --name <name>
Section titled “wrktr org create <slug> --name <name>”Create an organization; you become its owner. <slug> is its name in URLs and on the CLI.
wrktr org rename [<org>] --name <name>
Section titled “wrktr org rename [<org>] --name <name>”Change an organization’s display name (owners only; its slug stays).
wrktr org members [<org>]
Section titled “wrktr org members [<org>]”Its members with their roles, and pending invites.
wrktr org add [<org>] <email>
Section titled “wrktr org add [<org>] <email>”Add someone (owners only). If they have an account they join at once; otherwise they’re invited and join when they
first sign in with that email. --role <member|owner> (default member).
wrktr org role [<org>] <email> <owner|member>
Section titled “wrktr org role [<org>] <email> <owner|member>”Change a member’s role (owners only). An organization always keeps at least one owner.
wrktr org remove [<org>] <email>
Section titled “wrktr org remove [<org>] <email>”Remove a member, or cancel a pending invite to that email. Owners remove anyone; you can remove yourself to leave.
Branches
Section titled “Branches”wrktr branch new <name>
Section titled “wrktr branch new <name>”Create a branch in its own worktree under .wrktr/worktrees/<name>, copy the files listed in wrktr.json copy
into it, run its install command, and push it. The daemon keeps it in sync from then on. A name used before is
reused only if that branch is fully merged.
It starts from the default branch as wrktr has it: the latest is fetched first, so a local copy that fell behind is never the base (and is fast-forwarded when nothing has it checked out). Offline, it starts from the local copy.
| Flag | |
|---|---|
--from <ref> |
Where to start it (defaults to the latest default branch). |
--experiment |
A spike or prototype: it stays in progress and never lands. |
wrktr branch ls
Section titled “wrktr branch ls”The branches that have a worktree on this machine. With --all, every branch in progress on wrktr instead (its
head, state and when it last moved, newest first), from anywhere: it takes --project.
| Flag | |
|---|---|
--all |
List the branches on wrktr, not the worktrees here. |
--landed |
With --all, include branches that landed. |
--closed |
With --all, include branches that were closed. |
wrktr branch show [<name>]
Section titled “wrktr branch show [<name>]”What a branch does: the review agent’s description of it (a title, a summary, the changes by area, risks and how to check it), its head and its state. The description follows the branch as it moves; it says so when it was written for an older head.
wrktr branch rm <name>
Section titled “wrktr branch rm <name>”Remove a branch’s worktree. Alias: wrktr branch remove.
| Flag | |
|---|---|
--force |
Remove it even with uncommitted changes (they’re lost). |
--delete |
Also delete the branch, on wrktr and locally. Its review history stays. |
wrktr branch experiment [<name>]
Section titled “wrktr branch experiment [<name>]”Mark a branch as an experiment that never lands. --off lets it land again.
wrktr branch close [<name>]
Section titled “wrktr branch close [<name>]”Close a branch without landing it (a spike, an abandoned approach). Its agents and checks stop; its history and reviews stay.
wrktr branch reopen [<name>]
Section titled “wrktr branch reopen [<name>]”Reopen a closed branch.
Read a project’s history and changes from wrktr, no clone needed.
wrktr log [<ref>]
Section titled “wrktr log [<ref>]”Commits, newest first: short sha, date, author and subject. <ref> is a branch or a commit; it defaults to the
worktree’s branch, or the default branch outside a clone. --limit <n> for how many (default 20).
wrktr diff [<branch>]
Section titled “wrktr diff [<branch>]”What a branch changes against its base: by default a stat, one line per file (Added, Modified, Deleted,
+added -deleted lines), then the totals.
| Flag | |
|---|---|
--patch, -p |
Every file’s changes as a unified diff, like git diff. |
--file <path> |
Only this file’s changes, as a unified diff. |
--base <branch> |
Compare against this branch (default: the default branch). |
Where a branch stands
Section titled “Where a branch stands”wrktr status
Section titled “wrktr status”The branch’s head (and whether this worktree has commits not pushed yet), its state (in progress, landing when
ready, landed, closed, an experiment), its checks, the review agent’s verdict, open threads, and whether it
conflicts with the default branch or the daemon can’t sync it. Once it has landed, where the land is deployed:
each environment, its url and run when what’s live there has it (and whether the url serves it, for an environment
with verify), or that it isn’t there yet.
dev live at https://dev.example.com (run #4) · serving production not yet: run #3 (125fa7d) is live, from before it| Flag | |
|---|---|
--branch <name> |
The branch. |
--watch |
Refresh every 10 seconds. With --json, prints one JSON line per refresh. |
wrktr feedback show
Section titled “wrktr feedback show”The branch’s open reviews, their threads and failing checks: what an agent works through. --branch <name> for
another branch.
wrktr feedback reply <id> <body>
Section titled “wrktr feedback reply <id> <body>”Reply to a review thread, as the agent: what you did, or why not. --branch <name> for another branch.
wrktr feedback resolve <id>
Section titled “wrktr feedback resolve <id>”Mark a thread resolved. --branch <name> for another branch.
Reviews
Section titled “Reviews”wrktr review ls <branch>
Section titled “wrktr review ls <branch>”A branch’s reviews, newest first.
wrktr review submit <branch>
Section titled “wrktr review submit <branch>”Review a branch, yours or another agent’s: a summary, a verdict and line comments, in one go. Line numbers refer to the branch’s head.
| Flag | |
|---|---|
--verdict <approve|changes|comment> |
Approve, request changes, or leave notes without a verdict. |
--summary <markdown> |
What you found. |
--comments <file.json> |
Line comments: [{"path": "src/a.ts", "line": 12, "body": "..."}], or {"comments": [...], "notes": ["..."]} to add points that aren’t about one line. |
wrktr review dismiss <branch> <id>
Section titled “wrktr review dismiss <branch> <id>”Set a review aside so it no longer counts. <id> can be the start of an id from review ls.
wrktr review request [<branch>]
Section titled “wrktr review request [<branch>]”Ask the review agent to review the branch’s head now, replacing a review of it. It reviews by itself after each push once checks pass; this is for a review that failed, or a fresh look at the same head.
Each push runs the checks in wrktr.json ci. The review agent reads their results, and land waits for the
required ones to pass.
wrktr ci show [<run>]
Section titled “wrktr ci show [<run>]”A CI run: each check’s state, time and notes (optional, cached, exit code, a retry), and the last lines of the
ones that failed. Without <run>, the branch head’s run. <run> can be the start of an id from ci runs.
| Flag | |
|---|---|
--branch <name> |
The branch. |
--wait |
Wait until the head’s run is over, then exit 1 unless it passed: wrktr ci show --wait && wrktr land. |
--timeout <seconds> |
With --wait, give up after this long (default 1800), exiting 1. |
wrktr ci runs
Section titled “wrktr ci runs”The project’s CI runs, newest first: status, branch, commit, how long each took. --branch <name> for one
branch’s; --limit <n> for how many (default 10).
wrktr ci log <check>
Section titled “wrktr ci log <check>”A check’s full log, as stored when it finished (ci show prints only the last lines of a failed one). Defaults
to the branch head’s run: --run <id> for another, --branch <name> for another branch’s head.
wrktr ci rerun
Section titled “wrktr ci rerun”Run the branch head’s checks again, ignoring results reused from an identical tree (for a flaky check, or one
that depends on something outside the repo). --branch <name> for another branch.
Landing
Section titled “Landing”wrktr land [<branch>]
Section titled “wrktr land [<branch>]”Land a branch on the default branch with a merge commit, made by the server. It lands only if checks pass, the
review agent approved the current head and no blocking thread is open (nits never block); otherwise it says
what’s missing. Run from the branch’s worktree, it refuses uncommitted changes and a head the daemon hasn’t
pushed yet. After it lands, its on: land environments deploy it; wrktr env wait dev waits for that, and
wrktr status shows every run that shipped it.
| Flag | |
|---|---|
--when-ready |
Don’t land now: the server lands it (as you) as soon as it’s ready. Nothing has to keep running. |
--cancel |
Stop waiting to land it (undoes --when-ready). |
--force |
Land even though checks, threads or the review say it isn’t ready. |
--rm |
Remove the branch’s worktree after landing, if it has no uncommitted changes. |
Deploys
Section titled “Deploys”Environments are declared in wrktr.json under environments. An on: land environment deploys every land by
itself; an on: promote one deploys the commit someone promotes.
An environment whose secrets aren’t all set on the project isn’t set up: a land doesn’t run it, and promoting or
re-running it is refused, with what’s missing and wrktr secret set <name> to fix it. wrktr env ls and the
Environments page show it as not set up (gray, not a failed deploy); a fork starts that way, since secrets aren’t
copied. Once the secrets are set, the next land deploys it.
Every run’s steps get what they deploy as WRKTR_PROJECT, WRKTR_ENVIRONMENT, WRKTR_COMMIT, WRKTR_RUN,
WRKTR_TRIGGER and WRKTR_URL, for deploy scripts that want them.
Every Workers deploy says what it is. A run’s requests to the Cloudflare API go through wrktr’s deploy gateway,
which adds a small manifest to every Worker the run uploads, as a static asset at /.well-known/wrktr.json. For a
public project:
{ "project": "acme/web", "environment": "dev", "commit": "94b562e5c0d1a2b3c4d5e6f708192a3b4c5d6e7f", "run": 4, "trigger": "land", "deployedAt": "2026-10-13T17:05:12.000Z", "previous": { "commit": "5f3a1c0e9b8d7a6f5e4d3c2b1a0f9e8d7c6b5a49", "run": 3 }, "promotedFrom": null, "branches": ["copy-hex", "lock-colors"], "checks": { "ci": "passed", "review": "approved" }, "links": { "project": "https://wrktr.com/acme/web", "run": "https://wrktr.com/acme/web/-/environments/dev/runs/4", "compare": "https://wrktr.com/acme/web/main/commits" }}| Field | What it is |
|---|---|
previous |
The environment’s run that was live before this one (it ships previous.commit..commit), or null |
promotedFrom |
For a promotion or rollback, the run of the from environment that passed this commit; else null |
branches |
The branches landed between previous.commit and commit, oldest first ([] when it can’t tell) |
checks |
The deployed commit’s landing: its CI run and its review (approved, changes, commented); null if it wasn’t a land |
links.compare |
The default branch’s commits (wrktr has no compare page yet; links.run lists what the run shipped) |
A private project’s site serves only environment, commit and run: no project name, links, branches or
checks. Neither ever has people, commit messages, branch titles, review text, Cloudflare account or script names,
or secret names. The Worker version each run uploaded, and its compatibility date, are in the run (wrktr env show,
the API) rather than the file: Cloudflare names a version only after the assets, the manifest among them, are up.
Nothing to configure: it rides along on the assets upload your deploy already makes (a Worker without assets gets a
set holding just this file), so any bundler or framework works. Static assets are matched before your Worker runs, so
it’s served ahead of your own routes; a Worker with run_worker_first sees the request first and decides. If
anything about an upload isn’t what the gateway expects, it leaves the upload exactly as it was.
After a run passes, wrktr checks each environment with a url: the url must serve the manifest of the run’s commit,
retrying for about a minute while the edge catches up, and Cloudflare must have the Worker versions the run uploaded
deployed (asked with the same secret the deploy used). The run is then serving, not serving (with what the url
or Cloudflare has instead), or unverified when the url serves no manifest and Cloudflare can’t be asked (a deploy
that didn’t go through a Workers upload), which is gray, not red. wrktr env ls, wrktr env show, wrktr status
and the Environments page show which. "verify": { "check": "/health" } also requires a 2xx there. Nothing secret
or personal goes in the manifest; "verify": false on an environment turns off both the manifest and the check
(do that for one whose url isn’t the deployed site, like a package page, or to keep a private project’s commits
off its site).
wrktr env ls
Section titled “wrktr env ls”The project’s environments: what’s live in each, what’s running, and what a promotion would ship. Each one’s url is
its address; --json gives it to agents, who can check a landed change on dev there.
wrktr env runs <environment>
Section titled “wrktr env runs <environment>”An environment’s runs, newest first. --limit <n> for how many (default 10).
wrktr env show <environment> <run>
Section titled “wrktr env show <environment> <run>”One run: every step (done or not) with its command and state, the last lines of a failed step’s log, and the commits it ships.
wrktr env logs <environment> <run> [<step>]
Section titled “wrktr env logs <environment> <run> [<step>]”A run’s step logs, in order (or only <step>): a finished step’s full stored log, and what a running step has
printed so far. --json gives every step’s log in one result.
| Flag | |
|---|---|
--follow, -f |
Keep printing as the run goes, step after step; when it ends, exit 1 unless it passed. Not with --json. |
wrktr env wait <environment>
Section titled “wrktr env wait <environment>”Wait for a landed branch’s deploy to an environment, then say how it went: exit 0 once it’s live (serving, if
the environment checks its url, or replaced by a newer run that still has it), 1 if it didn’t go out, isn’t
served or was rolled back, 2 if the environment isn’t set up. It prints the url and what the site serves there
(/.well-known/wrktr.json: its commit, run and branches). The step after wrktr land --when-ready: wait, then open
the url and check the change.
| Flag | |
|---|---|
--branch <name> |
The landed branch (default: the current worktree’s) |
--commit <sha> |
A commit of the default branch (the full 40 characters), instead |
--timeout <secs> |
How long to wait before giving up with 1 (default 900) |
wrktr env promote <environment> [<commit>]
Section titled “wrktr env promote <environment> [<commit>]”Deploy a commit to a promote environment: by default what its from environment has live. The commit must be
the full 40 characters. An older commit than what’s live is a rollback.
wrktr env rerun <environment> <run>
Section titled “wrktr env rerun <environment> <run>”Run an environment’s newest run again, once it’s over.
wrktr env cancel <environment> <run>
Section titled “wrktr env cancel <environment> <run>”Stop a queued or running run.
Secrets
Section titled “Secrets”Values an environment’s steps use, listed under environments.<name>.secrets in wrktr.json. They’re stored
encrypted and only reach a deploy while it runs.
wrktr secret set <name>
Section titled “wrktr secret set <name>”Set a secret from stdin, never from the command line (so it isn’t in your shell history): pbpaste | wrktr secret set CLOUDFLARE_API_TOKEN. Owners only. Names are capitals, digits and _, starting with a letter.
wrktr secret ls
Section titled “wrktr secret ls”The project’s secrets: names, who set each and when. Never the values.
wrktr secret rm <name>
Section titled “wrktr secret rm <name>”Remove a secret. Owners only.
The daemon
Section titled “The daemon”The daemon keeps every worktree of every registered repo in sync: it commits after a quiet moment, pushes, merges the default branch in, and writes the files agents read.
wrktr daemon
Section titled “wrktr daemon”Run it in the foreground.
| Flag | |
|---|---|
--quiet-ms <ms> |
Commit after this long without file changes (overrides wrktr.json; default 30000). |
--poll-ms <ms> |
How often to check the remote (default 5000). |
wrktr daemon install / upgrade / restart / uninstall
Section titled “wrktr daemon install / upgrade / restart / uninstall”Run it as a login service from a stable copy of the CLI; move the service to this CLI’s build and restart it;
restart it; stop it and remove it. The service is a macOS LaunchAgent; elsewhere, run wrktr daemon under your
own supervisor (systemd, a container’s entrypoint).
wrktr daemon status
Section titled “wrktr daemon status”What the running daemon is syncing, repo by repo and worktree by worktree, with any errors.
wrktr daemon logs
Section titled “wrktr daemon logs”The service’s log. --follow (-f) keeps printing; --lines <n> (-n) for how many lines (default 50).
Agent skill
Section titled “Agent skill”wrktr skill install
Section titled “wrktr skill install”Install the wrktr skill, which teaches coding agents (Claude Code and others) to work the wrktr way. --dir <path> for another skills directory (defaults to ~/.claude/skills and ~/.agents/skills).
wrktr skill show
Section titled “wrktr skill show”Print the skill (SKILL.md).
JSON output and exit codes
Section titled “JSON output and exit codes”With --json:
- stdout carries exactly one JSON value: the command’s result. Progress lines, and the output of a new
worktree’s
installcommand, go to stderr instead.status --watch --jsonis the exception: one JSON value per line, one line per refresh.wrktr daemon(in the foreground) andwrktr daemon logsstream, so they refuse--json. - A failure prints
{"error": {"tag": "...", "message": "..."}}on stderr.tagnames the kind of failure when there is one (ProjectNotFound,Unauthorized,InvalidProjectFlag,ProjectFlagNotAllowed,JsonNotSupported, …).
Exit codes: 0 when the command did what it was asked, 1 when it didn’t (including a refusal, such as land
when the branch isn’t ready). Act on the exit code, not the wording.
wrktr status --project acme/api --branch fix-login --json | jq -r '.review.verdict'wrktr land fix-login --project acme/api --json || echo "not landed yet"Environment variables
Section titled “Environment variables”| Variable | |
|---|---|
WRKTR_TOKEN |
An access token. When set, the CLI uses it instead of ~/.wrktr/config.json, so no login is needed. |
WRKTR_API_URL |
The API to use with WRKTR_TOKEN (default https://api.wrktr.com). |
WRKTR_HOME |
Where the CLI keeps its config, state and the daemon’s files (default ~/.wrktr). Use one per wrktr environment. |
WRKTR_DEBUG |
Set to 1 to print a failure’s full cause instead of one line. |
WRKTR_INSTALL_DIR, WRKTR_VERSION |
For the install script: where to put the binary, and which release. |
| File | |
|---|---|
~/.wrktr/config.json |
The API and the access token (or an op:// reference), written by login. |
wrktr.json |
At the repo root, committed. copy: gitignored files to copy into each new worktree (such as .env). install: a command run in each new worktree. quietMs: how long the daemon waits before committing. maxFileBytes: files larger than this are never committed. ci: the checks each push runs. environments: where the project deploys. |
.wrktr/worktrees/<branch>/ |
Each branch’s worktree. .wrktr/ is kept out of git. |
.wrktr/FEEDBACK.md |
In a worktree: the branch’s open review threads and failing checks. |
.wrktr/BEHIND.md |
Merging the default branch in conflicts: what to do. |
.wrktr/DAEMON.md |
The daemon can’t sync this worktree: why. |
.wrktr/CONFLICT.json |
A rebase onto the remote stopped on conflicts: resolve them, then git rebase --continue. |