zirvDocs

DocsScripts

Usage

README.md, lines 1689–1946View source

zirv help (also zirv h, zirv --help, zirv -h) lists every available script and shortcut, local and global.

Initialize a Project#

Run:

bash
zirv init

Creates a .zirv/ directory, its .zirv/commands/ subdirectory (where you will define your scripts, as of zirv 3.0), and a default .shortcuts.yaml. The .zirv/ directory is created in the current working directory or in the HOME directory depending on the commandline interactions.

Creating a New Script#

bash
zirv create

Interactively asks for the script name, an optional shortcut key, and whether to create it locally or in the global ~/.zirv folder, then writes a template script into .zirv/commands/ (or ~/.zirv/commands/), plus a shortcut entry in .zirv/.shortcuts.yaml if one was given.

To script the creation (e.g. in CI or setup scripts), pass any of the three answers as flags to skip the corresponding prompt; passing all three skips every prompt:

bash
zirv create --name build --shortcut b --global false
  • --name <name> — the script name (file is written as <name>.yaml).
  • --shortcut <key> — a shortcut key, or an empty string for "no shortcut".
  • --global — create in ~/.zirv instead of the current directory. Bare --global means true; pass --global false to answer "no" without a prompt.

If the name or shortcut collides with a reserved command name, zirv warns and asks for confirmation before creating an unreachable script; in non-interactive mode (all three flags given) a collision is an error instead, since there is no prompt to fall back on.

Running Scripts#

Place your script files in .zirv/commands/ (e.g., build.yaml):

yaml
name: Build
description: Build the application.
commands:
  - command: cargo build --release
    options:
      proceed_on_failure: false
  - command: cargo test
    options:
      proceed_on_failure: false

Execute the script with:

bash
zirv build

If the name doesn't match any script or shortcut (checked locally in .zirv/commands/, then globally in ~/.zirv/commands/), zirv suggests up to 3 close matches by edit distance and points you to zirv help. If a script was left at the .zirv root instead of moved into commands/ (the pre-3.0 layout), the error names it and says where it needs to move — there is no fallback lookup at the old location:

text
error: No script or shortcut found for 'buld'. Did you mean: build? Run `zirv help` to see available scripts and shortcuts.

Passing Parameters#

If a script declares parameters;

yaml
name: Commit Changes
params:
  - commit_message
commands:
  - command: git add .
  - command: git commit -m "${commit_message}"
  - command: git push origin

Run with:

bash
zirv commit "Your commit message here"

Optional Parameters#

A parameter name ending in ? is optional and resolves to an empty string when omitted. Optional parameters must be declared after all required ones:

yaml
name: Greet
params:
  - name
  - greeting?
commands:
  - command: echo "${greeting} ${name}"
bash
zirv greet Alice            # greeting = "" -> prints " Alice"
zirv greet Alice "Welcome"  # greeting = "Welcome" -> prints "Welcome Alice"

Declaring an optional parameter before a required one, giving fewer arguments than there are required parameters, giving more than the total number of declared parameters, or reusing a parameter name (with or without the trailing ?) are all rejected with an error.

Capture Output#

To capture the output of a command, use the capture option:

yaml
name: Capture Test
commands:
  - command: "echo hello"
    capture: greeting
    options:
      proceed_on_failure: false
  - command: "echo Got: ${greeting}"

First step stores hello in the variable ${greeting}, which is then used in the second step to print Got: hello.

Failure Hooks#

Declare a failure hook for a command using fallback:

yaml
name: OnFailure Demo
commands:
  - command: "sh -c 'exit 1'"
    options:
      proceed_on_failure: true     # don't stop the script once fallback succeeds
      fallback:
        - command: "echo 'Fallback action'"

If the command fails, every fallback command runs, in order, once — the original command is never retried. If any fallback command itself fails, the step fails immediately with an error naming both the original and the failing fallback command. Otherwise, whether the step's own failure stops the script is controlled separately by proceed_on_failure: true continues to the next step, false (the default) stops the script with an error, even though every fallback succeeded.

Dry Run#

Pass --dry-run to preview a script without running anything:

bash
zirv build --dry-run

Each step is printed with its ${...} parameters substituted, instead of being executed, so you can check what a script would do first.

Chaining Scripts#

You can chain scripts by calling one script from another. For example, if you have a script build.yaml and want to call it from deploy.yaml:

yaml
name: Deploy
description: Deploy the application.
commands:
  - command: zirv test
    options:
      proceed_on_failure: false
  - command: zirv build
    options:
      proceed_on_failure: false

Run the deploy script with:

bash
zirv deploy

Concurrent Shells#

You can open multiple terminals at once by nesting lists. For example:

yaml
name: Parallel Commands
commands:
  - - command: "echo 'Running Task A'"
    - command: "echo 'Running Task B'"
  - - command: "echo 'Running Task 1'"
    - command: "echo 'Running Task 2'"

Each nested list spawns its own shell window. Every window executes the commands listed in that group and stays open until they finish.

This needs a desktop/GUI session: macOS uses osascript to drive Terminal, Windows opens a new cmd window, and Linux tries gnome-terminal, then x-terminal-emulator, then xterm. Over a headless or SSH-only connection — or on Linux specifically, whenever neither DISPLAY nor WAYLAND_DISPLAY is set — zirv returns a clear error naming what it tried, instead of failing cryptically or hanging.

The built-in cd command updates the working directory for any following commands in the same window, allowing scripts like:

yaml
commands:
  - - command: "cd backend"
    - command: "cargo run"

Agent Steps#

A command step can run a supervised AI-agent task instead of a shell command, using agent and prompt in place of command:

yaml
commands:
  - command: cargo test
  - agent: claude
    prompt: "Fix the failing tests in ${dir}"
    # optional:
    flags: ["--model", "sonnet"]
  - command: cargo test

runtime selects which machinery runs the step: harness (the default, and what every existing script keeps doing) or native — zirv conducts the conversation itself over a direct provider route, with no coding harness installed:

yaml
commands:
  - agent: fast-route          # a [route] name, not an adapter name
    runtime: native
    prompt: "Summarise the failing checks in ${dir}"

Under runtime: native the agent value names a provider route from ~/.zirv/native.toml (the reserved value native means "use the [roles] entry for the worker role"), and flags are refused rather than silently ignored — they exist to reach a vendor CLI and there is none. An unrecognised runtime fails at load time, so --dry-run and the real run reject the same script. Everything else — ${var} substitution, secrets, operating_system, proceed_on_failure, delay_ms, fallback and the exit-code contract — is identical on both runtimes.

prompt gets the same ${var} substitution as command, including the unresolved-placeholder error if a variable is missing. flags are passed straight through to the agent CLI. operating_system, proceed_on_failure, delay_ms and fallback work the same as they do for a regular command; capture and interactive are not supported and fail the step if set.

The step runs in-process through the same supervision zirv ctx exec uses: pacing against your usage windows, rot detection, and automatic restart with a distilled handoff if the session rots. A non-zero outcome fails the step like any other command. Only Claude Code is supported today (see Context Management below); naming any other agent fails with that adapter's own error.