CLI reference  ·  wt 0.8.3

Every command, every flag.

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

wt status

wt status [-q QUEUE] [--stuck-minutes N] [--all] [--json]

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, --queueLimit the report to a single queue. Omit to see all of them.
--stuck-minutesIdle threshold, in minutes, before a queue with open tickets is flagged STUCK.
--allAlso show archived queues.
--jsonMachine-readable output for scripts.

wt workers

wt workers [--json] [--all] wt workers release ...

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.

wt monitor

wt monitor -q QUEUE --cmd CMD [--title TITLE] [--note NOTE]

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, --queueQueue that receives a ticket on failure. Required.
--cmdShell command to run; non-zero exit means fail. Required.
--titleTicket title used when the check fails.
--noteTicket note used when the check fails.

Queues

wt config

wt config -q QUEUE [--auto-drain {on,off}] [--workers N] [--workers-local-path PATH] [--backend {file,github}] [--github-repo REPO] [--github-assignee WHO] [--engine {claude,codex,kimi,devin}] [--model MODEL] [--effort {low,medium,high,xhigh,max}] [--codex-transport {exec,app-server}] [--type {bug,feature}] [--grace-s N] [--queue-label LABEL] [--planner-engine E] [--planner-model M] [--plan-reviewer-engine E] [--plan-reviewer-model M] [--verifier-engine E] [--verifier-model M] [--assessor-engine E] [--assessor-model M] [--gate GATE] [--gate-worktree {fresh,persistent}] [--post-fix-assessment {on,off}] [--product-gate {on,off}] [--sent-back-release-min N] [--fallback-to-default-worker {on,off}] [--headroom-dispatch {on,off}] [--notify-events EVENTS] [--json]

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, --queueQueue to configure. Omit it to print the live config path. With no setting flags, --json prints the queue config.
--auto-drainon auto-spawns workers when the queue has depth; off is backlog mode.
--workersDesired worker count for this queue.
--workers-local-path / --repo-pathLocal repo path workers run in.
--backendfile (the default JSON queue) or github (GitHub Issues).
--github-repo / --github-assigneeTarget repo and assignee when the backend is GitHub.
--engineclaude (default), codex, kimi, or devin.
--model / --effortModel identifier and reasoning effort for spawned workers. See wt models for approved ids. An empty string clears the override.
--codex-transportHow Codex workers run: app-server (default, steerable while working) or exec (one-shot codex exec).
--typeRestrict auto-drain workers to a ticket type.
--grace-sSeconds 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-worktreeQueue 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-assessmenton gives every bug that closes as completed an independent six-point assessment (needs a local repo path).
--product-gateon makes workers get a human Ack (wt ack) after a minimal-diagnosis pitch before implementing.
--sent-back-release-minMinutes a verifier-rejected claim may show no progress before it returns to the pool (default 30; 0 disables).
--fallback-to-default-workeron 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-dispatchon checks quota headroom before launching workers and starts them on the engine in the fallback chain whose quota resets soonest. Launch-time only.
--notify-eventsComma-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-labelGitHub 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.

wt models

wt models --engine {claude,codex,kimi,devin,antigravity} [--json]

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.

wt models migrate / unpin

wt models migrate --from MODEL --to MODEL [--queues A,B] [--engine E] [--include-default] [--apply] wt models unpin (--queues A,B | --all-matching MODEL) [--apply]

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.

wt set

wt set -q QUEUE [--backend {file,github}] [--github-repo REPO] [--github-assignee WHO] [--repo-path PATH] [--engine {claude,codex,kimi,devin}] [--model MODEL] [--effort {low,medium,high,xhigh,max}] [--desired-workers N]

Compatibility alias for the basic queue settings that predate wt config. Prefer wt config for new scripts; it accepts --repo-path too.

-q, --queueQueue to configure. Required.
--repo-pathLocal repo the queue's workers operate in.
--engine / --model / --effortEngine, model, and reasoning effort for workers.
--desired-workersHow many workers this queue should staff.
--backend / --github-repo / --github-assigneeQueue backend and its GitHub target.

wt drain

