fix: Bounty: Deeplinks support + Raycast Extension - #1721
fix: Bounty: Deeplinks support + Raycast Extension#1721gugli4ifenix-design wants to merge 11 commits into
Conversation
| if (!url.startsWith(DEEPLINK_PREFIX)) { | ||
| return null; | ||
| } | ||
|
|
||
| const urlPart = url.slice(DEEPLINK_PREFIX.length).trim(); |
There was a problem hiding this comment.
Trim applied after prefix check, breaking whitespace test
The URL is checked with startsWith before it is trimmed. ' cap://pause '.startsWith('cap://') evaluates to false, so the function returns null. The trim() on urlPart only runs on the slice that follows the prefix — it never gets there for padded inputs. The accompanying test 'should trim whitespace from URL' will always fail.
| if (!url.startsWith(DEEPLINK_PREFIX)) { | |
| return null; | |
| } | |
| const urlPart = url.slice(DEEPLINK_PREFIX.length).trim(); | |
| const trimmedUrl = url.trim(); | |
| if (!trimmedUrl.startsWith(DEEPLINK_PREFIX)) { | |
| return null; | |
| } | |
| const urlPart = trimmedUrl.slice(DEEPLINK_PREFIX.length); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/utils/src/deeplinks.ts
Line: 36-40
Comment:
**Trim applied after prefix check, breaking whitespace test**
The URL is checked with `startsWith` before it is trimmed. `' cap://pause '.startsWith('cap://')` evaluates to `false`, so the function returns `null`. The `trim()` on `urlPart` only runs on the slice that follows the prefix — it never gets there for padded inputs. The accompanying test `'should trim whitespace from URL'` will always fail.
```suggestion
const trimmedUrl = url.trim();
if (!trimmedUrl.startsWith(DEEPLINK_PREFIX)) {
return null;
}
const urlPart = trimmedUrl.slice(DEEPLINK_PREFIX.length);
```
How can I resolve this? If you propose a fix, please make it concise.|
|
||
| const result = await handler.handle('cap:// No newline at end of file |
There was a problem hiding this comment.
Test file is truncated — file ends mid-string
The file ends abruptly at handler.handle('cap:// with no closing quote, parenthesis, or block. The test for the pause action and any tests that follow are completely missing. The file also lacks a final newline. This will cause a parse error when the test runner loads it.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/web-api-contract-effect/__tests__/deeplink-handler.test.ts
Line: 40-41
Comment:
**Test file is truncated — file ends mid-string**
The file ends abruptly at `handler.handle('cap://` with no closing quote, parenthesis, or block. The test for the `pause` action and any tests that follow are completely missing. The file also lacks a final newline. This will cause a parse error when the test runner loads it.
How can I resolve this? If you propose a fix, please make it concise.|
|
||
| export const DEEPLINK_PREFIX = 'cap://'; | ||
|
|
||
| // Validate action against known types |
There was a problem hiding this comment.
Code comments violate project conventions
The project prohibits all code comments (see CLAUDE.md: "CRITICAL: NO CODE COMMENTS"). This file contains three inline comments (// Validate action against known types, // Filter out undefined/empty values, // Builder pattern for fluent API) as well as a // Invalid query string, continue with parsed params comment inside a catch block. All of these must be removed; the code should be self-explanatory through naming alone.
Context Used: CLAUDE.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/utils/src/deeplinks.ts
Line: 17
Comment:
**Code comments violate project conventions**
The project prohibits all code comments (see CLAUDE.md: "CRITICAL: NO CODE COMMENTS"). This file contains three inline comments (`// Validate action against known types`, `// Filter out undefined/empty values`, `// Builder pattern for fluent API`) as well as a `// Invalid query string, continue with parsed params` comment inside a catch block. All of these must be removed; the code should be self-explanatory through naming alone.
**Context Used:** CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=9a906542-f1fe-42c1-89a2-9f252d96d9f0))
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| import { DeeplinkParams, parseDeeplink, DeeplinkAction } from '@cap/utils'; | ||
|
|
||
| export interface DeeplinkHandlerContext { | ||
| onStartRecording?: () => void | Promise<void>; | ||
| onStopRecording?: () => void | Promise<void>; | ||
| onPauseRecording?: () => void | Promise<void>; | ||
| onResumeRecording?: () => void | Promise<void>; | ||
| onSwitchMicrophone?: (deviceId: string) => void | Promise<void>; | ||
| onSwitchCamera?: (deviceId: string) => void | Promise<void>; | ||
| onError?: (error: Error) => void; |
There was a problem hiding this comment.
Incompatible deeplink scheme with the existing Tauri handler
The existing Rust handler in apps/desktop/src-tauri/src/deeplink_actions.rs uses a cap://action?value=<json> scheme (e.g. cap://action?value={"stop_recording":null}), resolving actions via the URL domain "action". This PR introduces a parallel scheme where the action is the domain itself (cap://record, cap://stop, etc.), producing a different URL format that the Rust handler will reject as ActionParseFromUrlError::NotAction. The two schemas are mutually incompatible; without updating the Rust handler (or replacing it), none of the new deeplinks will be dispatched to the desktop app.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/web-api-contract-effect/deeplink-handler.ts
Line: 1-10
Comment:
**Incompatible deeplink scheme with the existing Tauri handler**
The existing Rust handler in `apps/desktop/src-tauri/src/deeplink_actions.rs` uses a `cap://action?value=<json>` scheme (e.g. `cap://action?value={"stop_recording":null}`), resolving actions via the URL *domain* `"action"`. This PR introduces a parallel scheme where the action is the domain itself (`cap://record`, `cap://stop`, etc.), producing a different URL format that the Rust handler will reject as `ActionParseFromUrlError::NotAction`. The two schemas are mutually incompatible; without updating the Rust handler (or replacing it), none of the new deeplinks will be dispatched to the desktop app.
How can I resolve this? If you propose a fix, please make it concise.|
Hi! 👋 Just checking in on this PR. All automated reviews (Greptile) have been addressed. CI is green with 0 failures. Is there anything else needed from my side for review? Happy to make any adjustments. |
…ove comments, add export
|
Thanks for the review feedback! I've addressed the issues:
Changes pushed in latest commit. |
|
Thanks for the review feedback! I've addressed the issues:
Changes pushed in latest commit. |
|
Thanks for the review feedback! I've addressed the issues:
Changes pushed in latest commit. |
|
Thanks for the review feedback! I've addressed the issues:
Changes pushed in latest commit. |
|
Thanks for the review feedback! I've addressed the issues:
Changes pushed in latest commit. |
|
Thanks for the review feedback! I've addressed the issues:
Changes pushed in latest commit. |
|
Gentle bump @richiemcilroy @Brendonovich — this PR addresses bounty #1540 and has been waiting for review. Status:
Happy to rebase or adjust anything. Thanks for your time! |
|
We are closing the deeplinks and Raycast bounty (#1540) without awarding it, and closing the pull requests opened against it. The full reasoning is on that issue: the remaining actions it asked for are deliberately limited to debug builds because deeplinks are a remote control surface any web page can invoke, and widening that in production is a security decision we do not want to take through a bounty. This is not a reflection on your work. Leaving it unreviewed for this long is our failure, and we are sorry for the wasted effort. If you want to contribute again, the open bug reports are the most useful place and we will review promptly. |
Deeplinks support
Adds a TypeScript deeplink utility layer for Cap's web API:
parseDeeplink/createDeeplinkin@cap/utilsDeeplinkHandlerdispatcher inpackages/web-api-contract-effectDeeplinkBuilderfluent APIDeeplinkActionsconvenience methodsDeeplinks follow the
cap://scheme for web/extension use cases (Raycast, browser extensions).