diff --git a/extensions/raycast/assets/cap-icon.png b/extensions/raycast/assets/cap-icon.png new file mode 100644 index 00000000000..5e6aaf08f19 Binary files /dev/null and b/extensions/raycast/assets/cap-icon.png differ diff --git a/extensions/raycast/package.json b/extensions/raycast/package.json new file mode 100644 index 00000000000..b9c01e9ac7f --- /dev/null +++ b/extensions/raycast/package.json @@ -0,0 +1,88 @@ +{ + "$schema": "https://www.raycast.com/schemas/extension.json", + "name": "cap-screen-recorder", + "title": "Cap Screen Recorder", + "description": "Start and stop Cap.so recordings and open your Cap dashboard directly from Raycast.", + "icon": "cap-icon.png", + "author": "CapSoftware", + "categories": ["Media", "Productivity", "Developer Tools"], + "license": "MIT", + "commands": [ + { + "name": "start-recording", + "title": "Start Recording", + "description": "Start a new Cap screen recording with your configured capture target", + "mode": "no-view" + }, + { + "name": "stop-recording", + "title": "Stop Recording", + "description": "Stop the active Cap recording and copy the shareable video link", + "mode": "no-view" + }, + { + "name": "open-dashboard", + "title": "Open Cap Dashboard", + "description": "Open your Cap.so web dashboard in the default browser", + "mode": "no-view" + } + ], + "preferences": [ + { + "name": "recordingMode", + "title": "Recording Mode", + "description": "Cap recording mode (Studio or Instant)", + "type": "dropdown", + "required": false, + "default": "studio", + "data": [ + { "title": "Studio", "value": "studio" }, + { "title": "Instant", "value": "instant" } + ] + }, + { + "name": "captureTargetType", + "title": "Capture Target Type", + "description": "Whether to capture a Screen or a Window by name", + "type": "dropdown", + "required": false, + "default": "screen", + "data": [ + { "title": "Screen", "value": "screen" }, + { "title": "Window", "value": "window" } + ] + }, + { + "name": "targetName", + "title": "Target Screen or Window Name", + "description": "Exact display or window name to capture in Cap", + "type": "textfield", + "required": true + }, + { + "name": "captureSystemAudio", + "title": "Capture System Audio", + "description": "Include system audio when starting a recording", + "type": "checkbox", + "label": "Capture System Audio", + "required": false, + "default": true + }, + { + "name": "dashboardUrl", + "title": "Cap Dashboard URL", + "description": "Your Cap web instance URL (defaults to https://cap.so/dashboard)", + "type": "textfield", + "required": false, + "default": "https://cap.so/dashboard" + } + ], + "dependencies": { + "@raycast/api": "^1.83.1" + }, + "devDependencies": { + "@raycast/eslint-config": "^1.0.11", + "@types/node": "20.8.10", + "typescript": "^5.4.5" + } +} diff --git a/extensions/raycast/src/open-dashboard.ts b/extensions/raycast/src/open-dashboard.ts new file mode 100644 index 00000000000..0a7ecab4285 --- /dev/null +++ b/extensions/raycast/src/open-dashboard.ts @@ -0,0 +1,12 @@ +import { closeMainWindow, getPreferenceValues, open } from "@raycast/api"; + +interface Preferences { + dashboardUrl?: string; +} + +export default async function Command() { + const { dashboardUrl = "https://cap.so/dashboard" } = getPreferenceValues(); + const targetUrl = dashboardUrl.trim() || "https://cap.so/dashboard"; + await closeMainWindow(); + await open(targetUrl); +} diff --git a/extensions/raycast/src/start-recording.ts b/extensions/raycast/src/start-recording.ts new file mode 100644 index 00000000000..492373a55d9 --- /dev/null +++ b/extensions/raycast/src/start-recording.ts @@ -0,0 +1,55 @@ +import { + Toast, + closeMainWindow, + getPreferenceValues, + open, + openExtensionPreferences, + showHUD, + showToast, +} from "@raycast/api"; + +interface Preferences { + recordingMode?: "studio" | "instant"; + captureTargetType?: "screen" | "window"; + targetName: string; + captureSystemAudio?: boolean; +} + +export default async function Command() { + const { + recordingMode = "studio", + captureTargetType = "screen", + targetName, + captureSystemAudio = true, + } = getPreferenceValues(); + + const resolvedTarget = targetName?.trim(); + if (!resolvedTarget) { + await showToast({ + style: Toast.Style.Failure, + title: "Capture target name required", + message: "Set a valid display or window name in extension preferences before recording.", + }); + await openExtensionPreferences(); + return; + } + + const capture_mode = + captureTargetType === "window" + ? { window: resolvedTarget } + : { screen: resolvedTarget }; + + const action = { + start_recording: { + capture_mode, + camera: null, + mic_label: null, + capture_system_audio: Boolean(captureSystemAudio), + mode: recordingMode, + }, + }; + + await closeMainWindow(); + await open(`cap-desktop://action?value=${encodeURIComponent(JSON.stringify(action))}`); + await showHUD(`Cap ${recordingMode} recording started (${resolvedTarget})`); +} diff --git a/extensions/raycast/src/stop-recording.ts b/extensions/raycast/src/stop-recording.ts new file mode 100644 index 00000000000..1b3a0d8f85b --- /dev/null +++ b/extensions/raycast/src/stop-recording.ts @@ -0,0 +1,7 @@ +import { closeMainWindow, open, showHUD } from "@raycast/api"; + +export default async function Command() { + await closeMainWindow(); + await open(`cap-desktop://action?value=${encodeURIComponent(JSON.stringify("stop_recording"))}`); + await showHUD("Cap recording stopped"); +}