Files
galaxy/specs/harryalbert/APP-3858/TECH.md
T

147 lines
8.2 KiB
Markdown

# APP-3858: Tech Spec — Remote Control Entrypoint
## Problem
The CLI agent footer's "Share session" button opens the share modal, which is an unnecessary step for the primary use case (quick mobile handoff). We need to make it a one-click action that starts sharing without scrollback, auto-copies the link, and shows a stop button while active.
## Relevant Code
- `crates/warp_core/src/ui/icons.rs (10-296)``Icon` enum; needs `Phone01` variant
- `app/assets/bundled/svg/phone-01.svg` — phone icon for start-state (on branch)
- `Icon::StopFilled` — existing icon reused for stop-state
- `app/src/search/slash_command_menu/static_commands/commands.rs` — slash command definitions
- `app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs (491-500)``share_session_button` creation
- `app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs (1104-1108)` — CLI toolbar `ShareSession` render
- `app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs (1636-1644)` — agent view toolbar `ShareSession` render
- `app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs (1893, 2025-2027)``AgentInputFooterAction::ShareSession` handler
- `app/src/ai/blocklist/agent_view/agent_input_footer/mod.rs (2037-2045)``AgentInputFooterEvent` enum
- `app/src/ai/blocklist/agent_view/agent_input_footer/toolbar_item.rs (48, 74, 88)``AgentToolbarItemKind::ShareSession` display label and icon
- `app/src/terminal/view/use_agent_footer/mod.rs (217-218, 851-852)` — event forwarding
- `app/src/terminal/view/use_agent_footer/mod.rs (1019-1041)``UseAgentToolbarEvent` enum
- `app/src/terminal/view/shared_session/view_impl.rs (415-472)``attempt_to_share_session` (scrollback guard at 436-448)
- `app/src/terminal/view/shared_session/view_impl.rs (476-520)``on_session_share_started` (auto-opens sharing dialog at 515)
- `app/src/terminal/view/shared_session/view_impl.rs (522-529)``stop_sharing_session`
- `app/src/terminal/view/shared_session/view_impl.rs (1288-1311)``copy_shared_session_link`
- `app/src/terminal/shared_session/mod.rs (39)``COPY_LINK_TEXT` constant
- `app/src/terminal/shared_session/mod.rs (267-290)``SharedSessionActionSource` enum
## Current State
**Button**: A single static `share_session_button` with `Icon::Share`, tooltip "Share session". Click dispatches `AgentInputFooterAction::ShareSession` → emits `AgentInputFooterEvent::OpenShareSessionModal`.
**Event flow**: `OpenShareSessionModal` bubbles through `UseAgentToolbarEvent::OpenShareSessionModal``TerminalView::open_share_session_modal` → opens the sharing dialog.
**Post-share**: `on_session_share_started` unconditionally auto-opens the sharing dialog so the user can copy the link.
**No stop affordance**: The button never changes. Stopping requires the pane header overflow menu.
## Proposed Changes
### 1. Add icon variant
In `crates/warp_core/src/ui/icons.rs`, add one variant:
- `Phone01``"bundled/svg/phone-01.svg"`
The stop state reuses the existing `Icon::StopFilled`.
### 2. Two buttons instead of one
Replace the single `share_session_button` field in `AgentInputFooter` with two fields:
**`start_remote_control_button`**: `Phone01` icon, label "/remote-control". On click dispatches `AgentInputFooterAction::StartRemoteControl`.
**`stop_remote_control_button`**: `StopFilled` icon, label "Stop sharing". On click dispatches `AgentInputFooterAction::StopRemoteControl`.
### 3. Split action and event enums
**`AgentInputFooterAction`** (mod.rs:1893): Replace `ShareSession` with:
- `StartRemoteControl`
- `StopRemoteControl`
**`AgentInputFooterEvent`** (mod.rs:2037): Replace `OpenShareSessionModal` with:
- `StartRemoteControl`
- `StopRemoteControl`
**`UseAgentToolbarEvent`** (use_agent_footer/mod.rs:1019): Replace `OpenShareSessionModal` with:
- `StartRemoteControl`
- `StopRemoteControl`
Each action handler is trivial — it just emits the corresponding event up the chain.
### 4. Swap buttons at render time
In `render_cli_toolbar_item` and `render_toolbar_item` for the `ShareSession` variant, instead of always rendering the start button, check `terminal_model.lock().shared_session_status()`:
- Not sharing → render `start_remote_control_button`
- `is_active_sharer()` or `is_share_pending()` → render `stop_remote_control_button`
The footer already re-renders on `CLIAgentSessionsModel` changes. We need to verify shared session status changes also trigger re-renders; if not, subscribe to the relevant model event.
### 5. Handle `StartRemoteControl` in `TerminalView`
In `handle_use_agent_footer_event` (use_agent_footer/mod.rs:217):
- Call `attempt_to_share_session(SharedSessionScrollbackType::None, Some(FooterChip), SessionSourceType::Terminal, ctx)` with a new `bypass_conversation_guard: bool` parameter set to `true`.
**Bypass the scrollback guard**: Add `bypass_conversation_guard: bool` to `attempt_to_share_session` (view_impl.rs:415). When `true`, skip the guard at lines 436-448. All existing callers pass `false`.
### 6. Auto-copy link on share start
Thread `source: Option<SharedSessionActionSource>` through the share-started flow:
- `Event::StartSharingCurrentSession` gains a `source` field
- Terminal manager forwards it to `on_session_share_started`
In `on_session_share_started` (view_impl.rs:476):
- When source is `FooterChip`: skip `toggle_sharing_dialog`, call `copy_shared_session_link`, show toast "Remote control link copied".
- All other sources: keep existing behavior (auto-open sharing dialog).
### 7. Handle `StopRemoteControl` in `TerminalView`
Call `self.stop_sharing_session(SharedSessionActionSource::FooterChip, ctx)`.
### 8. Update toolbar item metadata
In `toolbar_item.rs`:
- Display label: `"Share Session"``"/remote-control"`
- Icon: `Icon::Share``Icon::Phone01`
### 9. Add `/remote-control` slash command
Add a `REMOTE_CONTROL` static command in `commands.rs` with:
- name: `/remote-control`
- description: "Start remote control for this session"
- icon_path: `"bundled/svg/phone-01.svg"`
- availability: CLI agent sessions only
Register it in the command list. Handle it in the slash command dispatch to emit the same `StartRemoteControl` action as the chip.
### 10. Banner copy
When sharing is started from the remote control entrypoint (`SharedSessionActionSource::FooterChip`), the inline banners show:
- "Remote control active" (instead of "Sharing started")
- "Remote control stopped" (instead of "Sharing ended")
This is threaded via an `is_remote_control: bool` field on `SharedSessionBanners::ActiveShare` and `LastShared`.
## End-to-End Flow
```
Start:
click start_remote_control_button
→ AgentInputFooterAction::StartRemoteControl
→ AgentInputFooterEvent::StartRemoteControl
→ UseAgentToolbarEvent::StartRemoteControl
→ attempt_to_share_session(None, FooterChip, bypass=true)
→ terminal manager establishes connection
→ on_session_share_started(source=FooterChip)
→ skips sharing dialog, copies link, shows toast
→ footer re-renders: swaps to stop_remote_control_button
Stop:
click stop_remote_control_button
→ AgentInputFooterAction::StopRemoteControl
→ AgentInputFooterEvent::StopRemoteControl
→ UseAgentToolbarEvent::StopRemoteControl
→ stop_sharing_session(FooterChip)
→ footer re-renders: swaps back to start_remote_control_button
```
## Risks and Mitigations
- **Scrollback guard bypass**: Deliberately allowing no-scrollback shares for remote control. Guard still applies for all other entry points (share modal, context menu, etc.).
- **State sync**: Reading `shared_session_status()` at render time means the button reflects state changes from any entry point. Must verify shared session status changes trigger footer re-renders.
- **Threading source through share-started flow**: `Event::StartSharingCurrentSession` and the terminal manager callback need to carry the source. Keep it optional so existing callers are unaffected.
## Testing and Validation
- Existing shared session tests pass (protocol unchanged).
- Manual: start CLI agent → click "Remote control" → verify link copied + toast → button shows stop state → click stop → session ends + button reverts.
- Verify starting share from pane menu causes footer to show stop button.
## Follow-ups
- "Text link to my device" stretch goal.
- Rename agent view (non-CLI) share button if desired.