Wardian CLI
Wardian includes a standalone wardian command for agents and automation to inspect, coordinate, and control known agent sessions. Wardian remains GUI/app-first for humans; the CLI is the textual control surface agents use when they need to discover themselves, coordinate peers, or ask the running app to perform live actions for the same WARDIAN_HOME.
Installation
The desktop app copies the bundled CLI on startup:
- Windows command:
%USERPROFILE%\.wardian\bin\wardian.cmd - Windows bash command:
%USERPROFILE%\.wardian\bin\wardian - Windows implementation binary:
%USERPROFILE%\.wardian\bin\wardian-cli.exe - macOS/Linux command:
$HOME/.wardian/bin/wardian - macOS/Linux implementation binary:
$HOME/.wardian/bin/wardian-cli
Wardian also attempts to add that bin directory to the user PATH. Restart the terminal after first launch if wardian is not found.
On Windows, Wardian installs both a wardian.cmd launcher for PowerShell/cmd and an extensionless POSIX shell launcher for Git Bash, MSYS2, or provider shell tools that execute bash. Wardian-managed agent processes also receive the active Wardian bin directory at the front of PATH, so shell tools inside Claude sessions can resolve wardian without depending on the user's global shell startup files.
Set WARDIAN_HOME to redirect state, the CLI install location, and the live app control endpoint for tests or isolated runs.
For development, set the same WARDIAN_HOME before starting the desktop app and before running CLI commands. Otherwise the app debug home and the CLI default production home may differ.
When the desktop app is running for the same WARDIAN_HOME, the CLI asks the app for live agent snapshots before falling back to state.db. Request status_source when you need to know which path answered:
livemeans the status came from the running desktop app.persistedmeans the CLI fell back to durablestate.dbstate.
Agent Identity
Wardian injects WARDIAN_SESSION_ID into managed agent processes. Inside an agent terminal, wardian agent resolves that session automatically.
Outside a managed agent process, pass a name or UUID:
wardian agent coder-a1
wardian agent show uuid-1Commands
wardian agent
wardian agent <name-or-uuid>
wardian agent show [name-or-uuid]
wardian agent list --scope workspace
wardian agent list --scope all
wardian agent kill <name-or-uuid>
wardian agent pause <name-or-uuid>
wardian agent resume <name-or-uuid>
wardian agent spawn --provider codex --class Reviewer --name reviewer-a1 --workspace <absolute-workspace-path>
wardian agent clone <name-or-uuid> --name coder-a2
wardian agent worktree list
wardian agent worktree enable <name-or-uuid> --name review-fixes
wardian agent worktree join <name-or-uuid> --worktree <absolute-worktree-path-or-id>
wardian agent worktree disable <name-or-uuid>
wardian agent wait reviewer-a1 --until idle --timeout 10m
wardian agent wait reviewer-a1 --until idle --next --timeout 10m
wardian agent watch reviewer-a1 --until output:REVIEW_DONE --include transcript,output,delivery --timeout 10m
wardian agent watch reviewer-a1 --include raw_output --raw
wardian team list
wardian team show <team-name-or-id>
wardian watchlist list
wardian watchlist show <watchlist-name-or-id>
wardian workflow list
wardian workflow show <id-or-name>
wardian workflow run <id>
wardian workflow stop <run-instance-id>
wardian ask reviewer-a1 --stdin --until output:REVIEW_DONE --timeout 10m
wardian send "review this" --to coder-a1
wardian send --as-command "/goal test" --to coder-a1
wardian send "review this" --to reviewer-a1 --wait-until idle --timeout 10m
wardian send "status?" --to class:Coder
wardian send "stand down" --to allCommon Workflows
Inspect the live roster before an agent coordinates work:
wardian agent list --scope all --fields name,class,provider,workspace,status,status_sourceHand a bounded review task to a peer and wait for response evidence:
wardian ask reviewer-a1 --file review-prompt.md --until output:REVIEW_DONE --timeout 10mSend a prompt to an existing agent and wait for the next Idle transition:
wardian send --file prompt.md --to coder-a1 --wait-until idle --timeout 10mWatch retained readable output for a deterministic marker:
wardian agent watch coder-a1 --until output:READY_FOR_REVIEW --include transcript,output,delivery --timeout 10mInspect provider-adapted transcript text, sanitized terminal fallback, or raw PTY evidence:
wardian agent watch Librarian --include transcript
wardian agent watch Librarian --include output
wardian agent watch Librarian --include raw_output --rawPowerShell:
wardian agent watch Librarian --include transcript
wardian agent watch Librarian --include output
wardian agent watch Librarian --include raw_output --rawRun a saved workflow through the app-owned backend:
wardian workflow list
wardian workflow run workflow-idMutating commands use Wardian's local control endpoint and require the desktop app to be running for the same WARDIAN_HOME. This includes agent lifecycle commands, agent worktree commands, workflow run, workflow stop, and send.
workflow list and workflow show try the running app first, then read workflow JSON files from disk when the app is unavailable.
agent spawn requires both --provider and --class so the created agent's runtime and role are explicit.
agent worktree list returns the worktrees currently managed by Wardian with source folder, worktree folder, display name, and member agent IDs. agent worktree enable, join, and disable are live-control commands. They reuse the same backend logic as the Source Control panel and force a fresh agent session after changing the runtime workspace. disable removes the assignment only; it does not delete the physical worktree folder.
team list/show and watchlist list/show read the existing watchlist state file. They accept the current v2 shape with global teams and legacy flat watchlist arrays, then return schema: 1 JSON for automation. Team mutation and send --to team:<name> are not implemented yet.
agent wait <target> --until <status> blocks inside the CLI process until a single agent name or UUID reaches a normalized status such as idle, processing, action_required, off, or error. Plain wait returns immediately when the target is already in the requested status. Add --next to wait for a newer matching observation. Use --timeout with ms, s, or m units.
agent watch <target> returns a live snapshot with agent status, a provider-adapted transcript, sanitized retained terminal output, delivery details, and a cursor. Raw PTY text is not returned by default. Add --raw or --include raw_output only when debugging terminal rendering, ANSI/control sequences, or PTY transport behavior. raw_output.text may contain escape sequences and prompt repaint fragments.
transcript is extracted from structured provider lines when Wardian has a provider adapter. This slice covers Codex, Claude, Gemini, OpenCode, and the mock provider. Gemini can backfill completed assistant text from Gemini chat logs, and OpenCode can backfill assistant text from its session database when the live TUI does not expose a clean structured line. Ambiguous provider lines fall back to sanitized terminal output until provider-specific transcript adapters are added. output is the compatibility surface for --until output:<substring> and is cleaned of common ANSI, OSC, cursor, and clear-line controls. Internally, marker matching also checks transcript text and the raw PTY tap so existing token-based automation keeps working without returning raw text by default.
Add --until to block until status:<status>, output:<substring>, event:<kind>, or delivery:<state> is observed. watch accepts only one name or UUID in this slice. --follow is reserved and returns not_supported.
ask <target> sends one prompt to one live Wardian-managed agent and creates a live structured request id. By default, Wardian appends reply instructions to the delivered prompt and waits for the target to answer with wardian reply <request-id> --status done --stdin. The JSON response includes request_id, reply.status, reply.body, delivery evidence, watch events, and retained output. reply.status can be done, blocked, or failed; timeout remains a separate watch_timeout error.
Use --until output:<token> only when you explicitly need the older output-substring mode, such as manual provider output matching or compatibility with agents that cannot run wardian reply. Other explicit watch conditions such as status:<status>, event:<kind>, and delivery:<state> also preserve the watch-based behavior. ask rejects all, class:<ClassName>, and reserved --thread usage with not_supported.
reply <request-id> --status done|blocked|failed --stdin records a structured reply through the live control endpoint. When run from a Wardian-managed agent terminal, WARDIAN_SESSION_ID is used to verify that the reply came from the target agent for that request. Replies submitted outside a Wardian-managed session are accepted for this first live-only slice so a human terminal can unblock a request, but that caller identity is not authenticated.
send submits a provider-aware message into the target agent runtime. Targets can be an agent name, UUID, class:<ClassName>, or all. --stdin reads the message from standard input, and --file <path> reads it from a file. By default, Wardian keeps inter-agent attribution and delivers messages with a From <sender>: prefix when sender context is available. Use --as-command for provider slash commands that must start at the first input token:
wardian send --as-command "/goal test" --to coder-a1
printf '%s' '/status' | wardian send --stdin --as-command --to coder-a1PowerShell:
"/status" | wardian send --stdin --as-command --to coder-a1--as-command sends the exact message body without the attribution prefix while still using the normal provider-aware submit path. It accepts only one explicit agent name or UUID, rejects all and class:<ClassName> with not_supported, and cannot be combined with --thread.
--wait-until <status> is available for single-agent targets and waits from a pre-send watch cursor for a newer matching status observation. --thread is reserved but not implemented yet; when the app is running, using it returns not_supported.
Successful send responses include input_mode and delivery[]; command sends also include delivery[].input_mode so automation can confirm command delivery. Failed or partial delivery returns a nonzero exit with JSON on stderr and details.delivery[], including runtime_state, delivery_state, and provider-specific input errors.
List filters:
--status <status>filters by normalized status, such asidle,processing, oraction_required.--class <class>filters by agent class.--workspace <absolute-path>filters by workspace and implies--scope all.
Output options:
--fields name,status,uuidreturns indented JSON with only those fields.--field statusreturns one bare value plus a newline.--field status_sourcereturnsliveorpersisted.--verboseaddspid,started_at, andlast_status_at.--prettyreturns aligned text for interactive inspection instead of JSON.
Default JSON is indented for terminal readability. It includes schema: 1 and an agent or agents payload with name, uuid, class, provider, workspace, and status.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Generic command error |
| 2 | Agent not found |
| 3 | WARDIAN_SESSION_ID is not set for self lookup |
| 4 | Wardian state database is unavailable |
| 5 | Lookup matched multiple agents |
| 6 | Desktop app is not running for a live control command |
Errors are written to stderr as JSON:
{
"schema": 1,
"error": {
"code": "not_in_session",
"message": "WARDIAN_SESSION_ID environment variable is not set",
"hint": "Pass a name or uuid to look up a specific agent from outside a Wardian-managed agent process: `wardian agent <name>`.",
"details": {
"command": "agent",
"requested": "self"
}
}
}