CLI reference · wt 0.8.3
The flags below were checked against wt --help and each subcommand's
--help for wt 0.8.3. Run wt <command> --help for anything not shown here.
Status
Per-queue depth, oldest-open age, and the stuck flag. With no queue given, it reports every queue. This is the glanceable health view: green means draining, red means open tickets with no progress.
| -q, --queue | Limit the report to a single queue. Omit to see all of them. |
| --stuck-minutes | Idle threshold, in minutes, before a queue with open tickets is flagged STUCK. |
| --all | Also show archived queues. |
| --json | Machine-readable output for scripts. |
List the workers this CLI started, with their queue, engine, and liveness.
--all also lists dead records that are kept by design.
release gracefully stops selected workers before their next claim.
Run a check; file a ticket into the queue if it fails. A non-zero exit from --cmd
counts as failure, which is how a scheduled sanity check turns into worker-drained work.
| -q, --queue | Queue that receives a ticket on failure. Required. |
| --cmd | Shell command to run; non-zero exit means fail. Required. |
| --title | Ticket title used when the check fails. |
| --note | Ticket note used when the check fails. |
Queues
The recommended queue configuration command. It combines the basic settings with auto-drain policy, so one call sets the engine, worker count, backend, and whether the queue self-staffs.
| -q, --queue | Queue to configure. Omit it to print the live config path. With no setting flags, --json prints the queue config. |
| --auto-drain | on auto-spawns workers when the queue has depth; off is backlog mode. |
| --workers | Desired worker count for this queue. |
| --workers-local-path / --repo-path | Local repo path workers run in. |
| --backend | file (the default JSON queue) or github (GitHub Issues). |
| --github-repo / --github-assignee | Target repo and assignee when the backend is GitHub. |
| --engine | claude (default), codex, kimi, or devin. |
| --model / --effort | Model identifier and reasoning effort for spawned workers. See wt models for approved ids. An empty string clears the override. |
| --codex-transport | How Codex workers run: app-server (default, steerable while working) or exec (one-shot codex exec). |
| --type | Restrict auto-drain workers to a ticket type. |
| --grace-s | Seconds a new ticket is left alone before auto-drain may claim it (default 180); 0 drains immediately. |
| --planner-* / --plan-reviewer-* | Engine and model for the planner and the plan reviewer. By default the reviewer is a different engine family than the builder. |
| --verifier-* / --assessor-* | Engine and model for the verify gate and the post-fix assessor. Same default: a different family than the builder. |
| --gate / --gate-worktree | Queue default acceptance gates (repeatable, ordered): cmd:<command>, verify, review or review:<target>; --gate none clears them. --gate-worktree picks where command gates run off HEAD: fresh (default) or persistent. |
| --post-fix-assessment | on gives every bug that closes as completed an independent six-point assessment (needs a local repo path). |
| --product-gate | on makes workers get a human Ack (wt ack) after a minimal-diagnosis pitch before implementing. |
| --sent-back-release-min | Minutes a verifier-rejected claim may show no progress before it returns to the pool (default 30; 0 disables). |
| --fallback-to-default-worker | on spawns workers on the fallback engine while the queue's engine keeps failing at launch; the queue setting is never changed. off (default) parks the queue. |
| --headroom-dispatch | on checks quota headroom before launching workers and starts them on the engine in the fallback chain whose quota resets soonest. Launch-time only. |
| --notify-events | Comma-separated events a ticket's submitter hears about: claimed, closed, needs_input, awaits_decision. Default is all but claimed; none silences, default restores. Subscribers always get everything. |
| --queue-label | GitHub label marking an issue as this queue's when 2+ queues share a repo (default watchtower:<QUEUE>); * makes it the repo's catch-all (every issue no other queue claims; one per repo); '' resets. |
List the WatchTower-approved model identifiers for one engine: the values
wt config --model and wt spawn --model accept.
antigravity is spawn-only; its Gemini ids carry effort in the suffix, so they take no
--effort.
Bulk-move queues from one model to another after a model bump. Dry run by default: lists every queue whose
effective model (the resolution wt config uses) equals --from, with engine,
auto-drain and open/WIP counts. --to must be approved (exit 1 otherwise); a cross-engine move needs
--engine. Only pinned queues are rewritten; queues inheriting the default move with
--include-default, which rewrites the matching keys in CCC's spawn-defaults.json and prints which.
Warns about open/WIP tickets whose model floor is above the new model and about queues on a policy-blocked model.
unpin clears the explicit model so a queue follows the default.
Compatibility alias for the basic queue settings that predate wt config.
Prefer wt config for new scripts; it accepts --repo-path too.
| -q, --queue | Queue to configure. Required. |
| --repo-path | Local repo the queue's workers operate in. |
| --engine / --model / --effort | Engine, model, and reasoning effort for workers. |
| --desired-workers | How many workers this queue should staff. |
| --backend / --github-repo / --github-assignee | Queue backend and its GitHub target. |
Toggle auto-drain for a queue. on auto-spawns workers and starts the service;
off is backlog mode where tickets accumulate untouched.
| {on,off} | Positional. on = auto-spawn workers; off = backlog mode. |
| QUEUE | Positional queue name, for example CCC or WT. |
| --type | Restrict auto-drain workers to these ticket types (repeatable); omit to clear. |
Enqueue
File a ticket into a queue. The core enqueue primitive: pure by design, with no spawn side effects, so it
is safe to call from automation and agents. The ticket gets a stable ref like MYAPP-1.
| -q, --queue | Destination queue. Required. |
| --title / --note / --text | Ticket title and body text. |
| --url | Attach a source or reference URL. |
| --lane | normal or express priority lane. |
| --type | Item type: bug or feature. |
| --readiness | ready, needs-shaping, needs-spec, or needs-rationale. |
| --priority | p0 (highest) through p4 (lowest). |
| --value / --confidence | Business value and confidence: H, M, or L. |
| --model-floor | Filer's best-guess minimum model this ticket needs (an approved model id from any engine). Empty is fine; never a blocker at filing time. |
| --depth / --budget-min | quick (default) or deep. A deep ticket's claim carries the deep-work brief: evidence first, an options memo, a measured goal, and a budget (default 90 minutes) with a stop rule. |
| --pre-ack | Skip the product gate for this ticket; the decision to build it is already made. |
| --dedupe-key | Stable incident key; atomically reuses an existing ticket in this local queue. |
| --placement | Which machine may run it: mac, cloud, or any. |
| --planner-model / --verifier-model | Override the queue's planner or verifier model for this ticket. |
| --submitter | Addressable target (worker id, @agent name, or session UUID) to notify when the ticket is claimed, closed, or needs input. Defaults to your own session. |
| --after | Not claimable until REF closes as completed (repeatable). |
| --gate / --accept | Per-ticket acceptance gates (override the queue's) and one plain-language acceptance line the verify gate checks. |
| --worker | Worker id to claim under when --claim is set. Defaults to wt-cli-<shell>, stable per terminal. |
| --claim / --run | --claim immediately claims the new ticket so no auto-drain worker picks it up. --run requests a run and dispatches now (like wt run), bypassing grace and auto-drain policy. |
| --group-parent / --children / --group | Plan groups: file a parent that gets one plan for its members and one integration check after they all close, attach open tickets as children (2 or more), or file a ticket as a member of an unsealed group. |
File a ticket and immediately claim it, so it is marked in progress under you in one step.
edit patches fields on an existing ticket, or moves it to another queue in place with
--queue. ls lists a queue's tickets (the default active view is open, in progress, in review, and awaiting answer);
find looks one up by ref across all queues, no -q needed
(--worker marks events you performed as "you").
ready marks a ticket ready for workers and dispatches its queue.
blocked lists tickets parked for a human;
answer answers one and auto-resumes its worker session
(--tid marks it Topic-Is-Done, telling the worker to push and close instead of parking again);
discuss attaches you to the blocked ticket's session interactively
(--print shows the resume command instead of running it).
comment appends a ticket activity comment.
dedup closes exact-duplicate open tickets; preview is the default,
--apply closes them.
Import
Turn a document into queue tickets. It sends the whole document through one Claude reasoning call, infers
explicit and implicit work, chooses ticket-sized units one worker can finish coherently, and preserves
dependency order. Preview is the default; --apply files it.
| FILE | Positional. Markdown or text document to extract tasks from. |
| -q, --queue | Destination queue. Required. |
| --apply | File the inferred tickets. Without it, the command previews only (dry-run). |
| --type | Override the inferred type for every newly filed ticket. |
WATCHTOWER_IMPORT_MODEL to override.
Wait · the signature move
Block until no tickets remain in open status, then optionally run a command.
In-progress, in-review, and awaiting-answer tickets do not keep it waiting. Check those states
separately before deploying or treating all work as complete.
| -q, --queue | Queue to wait on. Required. |
| --timeout | Maximum seconds to block. 0 means forever. |
| --interval | Seconds between depth checks. |
| --cmd | Shell command to run once the queue is drained. |
| --notify-webhook | POST JSON to this URL when the queue drains: the async-reply seam. |
Agent messaging
Push a message to a worker, agent, or session. TARGET is a worker id, @agent name, or session
UUID/prefix; TEXT of - reads the body from stdin (quote-safe for long, multi-line messages).
Undeliverable messages park in the outbox instead of failing.
| --mode | Delivery mode hint; delegate transports honor steer. |
| --no-queue | Fail immediately instead of parking in the outbox. |
| --ttl | Seconds before a queued outbox message expires. |
| --start-new-if-needed | If the target is large and cache-cold, start a new continuation session with this message instead of resuming it, which avoids a full-context cache miss. |
| --from | Claimed sender identity. |
Ask a target and wait for its reply (default 30 s). --notify-webhook returns
immediately and POSTs the answer to your URL when it arrives, mirroring
wt wait --notify-webhook.
spawn launches one ad-hoc one-shot agent on a goal; it reports back to
--report-to via wt send when done.
critique spawns two critique agents from families other than your own
(--family is auto-detected from harness env) so the review is cross-model.
outbox inspects and retries undelivered messages.
agents is the address book: list reachable agents, or name a session UUID.
chat runs multi-agent group chats.
snapshot manages session auto-snapshots taken before prompt-cache expiration.
Interrupt a worker's in-flight turn; the process stays alive. TARGET is a ticket ref (resolved to its claiming worker) or a worker id.
Review and gates
The product gate. When a queue has --product-gate on, a worker pitches a minimal
diagnosis and waits. gated lists the pitches awaiting you.
ack approves one (an optional comment steers the worker).
nack declines it and requires a reason; it parks the ticket in the icebox, or closes it as
Declined with --close.
Tickets that finish go to in_review before they close. accept closes one
and unblocks its dependents; --force accepts while the independent verifier's
verdict is still pending. reject sends it back to open and resumes its worker
with what must change. verdict is how an independent verifier files a pass or
fail.
The post-fix assessment. submit files the assessor's six-point assessment,
show prints its state, run (re)starts the assessor for a closed bug,
resume finishes a half-filed assessment without calling a model, approve releases
follow-ups so workers can claim them, and new files and closes a bug that was fixed without a
ticket, then assesses it.
The plan stage. A planner files a plan for a plan-gated ticket (submit), a reviewer accepts or
rejects it (verdict), the two can discuss, a human can decide a plan
that exhausted its reviews, and the builder blocks on wait until the plan is accepted.
stages supervises planner, verifier, and assessor sessions:
tick runs one pass in the foreground and show prints a ticket's record.
Ticket state
Read-only. Who owns each live ticket, whether it is proven at work, and what the backstop would do.
Say who a blocked ticket is waiting on: a decision only the owner can make, an external actor (name it with
--actor), a dependency (--ref), or a worker.
Take a ticket out of the pool until a data window ends, with no human needed. --until accepts
+90m, +24h, +2d, or an ISO time, at most 7 days out.
Acknowledge a closed ticket's caveat, follow-up, or unresolved chips without rewriting history. With no ref,
-q QUEUE --all bulk-acks a queue; --matching narrows it by resolution text and
--dry-run previews.
Subscriptions
Register a target (worker id, @agent name, or session UUID) to hear about every enqueue, claim,
close, and needs-input event on a queue, not just the tickets it filed itself. Omit the target to list
current subscribers.
Serve
wt serve)Open the night-watch dashboard: a background server plus your browser, on
http://127.0.0.1:8787 by default. It binds localhost only, with same-origin checks.
| --host / --port | Bind address and port. Defaults to 127.0.0.1:8787. |
| --no-open | Ensure the server is up but do not open a browser. |
| --stop | Stop the background dashboard server. |
| --foreground | Run the server in the foreground (blocking; for debugging). |
| --once | Handle one request then exit (for tests). |
Start or stop the background service (watcher plus reconciler plus HTTP API). The first
wt start installs a macOS LaunchAgent so the watcher restarts on login and on crash.
| --interval | Reconciler tick interval in seconds (default 30). |
| --stuck-minutes | Idle threshold before a queue is flagged stuck. |
| --engine | Default engine for spawned workers. |
| --auto-spawn | Auto spawn a worker on a stuck queue that has no live workers. |
| --dry-run | Log what a reconciler tick would do, but do not spawn or stop anything. |
| --host / --port | HTTP API bind host and port (default 127.0.0.1:8787). |
skills symlinks the bundled skills into every installed agent harness
(sync is the default and also runs on install; status inspects,
remove unlinks). uninstall removes the LaunchAgent so the
service stops auto-starting on login.
Store
migrate-store is a one-time, idempotent move from the JSON store to SQLite.
export-json dumps the store as classic {counter, items} JSON, to
stdout or to -o.
Worker protocol
A worker session drains a queue by looping over these. Each is a plain command, so you can drive a queue by hand or watch an autonomous worker do it.
wt claim -q DEMO # claim next open ticket (smart sort: priority + type + age) wt claim -q DEMO DEMO-1 # or claim a specific ticket by ref (--oldest = FIFO; # --type / --readiness filter what you'll take) wt close DEMO-1 --summary "fixed the overlap" --commit <SHA> \ --caveat "only tested on iOS" --follow-up "DEMO-2 tracks regression coverage" wt release DEMO-1 # give up a claim without closing; returns it to open # (--reserve-for WORKER holds it for that worker for --ttl seconds) wt reopen DEMO-1 --reason "regressed" # reopen a closed ticket back to open (no dispatch) # (--resume TEXT reopens, re-claims, and messages the original session) wt block DEMO-1 --question "ship behind a flag?" \ --progress "root cause found; fix drafted" # park for a human decision # (--kind input|rationale|awaiting-client; --wait-on owner|external|dependency|worker) wt defer DEMO-1 --until +24h --reason "need a day of data" # out of the pool until a data window ends
wt close requires --summary
and either a verified --commit <SHA> or explicit --no-code, plus optional
--caveat, --follow-up, and --unresolved. Pass
--enqueue-follow-ups to auto-file the follow-ups as new tickets. Otherwise, each follow-up or unresolved item
must cite a ticket ref. A blocked ticket comes back
through wt answer; releasing a blocked claim is refused without
--force so the open question is not erased.