Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9187572
feat: add deeplink parser and dispatcher utility
SyedHannanMehdi Mar 29, 2026
f2943e7
feat: add main-process deeplink handler (open-url + second-instance)
SyedHannanMehdi Mar 29, 2026
a70b0e3
feat: add useDeeplinks renderer hook for recording actions
SyedHannanMehdi Mar 29, 2026
a5e4e7e
feat(raycast): add extension package.json with all commands
SyedHannanMehdi Mar 29, 2026
f88468f
feat(raycast): add tsconfig
SyedHannanMehdi Mar 29, 2026
71c898c
feat(raycast): add deeplink builder/trigger utility
SyedHannanMehdi Mar 29, 2026
f869f25
feat(raycast): start-recording command
SyedHannanMehdi Mar 29, 2026
9e0fd5b
feat(raycast): stop-recording command
SyedHannanMehdi Mar 29, 2026
feee9f9
fix: align package.json commands with existing command files, add mis…
SyedHannanMehdi Mar 29, 2026
31202cb
feat: add pause-recording Raycast command
SyedHannanMehdi Mar 29, 2026
1324deb
feat: add resume-recording Raycast command
SyedHannanMehdi Mar 29, 2026
5f1e7b4
feat: add toggle-recording Raycast command
SyedHannanMehdi Mar 29, 2026
a40873c
feat: add restart-recording Raycast command
SyedHannanMehdi Mar 29, 2026
9133d59
fix: remove Electron imports from deeplinks.ts — make parseDeeplink a…
SyedHannanMehdi Mar 29, 2026
816fd40
fix: rewrite deeplink-handler.ts using @tauri-apps/plugin-deep-link i…
SyedHannanMehdi Mar 29, 2026
891217e
fix: rewrite useDeeplinks.ts as SolidJS hook using @tauri-apps/plugin…
SyedHannanMehdi Mar 29, 2026
72d07d3
feat: add deeplink handler module for Cap recording actions
SyedHannanMehdi Mar 29, 2026
e1d1a5d
feat: expose deeplink module from lib.rs
SyedHannanMehdi Mar 29, 2026
9d6a863
feat: add Tauri capability config for deep-link plugin
SyedHannanMehdi Mar 29, 2026
bf76e25
docs: document tauri.conf.json deep-link patch required
SyedHannanMehdi Mar 29, 2026
492fce4
feat: add frontend deeplink listener that maps actions to Tauri commands
SyedHannanMehdi Mar 29, 2026
0338d22
feat: add Tauri command wrapper for deep-link handler
SyedHannanMehdi Mar 29, 2026
aefcf07
feat: add Raycast extension package.json with all Cap commands
SyedHannanMehdi Mar 29, 2026
9352cdb
feat: add tsconfig for Raycast extension
SyedHannanMehdi Mar 29, 2026
3492869
feat: add deeplink utility helpers for Raycast extension
SyedHannanMehdi Mar 29, 2026
56e4731
fix(desktop): make deeplinks.ts a pure helper — remove Electron imports
SyedHannanMehdi Mar 29, 2026
c75d57b
fix(desktop): rewrite deeplink-handler.ts using @tauri-apps/plugin-de…
SyedHannanMehdi Mar 29, 2026
a2a36ca
fix(desktop): rewrite useDeeplinks as a SolidJS hook using @tauri-app…
SyedHannanMehdi Mar 29, 2026
8e7dbe9
feat(raycast): add pause-recording command
SyedHannanMehdi Mar 29, 2026
548b5cb
feat(raycast): add resume-recording command
SyedHannanMehdi Mar 29, 2026
f78fa27
feat(raycast): add toggle-recording command
SyedHannanMehdi Mar 29, 2026
b3b0e9c
feat(raycast): add restart-recording command
SyedHannanMehdi Mar 29, 2026
2a78e4f
feat(raycast): add switch-mode command
SyedHannanMehdi Mar 29, 2026
0149842
fix(desktop): extend deeplink parser to handle switch-mode action wit…
SyedHannanMehdi Mar 29, 2026
096158e
feat: add deeplink handler module
SyedHannanMehdi Mar 30, 2026
4a25c0a
feat: add deeplink tauri commands
SyedHannanMehdi Mar 30, 2026
c41b5b0
feat: add useDeeplinks React hook
SyedHannanMehdi Mar 30, 2026
6873002
feat: add Raycast extension package.json
SyedHannanMehdi Mar 30, 2026
d65afde
feat: add deeplink utility for Raycast extension
SyedHannanMehdi Mar 30, 2026
3c00200
feat: add start-recording command
SyedHannanMehdi Mar 30, 2026
a0307b9
feat: add stop-recording command
SyedHannanMehdi Mar 30, 2026
dc3d13e
feat: add pause-recording command
SyedHannanMehdi Mar 30, 2026
cf410a8
feat: add resume-recording command
SyedHannanMehdi Mar 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apps/desktop/src-tauri/capabilities/deeplink.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "deeplink",
"description": "Capability for deep-link URL scheme handling",
"windows": ["main", "camera", "in-progress-recording", "notifications", "recording-permissions", "upgrade", "prev-recordings", "window-caption"],
"permissions": [
"deep-link:default"
]
}
103 changes: 103 additions & 0 deletions apps/desktop/src-tauri/src/deeplink.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::sync::Arc;
use tauri::{AppHandle, Emitter, Manager};
use url::Url;

