Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Shell Tools & Policies

--shell lets the model run commands during text or chat requests on Unix systems.

zo --shell 'Run the test suite and summarize failures'
zo --chat --shell 'Help me reproduce this bug step by step'
zo --files read --shell 'Inspect the project, then run the relevant tests'

Shell access is independent of file-tool access. Approved commands run with zo's normal user permissions, environment, filesystem access, and network access; --files read does not make them read-only.

Execution model

  • Direct programs are preferred for simple commands.
  • A configured shell is used when pipelines, chaining, or redirection are needed.
  • Commands start in the current workspace. A requested working directory may move into relative subdirectories, but not outside it.
  • Commands receive no TTY and closed STDIN, so interactive programs should be avoided.
  • The default timeout is 30 seconds, the hard timeout cap is 120 seconds, and combined output is bounded to roughly 24,000 characters.

Multiline commands, background execution, command substitution, heredocs, here-strings, process substitution, and unbalanced quoting are rejected before execution.

Approvals

The default policy action is ask. A command is allowed, denied, or sent for confirmation after applying active policy rules and safety gates.

Some command shapes still require approval even when a rule allows them, including shell expansion, wildcards, chaining, redirection, inline environment assignments, explicit external paths, and hidden paths without --hidden.

--non-interactive evaluates policies normally but denies anything that would ask. --verbose shows compact tool calls and approval details.

Policy files

Shell defaults live in config.toml:

[shell]
default_action = "ask"
allowed_shells = ["/bin/sh", "/bin/bash", "/bin/zsh"]

Rules live in ~/.config/zo/policies/. The filename is the policy name:

# ~/.config/zo/policies/default
allow git status
deny gh auth **
allow gh pr view /\d+/

#TEST allow git status
#TEST deny gh auth login
#TEST allow gh pr view 100
#TEST default gh pr view abc

When --policies is omitted, policies/default is used if present. Supplying names activates only those files, in order:

zo --shell --policies coding,github 'Check this repository'

Later active policies override earlier matches. Policy names are case-insensitive and must be unique.

Rule syntax

Rules use <allow|ask|deny> <program> <argument patterns...>.

PatternMeaning
"text with spaces"One exact argument
/regex/One full-string regex argument
+Exactly one argument
*Zero or one argument
++One or more arguments
**Zero or more arguments

Inline #TEST cases run when shell mode loads. Rules cannot appear after the first test line. A default expectation means no rule in that policy should decide the command.

If you already have command output, a pipeline is simpler and keeps execution entirely under your control:

cargo test 2>&1 | zo 'Explain these failures'

CLI Usage → · Files & Workspace Tools → · Configuration →