From 04aef44fc30d599f11ea2ada60ed63c4856a18ff Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Mon, 2 Feb 2026 15:58:08 +0800 Subject: [PATCH] chore(desktop): integrate tauri-specta (#11740) --- packages/desktop/src-tauri/Cargo.lock | 247 +++++++++++++++++---- packages/desktop/src-tauri/Cargo.toml | 14 +- packages/desktop/src-tauri/src/cli.rs | 1 + packages/desktop/src-tauri/src/lib.rs | 41 +++- packages/desktop/src-tauri/src/markdown.rs | 5 +- packages/desktop/src/bindings.ts | 20 ++ packages/desktop/src/cli.ts | 4 +- packages/desktop/src/index.tsx | 20 +- packages/desktop/src/menu.ts | 4 +- packages/desktop/src/updater.ts | 6 +- 10 files changed, 289 insertions(+), 73 deletions(-) create mode 100644 packages/desktop/src/bindings.ts diff --git a/packages/desktop/src-tauri/Cargo.lock b/packages/desktop/src-tauri/Cargo.lock index 51e5e0049..14030218e 100644 --- a/packages/desktop/src-tauri/Cargo.lock +++ b/packages/desktop/src-tauri/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" + [[package]] name = "adler2" version = "2.0.1" @@ -1994,9 +2000,9 @@ dependencies = [ [[package]] name = "ico" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" dependencies = [ "byteorder", "png 0.17.16", @@ -3065,12 +3071,14 @@ dependencies = [ "listeners", "objc2 0.6.3", "objc2-web-kit", - "reqwest", + "reqwest 0.12.24", "semver", "serde", "serde_json", + "specta", + "specta-typescript", "tauri", - "tauri-build", + "tauri-build 2.5.2", "tauri-plugin-clipboard-manager", "tauri-plugin-decorum", "tauri-plugin-deep-link", @@ -3085,6 +3093,7 @@ dependencies = [ "tauri-plugin-store", "tauri-plugin-updater", "tauri-plugin-window-state", + "tauri-specta", "tokio", "uuid", "webkit2gtk", @@ -3221,6 +3230,12 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pathdiff" version = "0.2.3" @@ -3947,6 +3962,40 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "reqwest" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + [[package]] name = "rfd" version = "0.15.4" @@ -4497,6 +4546,44 @@ dependencies = [ "system-deps", ] +[[package]] +name = "specta" +version = "2.0.0-rc.22" +source = "git+https://github.com/specta-rs/specta?rev=106425eac4964d8ff34d3a02f1612e33117b08bb#106425eac4964d8ff34d3a02f1612e33117b08bb" +dependencies = [ + "paste", + "rustc_version", + "specta-macros", +] + +[[package]] +name = "specta-macros" +version = "2.0.0-rc.18" +source = "git+https://github.com/specta-rs/specta?rev=106425eac4964d8ff34d3a02f1612e33117b08bb#106425eac4964d8ff34d3a02f1612e33117b08bb" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "specta-serde" +version = "0.0.9" +source = "git+https://github.com/specta-rs/specta?rev=106425eac4964d8ff34d3a02f1612e33117b08bb#106425eac4964d8ff34d3a02f1612e33117b08bb" +dependencies = [ + "specta", +] + +[[package]] +name = "specta-typescript" +version = "0.0.9" +source = "git+https://github.com/specta-rs/specta?rev=106425eac4964d8ff34d3a02f1612e33117b08bb#106425eac4964d8ff34d3a02f1612e33117b08bb" +dependencies = [ + "specta", + "specta-serde", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -4712,9 +4799,8 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e492485dd390b35f7497401f67694f46161a2a00ffd800938d5dd3c898fb9d8" +version = "2.9.5" +source = "git+https://github.com/tauri-apps/tauri?rev=4d5d78daf636feaac20c5bc48a6071491c4291ee#4d5d78daf636feaac20c5bc48a6071491c4291ee" dependencies = [ "anyhow", "bytes", @@ -4740,17 +4826,18 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest", + "reqwest 0.13.1", "serde", "serde_json", "serde_repr", "serialize-to-javascript", + "specta", "swift-rs", - "tauri-build", + "tauri-build 2.5.3", "tauri-macros", "tauri-runtime", "tauri-runtime-wry", - "tauri-utils", + "tauri-utils 2.8.1", "thiserror 2.0.17", "tokio", "tray-icon", @@ -4777,7 +4864,28 @@ dependencies = [ "semver", "serde", "serde_json", - "tauri-utils", + "tauri-utils 2.8.0", + "tauri-winres", + "toml 0.9.8", + "walkdir", +] + +[[package]] +name = "tauri-build" +version = "2.5.3" +source = "git+https://github.com/tauri-apps/tauri?rev=4d5d78daf636feaac20c5bc48a6071491c4291ee#4d5d78daf636feaac20c5bc48a6071491c4291ee" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 0.8.22", + "semver", + "serde", + "serde_json", + "tauri-utils 2.8.1", "tauri-winres", "toml 0.9.8", "walkdir", @@ -4785,9 +4893,8 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ef707148f0755110ca54377560ab891d722de4d53297595380a748026f139f" +version = "2.5.2" +source = "git+https://github.com/tauri-apps/tauri?rev=4d5d78daf636feaac20c5bc48a6071491c4291ee#4d5d78daf636feaac20c5bc48a6071491c4291ee" dependencies = [ "base64 0.22.1", "brotli", @@ -4802,7 +4909,7 @@ dependencies = [ "serde_json", "sha2", "syn 2.0.110", - "tauri-utils", + "tauri-utils 2.8.1", "thiserror 2.0.17", "time", "url", @@ -4812,16 +4919,15 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71664fd715ee6e382c05345ad258d6d1d50f90cf1b58c0aa726638b33c2a075d" +version = "2.5.2" +source = "git+https://github.com/tauri-apps/tauri?rev=4d5d78daf636feaac20c5bc48a6071491c4291ee#4d5d78daf636feaac20c5bc48a6071491c4291ee" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.110", "tauri-codegen", - "tauri-utils", + "tauri-utils 2.8.1", ] [[package]] @@ -4836,7 +4942,7 @@ dependencies = [ "schemars 0.8.22", "serde", "serde_json", - "tauri-utils", + "tauri-utils 2.8.0", "toml 0.9.8", "walkdir", ] @@ -4886,7 +4992,7 @@ dependencies = [ "serde_json", "tauri", "tauri-plugin", - "tauri-utils", + "tauri-utils 2.8.0", "thiserror 2.0.17", "tracing", "url", @@ -4928,7 +5034,7 @@ dependencies = [ "serde_repr", "tauri", "tauri-plugin", - "tauri-utils", + "tauri-utils 2.8.0", "thiserror 2.0.17", "toml 0.9.8", "url", @@ -4945,7 +5051,7 @@ dependencies = [ "data-url", "http", "regex", - "reqwest", + "reqwest 0.12.24", "schemars 0.8.22", "serde", "serde_json", @@ -5096,7 +5202,7 @@ dependencies = [ "minisign-verify", "osakit", "percent-encoding", - "reqwest", + "reqwest 0.12.24", "semver", "serde", "serde_json", @@ -5129,9 +5235,8 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9368f09358496f2229313fccb37682ad116b7f46fa76981efe116994a0628926" +version = "2.9.2" +source = "git+https://github.com/tauri-apps/tauri?rev=4d5d78daf636feaac20c5bc48a6071491c4291ee#4d5d78daf636feaac20c5bc48a6071491c4291ee" dependencies = [ "cookie", "dpi", @@ -5144,7 +5249,7 @@ dependencies = [ "raw-window-handle", "serde", "serde_json", - "tauri-utils", + "tauri-utils 2.8.1", "thiserror 2.0.17", "url", "webkit2gtk", @@ -5154,9 +5259,8 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "929f5df216f5c02a9e894554401bcdab6eec3e39ec6a4a7731c7067fc8688a93" +version = "2.9.3" +source = "git+https://github.com/tauri-apps/tauri?rev=4d5d78daf636feaac20c5bc48a6071491c4291ee#4d5d78daf636feaac20c5bc48a6071491c4291ee" dependencies = [ "gtk", "http", @@ -5171,7 +5275,7 @@ dependencies = [ "softbuffer", "tao", "tauri-runtime", - "tauri-utils", + "tauri-utils 2.8.1", "url", "webkit2gtk", "webview2-com", @@ -5179,11 +5283,74 @@ dependencies = [ "wry", ] +[[package]] +name = "tauri-specta" +version = "2.0.0-rc.21" +source = "git+https://github.com/specta-rs/tauri-specta?rev=6720b2848eff9a3e40af54c48d65f6d56b640c0b#6720b2848eff9a3e40af54c48d65f6d56b640c0b" +dependencies = [ + "heck 0.5.0", + "serde", + "serde_json", + "specta", + "specta-typescript", + "tauri", + "tauri-specta-macros", + "thiserror 2.0.17", +] + +[[package]] +name = "tauri-specta-macros" +version = "2.0.0-rc.16" +source = "git+https://github.com/specta-rs/tauri-specta?rev=6720b2848eff9a3e40af54c48d65f6d56b640c0b#6720b2848eff9a3e40af54c48d65f6d56b640c0b" +dependencies = [ + "darling", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "tauri-utils" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b8bbe426abdbf52d050e52ed693130dbd68375b9ad82a3fb17efb4c8d85673" +dependencies = [ + "anyhow", + "cargo_metadata", + "ctor", + "dunce", + "glob", + "html5ever", + "http", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.3", + "proc-macro2", + "quote", + "regex", + "schemars 0.8.22", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.17", + "toml 0.9.8", + "url", + "urlpattern", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-utils" +version = "2.8.1" +source = "git+https://github.com/tauri-apps/tauri?rev=4d5d78daf636feaac20c5bc48a6071491c4291ee#4d5d78daf636feaac20c5bc48a6071491c4291ee" dependencies = [ "anyhow", "brotli", @@ -5547,9 +5714,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.10.0", "bytes", @@ -6034,9 +6201,9 @@ dependencies = [ [[package]] name = "webkit2gtk" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -6058,9 +6225,9 @@ dependencies = [ [[package]] name = "webkit2gtk-sys" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" dependencies = [ "bitflags 1.3.2", "cairo-sys-rs", @@ -6719,9 +6886,9 @@ checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wry" -version = "0.53.5" +version = "0.54.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728b7d4c8ec8d81cab295e0b5b8a4c263c0d41a785fb8f8c4df284e5411140a2" +checksum = "5ed1a195b0375491dd15a7066a10251be217ce743cf4bbbbdcf5391d6473bee0" dependencies = [ "base64 0.22.1", "block2 0.6.2", diff --git a/packages/desktop/src-tauri/Cargo.toml b/packages/desktop/src-tauri/Cargo.toml index e87bf77c2..2efa484e8 100644 --- a/packages/desktop/src-tauri/Cargo.toml +++ b/packages/desktop/src-tauri/Cargo.toml @@ -18,7 +18,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] tauri-build = { version = "2", features = [] } [dependencies] -tauri = { version = "2", features = ["macos-private-api", "devtools"] } +tauri = { version = "2.9.5", features = ["macos-private-api", "devtools"] } tauri-plugin-opener = "2" tauri-plugin-deep-link = "2.4.6" tauri-plugin-shell = "2" @@ -43,10 +43,13 @@ reqwest = { version = "0.12", default-features = false, features = ["rustls-tls" uuid = { version = "1.19.0", features = ["v4"] } tauri-plugin-decorum = "1.1.1" comrak = { version = "0.50", default-features = false } +specta = "=2.0.0-rc.22" +specta-typescript = "0.0.9" +tauri-specta = { version = "=2.0.0-rc.21", features = ["derive", "typescript"] } [target.'cfg(target_os = "linux")'.dependencies] gtk = "0.18.2" -webkit2gtk = "=2.0.1" +webkit2gtk = "=2.0.2" [target.'cfg(target_os = "macos")'.dependencies] objc2 = "0.6" @@ -59,3 +62,10 @@ windows = { version = "0.61", features = [ "Win32_System_Threading", "Win32_Security" ] } + +[patch.crates-io] +specta = { git = "https://github.com/specta-rs/specta", rev = "106425eac4964d8ff34d3a02f1612e33117b08bb" } +specta-typescript = { git = "https://github.com/specta-rs/specta", rev = "106425eac4964d8ff34d3a02f1612e33117b08bb" } +tauri-specta = { git = "https://github.com/specta-rs/tauri-specta", rev = "6720b2848eff9a3e40af54c48d65f6d56b640c0b" } +# TODO: https://github.com/tauri-apps/tauri/pull/14812 +tauri = { git = "https://github.com/tauri-apps/tauri", rev = "4d5d78daf636feaac20c5bc48a6071491c4291ee" } diff --git a/packages/desktop/src-tauri/src/cli.rs b/packages/desktop/src-tauri/src/cli.rs index f64beed6a..16e4bfec9 100644 --- a/packages/desktop/src-tauri/src/cli.rs +++ b/packages/desktop/src-tauri/src/cli.rs @@ -51,6 +51,7 @@ fn is_cli_installed() -> bool { const INSTALL_SCRIPT: &str = include_str!("../../../../install"); #[tauri::command] +#[specta::specta] pub fn install_cli(app: tauri::AppHandle) -> Result { if cfg!(not(unix)) { return Err("CLI installation is only supported on macOS & Linux".to_string()); diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs index 0958481ad..2fe7c4aa1 100644 --- a/packages/desktop/src-tauri/src/lib.rs +++ b/packages/desktop/src-tauri/src/lib.rs @@ -16,10 +16,10 @@ use std::{ time::{Duration, Instant}, }; use tauri::{AppHandle, LogicalSize, Manager, RunEvent, State, WebviewWindowBuilder}; -#[cfg(any(target_os = "linux", all(debug_assertions, windows)))] -use tauri_plugin_deep_link::DeepLinkExt; #[cfg(windows)] use tauri_plugin_decorum::WebviewWindowExt; +#[cfg(any(target_os = "linux", all(debug_assertions, windows)))] +use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogResult}; use tauri_plugin_shell::process::{CommandChild, CommandEvent}; use tauri_plugin_store::StoreExt; @@ -30,7 +30,7 @@ use crate::window_customizer::PinchZoomDisablePlugin; const SETTINGS_STORE: &str = "opencode.settings.dat"; const DEFAULT_SERVER_URL_KEY: &str = "defaultServerUrl"; -#[derive(Clone, serde::Serialize)] +#[derive(Clone, serde::Serialize, specta::Type)] struct ServerReadyData { url: String, password: Option, @@ -64,6 +64,7 @@ struct LogState(Arc>>); const MAX_LOG_ENTRIES: usize = 200; #[tauri::command] +#[specta::specta] fn kill_sidecar(app: AppHandle) { let Some(server_state) = app.try_state::() else { println!("Server not running"); @@ -97,6 +98,7 @@ async fn get_logs(app: AppHandle) -> Result { } #[tauri::command] +#[specta::specta] async fn ensure_server_ready(state: State<'_, ServerState>) -> Result { state .status @@ -106,6 +108,7 @@ async fn ensure_server_ready(state: State<'_, ServerState>) -> Result Result, String> { let store = app .store(SETTINGS_STORE) @@ -119,6 +122,7 @@ fn get_default_server_url(app: AppHandle) -> Result, String> { } #[tauri::command] +#[specta::specta] async fn set_default_server_url(app: AppHandle, url: Option) -> Result<(), String> { let store = app .store(SETTINGS_STORE) @@ -252,6 +256,26 @@ async fn check_server_health(url: &str, password: Option<&str>) -> bool { pub fn run() { let updater_enabled = option_env!("TAURI_SIGNING_PRIVATE_KEY").is_some(); + let builder = tauri_specta::Builder::::new() + // Then register them (separated by a comma) + .commands(tauri_specta::collect_commands![ + kill_sidecar, + install_cli, + ensure_server_ready, + get_default_server_url, + set_default_server_url, + markdown::parse_markdown_command + ]) + .error_handling(tauri_specta::ErrorHandlingMode::Throw); + + #[cfg(debug_assertions)] // <- Only export on non-release builds + builder + .export( + specta_typescript::Typescript::default(), + "../src/bindings.ts", + ) + .expect("Failed to export typescript bindings"); + #[cfg(all(target_os = "macos", not(debug_assertions)))] let _ = std::process::Command::new("killall") .arg("opencode-cli") @@ -285,15 +309,10 @@ pub fn run() { .plugin(tauri_plugin_notification::init()) .plugin(PinchZoomDisablePlugin) .plugin(tauri_plugin_decorum::init()) - .invoke_handler(tauri::generate_handler![ - kill_sidecar, - install_cli, - ensure_server_ready, - get_default_server_url, - set_default_server_url, - markdown::parse_markdown_command - ]) + .invoke_handler(builder.invoke_handler()) .setup(move |app| { + builder.mount_events(app); + #[cfg(any(target_os = "linux", all(debug_assertions, windows)))] app.deep_link().register_all().ok(); diff --git a/packages/desktop/src-tauri/src/markdown.rs b/packages/desktop/src-tauri/src/markdown.rs index c3ca73857..39a64a431 100644 --- a/packages/desktop/src-tauri/src/markdown.rs +++ b/packages/desktop/src-tauri/src/markdown.rs @@ -1,4 +1,6 @@ -use comrak::{create_formatter, parse_document, Arena, Options, html::ChildRendering, nodes::NodeValue}; +use comrak::{ + Arena, Options, create_formatter, html::ChildRendering, nodes::NodeValue, parse_document, +}; use std::fmt::Write; create_formatter!(ExternalLinkFormatter, { @@ -55,6 +57,7 @@ pub fn parse_markdown(input: &str) -> String { } #[tauri::command] +#[specta::specta] pub async fn parse_markdown_command(markdown: String) -> Result { Ok(parse_markdown(&markdown)) } diff --git a/packages/desktop/src/bindings.ts b/packages/desktop/src/bindings.ts new file mode 100644 index 000000000..eb5498fa6 --- /dev/null +++ b/packages/desktop/src/bindings.ts @@ -0,0 +1,20 @@ +// This file has been generated by Tauri Specta. Do not edit this file manually. + +import { invoke as __TAURI_INVOKE, Channel } from '@tauri-apps/api/core'; + +/** Commands */ +export const commands = { + killSidecar: () => __TAURI_INVOKE("kill_sidecar"), + installCli: () => __TAURI_INVOKE("install_cli"), + ensureServerReady: () => __TAURI_INVOKE("ensure_server_ready"), + getDefaultServerUrl: () => __TAURI_INVOKE("get_default_server_url"), + setDefaultServerUrl: (url: string | null) => __TAURI_INVOKE("set_default_server_url", { url }), + parseMarkdownCommand: (markdown: string) => __TAURI_INVOKE("parse_markdown_command", { markdown }), +}; + +/* Types */ +export type ServerReadyData = { + url: string, + password: string | null, + }; + diff --git a/packages/desktop/src/cli.ts b/packages/desktop/src/cli.ts index 5a8875cf8..28623bdf7 100644 --- a/packages/desktop/src/cli.ts +++ b/packages/desktop/src/cli.ts @@ -1,13 +1,13 @@ -import { invoke } from "@tauri-apps/api/core" import { message } from "@tauri-apps/plugin-dialog" import { initI18n, t } from "./i18n" +import { commands } from "./bindings" export async function installCli(): Promise { await initI18n() try { - const path = await invoke("install_cli") + const path = await commands.installCli() await message(t("desktop.cli.installed.message", { path }), { title: t("desktop.cli.installed.title") }) } catch (e) { await message(t("desktop.cli.failed.message", { error: String(e) }), { title: t("desktop.cli.failed.title") }) diff --git a/packages/desktop/src/index.tsx b/packages/desktop/src/index.tsx index 505a00b16..2b4406162 100644 --- a/packages/desktop/src/index.tsx +++ b/packages/desktop/src/index.tsx @@ -7,7 +7,6 @@ import { getCurrent, onOpenUrl } from "@tauri-apps/plugin-deep-link" import { open as shellOpen } from "@tauri-apps/plugin-shell" import { type as ostype } from "@tauri-apps/plugin-os" import { check, Update } from "@tauri-apps/plugin-updater" -import { invoke } from "@tauri-apps/api/core" import { getCurrentWindow } from "@tauri-apps/api/window" import { isPermissionGranted, requestPermission } from "@tauri-apps/plugin-notification" import { relaunch } from "@tauri-apps/plugin-process" @@ -22,6 +21,7 @@ import { createMenu } from "./menu" import { initI18n, t } from "./i18n" import pkg from "../package.json" import "./styles.css" +import { commands } from "./bindings" const root = document.getElementById("root") if (import.meta.env.DEV && !(root instanceof HTMLElement)) { @@ -274,12 +274,12 @@ const createPlatform = (password: Accessor): Platform => ({ update: async () => { if (!UPDATER_ENABLED || !update) return - if (ostype() === "windows") await invoke("kill_sidecar").catch(() => undefined) + if (ostype() === "windows") await commands.killSidecar().catch(() => undefined) await update.install().catch(() => undefined) }, restart: async () => { - await invoke("kill_sidecar").catch(() => undefined) + await commands.killSidecar().catch(() => undefined) await relaunch() }, @@ -335,17 +335,13 @@ const createPlatform = (password: Accessor): Platform => ({ }, getDefaultServerUrl: async () => { - const result = await invoke("get_default_server_url").catch(() => null) + const result = await commands.getDefaultServerUrl().catch(() => null) return result }, - setDefaultServerUrl: async (url: string | null) => { - await invoke("set_default_server_url", { url }) - }, + setDefaultServerUrl: async (url: string | null) => { await commands.setDefaultServerUrl(url) }, - parseMarkdown: async (markdown: string) => { - return invoke("parse_markdown_command", { markdown }) - }, + parseMarkdown: (markdown: string) => commands.parseMarkdownCommand(markdown), webviewZoom, }) @@ -394,7 +390,7 @@ type ServerReadyData = { url: string; password: string | null } // Gate component that waits for the server to be ready function ServerGate(props: { children: (data: Accessor) => JSX.Element }) { const [serverData] = createResource(() => - invoke("ensure_server_ready").then((v) => { + commands.ensureServerReady().then((v) => { return new Promise((res) => setTimeout(() => res(v as ServerReadyData), 2000)) }), ) @@ -408,7 +404,7 @@ function ServerGate(props: { children: (data: Accessor) => JSX. } const restartApp = async () => { - await invoke("kill_sidecar").catch(() => undefined) + await commands.killSidecar().catch(() => undefined) await relaunch().catch(() => undefined) } diff --git a/packages/desktop/src/menu.ts b/packages/desktop/src/menu.ts index 2edeff42b..d41084404 100644 --- a/packages/desktop/src/menu.ts +++ b/packages/desktop/src/menu.ts @@ -1,11 +1,11 @@ import { Menu, MenuItem, PredefinedMenuItem, Submenu } from "@tauri-apps/api/menu" import { type as ostype } from "@tauri-apps/plugin-os" -import { invoke } from "@tauri-apps/api/core" import { relaunch } from "@tauri-apps/plugin-process" import { runUpdater, UPDATER_ENABLED } from "./updater" import { installCli } from "./cli" import { initI18n, t } from "./i18n" +import { commands } from "./bindings" export async function createMenu() { if (ostype() !== "macos") return @@ -35,7 +35,7 @@ export async function createMenu() { }), await MenuItem.new({ action: async () => { - await invoke("kill_sidecar").catch(() => undefined) + await commands.killSidecar().catch(() => undefined) await relaunch().catch(() => undefined) }, text: t("desktop.menu.restart"), diff --git a/packages/desktop/src/updater.ts b/packages/desktop/src/updater.ts index b48bb6be0..732669633 100644 --- a/packages/desktop/src/updater.ts +++ b/packages/desktop/src/updater.ts @@ -1,10 +1,10 @@ import { check } from "@tauri-apps/plugin-updater" import { relaunch } from "@tauri-apps/plugin-process" import { ask, message } from "@tauri-apps/plugin-dialog" -import { invoke } from "@tauri-apps/api/core" import { type as ostype } from "@tauri-apps/plugin-os" import { initI18n, t } from "./i18n" +import { commands } from "./bindings" export const UPDATER_ENABLED = window.__OPENCODE__?.updaterEnabled ?? false @@ -39,13 +39,13 @@ export async function runUpdater({ alertOnFail }: { alertOnFail: boolean }) { if (!shouldUpdate) return try { - if (ostype() === "windows") await invoke("kill_sidecar") + if (ostype() === "windows") await commands.killSidecar() await update.install() } catch { await message(t("desktop.updater.installFailed.message"), { title: t("desktop.updater.installFailed.title") }) return } - await invoke("kill_sidecar") + await commands.killSidecar() await relaunch() }