diff --git a/v2/Cargo.lock b/v2/Cargo.lock index cd84229..487464f 100644 --- a/v2/Cargo.lock +++ b/v2/Cargo.lock @@ -302,6 +302,7 @@ dependencies = [ "serde_json", "tauri", "tauri-build", + "tauri-plugin-dialog", "tauri-plugin-log", "tauri-plugin-updater", "tempfile", @@ -3365,6 +3366,30 @@ dependencies = [ "web-sys", ] +[[package]] +name = "rfd" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" +dependencies = [ + "block2", + "dispatch2", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.60.2", +] + [[package]] name = "ring" version = "0.17.14" @@ -4331,6 +4356,46 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-dialog" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9204b425d9be8d12aa60c2a83a289cf7d1caae40f57f336ed1155b3a5c0e359b" +dependencies = [ + "log", + "raw-window-handle", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.18", + "url", +] + +[[package]] +name = "tauri-plugin-fs" +version = "2.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed390cc669f937afeb8b28032ce837bac8ea023d975a2e207375ec05afaf1804" +dependencies = [ + "anyhow", + "dunce", + "glob", + "percent-encoding", + "schemars 0.8.22", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.18", + "toml 0.9.12+spec-1.1.0", + "url", +] + [[package]] name = "tauri-plugin-log" version = "2.8.0" diff --git a/v2/package-lock.json b/v2/package-lock.json index 88fcf06..0a67dd4 100644 --- a/v2/package-lock.json +++ b/v2/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.70", "@tauri-apps/api": "^2.10.1", + "@tauri-apps/plugin-dialog": "^2.6.0", "@tauri-apps/plugin-updater": "^2.10.0", "@xterm/addon-canvas": "^0.7.0", "@xterm/addon-fit": "^0.11.0", @@ -1363,6 +1364,15 @@ "url": "https://opencollective.com/tauri" } }, + "node_modules/@tauri-apps/plugin-dialog": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.6.0.tgz", + "integrity": "sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" + } + }, "node_modules/@tauri-apps/plugin-updater": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.10.0.tgz", diff --git a/v2/package.json b/v2/package.json index d9812e8..042551b 100644 --- a/v2/package.json +++ b/v2/package.json @@ -27,6 +27,7 @@ "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.70", "@tauri-apps/api": "^2.10.1", + "@tauri-apps/plugin-dialog": "^2.6.0", "@tauri-apps/plugin-updater": "^2.10.0", "@xterm/addon-canvas": "^0.7.0", "@xterm/addon-fit": "^0.11.0", diff --git a/v2/src-tauri/Cargo.toml b/v2/src-tauri/Cargo.toml index 95d38e4..fe24865 100644 --- a/v2/src-tauri/Cargo.toml +++ b/v2/src-tauri/Cargo.toml @@ -27,6 +27,7 @@ rusqlite = { version = "0.31", features = ["bundled"] } dirs = "5" notify = { version = "6", features = ["macos_fsevent"] } tauri-plugin-updater = "2.10.0" +tauri-plugin-dialog = "2" uuid = { version = "1", features = ["v4"] } tokio-tungstenite = { version = "0.21", features = ["native-tls"] } tokio = { version = "1", features = ["full"] } diff --git a/v2/src-tauri/src/lib.rs b/v2/src-tauri/src/lib.rs index 1b8f8eb..8186cae 100644 --- a/v2/src-tauri/src/lib.rs +++ b/v2/src-tauri/src/lib.rs @@ -421,14 +421,7 @@ fn project_agent_state_load( state.session_db.load_project_agent_state(&project_id) } -// --- Directory picker command --- - -#[tauri::command] -fn pick_directory() -> Option { - // Use native file dialog via rfd - // Fallback: return None and let frontend use a text input - None -} +// Directory picker: uses tauri-plugin-dialog (frontend API: @tauri-apps/plugin-dialog) // --- CLI argument commands --- @@ -554,7 +547,6 @@ pub fn run() { claude_list_profiles, claude_list_skills, claude_read_skill, - pick_directory, groups_load, groups_save, discover_markdown_files, @@ -565,6 +557,7 @@ pub fn run() { cli_get_group, ]) .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_dialog::init()) .setup(move |app| { if cfg!(debug_assertions) { app.handle().plugin( diff --git a/v2/src/lib/components/Workspace/SettingsTab.svelte b/v2/src/lib/components/Workspace/SettingsTab.svelte index e42376e..d7f7bbd 100644 --- a/v2/src/lib/components/Workspace/SettingsTab.svelte +++ b/v2/src/lib/components/Workspace/SettingsTab.svelte @@ -16,6 +16,7 @@ import { getSetting, setSetting } from '../../adapters/settings-bridge'; import { getCurrentTheme, setTheme } from '../../stores/theme.svelte'; import { THEME_LIST, getPalette, type ThemeId } from '../../styles/themes'; + import { open as openDialog } from '@tauri-apps/plugin-dialog'; let activeGroupId = $derived(getActiveGroupId()); let activeGroup = $derived(getActiveGroup()); @@ -176,6 +177,11 @@ } } + async function browseDirectory(): Promise { + const selected = await openDialog({ directory: true, multiple: false }); + return typeof selected === 'string' ? selected : null; + } + // New project form let newName = $state(''); let newCwd = $state(''); @@ -385,12 +391,17 @@
- { defaultCwd = (e.target as HTMLInputElement).value; saveGlobalSetting('default_cwd', defaultCwd); }} - /> +
+ { defaultCwd = (e.target as HTMLInputElement).value; saveGlobalSetting('default_cwd', defaultCwd); }} + /> + +
@@ -434,10 +445,15 @@