# Quickstart Source: https://verdeai.dev/docs/quickstart Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/quickstart.md ## Install Install the latest Verde release from the website. On Linux or macOS: ```bash curl -fsSL https://verdeai.dev/install.sh | sh ``` On Windows x64, open PowerShell and run: ```powershell irm https://verdeai.dev/install.ps1 | iex ``` The installers download the matching release artifact from GitHub and verify it before installation. Linux installs into `~/.local`, macOS installs into `/Applications` and links its CLI at `~/.local/bin/verde`, and Windows installs the complete app and runtime package into `%LOCALAPPDATA%\Programs\Verde`, creates a Start Menu shortcut, and launches the app. On macOS with zsh, the installer adds `~/.local/bin` to `~/.zprofile` when needed; open a new terminal before running `verde`. The Windows install does not require administrator access and adds its `bin` directory to the current user's `PATH`; open a new terminal before running `verde`. For other paths — Arch Linux via the AUR, an npm launcher, a custom prefix, or a source build — see the [install section on the homepage](/#install). On Linux, the embedded browser pane uses the system WPE WebKit runtime. The installer will warn if the required libraries are missing and print the package command for your distribution. You can let it install them by setting `VERDE_INSTALL_BROWSER_DEPS=1` before running it. ## Authenticate a provider Verde does not host a model. It drives the coding-agent CLIs already installed on your machine, so install and authenticate a GUI provider or install a terminal-only provider before launching the app: | Provider | Setup | | ----------- | ---------------------------------------------------------------------------------- | | Codex | Install the [Codex CLI](https://github.com/openai/codex), then run `codex login`. | | Claude Code | Install [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and Node.js, ensure `node` is on `PATH`, then log in. | | OpenCode | Install [OpenCode](https://github.com/anomalyco/opencode); ensure `opencode` is on `PATH`. | | Cursor | Install the [Cursor CLI](https://cursor.com/docs/cli/installation), ensure `agent` is on `PATH`, run `agent login`. `CURSOR_API_KEY` is also supported for headless environments. | | Pi | Install [pi](https://pi.dev); ensure `pi` is on `PATH`. Pi drives Verde's native chat panes (`pi --mode rpc`) and can also launch as a terminal TUI. | | FX | Install [fx](https://fx.sh) with its setup script, then run `fx login`. FX drives Verde's native chat panes (`fx acp`) and can also launch as a terminal TUI. | | Grok Build | Install [Grok Build](https://docs.x.ai/build/overview#install); ensure `grok` is on `PATH`, then run `grok login`. Grok drives Verde's native chat panes and can also launch as a terminal TUI from the command palette. | | Amp | Install [Amp](https://ampcode.com); ensure `amp` is on `PATH`. Amp runs as a terminal TUI rather than a chat pane — launch it from the command palette. | See [Provider setup](/docs/providers) for the full per-provider notes. ## Launch ```bash verde ``` The first launch opens an empty workspace. If no GUI provider is ready, the **Connect an AI provider** screen shows which CLIs are missing, need sign-in, or are ready. Finish setup and choose **Check again**, or choose **Not now** to continue without a chat provider. The sidebar on the left lists your projects and threads; the main area is where chat, terminal, and browser panes live as a tiling tree. ## Import a project Right-click the sidebar or click the **+** button to import a project. Verde watches the project directory you import; threads, processes, and agents all operate against that workspace root. A project can optionally declare a stack in `verde.yml` (or `verde.yaml`) at its root — long-running processes and agent CLIs to drive from the terminal dock. See [Configuration & state](/docs/config) for the schema. ## Start a chat thread 1. With a project imported, click the workspace pencil to create a new chat thread. With prefix mode enabled, you can instead press `Ctrl+B`, then `c`. 2. Open the searchable model picker. Before the first message you can choose both the provider and model; after that, the provider stays bound to the thread. 3. Open the **Run** pill to choose available reasoning and speed options, plus **Supervised** or **Full access** command permissions. 4. Type a prompt and press `Enter` to send. The transcript grows as the agent streams; consecutive tool calls collapse into a status summary you can expand. 5. Press `Tab` while focused in a chat thread to return focus to the prompt box. See [Chat, models & runs](/docs/chat) for provider readiness, model shortcuts, follow-ups, approvals, and transcript preferences. ## Tile a browser pane Press `Ctrl+Shift+B` to toggle the embedded browser pane next to the focused chat. On Linux it uses WPE WebKit, on macOS WKWebView, on Windows WebView2 — never a bundled Chromium. Use it to keep docs, a preview server, or a staging URL in view while the agent works. You can drive the browser pane from the CLI too: ```bash verde live browser open --url http://localhost:3000 verde live browser navigate --url http://localhost:3000/dashboard verde live browser eval --script "document.title" ``` Click the browser inspector to enter **Design Mode**. Select an element, box, or freeform region; describe the change; then route the resulting context to a chat or terminal agent. See [Design Mode](/docs/design-mode) for platform screenshot support and delivery behavior. ## Split a terminal With prefix mode enabled, press `Ctrl+B`, then `t` to add a new terminal tab at the end of the strip, or `Ctrl+B`, then `Shift+T` to create a standalone terminal pane beside the focused one. To tile a terminal inside the focused pane instead, use the shifted `v` / `-` split chords or the pane header's terminal split buttons. Right-click inside a terminal for configured custom launch profiles and pane actions. Launch built-in provider TUIs from `Ctrl+Shift+P` or `verde live agent open --provider `. Per-terminal zoom (`Ctrl+-` / `Ctrl+=`) and the full layout persist across launches. ## Move around Workspaces automatically enter scrolling layout at two panes. Change the global or current-workspace threshold under **Settings → Workspace**, or set a workspace override to **Automatic**, **Always**, or **Disabled** directly from the command palette. **Use Global Default** clears that override. The palette also provides **Previous Pane** and **Next Pane** actions. - `Ctrl+Arrow` — move focus across panes - Optional: bind `workspace.focus_left/down/up/right` to `Ctrl+H/J/K/L` in `verde.json` - Horizontal touchpad/wheel, or `Ctrl`+vertical wheel in vertical mode — pan the scrolling pane strip - Drag a scrolling pane's trailing edge — set a persistent custom column width - `Ctrl+Shift+H / J / K / L` — swap the focused pane with its neighbor (rearrange the tiling) - `Alt+Shift+← ↑ ↓ →` — resize the focused pane - `Alt+Z` — zoom the focused pane to fill the workspace; press again to restore - `Alt+1 … Alt+9, Alt+0` — jump between workspaces by sidebar order - `Alt+↑ / Alt+↓` — cycle to the previous / next workspace The full set of defaults and how to remap them is in [Keybinds](/docs/keybinds). ## Open the command palette `Ctrl+Shift+P` opens a Raycast-style launcher that ranks chat threads, open panes, workspaces, and app commands in a single searchable list. Press `Ctrl+Enter` on any result to open it in a fresh pane. Closing a workspace with prefix `Shift+X` removes it from the active sidebar but keeps its layout and threads. Use the command palette's reopen action to bring it back. Slash commands like `/stack` and `/process` run from the composer alongside each provider's own commands. See [Panes & tiling](/docs/panes) for the full pane surface. ## Where to go next - [Provider setup](/docs/providers) — provider-specific notes and troubleshooting. - [Chat, models & runs](/docs/chat) — model selection, run permissions, approvals, and transcript controls. - [Design Mode](/docs/design-mode) — send browser selections to chat and terminal agents. - [Panes & tiling](/docs/panes) — splits, focus, resize, zoom, the terminal dock, and the browser pane. - [Keybinds](/docs/keybinds) — every default and how to remap. - [CLI reference](/docs/cli) — drive Verde from your shell with `verde live` and `verde state`. - [Configuration & state](/docs/config) — `verde.json`, `verde.yml`, themes, Omarchy integration. - [Troubleshooting](/docs/troubleshooting) — provider auth, browser runtime, source-build issues. --- # Provider setup Source: https://verdeai.dev/docs/providers Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/providers.md ## How providers work Verde does not host a model and does not relay your prompts through a hosted backend. It spawns and talks to the coding-agent CLIs you already have on your machine, and supports each agent in one or both of two modes: - **GUI chat** — the provider drives Verde's native chat panes over its own protocol: streaming transcript, composer, slash commands, approvals. - **Terminal TUI** — Verde launches the agent's own TUI inside an embedded Ghostty terminal pane, wired into the sidebar's live status pips. | Provider | GUI chat | Terminal TUI | How the GUI integration talks | | ----------- | -------- | ------------ | -------------------------------------------------------------- | | Codex | ✓ | ✓ | Runs the local `codex` CLI; boots `codex app-server` per thread | | Claude Code | ✓ | ✓ | Anthropic's Claude Agent SDK against the local runtime | | OpenCode | ✓ | ✓ | Drives the `opencode` CLI; starts `opencode serve` on demand | | Cursor | ✓ | ✓ | Speaks to the Cursor CLI ACP server (`agent acp`) | | Pi | ✓ | ✓ | Drives `pi --mode rpc` (JSONL over stdio), one process per turn | | FX | ✓ | ✓ | Speaks ACP to the `fx` CLI (`fx acp`), one process per turn | | Grok Build | ✓ | ✓ | Speaks ACP to the `grok` CLI (`grok agent stdio`), one process per turn | | Amp | – | ✓ | TUI-only — launches the `amp` CLI in a terminal pane | All of them run against the project directory you imported into Verde. Tokens, transcripts, and project files stay on your machine. ## Readiness check If none of the GUI providers is available at launch, Verde opens **Connect an AI provider**. Each provider reports **Ready**, **CLI not found**, **Sign-in needed**, or **Could not verify** while Verde checks its executable and local authentication. Install or sign in using the instructions below, then choose **Check again**. **Open setup guide** returns to this page and **Not now** dismisses the screen. Amp is excluded from this check because it is TUI-only. A GUI provider can also become unavailable later—for example, after credentials expire—in which case sending shows an explicit error instead of dropping the prompt. ## Codex Install the [Codex CLI](https://github.com/openai/codex) and authenticate: ```bash codex login ``` Verify `codex` is on `PATH` from a normal shell. Verde starts `codex app-server` when a Codex thread begins; you do not need to start it yourself. Codex threads expose **Default** and **Fast** under the composer's **Run** pill. The setting maps to Codex's `service_tier` / `fast_mode`. The Run menu also shows the reasoning levels supported by the selected model and the thread's access setting. ## Claude Code Install [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and log in on your machine. Verde talks to the local runtime through Anthropic's Claude Agent SDK — there is no Verde-side authentication. Make sure the Claude Code binary and `node` are both reachable from the shell environment Verde was launched from. Packaged Verde installs include the provider bridge; Verde runs it with the Node.js executable found on `PATH`. ## OpenCode Install [OpenCode](https://github.com/anomalyco/opencode) and verify `opencode` is on `PATH`. Verde starts `opencode serve` on demand when an OpenCode thread begins. OpenCode does not have a Codex-style speed tier concept, so the **Speed** row is hidden when OpenCode is selected. ## Cursor Install the [Cursor CLI](https://cursor.com/docs/cli/installation), make sure `agent` is on your `PATH`, and authenticate: ```bash agent login ``` `CURSOR_API_KEY` is also supported for headless environments where interactive login is not possible. Verde talks to the Cursor ACP server (`agent acp`) over its native protocol. Cursor models that advertise fast-mode support show **Default** and **Fast** under the **Run** pill. The row is hidden for Cursor models without that capability. ## Pi Install the [pi coding agent](https://pi.dev) and verify `pi` is on `PATH`. Verde drives pi in its programmatic RPC mode (`pi --mode rpc`, JSONL over stdio), starting one process per turn and resuming the same pi session for follow-up turns, so `pi` in a terminal sees the same project sessions. Pi authenticates against model providers through its own configuration (`pi login`, or API keys in pi's settings) — there is no Verde-side authentication. The readiness check reports **Sign-in needed** when the model provider currently selected in pi is not authenticated. The default model entry, **Default (pi config)**, defers to the model configured in pi itself; the model picker also lists every model pi reports as available, using pi's `provider/model` refs. Reasoning levels map one-to-one onto pi thinking levels (low through max). Pi has no Codex-style speed tier, so the **Speed** row is hidden. Existing pi sessions for the imported project can be imported as Verde threads (pi stores them per project directory). Pi does not use Verde's slash-command surface yet. To use the interactive TUI instead, open the current Pi thread with **Open Current Thread in TUI**, or launch `pi` in a terminal pane. ## FX Install [fx](https://fx.sh) with its setup script and authenticate against Vercel AI Gateway: ```bash curl -fsSL https://fx.sh/setup.sh | bash fx login ``` Verify `fx` is on `PATH` from a normal shell. Desktop launches often miss the installer location, so Verde also looks for `~/.local/bin/fx`. Verde drives fx through its Agent Client Protocol server (`fx acp`), starting one process per turn. The readiness check reports **Sign-in needed** until `fx login` has cached a usable Vercel AI Gateway credential. The default model entry, **Default (fx config)**, defers to the model persisted inside fx itself; the model picker also lists every model fx reports through ACP `configOptions`. FX has no reasoning-effort or speed-tier controls, so those rows are hidden. Image attachments are forwarded when the ACP session advertises image support; fx 0.0.8 and later advertise it and reject any single image above 3.75 MiB, which Verde reports as the failed turn's message. FX does not use Verde's slash-command surface yet, and existing fx sessions cannot be imported as Verde threads yet. To use the interactive TUI instead, open the current FX thread with **Open Current Thread in TUI**, or launch `fx` in a terminal pane. ## Grok Build Install Grok Build using its [official setup guide](https://docs.x.ai/build/overview#install) and make sure `grok` is on the `PATH` inherited by Verde, then run `grok login` once. Verde drives Grok through its Agent Client Protocol server (`grok agent stdio`), starting one process per turn and resuming the same grok session for follow-up turns, so `grok --resume` in a terminal sees the same threads. The readiness check reports **Sign-in needed** until `grok login` has cached a token. The default model entry, **Default (grok config)**, defers to the model persisted in grok itself; the model picker also lists every model grok reports (Grok 4.6, Grok 4.5, …). Reasoning levels map onto grok's reasoning efforts (low through extra high; there is no `max`). Grok has no speed tier, so the **Speed** row is hidden. Image attachments are forwarded to Grok; note that grok drops images smaller than about 512 pixels total without reporting an error. Grok loads Verde's MCP server from its own global config, so tool calls appear as command rows in the transcript. Existing grok sessions cannot be imported as Verde threads yet. Grok's own slash commands run through Verde's composer: the picker lists the built-ins (`/compact`, `/context`, `/session-info`, `/always-approve`, `/feedback`, `/review`, `/implement`, `/design`, `/deep-research`, `/goal`, `/loop`, `/workflow`, `/plugins`, `/hooks-list`), and any other command or installed skill grok advertises (for example `/figma-use` or `/omarchy`) is forwarded as typed. Verde sends the `/name args` text as a prompt turn, grok resolves it, and the reply lands in the thread as a system row. If Verde cannot find it, open `Ctrl+Shift+P` and run **Set Up Grok Build**. To use the interactive TUI instead, use **Start New Grok TUI** or: ```bash verde live agent open --provider grok ``` Verde checks `PATH` without running Grok and launches managed sessions with `grok --no-auto-update` so an update check cannot disrupt the PTY. A managed launch also attempts to install Verde's isolated personal status hook. You can manage it explicitly in **Settings → Status pip hooks** or from the CLI: ```bash verde integrations install grok --global verde integrations remove grok --global ``` The hook lives at `$GROK_HOME/hooks/verde-notify.json`, defaulting to `~/.grok/hooks/verde-notify.json`, and remains inert unless Grok inherited a Verde terminal identity. It reports idle, working, waiting, done, and error activity to the pane and sidebar. After a session completes, Verde also best-effort synchronizes Grok's generated session title when its summary file becomes available. ## Amp Install [Amp](https://ampcode.com) and make sure `amp` is on your `PATH`. Amp is **TUI-only**: it does not appear in the chat composer's provider switcher. Instead, launch it from the command palette (`Ctrl+Shift+P` → **Start New Amp TUI**) and Verde opens the `amp` CLI in a new embedded terminal pane in the current workspace. To wire Amp into the sidebar's live status pips, install Verde's Amp plugin: ```bash verde integrations install amp --global ``` That writes a small lifecycle plugin to `~/.config/amp/plugins/verde-notify.ts` which reports `working` / `done` / `error` to the pane's status pip as the agent runs (only when Amp is running inside a Verde pane). You can also toggle it from the settings modal under **Status pip hooks**, and remove it with `verde integrations remove amp --global`. ## Models and run settings The searchable model picker groups models by provider, marks defaults, and supports `Ctrl+1` through `Ctrl+9` for its visible results. OpenCode, Claude Code, Cursor, Pi, FX, and Grok model lists are loaded from the installed provider; Codex uses Verde's supported model list. Before a new thread sends its first message, choosing a model can also switch the provider. Once the transcript has started, the provider is locked to keep the provider session consistent. The **Run** pill contains only controls the selected provider/model supports: reasoning, **Default/Fast** speed, and **Supervised/Full access** permissions. See [Chat, models & runs](/docs/chat) for the complete behavior. To run several providers side by side, create additional chat threads (one per provider) and tile them in the same workspace. Each thread keeps its own provider, model, and transcript; the layout is shared. ## Driving provider CLIs from terminal docks You can also launch any provider's TUI directly inside a terminal pane — useful when you want the agent's native UI rather than Verde's chat surface. The command palette (`Ctrl+Shift+P`) has a **Start New … TUI** entry for each of Codex, Claude, OpenCode, Cursor, Grok, and Amp, plus **Open Current Thread in TUI** entries that promote a running GUI chat thread — including Pi, FX, and Grok — into that provider's terminal TUI. Launch `pi` in a terminal pane for a fresh Pi TUI. Right-clicking inside a terminal offers configured custom launch profiles and pane actions; use the palette or CLI for built-in provider TUI actions. From the CLI: ```bash verde live agent open --provider codex verde live agent open --provider grok verde live process restart --name codex ``` The first two commands open managed provider TUIs without requiring a `verde.yml` entry. Verde detects Grok from `PATH` without running it, offers a setup-guide action when it is absent, and launches it with `--no-auto-update`. The last command launches or restarts a Codex agent declared in your `verde.yml` `agents:` block. See [Configuration & state](/docs/config) for the stack schema and the [CLI reference](/docs/cli) for the full command surface. ## Troubleshooting provider auth If prompt sending fails, check in this order: 1. **Is the provider installed?** `which codex`, `which opencode`, `which agent`, `which pi`, `which fx`, `which grok`, etc., from the shell Verde was launched in. GUI launches on some platforms inherit a different `PATH` than a terminal — relaunch Verde from a terminal if you suspect this. 2. **Is the provider authenticated?** Re-run the provider's login command (`codex login`, `agent login`, `fx login`, `grok login`, `pi login`, etc.) and confirm credentials are still valid. 3. **Is the project imported?** Verde runs the provider against the imported project directory. A provider CLI in a different working directory will not see the same files. 4. **Check the logs.** Provider helper stderr is written to the runtime log alongside Zig panics. On Linux: ```bash tail -f ~/.local/share/verde/Native/logs/verde.stderr.log ``` For broader install and runtime issues, see [Troubleshooting](/docs/troubleshooting). --- # Chat, models & runs Source: https://verdeai.dev/docs/chat Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/chat.md ## Connect a provider Verde checks the GUI-chat providers—Codex, Claude Code, OpenCode, Cursor, Pi, FX, and Grok Build—when the app opens. If none is ready, the **Connect an AI provider** screen reports one of these states for each provider: - **Ready** — the CLI is installed and authenticated. - **CLI not found** — install the provider and make sure its executable is on the `PATH` inherited by Verde. - **Sign-in needed** — run the provider's login flow, then return to Verde. - **Could not verify** — the readiness check failed or timed out. After installing or signing in, choose **Check again**. **Not now** dismisses the screen without changing provider configuration. Amp is not listed because it runs as a terminal TUI rather than a native chat provider. See [Provider setup](/docs/providers) for the exact install and login commands. ## Choose a provider and model Create a chat with the workspace pencil—or `Ctrl+B`, then `c` when prefix mode is enabled—then open the model pill in the composer. The picker has a provider rail, model search, default-model badges, and `Ctrl+1` through `Ctrl+9` shortcuts for the visible results. Before the first message is sent, selecting a model from another provider also switches the thread's provider. Once a thread has messages, its provider is locked so the transcript and provider session stay consistent; create another thread to use a different provider. Verde loads the available models from OpenCode, Claude Code, Cursor, Pi, FX, and Grok at runtime. Codex models come from Verde's supported model list. A provider that is missing or signed out remains visible with a readiness hint instead of silently accepting a prompt it cannot send. ## Configure a run The **Run** pill groups the settings that affect the next agent run: - **Reasoning** appears only when the selected provider and model expose a reasoning-effort control. - **Speed** appears for Codex and for Cursor models that support fast mode. Choose **Default** or **Fast**. - **Access** is always available. **Supervised** asks before risky commands; **Full access** lets the agent run commands without asking first. Access is saved per thread. Reasoning and speed options can change when you switch models because not every provider exposes equivalent controls. ## Send, steer, and stop Press `Enter` to send the composer. While an agent is working, type another message and press `Tab`: Codex, Claude Code, and Pi try to steer the active turn, while OpenCode, Cursor, FX, and Grok queue the message as the next turn. The pending message stays pinned above the composer. Double-click that pin to pull it back into an empty composer for editing, then press `Tab` to queue it again. **Stop** aborts the active run. Verde keeps the draft with its thread, so changing panes does not discard unfinished text. Drafts — including staged image attachments — persist with the thread across pane switches and app restarts. Runs are owned by Verde's session daemon rather than the window: once a send is accepted, the turn keeps running and its transcript lands durably even if the desktop app is closed or restarted mid-turn. The same paths are scriptable with `verde live chat send`, `followup`, `stop`, and `draft`, and are exposed to agents over MCP (including daemon-direct `read_chat_thread` and `queue_chat_followup`). See [CLI reference](/docs/cli#chat-control). ## Attach images and mention files Paste an image with `Ctrl+V` (`Cmd+V` on macOS) while the chat composer owns focus. Verde stages it above the composer instead of converting it to text. Paste again to attach multiple images, remove individual previews before sending, and click a transcript image to open its full-size preview. Staged attachments are persisted with the thread's draft, so they survive switching threads or restarting the app, and sent images remain viewable in the saved transcript. Codex, Claude Code, OpenCode, Pi, and Grok accept local image attachments. Cursor and FX accept them when their ACP session advertises image support. To reference a workspace file, type `@` followed by part of its name or path. Verde searches the imported workspace, shows up to eight matching files, and inserts the selected relative path into the prompt. Use the arrow keys and `Enter`, or click a result. ## History and provider threads Each workspace ends with a **History · N** row in the expanded sidebar. It opens the command palette scoped to that workspace's saved chats, grouped into **Today**, **This week**, and **Older**. Search there to find a thread, press `Enter` to open it in an existing chat pane, or `Ctrl+Enter` to open it in a new pane. Press `Tab` on a result for thread actions. Right-click a workspace—or use `Ctrl+Shift+P`—to import an existing Codex, OpenCode, Claude Code, or Pi provider thread. The import dialog lists recent provider sessions and also accepts a provider thread ID. Cursor, FX, and Grok thread import is not supported yet. Imported and Verde-created provider threads can be refreshed with **Sync thread** when they have a provider thread ID and no request is running. The same thread menu can open a linked thread in its provider TUI, return a TUI thread to chat, or archive the thread. Archiving removes it from the active sidebar without deleting its persisted transcript. ## Approvals and input requests Providers can pause a run for approval. Verde renders the request in the transcript and lets you approve or deny it without leaving the chat pane. Codex MCP yes/no confirmations use this same approval surface. Structured MCP forms are not supported yet; Verde marks the input request unsupported and declines it rather than guessing an answer. **Full access** reduces command approvals, so use it only for workspaces and instructions you trust. ## Tool-call groups Consecutive tool calls collapse into a summary row showing the number of calls and their completed, failed, or running state. Click the row to inspect the individual calls. A group containing a failure opens by default so the error is not hidden. Choose the default under **Settings → Transcript → Tool call groups**: - **Collapsed** — start each group closed unless it failed. - **Expanded** — start each group open. - **Remember last** — reuse the last state you chose. The same preference is available as `transcript.tool_call_groups` in [`verde.json`](/docs/config#verdejson). ## Design feedback from the browser For UI work, Design Mode can select an element or region in the browser and send its DOM context—and, where supported, a screenshot—straight to a chat or terminal agent. See [Design Mode](/docs/design-mode). --- # Design Mode Source: https://verdeai.dev/docs/design-mode Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/design-mode.md ## Start Design Mode Open your app in Verde's browser pane, then click the inspector button beside the address bar. Design Mode overlays the page so you can turn a visual target into an agent-ready prompt without describing its location by hand. Use the inspector's dropdown to choose a selection mode: - **Point** — click one DOM element. - **Draw Box** — drag a rectangular region. - **Draw Freeform** — draw around an irregular region. Design Mode works on `app://` content and HTTP(S) pages, including localhost preview servers. It is unavailable on restricted URL schemes such as `file:`, `data:`, and `about:`. ## Describe the change After making a selection, type the requested change in the prompt bubble. Verde adds selection context such as the page URL, element details, and selected geometry. This gives the agent both your instruction and a stable description of what you pointed at. The selection overlay belongs to the page preview; it does not edit the page or source files by itself. The receiving agent still decides what code to inspect and change. ## Choose where to send it When more than one compatible agent pane is open, **Send to** lets you choose a chat thread or terminal TUI. With only one target, Verde selects it automatically. - An idle chat with a clean composer sends immediately. - A working chat can receive the request as a queued follow-up. - If the chat already has an unsent draft, Verde preserves it and places the Design Mode request in the composer instead of overwriting or unexpectedly sending the draft. - A terminal TUI receives the prompt as pasted input but does not submit it. Review or edit the text in the TUI, then press `Enter` yourself. ## Screenshots and platform support All native browser backends support the selection overlay and text context: WPE WebKit on Linux, WKWebView on macOS, and WebView2 on Windows. Selection screenshots currently require the Linux WPE backend's frame-copy support. On macOS and Windows, Design Mode still sends the instruction and DOM selection context without an image. If a screenshot is captured, chat targets receive it as an attachment; terminal targets receive its local file path in the pasted prompt. ## Control Design Mode from the CLI The live CLI can enable the inspector and select its mode: ```bash verde live browser inspector-enable verde live browser inspector-mode --mode point verde live browser inspector-mode --mode draw-box verde live browser inspector-mode --mode draw-freeform verde live browser inspector-disable ``` `inspector-toggle` is also available. Add `--json` for automation, and use the other browser commands to open or navigate the preview first. See [CLI reference](/docs/cli#browser-control). --- # Panes & tiling Source: https://verdeai.dev/docs/panes Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/panes.md ## Workspace anatomy Each Verde window is one workspace tied to an imported project. Inside a workspace you get a tiling tree of panes — chat threads, terminals, and a browser pane — that share the main area. The sidebar on the left lists projects and threads; the main area is the tiling surface; the terminal dock is a terminal pane living in the same tree as chat and browser panes. A detached quick or companion pane is an overlay and stays fixed above that surface. Tiled panes, the scrolling strip, and detached overlay geometry persist across launches. ## Splitting panes Splits come from the prefix table and the pane header buttons. With prefix mode enabled, `Ctrl+B`, then `c` adds a new tab (chat by default) and `Ctrl+B`, then `t` adds a terminal tab in the same place. `Ctrl+B`, then `Shift+T` creates a separate top-level terminal pane. Use `v`, `-`, `Shift+V`, or `Shift+-` when you want a tiled split inside the focused scrolling item. With prefix mode enabled, `Ctrl+B`, then `v` creates a vertical split of the configured default pane type (chat or terminal) inside the focused pane; `Ctrl+B`, then `-` creates the matching horizontal split. `Shift+V` and `Shift+-` create the other type. The same keys work after `Ctrl+B W`. In a scrolling workspace the panes stay tiled together as one scrolling item, and the sidebar shows the same split as a clickable miniature instead of flattening it into unrelated pane rows. For chat-vs-chat splits and terminal splits, use the pane header grid menu or the right-click **Split Pane** submenu. Those actions tile inside the focused scrolling item instead of adding a new strip pane. Right-click terminal content for selection copy, zoom, the same workspace splits around the focused pane, and **Close pane**. Right-click a terminal tab to rename or close it. If `terminal.profiles` is configured in `verde.json`, the first custom launch profile also appears in the terminal context menu. Use `Ctrl+Alt+T` for a new shell tab. Launch Codex, Claude, OpenCode, Cursor, Pi, FX, Grok, or Amp TUIs from the command palette, or open a running GUI thread in TUI; the built-in agent launchers are not entries in the terminal right-click menu. Terminal-internal tabs live inside the focused terminal pane. Workspace split actions create new workspace panes in the tiling tree, not new tabs inside a terminal. ## Moving focus - `Ctrl+Arrow` — focus the pane in that direction. - `Ctrl+H / J / K / L` are unbound by default; map the existing `keybinds.workspace.focus_left/down/up/right` actions to opt into vim-style focus. - Horizontal touchpad/wheel gestures pan a horizontal strip independently of focus. In vertical mode, hold `Ctrl` while using the vertical wheel so normal terminal and transcript scrolling remains available. - `Tab` — while focused inside a chat thread pane, return focus to the prompt box. - `Alt+1 … Alt+9, Alt+0` — jump between workspaces by sidebar order. - `Alt+↑ / Alt+↓` — cycle to the previous / next workspace. By default, Verde automatically switches to a scrolling strip when a workspace reaches two tiled panes, keeping the same order shown in the sidebar. **Settings → Workspace → Scrolling layout** can keep that automatic behavior, pin the scrolling layout with **Always**, or retain the split tree with **Disabled**. **Activation threshold** changes the automatic trigger from 1–64 panes. Use **Scrolling settings scope** to edit the global defaults or override mode and threshold only for the currently selected workspace. Workspace overrides and scroll positions both survive restart. The command palette also exposes **Scrolling Layout: Automatic**, **Always**, and **Disabled** to set an immediate override for the current workspace; **Scrolling Layout: Use Global Default** clears it. Use **Previous Pane** and **Next Pane** there to move through panes in sidebar order; the displayed shortcut follows the selected scroll direction. **Scroll direction** chooses a horizontal strip (the default) or vertical strip. **Panes per view** controls how many panes fit along that axis (1–6, default 2), and **Pane spacing** controls their gap. Manual wheel or touchpad scrolling is intentionally free-form, so the strip can stop with part of a pane visible like Niri. Adjacent focus movement scrolls just far enough to reveal the complete focused pane. Direct jumps from the sidebar, command palette, or numbered pane shortcut place the selected pane at the strip's leading edge (left in horizontal mode, top in vertical mode), including the final pane. Horizontal and vertical positions are restored independently per workspace; zoom temporarily fills the workspace without changing either saved position or the selected scrolling policy. Hovering the leading or trailing edge of the strip peeks to the adjacent pane without changing focus. In scrolling mode, every tiled workspace pane becomes one column (or row) in sidebar order. Existing nested split geometry is flattened for the strip; browser tabs remain inside their single browser pane, and detached quick or companion panes remain fixed overlays rather than joining the strip. ## Resizing - `Alt+Shift+← ↑ ↓ →` — grow the focused pane in that direction. - Drag the divider between two workspace panes to resize the split manually. - In scrolling layout, drag a pane's trailing edge to resize all columns within a 240–1600 px range. The custom width persists for that workspace; run **Reset Scrolling Column Width** from the command palette to return to **Panes per view** sizing. Resizes are committed to the layout immediately and persist with the workspace. ## Rearranging panes - `Ctrl+Shift+H / J / K / L` — move the focused pane past its neighbor in that direction. - `Ctrl`-drag a pane — pick it up with the mouse and drop it where it should go. - Drag pane rows in the sidebar to reorder them (scrolling strip order follows). Use these when the layout is right but a pane is in the wrong place. Moves are non-destructive — every pane keeps its content and provider. ## Zooming and closing - `Alt+Z` — zoom the focused pane to fill the workspace; press again to restore. - Pane context menu — close the pane (or prefix `x` when prefix mode is on). After the last pane is gone, prefix `x` again closes the empty workspace. ## The sidebar The left rail shows a pinned **ACTIVE** cluster of live, waiting, and recently finished work across workspaces, then the project tree beneath it. Each pane row carries its provider glyph and a live title, so you always know what is working without switching to it. ACTIVE stays put while you scroll the workspace list; if more than about ten rows need attention, that cluster scrolls on its own instead of burying the tree. - `Ctrl+S` — toggle the sidebar (visible ↔ icon rail). - `Ctrl+Shift+S` — toggle the sidebar's hidden mode (no rail at all). When collapsed to the icon rail, each workspace avatar carries a row of small **status pips** — one dot per open pane, in layout order. Pips pulse green while an agent is working, yellow while it waits for input, and settle when it's done or errors, so you can watch several agents from a rail a few pixels wide. Context menus (new thread, close, expand) still work from the collapsed rail. Right-click the sidebar for project import, rename, and **Close workspace**, and use the new-thread / pencil button to open a Codex TUI directly. Closing a workspace archives it without deleting its saved panes, threads, or layout. Use the command palette's reopen action—or `verde live workspace reopen`—to restore it. ## The terminal dock Verde's embedded terminals are powered by Ghostty's `libghostty-vt` terminal engine. Each terminal pane is a full terminal with tabs, splits, OSC titles, scrollback with a scrollbar, and per-terminal zoom. - `Ctrl+Alt+T` — new terminal tab inside the focused terminal pane. - `Ctrl+Shift+R` — rename the active terminal tab. - `Ctrl+Shift+PageUp` / `Ctrl+Shift+PageDown` — previous / next terminal tab. - `Ctrl+Alt+↑ ↓ ← →` — move focus between terminal splits inside the focused terminal pane. - `Ctrl+-` / `Ctrl+=` — per-terminal zoom; restored with the terminal layout. Per-terminal zoom is independent of the workspace-level zoom (`Alt+Z`). It persists per terminal surface, not per workspace. Terminal applications can render Kitty graphics-protocol images inline. The image follows terminal scrolling and is cleared when the application erases or replaces it, like other terminal content. ## The browser pane Press `Ctrl+Shift+B` to toggle the embedded browser pane next to the focused chat. The backend is the host platform's native webview: WPE WebKit on Linux, WKWebView on macOS, WebView2 on Windows. No bundled Chromium. You can drive the browser pane from the CLI: ```bash verde live browser open --url https://example.com verde live browser navigate --url https://example.com/dashboard verde live browser eval --script "document.title" verde live browser screenshot --json verde live browser status --json ``` The inspector button enters **Design Mode**, where you can select an element or draw a region and send its context to a chat or terminal agent. See [Design Mode](/docs/design-mode) for selection modes, routing, and screenshot support, and [CLI reference](/docs/cli) for the full browser command surface. ## Persisting layouts Workspace layouts, per-terminal zoom, terminal tab state, and the browser pane's URL all persist across launches in Verde's SQLite state. Closing the app and reopening it restores the same tiling tree for each project. Closing a workspace from the sidebar or with prefix `Shift+X` also preserves that state; reopen the workspace from the command palette when you need it again. You can inspect the persisted layout without launching the app: ```bash verde state panes --project current --json ``` And the live layout while the app is running: ```bash verde live panes --project current --json ``` ## Experimental companion **Settings → Experimental features** can enable the Companion sidecar (Sprout, Moss, or Vireo — pick the default under Appearance). Toggle it with `Ctrl+Shift+Space`. The companion is a pane-less overlay for orchestration: durable conversation, run/activity views, operation inspection, and **Mission Control** for multi-step goals. It stays experimental and is off by default. ## Command palette and slash commands `Ctrl+Shift+P` opens the command palette — a single ranked list of threads, panes, workspaces, and app commands. `Ctrl+Enter` on a thread result opens it in a fresh pane. The palette also carries **Start New … TUI** entries for Codex, Claude, OpenCode, Cursor, Grok, and Amp, and **Open Current Thread in TUI** entries that promote a GUI chat thread — including Pi, FX, and Grok — into that provider's terminal TUI. The sidebar's **History · N** row opens the same palette scoped to one workspace's saved threads. Thread actions include open in a new pane, sync from the provider, open as a TUI or chat, and archive. Workspace actions also import existing Codex, OpenCode, and Claude Code threads. See [Chat, models & runs](/docs/chat#history-and-provider-threads) for the complete workflow and current provider limitations. Typing `/` in the composer opens a slash-command picker. Running a command shows a pending row in the transcript while it executes, then a result card (`/usage` renders a structured card with limit bars and recent daily usage). Workspace commands, available with every provider: - `/stack` — start / stop / restart / status for every process and agent declared in the workspace's `verde.yml`. - `/process` — start / stop / restart / focus a single declared process by name; `/process crashed` refreshes status and reports the number of crashed processes. - `//text` — escape hatch: send a literal prompt that begins with a slash. Provider-native commands surface in the same picker: - **Claude Code** — `/usage`, `/compact [instructions]`, plus skill commands such as `/code-review`, `/debug`, `/loop`, `/batch`, and `/skills`. - **Codex** — `/usage`, `/compact`, `/goal [status|clear|…]`, `/review [changes|base |commit |custom …]`, and `/shell confirm ` (requires typed confirmation). - **OpenCode, Cursor, Pi, FX, Grok** — no native slash commands yet; `/stack`, `/process`, and `//` still work. --- # Keybinds Source: https://verdeai.dev/docs/keybinds Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/keybinds.md ## Default keybinds These are the defaults, read from `packages/desktop/src/app/keybinds.zig`. Override any of them under `keybinds` in your Verde config — see [Remapping](#remapping) below. ### App | Combo | Action | | -------------------------- | ------------------------------------- | | `Ctrl+Shift+P` / `Cmd+Shift+P` | Command palette | | unbound | Open Settings (`keybinds.settings`) | | `Ctrl+Shift+Space` | Toggle the experimental Companion (when enabled in Settings) | | `Ctrl+Shift+R` / `Cmd+Shift+R`, `F5` | Refresh / reload app | | `Alt+O` | Open the default project | | `Ctrl+Shift+O` | Open in external editor | Close pane and close workspace have no direct default chords. With prefix mode enabled, `x` closes the focused pane and `Shift+X` closes the current workspace. After the last pane is gone, prefix `x` again closes the empty workspace the same way tmux and herdr do. Reopen a closed workspace from the command palette. Bind `workspace.close` / `workspace.close_current` in `verde.json` if you want a direct shortcut back. ### Sidebar & panes | Combo | Action | | -------------------------- | ------------------------------------- | | `Ctrl+S` / `Cmd+S` | Toggle the sidebar (visible ↔ icon) | | `Ctrl+Shift+S` | Toggle the sidebar's hidden mode | | `Ctrl+Shift+B` | Toggle the embedded browser pane | | `Ctrl+R` / `Cmd+R` | Reload the active browser tab (browser pane only) | | `Tab` | Inside a chat pane, focus the prompt box | | `Ctrl+Tab` | Focus the next pane in sidebar order | | `Ctrl+Shift+Tab` | Focus the previous pane in sidebar order | | `Ctrl+1 … Ctrl+9, Ctrl+0` | Focus a pane in the current workspace by sidebar order | | `Ctrl+Shift+1 … Ctrl+Shift+9, Ctrl+Shift+0` | Jump to a row in the global Active section by displayed order | | `Ctrl+Shift+←` / `Ctrl+Shift+→` | Previous / next row in the global Active section | | `Alt+1 … Alt+9, Alt+0` | Jump between workspaces by sidebar order | | `Alt+↑` / `Alt+↓` | Cycle to the previous / next workspace | Pane cycling wraps at either end. When a pane is zoomed, cycling switches the zoomed pane without restoring the split layout. ### Focus | Combo | Action | | ------------ | ------------------------------------------------ | | `Ctrl+Left` | Focus the pane or horizontal strip item to the left | | `Ctrl+Right` | Focus the pane or horizontal strip item to the right | | `Ctrl+Up` | Focus the pane or vertical strip item above | | `Ctrl+Down` | Focus the pane or vertical strip item below | `Ctrl+H/J/K/L` are intentionally unbound by default. Set the corresponding `keybinds.workspace.focus_left/down/up/right` values in `verde.json` to opt in. `Alt+arrow` combos are no longer focus aliases — `Alt+↑` / `Alt+↓` now cycle between workspaces (see the sidebar table above). ### Swap (rearrange the tiling) | Combo | Action | | ------------------ | ------------------------------------- | | `Ctrl+Shift+H` | Swap focused pane with the left one | | `Ctrl+Shift+L` | Swap focused pane with the right one | | `Ctrl+Shift+K` | Swap focused pane with the one above | | `Ctrl+Shift+J` | Swap focused pane with the one below | ### Resize (grow) | Combo | Action | | ------------------ | ---------------------------- | | `Alt+Shift+←` | Grow the focused pane left | | `Alt+Shift+→` | Grow the focused pane right | | `Alt+Shift+↑` | Grow the focused pane up | | `Alt+Shift+↓` | Grow the focused pane down | ### Zoom | Combo | Action | | ------- | --------------------------------------------------- | | `Alt+Z` | Zoom the focused pane to fill the workspace; toggle again to restore | ### Workspace splits Workspace splits have no direct default keybinds. With prefix mode enabled, `Ctrl+B`, then `c` adds a new tab (chat by default) and `Ctrl+B`, then `t` adds a terminal tab in the same place. `Ctrl+B`, then `Shift+T` creates a separate top-level terminal pane. The `v` and `-` prefix chords create tiled splits of the configured default pane type (chat or terminal); `Shift+V` and `Shift+-` create the other type. You can also use the pane header buttons: `C|` / `C-` for chat vertical / horizontal and `T|` / `T-` for terminal vertical / horizontal, or bind any split action directly under `keybinds.workspace`. ### Terminal (inside a focused terminal pane) | Combo | Action | | ---------------------------------- | ------------------------------- | | `Ctrl+Alt+T` / `Cmd+Alt+T` | New terminal tab | | `Ctrl+Shift+R` / `Cmd+Shift+R` | Rename the active terminal tab | | `Ctrl+Shift+PageUp` | Previous terminal tab | | `Ctrl+Shift+PageDown` | Next terminal tab | | `Ctrl+Alt+↑` / `Cmd+Alt+↑` | Focus the terminal split above | | `Ctrl+Alt+↓` / `Cmd+Alt+↓` | Focus the terminal split below | | `Ctrl+Alt+←` / `Cmd+Alt+←` | Focus the terminal split left | | `Ctrl+Alt+→` / `Cmd+Alt+→` | Focus the terminal split right | | `Ctrl+-` / `Ctrl+=` | Per-terminal zoom out / in | ### Chat transcript scrolling | Combo | Action | | ----------- | ------------------------------- | | `↑` | Scroll up one line | | `↓` | Scroll down one line | | `PageUp` | Scroll up one page | | `PageDown` | Scroll down one page | Transcript scrolling is **direct** — no inertia or velocity decay. When input stops, the view stops. Do not expect a multi-frame glide. ## Prefix mode (tmux-style) Prefix mode is **on by default**. Pressing the prefix chord (`Ctrl+B` by default) arms Verde for one keypress: the next key resolves against the prefix table below instead of reaching the focused pane. While armed, a one-line status bar appears along the bottom (`PREFIX esc cancel Ctrl+B send prefix w workspace nav ? keybinds`); press `?` to open the full cheat sheet of every second key — including your own `command` scripts — without dropping the chord. `Esc` cancels, an unbound key is swallowed, and pressing the prefix twice sends the literal chord to the focused terminal (tmux `send-prefix`). Every built-in command has a default seat in the prefix table, with no configuration required. To disable prefix mode: ```json { "keybinds": { "prefix": false } } ``` Change the prefix chord with a string (which also enables prefix mode), or use the object form for full control: ```json { "keybinds": { "prefix": { "enabled": true, "key": ["Ctrl+A", "Ctrl+B"], "defaults": true, "bindings": { "c": "new_thread", "g": { "command": "lazygit", "in": "pane" }, "Shift+3": { "action": "workspace.select.3" }, "z": null } } } } ``` - `key` — one accelerator or an array. Any of them arms the prefix. - `defaults` — set to `false` to drop the built-in table and start empty. - `bindings` — keyed by the second key's accelerator (`"x"`, `"Shift+X"`, `"Ctrl+Left"`, `"Comma"`). A string value is an action name; `null` removes a default; `{ "command": "..." }` runs a shell script. Add `in` (or `open`) to choose where it runs: | `in` | What happens | | ---- | ------------ | | omitted / `background` | Detached `sh -lc` in the project directory, with the project path as `$1` (same as custom `open.default` actions). TUIs like lazygit will not show a pane. | | `terminal` | Types the command into the focused terminal. Falls back to `pane` if a terminal is not focused. | | `pane` | Opens a new terminal pane whose process is the command. | | `horizontal` / `split_horizontal` | Horizontal tiled split of the focused pane, then runs the command there. | | `vertical` / `split_vertical` | Vertical tiled split, then runs the command there. | | `floating` | Opens a floating quick terminal running the command. | | `tab` | New tab in the focused terminal dock. Falls back to `pane` if a terminal is not focused. | Aliases: `new_pane` / `new` → `pane`; `split` / `horizontal` → `split_horizontal`; `float` / `quick` → `floating`; `current` / `focused` → `terminal`; `detached` → `background`. Configured direct shortcuts work alongside prefix mode. Modifier state is exact: `Ctrl+B` then `x` is different from `Ctrl+B` then `Ctrl+X`, so release `Ctrl` before the second key unless the binding uses it. ### Workspace menu `prefix w` opens the herdr-style **NAVIGATE** workspace menu. The status bar switches to `» NAVIGATE esc back Up Prev workspace Down Next workspace Tab Next pane …`. Running any bound action closes the menu immediately; an unbound key leaves it open so you can choose again. Press `Esc` to close it without running anything. Defaults: `Up`/`Down` previous/next workspace, `Tab`/`Shift+Tab` next/previous pane, `h j k l` focus, `c` new thread, `v` / `-` split the configured default pane type, `Shift+V` / `Shift+-` split the other type, `x` close, `z` zoom, `p` command palette, `1`–`0` select workspace, `?` cheat sheet. The table is overridable exactly like `bindings`, under `"navigate"`: ```json { "keybinds": { "prefix": { "navigate": { "Up": null, "g": { "command": "lazygit" } } } } } ``` ### Default prefix table | After `Ctrl+B` | Action | | -------------------------------- | ------------------------------------------------- | | `?` | `prefix.keybinds` (cheat sheet, stays armed) | | `w` | `prefix.navigate` (one-shot workspace menu) | | `p` | `command_palette` | | `t` / `Shift+T` | `workspace.add_tab_terminal` / `new_terminal` | | `r` | `refresh` | | `o` / `e` | `open` / `open_editor` | | `Space` | `companion` | | `s` / `Shift+S` | `sidebar` / `sidebar_hidden` | | `b` | `browser` | | `` ` `` | `terminal.toggle` | | `q` | `workspace.toggle_quick_pane` | | `x` / `Shift+X` | `workspace.close` / `workspace.close_current` | | `z` | `workspace.toggle_maximize` | | `i` | `workspace.focus_prompt` | | `c` | `workspace.add_tab` (new tab at the end of the strip; chat by default) | | `a` | `workspace.add` (new workspace) | | `Shift+C` | `workspace.split_chat_horizontal` | | `v` / `-` | Default pane split, vertical / horizontal | | `Shift+V` / `Shift+-` | Alternate pane split, vertical / horizontal | | `h` `j` `k` `l`, arrows | `workspace.focus_*` | | `Shift+H/J/K/L` | `workspace.move_*` | | `Ctrl+H/J/K/L`, `Ctrl+arrows` | `workspace.grow_*` | | `n` / `Shift+N` | `workspace.pane_next` / `pane_previous` | | `[` / `]` | `workspace.previous` / `next` | | `Shift+[` / `Shift+]` | `workspace.active_previous` / `active_next` | | `1 … 9`, `0` | `workspace.pane_select.1 … 10` | | `Shift+1 … Shift+0` | `workspace.active_select.1 … 10` | | `Shift+Up` / `Shift+Down` | `chat_up` / `chat_down` | | `PageUp` / `PageDown` | `chat_page_up` / `chat_page_down` | | `m` / `Shift+M` | `chat.model_picker` / `chat.run_config` | | `d` | `chat.directory_picker` | | `Ctrl+T` / `Shift+W` | `terminal.new_tab` / `terminal.close` | | `,` | `terminal.rename_tab` | | `Ctrl+PageUp` / `Ctrl+PageDown` | `terminal.tab_previous` / `tab_next` | | `Alt+arrows` | `terminal.split_*` | | `Alt+Shift+arrows` | `terminal.focus_*` | Terminal and chat actions only apply while a pane of that kind is focused, exactly like their direct shortcuts. ### Prefix action names Action names mirror the remapping keys below, joined with `.` for nested groups: `refresh`, `open`, `open_editor`, `new_thread`, `new_terminal`, `workspace.add`, `workspace.add_tab`, `workspace.add_tab_terminal`, `command_palette`, `companion`, `sidebar`, `sidebar_hidden`, `browser`, `chat_up`, `chat_down`, `chat_page_up`, `chat_page_down`, `chat.model_picker`, `chat.run_config`, `chat.directory_picker`, `terminal.toggle`, `prefix.keybinds`, `prefix.navigate`, and `terminal.` for every terminal binding. The dynamic split names are `workspace.split_default_*` and `workspace.split_alternate_*`, alongside every `workspace.` including `workspace.add_tab_terminal`. Positional actions take a 1-based ordinal: `workspace.select.N`, `workspace.pane_select.N`, `workspace.active_select.N`. ## Remapping Override any binding under `keybinds` in your `verde.json`. On Unix it is under `$XDG_CONFIG_HOME/verde` or `~/.config/verde`; on Windows it is under `%APPDATA%\Verde`. Add `"$schema": "https://verdeai.dev/config.schema.json"` at the root of that file for editor autocomplete of every keybind and prefix action. Use a string for one shortcut, or a string array for multiple shortcuts on the same action: `Ctrl+T` and `Ctrl+Shift+T` are unbound by default. To opt back into those direct shortcuts, use `new_thread` and `workspace.split_terminal_horizontal` as shown below. Settings has no default chord; bind `settings` to add one. ```json { "keybinds": { "new_thread": "CommandOrControl+T", "settings": "Ctrl+Comma", "browser": "Ctrl+Shift+B", "companion": "Ctrl+Shift+Space", "workspace": { "split_terminal_horizontal": "CommandOrControl+Shift+T", "focus_up": "Ctrl+K", "focus_down": "Ctrl+J", "focus_left": "Ctrl+H", "focus_right": "Ctrl+L", "pane_previous": "Ctrl+Shift+Tab", "pane_next": "Ctrl+Tab", "active_select": ["Ctrl+Shift+1", "Ctrl+Shift+2", "Ctrl+Shift+3", "Ctrl+Shift+4", "Ctrl+Shift+5", "Ctrl+Shift+6", "Ctrl+Shift+7", "Ctrl+Shift+8", "Ctrl+Shift+9", "Ctrl+Shift+0"], "active_previous": "Alt+Left", "active_next": "Alt+Right", "pane_select": ["Ctrl+1", "Ctrl+2", "Ctrl+3", "Ctrl+4", "Ctrl+5", "Ctrl+6", "Ctrl+7", "Ctrl+8", "Ctrl+9", "Ctrl+0"], "previous": "Alt+Up", "next": "Alt+Down", "move_left": "Ctrl+Shift+H", "move_right": "Ctrl+Shift+L", "move_up": "Ctrl+Shift+K", "move_down": "Ctrl+Shift+J", "toggle_maximize": "Alt+Z", "select": ["Alt+1", "Alt+2", "Alt+3", "Alt+4", "Alt+5", "Alt+6", "Alt+7", "Alt+8", "Alt+9", "Alt+0"] }, "terminal": { "new_tab": "CommandOrControl+Alt+T", "close": "CommandOrControl+Shift+W", "rename_tab": "CommandOrControl+Shift+R", "tab_previous": "CommandOrControl+Shift+PageUp", "tab_next": "CommandOrControl+Shift+PageDown", "focus_up": "CommandOrControl+Alt+Up", "focus_down": "CommandOrControl+Alt+Down", "focus_left": "CommandOrControl+Alt+Left", "focus_right": "CommandOrControl+Alt+Right" } } } ``` `workspace.pane_select` is positional: the first shortcut focuses the first pane shown under the current workspace in the sidebar, the second shortcut focuses the second pane, and so on. `workspace.active_select` follows the sorted order currently shown in the sidebar's global Active section, including rows from other workspaces. `workspace.active_previous` / `workspace.active_next` cycle that same list; the defaults are `Ctrl+Shift+Left` / `Ctrl+Shift+Right`. Bind `Alt+Left` / `Alt+Right` (or any other chord) if you want a different cycle shortcut. `workspace.close` and `workspace.close_current` are unbound by default. Prefix `x` / `Shift+X` close a pane or workspace when prefix mode is on. To restore the old direct chords: ```json { "keybinds": { "workspace": { "close": ["CommandOrControl+W", "Alt+X"], "close_current": "CommandOrControl+Shift+W" } } } ``` ## Disabling a binding Set the binding to `null`, an empty string, or an empty array to disable it: ```json { "keybinds": { "terminal": { "toggle": null, "split_up": null, "split_down": null, "split_left": null, "split_right": null } } } ``` ## Binding keys reference The keybinds config uses the same accelerator grammar as the desktop defaults. The top-level keys group actions by surface; the inner values are one shortcut or an array of shortcuts. | Group | Keys (subset) | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | top | `refresh`, `open_default`, `open_editor`, `new_thread`, `command_palette`, `settings`, `companion`, `toggle_sidebar`, `toggle_sidebar_hidden`, `toggle_browser`, `toggle_terminal` | | chat | `chat_up`, `chat_down`, `chat_page_up`, `chat_page_down` | | `workspace` | `split_chat_vertical`, `split_chat_horizontal`, `split_terminal_vertical`, `split_terminal_horizontal`, `toggle_maximize`, `close`, `close_current`, `focus_left`, `focus_right`, `focus_up`, `focus_down`, `focus_prompt`, `pane_previous`, `pane_next`, `active_select`, `active_previous`, `active_next`, `pane_select`, `move_*`, `grow_*`, `select`, `previous`, `next` | | `terminal` | `new_tab`, `close`, `rename_tab`, `tab_previous`, `tab_next`, `split_up`, `split_down`, `split_left`, `split_right`, `focus_up`, `focus_down`, `focus_left`, `focus_right` | | `prefix` | `enabled`, `key`, `defaults`, `bindings`, `navigate` — see [Prefix mode](#prefix-mode-tmux-style) | Keybinds are loaded on startup, on app refresh (`F5`, `Ctrl+Shift+R`, or prefix then `r`), and whenever `verde.json` changes on disk. Refresh is app-owned even when a terminal TUI is focused. See [Configuration & state](/docs/config) for the hosted `verde.json` JSON Schema (`https://verdeai.dev/config.schema.json`) and where state lives. --- # CLI reference Source: https://verdeai.dev/docs/cli Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/cli.md ## Overview `verde` is both the desktop launcher and a CLI for reading persisted state and controlling a running app. CLI-only commands run before SDL startup, so you can use them from scripts without opening a window. ```bash verde # Launch the desktop app verde app # Launch the desktop app explicitly verde --help # Show CLI help verde version [--json] # Print version metadata verde update [--json] # Install the latest Verde release verde capabilities [--json] # Print supported CLI/live features verde open [--json] # Open a URL in this Verde workspace's browser pane verde completion # Print shell completion script verde state # Read persisted state while the app is closed verde notify [options] # Update the current terminal surface verde integrations # Inspect and install optional provider hooks verde theme # Import, validate, export, or reset themes verde session # Manage persistent terminal sessions verde mcp # Run Verde's stdio MCP bridge verde herdr # Open or inspect local Herdr-backed workspaces verde runtime # Manage non-secret runtime connection profiles verde live # Control or inspect the running app ``` Use `--json` when scripting. Live IPC responses use a stable envelope: ```json { "id": 1, "ok": true, "result": {} } ``` Errors return `ok: false` with an `error.code` and `error.message`. ## Updates ```bash verde update verde update --json ``` On Linux and macOS, `verde update` runs the official installer in the foreground, shows progress and errors, and exits only when installation finishes. A failed download or install returns a nonzero exit code. With `--json`, installer output goes to stderr and stdout contains the final result: `installed`, `package_manager_required`, or an error with `ok: false`. Restart Verde after a successful install. Windows starts its installer after the app exits. **Settings → App → Updates → Install update** runs this same `verde update` command in a terminal pane. Keep Verde open until it finishes, then restart it. Both entry points target the running installation's directory. For Arch package-managed installs, the card shows a package-manager command and **Copy update command**. Run the copied `yay -Syu`, `paru -Syu`, or `sudo pacman -Syu` command in your terminal. AUR packages need an AUR helper; if neither helper is installed, install one before running the suggested `yay` command. Curl installs on Arch still use the public installer. The card also shows the installed version, release notes, **Check now**, and the **Check automatically** preference. ## Runtime connection profiles Runtime commands manage the desktop's non-secret profile document without opening the app. They are currently offline administration commands. Mutations serialize across processes and replace the owner-only document atomically: ```bash verde runtime path [--json] verde runtime list [--json] verde runtime add-ssh --label "Build VM" --host devbox \ [--user verde] [--ssh-port 22] [--gateway-port 7420] \ [--expected-runtime-id <32-lowercase-hex-id>] [--json] verde runtime remove --id [--json] ``` Local is built in and is not stored as a user profile. SSH host aliases, keys, agents, jump hosts, and host-key policy remain owned by normal SSH configuration. These commands deliberately have no token option: gateway bearers and provider credentials must never enter shell history, process arguments, or `runtime-profiles.json`. The profile CLI is available before the native Remote selector is enabled. The secure tunnel, handshake, targeted heartbeat/general-RPC manager, durable identity pinning, and immutable per-thread route foundations are implemented, but credential-store hydration and selector/chat-execution wiring are not yet end to end. Adding a profile therefore does not move or remotely run an existing thread. ## Theme packages Theme commands run without launching the desktop UI. Imports accept local JSON, ordinary HTTP(S) URLs, and GitHub `blob` links. A successful import installs and activates the theme; it then appears alongside Verde and Omarchy in the Settings theme dropdown. ```bash verde theme import [--dry-run] [--json] verde theme validate [--json] verde theme export [file] [--name ] [--json] verde theme reset [--json] # Hosted example from the Verde theme gallery verde theme validate https://verdeai.dev/themes/kanagawa.json verde theme import https://verdeai.dev/themes/kanagawa.json ``` `validate` and `import --dry-run` do not change `verde.json`. `export` resolves Omarchy-derived colors into a portable package, so the result can be used on Linux, macOS, or Windows. Theme packages only apply allowlisted visual colors and optional UI/terminal font sizes; font-family and command settings are never imported. ## Offline state commands State commands read Verde's persisted SQLite state and do not require the app to be running. ```bash verde state path [--json] verde state workspaces [--json] verde state panes --project [--json] verde state threads --project [--json] verde state transcript --project --thread [--json] ``` - `path` prints the SDL pref path and `state.sqlite` location. - `workspaces` lists imported projects and the selected workspace. `projects` remains an alias for compatibility. - `panes` prints the saved workspace layout and terminal dock state for a project. - `threads` lists saved chat threads for a project. - `transcript` prints one saved chat transcript by thread index or provider thread id. ## Live discovery commands Live commands talk to the running desktop app over current-user local IPC: a Unix socket on Linux/macOS or a named pipe on Windows. Start the app first. ```bash verde live capabilities [--json] verde live status [--json] verde live projects [--json] verde live active [--json] verde live panes [--project ] [--json] verde live threads [--project ] [--json] verde live terminals [--project ] [--json] verde live surfaces [--json] verde live processes [--json] verde live inspect --pane [--project ] [--json] verde live inspect --focused [--json] verde live browser status [--json] verde live workspace select --project [--json] verde live workspace create --path /path/to/project [--json] verde live workspace rename --project --label "New name" [--json] verde live workspace close --project [--json] verde live workspace reopen [--project ] [--json] ``` - `capabilities` prints the live method list without requiring the app to be running. - `status` returns protocol version, app pid, selected project, focused pane, current pane graph, terminal/process summary, and browser runtime state. - `active` returns the current project and focused pane. - `surfaces` lists terminal surface status and attention metadata. Unacknowledged completions persist across app and terminal-daemon restarts until the pane is focused or the completion is cleared through the surface controls. - `panes` and `threads` expose native-chat `completion_pending` and `completed_at_ms` fields. Focusing that chat pane through `pane focus` acknowledges and clears the durable completion. - `workspace close` removes a workspace from the active sidebar without deleting its saved threads or layout. `archive` is an alias for `close`. - `workspace reopen` restores the specified closed workspace, or the most recently closed one when `--project` is omitted. ## Browser control ```bash verde live browser status [--json] verde live browser open --url https://example.com [--project ] [--json] verde live browser navigate --url https://example.com [--json] verde live browser close [--json] verde live browser toggle [--json] verde live browser back [--json] verde live browser forward [--json] verde live browser reload [--json] verde live browser focus [--json] verde live browser blur [--json] verde live browser select-all [--json] verde live browser copy [--json] verde live browser cut [--json] verde live browser paste-text --text "hello" [--json] verde live browser eval --script "document.title" [--json] verde live browser screenshot [--json] verde live browser post-json --json-payload '{"type":"ping"}' [--json] verde live browser inspector-enable [--json] verde live browser inspector-disable [--json] verde live browser inspector-toggle [--json] verde live browser inspector-mode --mode point|draw-box|draw-freeform [--json] ``` The browser pane uses the host platform's native webview (WPE WebKit, WKWebView, or WebView2). `browser open` opens a URL in the workspace's browser pane, creating one if needed. `browser eval` runs JavaScript in the loaded page and returns the result as JSON. The inspector commands control [Design Mode](/docs/design-mode) for browser-to-agent visual feedback. `browser screenshot` stores and returns the visible viewport as PNG data when the active presentation exposes a CPU-side frame. Native child-view backends return `unsupported` until their platform snapshot path is available. `select-all` and `copy` operate on the focused page element or selection; `cut` and `paste-text` target the focused editable element. ## Chat control Chat commands resolve the target workspace pane to a chat thread and drive it through the same composer / send path as the UI. ```bash verde live chat open --workspace --provider codex [--model ] [--reasoning low|medium|high|xhigh] [--fast|--no-fast] [--json] verde live chat status --pane [--json] verde live chat transcript --pane [--json] verde live chat draft set --pane --text "Reply with exactly: ok" [--json] verde live chat draft append --pane --text " and more" [--json] verde live chat send --pane [--prompt "fix the tests"] [--json] verde live chat followup --pane --prompt "now run the linter" [--json] verde live chat stop --pane [--json] verde live chat approve --pane --decision approve|deny [--call ] [--json] ``` - `open` validates provider/model reasoning and Fast settings before creating the pane. Its response and subsequent `status` responses report the effective reasoning effort, reasoning variant, Fast mode, and service tier. - `status` returns the current draft, send state, and pending approval status. - `transcript` returns persisted messages for the pane's thread. - `draft set` replaces the current draft; `draft append` appends to it. - `send` sends `--prompt`, `--text`, or a trailing prompt argument. If no prompt is supplied, it sends the current draft. - `followup` steers a prompt into the pane's **running** turn. It is daemon-led: it resolves the pane's thread through the session daemon, never changes focus, presentation, or the composer draft, and returns structured results — `disposition: "steered"` on success, `invalid_state` when the pane has no running turn (nothing is staged as a draft), and `not_found` for a missing pane or thread. Steering currently supports Claude local-CLI turns; other provider harnesses return a structured unsupported error. - `stop` aborts the current send for that chat thread. - `approve` resolves the current pending approval. `--decision` accepts `approve` or `deny`. Chat turns run in the session daemon, so an accepted turn keeps running and lands durably even if the desktop window is closed or restarted mid-turn. Drafts and staged image attachments persist with their thread across pane switches and app restarts. ## Terminal and process control Terminal commands resolve the target workspace pane to its terminal dock and write through the same active PTY input path as the UI. ```bash verde live terminal write --pane --text $'cargo test\r' [--json] verde live terminal write --focused --text $'printf "ok\\n"\r' [--json] verde live terminal key --pane --key enter [--json] verde live terminal key --pane --chord ctrl+c [--json] verde live terminal submit --pane [--json] verde live terminal tail --pane [--lines ] [--json] verde live terminal screen --pane [--lines ] [--json] verde live process list [--project ] [--json] verde live process start --name [--project ] [--json] verde live process stop --name [--project ] [--json] verde live process restart --name [--project ] [--json] verde live process inspect --name [--project ] [--json] verde live process logs --name [--project ] [--json] verde live agent open --provider codex|claude|opencode|cursor|grok [--project ] [--json] verde live stack start [--project ] [--json] verde live stack stop [--project ] [--json] verde live stack restart [--project ] [--json] verde live stack status [--project ] [--json] ``` - `terminal write` sends raw text to the active terminal tab/pane. Include `\r` when you want to submit a shell command. A stopped session is restarted before the write. - `terminal key` sends one validated atomic key chord without changing desktop focus. Use `--key` with `--ctrl`, `--alt`, `--shift`, or `--super`, or pass a chord such as `ctrl+c`. `terminal submit` is an atomic Enter alias. - Supported keys are Enter, Escape, Tab, arrows, Home/End, PageUp/PageDown, Backspace/Delete, Space, F1-F12, letters, and digits. Arbitrary escape sequences are rejected. - Key actions do not restart stopped or missing sessions. They can still submit or interrupt work, so automation should resolve an explicit pane id and inspect the target before sending Enter or another consequential key. - `terminal tail` returns recent terminal output; `screen` returns the current visible terminal screen. - `process start`, `stop`, and `restart` control entries loaded from `verde.yml`. - `agent open --provider ` opens that provider's first-class TUI in the selected workspace without requiring a `verde.yml` entry. Grok is detected from `PATH` and launched with `--no-auto-update`. - `stack start`, `stop`, and `restart` apply the same action to every configured process and agent in the selected workspace. ## Pane management ```bash verde live pane split --pane --kind chat|terminal --axis horizontal|vertical [--json] verde live pane focus --pane [--json] verde live pane resize --first --second --axis horizontal|vertical --ratio <0..1> [--json] verde live pane move --pane --direction left|right|up|down [--json] verde live pane maximize --pane [--json] verde live pane close --pane [--json] verde live palette list [--json] verde live palette run --command pane.split_terminal_down [--json] ``` ## Persistent terminal sessions The session daemon keeps terminal processes addressable independently of a particular visible pane. List and inspect sessions even when the desktop app is not running; persisted metadata remains available if the daemon is offline. ```bash verde session list [--json] verde session inspect --id [--json] verde session new [--workspace ] [--cwd ] [--name ] -- verde session attach --id verde session write --id --text $'cargo test\r' [--json] verde session tail --id [--lines ] [--json] verde session screen --id [--lines ] [--json] verde session kill --id [--json] verde session cleanup [--json] ``` `attach` is interactive. For automation, prefer `write`, `tail`, and `screen` with an explicit session id. ## MCP bridge `verde mcp` starts a JSONL stdio MCP server that exposes Verde's local live controls to compatible agents. It is primarily used by agent integrations; most users do not invoke it directly. The bridge handles MCP initialization, tool discovery, and tool calls, and requires the relevant live Verde target for operations that control the app. The bridge includes embedded-browser tools for status, open/navigation, DOM inspection, selector-based click and typing, and viewport screenshots. Browser actions correlate asynchronous webview evaluation results before returning to the agent. Potentially sensitive clicks, password entry, and form submission require an explicit confirmed retry so the agent client can ask the user first. `send_terminal_key` exposes the same atomic terminal-key path to MCP clients. It requires `pane_id`, accepts an optional workspace selector, and takes either a named key plus modifier booleans or a chord. It preserves desktop focus and does not restart a stopped session. ### Chat control over MCP The bridge exposes the full GUI-chat surface to agents: `open_chat`, `present_chat`, `send_chat_message`, `get_chat_draft` / `set_chat_draft`, `read_chat_thread`, `tail_chat_turn`, `stop_chat_turn`, `approve_chat_turn`, and `queue_chat_followup`, plus `list_workspaces` / `list_panes` for discovery. - `read_chat_thread` and `queue_chat_followup` are **daemon-direct**: they read persisted thread state through the session daemon, so they work even when the GUI has paged the thread out of memory. - `queue_chat_followup` steers a prompt into a running turn with the same semantics as `verde live chat followup` — structured `steered` / `invalid_state` / `not_found` results, no focus or composer changes, and no silent draft staging when the turn is idle. - Capabilities are granular: a tool that cannot run in the current configuration returns `capability_unavailable` instead of failing ambiguously. Discover the active surface with `verde capabilities --json`. ### Process coordination and retained outcomes The MCP bridge exposes `list_processes`, `check_command`, `acquire_lease`, `release_lease`, and `wait_for_process` for shared workspace coordination. `list_processes` combines configured processes, active terminal commands, GUI agent turns, background tasks, and active leases. Terminal commands keep the same stable process id as they move from active to final. Final records are retained in memory for 15 minutes, up to 32 per workspace, and report status `completed`, `failed`, `cancelled`, `crashed`, or `unknown`. When available they also include `finished_at_ms`, `exit_code`, `signal`, `cancellation_reason`, and ownership details. Retained records do not survive an app restart. `wait_for_process` waits up to 300 seconds by default, with a 900-second cap. Its tracking outcome is `completed`, `replaced`, `gone`, or `timed_out`. `completed` means a final record for that id was found; it does not mean the command exited successfully. Inspect the returned `process.status` and exit fields. A disappearing terminal command remains observable as `stopping` during a short finalization grace period so waiters do not receive a premature `gone`. ## Provider integrations Provider hooks are optional add-ons that let agent CLIs drive Verde's sidebar status pips. They never overwrite provider config or change provider login/auth behavior. ```bash verde integrations list [--json] verde integrations doctor [--json] verde integrations install [--global] verde integrations remove [--global] verde integrations disable ``` - **Claude / Codex** hooks are project-local (`.claude/settings.local.json` / `.codex/hooks.json`); `--global` installs them in `~/.claude/settings.json` / `~/.codex/hooks.json` instead. - **Cursor** supports project-local `.cursor/hooks.json` and a `--global` installer at `~/.cursor/hooks.json`. Verde merges its entries without replacing unrelated hooks. - **Grok** uses an isolated personal hook at `$GROK_HOME/hooks/verde-notify.json`, defaulting to `~/.grok/hooks/verde-notify.json`; install or remove it with `--global`. - **Amp** uses a global lifecycle plugin at `~/.config/amp/plugins/verde-notify.ts` (install with `--global`). The plugin is a no-op outside Verde panes. - **OpenCode** uses a global lifecycle plugin at `~/.config/opencode/plugin/verde-notify.ts`. - **Pi** uses a global extension at `~/.pi/agent/extensions/verde-notify.ts`. It reports settled lifecycle state and follows `/name` session-title changes, falling back to the submitted prompt before a session is named. - **FX** reports lifecycle directly through Verde's built-in compatibility endpoint. Its native session/workspace terminal title remains authoritative, so no hook file is required. ## Local Herdr handoff Herdr opens or attaches local Verde workspaces and syncs pane state for terminal/TUI handoff. `handoff` and `unlink` require the app to be running. ```bash verde herdr status [--json] verde herdr open --herdr-workspace [--session ] [--cwd ] [--local-dir ] [--json] verde herdr handoff [--workspace ] [--all] [--session ] [--dry-run] [--json] verde herdr unlink [--workspace ] [--all] [--json] ``` ## Terminal surface notifications Verde terminal children receive identity variables such as `VERDE=1`, `VERDE_SESSION_ID`, `VERDE_WORKSPACE_ID`, `VERDE_WORKSPACE_PATH`, `VERDE_DOCK_ID`, `VERDE_PANE_ID`, `VERDE_SOCKET`, `VERDE_LIVE_SOCKET`, `VERDE_SESSIONIZER_SOCKET`, and `VERDE_CLI`. Terminal tools can use those variables to update their pane surface: ```bash verde notify --title "Codex needs input" --body "Approve command?" --status waiting verde notify --status working --progress 0.4 --label "Running tests" verde notify --status done --title "Agent finished" verde notify --clear ``` `--status` accepts `idle`, `working`, `waiting`, `done`, or `error`. Combined with `--progress` (0..1), it drives the surface's progress bar. ## Selectors and exit codes - Use `--pane ` for deterministic automation. - Use `--focused` for interactive smoke tests. - Use `--project current` for the selected project, or pass a project index, id, or path. - Chat commands require a chat pane. Terminal commands require a terminal pane. | Exit | Meaning | | ---- | --------------------------------------------------------------------------------- | | `0` | CLI command parsed and, for live commands, received a live response. | | `1` | Command failure before a structured live response. | | `2` | Invalid CLI arguments. | | `3` | Live server is not running or not ready. | | `4` | Offline state target not found. | Live IPC request failures return JSON error codes such as `not_found`, `invalid_request`, `invalid_target`, `rejected`, `unsupported`, or `method_not_found`. Scripts must check the JSON envelope's `ok` field, not only the process exit code. ## Shell completion `verde completion` prints static completion scripts for bash, zsh, fish, and PowerShell. The generated completions cover command names, nested live-control commands, flags, and fixed flag values such as `--kind chat|terminal`, `--axis horizontal|vertical`, and `--decision approve|deny`. ```bash verde completion bash verde completion zsh verde completion fish verde completion powershell ``` Common install patterns: ```bash # bash verde completion bash > ~/.local/share/bash-completion/completions/verde # zsh mkdir -p ~/.zfunc verde completion zsh > ~/.zfunc/_verde # Ensure ~/.zfunc is in fpath before compinit, for example: # fpath=(~/.zfunc $fpath) # fish verde completion fish > ~/.config/fish/completions/verde.fish ``` The first completion slice is intentionally static so tab completion stays fast and never depends on the desktop app being open. Dynamic project, pane, process, and thread completions can be layered on top of this later. --- # Configuration & state Source: https://verdeai.dev/docs/config Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/config.md ## verde.json User config is loaded from `$XDG_CONFIG_HOME/verde/verde.json` or `~/.config/verde/verde.json` on Linux/macOS, and `%APPDATA%\Verde\verde.json` on Windows. `VERDE_CONFIG` can point to a custom file. It is read on startup and on app refresh. Point JSON language servers at the hosted schema so editors autocomplete and validate keys: ```json { "$schema": "https://verdeai.dev/config.schema.json" } ``` The schema is published at [`https://verdeai.dev/config.schema.json`](https://verdeai.dev/config.schema.json). Verde ignores `$schema` when loading config, and Settings saves leave the pointer in place. VS Code, Zed, Helix, and Neovim's JSON LSP pick it up from that field. You can also map the file globally: ```json { "json.schemas": [ { "fileMatch": ["**/verde/verde.json"], "url": "https://verdeai.dev/config.schema.json" } ] } ``` A complete example: ```json { "$schema": "https://verdeai.dev/config.schema.json", "theme": { "theme": "default", "colors": { "background": "#101820", "panel": "#151b24", "accent": "#50c878", "text": "#f0f0f5", "selection": "#58a6ff" } }, "ui": { "font_size": 20, "workspace_pane_gap": 12, "workspace_panes_per_view": 2, "workspace_split_default_pane": "chat", "workspace_scroll_direction": "horizontal", "workspace_scroll_mode": "automatic", "workspace_scroll_threshold": 2, "unzoom_on_pane_navigation": false, "workspace_tabs": "automatic" }, "open": { "default": "folder", "links": "verde_browser" }, "browser": { "scroll_speed": 2.5 }, "terminal": { "font_size": 18, "profiles": [ { "label": "Local Agent", "command": ["my-agent", "--interactive"] } ] }, "transcript": { "tool_call_groups": "collapsed" }, "chat": { "automatic_titles": true, "title_provider": "codex", "title_model": "gpt-5.6-luna", "default_provider": "codex", "default_model": "gpt-5.6-sol", "default_reasoning": "low", "favorite_models": [ { "provider": "codex", "model": "gpt-5.6-sol" } ], "new_pane_behavior": "new_pane" }, "updates": { "check_automatically": true }, "notifications": { "enabled": true }, "keybinds": { "new_thread": "CommandOrControl+T", "browser": "Ctrl+Shift+B", "workspace": { "focus_up": "Ctrl+K", "focus_down": "Ctrl+J", "focus_left": "Ctrl+H", "focus_right": "Ctrl+L", "pane_previous": "Ctrl+Shift+Tab", "pane_next": "Ctrl+Tab", "close": "Alt+X", "active_select": ["Ctrl+Shift+1", "Ctrl+Shift+2", "Ctrl+Shift+3", "Ctrl+Shift+4", "Ctrl+Shift+5", "Ctrl+Shift+6", "Ctrl+Shift+7", "Ctrl+Shift+8", "Ctrl+Shift+9", "Ctrl+Shift+0"], "pane_select": ["Ctrl+1", "Ctrl+2", "Ctrl+3", "Ctrl+4", "Ctrl+5", "Ctrl+6", "Ctrl+7", "Ctrl+8", "Ctrl+9", "Ctrl+0"], "previous": "Alt+Up", "next": "Alt+Down" } } } ``` Keybinds are loaded on startup and on app refresh. Use a string for one shortcut or a string array for multiple shortcuts. Use `null`, an empty string, or an empty array to disable a binding. The `workspace.pane_select` and `workspace.active_select` arrays are positional and follow the corresponding sidebar lists in displayed order. `new_thread`, `settings`, `workspace.close`, and `workspace.close_current` are unbound by default; prefix `x` / `Shift+X` still close a pane or workspace when prefix mode is on. Prefix `x` on an empty workspace closes that workspace too. The example above opts `close` back to `Alt+X`. See [Keybinds](/docs/keybinds) for the full keybinds reference. Most of these options also appear in Settings: - **Appearance** — theme and UI font size. - **Transcript** — tool-call groups: `collapsed`, `expanded`, or `remember_last`. - **Chat** — generate concise chat titles automatically after the opening exchange and choose the provider and model used for titles. - **Terminal** — font size, launch profiles, and whether terminal link clicks open in Verde's browser pane or the system browser. - **Browser** — set embedded-page wheel speed from `1.0×` to `5.0×`; the default is `2.5×`. - **Workspace** — choose `automatic`, `always`, or `disabled` scrolling layout, set the automatic activation threshold (1–64 panes), choose horizontal or vertical scrolling, control how many panes fit in one view and their gap, set the default open action for project files and folders, choose whether new chats create panes or replace an existing chat pane, and choose whether the unshifted prefix split keys create GUI chats or terminals. Mode and threshold can inherit these global values or be overridden for the currently selected workspace. Drag-resized column widths are also saved per workspace and take precedence over panes-per-view sizing until reset. `ui.workspace_pane_gap` also sets the outer margin for multi-pane scrolling views and the outer and internal spacing for tiled groups. A tiled scrolling group occupies the full viewport until only one pane remains; standalone and zoomed panes remain edge-to-edge. Pane navigation keeps the destination zoomed by default; set `ui.unzoom_on_pane_navigation` to `true` to restore on navigation instead. - **Agent integrations** — status-pip hooks for supported provider CLIs. - **Experimental features** — enable the Companion sidecar and Mission Control (off by default). **Appearance → Default companion** chooses Sprout, Moss, or Vireo when the companion is on. - **Updates** — check now, install an available release, and automatic checks. - **Notifications** — enable or disable desktop notifications when an agent finishes, waits for input, or errors. Settings that write `verde.json` apply when you choose **Save**. Provider hook installation/removal runs immediately because it updates the provider's own configuration. `browser.scroll_speed` accepts values from `1.0` through `5.0`. Older configs using `browser.fast_scrolling` remain compatible: `true` maps to the `2.5×` default and `false` maps to `1.0×`. ### Open actions `open.default` controls the workspace header's primary open action. Supported string values are `folder`, `editor`, `cursor`, `vscode`, and `zed`. `editor` uses the configured system editor; the named values target that application directly. For another editor or workspace tool, use a custom action: ```json { "open": { "default": { "label": "Workbench", "action": "my-editor ." }, "links": "system_browser", "chat_links": "verde_browser", "terminal_links": "global" } } ``` The custom command runs through the platform shell with the imported project as its working directory. `open.links` accepts `verde_browser` or `system_browser` and sets the global destination for web links. `open.chat_links` and `open.terminal_links` optionally override it for GUI chat and terminal links; each accepts `global`, `verde_browser`, or `system_browser`. New installations default to `system_browser` when `open.links` is not configured. ## Chat titles Automatic titles are enabled by default and run after the opening user and assistant exchange completes. `chat.title_provider` accepts `codex`, `claude`, `cursor`, or `opencode`; `chat.title_model` is the model reference understood by that provider. The default is GPT-5.6 Luna from Codex / ChatGPT. A title generation failure leaves Verde's prompt-derived fallback title unchanged. ## New chat defaults and favorite models New GUI chats start with `chat.default_provider`, `chat.default_model`, and `chat.default_reasoning`. Providers accept `codex`, `claude`, `cursor`, `opencode`, `pi`, `fx`, or `grok`; reasoning accepts `default`, `low`, `medium`, `high`, `xhigh`, or `max` when the chosen model supports it. These values are also available under **Settings → Chat → New chat defaults**. The model picker’s star tab shows only `chat.favorite_models`. Use the star on any provider/model row to add or remove it; provider tabs continue to show the full model list for that provider. The workspace pencil button creates and focuses a new chat pane. With prefix mode enabled, `Ctrl+B`, then `c` adds a new tab (chat by default). Set `chat.new_pane_behavior` to `replace_pane`, or choose **Replace chat pane** under **Settings → Workspace → New chat action**, to reuse an existing visible chat pane instead. ## Updates Automatic update checks are enabled by default. Disable them in Settings or with: ```json { "updates": { "check_automatically": false } } ``` The Updates card shows the installed version and a wrapped release-note preview. Use **Show more** to expand the notes in place or **Open release page** for the complete GitHub release. You can also install the newest release without opening Settings: ```bash verde update ``` On Linux and macOS, restart Verde after the installer completes. AUR-managed Linux installs open `yay` or `paru` in an interactive terminal pane. The Windows updater exits the running app, installs the release, and relaunches it. ## Transcript preferences `transcript.tool_call_groups` controls how consecutive transcript tool calls open: `collapsed`, `expanded`, or `remember_last`. Failed groups open so their error remains visible. With `remember_last`, Verde also maintains its internal last-expanded state for the next group. See [Chat, models & runs](/docs/chat). ## verde.yml stack config Project stack config is loaded from `verde.yml` or `verde.yaml` in the workspace root. `processes:` and `agents:` entries both run in terminal docks; agent entries may also declare `provider` (`codex`, `claude`, `opencode`, `cursor`, `grok`, `amp`, or `other`), `revive`, `notify`, `mcp`, and `hooks` metadata. New agent metadata defaults to disabled unless explicitly set. ```yaml processes: web: command: "npm run dev" cwd: "." restart: on_crash agents: codex: provider: codex command: "codex" cwd: "." revive: attach_or_create notify: true mcp: true hooks: true grok: provider: grok command: "grok --no-auto-update --continue" cwd: "." revive: attach_or_create ``` Use `processes:` for normal long-running commands such as dev servers. Use `agents:` for terminal/TUI AI tools that should behave like first-class Verde surfaces. With the Codex example above, Verde creates or reuses a terminal dock for the agent and wires Codex hook events into pane/workspace attention. Plain `codex` managed commands are launched with `features.hooks=true` when `hooks: true` is set, so `PermissionRequest` can mark the surface `waiting` and `Stop` can mark it `done`. Use `grok --no-auto-update` for a fresh Grok session, `--continue` for the most recent session in the workspace, or `--resume ` for a specific session stored by Grok. Start or restart a configured Codex agent with: ```bash verde live agent open --provider codex verde live process restart --name codex ``` Use `verde live agent open --provider codex` for the default Codex TUI flow; it creates a managed terminal surface, applies Codex hook setup, and does not need a `verde.yml` entry. Use `verde live process restart --name codex` when you want to launch or restart the named agent declared in `verde.yml`. The same default Codex TUI action is available from the workspace sidebar by right-clicking the workspace new-thread/pencil button and choosing `Open Codex TUI`. A Codex TUI opened manually in any Verde terminal still gets Verde identity environment variables and can update the surface through `verde notify`, BEL, OSC 777, or MCP, but it is not automatically a managed `verde.yml` agent unless it is launched through the configured process entry. ## Themes Verde ships a warm-green native theme out of the box. Choose Verde, Omarchy, or an installed theme from **Settings → Appearance → Theme**. The website's theme gallery provides portable packages that import and activate in one command: ```bash verde theme import https://verdeai.dev/themes/kanagawa.json ``` Imported themes remain in the same Settings dropdown after switching away. You can also import a local JSON file or a GitHub file-page URL. Use `verde theme validate ` to check a package without installing it, and `verde theme export [file] --name "My theme"` to create a portable package from the currently resolved colors. To override individual theme tokens manually, edit `verde.json` under `theme.colors`: ```json { "theme": { "colors": { "background": "#101820", "panel": "#151b24", "accent": "#50c878", "text": "#f0f0f5", "selection": "#58a6ff" } } } ``` Omit `theme.theme` to keep Omarchy auto-detection (see below), or set it to `"default"` to start from Verde's built-in colors. ## Omarchy color auto-detection On Omarchy systems, UI colors are loaded from an Omarchy-compatible `colors.toml`. Verde honors the first found of: 1. `VERDE_OMARCHY_COLORS=/path/to/colors.toml` 2. `~/.local/state/omarchy/current/theme/colors.toml` (Omarchy Quattro) 3. `$XDG_CONFIG_HOME/omarchy/current/theme/colors.toml` (pre-Quattro fallback) 4. Named Omarchy themes such as `$XDG_CONFIG_HOME/omarchy/themes/verde/colors.toml` or `~/.config/omarchy/themes/verde/colors.toml` Missing values fall back to Verde defaults. See [`examples/omarchy/verde/colors.toml`](https://github.com/JonathanRiche/verde/blob/master/examples/omarchy/verde/colors.toml) for the shape. ## State files App state is saved through SDL's pref path in `state.sqlite`. Discover the exact path on your machine with: ```bash verde state path --json ``` You can read projects, panes, threads, and transcripts offline: ```bash verde state workspaces --json verde state panes --project current --json verde state threads --project current --json verde state transcript --project current --thread 0 --json ``` See [CLI reference](/docs/cli) for the full state command surface. ## Logs Verde writes runtime logs under SDL's platform pref path. Discover the exact directory on your machine with `verde state path --json`. On Linux, the usual paths are: - `~/.local/share/verde/Native/logs/verde.stderr.log` - `~/.local/share/verde/Native/logs/last-crash.log` Those files capture Zig panic output, provider helper stderr, and the last panic marker written before the app aborted. Tail the stderr log to diagnose provider crashes, prompt-send failures, or rendering issues. ## Third-party components Main third-party components used by the desktop app: - `@anthropic-ai/claude-agent-sdk` for Claude Code provider integration. - `fff.nvim` / `fff-c` / `fff-search` for fast file indexing and search, vendored in [`vendor/fff`](https://github.com/JonathanRiche/verde/tree/master/vendor/fff). License: MIT. - Ghostty / `libghostty-vt` for terminal emulation and VT parsing. License: MIT. - `zsdl` from `zig-gamedev` for Zig bindings to SDL3. License: MIT. - SDL3 from libsdl-org for windowing, input, display integration, and rendering support. - `zqlite` by Karl Seguin for SQLite access. License: MIT-style. - `zig_dif` and `zig_markdown` for chat markdown and code rendering. - `stb_image` by Sean Barrett and contributors for image decoding, vendored in [`vendor/stb_image.h`](https://github.com/JonathanRiche/verde/blob/master/vendor/stb_image.h). License: public domain or MIT. - Codicon, Nerd Fonts, Noto Sans, JetBrains Mono Nerd Font, and Cal Sans font assets for the native UI. See notices in [`packages/desktop/src/assets/fonts`](https://github.com/JonathanRiche/verde/tree/master/packages/desktop/src/assets/fonts). If you redistribute Verde, keep the relevant upstream notices and license texts with the distributed app and any vendored source. Verde is licensed under the MIT License — see [LICENSE](https://github.com/JonathanRiche/verde/blob/master/LICENSE). --- # Troubleshooting Source: https://verdeai.dev/docs/troubleshooting Edit: https://github.com/JonathanRiche/verde/blob/master/packages/website/src/content/docs/troubleshooting.md ## Provider prompt sending fails If sending a prompt produces an error instead of streaming a reply, check in this order: 1. **Is the provider installed?** Run `which codex`, `which opencode`, `which agent`, etc., from the shell Verde was launched in. GUI launches on some platforms inherit a different `PATH` than a terminal — relaunch Verde from a terminal if you suspect this. ```bash which codex which opencode which agent which pi which fx which grok ``` 2. **Is the provider authenticated?** Re-run the provider's login command and confirm credentials are still valid: ```bash codex login agent login fx login grok login ``` Claude Code is authenticated through its own SDK; Verde has no Verde-side login for it. Make sure the Claude Code binary and `node` are both reachable from the shell environment Verde was launched from. Pi authenticates with `pi login` or API keys in pi's own settings. 3. **Is the project imported?** Verde runs the provider against the imported project directory. A provider CLI in a different working directory will not see the same files. 4. **Check the logs.** Provider helper stderr is written to the runtime log alongside Zig panics. On Linux: ```bash tail -f ~/.local/share/verde/Native/logs/verde.stderr.log ``` For provider-specific setup, see [Provider setup](/docs/providers). ## Provider readiness does not update After installing a provider CLI or completing its login flow, return to **Connect an AI provider** and choose **Check again**. If its state still says **CLI not found**, launch Verde from the same shell where the provider command works; desktop launchers can inherit a different `PATH`. If it says **Sign-in needed**, run the provider's login command outside Verde and retry. A timed-out or failed probe appears as **Could not verify** and should be checked against the runtime log. Amp never appears on this screen because it is a terminal-only provider. ## Linux browser runtime missing The embedded browser pane on Linux uses the system WPE WebKit runtime — there is no bundled Chromium. If the required libraries are missing, the installer warns and prints the install command for your distribution. The libraries Verde looks for are: - `libWPEWebKit-2.0.so` - `libWPEBackend-fdo-1.0.so` - `libjavascriptcoregtk-6.0.so` - `libEGL.so.1` - `libGLESv2.so.2` Install them by distribution: | Distro | Command | | ------------ | --------------------------------------------------------------------------------------------- | | Arch | `sudo pacman -S wpewebkit wpebackend-fdo` | | Debian 13+ | `sudo apt-get update && sudo apt-get install libwpewebkit-2.0-1 libwpebackend-fdo-1.0-1 libjavascriptcoregtk-6.0-1 libegl1 libgles2` | | Fedora | `sudo dnf install wpewebkit wpebackend-fdo` | | openSUSE | `sudo zypper install libWPEWebKit-2_0-1 libwpebackend-fdo-1_0-1 libjavascriptcoregtk-6_0-1 libEGL1 libGLESv2-2` | You can also let the installer install them by setting `VERDE_INSTALL_BROWSER_DEPS=1` before running it: ```bash curl -fsSL https://verdeai.dev/install.sh | VERDE_INSTALL_BROWSER_DEPS=1 sh ``` ## WebView2 on Windows Windows native-webview builds use Microsoft WebView2. Windows systems that do not include WebView2 need the Microsoft WebView2 Runtime installed separately, and packaged builds must ship or locate `WebView2Loader.dll` next to `verde.exe` or on the DLL search path. The Windows native-webview build also requires the Microsoft WebView2 SDK headers at compile time. ## Design Mode has no screenshot The element and region selector works with WPE WebKit on Linux, WKWebView on macOS, and WebView2 on Windows. Selection screenshots currently require the Linux WPE backend's frame-copy support. On macOS and Windows, Verde sends the instruction and DOM context without an image; this is expected. See [Design Mode](/docs/design-mode) for routing details. ## Update check or install fails Open **Settings → App → Updates** and choose **Check now** again. Update checks and installers need access to GitHub release metadata and assets. If the in-app flow still fails, run: ```bash verde update --json ``` The JSON error is suitable for scripts and issue reports. Standalone Linux/macOS installs need `curl`; Windows uses PowerShell. A `verde-bin` installation from the AUR needs either `yay` or `paru`; Settings shows a copyable update command for your package manager. For standalone installs, review the updater terminal for download or installation errors and keep Verde open until the installer finishes. You can also use the install command on the [homepage](/#install) to replace a standalone installation manually. ## Source-build errors Source builds require Zig `0.16.0` and SDL3 development files for your platform. The default browser backend uses the host platform webview instead of bundled Chromium. Linux builds also require WPE WebKit development packages. The supported invocation from the repo root is: ```bash mise run build ``` If you must call the build directly: ```bash zig build --release=safe -Dbrowser-backend=native_webview ``` Common pitfalls: - **Bare `zig build` does not compile.** It defaults to Debug + the WPE `verde-browser-linux` helper, which hits a `crt1.o` linker error. Always pass `--release=safe -Dbrowser-backend=native_webview`, or use `mise run build`. - **Running `zig build` from `packages/desktop`.** That installs to `packages/desktop/zig-out`, not the top-level `zig-out/bin/verde` the app launches from. Always build from the repo root. For release-style local installs, use the packaged install scripts: ```bash bash ./scripts/release/install-linux-local.sh ./scripts/release/install-macos-local.sh ``` ## Reading the runtime logs Verde writes runtime logs under SDL's platform pref path. On Linux, the usual paths are: - `~/.local/share/verde/Native/logs/verde.stderr.log` - `~/.local/share/verde/Native/logs/last-crash.log` Those files capture Zig panic output, provider helper stderr, and the last panic marker written before the app aborted. If the app crashes, the `last-crash.log` is the single best place to start. Discover the exact pref path on your machine: ```bash verde state path --json ``` ## Inspecting the live app While the app is running, you can inspect a lot without touching the UI: ```bash verde live status --json | jq '.result.browser' verde live panes --project current --json verde live processes --json verde live inspect --focused --json ``` Exit code `3` means the live server is not running or not ready — start the app first. See [CLI reference](/docs/cli) for the full command surface and exit codes. ## The session daemon Chat turns and persistent terminal sessions run in a background session daemon that outlives the desktop window. Useful properties when debugging: - Closing or restarting the app does **not** kill running agent turns or terminal sessions; the GUI reattaches to them on the next launch. - When a newer Verde starts against an older daemon, the daemon drains and upgrades itself automatically. If the CLI reports `method_not_found` for a feature the docs say exists, an old daemon is usually still winding down — retry after a moment, or restart the app. - `verde session list --json` shows daemon-owned terminal sessions even while the desktop app is closed. ## Getting help - [GitHub issues](https://github.com/JonathanRiche/verde/issues) for bugs and feature requests. - [CLI reference](/docs/cli) and [Configuration & state](/docs/config) for the full programmatic surface. - [Provider setup](/docs/providers) for provider-specific setup and authentication.