Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
# Finalize TOML Schema for Tab Configs
Linear: [APP-3575](https://linear.app/warpdotdev/issue/APP-3575/finalize-toml-schema-for-tab-configs)
## Summary
Replace the recursive `[layout]` / `[[layout.panes]]` TOML nesting in tab configs with a flat `[[panes]]` array where nodes reference children by string ID. This makes deeply nested split layouts readable and hand-editable, and ships a bundled Oz skill so users can generate tab configs from natural language.
## Problem
The existing tab config layout format uses recursive TOML tables (`[[layout.panes]]`, `[[layout.panes.panes]]`, etc.). At depth 3+ this becomes unreadable and error-prone for hand-editing. Users who want a 2x2 grid or deeper nesting have to mentally track nested array-of-tables syntax, which is a significant barrier to adoption.
Additionally, there is no guided way for users to create tab configs — they must hand-author TOML from scratch.
## Goals
- A flat, ID-referenced pane tree format that supports arbitrarily deep nesting while remaining readable.
- A bundled Oz skill (`tab-configs`) that generates valid tab config TOML from natural language descriptions.
- A default template that is ready to use out of the box (single terminal pane, uncommitted, with `commands = []` pre-populated).
- Tab color support (`color` field) matching launch config parity.
## Non-goals
- Supporting non-terminal pane types beyond agent and cloud (notebook, code, settings, etc.).
- Multi-tab or multi-window configs (tab configs define a single tab by design).
- Proportional/flex sizing of children within a split.
- Converting existing launch configs to the new tab config format.
## Figma
Figma: none provided. This feature has no new UI — it changes the file format and adds an Oz skill.
## User experience
### Creating a new tab config
1. User clicks `+` → "Create new tab config..." in the tab bar menu.
2. Warp writes the default template to `~/.warp/tab_configs/my_tab_config.toml` and opens it in the user's configured editor.
3. The template contains an active single-pane config with `commands = []`, and commented-out examples for two-pane split, 2x2 grid, and parameterized configs.
4. The template header mentions the Oz skill: "Ask Oz to generate a tab config for you!"
### Using the Oz skill
- User invokes `/skills → tab-configs` or asks Oz naturally (e.g. "create me a 2x2 tab config with one pane running my dev server").
- Oz generates a valid `.toml` file and writes it to `~/.warp/tab_configs/`.
- The file immediately appears in the `+` menu (the filesystem watcher picks it up).
### Opening a tab config
- User clicks `+` → "New Tab: <config name>".
- If the config has `[params]`, a modal appears for the user to fill in values.
- Warp opens a new tab with the specified pane layout, running any configured commands.
- If the config has a `color` field, the tab gets that color.
### Format behavior
- Pane layout is defined with a flat `[[panes]]` array.
- The first `[[panes]]` entry is the root of the tree.
- Split nodes have `split` (horizontal/vertical) and `children` (ordered array of child IDs).
- Leaf nodes have `id`, required `type` (`"terminal"`, `"agent"`, or `"cloud"`), optional `cwd`, optional `commands`, and optional `is_focused`.
- `terminal` opens a standard shell session. `agent` opens a terminal in Agent Mode. `cloud` opens a cloud mode (ambient agent) pane with no local shell.
- `cwd` and `commands` apply to `terminal` and `agent` types; they are ignored for `cloud`.
- `worktree_name_autogenerated` (optional, bool, default false): when `true`, Warp auto-generates the worktree branch name instead of prompting the user. The app detects worktree configs by scanning `commands` for `git worktree`.
- All children within a split are equally sized.
- If no pane has `is_focused = true`, the first leaf pane gets focus automatically.
### Error handling
- If the flat pane tree has validation errors (missing child references, duplicate IDs, fewer than 2 children in a split), the config falls back to a single empty terminal pane and logs a warning.
- Invalid TOML or missing `name` field causes the file to be skipped with a warning logged.
## Success criteria
1. A tab config using the flat `[[panes]]` format with a horizontal 2-pane split opens correctly: two side-by-side terminal panes, each with the specified `cwd` and `commands`.
2. A tab config using the flat format with a 2x2 grid (horizontal split → two vertical splits → four terminals) opens correctly with four equal-sized panes.
3. A tab config with `color = "blue"` opens with a blue tab.
4. A tab config with `is_focused = true` on a specific pane gives that pane initial focus.
5. A tab config with no `is_focused` gives focus to the first (leftmost/topmost) leaf pane.
6. A tab config with `[params]` shows the param-fill modal before opening.
7. A tab config with a `[[panes]]` format that has an invalid child reference logs a warning and opens a single empty terminal pane.
8. The `tab-configs` bundled skill appears in `/skills` in Warp.
9. The default template, when uncommitted and left as-is, parses as a valid single-pane tab config named "My Tab Config".
## Validation
- Unit tests for parsing and rendering the flat format (single pane, split, 2x2, focus handling, error cases).
- Manual verification: create a 2x2 tab config TOML, open it from the `+` menu, confirm four panes appear with correct `cwd` and `commands`.
- Manual verification: invoke the `tab-configs` skill and confirm it generates a valid TOML file that opens correctly.
## Open questions
(None outstanding.)
+118
View File
@@ -0,0 +1,118 @@
# Finalize TOML Schema for Tab Configs — Tech Spec
Linear: [APP-3575](https://linear.app/warpdotdev/issue/APP-3575/finalize-toml-schema-for-tab-configs)
## Problem
The recursive `[layout]` / `[[layout.panes]]` TOML format becomes unreadable at depth 3+. We need to replace it with a flat `[[panes]]` array where nodes reference children by string ID, add tab color support, and ship a bundled Oz skill for generating configs.
## Relevant code
- `app/src/tab_configs/tab_config.rs` — `TabConfig`, `TabConfigPaneNode`, `render_tab_config`, `resolve_pane_tree`
- `app/src/tab_configs/tab_config_tests.rs` — existing tests for parsing and rendering
- `app/src/tab_configs/mod.rs` — public exports
- `app/src/workspace/view.rs:4702-4780` — `open_tab_config_with_params`, `open_tab_config`, `create_and_open_new_tab_config`
- `app/src/launch_configs/launch_config.rs` — `PaneTemplateType`, `SplitDirection`, `CommandTemplate` (the output types tab configs produce)
- `app/src/pane_group/mod.rs:1181-1333` — `pane_tree_from_template` (consumes `PaneTemplateType` to create panes)
- `app/src/user_config/native.rs:228-232` — `load_tab_configs`
- `app/src/user_config/util.rs:167-180` — `parse_tab_config_dir_entry` (TOML parsing)
- `app/resources/tab_configs/new_tab_config_template.toml` — default template
- `resources/bundled/skills/tab-configs/SKILL.md` — bundled Oz skill
- `app/src/ai/skills/skill_manager.rs` — bundled skill loading from `resources/bundled/skills/`
## Current state
Tab configs are TOML files in `~/.warp/tab_configs/`. They previously used a recursive `TabConfigLayout` struct with nested `panes: Vec<TabConfigLayout>` for child splits, which became impractical at depth 3+.
There is no `color` field on `TabConfig` — launch configs support color via `TabTemplate.color` but tab configs don't.
There is no bundled skill for generating tab configs.
## Proposed changes
### 1. New struct: `TabConfigPaneNode`
A flat node in the `[[panes]]` array. Distinguished as split vs leaf by the presence of `split` + `children`. No `type` field — all leaves are terminal panes (a `type` discriminator will be added when non-terminal pane types are supported).
Fields: `id`, `pane_type` (serde-renamed to `type`), `split`, `children`, `is_focused`, `cwd`, `commands`, `worktree_name_autogenerated`.
`worktree_name_autogenerated` (bool, default false): when `true`, the param-fill UI auto-generates the worktree branch name instead of showing a free-text input. The app infers "is this a worktree config?" by scanning `commands` for `git worktree` — no separate `worktree` flag is needed.
### 1b. New enum: `TabConfigPaneType`
Terminal / Agent / Cloud — maps to `PaneMode` at render time.
### 1c. New enum: `PaneMode` (in `launch_config.rs`)
Terminal (default) / Agent / Cloud — added as a field on `PaneTemplateType::PaneTemplate` with `#[serde(default)]` so launch config deserialization is unaffected.
### 2. Updated `TabConfig`
Add two fields:
- `color: Option<AnsiColorIdentifier>` — tab color, applied after tab creation (matching the launch config pattern in `open_launch_config_window`).
- `panes: Vec<TabConfigPaneNode>` — flat pane list. The first entry is the root of the pane tree.
Remove the old `layout: TabConfigLayout` field and the `TabConfigLayout` struct entirely. The legacy `[layout]` format is no longer supported.
### 3. `resolve_pane_tree` function
Converts the flat `panes` list into a `PaneTemplateType` tree:
1. Index all nodes by ID. Reject duplicate IDs.
2. Root = first entry.
3. Recursively resolve: split nodes look up children by ID; leaf nodes produce `PaneTemplate { cwd, commands, is_focused }`.
4. Focus handling: if any pane has explicit `is_focused = true`, use it. Otherwise auto-focus the first leaf (matching legacy `render_layout` behavior).
5. On error (missing refs, <2 children), return `Err` and the caller falls back to a single empty terminal.
### 4. Updated `render_tab_config`
Always calls `resolve_pane_tree`. On error (empty panes, missing refs, missing `type` on a leaf, etc.), falls back to a single empty terminal pane with a logged warning. Leaf resolution maps `TabConfigPaneType` to `PaneMode` and sets it on the produced `PaneTemplate`.
### 5. Updated `open_tab_config_with_params` in workspace view
After `add_tab_with_pane_layout`, apply `tab_config.color` to the new tab's `selected_color` — the same pattern launch configs use at `workspace/view.rs:2386`.
### 6. Updated template
`app/resources/tab_configs/new_tab_config_template.toml` uses the new flat format. Active (uncommented) content is a single-pane terminal with `commands = []`. Commented examples show two-pane split, 2x2 grid, and parameterized configs.
### 7. Bundled Oz skill
`resources/bundled/skills/tab-configs/SKILL.md` contains the full schema reference, examples, validation rules, and common natural-language-to-layout mappings. The build script (`script/prepare_bundled_resources`) copies it into the app bundle automatically.
## End-to-end flow
1. User creates/edits a `.toml` file in `~/.warp/tab_configs/`.
2. Filesystem watcher in `WarpConfig` detects the change and calls `load_tab_configs`.
3. `parse_tab_config_dir_entry` calls `toml::from_str::<TabConfig>()`. The `panes` field deserializes from `[[panes]]` entries.
4. User selects the config from the `+` menu → `open_tab_config` is called.
5. If params exist, the param-fill modal opens. Otherwise `open_tab_config_with_params` is called directly.
6. `render_tab_config` builds param contexts, calls `resolve_pane_tree`, returns `(Option<String>, PaneTemplateType)`.
7. Workspace calls `add_tab_with_pane_layout(PanesLayout::Template(pane_template), ...)`.
8. `PaneGroup::pane_tree_from_template` recursively creates panes from the `PaneTemplateType` tree. For `PaneMode::Agent`, it creates a terminal session then enters agent mode. For `PaneMode::Cloud`, it creates an ambient agent pane via `create_ambient_agent_terminal`.
9. If `tab_config.color` is set, the tab's `selected_color` is updated.
## Risks and mitigations
- **Flat pane list validation**: Invalid configs (missing refs, cycles) are caught at render time with descriptive error messages logged and a fallback to a single terminal pane. The user's tab config file is never modified.
- **Skill generating invalid TOML**: The skill embeds validation rules and examples. The schema is simple enough (terminal-only, no type field) that generation errors are unlikely.
## Testing and validation
- Unit tests in `tab_config_tests.rs`:
- Parse single flat pane.
- Parse and render flat two-pane split.
- Parse and render flat 2x2 grid.
- Explicit `is_focused` honored.
- Auto-focus first leaf when no explicit focus.
- Invalid flat pane tree (missing child ref) returns error.
- Duplicate IDs rejected.
- Tab color deserialized correctly.
- Manual: build and run Warp, create tab configs, verify pane layouts open correctly.
- Manual: invoke the `tab-configs` skill, confirm it generates a working config.
## Follow-ups
- Add non-terminal pane types (notebook, code, settings, etc.) with a `type` field discriminator.
- Consider cycle detection in validation (currently not implemented — the recursive resolver will stack overflow on cycles, but configs are small enough that this is not a practical concern).
- Consider orphan pane warnings (panes not referenced by any `children` and not the root).
- Investigate whether the Oz skill should auto-open the created config in the user's editor.