feat(uri): add warposs://pane/{uuid} deep link for pane focus#9655
feat(uri): add warposs://pane/{uuid} deep link for pane focus#9655seemeroland merged 8 commits intowarpdotdev:masterfrom
Conversation
Add PaneGroup::find_pane_by_session_uuid(&[u8]) -> Option<PaneId> that iterates terminal panes and matches by persistent session UUID. This enables deep link handlers to locate a specific pane across all windows without exposing session_uuid() outside pane_group. Co-Authored-By: Warp <[email protected]>
Add UriHost::Pane variant that accepts a 32-char hex UUID in the path, decodes it to bytes, walks all workspaces/windows to find the matching terminal pane via find_pane_by_session_uuid, then focuses the window and dispatches handle_pane_navigation_event to switch to that tab. Uses WindowBehaviorHint::Nothing since the handler explicitly calls show_window_and_focus_app. Allows arbitrary path in validate_custom_uri. Co-Authored-By: Warp <[email protected]>
Cover host parsing, full URI validation, empty path handling, invalid hex rejection, and case-insensitive hex decoding. Co-Authored-By: Warp <[email protected]>
7f548d4 to
a0e5fae
Compare
There was a problem hiding this comment.
Overview
This PR adds a warposs://pane/{uuid_hex} custom URI host that decodes a 32-character pane UUID, searches registered workspaces for the matching terminal pane, and dispatches the existing pane navigation action to focus it. It also adds URI parsing and validation coverage for the new host.
Concerns
- No blocking correctness or security concerns found in the changed diff lines.
Verdict
Found: 0 critical, 0 important, 0 suggestions
Approve
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
|
Same question and nits as in the original review: #9613 (review) How do you anticipate users getting the session_uuid to use with this URI? I don't believe we expose this in a nice way. Were you thinking of reading from sqlite? Trying to understand the use case for this |
My bad, it's true I did not explain the usecase I'm using ( and try to contribute to ) an open source project : Open Vibe Island (https://github.com/Octane0411/open-vibe-island), a macOS menubar app that monitors AI coding agents running inside Warp. How an external app retrieves pane UUIDs: The terminal_panes table has a uuid column (16-byte BLOB, unique): The returned hex string is used directly in the deep link: This is the same approach Warp itself uses for persistence — the UUID is the canonical pane identifier across restarts. An external app just reads the same DB. No new API surface is needed: the SQLite file is already world-readable on macOS, and the schema is stable (diesel-managed migrations). Thank you for taking time on this PR ;-) |
There was a problem hiding this comment.
Overview
This PR adds a warposs://pane/{uuid} custom URI host that decodes a 32-character hex UUID, searches registered workspaces for a matching terminal pane UUID, and dispatches the existing pane navigation action to focus it.
Concerns
- The new pane UUID lookup scans all terminal pane contents, including panes retained but hidden by pane-tree state, so a stale or hidden pane UUID can be treated as a successful match instead of being ignored.
- The case-insensitive decoding test reimplements the decoding logic locally instead of exercising the production decode path.
Verdict
Found: 0 critical, 1 important, 1 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
find_pane_by_session_uuid now skips panes hidden for undo-close so deep links cannot resolve to unfocusable targets. Extract decode_uuid_hex helper shared between handler and tests. Add coverage for wrong-length and invalid-char hex inputs.
There was a problem hiding this comment.
Overview
Adds a warposs://pane/{uuid} URI host that decodes 32-char hex session UUIDs, finds a matching visible terminal pane across registered workspaces, focuses the corresponding pane/tab/window, and adds URI/hex parsing unit coverage.
Concerns
- Supplemental security pass: no blocking issues found. The handler avoids logging UUID values and rejects malformed hex before lookup.
Verdict
Found: 0 critical, 0 important, 0 suggestions
Approve
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
|
/oz-review |
There was a problem hiding this comment.
Overview
This PR adds a warposs://pane/{uuid} custom URI host that looks up terminal panes by persistent session UUID and focuses the matching pane across workspaces/windows.
Concerns
- The UUID decoder can panic on non-ASCII path segments because it slices a UTF-8 string at fixed byte offsets after only checking byte length. Since custom URIs are external inputs, malformed links should be rejected without crashing.
Verdict
Found: 1 critical, 0 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
Use as_bytes() + chunks_exact(2) instead of str slicing by byte offset, which can panic on multi-byte UTF-8 characters in external URI input.
|
/oz-review |
|
I'm re-reviewing this pull request in response to a review request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This PR adds a warposs://pane/{uuid} custom URI host that scans registered workspaces for a terminal pane by persistent session UUID and focuses the containing window/tab/pane.
Concerns
- [SECURITY] The new route places a stable pane/session identifier in
url.path(), buthandle_incoming_urilogs scheme/host/path throughsafe_url_log_fieldsbefore dispatch. That means pane deeplinks will persist capability-like focus tokens in release logs unless the pane path is redacted or the token is moved out of logged fields.
Security
- Redact pane deeplink UUIDs from URI logs before enabling this route.
Verdict
Found: 0 critical, 1 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
Pane UUIDs are stable session identifiers — logging them via safe_url_log_fields persists focus tokens. Redact path for pane URIs.
|
/oz-review |
|
I'm re-reviewing this pull request in response to a review request. You can view the conversation on Warp. I reviewed this pull request and requested human review from: @seemeroland. Comment Powered by Oz |
Oz no longer requests changes for this pull request after the latest automated review.
There was a problem hiding this comment.
Overview
This PR adds a pane URI host for focusing an existing terminal pane by its persistent session UUID, including UUID hex decoding, workspace-wide lookup, window focus/navigation dispatch, safe URL logging redaction, and unit coverage for parsing/validation helpers.
Concerns
- No blocking correctness or security concerns found in the changed lines.
Verdict
Found: 0 critical, 0 important, 0 suggestions
Approve
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
There was a problem hiding this comment.
Overview
This PR adds a pane URI host for focusing an existing terminal pane by its persistent session UUID, including UUID hex decoding, workspace-wide lookup, window focus/navigation dispatch, safe URL logging redaction, and unit coverage for parsing/validation helpers.
Concerns
- No blocking correctness or security concerns found in the changed lines.
Verdict
Found: 0 critical, 0 important, 0 suggestions
Approve
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
seemeroland
left a comment
There was a problem hiding this comment.
I see, we probably should expose IDs in another way rather than require querying the sqlite table, but it seems fine to add the URI regardless. The session UUID is specifically for a terminal pane, and is different from the PaneId which is usually used to identify a pane generically (there are other types of panes than terminal panes).
Since you need the UUID to be stable across session restarts, the session UUID seems fine. But I would rename to make it clear that this is not a pane ID. Specifically:
- The URI should be /session/{uuid}
|
|
||
| /// Returns the [`PaneId`] of the terminal pane whose persistent UUID matches | ||
| /// the given bytes, or `None` if no such pane exists in this group. | ||
| pub fn find_pane_by_session_uuid(&self, uuid: &[u8]) -> Option<PaneId> { |
There was a problem hiding this comment.
nit: find_terminal_pane_by_session_uuid
| /// Actions triggered from Linear integrations (e.g. work on issue). | ||
| Linear, | ||
| /// Focuses a specific terminal pane by its persistent UUID. | ||
| Pane, |
There was a problem hiding this comment.
Session, assuming we want to find by session UUID and not PaneId
| url.path(), | ||
| ) | ||
| let host = url.host_str().unwrap_or("-"); | ||
| let path = if host == "pane" { "[redacted]" } else { url.path() }; |
There was a problem hiding this comment.
nit: I know the oz review flagged this, but I don't think the path is sensitive info and it should be fine to log it. I don't think we need to change this and I don't love this special check for pane host
The URI identifies a terminal session UUID, not a generic PaneId.
- UriHost::Pane → UriHost::Session, route is now warposs://session/{uuid}
- find_pane_by_session_uuid → find_terminal_pane_by_session_uuid
- Remove unnecessary path redaction in safe_url_log_fields
|
@seemeroland Thanks for the review! All addressed in 6dd92af:
Let me know if anything else needs adjusting. |
seemeroland
left a comment
There was a problem hiding this comment.
Thanks for iterating!
Description
Adds a
warposs://pane/{uuid_hex}deep link that focuses a specific terminal pane by its persistent session UUID. This enables external tools to programmatically switch to a given pane/tab/window in Warp.What
PaneGroup::find_pane_by_session_uuid— new method that iterates terminal panes and matches by persistent UUID bytes, returning thePaneIdUriHost::Pane— new URI host variant with full handler: decodes 32-char hex UUID, walks all workspaces/windows viaWorkspaceRegistry::all_workspaces(), dispatcheshandle_pane_navigation_eventto focus the tab, and callsshow_window_and_focus_appto bring the window forwardWhy
External tools (e.g. orchestration UIs) that know a pane's UUID need a way to switch focus to that pane without user interaction. The pane UUID is already persisted in SQLite and is stable across sessions.
How
[u8; 16]viau8::from_str_radix(no new crate dependency)WorkspaceRegistry::all_workspaces()+tab_views()pattern (matchesfocus_terminal_view_in_other_window)WindowBehaviorHint::Nothingsince handler explicitly manages window focusTesting
uri_test.rs)open "warposs://pane/{uuid}"correctly focuses the target pane across tabs and windowsCo-Authored-By: Warp [email protected]