Skip to content

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

CommandDescription
zen workflow listList all available workflows
zen workflow list --jsonMachine-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 statusShow 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

CommandDescription
zen isolation listList all active worktrees
zen isolation cleanupRemove stale worktrees (older than 7 days)
zen isolation cleanup <days>Remove stale worktrees older than N days
zen isolation cleanup --mergedRemove worktrees whose branches merged into main
zen isolation cleanup --merged --include-closedAlso remove worktrees with closed (abandoned) PRs

zen complete

CommandDescription
zen complete <branch>Remove worktree, local branch, and remote branch
zen complete <branch> --forceSkip uncommitted-changes check

zen validate

CommandDescription
zen validate workflowsValidate all workflow definitions
zen validate workflows <name>Validate a single workflow
zen validate workflows <name> --jsonMachine-readable validation output
zen validate commandsValidate all command files
zen validate commands <name>Validate a single command

zen version

bash
zen version

Variables

Variables are substituted at runtime in command bodies and workflow prompt: fields.

VariableAvailable InContains
$ARGUMENTSCommands, promptsAll arguments passed to the command as a single string
$1, $2, $3Commands, promptsFirst, second, third positional arguments
$ARTIFACTS_DIRCommands, promptsAbsolute path to the workflow run's artifact directory
$WORKFLOW_IDCommands, promptsThe current workflow run ID
$BASE_BRANCHCommands, promptsBase git branch (auto-detected or set via worktree.baseBranch)
$DOCS_DIRCommands, promptsDocumentation directory path (default: docs/)
$<nodeId>.outputDAG when: conditions, downstream prompt: fieldsThe text output from a completed node

Examples:

bash
# 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"
yaml
# Reference a node's output in a condition
- id: implement
  command: implement-changes
  when: "$classify.output.type == 'BUG'"

Workflow YAML Schema

Top-Level Options

FieldRequiredTypeDescription
nameYesstringIdentifies the workflow in zen workflow list
descriptionYesstringShown in listings and used by the router
nodesYesarrayDAG nodes (see Node Options below)
providerNoclaude | codexAI provider for all nodes (default: claude)
modelNostringModel for all nodes (sonnet, opus, haiku, or full model ID)
modelReasoningEffortNostringCodex only: minimal | low | medium | high | xhigh
webSearchModeNostringCodex only: disabled | cached | live
additionalDirectoriesNostring[]Extra directories available to the AI

Node Options (DAG)

All nodes share these base fields:

FieldRequiredTypeDescription
idYesstringUnique node identifier; used in depends_on and $nodeId.output
commandOne ofstringName of a command file in .zen/commands/
promptOne ofstringInline AI instructions
bashOne ofstringShell script (runs without AI; stdout captured as $nodeId.output)
loopOne ofobjectLoop configuration (see Loop Options below)
depends_onNostring[]Node IDs that must complete before this node runs
whenNostringCondition expression; node is skipped if false
trigger_ruleNostringJoin semantics when multiple upstreams exist (see Trigger Rules)
providerNoclaude | codexPer-node provider override
modelNostringPer-node model override
contextNofresh | sharedSession context; fresh starts a new conversation, shared inherits from prior node
output_formatNoJSON SchemaEnforce structured JSON output from this node
allowed_toolsNostring[]Restrict available tools to this list (Claude only)
denied_toolsNostring[]Remove specific tools from this node's context (Claude only)
idle_timeoutNonumberPer-node idle timeout in milliseconds (default: 5 minutes)
retryNoobjectRetry configuration for transient failures (see Retry Options)
hooksNoobjectSDK hook callbacks (Claude only; see Hook Schema)
mcpNostringPath to MCP server config JSON file (Claude only)
skillsNostring[]Skill names to preload into this node's context (Claude only)

bash node timeout: The timeout field on bash nodes is in milliseconds (default: 120000). This differs from hook timeout, which is in seconds.

Trigger Rules

ValueBehavior
all_successRun only if all upstream nodes succeeded (default)
one_successRun if at least one upstream node succeeded
none_failed_min_one_successRun if no upstream failed and at least one succeeded
all_doneRun after all upstream nodes complete, regardless of result

Loop Node Options

Defined under loop: inside a node:

FieldRequiredTypeDescription
promptYesstringAI instructions executed each iteration
untilYesstringCompletion signal string; loop ends when AI output contains this
max_iterationsYesnumberMaximum iterations before the node fails
fresh_contextNobooleanStart a new session each iteration (default: false)
until_bashNostringShell script run after each iteration; exit 0 signals completion

Example:

yaml
- id: refine
  loop:
    prompt: "Review the current draft and improve it. Output COMPLETE when done."
    until: "COMPLETE"
    max_iterations: 5

Retry Options

Defined under retry: inside a node:

FieldRequiredDefaultDescription
max_attemptsYes;Retry attempts after the initial failure (max: 5)
delay_msNo3000Initial delay in milliseconds; doubles each attempt (1000-60000)
on_errorNotransienttransient 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.

yaml
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 EventWhen it fires
PreToolUseBefore a tool executes
PostToolUseAfter a tool completes successfully
PostToolUseFailureAfter a tool fails
SessionStart / SessionEndOn session lifecycle events
StopWhen 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.yaml

Bundled 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:

yaml
# .zen/config.yaml
defaults:
  loadDefaultCommands: false
  loadDefaultWorkflows: false

Troubleshooting

Common Errors

ErrorLikely CauseFix
Workflow "X" not foundYAML file not discoveredCheck file is in .zen/workflows/ and zen workflow list shows it
Command "X" not foundCommand file missingCheck .zen/commands/X.md exists and zen validate commands X passes
Routing unclear; no workflow matchedNo workflow matched the inputUse an explicit workflow name: zen workflow run my-workflow "..."
Worktree already exists for branch XPrior run left a worktreeRun zen complete X or zen isolation cleanup
Not a git repositoryRunning outside a repocd into a git repo first; workflow and isolation commands require one
Model X is not valid for provider YProvider/model mismatchUse Claude models (sonnet, opus, haiku) with provider: claude; use other models with provider: codex
$BASE_BRANCH referenced but could not be detectedNo base branch set and auto-detection failedSet worktree.baseBranch in .zen/config.yaml or ensure main/master exists
Workflow hangs with no outputNode idle timeout hitIncrease idle_timeout on the node (milliseconds)

Debug Techniques

See what Z.E.N. found:

bash
zen workflow list          # Are your workflows loaded?
zen validate workflows     # Any YAML errors?
zen isolation list         # Any stale worktrees?

Enable verbose logging:

bash
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:

bash
zen workflow run my-workflow --no-worktree "..."

Test a command directly before embedding it in a workflow:

bash
zen workflow run morning-brief "/command-invoke my-command some-arg"

Getting Help


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.

AI that follows a recipe, not a conversation.