wt drain {on,off} QUEUE [--type {bug,feature}]

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.
QUEUEPositional queue name, for example CCC or WT.
--typeRestrict auto-drain workers to these ticket types (repeatable); omit to clear.

Enqueue

wt add

wt add -q QUEUE [--title T] [--note N] [--text T] [--url U] [--lane {normal,express}] [--type {bug,feature}] [--readiness {ready,needs-shaping,needs-spec,needs-rationale}] [--priority {p0,p1,p2,p3,p4}] [--value {H,M,L}] [--confidence {H,M,L}] [--depth {quick,deep}] [--budget-min N] [--pre-ack] [--dedupe-key KEY] [--model-floor MODEL] [--placement {any,mac,cloud}] [--planner-model M] [--verifier-model M] [--worker W] [--submitter TARGET] [--after REF] [--gate GATE] [--accept LINE] [--claim | --run] [--group-parent [--children REF,REF]] [--group PARENT]

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, --queueDestination queue. Required.
--title / --note / --textTicket title and body text.
--urlAttach a source or reference URL.
--lanenormal or express priority lane.
--typeItem type: bug or feature.
--readinessready, needs-shaping, needs-spec, or needs-rationale.
--priorityp0 (highest) through p4 (lowest).
--value / --confidenceBusiness value and confidence: H, M, or L.
--model-floorFiler'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-minquick (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-ackSkip the product gate for this ticket; the decision to build it is already made.
--dedupe-keyStable incident key; atomically reuses an existing ticket in this local queue.
--placementWhich machine may run it: mac, cloud, or any.
--planner-model / --verifier-modelOverride the queue's planner or verifier model for this ticket.
--submitterAddressable target (worker id, @agent name, or session UUID) to notify when the ticket is claimed, closed, or needs input. Defaults to your own session.
--afterNot claimable until REF closes as completed (repeatable).
--gate / --acceptPer-ticket acceptance gates (override the queue's) and one plain-language acceptance line the verify gate checks.
--workerWorker 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 / --groupPlan 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.

wt take

wt take ... (= wt add --claim)

File a ticket and immediately claim it, so it is marked in progress under you in one step.

wt edit / ls / find

wt edit REF [--title ...] [--priority ...] [--type ...] [--model-floor MODEL] [--after REF | --clear-after] [--gate G | --clear-gates] [--depth ...] [--queue OTHER] [--json] wt ls -q QUEUE [--status {active,open,in_progress,in_review,awaiting_answer,blocked,closed,unresolved,all}] [--limit N] [--unresolved] [--json] wt find REF [--worker W] [--json]

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").

wt ready / blocked / answer / discuss

wt ready REF [--no-dispatch] [--cancel] (alias: wt run) wt blocked [-q QUEUE] [--json] wt answer REF TEXT [--engine {claude,codex,kimi,devin}] [--worker W] [--tid] wt discuss REF [--engine {claude,codex,kimi,devin}] [--print]

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).

wt comment / dedup

wt comment REF TEXT [--by {human,worker,system}] wt dedup [-q QUEUE] [--apply]

comment appends a ticket activity comment. dedup closes exact-duplicate open tickets; preview is the default, --apply closes them.

Import

wt import

wt import FILE -q QUEUE [--apply] [--type {bug,feature}]

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.

FILEPositional. Markdown or text document to extract tasks from.
-q, --queueDestination queue. Required.
--applyFile the inferred tickets. Without it, the command previews only (dry-run).
--typeOverride the inferred type for every newly filed ticket.
Repeat-safe. Each ticket records the resolved source file and line anchor. Importing the same document again creates no duplicates; only newly inferred tasks become new tickets. Imports use Sonnet in Claude safe mode by default; set WATCHTOWER_IMPORT_MODEL to override.

Wait  ·  the signature move

wt wait

wt wait -q QUEUE [--timeout SECONDS] [--interval SECONDS] [--cmd CMD] [--notify-webhook URL]

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, --queueQueue to wait on. Required.
--timeoutMaximum seconds to block. 0 means forever.
--intervalSeconds between depth checks.
--cmdShell command to run once the queue is drained.
--notify-webhookPOST JSON to this URL when the queue drains: the async-reply seam.

