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.
This commit is contained in:
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,9 +205,20 @@ pub(crate) fn verify_project_dir_in(paths: &Paths, project: &str) -> Result<Path
|
||||
Ok(dir)
|
||||
}
|
||||
|
||||
/// Fehlerkennung „Projekt hat keinen Pool". Der Tray-/Popup-Start fängt genau
|
||||
/// diese ab und öffnet die Pool-Auswahl. Eine Kennung statt Klartext, damit die
|
||||
/// Unterscheidung nicht an einer übersetzbaren Meldung hängt.
|
||||
pub(crate) const NO_POOL: &str = "no-pool";
|
||||
|
||||
/// Pool-Config-Verzeichnis eines Projekts — wird dem Terminal als
|
||||
/// CLAUDE_CONFIG_DIR mitgegeben.
|
||||
///
|
||||
/// Ohne zugewiesenen Pool ist das ein Fehler, kein `Ok(None)`: Sonst startete
|
||||
/// die Session ohne CLAUDE_CONFIG_DIR und übernähme damit stillschweigend
|
||||
/// claudes Default-Verzeichnis samt dessen Login — ein Verzeichnis, das der
|
||||
/// Nutzer nie gewählt hat. `Ok(None)` bleibt allein dem Referenzpool auf
|
||||
/// `~/.claude` vorbehalten: dort ist der Default die ausdrückliche Wahl.
|
||||
///
|
||||
/// Der Pool-Name wird geprüft, obwohl `assign_pool_in` das beim Zuweisen schon
|
||||
/// tut: Die Migration übernimmt Pool-Einträge aus der alten, versionierten
|
||||
/// ai-control.json eines geklonten Repos. Ungeprüft bestimmte ein `../…`
|
||||
@@ -223,7 +234,7 @@ pub(crate) fn project_pool_dir_in(
|
||||
project: &str,
|
||||
) -> Result<Option<PathBuf>, 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]
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user