# Tools

The default tools, optional JavaScript orchestration, and native PowerShell execution on Windows.

Five tools enabled by default, plus optional [Codemode](/docs/codemode) for JavaScript orchestration and native PowerShell execution on Windows.

| Tool | What it does |
| --- | --- |
| read | Read text files, or render PNG / JPG / GIF / WebP inline on modern terminals. |
| write | Create or overwrite files, making parent directories as needed. |
| edit | One or more exact-match replacements in an existing file. |
| glob | Find files matching patterns such as **/*.go or src/**/*.ts. Searches recursively, honors root and nested .gitignore rules, excludes hidden paths by default, and respects jail mode. |
| bash | Run a command in the session cwd with merged stdout/stderr and a timeout. On Unix, zot uses /bin/bash when available, then Bash from PATH, and falls back to POSIX /bin/sh. On Windows, it uses cmd /C. |

On Windows, the `bash` tool runs Command Prompt, not Bash. Use cmd syntax such as `dir`, `type`, `findstr`, and `%VAR%`, not `ls`, `cat`, `grep`, or `$VAR`. Double-quote paths containing spaces. Single quotes are not quoting characters in cmd. For more complex Windows commands, enable the optional PowerShell tool below.

## Codemode

Enable `zot --codemode` to let the model call tools from JavaScript, run independent calls in parallel, and return only selected output. `zot --codemode-only` exposes client tools through scripts instead of direct definitions. Both retain normal guards, confirmations, and permissions. `--no-tools` disables codemode too.

Scripts support tool discovery, persistent JSON state, classification, and image generation. They run inside an embedded WebAssembly VM with a 256 MiB linear-memory cap and no external runtime. Authorized host tools are not sandboxed by the VM. See [Codemode](/docs/codemode) for configuration, examples, output limits, and isolation details.

## PowerShell tool (Windows)

Open `/settings` and toggle **PowerShell tool** to enable or disable the optional `powershell` tool alongside the default tools. It is off by default. The setting is visible only on Windows, updates the live tool list without a restart, and persists as `powershell_enabled` in `$ZOT_HOME/config.json`. The saved preference also applies to other modes on Windows.

For a one-run selection that uses PowerShell instead of the `bash` tool:

```powershell
zot --tools read,write,edit,glob,powershell
```

Include `bash` in the list to enable both. Explicit `--tools` and `--no-tools` override the saved preference and disable the settings toggle for that run. Enabling PowerShell does not change `!` shell escapes, which still use `cmd /C` on Windows.

The tool prefers `pwsh.exe` on `PATH`, falling back to `powershell.exe`. It starts without profiles or interactive input, using `-NoProfile -NonInteractive -ExecutionPolicy Bypass`. Administrator-enforced execution policies can still take precedence. Encoded command transport preserves Unicode and quoting, and output is UTF-8. Missing executables and non-Windows execution return explicit errors.

Pass `command` and an optional `timeout` in seconds. Output streams with merged stdout/stderr, a `PS>` prompt, exit status, and the same output limits as `bash`. On Windows, cancellation terminates the shell and bounds output draining, but does not guarantee termination of descendant processes.

PowerShell execution is blocked while jailed because the existing shell checks do not parse PowerShell syntax. Packaged agents require `permissions.bash.mode` set to `"ask"` for launch-time consent; `none`, `allowlist`, and unknown modes deny execution. Bash allowlists do not apply to PowerShell. See [Jail mode](/docs/jail) and `.zot agents`.

## Child process environment

CLI-launched shell commands can use runtime environment variables for attribution and diagnostics. These variables require a zot build containing PR #171: [https://github.com/patriceckhart/zot/pull/171](https://github.com/patriceckhart/zot/pull/171).

| Variable | Meaning |
| --- | --- |
| `AI_AGENT` | Generic agent marker, set to `zot` by the CLI. |
| `ZOT_AGENT` | Zot-specific process marker, set to `1` by the CLI. |
| `ZOT_CHILD_SESSION` | Set to `1` for commands launched through the `bash` or `powershell` tool. Descendants inherit it. |
| `ZOT_SESSION_ID` | Current session ID, when a persisted session is open. |
| `ZOT_SESSION_FILE` | Path to the current session file, when a persisted session is open. |
| `ZOT_PROVIDER` | Current model provider. |
| `ZOT_MODEL` | Current model ID. |
| `ZOT_REASONING_LEVEL` | Current reasoning level; unset when reasoning is off. |

Interactive, print, and JSON CLI runs publish session and model metadata. With `--no-session`, model metadata remains available, but session ID and file are omitted. In interactive mode, newly launched shell commands reflect session switches, `/cd` working-directory changes, model selections, and reasoning-level changes.

Subprocesses inherit a snapshot at launch. Updating zot's environment does not update an already-running shell or extension, and extensions started before session initialization may not receive session metadata. Do not assume the same metadata is populated by SDK embeddings or bot modes.

These variables contain no credentials, but the session file path can reveal local filesystem information. They are diagnostic hints, not proof of trusted execution or a security boundary. Use `AI_AGENT` or `ZOT_AGENT` for agent detection and avoid sharing session paths unnecessarily.

## Tool rendering

Tool calls use bordered panels by default. Set `tool_render` to `"flat"` in `$ZOT_HOME/config.json` for a border-free header and indented output. `ZOT_FLAT_TOOLS=1` overrides that key to select flat rendering for a single run.

The main `Settings` dialog also offers two independent toggles, both off by default and applied immediately:

- **compact transcript rendering** (`compact_mode`): remove tool borders and padded sent-message bubbles to reduce visual chrome.
- **collapse tool call rendering** (`collapse_tool_call`): retain the header and the final non-empty rendered preview line, hiding the rest of the body. The preview may be an exit status, output line, or truncation summary. Failed calls retain an explicit error indicator. The selected boxed, flat, or compact layout stays unchanged.

Press `ctrl+o` to expand the full tool output, then press it again to restore collapsed output. These toggles live directly in `/settings`, not its `tui settings` sub-view.

## Jail mode

Type `/jail` to restrict filesystem access and apply shell guardrails for this session, or enable `jail new sessions by default` in `/settings` to apply it across launches. The PowerShell tool refuses execution while jailed. Bash refuses `sudo`, `rm -rf /`, other obvious escape patterns, and path arguments or redirections that resolve outside the sandbox. It is a guardrail against accidents, not a hard security boundary. See [Jail mode](/docs/jail) for the full behavior.

## Shell escape

Type `!` followed by a command to run it straight in your shell, no model call involved: `!mkdir foo`, `!git status`, `!ls -la` on Unix or `!dir` on Windows.

After a shell command finishes, `up` / `down` input history recalls it with the leading `!`, without its output or exit status. This also works when resuming sessions saved with command metadata. Shell commands from older sessions without that metadata remain excluded from input history.

> Shell-command history recall is an upcoming CLI fix and may not be available in your installed release.

Everything after the `!` is passed to the same shell the `bash` tool uses (`/bin/bash -c` when available on Unix, then `bash -c` from `PATH`, with POSIX `/bin/sh -c` as a fallback; `cmd /C` on Windows), runs in the session working directory, and honors the `/jail` sandbox. macOS ships Bash 3.2 by default, so newer Bash features may be unavailable. The command, merged output, and exit status are appended to the transcript as user context, so the model can use them on the next turn. Running the command does not itself start a model turn. A running `!command` shares the busy state with the agent: `esc` cancels it, and you cannot start one while a turn (or another shell escape) is in flight.