Agent messaging

wt send

wt send TARGET TEXT [--mode {send,steer}] [--no-queue] [--ttl SECONDS] [--start-new-if-needed] [--from SENDER] [--json]

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.

--modeDelivery mode hint; delegate transports honor steer.
--no-queueFail immediately instead of parking in the outbox.
--ttlSeconds before a queued outbox message expires.
--start-new-if-neededIf 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.
--fromClaimed sender identity.

wt ask

wt ask TARGET TEXT [--timeout SECONDS] [--notify-webhook URL] [--json]

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.

wt spawn / critique

wt spawn GOAL [--engine {claude,codex,antigravity}] [--model M] [--repo DIR] [--name N] [--report-to WHO] [--dry-run] [--json] wt critique GOAL [--family {claude,codex,antigravity}] [--engine1 M] [--engine2 M] [--report-to WHO] [--cwd DIR] [--dry-run] [--json]

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.

wt outbox / agents / chat / snapshot

wt outbox {ls,retry,rm} wt agents [--json] [register|set-name|rm ...] wt chat {new,post,read,ls,nudge,add,leave,archive,close,set} ... wt snapshot {arm,disarm,status,fire,timer-run,path,record,latest,consume,sessions} ...

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.

wt interrupt

wt interrupt TARGET [--json]

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

wt gated / ack / nack

wt gated [-q QUEUE] [--json] wt ack REF [-m COMMENT] [--by WHO] [--engine E] [--json] wt nack REF -m COMMENT [--close] [--by WHO] [--json]

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.

wt accept / reject / verdict

wt accept REF [--by WHO] [--force] [--no-proof] [--json] wt reject REF --reason TEXT [--by WHO] [--engine E] [--json] wt verdict REF (--pass | --fail) [--findings TEXT] [--by WHO] [--verify-cycle N] [--engine E] [--json]

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.

wt assess

wt assess {submit,show,run,resume,approve,new} ...

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.

wt plan / stages

wt plan {submit,verdict,show,discuss,decide,wait} ... wt stages {tick,show} ...

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

wt liveness

wt liveness [REF] [-q QUEUE] [--json]

Read-only. Who owns each live ticket, whether it is proven at work, and what the backstop would do.

wt wait-on

wt wait-on REF --on {owner,external,dependency,worker} [--actor WHO] [--ref REF] [--note TEXT] [--json]

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.

wt defer

wt defer REF --until WHEN --reason TEXT [--progress TEXT] [--json]

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.

wt unresolved-ack

wt unresolved-ack [REF] [-q QUEUE] [--all] [--caveat N] [--follow-up N] [--unresolved N] [--undo] [--matching TEXT] [--dry-run] [--by WHO] [--json]

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

wt subscribe / unsubscribe

wt subscribe QUEUE [TARGET] [--json] wt unsubscribe QUEUE TARGET

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 dashboard (alias: wt serve)

wt dashboard [--host HOST] [--port PORT] [--no-open] [--stop] [--foreground] [--once]

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 / --portBind address and port. Defaults to 127.0.0.1:8787.
--no-openEnsure the server is up but do not open a browser.
--stopStop the background dashboard server.
--foregroundRun the server in the foreground (blocking; for debugging).
--onceHandle one request then exit (for tests).

wt start / stop

wt start [--interval N] [--stuck-minutes N] [--engine {claude,codex,kimi,devin}] [--auto-spawn] [--dry-run] [--host HOST] [--port PORT] wt stop

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.

--intervalReconciler tick interval in seconds (default 30).
--stuck-minutesIdle threshold before a queue is flagged stuck.
--engineDefault engine for spawned workers.
--auto-spawnAuto spawn a worker on a stuck queue that has no live workers.
--dry-runLog what a reconciler tick would do, but do not spawn or stop anything.
--host / --portHTTP API bind host and port (default 127.0.0.1:8787).

wt skills / uninstall

wt skills [sync|status|remove] wt uninstall

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

wt migrate-store / export-json

wt migrate-store wt export-json [-o OUT]

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

What a worker runs, one ticket at a time.

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
Closes carry how it was fixed. 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.