# CLI and TUI reference
## Command line
```bash
mermaid # Start fresh session
mermaid --continue # Resume the most recent session in this directory
mermaid --resume # Pick a past session from a searchable list
mermaid --model ollama/qwen3-coder:30b # Ollama local (any installed model — `mermaid list`)
mermaid --model anthropic/<model> # Anthropic (requires ANTHROPIC_API_KEY)
mermaid --model gemini/<model> # Gemini (requires GOOGLE_API_KEY)
mermaid --model openai/<model> # OpenAI (requires OPENAI_API_KEY)
mermaid --model groq/<model> # Groq (requires GROQ_API_KEY)
mermaid --model grok/grok-4.6 # Grok (xAI) (requires XAI_API_KEY; alias xai/<model>)
mermaid --model nvidia/z-ai/glm-5.2 # NVIDIA NIM (requires NVIDIA_API_KEY)
mermaid --model cloudflare/@cf/zai-org/glm-5.2 # Cloudflare Workers AI (CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID)
mermaid --reasoning high # Override default reasoning depth
mermaid --path /path/to/project # Run against a specific project directory
mermaid --add-dir ../shared-lib # Also work in another directory with the project's trust (repeatable)
mermaid --record /tmp/session.jsonl # Record reducer events for replay/debugging
mermaid --replay /tmp/session.jsonl # Reconstruct a recorded session (headless, deterministic)
mermaid --append-system-prompt "Prefer small diffs" # Add one-off runtime instructions
mermaid --append-system-prompt-file ./rules.md # ...or append them from a file
mermaid --system-prompt "You are terse." # Replace the default prompt for one run
mermaid --system-prompt-file ./prompt.md # ...or replace it from a file
mermaid --output-style concise # Use an output style for one run (session-scoped)
mermaid -c safety.mode=full_access # Override any config key for this run (repeatable, TOML values)
mermaid --profile ci # Apply the [profiles.ci] overlay from your user config
mermaid -v # Verbose logging
mermaid list # List available models across providers
mermaid doctor # First-run readiness check
mermaid status # Lower-level Ollama, MCP, and provider config
mermaid update # Update to the latest release (or use brew/scoop)
mermaid self-test # Fast deterministic Mermaid self-test
mermaid init # Create default config file
mermaid clean-config # Delete config keys this version no longer uses (keeps a backup)
mermaid cloud-setup # Configure Ollama Cloud API key
mermaid run "fix the tests" # Non-interactive mode
mermaid run "explain main.rs" -f json # JSON output (single typed object)
mermaid run "explain main.rs" -f ndjson # Streaming NDJSON events (SDK/scripting)
mermaid run "summarize this repo" --output-schema schema.json -f json
# Structured output: the agentic loop runs
# normally, then one formatting turn reshapes
# the answer to your JSON Schema (validated
# client-side; result carries structured_output).
# Native constrained output on OpenAI-compatible
# providers, Gemini, Ollama, and Anthropic
# (output_config.format on current models).
mermaid run "/goal all tests pass" # Keep working until a check finds the goal met
# (see Goals below; the run's errors say
# when it stopped without meeting it)
mermaid --resume <id> run "and now the tests" # Continue a saved session headless (id from
# ndjson session_started/result, json result,
# or the `session:` line on stderr)
mermaid --continue run "keep going" # Resume this directory's most recent session
mermaid --no-network run "audit the code" # Deny web tools everywhere; shell network on Linux/macOS/Windows
mermaid --confine-fs run "tidy the tests" # Confine shell writes to the project, temp dir (and /dev)
mermaid --sandbox run "refactor this" # Both at once (see docs/sandbox.md)
mermaid add <name> # Add an MCP server (e.g., context7, git)
mermaid remove <name> # Remove a configured MCP server
mermaid add <name> --url <URL> # Add a remote MCP server (signs in if it uses OAuth)
mermaid mcp # List configured MCP servers
mermaid mcp login <name> # Sign in to a remote MCP server (OAuth, in the browser)
mermaid mcp logout <name> # Delete a remote MCP server's stored sign-in
```
`mermaid tasks`, `mermaid processes`, `mermaid plugin`, and the other durable-runtime verbs are
documented in [runtime.md](runtime.md).
### Added working directories
`--add-dir <dir>` (repeatable), `[workspace] additional_dirs` in your user config
([configuration.md](configuration.md)) and `/add-dir <path>` mid-session give extra directories
the same trust as the project directory:
- The file tools treat paths inside them like project paths: no outside-the-project approval or
Auto-mode review, edits are checkpointed, and writes go through the same symlink-confined
helpers with the added directory as the root. A symlink inside one that points out of it does
not count as inside, and neither does a path outside that symlinks in.
- `execute_command` with a `working_dir` inside one is not escalated.
- `--confine-fs` / `--sandbox` let shell commands write there ([sandbox.md](sandbox.md)).
- `read_only` mode still blocks writes everywhere; reads of an added directory are simply not
external reads.
- Subagents get the same list, and `/doctor` and the model's session facts name them.
Each path is canonicalized when it is added; one that does not exist is an error (at startup,
the session does not start). Flag paths resolve against the shell's current directory, config
and `/add-dir` paths against the project directory. A repository's `.mermaid/config.toml` cannot
add one. Additions made with `/add-dir` last until the session exits and are not saved.
## Keyboard shortcuts
| Key | Action |
|-----|--------|
| Enter | Send message (or queue while the model is generating) |
| Esc | Stop generation / dismiss command palette or attachment focus |
| Esc Esc | (idle) Rewind: fork the session at an earlier message — original preserved, composer pre-filled |
| Ctrl+C | Quit (auto-saves the session) |
| Ctrl+D | Quit when the input box is empty (auto-saves the session) |
| Ctrl+B | While tools are running, send the foreground command to the background (it keeps running as a `/processes` entry) |
| Alt+T | Cycle reasoning level: `None → Minimal → Low → Medium → High → XHigh → Max → None` |
| Shift+Tab | Cycle safety mode: `read_only → ask → auto → full_access → read_only` (session-scoped) |
| Ctrl+V | Paste image or text from clipboard (a copied image *file* pastes as the image) |
| Ctrl+O | Compose the prompt in `$VISUAL`/`$EDITOR` (TUI suspends, resumes on save-quit) |
| Ctrl+Click | Open image from chat history |
| Drag | Select chat text (highlights; does not copy) |
| Ctrl+Shift+C | Copy the selected chat text to the clipboard |
| Shift+Drag | Native terminal selection (bypasses Mermaid's mouse capture — useful for selecting across the whole window, including the input box and status bar) |
| `/` | Open slash-command palette (filter-as-you-type); closes itself when nothing matches |
| `@` | Open the fuzzy file picker (at the start of a word); type to filter, Tab/Enter inserts `@path`, Esc dismisses |
| Tab | In palette: complete highlighted command name |
| Up/Down | Navigate input history; palette and conversation-list navigation |
| Ctrl+R | Search earlier prompts, from this session and the project's saved sessions; type to filter, Ctrl+R or Down for the next match, Enter puts the prompt in the composer (it is not sent) |
| Mouse Wheel | Scroll chat |
### Message queuing and mid-run steering
Type while the agent works. Queued messages are delivered at the next tool boundary within the
run, so the model course-corrects mid-task, or at run end when no boundary follows.
### Image paste
Ctrl+V attaches images for vision models on X11, Wayland, macOS, and Windows. All three
clipboard shapes work on every backend: a raster copy (screenshot tools, "Copy image"), an
encoded blob with no raster form (GIMP, Figma — `PNG` with no `CF_BITMAP`), and a file reference
from a file manager's Copy (Explorer / Finder / Nautilus). File-reference pastes accept
png/jpeg/gif/webp/bmp/tiff up to 32 MB.
The paste reads the clipboard through the platform's own helper:
| Platform | Helper |
| --- | --- |
| Linux / X11 | `xclip` |
| Linux / Wayland | `wl-clipboard` (`wl-paste`) |
| macOS | `pngpaste` / `osascript` |
| Windows | PowerShell |
```bash
sudo apt install xclip # X11
sudo apt install wl-clipboard # Wayland
```
### @-mentions
Type `@` in the composer to fuzzy-pick a project file (gitignore-aware); the path lands in your
prompt as text the agent reads with its tools.
## Slash commands
Type `/` to open the command palette (shows all commands with live filter); type `/<name>` to invoke directly. `/help` shows the same commands grouped in the TUI.
A line is a command only when its first word names one. Anything else that happens to start with a slash is an ordinary message: paths (`/etc/hosts`, `/home/you/pkg.deb can you make this run on fedora`), a doubled slash (`//`), a typo, or a leading space before the slash. While you type one, the palette closes, Up/Down/Tab/Esc keep their normal meanings, and Enter sends the line exactly as written. While the line is still a bare word, a dim `No commands match "/tmp"` sits above the composer to explain why nothing is filtering; it disappears once a space follows, since a sentence needs no caption.
Everyday:
- `/doctor` — show current model, safety, prompt, instruction, and tool readiness
- `/init [focus]` — ask the agent to write AGENTS.md for this project, or improve the one there; extra words are added to the request
- `/clear`, `/save [name]`, `/load [id]`, `/list` — manage the conversation
- `/cancel [id]` — cancel the active turn or a durable task
- `/handoff [id]`, `/report [id]` — write a current-context report or inspect a task report
- `/theme [dark|light]` — switch the color theme (persisted); `NO_COLOR` disables colors entirely
- `/todos` — show or edit the task checklist the agent keeps for the current run
- `/goal [condition|clear]` — keep working until the condition is met (see Goals below); no argument shows the goal's status
- `/scratchpad` — show the session's scratch directory and what is in it
- `/add-dir [path]` — add a working directory for the rest of the session (relative paths resolve against the project directory, `~` against your home), or list the added ones. See "Added working directories" below
- `/btw <question>` — ask a side question while the agent works; see [Side questions](#side-questions)
- `/editor` — compose the prompt in `$VISUAL`/`$EDITOR` (Ctrl+O keeps the current draft)
- `/help` (`/h`), `/quit` (`/q`)
Model and context:
- `/model` — open the model picker: every model this machine can reach, local Ollama models grouped first, the active one marked, type to filter (↑↓ navigate · Enter switch · Esc cancel). Rows drop the provider their group heading already names — `mistralai/mistral-large-2-instruct` under `nvidia` — and the footer shows the highlighted row's full id, the string `/model <name>` and `--model` take. `/model <name>` switches directly; either way an Ollama model auto-pulls if needed
- `/reasoning <level>` — set reasoning: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`
- `/visible-reasoning [on|off|toggle]` — show or hide reasoning blocks in the transcript
- `/usage` — token usage for the last request and the session, and an estimated cost per model at list prices (see `[pricing]` in [configuration.md](configuration.md))
- `/context`, `/compact [instructions]`
- `/autocompact [tokens|off|on|reset] [global|project] [current-model|all-models]` — show or set when automatic compaction starts. `/autocompact 250000` compacts the current model at 250k tokens. The value goes to your user config, or to the project config with `project`; `all-models` sets it for every model. A value for one model overrides the one for all models. `off` and `on` apply to all models. `reset all-models` removes every auto-compact value from that file
- `/model-info <model>`
- `/output-style [name] [--project]` — show or set the output style (voice/format preset: `default`, `proactive`, `concise`, `explanatory`, `learning`, or a custom style file). Persists to your user config, or to the project config with `--project`; applies to the next message, subagents keep the stock prompt
Durable memory:
- `/memory` (alias `/memories`) — list the durable facts Mermaid has saved across sessions
- `/remember <fact>` — save a fact to durable memory
- `/forget <name>` — delete a saved memory by name
- `/consolidate-memory` (aliases `/memory-consolidate`, `/prune-memory`) — merge duplicates and prune stale memories
Safety and recovery:
- `/safety [read_only|ask|auto|full_access]` (alias `/permission`) — show or set the session safety mode; Shift+Tab cycles it
- `/approvals`, `/approve <id>`, `/deny <id>`
- `/checkpoint <path...>`, `/checkpoints`, `/restore <id>`
Integrations:
- `/plugins`, `/cloud-setup`
Advanced runtime:
- `/tasks`, `/task <id>`, `/pause <id>`, `/resume <id>`
- `/agents` — list background subagents, or kill one
- `/processes`, `/logs <id>`, `/stop <id>`, `/restart <id>`, `/open <target>`, `/ports`
### Goals
`/goal <condition>` sets a completion condition and starts a turn with the condition as the
request. Each time the run would end, a separate model call reads the latest part of the
conversation and answers met, not met, or impossible. Not met starts the next turn with the
check's reason and the goal restated; the transcript shows both. Met or impossible clears the
goal. One goal is active at a time; a new `/goal` replaces it.
The check judges only what the conversation shows, so write a condition the agent's own tool
output can prove: "`cargo test` passes and `cargo clippy` is clean", not "the code is good". To
bound a goal, say so in the condition ("or stop after 10 turns"); the check sees how many checks
have run.
The goal pauses, still set, when you press Esc, when a turn fails, after `[goal] max_turns` goal
turns without a message from you (default 50), or after 3 goal turns in a row with no tool call.
Send a message to continue, or `/goal clear` (also `stop`, `off`, `reset`, `none`, `cancel`) to
remove it. A message you send while the goal runs goes first, and the goal is checked again after
it. The footer shows `goal 4m` while a goal is set. `--resume` and `--continue` keep the goal;
it runs again after your next message.
The check uses the session's model unless `[goal] model` names another (see
[configuration](configuration.md)); its tokens count toward the session's spend. Headless,
`mermaid run "/goal <condition>"` runs the loop to the end; a goal that did not end met adds a
`goal:` line to the run's errors. The 20-minute limit of a headless run still applies.
Reasoning choices persist per-model: set `/reasoning high` on one model and `/reasoning low` on another, and each is remembered independently across sessions.
### Side questions
`/btw <question>` asks about the current work without adding to the conversation:
```
/btw what was the name of that config file again?
```
The model answers from what the session already holds: your messages, its replies, and the tool results it has gathered. It sees everything except the reply still being written. You can ask while the agent works; the side question runs as its own model call and does not interrupt the main turn. It has no tools, so it cannot read files, run commands, or search; if the model asks for a tool anyway, the answer says that nothing was run.
The question and its answer never enter the conversation. They are not saved, not compacted, and not sent with later turns. A later side question does see your earlier ones (the newest 20), so you can ask a follow-up. The answer shows in a pane under the composer:
| Key | Action |
| --- | --- |
| Esc, Enter, Space | Close the pane |
| Up / Down | Scroll the answer |
| Left / Right (or `[` / `]`, Tab / Shift+Tab) | Step to older / newer side questions |
| `c` | Copy the answer as raw Markdown |
| `f` | Fork: start a background agent that carries on from this answer with full tools |
| `x` | Clear the earlier side questions, keeping the one on view |
The five newest earlier questions show dimmed above the current one. Run `/btw` with no question to reopen the pane on the newest answer; if an answer arrives after you close the pane, a short note says it is ready. `/clear`, `/load`, and a rewind fork start a fresh side-question thread. Because the side question sends the same prompt as the main turn, a provider prompt cache that is still warm makes it cheap.
The fork (`f`) is for an answer you want to act on. The agent starts from the whole conversation plus the side question and its answer, runs in the background like a Ctrl+B agent, and does not interrupt the main turn. `/agents` lists it, and its report is posted to the conversation when it finishes. Wait for the answer to finish before you fork it.