[Fix] Add Cap deeplinks and Raycast controls#1811
Conversation
| { | ||
| "$schema": "https://www.raycast.com/schemas/extension.json", | ||
| "name": "cap-raycast", | ||
| "title": "Cap", | ||
| "description": "Control Cap recordings with deeplinks.", | ||
| "icon": "command-icon.png", | ||
| "author": "Cap", | ||
| "license": "AGPL-3.0-or-later", | ||
| "commands": [ | ||
| { |
There was a problem hiding this comment.
Biome will conflict with Prettier on every
pnpm format/pnpm lint run
apps/raycast is included in the pnpm-workspace.yaml (apps/*) and biome.json's includes: ["**"] has no exclusion for it. Every file under apps/raycast/src/ uses 2-space indentation and the extension's own prettier config, but Biome enforces indentStyle: "tab". Running pnpm format or pnpm lint from the repo root will reformat these files, breaking the Raycast toolchain expectation and causing CI failures. The apps/raycast directory should be added to Biome's ignores list, or the extension files should be rewritten to use tabs/double-quotes to match the workspace's Biome config.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast/package.json
Line: 1-10
Comment:
**Biome will conflict with Prettier on every `pnpm format`/`pnpm lint` run**
`apps/raycast` is included in the `pnpm-workspace.yaml` (`apps/*`) and `biome.json`'s `includes: ["**"]` has no exclusion for it. Every file under `apps/raycast/src/` uses 2-space indentation and the extension's own `prettier` config, but Biome enforces `indentStyle: "tab"`. Running `pnpm format` or `pnpm lint` from the repo root will reformat these files, breaking the Raycast toolchain expectation and causing CI failures. The `apps/raycast` directory should be added to Biome's `ignores` list, or the extension files should be rewritten to use tabs/double-quotes to match the workspace's Biome config.
How can I resolve this? If you propose a fix, please make it concise.| "author": "Cap", | ||
| "license": "AGPL-3.0-or-later", |
There was a problem hiding this comment.
author must be a Raycast account username, not a display name
The Raycast manifest spec and store validation require the author field to be your actual Raycast account username (e.g., "adminlip"). Using "Cap" (a company display name) will cause ray build to warn and any store submission to fail. The license field also needs to be "MIT" for the Raycast store; AGPL-3.0 extensions are rejected.
| "author": "Cap", | |
| "license": "AGPL-3.0-or-later", | |
| "author": "adminlip", | |
| "license": "MIT", |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast/package.json
Line: 7-8
Comment:
**`author` must be a Raycast account username, not a display name**
The Raycast manifest spec and store validation require the `author` field to be your actual Raycast account username (e.g., `"adminlip"`). Using `"Cap"` (a company display name) will cause `ray build` to warn and any store submission to fail. The `license` field also needs to be `"MIT"` for the Raycast store; AGPL-3.0 extensions are rejected.
```suggestion
"author": "adminlip",
"license": "MIT",
```
How can I resolve this? If you propose a fix, please make it concise.| for (const [key, value] of Object.entries(params)) { | ||
| if (value !== undefined && value !== "") | ||
| url.searchParams.set(key, String(value)); | ||
| } |
There was a problem hiding this comment.
false boolean values are always appended to URLs even when they are the server-side default
The guard value !== undefined && value !== "" passes false booleans through, so start-recording always appends system_audio=false to the URL. In parse_bool_param the default is already false, so this is redundant. Consider also filtering out false unless the param is required.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast/src/cap.ts
Line: 10-13
Comment:
**`false` boolean values are always appended to URLs even when they are the server-side default**
The guard `value !== undefined && value !== ""` passes `false` booleans through, so `start-recording` always appends `system_audio=false` to the URL. In `parse_bool_param` the default is already `false`, so this is redundant. Consider also filtering out `false` unless the param is required.
How can I resolve this? If you propose a fix, please make it concise.| fn parse_bool_param( | ||
| params: &std::collections::HashMap<std::borrow::Cow<'_, str>, std::borrow::Cow<'_, str>>, | ||
| key: &str, | ||
| default: bool, | ||
| ) -> bool { | ||
| params | ||
| .get(key) | ||
| .and_then(|value| value.parse::<bool>().ok()) | ||
| .unwrap_or(default) | ||
| } |
There was a problem hiding this comment.
parse_bool_param only accepts lowercase "true"/"false"
Rust's str::parse::<bool>() is case-sensitive and recognises exactly "true" and "false". Values like "1", "0", "True", or "yes" silently fall back to default. For a URL-based API called by scripts or integrations outside the Raycast extension, this can cause unexpected silent misbehaviour.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src-tauri/src/deeplink_actions.rs
Line: 181-190
Comment:
**`parse_bool_param` only accepts lowercase `"true"`/`"false"`**
Rust's `str::parse::<bool>()` is case-sensitive and recognises exactly `"true"` and `"false"`. Values like `"1"`, `"0"`, `"True"`, or `"yes"` silently fall back to `default`. For a URL-based API called by scripts or integrations outside the Raycast extension, this can cause unexpected silent misbehaviour.
How can I resolve this? If you propose a fix, please make it concise.| { | ||
| "$schema": "https://www.raycast.com/schemas/extension.json", | ||
| "name": "cap-raycast", | ||
| "title": "Cap", | ||
| "description": "Control Cap recordings with deeplinks.", | ||
| "icon": "command-icon.png", | ||
| "author": "Cap", | ||
| "license": "AGPL-3.0-or-later", | ||
| "commands": [ | ||
| { | ||
| "name": "start-recording", | ||
| "title": "Start Recording", | ||
| "description": "Start a Cap recording with a display or window target.", | ||
| "mode": "view" | ||
| }, | ||
| { | ||
| "name": "stop-recording", | ||
| "title": "Stop Recording", | ||
| "description": "Stop the current Cap recording.", | ||
| "mode": "no-view" | ||
| }, | ||
| { | ||
| "name": "pause-recording", | ||
| "title": "Pause Recording", | ||
| "description": "Pause the current Cap recording.", | ||
| "mode": "no-view" | ||
| }, | ||
| { | ||
| "name": "resume-recording", | ||
| "title": "Resume Recording", | ||
| "description": "Resume the current Cap recording.", | ||
| "mode": "no-view" | ||
| }, | ||
| { | ||
| "name": "toggle-pause-recording", | ||
| "title": "Toggle Pause Recording", | ||
| "description": "Toggle pause for the current Cap recording.", | ||
| "mode": "no-view" | ||
| }, | ||
| { | ||
| "name": "set-microphone", | ||
| "title": "Set Microphone", | ||
| "description": "Set or clear Cap's microphone input.", | ||
| "mode": "view" | ||
| }, | ||
| { | ||
| "name": "set-camera", | ||
| "title": "Set Camera", | ||
| "description": "Set or clear Cap's camera input.", | ||
| "mode": "view" | ||
| }, | ||
| { | ||
| "name": "open-settings", | ||
| "title": "Open Settings", | ||
| "description": "Open Cap settings.", | ||
| "mode": "view" | ||
| } | ||
| ], | ||
| "dependencies": { | ||
| "@raycast/api": "^1.83.2" | ||
| }, | ||
| "devDependencies": { | ||
| "@raycast/eslint-config": "^1.0.11", | ||
| "@types/node": "^20.17.6", | ||
| "eslint": "^8.57.1", | ||
| "prettier": "^3.3.3", | ||
| "typescript": "^5.6.3" | ||
| }, | ||
| "scripts": { | ||
| "build": "ray build -e dist", | ||
| "dev": "ray develop", | ||
| "lint": "ray lint", | ||
| "fix-lint": "ray lint --fix" | ||
| } | ||
| } |
There was a problem hiding this comment.
Missing
platforms field and package-lock.json
The Raycast manifest recommends declaring a platforms field (e.g., ["macOS"]) so users on other platforms are informed the extension is macOS-only. Additionally, Raycast's store CI builds extensions with npm using package-lock.json; without one the lockfile is missing and dependency versions aren't pinned for store validation.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast/package.json
Line: 1-75
Comment:
**Missing `platforms` field and `package-lock.json`**
The Raycast manifest recommends declaring a `platforms` field (e.g., `["macOS"]`) so users on other platforms are informed the extension is macOS-only. Additionally, Raycast's store CI builds extensions with `npm` using `package-lock.json`; without one the lockfile is missing and dependency versions aren't pinned for store validation.
How can I resolve this? If you propose a fix, please make it concise.8acbf8d to
f0a9741
Compare
What
cap-desktop://...actions.Why
Issue #1540 requests deeplink support so a Raycast extension can control Cap recording workflows.
Testing
pnpm --dir apps/raycast lintpnpm --dir apps/raycast buildgit diff --checkNote: Rust workspace formatting/checking could not be run in this container because the installed Cargo is 1.75 and this workspace requires Rust edition 2024 support.
Fixes #1540