Files
thewh1teagle--vibe/handoff-wasm/Cargo.toml
T
thewh1teagle 18160c22f7 Add phone handoff: record on a phone, transcribe on the desktop (#1411)
Pairs a phone to the desktop by QR code, then sends recordings over an
iroh connection for Sona to transcribe, streaming the transcript back.

The phone side is a PWA deployed alongside the website at /vibe/phone/.
Browsers cannot hole-punch, so its traffic is relayed — end-to-end
encrypted throughout, so the relay only ever sees ciphertext.

Desktop:
- iroh endpoint behind the `vibe/handoff/0` ALPN, off by default and
  restored on startup only when the user previously enabled it
- pairing token compared in constant time; identity persisted so the QR
  survives restarts
- incoming audio saved to ~/Documents/Vibe like any other recording, and
  written to the transcripts store so it lands in Recents
- Settings -> Phone section with a self-contained QR encoder, reachable
  from a phone icon in the sidebar footer
- launch-at-startup setting via tauri-plugin-autostart, default off

Phone PWA:
- React + Vite on the desktop app's UI stack
- language list and model come from the desktop over the wire, never
  hardcoded, so the picker always matches the loaded model
- MediaRecorder mime negotiation for Safari, screen wake lock, and an
  install-to-home-screen hint

Analytics cover adoption and success rate without sending transcripts,
filenames, paths, or the chosen language.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 18:47:57 +03:00

35 lines
847 B
TOML

[package]
name = "handoff-wasm"
version = "0.1.0"
edition = "2021"
publish = false
# Standalone crate: an empty `[workspace]` table detaches this crate from the
# repo-root workspace so the desktop build never tries to compile it.
[workspace]
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
iroh = { version = "1.0.0", default-features = false, features = ["tls-ring"] }
n0-future = "0.3"
anyhow = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["fmt"] }
tracing-subscriber-wasm = "0.1"
async-channel = "2"
getrandom = { version = "0.3", features = ["wasm_js"] }
wasm-bindgen = "=0.2.122"
wasm-bindgen-futures = "0.4.50"
console_error_panic_hook = "0.1"
wasm-streams = "0.5"
serde-wasm-bindgen = "0.6"
[profile.release]
opt-level = "s"
lto = true