Summary

  • extend desktop deeplink actions with pause/resume/toggle + mic/camera switching
  • add a new apps/raycast extension with commands for start/stop/pause/resume/toggle and mic/camera switching
  • keep existing cap-desktop://action?value=... payload format for compatibility

Validation

  • pnpm --dir apps/raycast run typecheck
  • cargo test -p cap-desktop deeplink_actions -- --nocapture (blocked in this environment: cargo not installed)

/claim #1540

Greptile Summary

This PR adds pause/resume/toggle deeplink actions to the Cap desktop app and introduces a new Raycast extension (apps/raycast) that exposes seven commands (start/stop/pause/resume/toggle recording, switch mic, switch camera) by serializing DeepLinkAction payloads and dispatching them via macOS’s open URL scheme.

Key changes:

  • deeplink_actions.rs: Adds PauseRecording, ResumeRecording, TogglePauseRecording, SetMicrophone, and SetCamera enum variants with correct delegation to existing recording.rs functions.
  • apps/raycast/: New workspace package with a utils.ts dispatcher (execFile("open", [...])) and one source file per command.
  • pnpm-lock.yaml: Adds @raycast/api and related dev dependencies for the new workspace; also reflects minor transitive dependency bumps.

Issues found:

  • Race condition in start-recording.tsx: The form fires two sequential open deeplinks — start_recording (with camera: null) then set_camera. Because open returns before Cap processes the URL, these can be handled by Cap out of order. If set_camera is processed first, the subsequent StartRecording handler’s call to set_camera_input(..., None, None) silently overwrites the camera selection back to null.
  • Missing isRequired on targetName: An empty target name passes form validation but causes a silent Rust-side error when the lookup fails.

Confidence Score: 2/5

  • Safe to merge for basic pause/resume/toggle/mic/camera deeplinks; however, the start-recording race condition can silently overwrite camera selection and should be addressed before heavy use of that command.
  • The Rust deeplink additions are clean and delegate to already-tested recording functions. The simple Raycast commands (pause, resume, toggle, stop, switch-mic, switch-camera) are straightforward and low-risk. However, the score is reduced due to two issues in start-recording.tsx: (1) a race condition where the two-step start_recording + set_camera dispatch pattern can silently overwrite the user’s camera selection back to null if processing order is inverted, and (2) missing isRequired validation on the targetName field allowing empty form submission with silent Rust-side failures. The race condition specifically poses a data-loss risk in the most complex command.
  • apps/raycast/src/start-recording.tsx — two issues: race condition between sequential deeplink dispatches, and missing field validation.

Sequence Diagram

sequenceDiagram
participant User
participant Raycast
participant macOS as macOS open
participant Cap as Cap Desktop (Tauri)
participant Recording as recording.rs
User->>Raycast: Invoke command (e.g. Pause Recording)
Raycast->>macOS: open cap-desktop://action?value={"pause_recording":null}
macOS-->>Raycast: returns immediately
Raycast->>Raycast: showToast("Sent to Cap")
macOS->>Cap: deliver deeplink URL
Cap->>Cap: DeepLinkAction::try_from(url) → PauseRecording
Cap->>Recording: pause_recording(app, state)
Note over Raycast,Cap: start-recording race condition
User->>Raycast: Submit start form (with cameraLabel)
Raycast->>macOS: open cap-desktop://action?value={"start_recording":{...,"camera":null}}
macOS-->>Raycast: returns immediately
Raycast->>macOS: open cap-desktop://action?value={"set_camera":{"camera_label":"..."}}
macOS-->>Raycast: returns immediately
macOS->>Cap: deliver start_recording (camera=null)
macOS->>Cap: deliver set_camera (may arrive before OR after start_recording)
Cap->>Recording: set_camera_input(..., None) ← may overwrite set_camera result

Last reviewed commit: 525d651

Greptile also left 2 inline comments on this PR.

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

Claim

Total prize pool $200.10
Total paid $0
Status Pending
Submitted March 06, 2026
Last updated March 06, 2026

Contributors

LU

Luna Ops

@lustsazeus-lab

100%

Sponsors

CA

Cap

@CapSoftware

$200
AB

Abhishek Verma

@w3Abhishek

$0.10