[package] name = "OpenHuman" version = "0.58.1" description = "OpenHuman - AI-powered Super Assistant" authors = ["OpenHuman"] edition = "2021" default-run = "OpenHuman" autobins = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] # The `_lib` suffix may seem redundant but it is necessary # to make the lib name unique and wouldn't conflict with the bin name. # This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 name = "openhuman" crate-type = ["staticlib", "cdylib", "rlib"] [[bin]] name = "OpenHuman" path = "src/main.rs" [build-dependencies] tauri-build = { version = "2", features = [] } serde_json = "1" [dependencies] # Tauri core and plugins. # # The only supported runtime is CEF (Chromium Embedded Framework) via # `tauri-runtime-cef` — CI builds, release installers, and local `cargo tauri # dev` all run against CEF. The `[patch.crates-io]` block at the bottom of this # file pins every tauri crate and plugin to the `feat/cef` branch on github so # CEF symbols are in scope, and `cef-dll-sys`'s build script auto-downloads the # Chromium runtime for the current target on first build. tauri = { version = "2.10", default-features = false, features = [ "cef", "common-controls-v6", "devtools", "macos-private-api", "tray-icon", "unstable", "webview-data-url", ] } tauri-plugin-deep-link = "2.0.0" tauri-plugin-global-shortcut = "2" tauri-plugin-notification = { path = "vendor/tauri-plugin-notification" } tauri-plugin-opener = "2" # Prevents a second launch from racing into CEF init and hitting the # `cef::initialize(...) != 1` cache-lock panic seen in production # (Sentry OPENHUMAN-TAURI-A). The plugin acquires a per-identifier # lock before any tauri::Builder work happens, so the secondary # process exits cleanly after handing its argv to the primary. The `deep-link` # feature forwards second-launch deep-link payloads to the primary instance on # Windows/Linux, which is required for hot-instance OAuth callbacks. tauri-plugin-single-instance = { version = "2", features = ["deep-link"] } # Auto-update for the Tauri shell itself. The core sidecar already has its own # updater (see `core_update.rs`); this plugin handles the .app/.exe/.AppImage # bundle. Both are needed because shipping a new RPC method requires both # pieces in lockstep, and on macOS the .app bundle is what carries TCC grants. tauri-plugin-updater = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" toml = "0.8" directories = "5" # Native Save-As file dialog for artifact export (#3162). default-features # off + xdg-portal keeps Linux off GTK (the Downloads-copy fallback covers # headless CI where no portal is available); tokio drives the async backend. rfd = { version = "0.15", default-features = false, features = ["xdg-portal", "tokio"] } # Used by gmail/cdp_fetch for decoding binary IO.read chunks. Base64 is # only emitted by CDP IO.read when the stream contains non-UTF-8 bytes, # but we opt into the feature to stay robust against unexpected responses. base64 = "0.22" tokio = { version = "1", features = ["rt-multi-thread", "process", "sync", "time", "net"] } tokio-util = { version = "0.7", features = ["rt"] } # WebSocket client + server for two uses: # - Client: Chrome DevTools Protocol connections to the embedded CEF # instance over `--remote-debugging-port=9222` (IndexedDB reads, # `Runtime.evaluate` for the WhatsApp recipe, DOMSnapshot / Network # calls for the Gmail connector). # - Server: the `webview_apis` bridge at 127.0.0.1 that accepts # JSON-RPC frames from the core sidecar so core-side handlers can # reach the live-webview connectors via CDP. tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "handshake"] } url = "2" futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] } reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } rand = "0.9" hex = "0.4" # Tauri's vendored dev-server proxy (see `vendor/tauri-cef/.../protocol/tauri.rs`) # builds a reqwest 0.13 client that requires a process-wide rustls # `CryptoProvider`. Without one, `ClientBuilder::build()` panics with # "No provider set" the first time `tauri dev` proxies a request. We install # the ring provider at startup in `lib.rs::run()`. rustls = { version = "0.23", default-features = false, features = ["ring"] } log = "0.4" env_logger = "0.11" # Sentry for the Tauri shell (desktop host) process — separate Sentry project # from the React frontend and the Rust core sidecar. DSN is baked at compile # time via `option_env!("OPENHUMAN_TAURI_SENTRY_DSN")` in `lib.rs::run()` and # can be overridden at runtime via the same env var. Feature set mirrors the # core sidecar (`Cargo.toml` at repo root) minus `tracing` since the shell # uses `log` + `env_logger`. sentry = { version = "0.47.0", default-features = false, features = ["backtrace", "contexts", "panic", "debug-images", "reqwest", "rustls"] } # Used by the imessage_scanner module. anyhow = "1.0" parking_lot = "0.12" chrono = "0.4" async-trait = "0.1" # Mascot fake-camera pipeline (meet_call): rasterizes the OpenHuman # mascot SVG to a PNG once, converts it to a YUV420 Y4M frame, and # points CEF's `--use-file-for-fake-video-capture` flag at the cached # file so Meet sees the mascot as the agent's webcam. Pure Rust, no # system codecs needed. resvg = { version = "0.45", default-features = false, features = ["text", "system-fonts"] } tiny-skia = "0.11" # CEF + tauri-runtime-cef dependencies (always required). # `tauri-runtime-cef::notification::register` is how we hook native Web # Notification interception per webview, and `cef::Browser` is what we downcast # from the boxed handle returned by `Webview::with_webview`. tauri-runtime-cef # isn't published to crates.io — we vendor the whole tauri fork as a submodule # at `vendor/tauri-cef` and reference the crate by path. tauri-runtime-cef = { path = "vendor/tauri-cef/crates/tauri-runtime-cef" } cef = { version = "=146.4.1", default-features = false } # Core domain logic, embedded in-process so the core's HTTP/JSON-RPC server # runs as a tokio task inside the Tauri host. Avoids the orphan-sidecar class # of bugs (PR #1061: Cmd+Q leaving `openhuman-core` and CEF helpers behind) # by tying the core's lifetime to the GUI process. The existing port-7788 # probe in `core_process::ensure_running` still attaches to a running # `openhuman-core run` harness when one is already listening. openhuman_core = { path = "../..", package = "openhuman", default-features = false } [target.'cfg(unix)'.dependencies] nix = { version = "0.29", default-features = false, features = ["signal", "user"] } [target.'cfg(target_os = "macos")'.dependencies] objc2 = "0.6" objc2-app-kit = "0.3.2" mac-notification-sys = "0.6" # iMessage scanner reads ~/Library/Messages/chat.db read-only on macOS. rusqlite = { version = "0.37", features = ["bundled"] } objc2-user-notifications = "0.3.2" block2 = "0.6.2" objc2-foundation = { version = "0.3.2", features = ["NSTimer", "block2"] } # Native WKWebView host for the floating mascot window — bypasses CEF # (which can't render transparent windowed-mode browsers). objc2-web-kit = { version = "0.3.2", features = ["block2"] } [target.'cfg(target_os = "linux")'.dependencies] notify-rust = { version = "4", default-features = false, features = ["dbus"] } [target.'cfg(target_os = "windows")'.dependencies] # AttachConsole — re-attach to the parent shell when the binary runs as a CLI # (the `core` subcommand). The main binary itself is windows-subsystem so # launching the Tauri app from Explorer does not pop a console; the helper # CEF subprocess re-execs inherit that same subsystem. windows-sys = { version = "0.59", features = [ "Win32_System_Console", "Win32_Foundation", # EnumWindows / ShowWindow / SW_HIDE / SW_SHOW used by the main-window # close handler. tauri-runtime-cef's window.hide() / minimize() target a # cef::Window internal handle, not the visible Chrome_WidgetWin_1 # top-level frame, so we walk the OS window list ourselves (#1607). "Win32_UI_WindowsAndMessaging", # CreateMutexW / CloseHandle — used by the pre-CEF single-instance guard # (see run() in lib.rs) that detects a second launch before CefRuntime::init # fires (Sentry OPENHUMAN-TAURI-A). # Win32_Security is required because CreateMutexW's SECURITY_ATTRIBUTES # parameter is gated behind it in windows-sys 0.59. "Win32_System_Threading", "Win32_Security", # CreateToolhelp32Snapshot / Process32FirstW / Process32NextW — used by the # pre-CEF cache-lock wait (cef_singleton_wait.rs) that counts straggler # processes from a dying prior instance before cef::initialize (TAURI-RUST-F). "Win32_System_Diagnostics_ToolHelp", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_Pipes", # RegOpenKeyExW / RegQueryValueExW / RegCloseKey — used by # deep_link_registration_check::verify_protocol_registration to read # back HKCU\Software\Classes\openhuman\shell\open\command after # `tauri-plugin-deep-link::register_all` so a silently-failed write # surfaces in the Sentry / user logs (issue #2699). "Win32_System_Registry", ] } [features] default = [] # `custom-protocol` switches Tauri from `devUrl` (vite dev server) to the # bundled `frontendDist` served via `tauri://localhost`. `cargo tauri build` # turns this on automatically for release; do not put it in `default` or # every `pnpm dev:app` will silently load the production bundle. DO NOT REMOVE!! custom-protocol = ["tauri/custom-protocol"] sandbox-bubblewrap = [] # Forwarded to the core crate to expose `openhuman.test_reset`. Off by # default; the E2E build flips it on via `cargo tauri build --features # e2e-test-support`. See app/scripts/e2e-build.sh. e2e-test-support = ["openhuman_core/e2e-test-support"] [patch.crates-io] # `cargo tauri build` resolves dependencies from this manifest, so the # workspace-level whisper-rs-sys patch is not applied here. The fork forces # whisper.cpp to use MSVC's static runtime (/MT), matching CEF and avoiding # LNK2038/LNK1169 CRT conflicts on Windows. whisper-rs-sys = { git = "https://github.com/tinyhumansai/whisper-rs-sys.git", branch = "main" } # CEF support lives on the `feat/cef` branch of tauri-apps/tauri. We carry our # own fork at tinyhumansai/tauri-cef on `feat/cef-notification-intercept` which # adds native Web Notifications interception — `tauri-runtime-cef::notification` # (browser-process callback registry) plus `cef-helper` patching `window.Notification` # and `ServiceWorkerRegistration.prototype.showNotification` from the renderer # side. The fork is vendored as a git submodule at `vendor/tauri-cef`; the # submodule's recorded commit is the pin. # # Plugins still patch from upstream tauri-apps/plugins-workspace@feat/cef — the # fork is tauri-only. tauri = { path = "vendor/tauri-cef/crates/tauri" } tauri-build = { path = "vendor/tauri-cef/crates/tauri-build" } tauri-utils = { path = "vendor/tauri-cef/crates/tauri-utils" } tauri-macros = { path = "vendor/tauri-cef/crates/tauri-macros" } tauri-runtime = { path = "vendor/tauri-cef/crates/tauri-runtime" } tauri-runtime-wry = { path = "vendor/tauri-cef/crates/tauri-runtime-wry" } tauri-plugin = { path = "vendor/tauri-cef/crates/tauri-plugin" } # Pinned to a specific commit on plugins-workspace@feat/cef so fresh # dependency resolution (without Cargo.lock) is reproducible and doesn't # silently drift when upstream pushes to the branch. tauri-plugin-opener = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" } tauri-plugin-deep-link = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" } tauri-plugin-global-shortcut = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" } tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", rev = "c6561ab6b4f9e7f650d4fc8c53fd8acc9b65b9b2" } tauri-plugin-notification = { path = "vendor/tauri-plugin-notification" } [dev-dependencies] # `test-util` enables `#[tokio::test(start_paused = true)]` for the # idle-watchdog unit tests in `cdp/session.rs` (#1213). tokio = { version = "1", features = ["macros", "rt", "test-util"] } tempfile = "3" # Emit just enough DWARF in release builds for Sentry to symbolicate Rust # panics + render surrounding source lines. `line-tables-only` keeps the # binary small (only file+line tables, no full type info) while still # letting `sentry-cli debug-files upload --include-sources` produce a # usable `.src.zip`. `split-debuginfo = "packed"` writes the debug data # into a separate `.dSYM` bundle on macOS so the shipped executable # itself stays slim. [profile.release] debug = "line-tables-only" split-debuginfo = "packed" # Fast CI builds: trade runtime perf for compile speed [profile.ci] inherits = "release" opt-level = 1 codegen-units = 16 lto = false incremental = false strip = true debug = false # Faster local + CI iteration (#3877): compile third-party dependencies in the # dev/test profiles WITHOUT debuginfo. The Tauri shell embeds the full core # crate, so its dev dependency graph is huge (a local checkout showed # `app/src-tauri/target/` ~4.4G) and DWARF generation + linking for every # dependency dominates `cargo build` / `cargo tauri dev` / `cargo llvm-cov`. # # Scope is intentionally narrow and low-risk (kept in sync with the root # crate's `Cargo.toml` so both Cargo worlds get the same discipline): # * `package."*"` targets dependencies only — the shell + core crates keep # full debuginfo, so panics/backtraces still resolve to file:line. # * Only the unoptimised `dev`/`test` profiles change; `release`/`ci` are # untouched, so shipped bundles and Sentry symbolication are unaffected. # * No artifact paths, features, or runtime behaviour change. [profile.dev.package."*"] debug = false