use crate::recording::{PauseStopRecording, RecordingState};

/// Parse and handle a `cap://` deep-link URL.
///
/// Supported routes:
/// cap://recording/start
/// cap://recording/stop
/// cap://recording/pause
/// cap://recording/resume
/// cap://recording/restart
/// cap://recording/screenshot
/// cap://mic/set?deviceId=<id>
/// cap://camera/set?deviceId=<id>
/// cap://camera/toggle (show / hide)
/// cap://mode/set?mode=<mode> (e.g. "hd", "screenshot")
pub fn handle_deeplink(app: &AppHandle, url: &str) {
let parsed = match Url::parse(url) {
Ok(u) => u,
Err(e) => {
eprintln!("[deeplink] Failed to parse URL `{}`: {}", url, e);
return;
}
};

// Only accept our custom scheme
if parsed.scheme() != "cap" {
eprintln!("[deeplink] Unexpected scheme: {}", parsed.scheme());
return;
}

let host = parsed.host_str().unwrap_or("");
let path = parsed.path().trim_start_matches('/');
let route = if path.is_empty() {
host.to_string()
} else {
format!("{}/{}", host, path)
};

println!("[deeplink] Handling route: {}", route);

match route.as_str() {
// ── Recording controls ──────────────────────────────────────────────
"recording/start" => {
app.emit("deeplink-recording-start", ()).ok();
}
"recording/stop" => {
app.emit("deeplink-recording-stop", ()).ok();
}
"recording/pause" => {
app.emit("deeplink-recording-pause", ()).ok();
}
"recording/resume" => {
app.emit("deeplink-recording-resume", ()).ok();
}
"recording/restart" => {
app.emit("deeplink-recording-restart", ()).ok();
}
"recording/screenshot" => {
app.emit("deeplink-screenshot", ()).ok();
}

// ── Microphone ──────────────────────────────────────────────────────
"mic/set" => {
let device_id = query_param(&parsed, "deviceId");
app.emit("deeplink-mic-set", device_id).ok();
}

// ── Camera ──────────────────────────────────────────────────────────
"camera/set" => {
let device_id = query_param(&parsed, "deviceId");
app.emit("deeplink-camera-set", device_id).ok();
}
"camera/toggle" => {
app.emit("deeplink-camera-toggle", ()).ok();
}

// ── Mode ────────────────────────────────────────────────────────────
"mode/set" => {
let mode = query_param(&parsed, "mode");
app.emit("deeplink-mode-set", mode).ok();
}

// ── Status (returns JSON via a window event) ─────────────────────
"recording/status" => {
// The frontend will respond via the `recording-status-response` event
app.emit("deeplink-recording-status", ()).ok();
}

unknown => {
eprintln!("[deeplink] Unknown route: {}", unknown);
}
}
}

fn query_param(url: &Url, key: &str) -> Option<String> {
url.query_pairs()
.find(|(k, _)| k == key)
.map(|(_, v)| v.into_owned())
}
12 changes: 12 additions & 0 deletions apps/desktop/src-tauri/src/deeplink_commands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// Tauri commands exposed to the frontend for programmatic deep-link testing
/// and for querying current recording state.
use tauri::{command, AppHandle};

use crate::deeplink::handle_deeplink;

/// Trigger any `cap://` deep-link from the frontend (useful for tests / debugging).
#[command]
pub async fn trigger_deeplink(app: AppHandle, url: String) -> Result<(), String> {
handle_deeplink(&app, &url);
Ok(())
}
Loading