--- name: tab-configs description: Reference the Warp tab config schema, validation rules, and examples. Use when creating or updating Warp tab config TOML files or when another tab-config skill needs the canonical schema details. --- # tab-configs This skill is the canonical reference for Warp tab config TOML files. Tab configs live under `~/.warp/tab_configs/` for standard Warp builds. Non-stable builds (e.g. Preview or pre-release channels) use a channel-specific variant such as `~/.warp-/tab_configs/`. Do NOT use `~/Library/Application Support/` — that is the wrong location. To find the active data directory, inspect which `~/.warp*` directories exist on the user's machine. Each `.toml` file defines a single tab layout that appears in the `+` menu. When the user selects one, Warp opens a new tab with the configured pane layout and runs any specified commands. Use this skill as shared context: - `create-tab-config` should use it when authoring a new config. - `update-tab-config` should use it when modifying an existing config. - If this skill is invoked directly for a creation or editing task, follow the same guidance below. ## Guidance before writing or editing - If the request is missing important details, use the `ask_user_question` tool instead of guessing. Clarify things like: - whether the user wants a new config or wants to edit an existing one - the desired pane layout - directories, commands, and which pane should be focused - whether parameters are needed - Use descriptive pane IDs such as `"editor"`, `"server"`, or `"top_left"` instead of generic names like `"pane1"`. - Use snake_case file names for new configs. - When creating or locating tab configs, use the correct tab config directory for the user's current Warp build/channel rather than hardcoding a single base directory. - If updating an existing config, read the file first and preserve user structure where possible. ## Schema Reference ### Top-level fields - `name` (required, string): Display name shown in the `+` menu. - `title` (optional, string): Custom tab title. Supports `{{param}}` template variables. - `color` (optional, string): Tab color. One of: `"black"`, `"red"`, `"green"`, `"yellow"`, `"blue"`, `"magenta"`, `"cyan"`, `"white"`. ### Pane list All panes are defined in a flat `[[panes]]` array of tables. The **first entry is the root**. Each entry is either a **split node** (branch) or a **leaf node**. #### Leaf node fields - `id` (required, string): Unique identifier. - `type` (required, string): `"terminal"` (standard shell), `"agent"` (opens in Agent Mode), or `"cloud"` (cloud mode pane, no local shell). - `directory` (optional, string): Initial working directory. Supports `~` expansion. Applies to `terminal` and `agent` types. - `commands` (optional, array of strings): Commands to run in sequence on open. Applies to `terminal` and `agent` types. - `is_focused` (optional, bool): Set `true` on at most one pane to give it initial focus. - `shell` (optional, string): Shell executable to open this pane in (e.g. `"pwsh"`, `"zsh"`, `"bash"`, `"fish"`). Only applies to `terminal` and `agent` types. If omitted or the shell is not installed, the user's default shell is used. #### Split node fields - `id` (required, string): Unique identifier for this node. - `split` (required, string): `"horizontal"` (children arranged left-to-right) or `"vertical"` (children arranged top-to-bottom). - `children` (required, array of strings): Ordered list of child pane IDs. Must have 2+ entries. Order = visual order. ```toml [[panes]] id = "server" type = "terminal" directory = "~/code/backend" commands = ["cargo watch -x run"] ``` ### Sizing All children within a split are equally sized. There are no flex or proportion values. ### Parameters Parameters let users fill in values at open time via a modal UI. Declare them with `[params.]` tables. Reference them in `directory`, `commands`, and `title` with `{{name}}` syntax. `{{autogenerated_branch_name}}` is a special-cased reserved template variable: if a tab config references it, Warp generates a unique worktree branch name on each open instead of prompting the user for that value. Each parameter has: - `type` (optional, string): `"text"` (default), `"branch"` (git branch picker), or `"repo"` (repo picker). - `description` (optional, string): Shown in the fill-in UI. - `default` (optional, string): Default value. ```toml [params.project_dir] type = "repo" description = "Project directory" [params.branch] type = "branch" description = "Branch to check out" ``` ### Validation rules Ensure your output follows these rules: - Every ID in a `children` array must reference an existing `[[panes]]` entry. - No cycles in the pane tree. - Leaf panes must NOT have `children` or `split`. - Leaf panes must have a `type` field (`"terminal"`, `"agent"`, or `"cloud"`). - Split panes (have `split`) must have `children` with at least 2 entries. - At most one pane may have `is_focused = true`. - All `id` values must be unique across the file. - The first `[[panes]]` entry is the root of the tree. ## Examples ### Single pane ```toml name = "Dev Server" [[panes]] id = "main" type = "terminal" directory = "~/code/my-app" commands = ["npm run dev"] ``` ### Two panes side by side ```toml name = "Editor + Server" color = "green" [[panes]] id = "root" split = "horizontal" children = ["editor", "server"] [[panes]] id = "editor" type = "terminal" directory = "~/code/my-app" commands = ["nvim ."] is_focused = true [[panes]] id = "server" type = "terminal" directory = "~/code/my-app" commands = ["npm run dev"] ``` ### 2x2 grid ```toml name = "Full Stack" [[panes]] id = "root" split = "horizontal" children = ["left_col", "right_col"] [[panes]] id = "left_col" split = "vertical" children = ["frontend", "backend"] [[panes]] id = "frontend" type = "terminal" directory = "~/code/frontend" commands = ["npm run dev"] is_focused = true [[panes]] id = "backend" type = "terminal" directory = "~/code/backend" commands = ["cargo watch -x run"] [[panes]] id = "right_col" split = "vertical" children = ["tests", "logs"] [[panes]] id = "tests" type = "terminal" directory = "~/code/backend" commands = [] [[panes]] id = "logs" type = "terminal" directory = "~/code/backend" commands = ["tail -f logs/dev.log"] ``` ### Three-pane layout (1 left, 2 stacked right) ```toml name = "Main + Side Stack" [[panes]] id = "root" split = "horizontal" children = ["main", "side_stack"] [[panes]] id = "main" type = "terminal" directory = "~/code/project" commands = [] is_focused = true [[panes]] id = "side_stack" split = "vertical" children = ["top_right", "bottom_right"] [[panes]] id = "top_right" type = "terminal" directory = "~/code/project" commands = [] [[panes]] id = "bottom_right" type = "terminal" directory = "~/code/project" commands = [] ``` ### With parameters Warp-generated worktree configs default to `~/.warp/worktrees//`. When writing a reusable config by hand, derive the repo-name segment at shell runtime with `$(basename {{repo}})`. ```toml name = "New Worktree" title = "{{branch_name}}" [[panes]] id = "main" type = "terminal" directory = "{{repo}}" commands = [ "git worktree add -b {{branch_name}} $HOME/.warp/worktrees/$(basename {{repo}})/{{branch_name}} {{base_branch}}", "cd $HOME/.warp/worktrees/$(basename {{repo}})/{{branch_name}}", ] [params.repo] type = "repo" description = "Repository path" [params.base_branch] type = "branch" description = "Base branch to branch from" [params.branch_name] type = "text" description = "New branch name" default = "my-feature" ``` ## Common patterns When the user says... | Generate... "single pane" / "simple tab" | One `[[panes]]` leaf entry "split" / "side by side" / "two panes" | Horizontal split with 2 terminal children "top and bottom" / "stacked" | Vertical split with 2 terminal children "2x2" / "grid" / "four panes" | Horizontal split → 2 vertical splits → 4 terminals "run X" / "auto-run X" | Put `X` in the `commands` array "with claude" / "running claude" | `commands = ["claude"]` in the relevant pane "three panes" (no further detail) | Horizontal split: 1 terminal + 1 vertical split with 2 terminals