//! Tauri command for launching the Python `command_builder` GUI. //! //! The Python fork ships a separate yaml-editing tool at //! `python/tools/command_builder/` (a pywebview-based GUI). Without a launcher //! button in the main Tauri GUI the user has no easy way to find it. //! //! Resolution order for the python checkout: //! 1. `JARVIS_PYTHON_DIR` env override //! 2. Sibling `python/` directory next to this jarvis-rust checkout //! 3. `C:\Jarvis\python` (the dev box default) //! //! We don't ship the Python fork inside the Rust binary — this launcher just //! tries to spawn it. If Python isn't installed, we open the docs URL instead. use std::path::{Path, PathBuf}; use std::process::Command; fn locate_python_dir() -> Option { if let Ok(p) = std::env::var("JARVIS_PYTHON_DIR") { let pp = PathBuf::from(p); if pp.is_dir() { return Some(pp); } } if let Ok(exe) = std::env::current_exe() { let mut dir = exe.parent().map(|p| p.to_path_buf()); for _ in 0..6 { if let Some(d) = &dir { let candidate = d.join("python"); if candidate.join("tools").join("command_builder").is_dir() { return Some(candidate); } dir = d.parent().map(|p| p.to_path_buf()); } } } let fallback = PathBuf::from(r"C:\Jarvis\python"); if fallback.join("tools").join("command_builder").is_dir() { return Some(fallback); } None } /// Find a python interpreter to run the builder with. Prefers the project's /// `.venv\Scripts\python.exe` (where all deps are installed), then `python`. fn python_bin(py_dir: &Path) -> PathBuf { let venv = py_dir.join(".venv").join("Scripts").join("python.exe"); if venv.is_file() { venv } else { PathBuf::from("python") } } #[tauri::command] pub fn open_command_builder() -> Result { let py_dir = locate_python_dir() .ok_or_else(|| "Python fork not found. Set JARVIS_PYTHON_DIR or install at C:\\Jarvis\\python.".to_string())?; let py = python_bin(&py_dir); Command::new(&py) .args(["-m", "tools.command_builder"]) .current_dir(&py_dir) .spawn() .map_err(|e| format!("Failed to launch command builder: {} (using {})", e, py.display()))?; Ok(format!("Launched from {}", py_dir.display())) }