From 082422c32a987d0b13fd8bf48b4e29366a948db4 Mon Sep 17 00:00:00 2001 From: "marcus.hinz" Date: Sun, 26 Jul 2026 21:01:41 +0200 Subject: [PATCH] Tray-Start ohne Pool oeffnet die Pool-Auswahl Ein Projekt ohne zugewiesenen Pool liefert jetzt den Fehler NO_POOL, statt still claudes Default-CLAUDE_CONFIG_DIR zu uebernehmen. Der Tray-/Popup-Start faengt ihn ab, holt das Hauptfenster nach vorn und oeffnet die Pool-Auswahl (pool-required-Event, ProjectList), mit Tests. --- src-tauri/src/commands.rs | 18 ++++++- src-tauri/src/domain/project.rs | 25 ++++++++- src-tauri/src/terminal.rs | 4 ++ src/components/ProjectList.vue | 90 ++++++++++++++++++++++++++++++++- src/messages.ts | 12 +++++ 5 files changed, 145 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index fca7c17..6626228 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -291,6 +291,18 @@ pub(crate) fn restart_project(app: tauri::AppHandle, project: String) -> Result< terminal::open_terminal(app, project) } +/// Projekt ohne Pool: Hauptfenster nach vorn holen und dort die Pool-Auswahl +/// öffnen. Aus dem Tray heraus gibt es sonst keinen Ort für die Wahl — und +/// still den Default zu nehmen ist genau das, was die Pool-Pflicht verhindert. +fn request_pool_choice(app: &tauri::AppHandle, project: &str) { + use tauri::{Emitter, Manager}; + if let Some(w) = app.get_webview_window("main") { + let _ = w.show(); + let _ = w.set_focus(); + } + let _ = app.emit("pool-required", project); +} + /// Tray-Klick auf ein Projekt: läuft es, kommt das Terminal-Fenster nach vorn, /// sonst startet es. fn start_or_focus(app: &tauri::AppHandle, project: &str) { @@ -298,7 +310,11 @@ fn start_or_focus(app: &tauri::AppHandle, project: &str) { Some(pid) => crate::platform::focus_terminal(*pid), None => { if let Err(e) = terminal::open_terminal(app.clone(), project.to_string()) { - eprintln!("{project} starten: {e}"); + if e == crate::domain::project::NO_POOL { + request_pool_choice(app, project); + } else { + eprintln!("{project} starten: {e}"); + } } } } diff --git a/src-tauri/src/domain/project.rs b/src-tauri/src/domain/project.rs index 891fd2d..ba4e32c 100644 --- a/src-tauri/src/domain/project.rs +++ b/src-tauri/src/domain/project.rs @@ -205,9 +205,20 @@ pub(crate) fn verify_project_dir_in(paths: &Paths, project: &str) -> Result Result, String> { let Some(pool) = project_pool(paths, project)? else { - return Ok(None); + return Err(NO_POOL.to_string()); }; check_name(&pool).map_err(|_| format!("ungültiger Pool in der Registry: {pool}"))?; let dir = crate::domain::pool::pool_config_dir(paths, &pool)?; @@ -798,6 +809,18 @@ mod tests { assert!(err.contains("ungültiger Pool")); } + /// Ohne zugewiesenen Pool gibt es kein CLAUDE_CONFIG_DIR und damit auch + /// keine Session: Der Fehler trägt die Kennung, an der der Tray-Start die + /// Pool-Auswahl öffnet. Ein stilles `Ok(None)` würde claudes + /// Default-Verzeichnis ungefragt übernehmen. + #[test] + fn projekt_ohne_pool_liefert_fehler() { + let p = tmp_paths(); + create_project(&p, "ohne").unwrap(); + + assert_eq!(project_pool_dir_in(&p, "ohne").unwrap_err(), NO_POOL); + } + /// Das Setzen der Terminal-Config kommt aus der Oberfläche und kennt nur /// theme/icon/title — unbekannte Keys müssen trotzdem stehen bleiben. #[test] diff --git a/src-tauri/src/terminal.rs b/src-tauri/src/terminal.rs index 34ab83f..fc1e406 100644 --- a/src-tauri/src/terminal.rs +++ b/src-tauri/src/terminal.rs @@ -38,6 +38,10 @@ pub fn open_terminal(app: AppHandle, project: String) -> Result<(), String> { if !dir.is_dir() { return Err(format!("Projektordner fehlt: {}", dir.display())); } + // Pool-Pflicht vor dem Fenster: Ohne zugewiesenen Pool gibt es kein + // Terminal. Die Prüfung gehört hierher und nicht erst in `term_start` — + // dort stünde bereits ein Fenster, das nur noch scheitern könnte. + project_pool_dir(&project)?; let bundle_id = app.config().identifier.clone(); app .run_on_main_thread(move || crate::platform::yield_activation(&bundle_id)) diff --git a/src/components/ProjectList.vue b/src/components/ProjectList.vue index ba38a76..76bb8da 100644 --- a/src/components/ProjectList.vue +++ b/src/components/ProjectList.vue @@ -1,7 +1,11 @@