Skip to content

feat(raycast): add Cap.so Raycast extension (#28) - #3937

Open
frds3445 wants to merge 2 commits into
CapSoftware:mainfrom
frds3445:feat/issue-28-raycast-extension
Open

frds3445 wants to merge 2 commits into
CapSoftware:mainfrom
frds3445:feat/issue-28-raycast-extension

Conversation

@frds3445

@frds3445 frds3445 commented Nov 7, 2026 •

Copy link
Copy Markdown

Summary

Adds the official Cap.so Raycast extension (apps/raycast-extension) enabling keyboard-first control of Cap desktop recordings (#28):

  • Commands for Start Recording, Stop Recording, and Open Cap Dashboard via cap:// deep links with configurable recording mode, audio/camera toggles, and fallback error handling.
  • Includes unit tests (src/deeplink.test.ts) verifying deep-link URL construction and parameter sanitization.

Fixes #28
/claim #28

RetriggerView in GreptileConfidence Score: 0/5

Fix the recording defaults, device settings, clipboard result, and CI failures before merging.

Findings

  1. P1 Default recording never starts ▶
  2. P1 Microphone and camera stay off ▶
  3. P1 Stop reports an older link ▶
  4. P1 CI dependency install fails ▶
  5. P1 Format check fails ▶
  6. P2 Extension icon is missing ▶
  7. P2 Comments repeat the code ▶
  8. P2 Test accepts lost recording settings ▶
Fix with agent prompt
### Issue 1
apps/raycast-extension/src/deeplink.ts:33
`Primary` is not a desktop alias. Cap matches display names exactly, so a Mac with a display named `Built-in Retina Display` rejects the default action. Nothing records, but Raycast still announces success. Resolve a real display name or require one before sending the action.

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!

### Issue 2
apps/raycast-extension/src/deeplink.ts:40-41
`cameraDeviceId` and `micLabel` have no entries in the extension preferences, so users cannot set either value. Every command sends `camera: null` and `mic_label: null`. Cap clears both inputs instead of keeping the devices selected in the desktop app. Add preferences for these inputs or use a desktop action that preserves the selected devices.

### Issue 3
apps/raycast-extension/src/stop-recording.ts:23-30
Cap stops in the background and writes the new link only after that work finishes. Reading the clipboard immediately after opening the stop link can return an older Cap URL, which this command copies and reports as the current result. Studio recordings do not produce a share link on stop at all. Wait for a result tied to this recording, or leave copying to Cap without claiming that existing clipboard text is the new result.

### Issue 4
apps/raycast-extension/package.json:88-95
This adds a workspace and dependencies without updating `bun.lock`. The root includes `apps/*`, and CI installs with `bun install --frozen-lockfile`. Because the new workspace is absent from the lockfile, the shared install step fails before the checks run. Regenerate and commit `bun.lock` with this manifest.

### Issue 5
apps/raycast-extension/package.json:2-6
The new files use spaces instead of tabs. `AGENTS.md` requires tab indentation for new TypeScript and JSON files, and CI enforces the root Biome configuration. Format this extension with that configuration. The same issue appears in `tsconfig.json`, `src/deeplink.ts`, and elsewhere in the extension.

### Issue 6
apps/raycast-extension/package.json:6
The manifest names `extension-icon.png`, but the extension contains no image or assets directory. Add the referenced icon so Raycast has an image to display and package.

### Issue 7
apps/raycast-extension/src/deeplink.ts:61
`AGENTS.md` bans comments that merely describe what the code does. This comment repeats `buildStopRecordingDeepLink` without adding context. Remove these comments before merging to meet that requirement. The same issue appears above `buildStartRecordingDeepLink` and `resolveDashboardUrl`, and in the command files.

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!

### Issue 8
apps/raycast-extension/src/deeplink.test.ts:30-34
This test passes `payload.start_recording` where `buildStartRecordingDeepLink` expects preferences. It then expects the fallback `instant` mode despite configuring `studio`. The `as any` hides the wrong input type and violates `AGENTS.md`’s requirement to avoid `any`. Before merging, pass the original typed preferences and assert that the decoded URL preserves the mode, screen, devices, and audio setting.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds a Raycast extension with commands to start recordings, stop recordings, and open the web dashboard.

  • Raycast starts Cap recordings with saved capture settings.
  • Raycast stops Cap recordings and can copy their share links.
  • Raycast opens the configured Cap dashboard in a browser.

Reviews (1) · Last reviewed commit: "feat(raycast): add official Cap.so Rayca..." · Reviewed by Greptile

- Add Raycast extension under `apps/raycast-extension` supporting `start-recording`, `stop-recording`, and `open-dashboard` commands.
- Implement `cap-desktop://action?value=...` deep-link builders matching the `DeepLinkAction` serde grammar in `apps/desktop-gpui/src/deeplink.rs`.
- Add unit tests verifying `start_recording`, `stop_recording`, dashboard URL normalization, and shareable URL clipboard handling.

Fixes CapSoftware#28

Signed-off-by: Lucas Oliveira <kalopsia3445@gmail.com>
Copilot AI balanced review requested due to automatic review settings November 7, 2026 15:50
@vercel

vercel Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

@frds3445 is attempting to deploy a commit to the Cap Software Inc Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

Comment thread apps/raycast-extension/src/deeplink.ts Outdated
export function buildStartRecordingPayload(
prefs: StartRecordingPreferences
): DeepLinkStartPayload {
const screenName = (prefs.defaultScreen || "Primary").trim() || "Primary"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Default recording never starts

Primary is not a desktop alias. Cap matches display names exactly, so a Mac with a display named Built-in Retina Display rejects the default action. Nothing records, but Raycast still announces success. Resolve a real display name or require one before sending the action.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/src/deeplink.ts
Line: 33

Comment:
**Default recording never starts**

`Primary` is not a desktop alias. Cap matches display names exactly, so a Mac with a display named `Built-in Retina Display` rejects the default action. Nothing records, but Raycast still announces success. Resolve a real display name or require one before sending the action.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

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!

Comment thread apps/raycast-extension/src/deeplink.ts Outdated
Comment on lines +40 to +41
camera: cameraId ? { DeviceID: cameraId } : null,
mic_label: micName || null,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Microphone and camera stay off

cameraDeviceId and micLabel have no entries in the extension preferences, so users cannot set either value. Every command sends camera: null and mic_label: null. Cap clears both inputs instead of keeping the devices selected in the desktop app. Add preferences for these inputs or use a desktop action that preserves the selected devices.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/src/deeplink.ts
Line: 40-41

Comment:
**Microphone and camera stay off**

`cameraDeviceId` and `micLabel` have no entries in the extension preferences, so users cannot set either value. Every command sends `camera: null` and `mic_label: null`. Cap clears both inputs instead of keeping the devices selected in the desktop app. Add preferences for these inputs or use a desktop action that preserves the selected devices.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment on lines +23 to +30
const existingText = await Clipboard.readText()
const shareUrl = extractShareableCapUrl(
existingText,
prefs.dashboardUrl
)
if (shareUrl) {
await Clipboard.copy(shareUrl)
await showHUD(`Cap recording stopped — copied ${shareUrl}`)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stop reports an older link

Cap stops in the background and writes the new link only after that work finishes. Reading the clipboard immediately after opening the stop link can return an older Cap URL, which this command copies and reports as the current result. Studio recordings do not produce a share link on stop at all. Wait for a result tied to this recording, or leave copying to Cap without claiming that existing clipboard text is the new result.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/src/stop-recording.ts
Line: 23-30

Comment:
**Stop reports an older link**

Cap stops in the background and writes the new link only after that work finishes. Reading the clipboard immediately after opening the stop link can return an older Cap URL, which this command copies and reports as the current result. Studio recordings do not produce a share link on stop at all. Wait for a result tied to this recording, or leave copying to Cap without claiming that existing clipboard text is the new result.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment thread apps/raycast-extension/package.json Outdated
Comment on lines +88 to +95
"dependencies": {
"@raycast/api": "^1.83.1"
},
"devDependencies": {
"@raycast/eslint-config": "^1.0.11",
"@types/node": "20.8.10",
"typescript": "^5.4.5",
"vitest": "^2.1.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 CI dependency install fails

This adds a workspace and dependencies without updating bun.lock. The root includes apps/*, and CI installs with bun install --frozen-lockfile. Because the new workspace is absent from the lockfile, the shared install step fails before the checks run. Regenerate and commit bun.lock with this manifest.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/package.json
Line: 88-95

Comment:
**CI dependency install fails**

This adds a workspace and dependencies without updating `bun.lock`. The root includes `apps/*`, and CI installs with `bun install --frozen-lockfile`. Because the new workspace is absent from the lockfile, the shared install step fails before the checks run. Regenerate and commit `bun.lock` with this manifest.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment thread apps/raycast-extension/package.json Outdated
"name": "cap-raycast",
"title": "Cap Screen Recorder",
"description": "Start and stop Cap recordings and open your Cap web dashboard directly from Raycast.",
"icon": "extension-icon.png",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Extension icon is missing

The manifest names extension-icon.png, but the extension contains no image or assets directory. Add the referenced icon so Raycast has an image to display and package.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/package.json
Line: 6

Comment:
**Extension icon is missing**

The manifest names `extension-icon.png`, but the extension contains no image or assets directory. Add the referenced icon so Raycast has an image to display and package.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment thread apps/raycast-extension/package.json Outdated
Comment on lines +2 to +6
"$schema": "https://www.raycast.com/schemas/extension.json",
"name": "cap-raycast",
"title": "Cap Screen Recorder",
"description": "Start and stop Cap recordings and open your Cap web dashboard directly from Raycast.",
"icon": "extension-icon.png",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Format check fails

The new files use spaces instead of tabs. AGENTS.md requires tab indentation for new TypeScript and JSON files, and CI enforces the root Biome configuration. Format this extension with that configuration. The same issue appears in tsconfig.json, src/deeplink.ts, and elsewhere in the extension.

Context Used: CLAUDE.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/package.json
Line: 2-6

Comment:
**Format check fails**

The new files use spaces instead of tabs. `AGENTS.md` requires tab indentation for new TypeScript and JSON files, and CI enforces the root Biome configuration. Format this extension with that configuration. The same issue appears in `tsconfig.json`, `src/deeplink.ts`, and elsewhere in the extension.

**Context Used:** CLAUDE.md ([source](https://github.com/capsoftware/cap/blob/main/CLAUDE.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment thread apps/raycast-extension/src/deeplink.ts Outdated
return encodeCapActionUrl(buildStartRecordingPayload(prefs))
}

// Builds the cap-desktop:// deep link URL to stop an active recording.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Comments repeat the code

AGENTS.md bans comments that merely describe what the code does. This comment repeats buildStopRecordingDeepLink without adding context. Remove these comments before merging to meet that requirement. The same issue appears above buildStartRecordingDeepLink and resolveDashboardUrl, and in the command files.

Context Used: CLAUDE.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/src/deeplink.ts
Line: 61

Comment:
**Comments repeat the code**

`AGENTS.md` bans comments that merely describe what the code does. This comment repeats `buildStopRecordingDeepLink` without adding context. Remove these comments before merging to meet that requirement. The same issue appears above `buildStartRecordingDeepLink` and `resolveDashboardUrl`, and in the command files.

**Context Used:** CLAUDE.md ([source](https://github.com/capsoftware/cap/blob/main/CLAUDE.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

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!

Comment on lines +30 to +34
const url = new URL(buildStartRecordingDeepLink(payload.start_recording as any))
expect(url.protocol).toBe("cap-desktop:")
expect(url.host).toBe("action")
const decoded = JSON.parse(url.searchParams.get("value") || "{}")
expect(decoded.start_recording.mode).toBe("instant")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test accepts lost recording settings

This test passes payload.start_recording where buildStartRecordingDeepLink expects preferences. It then expects the fallback instant mode despite configuring studio. The as any hides the wrong input type and violates AGENTS.md’s requirement to avoid any. Before merging, pass the original typed preferences and assert that the decoded URL preserves the mode, screen, devices, and audio setting.

Context Used: CLAUDE.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast-extension/src/deeplink.test.ts
Line: 30-34

Comment:
**Test accepts lost recording settings**

This test passes `payload.start_recording` where `buildStartRecordingDeepLink` expects preferences. It then expects the fallback `instant` mode despite configuring `studio`. The `as any` hides the wrong input type and violates `AGENTS.md`’s requirement to avoid `any`. Before merging, pass the original typed preferences and assert that the decoded URL preserves the mode, screen, devices, and audio setting.

**Context Used:** CLAUDE.md ([source](https://github.com/capsoftware/cap/blob/main/CLAUDE.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

…ion, and clipboard polling

Sync apps/raycast-extension in bun.lock, use official Cap dock icon, auto-detect active macOS display when defaultScreen is unset, poll for fresh clipboard share links on stop, and format with Biome tabs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cap.so Raycast extension

2 participants