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
+150
View File
@@ -0,0 +1,150 @@
# APP-3713: Vertical Tabs — Primary Info Selector in Settings Popup
## Summary
Replace the placeholder "Group panes by" section in the vertical tabs settings popup with a "Show first" selector that lets users choose which information appears on the primary (top) line of terminal pane rows. The two options are "Command / Conversation" (default, current behavior) and "Directory / Branch" (swaps the current primary and secondary lines). The selected option shows a checkmark. This applies to both expanded and compact view modes.
## Problem
The vertical tabs settings popup currently contains a "Group panes by" section with a single hardcoded "Tab" option that does nothing useful. This section occupies popup real estate without providing value. Meanwhile, users have different workflows: some care most about _what_ is running (the terminal command or agent conversation) while others care most about _where_ they are (the working directory and git branch). There is no way to customize which of these is most prominent in the pane row.
## Goals
- Let users choose whether terminal pane rows prioritize the terminal command / agent conversation title or the working directory / git branch as the primary line.
- Remove the non-functional "Group panes by" section from the settings popup.
- Persist the preference across sessions as a synced cloud setting.
- Apply the preference to both expanded and compact view modes.
## Non-goals
- Adding group-by functionality (the section being removed was a placeholder for future work; re-adding it is a separate concern).
- Changing non-terminal pane rows (code, notebook, settings, etc.) — this only affects terminal pane rows.
- Changing the segmented compact/expanded control in the popup (it remains unchanged below the divider).
## Figma / design references
Figma: none provided
## User experience
### Setting
A new user setting (`VerticalTabsPrimaryInfo`) controls which content appears on the primary line of terminal pane rows. It has two variants:
- **`Command`** (default): Terminal command / agent conversation title is the primary line. Working directory / git branch is the secondary line. This matches the current behavior.
- **`WorkingDirectory`**: Working directory / git branch is the primary line. Terminal command / agent conversation title is the secondary line.
The setting is a synced cloud setting (same sync behavior as `VerticalTabsViewMode`).
### Settings popup layout
The popup replaces the current "Group panes by" section. The new layout is:
```
┌──────────────────────────────────┐
│ Show first │ ← section header (sub-text color)
│ ✓ Command / Conversation │ ← option (selected state shown)
│ Directory / Branch │ ← option
│ ─────────────────────────── │ ← divider (unchanged)
│ [ compact ] [ expanded ] │ ← segmented control (unchanged)
└──────────────────────────────────┘
```
#### Section header
- Text: **"Show first"**
- Styled identically to the current "Group panes by" header: sub-text color, 12px, 16px horizontal padding, 8px bottom margin.
#### Option items
Each option is a single row inside the popup. The currently selected option shows a checkmark icon on the left; the unselected option shows an empty space of the same width (so text stays aligned).
- **"Command / Conversation"**: When selected, terminal pane rows use the current primary/secondary line assignment (terminal command or agent conversation title on top, working directory on the second line).
- **"Directory / Branch"**: When selected, terminal pane rows swap their primary and secondary lines (working directory / git branch on top, terminal command or agent conversation title on the second line).
Clicking an option:
1. Updates the `VerticalTabsPrimaryInfo` setting immediately.
2. The panel re-renders with the new line order.
3. The popup **stays open** (so the user can see the checkmark move and the change take effect, then dismiss manually).
Each option row:
- Has 16px horizontal padding (matching the current "Tab" item).
- Shows the checkmark icon (16×16, main-text color) for the selected option, or a 16×16 transparent spacer for the unselected option.
- 8px gap between the icon/spacer and the label text.
- Label text is 12px in main-text color.
- Has a hover highlight (same `fg_overlay_1` pattern used elsewhere in the popup).
- Cursor changes to pointing hand on hover.
#### Divider and segmented control
Unchanged from the current implementation. The divider separates the "Show first" section from the compact/expanded segmented control.
### Effect on expanded terminal pane rows
#### When `Command` is selected (default — current behavior)
No change from today. The expanded terminal row layout remains:
1. **Primary line** (main text color): terminal title, agent conversation status + title, CLI agent title, or last completed command (per the existing precedence rules from APP-3651).
2. **Secondary line** (sub text color): working directory • git branch.
3. **Tertiary line**: kind badge + badges (unchanged).
#### When `WorkingDirectory` is selected
The primary and secondary lines swap:
1. **Primary line** (main text color): working directory • git branch. Uses the same layout as the current secondary line but rendered in main-text color. Working directory clips from the start; git branch clips from the end.
2. **Secondary line** (sub text color): terminal title, agent conversation status + title, CLI agent title, or last completed command (same precedence rules as the current primary line, but rendered in sub-text color). For agent conversations, the status indicator icon still precedes the title text.
3. **Tertiary line**: kind badge + badges (unchanged).
### Effect on compact terminal pane rows
#### When `Command` is selected (default — current behavior)
No change. The compact row shows the terminal icon + terminal title (or agent status icon + conversation title) as a single line.
#### When `WorkingDirectory` is selected
The compact row shows:
- **Non-agent terminal**: Terminal icon + working directory (instead of terminal title). The working directory clips from the start.
- **Agent terminal (Oz or CLI agent)**: Conversation status icon + working directory (instead of conversation title). The working directory clips from the start.
- **Ambient agent**: `OzCloud` icon + working directory.
#### Icon behavior (both modes)
The kind icon at the start of the compact row is always determined by the pane type and agent state, not by the primary info setting. A non-agent terminal always shows the terminal icon; an agent terminal always shows the conversation status icon; an ambient agent always shows the `OzCloud` icon. Only the *text* portion of the row changes when the setting is toggled.
### Non-terminal panes
Non-terminal pane rows (code, notebook, settings, etc.) are not affected by this setting in either view mode. Their layout remains unchanged.
### Search behavior
The search input already indexes both the primary text and the working directory for terminal panes. This behavior is unchanged — both fields remain searchable regardless of which is shown as the primary line.
## Success criteria
1. The "Group panes by" header and "Tab" item are removed from the settings popup.
2. A "Show first" header appears at the top of the popup with two options: "Command / Conversation" (checked by default) and "Directory / Branch".
3. Clicking "Directory / Branch" moves the checkmark to that option and immediately swaps the primary and secondary lines for all terminal pane rows.
4. Clicking "Command / Conversation" restores the default line order and moves the checkmark back.
5. In expanded mode with "Directory / Branch" selected: the primary line shows the working directory (start-clipped) and git branch in main-text color; the secondary line shows the terminal title or agent conversation title in sub-text color.
6. In expanded mode with "Directory / Branch" selected and an active agent conversation: the secondary line shows the conversation status indicator followed by the conversation title in sub-text color.
7. In compact mode with "Directory / Branch" selected: the single-line row shows the terminal icon + working directory (start-clipped) instead of the terminal title.
8. In compact mode with "Directory / Branch" selected and an agent conversation: the row shows the conversation status icon + working directory.
9. The setting persists across sessions. Quitting and relaunching with "Working directory" selected shows the same line order.
10. The popup stays open after clicking an option, allowing the user to see the change and dismiss manually.
11. The segmented compact/expanded control below the divider is unchanged.
12. Non-terminal panes are unaffected by the setting.
## Validation
- **Manual toggle**: Open the settings popup, switch between "Command / Conversation" and "Directory / Branch". Verify the pane rows update immediately and the checkmark moves.
- **Expanded mode**: With "Directory / Branch" selected, verify the primary line shows the working directory (start-clipped) + git branch in main-text color, and the secondary line shows the terminal title or agent info in sub-text color.
- **Compact mode**: Switch to compact mode with "Directory / Branch" selected. Verify the single-line row shows terminal icon + working directory.
- **Agent panes**: Start an agent conversation. With "Directory / Branch" selected, verify the expanded secondary line shows the status indicator + conversation title. In compact mode, verify the status icon + working directory.
- **Persistence**: Select "Directory / Branch", quit Warp, relaunch, and verify the setting is preserved.
- **Non-terminal panes**: Open a code pane or notebook. Verify changing the primary info setting has no effect on these rows.
- **Search**: With "Directory / Branch" as primary, search for a terminal title string. Verify it still matches (search indexes both fields regardless of display order).
## Open questions
None — all resolved. Agent panes swap uniformly with non-agent terminals (working directory becomes primary when "Directory / Branch" is selected).
+200
View File
@@ -0,0 +1,200 @@
# APP-3713: Tech Spec — Primary Info Selector in Vertical Tabs Settings Popup
## Problem
The vertical tabs settings popup contains a hardcoded "Group panes by" section with a single "Tab" option that has no effect. Per the product spec, this section should be replaced with a "Show first" selector that lets users choose whether terminal pane rows display the terminal command / agent conversation title or the working directory / git branch as the primary (top) line. The setting must affect both expanded and compact view modes and persist across sessions.
## Relevant code
- `app/src/workspace/tab_settings.rs (166-214)` — `VerticalTabsViewMode` enum and `TabSettings` group; the new setting will live here
- `app/src/workspace/view/vertical_tabs.rs (2004-2143)` — `render_settings_popup` and the "Group panes by" / "Tab" UI to be replaced
- `app/src/workspace/view/vertical_tabs.rs (1395-1447)` — `render_terminal_row_content` (expanded mode), assembles primary + secondary + tertiary lines
- `app/src/workspace/view/vertical_tabs.rs (1449-1479)` — `render_terminal_primary_line_for_view`, builds the primary line element from `TerminalView` data
- `app/src/workspace/view/vertical_tabs.rs (1585-1646)` — `render_terminal_secondary_line`, builds working directory + git branch line
- `app/src/workspace/view/vertical_tabs.rs (2183-2230)` — `render_compact_pane_row`, single-line compact rendering for terminal panes
- `app/src/workspace/action.rs (234-235)` — `ToggleVerticalTabsSettingsPopup` and `SetVerticalTabsViewMode` actions; new action for setting primary info will follow this pattern
- `app/src/workspace/view.rs (16988-17004)` — action handlers for the existing popup actions
- `app/src/workspace/view.rs (18467-18487)` — popup overlay rendering with `Dismiss` wrapper
- `app/src/workspace/view/vertical_tabs_tests.rs` — existing unit tests for primary line data logic
- `app/src/workspace/action_tests.rs` — tests for action `should_save_app_state_on_action`
## Current state
### Setting and persistence
`VerticalTabsViewMode` is a two-variant enum (`Compact`, `Expanded`) registered as a synced cloud setting in `TabSettings`. It uses the `implement_setting_for_enum!` macro with `SyncToCloud::Globally(RespectUserSyncSetting::Yes)` and hierarchy `"appearance.tabs"`. The new primary info setting will follow this exact pattern.
### Settings popup
`render_settings_popup` builds a fixed-width (200px) popup with:
1. A "Group panes by" header (sub-text color, 12px)
2. A "Tab" item (checkmark icon + "Tab" label, always selected)
3. A divider
4. A segmented control for compact/expanded
The "Group panes by" section is purely visual — it dispatches no actions and reads no settings.
### Expanded terminal row rendering
`render_terminal_row_content` builds a three-line column:
- **Primary**: calls `render_terminal_primary_line_for_view` → `render_terminal_primary_line`, which resolves `TerminalPrimaryLineData` through the precedence cascade (conversation title > CLI agent title > terminal title > last command > "New session"), then renders in main-text color.
- **Secondary**: calls `render_terminal_secondary_line(working_directory, git_branch)`, which renders working directory (start-clipped) + git branch (end-clipped) in sub-text color.
- **Tertiary**: kind badge + right-side badges (unchanged by this feature).
### Compact terminal row rendering
`render_compact_pane_row` calls `render_terminal_primary_line_for_view` with `Some(WarpIcon::Terminal)` as a prefix icon, producing a single-line row with the terminal icon + primary line data text. For agent terminals, the status icon comes from the `StatusText` variant of `TerminalPrimaryLineData`.
### Key render functions and their color contracts
- `render_terminal_primary_line` always uses `main_text_color`.
- `render_terminal_secondary_line` always uses `sub_text_color`.
When swapping lines, we need parameterized color rather than hardcoded main/sub text.
## Proposed changes
### 1. Add `VerticalTabsPrimaryInfo` setting
In `app/src/workspace/tab_settings.rs`, add a new enum and register it in `TabSettings`:
```rust
#[derive(Default, Debug, serde::Serialize, serde::Deserialize, PartialEq, Copy, Clone)]
pub enum VerticalTabsPrimaryInfo {
#[default]
Command,
WorkingDirectory,
}
```
Register with `implement_setting_for_enum!` using the same sync/hierarchy as `VerticalTabsViewMode`:
- `SupportedPlatforms::ALL`
- `SyncToCloud::Globally(RespectUserSyncSetting::Yes)`
- `hierarchy: "appearance.tabs"`
Add `vertical_tabs_primary_info: VerticalTabsPrimaryInfo` to the `TabSettings` group.
### 2. Add `SetVerticalTabsPrimaryInfo` action
In `app/src/workspace/action.rs`:
- Add variant `SetVerticalTabsPrimaryInfo(VerticalTabsPrimaryInfo)` next to `SetVerticalTabsViewMode`.
- In `should_save_app_state_on_action`, add it to the `false` arm (same as `SetVerticalTabsViewMode` — the setting is persisted via the settings framework, not workspace state).
In `app/src/workspace/view.rs`, add the handler in the same block as `SetVerticalTabsViewMode`:
```rust
SetVerticalTabsPrimaryInfo(primary_info) => {
let primary_info = *primary_info;
TabSettings::handle(ctx).update(ctx, |settings, ctx| {
let _ = settings.vertical_tabs_primary_info.set_value(primary_info, ctx);
});
ctx.notify();
}
```
### 3. Add mouse state handles for option rows
In `VerticalTabsPanelState`, add two new `MouseStateHandle` fields for the popup option rows:
```rust
command_option_mouse_state: MouseStateHandle,
directory_option_mouse_state: MouseStateHandle,
```
Initialize with `Default::default()` in the `Default` impl.
### 4. Replace popup "Group by" section with "Show first" section
In `render_settings_popup`:
**Remove**: The `group_by_header` and `tab_item` variables and their children in the assembled column.
**Replace with**: A "Show first" header and two clickable option rows.
The header reuses the same styling as the current "Group panes by" header but with text `"Show first"`.
Each option row is a `Hoverable` wrapping a `Flex::row` with:
- A 16×16 checkmark icon (`WarpIcon::Check` in main-text color) if selected, or a 16×16 `Empty` spacer if not.
- An 8px gap.
- Label text ("Command / Conversation" or "Directory / Branch") in main-text color, 12px.
On hover: `fg_overlay_1` background, pointing hand cursor.
On click: dispatch `WorkspaceAction::SetVerticalTabsPrimaryInfo(variant)`. The popup does **not** close on click (unlike `ToggleVerticalTabsSettingsPopup`), so the user sees the checkmark move.
Read the current setting via `*TabSettings::as_ref(app).vertical_tabs_primary_info.value()` to determine which option gets the checkmark.
The divider and segmented control below remain unchanged.
### 5. Parameterize text color in terminal line renderers
The existing `render_terminal_primary_line` hardcodes `main_text_color` and `render_terminal_secondary_line` hardcodes `sub_text_color`. To support swapping, add a `text_color: WarpThemeFill` parameter to both functions so the caller controls which color each line uses.
**`render_terminal_primary_line`**: Add `text_color` param. Replace `main_text_color` usage for text rendering with the passed color. The status indicator icon color remains unchanged (it comes from `render_status_element` and is independent of text color).
**`render_terminal_secondary_line`**: Add `text_color` param. Replace `sub_text_color` usage with the passed color.
### 6. Update `render_terminal_row_content` (expanded mode)
Read the primary info setting:
```rust
let primary_info = *TabSettings::as_ref(app).vertical_tabs_primary_info.value();
```
Branch on the setting to decide line order:
- **`Command` (default)**: Call `render_terminal_primary_line_for_view` with `main_text_color` as first child, `render_terminal_secondary_line` with `sub_text_color` as second child. This is the current behavior.
- **`WorkingDirectory`**: Call `render_terminal_secondary_line` with `main_text_color` as first child, `render_terminal_primary_line_for_view` with `sub_text_color` as second child. This swaps the line order and colors.
The tertiary line is always appended last, unchanged.
### 7. Update `render_compact_pane_row` (compact mode)
Read the primary info setting. For terminal panes:
- **`Command`**: Current behavior — call `render_terminal_primary_line_for_view` with `Some(WarpIcon::Terminal)` prefix icon.
- **`WorkingDirectory`**: Render a single-line row with the terminal icon (or agent status icon) + working directory text (start-clipped). This can be done by building a `Flex::row` directly:
- Add the kind icon (terminal icon for non-agent, status element for agent, `OzCloud` for ambient agent) — same icon logic as the current compact rendering.
- Add the working directory text with `ClipConfig::start()`.
The icon is always determined by pane type / agent state, not by the primary info setting.
### 8. Update `render_terminal_primary_line_for_view`
Add a `text_color: WarpThemeFill` parameter. Pass it through to `render_terminal_primary_line`.
All existing call sites pass `theme.main_text_color(theme.background())` to preserve current behavior unless the caller is in the swapped path.
## End-to-end flow
1. User clicks the settings icon button in the vertical tabs control bar → `ToggleVerticalTabsSettingsPopup` is dispatched → `show_settings_popup` toggles to `true` → popup renders via `render_settings_popup`.
2. Popup shows "Show first" header with "Command / Conversation" checked (default). Segmented control below.
3. User clicks "Directory / Branch" → `SetVerticalTabsPrimaryInfo(WorkingDirectory)` is dispatched → `TabSettings.vertical_tabs_primary_info` is updated → `ctx.notify()` triggers re-render.
4. Popup stays open; checkmark moves to "Directory / Branch".
5. All terminal pane rows in the panel re-render: expanded rows swap primary/secondary lines; compact rows show working directory text.
6. Setting is persisted to cloud via the settings sync framework.
7. On next launch, `TabSettings::as_ref(app).vertical_tabs_primary_info.value()` returns `WorkingDirectory`, so rows render in the swapped order immediately.
## Risks and mitigations
- **Color regression**: Parameterizing text color introduces risk of passing the wrong color at call sites. Mitigation: only two call sites per function (one for each branch of the setting match). Unit test the data logic; visual testing catches color regressions.
- **Compact mode icon/text mismatch**: In `WorkingDirectory` compact mode, an agent terminal must still show the status icon (not the terminal icon) but with the working directory text. The icon resolution logic is already separated from the text logic in the current code, so this is straightforward.
- **Search correctness**: `terminal_pane_search_text_fragments` indexes both the primary text and working directory regardless of display order. No changes needed; search stays correct.
## Testing and validation
### Unit tests (`vertical_tabs_tests.rs`)
- Add tests for the "Show first" setting variants confirming `VerticalTabsPrimaryInfo::Command` and `VerticalTabsPrimaryInfo::WorkingDirectory` are `Default` and `Copy`/`Clone`/`PartialEq` as expected.
### Action tests (`action_tests.rs`)
- `SetVerticalTabsPrimaryInfo` should return `false` from `should_save_app_state_on_action` (same pattern as the existing `SetVerticalTabsViewMode` test).
### Manual validation
Per the product spec validation section: toggle between options in the popup, verify expanded/compact rendering, agent panes, persistence across restart, search correctness, and non-terminal pane immunity.
## Follow-ups
- When group-by functionality is implemented in the future, the "Show first" section and the group-by section can coexist in the same popup. The popup layout would then be: "Show first" options → divider → "Group by" options → divider → segmented control.
- A keyboard shortcut for toggling the primary info setting could be added later.