Description

Adds deeplink support for controlling recording state and a new Raycast extension.

Changes

  • apps/desktop:
    • Added PauseRecording, ResumeRecording, CycleMicrophone, CycleCamera, StartDefaultRecording to deeplink_actions.rs.
    • Implemented helper functions in lib.rs for pausing, resuming, and cycling inputs.
  • apps/raycast-extension:
    • Created a new Raycast extension cap-control with commands to Start, Stop, Pause, Resume, and Switch inputs.

How to test

  1. Run pnpm dev:desktop.
  2. Open cap-desktop://action?value="start_default_recording" to start.
  3. Open cap-desktop://action?value="pause_recording" to pause.
  4. Open cap-desktop://action?value="resume_recording" to resume.
  5. Open cap-desktop://action?value="cycle_microphone" to switch mic.
  6. Install the Raycast extension from apps/raycast-extension and test commands.

/closes #1540 /claim #1540

Greptile Summary

Added deeplink support for controlling recording state (pause, resume, cycle microphone/camera) and created a new Raycast extension to invoke these deeplinks. The Raycast extension provides commands for starting, stopping, pausing, resuming recordings, and switching camera/microphone inputs.

Major Changes:

  • Added 6 new deeplink actions: StartDefaultRecording, PauseRecording, ResumeRecording, SetMicrophone, SetCamera, CycleMicrophone, CycleCamera
  • Implemented helper functions cycle_mic_input() and cycle_camera_input() in lib.rs
  • Created Raycast extension with 6 commands that trigger deeplinks via cap-desktop:// URLs
  • Reused existing recording::pause_recording() and recording::resume_recording() functions from recording.rs

Critical Issues Found:

  • Multiple syntax errors prevent compilation: duplicate match arms in deeplink_actions.rs:190-200, duplicate permission checks and orphaned braces in lib.rs:635-641, duplicate variable assignment in lib.rs:667-671
  • New commands cycle_mic_input and cycle_camera_input not registered in the command collection, making them uncallable
  • Missing permissions checks in CycleMicrophone and CycleCamera deeplink handlers (inconsistent with SetMicrophone and SetCamera)
  • Documentation has conflicting build instructions

Positive Notes:

  • Proper reuse of existing recording functions maintains event emission consistency
  • Permission checks properly implemented for most operations
  • Clean Raycast extension architecture with proper error handling
  • Good separation of concerns between deeplink parsing and execution

Confidence Score: 1/5

  • This PR cannot be merged - it contains multiple critical syntax errors that prevent compilation
  • Score reflects compilation-breaking syntax errors in both deeplink_actions.rs (duplicate match arms) and lib.rs (duplicate permission checks, orphaned braces, duplicate variable assignments). Additionally, new commands are not registered making them uncallable. These are blocking issues that must be fixed before merge.
  • apps/desktop/src-tauri/src/lib.rs requires immediate attention due to multiple syntax errors. apps/desktop/src-tauri/src/deeplink_actions.rs has duplicate match arms causing compilation failure.

Important Files Changed

Filename Overview
apps/desktop/src-tauri/src/deeplink_actions.rs Added new deeplink actions (pause, resume, cycle inputs). Has critical duplicate match arms causing compilation failure.
apps/desktop/src-tauri/src/lib.rs Added cycle_mic_input and cycle_camera_input functions. Has multiple critical syntax errors: duplicate permission checks, orphaned braces, duplicate variable assignments, and missing command registration.
apps/raycast-extension/README.md Documentation for Raycast extension. Has duplicate build step with conflicting commands.

Sequence Diagram

sequenceDiagram
participant Raycast
participant DeeplinkURL
participant DeeplinkHandler
participant App
participant Recording
participant MicFeed
participant Camera
Note over Raycast,Camera: Start Recording Flow
Raycast->>DeeplinkURL: cap-desktop://action?value="start_default_recording"
DeeplinkURL->>DeeplinkHandler: Parse action
DeeplinkHandler->>DeeplinkHandler: Check screen recording permission
DeeplinkHandler->>App: list_displays()
App-->>DeeplinkHandler: displays[]
DeeplinkHandler->>Recording: start_recording(display, mode=Instant)
Recording-->>Raycast: Recording started
Note over Raycast,Camera: Pause/Resume Flow
Raycast->>DeeplinkURL: cap-desktop://action?value="pause_recording"
DeeplinkURL->>DeeplinkHandler: Parse action
DeeplinkHandler->>Recording: pause_recording()
Recording->>Recording: Emit RecordingEvent::Paused
Recording-->>Raycast: Recording paused
Raycast->>DeeplinkURL: cap-desktop://action?value="resume_recording"
DeeplinkURL->>DeeplinkHandler: Parse action
DeeplinkHandler->>Recording: resume_recording()
Recording->>Recording: Emit RecordingEvent::Resumed
Recording-->>Raycast: Recording resumed
Note over Raycast,Camera: Cycle Microphone Flow
Raycast->>DeeplinkURL: cap-desktop://action?value="cycle_microphone"
DeeplinkURL->>DeeplinkHandler: Parse action
DeeplinkHandler->>App: cycle_mic_input()
App->>App: Check microphone permission
App->>MicFeed: list()
MicFeed-->>App: mic_list[]
App->>App: Find current + select next
App->>App: set_mic_input(next_label)
App-->>Raycast: Microphone switched
Note over Raycast,Camera: Cycle Camera Flow
Raycast->>DeeplinkURL: cap-desktop://action?value="cycle_camera"
DeeplinkURL->>DeeplinkHandler: Parse action
DeeplinkHandler->>App: cycle_camera_input()
App->>App: Check camera permission
App->>Camera: list_cameras()
Camera-->>App: camera_list[]
App->>App: Find current + select next
App->>App: set_camera_input(next_id)
App-->>Raycast: Camera switched
Note over Raycast,Camera: Stop Recording Flow
Raycast->>DeeplinkURL: cap-desktop://action?value="stop_recording"
DeeplinkURL->>DeeplinkHandler: Parse action
DeeplinkHandler->>Recording: stop_recording()
Recording-->>Raycast: Recording stopped

Claim

Total prize pool $200
Total paid $0
Status Pending
Submitted January 24, 2026
Last updated January 24, 2026

Contributors

EX

Excellencedev

@Excellencedev

100%

Sponsors

CA

Cap

@CapSoftware

$200