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
+94
View File
@@ -0,0 +1,94 @@
# /queue Slash Command & Auto-Queue Toggle
Linear: [APP-4041](https://linear.app/warpdotdev/issue/APP-4041/add-queue-command)
Figma: none provided
## Summary
Two complementary features for queuing follow-up prompts while the agent is responding:
1. `/queue <prompt>` — a slash command that queues a specific prompt.
2. **Auto-queue toggle** — a status bar button (and keyboard shortcut) that causes the next regular input submission to be queued instead of sent immediately.
When the agent finishes, the queued prompt is automatically sent to the same conversation.
## Problem
When the agent is mid-response the user often already knows what they want to ask next, but they have to wait for the agent to finish before they can type and send it. This breaks flow and wastes time.
## Goals
- Let users queue exactly one follow-up prompt while the agent is busy.
- Provide visual feedback that a prompt is queued and will be sent automatically.
- Let users cancel the queued prompt before it fires.
- Automatically send the queued prompt when the agent finishes successfully; gracefully handle failures.
## Non-goals
- Queuing multiple prompts in sequence (only one at a time).
- Providing a persistent prompt queue that survives app restart.
## User Experience
### Invoking `/queue`
1. The command is `/queue <prompt>` and appears in the slash command menu when the `QueueSlashCommand` feature flag is enabled (dogfood).
2. The prompt argument is required; `/queue` with no argument shows an error toast.
3. The command is only available when the user is in an agent view with an active conversation.
4. If the agent is currently responding (in-progress or blocked), the prompt is queued and the input buffer is cleared.
5. If the agent is idle (conversation finished), the prompt is sent immediately — same as typing it and pressing enter.
### Auto-queue toggle
6. A toggle button appears in the warping indicator (status bar) when the agent is responding, gated behind `QueueSlashCommand`.
7. The button uses a `ClockPlus` icon; when active the icon is accent-colored, otherwise disabled-colored.
8. Keyboard shortcut: `Cmd+Shift+J` (Mac) / `Ctrl+Shift+J` (Linux/Windows).
9. When the toggle is on and the user submits any input (regular prompt, slash command, or skill command) while the conversation is in progress, the input is queued instead of sent immediately.
10. The toggle persists across exchanges in the same conversation (same semantics as fast-forward / auto-approve).
### Pending query indicator
11. A "pending user query" block appears at the bottom of the blocklist showing:
- The user's avatar and display name.
- The queued prompt text (dimmed, bold).
- A "Queued" badge (italic, smaller font).
- A dismiss button (X icon) in the top-right corner with a "Remove queued prompt" label.
- A "Send now" button (Play icon) when the queued prompt is interruptible (i.e. from `/queue` or auto-queue, but not from summarization-triggered queuing like `/compact-and`).
12. The pending block is gated behind the `PendingUserQueryIndicator` feature flag (dogfood).
### Dismissal
13. Clicking the dismiss button (X) removes the pending query block and cancels the queued prompt — it will not be sent.
14. Clicking the "Send now" button removes the pending query block and immediately submits the queued prompt, interrupting the in-progress conversation.
15. Exiting the agent view while a prompt is queued also cancels it.
### Auto-send behavior
16. When the agent finishes successfully (`FinishReason::Complete`), the queued prompt is re-submitted through the normal input flow (so slash commands, skill commands, and session sharing are all handled correctly).
17. When the agent finishes with an error, cancellation, or cancelled-during-command-execution, the queued prompt is placed back into the input buffer (so the user doesn't lose it) instead of being sent.
### Interaction with other commands
18. Both `/queue` and the auto-queue toggle reuse the same `send_user_query_after_next_conversation_finished` mechanism as `/compact-and` and `/fork-and-compact`, meaning only one queued prompt can exist at a time (the latest one wins).
## Success Criteria
- `/queue fix the tests` queues the prompt, shows the pending indicator, and auto-sends "fix the tests" once the agent finishes.
- `/queue` with no argument shows an error toast and does not clear the input.
- `/queue` when the agent is idle sends the prompt immediately.
- `/queue` when there is no active conversation shows an error toast.
- Clicking the dismiss X removes the pending block and prevents the prompt from sending.
- If the agent errors or is cancelled, the prompt text is restored to the input buffer.
- The `active_ai_block` and `last_ai_block` helpers correctly skip over the pending query block (same as they skip usage footers).
- Auto-queue toggle: toggling on and submitting during an in-progress conversation queues the prompt.
- Auto-queue toggle: toggle state persists across exchanges until the user explicitly toggles it off.
## Validation
- Manual: invoke `/queue` during an in-progress conversation, verify indicator appears and prompt auto-sends on completion.
- Manual: invoke `/queue` then dismiss, verify prompt does not send.
- Manual: invoke `/queue` then cancel the agent, verify prompt is placed in input buffer.
- Manual: invoke `/queue` when agent is idle, verify prompt is sent immediately.
- Manual: invoke `/queue` with no argument, verify error toast.
- Manual: toggle auto-queue on, type a prompt and press enter during in-progress conversation, verify it queues.
- Manual: verify auto-queue toggle persists after a queued prompt is sent.
- Code review: verify `active_ai_block` and `last_ai_block` skip `is_pending_user_query()` entries.
+115
View File
@@ -0,0 +1,115 @@
# /queue Slash Command & Auto-Queue Toggle — Technical Spec
## Problem
Users need a way to queue a follow-up prompt while the agent is mid-response. This requires a new slash command, an auto-queue toggle in the status bar, validation logic, a workspace action to route the prompt, and updates to the pending user query block to support dismissal.
## Relevant Code
- `app/src/search/slash_command_menu/static_commands/commands.rs (288-297)` — `QUEUE` static command definition
- `app/src/terminal/input/slash_commands/mod.rs (739-768)` — `/queue` execution handler
- `app/src/terminal/input.rs` — `submit_queued_prompt` (re-submits queued prompts through slash/skill/plain-text routing) and `maybe_queue_input_for_in_progress_conversation` (auto-queue toggle bottleneck)
- `app/src/workspace/action.rs (453-456)` — `QueuePromptForConversation` workspace action variant
- `app/src/workspace/view.rs (19634-19658)` — workspace-level handler that routes to `TerminalView`
- `app/src/terminal/view/pending_user_query.rs` — pending query block insertion, removal, and auto-send logic
- `app/src/ai/blocklist/block/pending_user_query_block.rs` — pending block view with dismiss button
- `app/src/ai/blocklist/block/status_bar.rs` — auto-queue toggle button in the warping indicator
- `app/src/ai/blocklist/context_model.rs` — `queue_next_prompt_enabled` state
- `app/src/terminal/view.rs:18101` — `active_ai_block` helper (skips pending query blocks)
- `app/src/terminal/view.rs:20044` — `last_ai_block` helper (skips pending query blocks)
- `app/src/terminal/view/init.rs` — `TOGGLE_QUEUE_NEXT_PROMPT_KEYBINDING` (`Cmd+Shift+J`)
## Current State
The codebase already has a `PendingUserQueryBlock` and `send_user_query_after_next_conversation_finished` mechanism used by `/compact-and` and `/fork-and-compact`. These commands queue a prompt that fires after summarization completes. The `/queue` command reuses this infrastructure for a simpler case: queue a prompt during any in-progress conversation (no summarization involved).
Prior to this change, `PendingUserQueryBlock` had no dismiss functionality, and `active_ai_block`/`last_ai_block` did not account for pending query blocks at the tail of the rich content list.
## Proposed Changes
### 1. Slash command registration
New `QUEUE` static command in `commands.rs` with:
- Required argument (the prompt text).
- Availability: `AGENT_VIEW | ACTIVE_CONVERSATION | NO_LRC_CONTROL`.
- `requires_ai_mode: true`.
- Gated behind `FeatureFlag::QueueSlashCommand` (dogfood). The command only appears in the slash command menu when the flag is enabled.
### 2. Command execution (`slash_commands/mod.rs`)
The handler validates two preconditions:
1. Active conversation exists (else error toast).
2. Prompt argument is non-empty (else error toast).
Then checks conversation status:
- If `is_in_progress()` or `is_blocked()`: dispatches `WorkspaceAction::QueuePromptForConversation { prompt }`.
- If idle (conversation finished): sends the prompt immediately via `submit_queued_prompt`, which routes through slash command / skill / plain-text detection.
### 3. Workspace action routing (`action.rs`, `view.rs`)
New `QueuePromptForConversation { prompt }` variant on `WorkspaceAction`. The workspace handler resolves the active terminal view and calls `terminal.send_user_query_after_next_conversation_finished(prompt, interruptible: true, ctx)`. The `interruptible` parameter controls whether the pending block shows a "Send now" button; `/queue` and auto-queue set this to `true`, while summarization-triggered queuing (`/compact-and`, `/fork-and-compact`) sets it to `false`.
### 4. Dismiss and Send-now support on `PendingUserQueryBlock`
- Block now owns a `ViewHandle<ActionButton>` close button (X icon, `ButtonSize::XSmall`, `NakedTheme`) and an optional `ViewHandle<ActionButton>` send-now button (Play icon), created only when the block is constructed with `interruptible: true`.
- New `PendingUserQueryBlockAction::{Dismiss, SendNow}` and `PendingUserQueryBlockEvent::{Dismissed, SendNow}`.
- `PendingUserQueryBlock` implements `TypedActionView` to translate actions → events.
- The button column ("Remove queued prompt" + optional "Send now") is positioned top-right via `Stack` + `OffsetPositioning`.
- The caller in `pending_user_query.rs` subscribes to `Dismissed` (→ `remove_pending_user_query_block`) and `SendNow` (→ `send_queued_prompt_now`, which removes the block and immediately submits the queued prompt through the input) events.
### 5. Skip pending blocks in `active_ai_block` / `last_ai_block`
Both methods use `Iterator::rfind` to skip all trailing non-AI items (usage footers and pending query blocks) rather than checking only the last entry.
### 6. Auto-queue toggle (`context_model.rs`, `status_bar.rs`, `input.rs`)
- `queue_next_prompt_enabled: bool` on `BlocklistAIContextModel` tracks the toggle state.
- `toggle_queue_next_prompt()` flips the flag and emits `QueueNextPromptToggled`.
- The status bar renders a `ClockPlus` icon button gated behind `FeatureFlag::QueueSlashCommand`. The icon is accent-colored when active.
- Keybinding `Cmd+Shift+J` maps to `TerminalAction::ToggleQueueNextPrompt`.
- `maybe_queue_input_for_in_progress_conversation` in `input.rs` is the bottleneck: when the toggle is on and the active conversation is in progress, it captures the input buffer, clears it, and dispatches `QueuePromptForConversation`.
- The toggle persists across exchanges (same semantics as fast-forward).
## End-to-End Flow
```mermaid
sequenceDiagram
participant User
participant Input as TerminalInput
participant WS as WorkspaceView
participant TV as TerminalView
participant PUQ as PendingUserQueryBlock
User->>Input: /queue fix the tests
Input->>Input: Validate conversation, prompt, status
Input->>WS: dispatch QueuePromptForConversation
WS->>TV: send_user_query_after_next_conversation_finished
TV->>PUQ: insert_pending_user_query_block
Note over PUQ: Shows queued prompt with dismiss button
alt Agent completes successfully
TV->>TV: on_next_conversation_finished(Complete)
TV->>Input: submit_queued_prompt("fix the tests")
Note over Input: Routes through slash/skill/plain-text detection
TV->>PUQ: remove block
else Agent errors/cancelled
TV->>TV: on_next_conversation_finished(Error|Cancelled)
TV->>TV: restore prompt to input buffer
TV->>PUQ: remove block
else User dismisses
User->>PUQ: click X
PUQ->>TV: PendingUserQueryBlockEvent::Dismissed
TV->>TV: remove_pending_user_query_block (cancels callback)
end
```
## Risks and Mitigations
- **Only one queued prompt at a time**: calling `/queue` again while one is pending replaces the previous one (via `remove_pending_user_query_block` in `insert_pending_user_query_block`). This is acceptable for v1.
- **Pending indicator behind feature flag**: the `PendingUserQueryIndicator` flag gates the visual block (dogfood). Without the flag, the prompt is still queued and auto-sent — just without visual feedback. This is the same behavior as `/compact-and`.
- **Queue command behind feature flag**: the `QueueSlashCommand` flag gates the `/queue` command registration (dogfood). The command handler, workspace action, and pending block infrastructure are always compiled in but only reachable when the flag is enabled.
## Testing and Validation
- Manual testing of the five error/success paths described in the product spec.
- Code review of the `active_ai_block` / `last_ai_block` skip logic to ensure pending blocks don't break conversation state detection.