-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: Add Raycast extension for controlling Cap recordings #1554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Add Raycast extension for controlling Cap recordings #1554
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 files reviewed, 4 comments
| "name": "cap", | ||
| "title": "Cap", | ||
| "description": "Control Cap screen recording from Raycast", | ||
| "icon": "cap-icon.png", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Icon file cap-icon.png is referenced here but isn’t included in this PR; Raycast will fail to load the extension icon unless it exists. Consider adding it or switching to a built-in icon.
| mic_label: string; | ||
| } | ||
|
|
||
| export type DeepLinkAction = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unit enum variants in the Rust DeepLinkAction deserialize from a JSON string (e.g. "stop_recording"), not an object like { stop_recording: {} }. JSON.stringify() will do the right thing if you pass a string here.
| export type DeepLinkAction = | |
| export type DeepLinkAction = | |
| | { start_recording: StartRecordingOptions } | |
| | "stop_recording" | |
| | "pause_recording" | |
| | "resume_recording" | |
| | "toggle_pause_recording" | |
| | { switch_camera: SwitchCameraOptions } | |
| | { switch_microphone: SwitchMicrophoneOptions }; |
| title: "Stopping recording...", | ||
| }); | ||
|
|
||
| await executeCapAction({ stop_recording: {} }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the enum serialization, this should be a JSON string action.
| await executeCapAction({ stop_recording: {} }); | |
| await executeCapAction("stop_recording"); |
| title: "Pausing recording...", | ||
| }); | ||
|
|
||
| await executeCapAction({ pause_recording: {} }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the enum serialization, this should be a JSON string action.
| await executeCapAction({ pause_recording: {} }); | |
| await executeCapAction("pause_recording"); |
| title: "Resuming recording...", | ||
| }); | ||
|
|
||
| await executeCapAction({ resume_recording: {} }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the enum serialization, this should be a JSON string action.
| await executeCapAction({ resume_recording: {} }); | |
| await executeCapAction("resume_recording"); |
| title: "Toggling pause...", | ||
| }); | ||
|
|
||
| await executeCapAction({ toggle_pause_recording: {} }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the enum serialization, this should be a JSON string action.
| await executeCapAction({ toggle_pause_recording: {} }); | |
| await executeCapAction("toggle_pause_recording"); |
| title: "Starting recording...", | ||
| }); | ||
|
|
||
| // For simplicity, using default screen/window |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: this repo avoids code comments; you can drop these without losing clarity.
| // For simplicity, using default screen/window | |
| const capture_mode = |
| // In a real implementation, you'd want to list available screens/windows | ||
| const capture_mode = | ||
| captureType === "screen" | ||
| ? { screen: "Default Screen" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capture_mode uses a display/window name and the backend matches it exactly. Default Screen / Default Window won’t exist, so this command will consistently fail unless you wire it up to real screen/window names (or adjust the deep link/backend to accept a default/ID).
|
|
||
| await executeCapAction({ | ||
| switch_camera: { | ||
| camera: cameraId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The backend expects DeviceOrModelID for camera (serde enum like { "DeviceID": "..." } or { "ModelID": "vid:pid" }), so a raw string here won’t deserialize. Probably want to update the payload/type accordingly (even if you still keep placeholder IDs for now).
Description
This PR adds a Raycast extension that allows users to control Cap screen recordings directly from Raycast using the existing deep link protocol.
Changes
Backend Updates (
apps/desktop/src-tauri/src/deeplink_actions.rs)DeepLinkActionenum to include recording control actions:StopRecording- Stop the current recordingPauseRecording- Pause the current recordingResumeRecording- Resume a paused recordingTogglePauseRecording- Toggle between pause/resume statesSwitchCamera- Switch to a different cameraSwitchMicrophone- Switch to a different microphonecap://actiondeep link protocolRaycast Extension (
extensions/raycast/)Created a complete Raycast extension with the following commands:
Start Recording (
start-recording.tsx)Stop Recording (
stop-recording.tsx)Pause Recording (
pause-recording.tsx)Resume Recording (
resume-recording.tsx)Toggle Pause (
toggle-pause.tsx)Switch Camera (
switch-camera.tsx)Switch Microphone (
switch-microphone.tsx)Supporting Files
utils.ts- TypeScript types and deep link execution helperpackage.json- Extension metadata and dependenciestsconfig.json- TypeScript configurationREADME.md- Documentation for installation and usageTechnical Details
cap://actiondeep link protocolTesting
The extension can be tested by:
cd extensions/raycast && npm installnpm run devBenefits
Future Enhancements
Related Issues
Closes #[issue-number] (if applicable)
Note: This extension requires Cap desktop application to be installed and running. It's designed for macOS users who use Raycast as their launcher.
Greptile Overview
Greptile Summary
Adds a Raycast extension for controlling Cap recordings via the existing
cap://actiondeep link protocol, enabling keyboard-driven recording control without opening the Cap UI.Major changes:
DeepLinkActionenum in Rust backend with 6 new recording control actions (pause, resume, toggle pause, camera/mic switching)pause_recording,resume_recording,set_camera_input,set_mic_input)Issues found:
cap-icon.pngfile will cause extension installation to failConfidence Score: 2/5
extensions/raycast/package.json(missing icon),extensions/raycast/src/start-recording.tsx,extensions/raycast/src/switch-camera.tsx, andextensions/raycast/src/switch-microphone.tsx(hardcoded placeholders)Important Files Changed
cap-icon.pngSequence Diagram
sequenceDiagram participant User participant Raycast participant Extension participant DeepLink participant CapApp participant Recording User->>Raycast: Trigger command Raycast->>Extension: Execute command Extension->>Extension: Build action JSON Extension->>DeepLink: Open cap://action?value={encoded_json} DeepLink->>CapApp: Parse deep link URL CapApp->>CapApp: Deserialize action enum alt Start Recording CapApp->>CapApp: Set camera/mic inputs CapApp->>CapApp: Resolve screen/window name CapApp->>Recording: start_recording() else Stop/Pause/Resume CapApp->>Recording: stop/pause/resume_recording() else Switch Camera/Mic CapApp->>CapApp: set_camera_input/set_mic_input() end CapApp-->>User: Action executed(2/5) Greptile learns from your feedback when you react with thumbs up/down!