fix: Bounty: Deeplinks support + Raycast Extension#1721
fix: Bounty: Deeplinks support + Raycast Extension#1721gugli4ifenix-design wants to merge 5 commits intoCapSoftware:mainfrom
Conversation
packages/utils/src/deeplinks.ts
Outdated
| 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.
packages/utils/src/deeplinks.ts
Outdated
|
|
||
| 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
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).