Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
# HOA Onboarding Flow for Existing Users
|
||||
|
||||
Linear: APP-3809
|
||||
|
||||
## Summary
|
||||
|
||||
A guided onboarding flow that introduces existing Warp users to House of Agents (HOA) features: vertical tabs, agent inbox, and default tab config creation. The flow is shown once, behind a feature flag (`HOAOnboardingFlow`), and is only shown to users who did not go through the new-user onboarding (i.e. existing users who update to the HOA release).
|
||||
|
||||
## Problem
|
||||
|
||||
Existing Warp users will receive a major update with HOA features (vertical tabs, agent inbox/notifications, native code review, CLI agent integrations) but have no guided introduction to these changes. Without a targeted onboarding flow, users may not discover or understand the new capabilities, leading to lower adoption of key features.
|
||||
|
||||
## Goals
|
||||
|
||||
- Introduce existing users to HOA features through a 4-step guided flow.
|
||||
- Let users configure vertical vs. horizontal tabs with a live toggle.
|
||||
- Guide users to create their default tab config (session type, directory, worktree).
|
||||
- Show the flow exactly once per user, gated behind `HOAOnboardingFlow` feature flag.
|
||||
- Reuse the existing session config modal rendering code for the tab config step.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Redesigning the new-user onboarding flow.
|
||||
- Onboarding for features not shown in the Figma (e.g. MCP servers, voice input).
|
||||
- Animation of the welcome banner hero art (static image is acceptable for v1).
|
||||
- Allowing users to navigate backward through steps.
|
||||
|
||||
## Figma
|
||||
|
||||
https://www.figma.com/design/CsBdBW4YoLgSAbr5eSkwV6/House-of-Agents?node-id=7495-108638&m=dev
|
||||
|
||||
## User Experience
|
||||
|
||||
### Triggering conditions
|
||||
|
||||
- The `HOAOnboardingFlow` feature flag is enabled (dogfood initially).
|
||||
- The user has NOT gone through the new-user onboarding for this version.
|
||||
(Use a `private_user_preferences` key, similar to `HasCompletedOnboarding`, to track whether this flow has been shown.)
|
||||
- The flow is shown at most once. Completing any step or dismissing marks it as done.
|
||||
- New users who complete the standard onboarding flow should have this flag pre-set so they never see the HOA onboarding.
|
||||
|
||||
### Flow overview
|
||||
|
||||
The flow has 4 sequential steps. The user progresses forward only (no back navigation). Each step must be completed or the flow dismissed before normal interaction resumes.
|
||||
|
||||
---
|
||||
|
||||
### Step 1: Welcome Banner
|
||||
|
||||
**Presentation**: A centered modal dialog overlaying the terminal window with a semi-transparent background scrim.
|
||||
|
||||
**Content**:
|
||||
- Hero image area at top (Claude, OpenAI, OpenCode logos — static image).
|
||||
- X (close) button in the top-right corner of the hero area.
|
||||
- "New" badge (magenta pill).
|
||||
- Title: "Introducing first-class support for Claude Code, Codex, and OpenCode"
|
||||
- 4 feature bullet points, each with an icon:
|
||||
1. **Vertical tabs** (layout-left icon): "Rich tab-titles and customizable content, so you can keep an eye on your agents how you want."
|
||||
2. **Agent inbox and notifications** (inbox-01 icon): "Get notified when agents need approval or feedback, so nothing blocks progress."
|
||||
3. **Native code review** (message-check-square icon): "Review and refine code with your CLI agent without leaving Warp."
|
||||
4. **Warp's input bar** (text-input icon): "Move faster with a smarter input. Attach images, use voice, and trigger actions - all from one place."
|
||||
- Primary CTA button: "See what's new" (light text on dark background, full width within the card).
|
||||
|
||||
**Behavior**:
|
||||
- Clicking "See what's new" advances to Step 2.
|
||||
- Clicking the X button dismisses the entire flow and marks it complete. The user never sees it again.
|
||||
- The scrim blocks interaction with the terminal behind it.
|
||||
|
||||
---
|
||||
|
||||
### Step 2: Vertical Tabs Callout
|
||||
|
||||
**Presentation**: A tooltip/popover (480px wide) anchored to the vertical tab sidebar area, with a pointer/arrow indicating the target. The terminal remains visible behind it, but workspace interactions are blocked until the user advances or dismisses the flow. The vertical tabs sidebar should already be open/visible at this point.
|
||||
|
||||
**Content**:
|
||||
- Title: "Introducing vertical tabs - the new default"
|
||||
- Description: "Vertical tabs display all panes within each terminal window and have rich headers and context for all CLI agents."
|
||||
- Checkbox (unchecked by default): "Switch back to horizontal tabs"
|
||||
- Progress indicator: 3 dots, dot 1 active (filled blue).
|
||||
- "Next" button (primary, right-aligned in footer).
|
||||
|
||||
**Behavior**:
|
||||
- The checkbox is a **live toggle**: checking it immediately switches the tab layout to horizontal tabs. Unchecking switches back to vertical. The underlying tab layout setting is persisted when toggled.
|
||||
- The popover arrow/pointer updates position based on the current tab layout:
|
||||
- Vertical tabs: pointer points toward the left sidebar.
|
||||
- Horizontal tabs: pointer points toward the top tab bar.
|
||||
- Clicking "Next" advances to Step 3.
|
||||
|
||||
---
|
||||
|
||||
### Step 3: Agent Inbox Callout
|
||||
|
||||
**Presentation**: A tooltip/popover (480px wide) anchored to the inbox icon in the title bar (top-right area), with a pointer/arrow indicating the inbox icon.
|
||||
|
||||
**Content**:
|
||||
- Title: "Meet your new agent inbox"
|
||||
- Description: "Your inbox is your central place to manage agent notifications and access produced artifacts like plans and PRs."
|
||||
- Progress indicator: 3 dots, dot 2 active.
|
||||
- "Next" button (primary, right-aligned in footer).
|
||||
|
||||
**Behavior**:
|
||||
- Clicking "Next" advances to Step 4.
|
||||
|
||||
---
|
||||
|
||||
### Step 4: Default Tab Config
|
||||
|
||||
**Presentation**: A popover/panel (480px wide) anchored to the vertical tabs panel in vertical-tabs mode, or to the new-tab button in horizontal-tabs mode.
|
||||
|
||||
**Content**:
|
||||
- Title: "Create your default tab config"
|
||||
- Description: "A tab config defines what opens when you create a new tab. Select a repo, choose a session type (terminal, Warp agent, or third-party agents like Claude or Codex), and optionally attach a worktree. This setup is used for every new tab."
|
||||
- **Session type** selector: pill/chip buttons matching the existing session config modal (reuse the same rendering code and logic, including dynamic filtering of session types based on whether Oz/AI is enabled).
|
||||
- **Select directory** button: opens the native file picker. Displays the selected path in user-friendly form (e.g. `~/warp-internal`). Defaults to the user's home directory.
|
||||
- **Enable worktree support** checkbox with description: "Work on multiple branches at once. Worktrees give each tab its own copy of the repo, so you don't need to switch branches or stash changes." Disabled when the selected directory is not a git repo, with a tooltip explaining why.
|
||||
- Progress indicator: 3 dots, dot 3 active.
|
||||
- "Finish" button (primary, right-aligned in footer).
|
||||
|
||||
**Behavior**:
|
||||
- Session type, directory, and worktree selections follow the same logic as the existing `SessionConfigModal`.
|
||||
- Clicking "Finish" saves the tab config as the user's default and closes the flow. The flow is marked complete.
|
||||
- Clicking "Finish" is the only way to leave this step. The tab config is saved and the flow is marked complete.
|
||||
|
||||
---
|
||||
|
||||
### Shared rendering
|
||||
|
||||
The session type picker, directory selector, and worktree checkbox in Step 4 should be extracted from the existing `SessionConfigModal` into shared rendering functions so the same code is used in both the onboarding flow and the standalone modal.
|
||||
|
||||
### Feature flag
|
||||
|
||||
- Flag name: `HOAOnboardingFlow`
|
||||
- Added to `DOGFOOD_FLAGS` initially.
|
||||
- Gates the entire flow: when disabled, existing users see nothing.
|
||||
|
||||
### Persistence
|
||||
|
||||
- A `private_user_preferences` key (e.g. `HasCompletedHOAOnboarding`) tracks whether the flow has been shown.
|
||||
- The key is set to `true` when:
|
||||
- The user clicks "Finish" on Step 4.
|
||||
- The user clicks X on the welcome banner.
|
||||
- The key is also set to `true` at the end of new-user onboarding, so new users never see this flow.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. When `HOAOnboardingFlow` is enabled and the user has not seen the flow, the welcome banner appears on app launch.
|
||||
2. The welcome banner displays all 4 feature descriptions with correct icons and text matching the Figma.
|
||||
3. Clicking "See what's new" transitions to the vertical tabs callout (Step 2) with vertical tabs visible.
|
||||
4. The "Switch back to horizontal tabs" checkbox live-toggles the tab layout setting. The UI immediately reflects the change (sidebar ↔ top tabs). The popover re-anchors its pointer.
|
||||
5. Clicking "Next" on Step 2 transitions to the agent inbox callout (Step 3), anchored to the inbox icon.
|
||||
6. Clicking "Next" on Step 3 transitions to the tab config step (Step 4).
|
||||
7. The session type picker in Step 4 displays the same options as the existing `SessionConfigModal` (filtered by AI availability).
|
||||
8. The directory picker opens a native file dialog and the worktree checkbox disables for non-git directories, matching existing behavior.
|
||||
9. Clicking "Finish" saves the default tab config and closes the flow.
|
||||
10. After completing or dismissing the flow, it never appears again for that user.
|
||||
11. Users who complete the new-user onboarding never see this flow.
|
||||
12. The flow is forward-only: no back button, no clickable progress dots.
|
||||
13. Progress dots accurately reflect the current step (1/3, 2/3, 3/3) across Steps 2–4.
|
||||
|
||||
## Validation
|
||||
|
||||
- **Unit tests**: Verify the persistence logic (flag set on completion, flag set on dismiss, flag prevents re-show, flag set after new-user onboarding).
|
||||
- **Manual / computer-use verification**:
|
||||
- Walk through all 4 steps and confirm layout, text, and icons match the Figma.
|
||||
- Verify the vertical tabs checkbox live-toggles the layout.
|
||||
- Verify the tab config step reuses session config modal behavior (session types, directory picker, worktree).
|
||||
- Verify dismissing via X at any point marks the flow complete.
|
||||
- Verify a fresh user who completes new-user onboarding does not see this flow.
|
||||
- **Integration tests**: If feasible, test the full step progression and that the flow doesn't appear after completion.
|
||||
|
||||
## Resolved Design Decisions
|
||||
|
||||
1. **Hero art**: Static raster image asset for v1.
|
||||
2. **Popover anchoring**: The existing FTU callout pattern (`app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs:1758-1840`) uses stacked `CalloutTriangleBorderDown` / `CalloutTriangleFillDown` icons for the arrow and `OffsetPositioning::offset_from_save_position_element` for anchoring to named UI elements. Extract this into a shared callout helper and reuse it for Steps 2–3.
|
||||
3. **Dismiss controls**: Only Step 1 has an X/close button. Steps 2–3 use "Next" and Step 4 uses "Finish".
|
||||
@@ -0,0 +1,238 @@
|
||||
# HOA Onboarding Flow — Tech Spec
|
||||
|
||||
Linear: APP-3809
|
||||
Product spec: `specs/harryalbert/APP-3809/PRODUCT.md`
|
||||
|
||||
## Problem
|
||||
|
||||
We need a 4-step guided onboarding flow for existing users that introduces HOA features (vertical tabs, agent inbox, tab configs). The flow must be shown exactly once, gated behind a feature flag, and must reuse existing rendering code from `SessionConfigModal` and the FTU callout pattern.
|
||||
|
||||
## Relevant Code
|
||||
|
||||
### Triggering & persistence
|
||||
- `app/src/workspace/one_time_modal_model.rs` — `OneTimeModalModel`: existing pattern for one-time modals (Oz launch, build plan migration). Subscribes to auth events, waits for cloud preferences sync, then triggers.
|
||||
- `app/src/root_view.rs:1614-1631` — `HAS_COMPLETED_ONBOARDING_KEY` / `private_user_preferences`: the other persistence approach (local-only, no cloud sync needed).
|
||||
- `app/src/root_view.rs:2143-2155` — post-onboarding flow: opens vertical tabs panel + shows `SessionConfigModal` for new users.
|
||||
|
||||
### Session config modal (for extraction)
|
||||
- `app/src/tab_configs/session_config_modal.rs` — `SessionConfigModal`: the full modal with session type pills, directory picker, worktree checkbox. All rendering is in private methods (`render_session_type_section`, `render_directory_section`, `render_checkboxes`).
|
||||
- `app/src/tab_configs/session_config.rs` — `SessionConfigSelection`, `SessionType`, `is_git_repo`, `build_tab_config`, `write_tab_config`.
|
||||
|
||||
### FTU callout (for extraction)
|
||||
- `app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs:1758-1840` — `render_ftu_callout`: renders a bubble with a triangle arrow using stacked `CalloutTriangleBorderDown` / `CalloutTriangleFillDown` icons. Positions via `OffsetPositioning::offset_from_save_position_element`.
|
||||
|
||||
### Tab layout setting
|
||||
- `app/src/workspace/tab_settings.rs:245` — `use_vertical_tabs: bool` setting.
|
||||
- `app/src/workspace/view.rs:1607-1614` — `open_vertical_tabs_panel_if_enabled`: opens the vertical tabs panel based on the setting.
|
||||
|
||||
### Anchoring targets
|
||||
- `app/src/workspace/view.rs:535` — `NOTIFICATIONS_MAILBOX_POSITION_ID = "workspace:notifications_mailbox"`: the inbox icon already uses `SavePosition` for anchoring (line 15262).
|
||||
- `app/src/workspace/view.rs:515` — `TAB_BAR_POSITION_ID`: the tab bar already has a `SavePosition`.
|
||||
|
||||
### Feature flags
|
||||
- `crates/warp_features/src/lib.rs:9` — `FeatureFlag` enum.
|
||||
- `crates/warp_features/src/lib.rs:797` — `DOGFOOD_FLAGS` array.
|
||||
|
||||
### Workspace integration
|
||||
- `app/src/workspace/view.rs:779-901` — `Workspace` struct: holds all modal view handles, panel state.
|
||||
- `app/src/workspace/view.rs:1463-1494` — `build_session_config_modal`: how modals are constructed and subscribed.
|
||||
- `app/src/workspace/view.rs:1617-1638` — `show_session_config_modal` / `close_session_config_modal`.
|
||||
|
||||
## Current State
|
||||
|
||||
- New users go through `AgentOnboardingView` → then post-onboarding opens vertical tabs + `SessionConfigModal` (`root_view.rs:2143-2155`).
|
||||
- Existing users get no introduction to HOA features.
|
||||
- The `SessionConfigModal` rendering methods are private and tightly coupled to the modal's `View` impl — they can't be reused without extraction.
|
||||
- The FTU callout rendering is a standalone `fn render_ftu_callout` but hardcodes text, colors, and arrow direction. The general pattern (bubble + positioned triangle) is reusable.
|
||||
- `OneTimeModalModel` handles one-time modal triggering for existing users (auth → cloud sync → check flag → show). It uses `AISettings` to persist "shown" state via cloud-synced settings.
|
||||
|
||||
## Proposed Changes
|
||||
|
||||
### 1. Feature flag
|
||||
|
||||
Add `HOAOnboardingFlow` to the `FeatureFlag` enum and `DOGFOOD_FLAGS`. Read the create feature flag skill for information on how to do this in a complete way.
|
||||
|
||||
File: `crates/warp_features/src/lib.rs`
|
||||
|
||||
### 2. Shared callout bubble component
|
||||
|
||||
Extract from the FTU callout into a general-purpose helper in a new file.
|
||||
|
||||
File: `app/src/view_components/callout_bubble.rs`
|
||||
|
||||
```rust
|
||||
pub enum CalloutArrowDirection {
|
||||
Up,
|
||||
Left,
|
||||
}
|
||||
|
||||
pub enum CalloutArrowPosition {
|
||||
Start(f32),
|
||||
Center,
|
||||
End(f32),
|
||||
}
|
||||
|
||||
pub struct CalloutBubbleConfig {
|
||||
pub width: f32,
|
||||
pub arrow_direction: CalloutArrowDirection,
|
||||
pub arrow_position: CalloutArrowPosition,
|
||||
}
|
||||
```
|
||||
|
||||
A `render_callout_bubble(content, config, appearance) -> Box<dyn Element>` function that:
|
||||
- Wraps `content` in a bordered, rounded container with accent-tinted background (matching FTU style).
|
||||
- Appends/prepends a triangle arrow (using the existing `CalloutTriangleBorderDown` / `CalloutTriangleFillDown` icon stacking technique) positioned per the config.
|
||||
|
||||
This is reused by the HOA flow's Steps 2–4.
|
||||
|
||||
### 3. Shared session config rendering
|
||||
|
||||
Extract the rendering portions of `SessionConfigModal` into free functions that both the modal and the onboarding step can call.
|
||||
|
||||
File: `app/src/tab_configs/session_config_rendering.rs`
|
||||
|
||||
Extract these from `SessionConfigModal`:
|
||||
- `render_session_type_pills(session_types, selected_index, pill_mouse_states, appearance) -> Box<dyn Element>`
|
||||
- `render_directory_picker(selected_directory, mouse_state, appearance) -> Box<dyn Element>`
|
||||
- `render_worktree_checkbox(enabled, is_git_repo, checkbox_mouse_state, tooltip_mouse_state, appearance) -> Box<dyn Element>`
|
||||
|
||||
`SessionConfigModal` calls these extracted functions in its `render` method instead of its current private methods. The onboarding Step 4 view calls the same functions.
|
||||
|
||||
The action dispatch, state management, and file picker logic remain in each caller (`SessionConfigModal` and the onboarding view) — only the rendering is shared.
|
||||
|
||||
### 4. HOA onboarding view
|
||||
|
||||
New module: `app/src/workspace/hoa_onboarding/`
|
||||
- `mod.rs` — re-exports.
|
||||
- `hoa_onboarding_flow.rs` — the main `HoaOnboardingFlow` view.
|
||||
- `welcome_banner.rs` — Step 1 rendering.
|
||||
- `tab_config_step.rs` — Step 4 rendering (uses shared session config rendering).
|
||||
|
||||
#### `HoaOnboardingFlow` view
|
||||
|
||||
```rust
|
||||
enum HoaOnboardingStep {
|
||||
WelcomeBanner,
|
||||
VerticalTabsCallout,
|
||||
AgentInboxCallout,
|
||||
TabConfig,
|
||||
}
|
||||
|
||||
struct HoaOnboardingFlow {
|
||||
step: HoaOnboardingStep,
|
||||
// Step 1 state
|
||||
close_button: ViewHandle<ActionButton>,
|
||||
// Step 2 state
|
||||
switch_to_horizontal_checkbox_mouse_state: MouseStateHandle,
|
||||
// Step 4 state (mirrors SessionConfigModal fields)
|
||||
session_types: Vec<SessionType>,
|
||||
selected_session_type_index: usize,
|
||||
selected_directory: PathBuf,
|
||||
is_git_repo: bool,
|
||||
enable_worktree: bool,
|
||||
session_pill_mouse_states: Vec<MouseStateHandle>,
|
||||
directory_button_mouse_state: MouseStateHandle,
|
||||
worktree_checkbox_mouse_state: MouseStateHandle,
|
||||
worktree_tooltip_mouse_state: MouseStateHandle,
|
||||
}
|
||||
```
|
||||
|
||||
**Events**:
|
||||
```rust
|
||||
enum HoaOnboardingFlowEvent {
|
||||
Completed(Option<SessionConfigSelection>),
|
||||
Dismissed,
|
||||
}
|
||||
```
|
||||
|
||||
- `Completed(Some(selection))` — user clicked Finish with a valid tab config.
|
||||
- `Completed(None)` — user completed the flow but didn't reach the tab config (shouldn't happen in normal flow, but covers edge cases).
|
||||
- `Dismissed` — user clicked X.
|
||||
|
||||
**Rendering** dispatches to different renderers per step:
|
||||
- Steps 1: a centered modal with scrim (similar to how `SessionConfigModal` is wrapped in a `Modal`).
|
||||
- Steps 2–3: the shared `render_callout_bubble` positioned via `OffsetPositioning::offset_from_save_position_element`, anchored to the vertical tabs panel or `NOTIFICATIONS_MAILBOX_POSITION_ID`.
|
||||
- Step 4: the shared `render_callout_bubble` with the tab config form body, anchored to the vertical tabs panel in vertical tabs mode or the tab bar in horizontal tabs mode.
|
||||
|
||||
### 5. Persistence
|
||||
|
||||
Add a new `private_user_preferences` key: `HasCompletedHOAOnboarding`.
|
||||
|
||||
Use the same pattern as `HAS_COMPLETED_ONBOARDING_KEY` in `root_view.rs:1614-1631` — a simple boolean read/write via `ctx.private_user_preferences()`. This should be cloud synced.
|
||||
|
||||
Helper functions (placed near the onboarding flow or in a shared utils module):
|
||||
```rust
|
||||
const HAS_COMPLETED_HOA_ONBOARDING_KEY: &str = "HasCompletedHOAOnboarding";
|
||||
|
||||
fn has_completed_hoa_onboarding(ctx: &AppContext) -> bool { ... }
|
||||
fn mark_hoa_onboarding_completed(ctx: &AppContext) { ... }
|
||||
```
|
||||
|
||||
### 6. Triggering
|
||||
|
||||
Integrate into `OneTimeModalModel`:
|
||||
- Add `is_hoa_onboarding_open: bool` field.
|
||||
- Add a `check_and_trigger_hoa_onboarding` method that:
|
||||
1. Checks `FeatureFlag::HOAOnboardingFlow.is_enabled()`.
|
||||
2. Checks `!has_completed_hoa_onboarding(ctx)`.
|
||||
3. Checks `has_completed_local_onboarding(ctx)` — ensures this is an existing user (not someone mid-new-user-onboarding).
|
||||
4. Sets `is_hoa_onboarding_open = true` and emits the event.
|
||||
- Call this from `check_and_trigger_all_modals` alongside the existing Oz launch and build plan migration checks.
|
||||
|
||||
In `Workspace`, subscribe to `OneTimeModalEvent` and when the HOA onboarding should show:
|
||||
- Ensure vertical tabs are enabled (set the `use_vertical_tabs` setting to `true` if not already).
|
||||
- Open the vertical tabs panel.
|
||||
- Show the `HoaOnboardingFlow` view as an overlay.
|
||||
|
||||
### 7. New-user onboarding integration
|
||||
|
||||
In `root_view.rs`, after new-user onboarding completes (`AgentOnboardingEvent::OnboardingCompleted`), call `mark_hoa_onboarding_completed(ctx)` to ensure the HOA flow never shows for new users (only if the hoa flow feature flag is enabled).
|
||||
|
||||
### 8. Workspace rendering integration
|
||||
|
||||
Add `hoa_onboarding_flow: Option<ViewHandle<HoaOnboardingFlow>>` to `Workspace`.
|
||||
|
||||
In the workspace's `render` method:
|
||||
- When `hoa_onboarding_flow` is `Some` and the step is `WelcomeBanner`, render a full-window scrim overlay with the banner centered.
|
||||
- When the step is `VerticalTabsCallout` or `AgentInboxCallout`, render the callout bubble as a positioned overlay (using `Stack::add_positioned_overlay_child`) anchored to the appropriate `SavePosition` element.
|
||||
- When the step is `TabConfig`, render the tab config popover as a positioned overlay anchored to the content area.
|
||||
|
||||
Handle `HoaOnboardingFlowEvent`:
|
||||
- On `Dismissed`: call `mark_hoa_onboarding_completed`, drop the flow view.
|
||||
- On `Completed(Some(selection))`: call `mark_hoa_onboarding_completed`, process the tab config selection (reuse `handle_session_config_completed` logic), drop the flow view.
|
||||
- On `Completed(None)`: call `mark_hoa_onboarding_completed`, drop the flow view.
|
||||
|
||||
## End-to-End Flow
|
||||
|
||||
1. Existing user launches Warp with `HOAOnboardingFlow` enabled.
|
||||
2. `OneTimeModalModel` receives auth + cloud sync completion → calls `check_and_trigger_hoa_onboarding`.
|
||||
3. Checks pass (flag enabled, not completed, is existing user) → emits `OneTimeModalEvent`.
|
||||
4. `Workspace` receives event → enables vertical tabs setting → opens vertical tabs panel → creates `HoaOnboardingFlow` in `WelcomeBanner` step → renders scrim + banner.
|
||||
5. User clicks "See what's new" → flow advances to `VerticalTabsCallout` → callout bubble rendered anchored to vertical tabs panel.
|
||||
6. User optionally toggles "Switch back to horizontal tabs" → `use_vertical_tabs` setting toggled, UI updates live, callout re-anchors.
|
||||
7. User clicks "Next" → flow advances to `AgentInboxCallout` → callout bubble rendered anchored to `NOTIFICATIONS_MAILBOX_POSITION_ID`.
|
||||
8. User clicks "Next" → flow advances to `TabConfig` → popover with session config fields rendered.
|
||||
9. User configures and clicks "Finish" → `HoaOnboardingFlowEvent::Completed(Some(selection))` emitted → tab config saved, flow closed, preferences key set.
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
1. **Rendering extraction breaking `SessionConfigModal`**: The extraction of rendering functions is a refactor of existing code. Risk: subtle visual regressions. Mitigation: compare screenshots before/after extraction to verify pixel-identical output.
|
||||
|
||||
2. **Callout positioning edge cases**: If the vertical tabs panel or inbox icon aren't rendered yet when the callout tries to anchor, `offset_from_save_position_element` may position incorrectly. Mitigation: the flow ensures vertical tabs are opened before Step 2, and the inbox icon is always in the title bar when `HOANotifications` is enabled.
|
||||
|
||||
3. **Interaction with other one-time modals**: `OneTimeModalModel` runs checks sequentially — Oz launch modal takes priority. If the Oz launch modal shows, the HOA flow won't trigger until the next app launch. This is acceptable; the flow persists across launches until shown.
|
||||
|
||||
4. **Feature flag dependency**: The flow assumes `VerticalTabs`, `HOANotifications`, and `TabConfigs` flags are also enabled. If any are disabled, certain steps may reference UI that doesn't exist. Mitigation: gate the HOA flow on all required flags in `check_and_trigger_hoa_onboarding`.
|
||||
|
||||
## Testing and Validation
|
||||
|
||||
- **Unit tests**: persistence helpers (`has_completed_hoa_onboarding`, `mark_hoa_onboarding_completed`), step transitions in `HoaOnboardingFlow`, new-user exclusion logic.
|
||||
- **Visual verification**: local walkthrough of all 4 steps after building.
|
||||
- **Extraction regression**: verify `SessionConfigModal` still renders identically after extracting shared rendering functions.
|
||||
- **Edge cases**: dismiss at Step 1, dismiss at Step 4, toggle horizontal tabs back and forth, select non-git directory for worktree.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Remove `HOAOnboardingFlow` feature flag once stable (promote through preview → release).
|
||||
- Refactor the existing FTU callout in `agent_input_footer` to use the shared `callout_bubble` component.
|
||||
- Hero art asset: needs a static image to be produced and bundled.
|
||||
Reference in New Issue
Block a user