summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop/src-tauri/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'packages/desktop/src-tauri/src/lib.rs')
-rw-r--r--packages/desktop/src-tauri/src/lib.rs179
1 files changed, 96 insertions, 83 deletions
diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs
index 46c0ab256..4012fe1a5 100644
--- a/packages/desktop/src-tauri/src/lib.rs
+++ b/packages/desktop/src-tauri/src/lib.rs
@@ -1,12 +1,16 @@
+mod cli;
mod window_customizer;
+use cli::{get_sidecar_path, install_cli, sync_cli};
use std::{
collections::VecDeque,
net::{SocketAddr, TcpListener},
sync::{Arc, Mutex},
time::{Duration, Instant},
};
-use tauri::{AppHandle, LogicalSize, Manager, RunEvent, WebviewUrl, WebviewWindow, path::BaseDirectory};
+use tauri::{
+ path::BaseDirectory, AppHandle, LogicalSize, Manager, RunEvent, WebviewUrl, WebviewWindow,
+};
use tauri_plugin_clipboard_manager::ClipboardExt;
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogResult};
use tauri_plugin_shell::process::{CommandChild, CommandEvent};
@@ -116,11 +120,7 @@ fn spawn_sidecar(app: &AppHandle, port: u32) -> CommandChild {
#[cfg(not(target_os = "windows"))]
let (mut rx, child) = {
- let sidecar_path = tauri::utils::platform::current_exe()
- .expect("Failed to get current exe")
- .parent()
- .expect("Failed to get parent dir")
- .join("opencode-cli");
+ let sidecar = get_sidecar_path();
let shell = get_user_shell();
app.shell()
.command(&shell)
@@ -130,7 +130,7 @@ fn spawn_sidecar(app: &AppHandle, port: u32) -> CommandChild {
.args([
"-il",
"-c",
- &format!("{} serve --port={}", sidecar_path.display(), port),
+ &format!("{} serve --port={}", sidecar.display(), port),
])
.spawn()
.expect("Failed to spawn opencode")
@@ -203,7 +203,8 @@ pub fn run() {
.invoke_handler(tauri::generate_handler![
kill_sidecar,
copy_logs_to_clipboard,
- get_logs
+ get_logs,
+ install_cli
])
.setup(move |app| {
let app = app.handle().clone();
@@ -211,83 +212,95 @@ pub fn run() {
// Initialize log state
app.manage(LogState(Arc::new(Mutex::new(VecDeque::new()))));
- tauri::async_runtime::spawn(async move {
- let port = get_sidecar_port();
-
- let should_spawn_sidecar = !is_server_running(port).await;
-
- let child = if should_spawn_sidecar {
- let child = spawn_sidecar(&app, port);
-
- let timestamp = Instant::now();
- loop {
- if timestamp.elapsed() > Duration::from_secs(7) {
- let res = app.dialog()
- .message("Failed to spawn OpenCode Server. Copy logs using the button below and send them to the team for assistance.")
- .title("Startup Failed")
- .buttons(MessageDialogButtons::OkCancelCustom("Copy Logs And Exit".to_string(), "Exit".to_string()))
- .blocking_show_with_result();
-
- if matches!(&res, MessageDialogResult::Custom(name) if name == "Copy Logs And Exit") {
- match copy_logs_to_clipboard(app.clone()).await {
- Ok(()) => println!("Logs copied to clipboard successfully"),
- Err(e) => println!("Failed to copy logs to clipboard: {}", e),
- }
- }
-
- app.exit(1);
-
- return;
- }
-
- tokio::time::sleep(Duration::from_millis(10)).await;
-
- if is_server_running(port).await {
- // give the server a little bit more time to warm up
- tokio::time::sleep(Duration::from_millis(10)).await;
-
- break;
- }
- }
+ {
+ let app = app.clone();
+ tauri::async_runtime::spawn(async move {
+ let port = get_sidecar_port();
+
+ let should_spawn_sidecar = !is_server_running(port).await;
+
+ let child = if should_spawn_sidecar {
+ let child = spawn_sidecar(&app, port);
+
+ let timestamp = Instant::now();
+ loop {
+ if timestamp.elapsed() > Duration::from_secs(7) {
+ let res = app.dialog()
+ .message("Failed to spawn OpenCode Server. Copy logs using the button below and send them to the team for assistance.")
+ .title("Startup Failed")
+ .buttons(MessageDialogButtons::OkCancelCustom("Copy Logs And Exit".to_string(), "Exit".to_string()))
+ .blocking_show_with_result();
+
+ if matches!(&res, MessageDialogResult::Custom(name) if name == "Copy Logs And Exit") {
+ match copy_logs_to_clipboard(app.clone()).await {
+ Ok(()) => println!("Logs copied to clipboard successfully"),
+ Err(e) => println!("Failed to copy logs to clipboard: {}", e),
+ }
+ }
+
+ app.exit(1);
+
+ return;
+ }
+
+ tokio::time::sleep(Duration::from_millis(10)).await;
+
+ if is_server_running(port).await {
+ // give the server a little bit more time to warm up
+ tokio::time::sleep(Duration::from_millis(10)).await;
+
+ break;
+ }
+ }
+
+ println!("Server ready after {:?}", timestamp.elapsed());
+
+ Some(child)
+ } else {
+ None
+ };
+
+ let primary_monitor = app.primary_monitor().ok().flatten();
+ let size = primary_monitor
+ .map(|m| m.size().to_logical(m.scale_factor()))
+ .unwrap_or(LogicalSize::new(1920, 1080));
+
+ let mut window_builder =
+ WebviewWindow::builder(&app, "main", WebviewUrl::App("/".into()))
+ .title("OpenCode")
+ .inner_size(size.width as f64, size.height as f64)
+ .decorations(true)
+ .zoom_hotkeys_enabled(true)
+ .disable_drag_drop_handler()
+ .initialization_script(format!(
+ r#"
+ window.__OPENCODE__ ??= {{}};
+ window.__OPENCODE__.updaterEnabled = {updater_enabled};
+ window.__OPENCODE__.port = {port};
+ "#
+ ));
+
+ #[cfg(target_os = "macos")]
+ {
+ window_builder = window_builder
+ .title_bar_style(tauri::TitleBarStyle::Overlay)
+ .hidden_title(true);
+ }
+
+ window_builder.build().expect("Failed to create window");
+
+ app.manage(ServerState(Arc::new(Mutex::new(child))));
+ });
+ }
- println!("Server ready after {:?}", timestamp.elapsed());
-
- Some(child)
- } else {
- None
- };
-
- let primary_monitor = app.primary_monitor().ok().flatten();
- let size = primary_monitor
- .map(|m| m.size().to_logical(m.scale_factor()))
- .unwrap_or(LogicalSize::new(1920, 1080));
-
- let mut window_builder =
- WebviewWindow::builder(&app, "main", WebviewUrl::App("/".into()))
- .title("OpenCode")
- .inner_size(size.width as f64, size.height as f64)
- .decorations(true)
- .zoom_hotkeys_enabled(true)
- .disable_drag_drop_handler()
- .initialization_script(format!(
- r#"
- window.__OPENCODE__ ??= {{}};
- window.__OPENCODE__.updaterEnabled = {updater_enabled};
- window.__OPENCODE__.port = {port};
- "#
- ));
-
- #[cfg(target_os = "macos")]
- {
- window_builder = window_builder
- .title_bar_style(tauri::TitleBarStyle::Overlay)
- .hidden_title(true);
+ {
+ let app = app.clone();
+ tauri::async_runtime::spawn(async move {
+ if let Err(e) = sync_cli(app) {
+ eprintln!("Failed to sync CLI: {e}");
}
-
- window_builder.build().expect("Failed to create window");
-
- app.manage(ServerState(Arc::new(Mutex::new(child))));
- });
+ });
+ }
Ok(())
});