This chapter collects every CLI command, variable, and YAML option in one place. No explanations; just the facts. Use it when you know what you need and just need the syntax.
CLI Commands
zen workflow
| Command | Description |
|---|---|
zen workflow list | List all available workflows |
zen workflow list --json | Machine-readable JSON output |
zen workflow run <name> "<prompt>" | Run a workflow |
zen workflow run <name> --branch <name> "<prompt>" | Run with an explicit branch |
zen workflow run <name> --no-worktree "<prompt>" | Run in the live checkout (no isolation) |
zen workflow run <name> --cwd /path "<prompt>" | Run against a specific directory |
zen workflow status | Show status of active workflow runs |
zen workflow resume <run-id> | Resume a failed workflow run |
zen workflow abandon <run-id> | Abandon a non-terminal workflow run |
zen workflow cleanup [days] | Delete old workflow run records (default: 7 days) |
zen isolation
| Command | Description |
|---|---|
zen isolation list | List all active worktrees |
zen isolation cleanup | Remove stale worktrees (older than 7 days) |
zen isolation cleanup <days> | Remove stale worktrees older than N days |
zen isolation cleanup --merged | Remove worktrees whose branches merged into main |
zen isolation cleanup --merged --include-closed | Also remove worktrees with closed (abandoned) PRs |
zen complete
| Command | Description |
|---|---|
zen complete <branch> | Remove worktree, local branch, and remote branch |
zen complete <branch> --force | Skip uncommitted-changes check |
zen validate
| Command | Description |
|---|---|
zen validate workflows | Validate all workflow definitions |
zen validate workflows <name> | Validate a single workflow |
zen validate workflows <name> --json | Machine-readable validation output |
zen validate commands | Validate all command files |
zen validate commands <name> | Validate a single command |
zen version
zen versionVariables
Variables are substituted at runtime in command bodies and workflow prompt: fields.
| Variable | Available In | Contains |
|---|---|---|
$ARGUMENTS | Commands, prompts | All arguments passed to the command as a single string |
$1, $2, $3 | Commands, prompts | First, second, third positional arguments |
$ARTIFACTS_DIR | Commands, prompts | Absolute path to the workflow run's artifact directory |
$WORKFLOW_ID | Commands, prompts | The current workflow run ID |
$BASE_BRANCH | Commands, prompts | Base git branch (auto-detected or set via worktree.baseBranch) |
$DOCS_DIR | Commands, prompts | Documentation directory path (default: docs/) |
$<nodeId>.output | DAG when: conditions, downstream prompt: fields | The text output from a completed node |
Examples:
# Pass a module name to a command
zen workflow run my-workflow "auth"
# $ARGUMENTS = "auth", $1 = "auth"
# Multi-argument
zen workflow run my-workflow "auth refresh-tokens"
# $ARGUMENTS = "auth refresh-tokens", $1 = "auth", $2 = "refresh-tokens"# Reference a node's output in a condition
- id: implement
command: implement-changes
when: "$classify.output.type == 'BUG'"Workflow YAML Schema
Top-Level Options
| Field | Required | Type | Description |
|---|---|---|---|
name | Yes | string | Identifies the workflow in zen workflow list |
description | Yes | string | Shown in listings and used by the router |
nodes | Yes | array | DAG nodes (see Node Options below) |
provider | No | claude | codex | AI provider for all nodes (default: claude) |
model | No | string | Model for all nodes (sonnet, opus, haiku, or full model ID) |
modelReasoningEffort | No | string | Codex only: minimal | low | medium | high | xhigh |
webSearchMode | No | string | Codex only: disabled | cached | live |
additionalDirectories | No | string[] | Extra directories available to the AI |
Node Options (DAG)
All nodes share these base fields:
| Field | Required | Type | Description |
|---|---|---|---|
id | Yes | string | Unique node identifier; used in depends_on and $nodeId.output |
command | One of | string | Name of a command file in .zen/commands/ |
prompt | One of | string | Inline AI instructions |
bash | One of | string | Shell script (runs without AI; stdout captured as $nodeId.output) |
loop | One of | object | Loop configuration (see Loop Options below) |
depends_on | No | string[] | Node IDs that must complete before this node runs |
when | No | string | Condition expression; node is skipped if false |
trigger_rule | No | string | Join semantics when multiple upstreams exist (see Trigger Rules) |
provider | No | claude | codex | Per-node provider override |
model | No | string | Per-node model override |
context | No | fresh | shared | Session context; fresh starts a new conversation, shared inherits from prior node |
output_format | No | JSON Schema | Enforce structured JSON output from this node |
allowed_tools | No | string[] | Restrict available tools to this list (Claude only) |
denied_tools | No | string[] | Remove specific tools from this node's context (Claude only) |
idle_timeout | No | number | Per-node idle timeout in milliseconds (default: 5 minutes) |
retry | No | object | Retry configuration for transient failures (see Retry Options) |
hooks | No | object | SDK hook callbacks (Claude only; see Hook Schema) |
mcp | No | string | Path to MCP server config JSON file (Claude only) |
skills | No | string[] | Skill names to preload into this node's context (Claude only) |
bash node timeout: The
timeoutfield on bash nodes is in milliseconds (default: 120000). This differs from hooktimeout, which is in seconds.
Trigger Rules
| Value | Behavior |
|---|---|
all_success | Run only if all upstream nodes succeeded (default) |
one_success | Run if at least one upstream node succeeded |
none_failed_min_one_success | Run if no upstream failed and at least one succeeded |
all_done | Run after all upstream nodes complete, regardless of result |
Loop Node Options
Defined under loop: inside a node:
| Field | Required | Type | Description |
|---|---|---|---|
prompt | Yes | string | AI instructions executed each iteration |
until | Yes | string | Completion signal string; loop ends when AI output contains this |
max_iterations | Yes | number | Maximum iterations before the node fails |
fresh_context | No | boolean | Start a new session each iteration (default: false) |
until_bash | No | string | Shell script run after each iteration; exit 0 signals completion |
Example:
- id: refine
loop:
prompt: "Review the current draft and improve it. Output COMPLETE when done."
until: "COMPLETE"
max_iterations: 5Retry Options
Defined under retry: inside a node:
| Field | Required | Default | Description |
|---|---|---|---|
max_attempts | Yes | ; | Retry attempts after the initial failure (max: 5) |
delay_ms | No | 3000 | Initial delay in milliseconds; doubles each attempt (1000-60000) |
on_error | No | transient | transient retries rate limits/network errors; all retries everything except fatal errors |
Fatal errors are never retried: auth failures, permission errors, and exhausted credit balances fail immediately regardless of retry config.
Hook Schema
Hooks are defined per-node under hooks:. See Chapter 9 for full examples.
hooks:
PreToolUse:
- matcher: "Write|Edit" # Regex against tool name. Omit to match all.
timeout: 60 # Seconds. Default: 60.
response:
hookSpecificOutput:
hookEventName: PreToolUse
additionalContext: "Verify the file before writing"
permissionDecision: deny # allow | deny | ask
permissionDecisionReason: "Not allowed in this node"
updatedInput: # Override tool arguments
file_path: "/sandbox/out.ts"
PostToolUse:
- matcher: "Read"
response:
hookSpecificOutput:
hookEventName: PostToolUse
additionalContext: "This file is read-only. Do not modify it."| Hook Event | When it fires |
|---|---|
PreToolUse | Before a tool executes |
PostToolUse | After a tool completes successfully |
PostToolUseFailure | After a tool fails |
SessionStart / SessionEnd | On session lifecycle events |
Stop | When the agent stops |
Directory Structure
~/.zen/ (user-level)
~/.zen/
├── config.yaml # Global configuration (non-secrets)
├── zen.db # SQLite database (default; no DATABASE_URL needed)
└── workspaces/
└── <owner>/
└── <repo>/
├── source/ # Git clone or symlink to local path
├── worktrees/ # Per-task git worktrees
├── artifacts/ # Workflow artifacts (never committed)
└── logs/ # Workflow execution logs (JSONL).zen/ (repo-level)
.zen/
├── config.yaml # Repo-specific configuration
├── commands/ # Custom command files (*.md)
│ └── my-command.md
└── workflows/ # Custom workflow files (*.yaml)
└── my-workflow.yamlBundled defaults; built-in commands and workflows ship with Z.E.N. and load automatically. Repo-level files with the same name override the bundled version. To disable defaults entirely:
# .zen/config.yaml
defaults:
loadDefaultCommands: false
loadDefaultWorkflows: falseTroubleshooting
Common Errors
| Error | Likely Cause | Fix |
|---|---|---|
Workflow "X" not found | YAML file not discovered | Check file is in .zen/workflows/ and zen workflow list shows it |
Command "X" not found | Command file missing | Check .zen/commands/X.md exists and zen validate commands X passes |
Routing unclear; no workflow matched | No workflow matched the input | Use an explicit workflow name: zen workflow run my-workflow "..." |
Worktree already exists for branch X | Prior run left a worktree | Run zen complete X or zen isolation cleanup |
Not a git repository | Running outside a repo | cd into a git repo first; workflow and isolation commands require one |
Model X is not valid for provider Y | Provider/model mismatch | Use Claude models (sonnet, opus, haiku) with provider: claude; use other models with provider: codex |
$BASE_BRANCH referenced but could not be detected | No base branch set and auto-detection failed | Set worktree.baseBranch in .zen/config.yaml or ensure main/master exists |
| Workflow hangs with no output | Node idle timeout hit | Increase idle_timeout on the node (milliseconds) |
Debug Techniques
See what Z.E.N. found:
zen workflow list # Are your workflows loaded?
zen validate workflows # Any YAML errors?
zen isolation list # Any stale worktrees?Enable verbose logging:
zen --verbose workflow run my-workflow "..."Check execution logs; each run writes a JSONL log:
~/.zen/workspaces/<owner>/<repo>/logs/Run without isolation to simplify debugging:
zen workflow run my-workflow --no-worktree "..."Test a command directly before embedding it in a workflow:
zen workflow run morning-brief "/command-invoke my-command some-arg"Getting Help
- Validate your YAML:
zen validate workflows my-workflow - Check the logs:
~/.zen/workspaces/<owner>/<repo>/logs/ - Report issues: github.com/Cadence-Intelligence/zen/issues
You've covered the full guide; from mental model to hooks to this reference. When you need to look something up quickly, this is the page to come back to.