From f9b992227c73db902e39a2cab5f227e0a83d0eb3 Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Sat, 29 Aug 2026 16:24:58 +0800 Subject: [PATCH] feat(console,src-tauri): local "Config folder" setting (studio#128) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a "Config folder" field to the Debug drawer's Config tab — a user-picked local directory (native folder picker via tauri-plugin-dialog) that later work will mirror each agent's generated config.toml into (//config.toml, alongside the existing S3 upload provision_agent/provision_agent_k8s already do — unchanged) and that the "view an agent's config" screen (also studio#128, separate follow-up) will read from directly, no S3 round-trip. This slice is just the setting itself: plugin registration + capability grant (dialog:allow-open — the app's capabilities/default.json had no dialog permission at all before this) + picker UI, persisted like the existing theme/log-level settings (localStorage), not Tauri's hidden app-config-dir — this setting points at other local files, so storing it in the hidden config dir would just be an extra layer of indirection. Wiring the wizard/view-screen to actually use it lands with those pieces. Verification: npm run typecheck clean, npm test 106/106 passing, npm run build succeeds. Rust side (plugin registration, Cargo.toml) not locally compiled — same pre-existing limitation as every other Rust change this week; tauri-plugin-dialog's exact API (invoke command name "plugin:dialog|open", options shape, return type for directory+non-multiple mode) was checked against the plugin's actual TypeScript source before using it, not guessed. Ref #128. --- console/index.html | 13 +++++++++ console/src/main.ts | 41 +++++++++++++++++++++++++++++ console/src/styles.css | 32 ++++++++++++++++++++++ src-tauri/Cargo.toml | 5 ++++ src-tauri/capabilities/default.json | 1 + src-tauri/src/lib.rs | 1 + 6 files changed, 93 insertions(+) diff --git a/console/index.html b/console/index.html index 22acdf1..e1dada7 100644 --- a/console/index.html +++ b/console/index.html @@ -273,6 +273,19 @@ explicit auth error, not a silent drift.

+
+ +
+ — not set — + +
+

+ Local folder the New Fleet wizard mirrors each agent's generated + config.toml into (<folder>/<agent-name>/config.toml), + alongside the S3 copy it deploys from — this is what "view an + agent's config" reads from, no S3 round-trip. +

+
diff --git a/console/src/main.ts b/console/src/main.ts index 8875e51..7c108cc 100644 --- a/console/src/main.ts +++ b/console/src/main.ts @@ -174,6 +174,47 @@ const mcp = mcpEl ? createPane(mcpEl, () => flag("mcpio")) : null; }); })(); +// Local "Config folder" (studio#128) — where the New Fleet wizard mirrors +// each agent's generated config.toml (alongside the S3 copy it deploys +// from) and where the "view an agent's config" screen reads from, no S3 +// round-trip. Persisted like the theme/log-level settings above +// (localStorage), not Tauri's app-config-dir — this setting *points at* +// other local files, storing it in the hidden config dir would just be an +// extra layer of indirection for no reason. +(function setupConfigFolder(): void { + const pathEl = document.getElementById("config-folder-path"); + const pickBtn = document.getElementById("config-folder-pick"); + if (!pathEl || !pickBtn) return; + const KEY = "oab-studio.configFolder"; + + const render = (): void => { + let saved: string | null = null; + try { + saved = localStorage.getItem(KEY); + } catch { + /* storage unavailable — falls through to the placeholder */ + } + pathEl.textContent = saved || "— not set —"; + }; + render(); + + pickBtn.addEventListener("click", () => { + const invoke = tauriInvoke(); + if (!invoke) return; + invoke("plugin:dialog|open", { options: { directory: true } }) + .then((path) => { + if (!path) return; + try { + localStorage.setItem(KEY, path); + } catch { + /* storage unavailable — the choice still applies this session */ + } + render(); + }) + .catch((e) => note("error", `config folder pick failed: ${errText(e)}`)); + }); +})(); + // Build stamp (injected by vite) — shown under the brand and logged on launch, // so it's obvious which commit this build is. const BUILD = `v${__APP_VERSION__} · ${__BUILD_SHA__}`; diff --git a/console/src/styles.css b/console/src/styles.css index ea74ab1..03ec2d3 100644 --- a/console/src/styles.css +++ b/console/src/styles.css @@ -1244,6 +1244,38 @@ button.act:disabled { color: var(--muted); } +.config-folder { + display: flex; + flex-direction: column; + gap: 8px; + max-width: 420px; + margin-top: 20px; + padding-top: 16px; + border-top: 1px solid var(--border); +} +.config-folder > label { + font-size: 12px; + color: var(--muted); +} +.config-folder-row { + display: flex; + align-items: center; + gap: 12px; +} +.config-folder-path { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 12px; + color: var(--text); + padding: 6px 8px; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--bg); +} + /* Compose (agent-deployment ADR, slice 1): the deploy panel's bundle-preview step (`deploy.ts`'s `#deploy-compose`) — the standalone authoring tab this used to also style is gone, see compose.ts. */ diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 4d6d0e0..2eb2d58 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -55,6 +55,11 @@ tauri-plugin-updater = "2" # commit rather than the floating `dev` branch for reproducibility. fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", rev = "c4c45d503ea115a839aae718d02f79e7c7f0f673" } +# Native folder-picker dialog (studio#128) — lets the operator choose the +# local "Config folder" the New Fleet wizard mirrors generated config.toml +# files into, instead of a hidden hardcoded path. +tauri-plugin-dialog = "2" + # Its own workspace so the desktop build stays out of the root workspace's # `cargo build --workspace` (kept to the small crates + CI). [workspace] diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 4a8d596..aacca3c 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -9,6 +9,7 @@ "core:default", "shell:allow-stdin-write", "shell:allow-kill", + "dialog:allow-open", { "identifier": "shell:allow-spawn", "allow": [ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 62c03ca..94f5492 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -773,6 +773,7 @@ pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_dialog::init()) .setup(|app| { if cfg!(debug_assertions) { app.handle().plugin(