From 603dbcba8556dd454e9aaeaeb467178e57d73676 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Wed, 4 Feb 2026 23:31:28 +0530 Subject: [PATCH] feat: enhance build process and resource management - Added a new build command in package.json for building the app with skills integration. - Updated tauri.conf.json to use the new build command before building the app. - Enhanced the RuntimeEngine to manage a resource directory for bundled skills in production, improving resource handling. - Implemented logic to locate skills from various directories, including bundled resources, ensuring flexibility in both development and production environments. --- package.json | 1 + src-tauri/src/lib.rs | 6 ++++ src-tauri/src/runtime/v8_engine.rs | 50 ++++++++++++++++++++++++++++-- src-tauri/tauri.conf.json | 3 +- 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index b5893a0ad..86f84a3db 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dev": "vite", "dev:web": "vite", "build": "tsc && vite build", + "build:app": "yarn skills:build && tsc && vite build", "compile": "tsc --noEmit", "preview": "vite preview", "tauri": "tauri", diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b1f5bfd80..2c9d94105 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -311,6 +311,12 @@ pub fn run() { match runtime::v8_engine::RuntimeEngine::new(skills_data_dir) { Ok(engine) => { engine.set_app_handle(app.handle().clone()); + + // Set resource directory for bundled skills (production builds) + if let Ok(resource_dir) = app.path().resource_dir() { + engine.set_resource_dir(resource_dir); + } + let engine = std::sync::Arc::new(engine); // Wire the SkillRegistry into the SocketManager for MCP diff --git a/src-tauri/src/runtime/v8_engine.rs b/src-tauri/src/runtime/v8_engine.rs index 16110c347..d54d5f8b9 100644 --- a/src-tauri/src/runtime/v8_engine.rs +++ b/src-tauri/src/runtime/v8_engine.rs @@ -29,6 +29,8 @@ pub struct RuntimeEngine { skills_data_dir: PathBuf, /// Directory containing skill source files. skills_source_dir: RwLock>, + /// Tauri resource directory (bundled skills in production). + resource_dir: RwLock>, /// Tauri app handle for emitting events. app_handle: RwLock>, } @@ -49,6 +51,7 @@ impl RuntimeEngine { preferences, skills_data_dir, skills_source_dir: RwLock::new(None), + resource_dir: RwLock::new(None), app_handle: RwLock::new(None), }) } @@ -74,32 +77,73 @@ impl RuntimeEngine { *self.skills_source_dir.write() = Some(dir); } + /// Set the Tauri resource directory (for bundled skills in production). + pub fn set_resource_dir(&self, dir: PathBuf) { + log::info!("[runtime] Resource directory set to: {:?}", dir); + *self.resource_dir.write() = Some(dir); + } + /// Get the skills source directory. fn get_skills_source_dir(&self) -> Result { + // 1. Explicitly set source dir (highest priority) if let Some(dir) = self.skills_source_dir.read().as_ref() { + log::info!("[runtime] Using explicit skills source dir: {:?}", dir); return Ok(dir.clone()); } let current = std::env::current_dir().map_err(|e| format!("Failed to get current dir: {e}"))?; - // Check: cwd/skills/skills + // 2. Dev: cwd/skills/skills let dev_skills = current.join("skills").join("skills"); if dev_skills.exists() { + log::info!("[runtime] Using dev skills dir: {:?}", dev_skills); return Ok(dev_skills); } - // Check: ../skills/skills + // 3. Dev: ../skills/skills if let Some(parent) = current.parent() { let parent_skills = parent.join("skills").join("skills"); if parent_skills.exists() { + log::info!("[runtime] Using parent dev skills dir: {:?}", parent_skills); return Ok(parent_skills); } } + // 4. Production: bundled resources + // Tauri converts "../" to "_up_/" when bundling resources with array notation + if let Some(resource_dir) = self.resource_dir.read().as_ref() { + // Try: $RESOURCE/_up_/skills/skills/ (array notation with ../) + let bundled_skills = resource_dir.join("_up_").join("skills").join("skills"); + if bundled_skills.exists() { + log::info!( + "[runtime] Using bundled skills from resources: {:?}", + bundled_skills + ); + return Ok(bundled_skills); + } + + // Try: $RESOURCE/skills/ (map notation) + let bundled_skills_alt = resource_dir.join("skills"); + if bundled_skills_alt.exists() { + log::info!( + "[runtime] Using bundled skills from resources (alt): {:?}", + bundled_skills_alt + ); + return Ok(bundled_skills_alt); + } + + log::warn!( + "[runtime] Resource dir set but skills not found. Checked: {:?} and {:?}", + bundled_skills, + bundled_skills_alt + ); + } + + // 5. Final fallback: app data dir (for user-installed skills) let prod_dir = self.skills_data_dir.clone(); log::info!( - "[runtime] Skills source dir (production fallback): {:?}", + "[runtime] Skills source dir (data dir fallback): {:?}", prod_dir ); Ok(prod_dir) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 1574a9fe8..11c58d4bd 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -6,7 +6,7 @@ "build": { "beforeDevCommand": "npm run dev", "devUrl": "http://localhost:1420", - "beforeBuildCommand": "npm run build", + "beforeBuildCommand": "npm run build:app", "frontendDist": "../dist" }, "app": { @@ -37,6 +37,7 @@ "icons/icon.icns", "icons/icon.ico" ], + "resources": ["../skills/skills"], "macOS": { "minimumSystemVersion": "10.15" }