Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
# Product Spec: GitHub PR Prompt Chip — Default Inclusion with Validation
|
||||
|
||||
## Summary
|
||||
|
||||
Show the GitHub PR prompt chip by default in both the terminal prompt and the agent view footer. Reuse the chip's existing runtime behavior to validate whether the chip can work for the user. If the chip hits a deterministic `gh` readiness failure, suppress it from future default layouts and surface a warning in vertical tabs when relevant.
|
||||
|
||||
## Problem
|
||||
|
||||
The PR chip's current default inclusion is inconsistent:
|
||||
|
||||
- **Terminal prompt default:** chip is absent, so users with a working `gh` CLI do not discover it unless they manually customize their prompt.
|
||||
- **Agent view footer default:** chip is present, so users without a working `gh` CLI can get a silent no-op.
|
||||
|
||||
The first proposed design added a separate proactive `gh` readiness model, but that duplicates capabilities already present in the chip runtime: required executable detection, local-session gating, command execution, failure suppression, and command-based invalidation.
|
||||
|
||||
## Goals
|
||||
|
||||
- Include the GitHub PR chip by default in both terminal prompt and agent view footer.
|
||||
- Avoid mutating users' saved prompt or footer customizations.
|
||||
- Reuse the PR chip runtime as the validation path rather than adding a redundant proactive readiness model.
|
||||
- Suppress the chip from default layouts after deterministic readiness failures such as missing or unauthenticated `gh`.
|
||||
- Keep the vertical tabs "Show: PR link" setting decoupled from validation, while showing a warning if PR links are enabled but cannot work.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Adding a `gh auth` flow or prompting users to install `gh`.
|
||||
- Detecting whether the current repo is hosted on GitHub beyond what the existing chip script already does.
|
||||
- Changing CLI agent footer defaults.
|
||||
- Changing the persisted `vertical_tabs_show_pr_link` setting default or type.
|
||||
- Suppressing the chip permanently after transient failures such as timeouts, network errors, GitHub outages, or rate limits.
|
||||
- Changing behavior for custom prompt/footer configurations except for the existing runtime chip behavior if the user manually included the chip.
|
||||
|
||||
## Figma
|
||||
|
||||
None provided.
|
||||
|
||||
## User Experience
|
||||
|
||||
### Definitions
|
||||
|
||||
- **Default prompt/footer:** the runtime-resolved chip set used when the user has not customized that surface (`PromptSelection::Default` or `AgentToolbarChipSelection::Default`).
|
||||
- **Custom prompt/footer:** chip set explicitly saved by the user. This feature does not remove chips from custom configurations.
|
||||
- **Validation state:** a hidden app state used to decide whether default layouts should keep showing the PR chip. It begins unvalidated.
|
||||
- **Deterministic readiness failure:** a failure that shows the PR chip cannot work until the user changes local setup, such as `gh` missing from `$PATH` or `gh` installed but unauthenticated.
|
||||
- **Transient failure:** a failure that should not suppress defaults, such as network errors, timeouts, GitHub outages, API/rate-limit errors, or unexpected `gh` failures.
|
||||
|
||||
### Behavior Rules
|
||||
|
||||
1. **Initial default terminal prompt:** The GitHub PR chip is included in the effective default prompt, positioned after `GitDiffStats`.
|
||||
|
||||
2. **Initial default agent view footer:** The GitHub PR chip is included in the effective default agent footer, in the existing agent-footer PR chip position after `GitDiffStats` and before `NLDToggle`.
|
||||
|
||||
3. **Successful validation:** If the PR chip successfully reaches the `gh`-backed path and resolves a PR URL, records "no PR found" as a benign empty result, or otherwise completes in a way that demonstrates `gh` is installed and authenticated, the chip remains in default layouts.
|
||||
|
||||
4. **Benign empty states:** Non-GitHub repo, no Git repo, detached HEAD, no `origin`, non-GitHub remote, and no open PR should not be treated as readiness failures. These states may produce no chip value, but they should not suppress the default.
|
||||
|
||||
5. **Deterministic readiness failure:** If the PR chip fails because `gh` is missing or unauthenticated, the chip is suppressed from future effective default terminal prompt and agent footer layouts.
|
||||
|
||||
6. **Transient failure:** If the PR chip fails for a transient reason, the chip remains in default layouts and may retry according to the existing chip invalidation/runtime behavior.
|
||||
|
||||
7. **Custom prompt or footer:** If a user explicitly added the GitHub PR chip to a custom prompt or footer, keep it there regardless of validation state. Existing runtime disabled/failure behavior still applies.
|
||||
|
||||
8. **Remote / SSH sessions:** The existing PR chip `local_only` runtime policy remains in effect. Remote-session failures should not rewrite custom settings. Whether they should mark the default as suppressed depends on implementation details, but the user-facing result should avoid showing a non-working PR chip in remote default layouts.
|
||||
|
||||
9. **No stored prompt/footer mutation:** The saved prompt/footer setting remains `Default` or `Custom` as-is. Suppression is applied to the effective default layout, not by rewriting a saved chip list.
|
||||
|
||||
10. **Re-enabling after setup changes:** If the user installs or authenticates `gh` after the default has been suppressed, they can manually add the PR chip from the prompt/footer editor. Automatic revalidation can be considered later but is not required for this change.
|
||||
|
||||
### Vertical Tabs "Show: PR link" Setting
|
||||
|
||||
The vertical tabs settings popup (expanded mode) has a "Show: PR link" toggle (`vertical_tabs_show_pr_link` in `TabSettings`). This setting's default value and persistence are not changed — it remains a plain `bool` defaulting to `true`. The toggle is decoupled from PR chip validation.
|
||||
|
||||
When "Show: PR link" is enabled but the PR chip has been suppressed due to a deterministic readiness failure, a warning icon is shown next to the toggle label in the settings popup.
|
||||
|
||||
11. **"Show: PR link" enabled and validation is not suppressed:** No warning. PR badges render in expanded vertical tab rows when a PR URL is available.
|
||||
|
||||
12. **"Show: PR link" enabled and validation is suppressed:** A warning icon appears inline next to the "PR link" label in the settings popup. Hovering the icon shows a tooltip explaining that the GitHub CLI must be installed and authenticated. No PR badges render unless the user manually re-enables/fixes the PR chip flow.
|
||||
|
||||
13. **"Show: PR link" disabled:** No warning icon, regardless of validation state. No PR badges render.
|
||||
|
||||
### Vertical Tabs Warning Details
|
||||
|
||||
When the warning is shown, it is rendered only in the expanded vertical-tabs settings popup's "Show" section on the "PR link" row.
|
||||
|
||||
- Row layout: `[check icon] [8px gap] [PR link label] [4px gap] [warning icon]`.
|
||||
- Icon: `Icon::AlertTriangle`.
|
||||
- Icon size: 12px by 12px.
|
||||
- Icon color: the standard theme warning color (e.g., `theme.ui_warning_color()`), not the error color.
|
||||
- Tooltip trigger: hovering the warning icon only. Hovering the rest of the row continues to behave like today: it highlights the clickable row and clicking toggles "Show: PR link".
|
||||
- Tooltip text: "Requires the GitHub CLI to be installed and authenticated".
|
||||
- Tooltip positioning: above the warning icon, using the standard Warp tooltip styling and overlay behavior.
|
||||
- The warning icon is omitted entirely when "Show: PR link" is disabled or validation is not suppressed.
|
||||
|
||||
### What Does NOT Change
|
||||
|
||||
- The `GithubPrPromptChip` feature flag still gates the chip's existence entirely.
|
||||
- The chip's shell scripts still handle repo/branch/no-PR cases.
|
||||
- The chip's runtime behavior still handles local-session gating, dependencies, timeout, failure suppression, fingerprint caching, and invalidation.
|
||||
- The `available_chips()` and `agent_footer_available_chips()` lists still expose `GithubPullRequest` when the feature flag is on so users can manually add it.
|
||||
- The vertical tabs "Show: Diff stats" setting is unchanged.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
1. A user with a working authenticated `gh` CLI on a fresh Warp install sees the PR chip in both terminal prompt and agent view footer without configuration.
|
||||
|
||||
2. A user without `gh` initially sees the PR chip in default layouts until the PR chip runtime deterministically detects the missing dependency; afterward, the chip is suppressed from default layouts.
|
||||
|
||||
3. A user with unauthenticated `gh` initially sees the PR chip in default layouts until the PR chip runtime deterministically detects the auth failure; afterward, the chip is suppressed from default layouts.
|
||||
|
||||
4. Users with custom prompt/footer configurations see no saved customization changes.
|
||||
|
||||
5. No saved prompt/footer chip lists are rewritten by suppression.
|
||||
|
||||
6. No-PR, non-GitHub repo, non-git directory, detached HEAD, and non-GitHub remote states do not suppress the PR chip by themselves.
|
||||
|
||||
7. Transient failures do not suppress the PR chip by themselves.
|
||||
|
||||
8. When suppression has occurred and "Show: PR link" is enabled, vertical tabs settings show the specified warning icon and tooltip.
|
||||
|
||||
9. When "Show: PR link" is disabled, vertical tabs settings do not show the warning icon.
|
||||
|
||||
## Validation
|
||||
|
||||
- **Unit tests:** Default terminal prompt includes `GithubPullRequest` before suppression.
|
||||
- **Unit tests:** Default agent footer includes `GithubPullRequest` before suppression.
|
||||
- **Unit tests:** Custom prompt/footer configurations are not modified by suppression.
|
||||
- **Unit tests:** Missing `gh` and unauthenticated `gh` transition validation state to suppressed.
|
||||
- **Unit tests:** Benign empty states and transient failures do not transition validation state to suppressed.
|
||||
- **Manual test (happy path):** With authenticated `gh`, open Warp with default settings in a GitHub repo branch with an open PR. Confirm chip appears in terminal prompt and agent footer and renders "PR #N".
|
||||
- **Manual test (missing `gh`):** Remove/rename `gh` from `$PATH`. Open Warp with default settings. Confirm the chip is suppressed after deterministic failure.
|
||||
- **Manual test (unauthenticated):** Run `gh auth logout`. Open Warp with default settings. Confirm the chip is suppressed after deterministic auth failure.
|
||||
- **Manual test (custom prompt):** Add the PR chip manually to a custom prompt. Confirm suppression does not remove it from the saved custom config.
|
||||
- **Manual test (vertical tabs warning):** With "Show: PR link" enabled and validation suppressed, confirm the warning icon appears next to the "PR link" label and the tooltip text matches the spec.
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. Which exact chip-runtime failure values should count as deterministic unauthenticated `gh` failures? The implementation should prefer narrow matching to avoid suppressing defaults after transient errors.
|
||||
|
||||
2. Should suppression ever automatically reset after the user runs a successful `gh auth login` or installs `gh`? This is not required for this change, but could be added later if the one-way suppression feels too sticky.
|
||||
@@ -0,0 +1,204 @@
|
||||
# Technical Spec: GitHub PR Prompt Chip — Default Inclusion with Validation
|
||||
|
||||
## Problem
|
||||
|
||||
We want the GitHub PR chip to be included in terminal prompt and agent view defaults without introducing a separate proactive readiness model. The existing chip runtime already knows how to check executables, run shell commands, suppress failures, and invalidate after relevant commands. The implementation should reuse that path to validate default inclusion and only add minimal state for remembering deterministic setup failures.
|
||||
|
||||
## Relevant Code
|
||||
|
||||
- `specs/APP-3908/PRODUCT.md` — product behavior.
|
||||
- `app/src/context_chips/prompt.rs (1-348)` — `PromptSelection`, persisted prompt config, and `PromptConfiguration::default_prompt()`.
|
||||
- `app/src/context_chips/current_prompt.rs (923-1424)` — chip state, chip execution, `chips_to_run`, snapshots, prompt string, and command-based invalidation.
|
||||
- `app/src/context_chips/context_chip.rs (76-365)` — chip runtime capabilities and disabled reasons.
|
||||
- `app/src/context_chips/mod.rs (142-341)` — `GithubPullRequest` chip policy, `gh`/`git` dependencies, timeout, failure suppression, and `git`/`gh`/`gt` invalidation.
|
||||
- `app/src/context_chips/builtins.rs (147-180)` and `app/src/context_chips/scripts/github_pull_request_prompt_chip.*` — PR URL shell generator and benign empty cases.
|
||||
- `app/src/context_chips/prompt_snapshot.rs (1-91)` — prompt snapshots currently order chips from `Prompt::chip_kinds()`.
|
||||
- `app/src/context_chips/prompt_type.rs (1-184)` — dynamic/static prompt resolution and agent footer chip resolution.
|
||||
- `app/src/ai/blocklist/agent_view/agent_input_footer/toolbar_item.rs (1-210)` — agent footer defaults and available toolbar items.
|
||||
- `app/src/terminal/session_settings.rs (76-311)` — `AgentToolbarChipSelection` and `CLIAgentToolbarChipSelection` default/custom variants.
|
||||
- `app/src/terminal/model/session.rs (816-1014)` — `Session::load_external_commands`, `Session::executable_names`, and command execution.
|
||||
- `app/src/workspace/tab_settings.rs (129-293)` — persisted `vertical_tabs_show_pr_link` bool.
|
||||
- `app/src/workspace/view/vertical_tabs.rs (1-200, 2688-2924, 3021-3655)` — vertical tabs settings popup, PR badge rendering, and toggle row rendering.
|
||||
- `app/src/workspace/view.rs (18171-18369)` — vertical tabs settings actions.
|
||||
|
||||
## Current State
|
||||
|
||||
The terminal prompt default omits `GithubPullRequest`. `PromptSelection::Default` is converted into a concrete `PromptConfiguration::default_prompt()` in the `Prompt` singleton, and downstream paths frequently call `Prompt::chip_kinds()`.
|
||||
|
||||
The agent footer default includes `GithubPullRequest` whenever `FeatureFlag::GithubPrPromptChip` is enabled. The default is returned from `AgentToolbarItemKind::default_left()`.
|
||||
|
||||
The PR chip already has a runtime policy:
|
||||
|
||||
- required executables: `gh` and `git`
|
||||
- `local_only: true`
|
||||
- 5s timeout
|
||||
- `suppress_on_failure`
|
||||
- fingerprint invalidation on `git`, `gh`, and `gt`
|
||||
|
||||
The shell scripts intentionally exit 0 with empty output for benign states such as not being in a git repo, detached HEAD, missing origin, non-GitHub remote, or no PR.
|
||||
|
||||
Vertical tabs render PR badges through `TerminalView::current_pull_request_url()`, which currently reads from `agent_view_chips()`. `vertical_tabs_show_pr_link` is a persisted bool defaulting to `true`.
|
||||
|
||||
## Proposed Changes
|
||||
|
||||
### 1. Add a small validation state
|
||||
|
||||
Add a hidden app setting or model-backed persisted state that tracks the default PR chip validation outcome:
|
||||
|
||||
```rust
|
||||
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum GithubPrPromptChipDefaultValidation {
|
||||
#[default]
|
||||
Unvalidated,
|
||||
Validated,
|
||||
Suppressed,
|
||||
}
|
||||
```
|
||||
|
||||
This should be global, private, and synced the same way other user preference defaults are synced only if product wants suppression to follow the user across machines. If suppression should be machine-specific because `gh` installation/auth is machine-specific, use non-synced local storage instead. Recommendation: make this **local/non-synced** because `gh` readiness depends on the current machine/session environment.
|
||||
|
||||
Only `Suppressed` affects default inclusion. `Unvalidated` and `Validated` both include the PR chip in defaults.
|
||||
|
||||
### 2. Include the PR chip in both defaults unless suppressed
|
||||
|
||||
Update `PromptConfiguration::default_prompt()` or the effective prompt-default resolver so the default chip list includes `ContextChipKind::GithubPullRequest` after `GitDiffStats` when:
|
||||
|
||||
- `FeatureFlag::GithubPrPromptChip` is enabled
|
||||
- validation state is not `Suppressed`
|
||||
|
||||
Do not rewrite `SessionSettings.saved_prompt`.
|
||||
|
||||
Update `AgentToolbarItemKind::default_left()` or a new parameterized helper so `ContextChipKind::GithubPullRequest` is included when:
|
||||
|
||||
- `FeatureFlag::GithubPrPromptChip` is enabled
|
||||
- validation state is not `Suppressed`
|
||||
|
||||
Do not change `CLIAgentToolbarChipSelection` defaults.
|
||||
|
||||
Implementation detail: because the current default helpers are static, prefer introducing effective default helpers that take `GithubPrPromptChipDefaultValidation` as input instead of reading global state inside low-level static helpers. This keeps unit tests simple and avoids hidden dependencies.
|
||||
|
||||
### 3. Feed runtime failures back into validation state
|
||||
|
||||
Extend `CurrentPrompt::fetch_chip_value_once` completion handling for `ContextChipKind::GithubPullRequest` so deterministic setup failures update validation state:
|
||||
|
||||
- `ChipAvailability::Disabled(RequiresExecutable { command: "gh" })` → `Suppressed`
|
||||
- unauthenticated `gh` error from the PR shell command → `Suppressed`
|
||||
- successful `gh`-backed execution → `Validated`
|
||||
|
||||
Do **not** suppress for:
|
||||
|
||||
- successful empty output from benign states
|
||||
- timeouts
|
||||
- generic non-auth command errors
|
||||
- network errors
|
||||
- rate-limit/API outages
|
||||
|
||||
For auth failures, use narrow matching. The shell script currently prints the raw `gh pr view` error to stderr for non-benign failures. Add a helper that classifies `CommandOutput` stderr/stdout into:
|
||||
|
||||
```rust
|
||||
enum GithubPrPromptChipValidationOutcome {
|
||||
Validated,
|
||||
SuppressDueToMissingGh,
|
||||
SuppressDueToUnauthenticatedGh,
|
||||
NoValidationChange,
|
||||
}
|
||||
```
|
||||
|
||||
Keep this helper small and unit-tested. If auth error strings are ambiguous, prefer `NoValidationChange` over over-suppressing.
|
||||
|
||||
### 4. Keep the PR chip running for validation while unvalidated
|
||||
|
||||
If the chip is included by default while `Unvalidated`, the existing chip runtime will run it and produce the validation signal.
|
||||
|
||||
After state transitions to `Suppressed`, rebuild effective default chip sets so:
|
||||
|
||||
- default terminal prompt no longer includes the PR chip
|
||||
- default agent footer no longer includes the PR chip
|
||||
- custom prompt/footer selections are unchanged
|
||||
|
||||
The `CurrentPrompt::handle_model_event` invalidation for `gh` commands can remain as-is for chip data. Automatic revalidation after suppression is not required for this feature, but a future follow-up could reset `Suppressed` after a successful `gh` command.
|
||||
|
||||
### 5. Keep vertical tabs setting decoupled, but show warning
|
||||
|
||||
Keep `vertical_tabs_show_pr_link` unchanged in `TabSettings`.
|
||||
|
||||
Add `show_pr_link_warning_mouse_state: MouseStateHandle` to `VerticalTabsPanelState`.
|
||||
|
||||
In `render_settings_popup`, compute:
|
||||
|
||||
```rust
|
||||
let show_pr_link_warning =
|
||||
show_pr_link && validation_state == GithubPrPromptChipDefaultValidation::Suppressed;
|
||||
```
|
||||
|
||||
Update `render_show_toggle_option` to accept an optional warning config:
|
||||
|
||||
```rust
|
||||
struct ShowToggleWarning {
|
||||
mouse_state: MouseStateHandle,
|
||||
tooltip: &'static str,
|
||||
}
|
||||
```
|
||||
|
||||
For the PR link row only, pass a warning when `show_pr_link_warning` is true. Render the warning icon inline after the label:
|
||||
|
||||
- row layout: check icon, 8px gap, label, 4px gap, warning icon
|
||||
- icon: `UiIcon::AlertTriangle`
|
||||
- size: 12px by 12px
|
||||
- color: `theme.ui_warning_color()`
|
||||
- tooltip text: `Requires the GitHub CLI to be installed and authenticated`
|
||||
- tooltip trigger: hover on the warning icon only
|
||||
- tooltip position: above the warning icon, using `appearance.ui_builder().tool_tip(...)` and `Stack`
|
||||
|
||||
The row's existing click behavior remains unchanged.
|
||||
|
||||
### 6. Decouple vertical tab PR badge value from agent footer customization
|
||||
|
||||
Change `TerminalView::current_pull_request_url()` so it does not depend on `agent_view_chips()`. Use `PromptType::latest_chip_value(&ContextChipKind::GithubPullRequest, ctx)` or a direct `CurrentPrompt` accessor.
|
||||
|
||||
This ensures vertical tab PR badges are controlled by `vertical_tabs_show_pr_link` and chip availability, not by whether the user customized the agent footer.
|
||||
|
||||
## End-to-End Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Default prompt/footer resolution] --> B{Validation state Suppressed?}
|
||||
B -->|No| C[Include GitHub PR chip]
|
||||
B -->|Yes| D[Omit GitHub PR chip from effective defaults]
|
||||
C --> E[Existing chip runtime executes]
|
||||
E --> F{Outcome}
|
||||
F -->|Deterministic missing/unauth gh| G[Set validation state Suppressed]
|
||||
F -->|Successful gh-backed result| H[Set validation state Validated]
|
||||
F -->|Benign empty/transient failure| I[No validation change]
|
||||
G --> D
|
||||
G --> J[Vertical tabs Show PR link warning if setting enabled]
|
||||
```
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
- **False suppression from transient errors:** Keep classification narrow. Unknown failures should not transition to `Suppressed`.
|
||||
- **Benign empty results do not validate auth:** This is acceptable; keep the chip in defaults while `Unvalidated` unless a deterministic readiness failure occurs.
|
||||
- **Suppression may be sticky after the user fixes `gh`:** Product accepts one-way suppression for this iteration. Users can manually add the chip; automatic reset can be a follow-up.
|
||||
- **Prompt/default resolution paths are scattered:** Audit and update prompt display, prompt snapshots, prompt string, copy menu, and agent footer chip resolution so all effective defaults agree.
|
||||
- **Machine-specific state:** If validation state is synced, suppression from one machine could hide the chip on another where `gh` works. Prefer non-synced local storage.
|
||||
- **Vertical tabs warning state source:** The warning should use the same validation state as prompt/footer suppression to avoid another readiness model.
|
||||
|
||||
## Testing and Validation
|
||||
|
||||
- Unit test default prompt resolution includes PR chip for `Unvalidated` and `Validated`, and omits it for `Suppressed`.
|
||||
- Unit test default agent footer resolution includes PR chip for `Unvalidated` and `Validated`, and omits it for `Suppressed`.
|
||||
- Unit test custom prompt/footer configs are not changed by validation state.
|
||||
- Unit test validation transitions:
|
||||
- missing `gh` → `Suppressed`
|
||||
- unauthenticated `gh` output → `Suppressed`
|
||||
- successful PR URL → `Validated`
|
||||
- no PR / non-GitHub remote / no git repo → no suppression
|
||||
- timeout / unknown error → no suppression
|
||||
- Unit test or lightweight UI test `render_show_toggle_option` warning behavior.
|
||||
- Manual validation for authenticated `gh`, missing `gh`, unauthenticated `gh`, custom prompt, and vertical tabs warning.
|
||||
|
||||
## Follow-Ups
|
||||
|
||||
- Reset `Suppressed` automatically after detecting a successful `gh auth login` or a later successful PR chip execution.
|
||||
- Improve the prompt editor disabled tooltip to distinguish missing `gh` from unauthenticated `gh`.
|
||||
- Add telemetry for validation transitions if rollout needs observability.
|
||||
Reference in New Issue
Block a user