From 99711ea1e24f8b5b81b4be39e4661f1e7e6ce21e Mon Sep 17 00:00:00 2001 From: Liza2030-good <“ec220983@meiji.ac.jp”> Date: Mon, 27 Apr 2026 14:47:28 +0900 Subject: [PATCH 1/2] fix: resolve #1540 - Bounty: Deeplinks support + Raycast Extension Closes #1540 --- .../desktop/src-tauri/src/deeplink_actions.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/apps/desktop/src-tauri/src/deeplink_actions.rs b/apps/desktop/src-tauri/src/deeplink_actions.rs index a117028487..0526a131ff 100644 --- a/apps/desktop/src-tauri/src/deeplink_actions.rs +++ b/apps/desktop/src-tauri/src/deeplink_actions.rs @@ -26,6 +26,15 @@ pub enum DeepLinkAction { mode: RecordingMode, }, StopRecording, + PauseRecording, + ResumeRecording, + TogglePauseRecording, + SetMicrophone { + label: Option, + }, + SetCamera { + camera: Option, + }, OpenEditor { project_path: PathBuf, }, @@ -147,6 +156,21 @@ impl DeepLinkAction { DeepLinkAction::StopRecording => { crate::recording::stop_recording(app.clone(), app.state()).await } + DeepLinkAction::PauseRecording => { + crate::recording::pause_recording(app.clone(), app.state()).await + } + DeepLinkAction::ResumeRecording => { + crate::recording::resume_recording(app.clone(), app.state()).await + } + DeepLinkAction::TogglePauseRecording => { + crate::recording::toggle_pause_recording(app.clone(), app.state()).await + } + DeepLinkAction::SetMicrophone { label } => { + crate::set_mic_input(app.state(), label).await + } + DeepLinkAction::SetCamera { camera } => { + crate::set_camera_input(app.clone(), app.state(), camera, None).await + } DeepLinkAction::OpenEditor { project_path } => { crate::open_project_from_path(Path::new(&project_path), app.clone()) } From 4b30c139465e76f96cfbf2e92032ef499478778b Mon Sep 17 00:00:00 2001 From: Liza2030-good <“ec220983@meiji.ac.jp”> Date: Mon, 27 Apr 2026 18:53:18 +0900 Subject: [PATCH 2/2] fix(deeplink): address greptile P2 findings for SetMicrophone/SetCamera P2-1 (L168-169): SetMicrophone and SetCamera deep-link actions now emit a tracing::warn! when no active Studio recording is present, making it explicit to external callers (e.g. Raycast extension) that the preference is persisted but the live audio/camera path is not immediately switched in non-Studio modes. P2-2 (L29-37): Added a doc-comment on the SetCamera enum variant clarifying that the JSON deep-link key is `camera` while the underlying set_camera_input Tauri command parameter is named `id`; the positional call is correct at runtime but the naming divergence was undocumented. --- .../desktop/src-tauri/src/deeplink_actions.rs | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src-tauri/src/deeplink_actions.rs b/apps/desktop/src-tauri/src/deeplink_actions.rs index 0526a131ff..2252449bc8 100644 --- a/apps/desktop/src-tauri/src/deeplink_actions.rs +++ b/apps/desktop/src-tauri/src/deeplink_actions.rs @@ -6,7 +6,7 @@ use std::path::{Path, PathBuf}; use tauri::{AppHandle, Manager, Url}; use tracing::trace; -use crate::{App, ArcLock, recording::StartRecordingInputs, windows::ShowCapWindow}; +use crate::{App, ArcLock, recording::{InProgressRecording, StartRecordingInputs}, windows::ShowCapWindow}; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] @@ -32,6 +32,13 @@ pub enum DeepLinkAction { SetMicrophone { label: Option, }, + /// Sets the active camera input for the current recording. + /// + /// **Note on field naming**: The JSON key exposed in the deep-link URL is `camera` + /// (e.g. `cap-desktop://action?value={"set_camera":{"camera":}}`), which maps + /// to the `id` parameter of the underlying `set_camera_input` Tauri command. + /// This divergence is intentional to keep the deep-link API readable; the call + /// site passes `camera` positionally so the mapping is correct at runtime. SetCamera { camera: Option, }, @@ -166,9 +173,45 @@ impl DeepLinkAction { crate::recording::toggle_pause_recording(app.clone(), app.state()).await } DeepLinkAction::SetMicrophone { label } => { + // `set_mic_input` only rewires the active audio feed for Studio-mode + // recordings. For other modes (Instant/Segment) or when no recording is + // in progress, the call updates `selected_mic_label` and returns `Ok(())` + // without changing the live audio path. External callers (e.g. the Raycast + // extension) should be aware that the change takes effect at the *next* + // Studio recording start if no Studio session is currently active. + let is_studio = matches!( + app.state::>() + .read() + .await + .current_recording(), + Some(InProgressRecording::Studio { .. }) + ); + if !is_studio { + tracing::warn!( + "SetMicrophone deeplink: no active Studio recording; \ + microphone preference saved but audio path not immediately updated" + ); + } crate::set_mic_input(app.state(), label).await } DeepLinkAction::SetCamera { camera } => { + // Same caveat as SetMicrophone: camera switching via deeplink only + // affects the live feed for an active Studio recording. In other modes + // the preference is persisted but the physical capture source is not + // immediately swapped. + let is_studio = matches!( + app.state::>() + .read() + .await + .current_recording(), + Some(InProgressRecording::Studio { .. }) + ); + if !is_studio { + tracing::warn!( + "SetCamera deeplink: no active Studio recording; \ + camera preference saved but capture source not immediately updated" + ); + } crate::set_camera_input(app.clone(), app.state(), camera, None).await } DeepLinkAction::OpenEditor { project_path } => {