feat: add raycast extension and deeplink support#1700
feat: add raycast extension and deeplink support#1700Chronolapse411 wants to merge 2 commits intoCapSoftware:mainfrom
Conversation
| let _ = crate::set_camera_input(app.clone(), state.clone(), settings.camera_id, None).await; | ||
|
|
||
| let inputs = StartRecordingInputs { | ||
| mode: crate::recording::RecordingMode::Screen, |
There was a problem hiding this comment.
RecordingMode::Screen does not exist — compile error
crate::recording::RecordingMode is cap_recording::RecordingMode, whose only variants are Studio, Instant, and Screenshot. There is no Screen variant. This line will cause a compilation failure.
Additionally, RecordingMode is not re-exported from crate::recording (the use cap_recording::RecordingMode in recording.rs is not pub use), so the qualified path crate::recording::RecordingMode won't resolve either.
For a "start default recording" action, the correct approach is to read the user's configured mode from settings (which RecordingSettingsStore already exposes as mode: Option<RecordingMode>) or fall back to the default:
| mode: crate::recording::RecordingMode::Screen, | |
| let inputs = StartRecordingInputs { | |
| mode: settings.mode.unwrap_or_default(), |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src-tauri/src/deeplink_actions.rs
Line: 168
Comment:
**`RecordingMode::Screen` does not exist — compile error**
`crate::recording::RecordingMode` is `cap_recording::RecordingMode`, whose only variants are `Studio`, `Instant`, and `Screenshot`. There is no `Screen` variant. This line will cause a compilation failure.
Additionally, `RecordingMode` is not re-exported from `crate::recording` (the `use cap_recording::RecordingMode` in `recording.rs` is not `pub use`), so the qualified path `crate::recording::RecordingMode` won't resolve either.
For a "start default recording" action, the correct approach is to read the user's configured mode from settings (which `RecordingSettingsStore` already exposes as `mode: Option<RecordingMode>`) or fall back to the default:
```suggestion
let inputs = StartRecordingInputs {
mode: settings.mode.unwrap_or_default(),
```
How can I resolve this? If you propose a fix, please make it concise.| ActionParseFromUrlError::Invalid => { | ||
| eprintln!("Invalid deep link format \"{}\"", &url) | ||
| } | ||
| // Likely login action, not handled here. |
There was a problem hiding this comment.
Code comment violates the NO CODE COMMENTS convention
Per the project's CLAUDE.md and AGENTS.md, no comments of any kind are permitted in code. The line // Likely login action, not handled here. is a pre-existing violation that was re-introduced by this PR when the file was rewritten. Code must be self-explanatory through naming and types.
| // Likely login action, not handled here. | |
| ActionParseFromUrlError::NotAction => {} |
Context Used: AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src-tauri/src/deeplink_actions.rs
Line: 53
Comment:
**Code comment violates the NO CODE COMMENTS convention**
Per the project's CLAUDE.md and AGENTS.md, no comments of any kind are permitted in code. The line `// Likely login action, not handled here.` is a pre-existing violation that was re-introduced by this PR when the file was rewritten. Code must be self-explanatory through naming and types.
```suggestion
ActionParseFromUrlError::NotAction => {}
```
**Context Used:** AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=27801409-c24c-4476-9c6c-180f1ef0a7f2))
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!
| await closeMainWindow(); | ||
| await showHUD("Starting default recording in Cap"); |
There was a problem hiding this comment.
Optimistic HUD message fires before the operation completes
open() only triggers the deeplink (launching the URL handler in the native app) and returns immediately — it does not wait for Cap to actually begin recording. showHUD("Starting default recording in Cap") therefore fires regardless of whether recording actually starts successfully (e.g., Cap isn't running, permissions are missing, or the deeplink returns an error). Consider wording the message to reflect that the request was sent rather than that recording has started, e.g. "Recording requested in Cap", to avoid giving users false confidence.
The same pattern applies in stop-recording.tsx line 8 ("Stopped recording in Cap").
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/src/start-recording.tsx
Line: 7-8
Comment:
**Optimistic HUD message fires before the operation completes**
`open()` only triggers the deeplink (launching the URL handler in the native app) and returns immediately — it does not wait for Cap to actually begin recording. `showHUD("Starting default recording in Cap")` therefore fires regardless of whether recording actually starts successfully (e.g., Cap isn't running, permissions are missing, or the deeplink returns an error). Consider wording the message to reflect that the request was *sent* rather than that recording has *started*, e.g. `"Recording requested in Cap"`, to avoid giving users false confidence.
The same pattern applies in `stop-recording.tsx` line 8 (`"Stopped recording in Cap"`).
How can I resolve this? If you propose a fix, please make it concise.| "description": "Control Cap Screen Recorder from Raycast", | ||
| "icon": "icon.png", | ||
| "author": "Cap", | ||
| "categories": [ |
There was a problem hiding this comment.
author field may not match a valid Raycast handle
Raycast requires the author field to be the publisher's Raycast developer username, not a display name. If this extension is intended for Raycast Store publishing (the package.json includes a publish script), "Cap" may not match an actual registered account and will cause the publish command to fail. Confirm the correct Raycast username or document that this is internal-only. Is this extension intended for Raycast Store publishing? If so, does "Cap" match the registered Raycast developer username?
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/package.json
Line: 8
Comment:
**`author` field may not match a valid Raycast handle**
Raycast requires the `author` field to be the publisher's Raycast developer username, not a display name. If this extension is intended for Raycast Store publishing (the `package.json` includes a `publish` script), `"Cap"` may not match an actual registered account and will cause the publish command to fail. Confirm the correct Raycast username or document that this is internal-only. Is this extension intended for Raycast Store publishing? If so, does `"Cap"` match the registered Raycast developer username?
How can I resolve this? If you propose a fix, please make it concise.
Allows starting/stopping recording via deeplinks and adds a Raycast extension for ease of use. Fixes #1540
Greptile Summary
This PR adds a Raycast extension and a new
StartDefaultRecordingdeeplink action to allow users to start and stop Cap recordings from Raycast without opening the app. The Raycast side is clean and the deeplink URL encoding is correct, but the RustStartDefaultRecordingimplementation contains a critical compile-time error that will prevent the desktop app from building.Key changes:
DeepLinkAction::StartDefaultRecordingvariant indeeplink_actions.rsthat reads the user's stored recording settings (mic, camera, capture target, system audio, org ID) and starts a recording using sensible defaultsapps/raycast-extensionwith two no-view commands (start-recording,stop-recording) that fire the corresponding deeplinks viaopen()Issues found:
crate::recording::RecordingMode::Screenon line 168 ofdeeplink_actions.rsreferences a variant that does not exist.cap_recording::RecordingModeonly hasStudio,Instant, andScreenshot. The fix is to usesettings.mode.unwrap_or_default()open()returns, before Cap has confirmed the operationauthorfield:\"Cap\"inpackage.jsonmay not match a registered Raycast developer handle, blocking Raycast Store publishing// Likely login action, not handled here.comment was re-introduced when the file was rewritten, violating the project's strict no-comments conventionConfidence Score: 4/5
Not safe to merge — the
RecordingMode::Screencompile error will break the desktop app build.A confirmed P0 compile error in
deeplink_actions.rs(non-existentRecordingMode::Screenvariant) will preventcap-desktopfrom building. This must be fixed before merge. All other findings are P2 style/UX concerns that don't block correctness.apps/desktop/src-tauri/src/deeplink_actions.rs— theStartDefaultRecordingarm uses a non-existent enum variant and needs the mode fixed tosettings.mode.unwrap_or_default().Important Files Changed
StartDefaultRecordingvariant that reads settings and triggers recording — but uses the non-existentRecordingMode::Screenvariant, causing a compile error; also re-introduces a pre-existing code comment that violates project conventions.cap://action?value="start_default_recording"deeplink and shows a HUD; deeplink encoding is correct but the HUD fires optimistically before Cap confirms recording has started.cap://action?value="stop_recording"deeplink; deeplink encoding is correct but the success HUD fires optimistically before stop is confirmed.author: "Cap"may not be a valid Raycast store handle, which could block publishing.cap-desktopfrom 0.4.81 to 0.4.82; expected change for this feature addition.Sequence Diagram
sequenceDiagram participant User participant Raycast participant OS participant CapDesktop participant RecordingSettingsStore User->>Raycast: Trigger "Start Default Recording" Raycast->>OS: open("cap://action?value=%22start_default_recording%22") Raycast->>Raycast: closeMainWindow() Raycast->>Raycast: showHUD("Starting default recording in Cap") OS->>CapDesktop: Deep link event (cap://action?value=...) CapDesktop->>CapDesktop: handle() → parse DeepLinkAction CapDesktop->>RecordingSettingsStore: RecordingSettingsStore::get(app) RecordingSettingsStore-->>CapDesktop: settings (mic, camera, target, system_audio, org_id) CapDesktop->>CapDesktop: set_mic_input (errors silenced) CapDesktop->>CapDesktop: set_camera_input (errors silenced) CapDesktop->>CapDesktop: start_recording(StartRecordingInputs) Note over CapDesktop: mode: RecordingMode::Screen ← COMPILE ERROR User->>Raycast: Trigger "Stop Recording" Raycast->>OS: open("cap://action?value=%22stop_recording%22") Raycast->>Raycast: closeMainWindow() Raycast->>Raycast: showHUD("Stopped recording in Cap") OS->>CapDesktop: Deep link event CapDesktop->>CapDesktop: stop_recording()Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat: add raycast extension and deeplink..." | Re-trigger Greptile
(2/5) Greptile learns from your feedback when you react with thumbs up/down!
Context used: