Add Cap recording deeplinks and Raycast controls#1842
Add Cap recording deeplinks and Raycast controls#1842partyplatter08-lab wants to merge 2 commits into
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| DeepLinkAction::SetMicrophone { label } => { | ||
| pause_for_input_change(app).await?; | ||
| crate::set_mic_input(app.state(), label).await | ||
| } | ||
| DeepLinkAction::SetCamera { selector } => { | ||
| pause_for_input_change(app).await?; | ||
| let camera_id = selector | ||
| .as_ref() | ||
| .map(|selector| resolve_camera_selector(selector, &CameraIdentity::current())) | ||
| .transpose()?; | ||
| crate::set_camera_input(app.clone(), app.state(), camera_id, None).await | ||
| } |
There was a problem hiding this comment.
Recording left paused after failed device switch
pause_for_input_change pauses an active recording before the switch, but there is no corresponding resume if the subsequent operation fails. If resolve_camera_selector returns an error (e.g. unknown device ID passed by an external caller), or if set_camera_input / set_mic_input fails, the recording silently remains paused with no way for the deeplink caller to recover it. The same issue exists in SetMicrophone (line 373). Consider wrapping the device-switch call in a guard that resumes the recording on any error path.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src-tauri/src/deeplink_actions.rs
Line: 372-383
Comment:
**Recording left paused after failed device switch**
`pause_for_input_change` pauses an active recording before the switch, but there is no corresponding resume if the subsequent operation fails. If `resolve_camera_selector` returns an error (e.g. unknown device ID passed by an external caller), or if `set_camera_input` / `set_mic_input` fails, the recording silently remains paused with no way for the deeplink caller to recover it. The same issue exists in `SetMicrophone` (line 373). Consider wrapping the device-switch call in a guard that resumes the recording on any error path.
How can I resolve this? If you propose a fix, please make it concise.| } catch (loadError) { | ||
| const message = | ||
| loadError instanceof Error ? loadError.message : String(loadError); | ||
| if (!cancelled) { | ||
| setItems([]); | ||
| setError(message); | ||
| } | ||
| await showToast({ | ||
| style: Toast.Style.Failure, | ||
| title: "Failed to enumerate devices", | ||
| message, | ||
| }); |
There was a problem hiding this comment.
showToast is called outside the if (!cancelled) guard, so it can fire after the Raycast command has already been dismissed. The state updates above it are correctly guarded — the toast should be too, to stay consistent and avoid surfacing stale error notifications.
| } catch (loadError) { | |
| const message = | |
| loadError instanceof Error ? loadError.message : String(loadError); | |
| if (!cancelled) { | |
| setItems([]); | |
| setError(message); | |
| } | |
| await showToast({ | |
| style: Toast.Style.Failure, | |
| title: "Failed to enumerate devices", | |
| message, | |
| }); | |
| } catch (loadError) { | |
| const message = | |
| loadError instanceof Error ? loadError.message : String(loadError); | |
| if (!cancelled) { | |
| setItems([]); | |
| setError(message); | |
| await showToast({ | |
| style: Toast.Style.Failure, | |
| title: "Failed to enumerate devices", | |
| message, | |
| }); | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/raycast/src/switch-device.tsx
Line: 21-32
Comment:
`showToast` is called outside the `if (!cancelled)` guard, so it can fire after the Raycast command has already been dismissed. The state updates above it are correctly guarded — the toast should be too, to stay consistent and avoid surfacing stale error notifications.
```suggestion
} catch (loadError) {
const message =
loadError instanceof Error ? loadError.message : String(loadError);
if (!cancelled) {
setItems([]);
setError(message);
await showToast({
style: Toast.Style.Failure,
title: "Failed to enumerate devices",
message,
});
}
```
How can I resolve this? If you propose a fix, please make it concise.
/claim #1540
Summary
cap-desktop://record/*deeplinks for starting, stopping, pausing, resuming, and toggling pausecap-desktop://device/*deeplinks for microphone and camera switching, including camera model ID, device ID, label, and off selectorsValidation
pnpm exec biome check apps/raycast/package.json apps/raycast/tsconfig.json apps/raycast/README.md apps/raycast/src apps/raycast/scripts apps/desktop/src-tauri/DEEPLINKS.mdpnpm --dir apps/raycast exec tsc --noEmit --pretty falsepnpm --dir apps/raycast run smoke:devicespnpm --dir apps/raycast run lintGreptile Summary
This PR adds semantic
cap-desktop://deeplinks for recording control (start, stop, pause, resume, toggle-pause) and device switching (microphone by label, camera by model ID / device ID / label), plus a new Raycast extension that wraps those deeplinks into two commands. The Rust deeplink parser is substantially rewritten from a single legacyactionhandler into a routed URL parser with comprehensive unit tests.deeplink_actions.rsis refactored into a proper URL router (record/*,device/*) with new action variants, case-insensitive camera resolution, and aCameraSelectorenum; the existingaction?value=legacy path is preserved unchanged.lib.rsextracts thestart_recording_from_saved_settingshelper so it can be shared between theRequestStartRecordingevent handler and the new deeplinkStartSavedRecordingaction.apps/raycast/introduces a self-contained Raycast extension with a recording-control list command, a device-switching list command backed by a heuristicsystem_profilerparser, and a smoke test script.Confidence Score: 3/5
The recording-control and Raycast extension changes are generally well-structured, but a device-switch failure over a deeplink can leave an active recording stuck in a paused state with no recovery path.
The
pause_for_input_changehelper pauses a live recording before switching camera or microphone, but there is no matching resume on the error paths that follow it. An external caller who sends an unknown camera device_id or model_id will find their recording silently paused and never auto-resumed.apps/desktop/src-tauri/src/deeplink_actions.rs — the SetCamera and SetMicrophone execute arms need an error-path resume guard.
Important Files Changed
pause_for_input_changehas already paused the recording, the recording remains stuck paused.start_recording_from_saved_settingslogic into a namedpub(crate)function, reused by bothRequestStartRecordingand the new deeplinkStartSavedRecordingaction. Refactor is semantically equivalent to the original.system_profilerparser for enumerating microphones and cameras into deeplink URLs; well-guarded against false positives viahasChildObjects, name-match filters, and URL-based deduplication for cameras.showToastin the error path fires outside thecancelledcheck, potentially showing a stale toast after the command is dismissed.openCapDeeplinkhelper with error handling via Raycast Toast — straightforward and correct.buildDeviceItemsFromSystemProfilercovering microphone, model-ID camera, device-ID camera, label-only camera, false-positive filtering, and off entries — good coverage of the heuristic parser.idalias fordevice_id, error handling notes, and how the routes map to existing Tauri commands.Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat: add Cap deeplink controls and Rayc..." | Re-trigger Greptile