Projekt-Identität und -Config neu: .ai-control/config.json mit UUID und Name
- Projekt-Config zieht von ai-control.json nach .ai-control/config.json um, das Icon liegt daneben und synct mit dem Projekt. - Jedes Projekt trägt eine UUID (id) und den Anzeigenamen (name) in der Config; die UUID ist Registry-Schlüssel und project-Parameter aller Commands, der Name reine Darstellung. - Pool-Zuordnung ist maschinenlokal und liegt in der projects.json-Registry, nicht mehr in der syncbaren Projekt-Config. - open_terminal prüft die ID im Ordner gegen die Registry (verschobene oder ersetzte Ordner scheitern laut). - Import übernimmt eine mitgebrachte ID, legt Arbeitsordner und Archiv-Home an und zieht die Archiv-Permission nach. - Migration beim App-Start: Alt-Datei umziehen, Pool in die Registry, Icons aus ~/.config/ai-control/icons ins Projekt, Registry auf UUIDs. - ProjectConfig reicht unbekannte Keys per serde(flatten) durch den Round-Trip (Regressionstest config_roundtrip_erhaelt_fremde_keys).
This commit is contained in:
@@ -6,7 +6,9 @@ use std::sync::Mutex;
|
||||
use tauri::{AppHandle, Emitter, Manager, State, WebviewUrl, WebviewWindowBuilder};
|
||||
|
||||
use crate::domain::paths::{commands_file, panel_file, search_file, wiki_file, Paths};
|
||||
use crate::domain::project::{project_pool_dir, terminal_config, TerminalConfig};
|
||||
use crate::domain::project::{
|
||||
project_config, project_pool_dir, verify_project_dir_in, ProjectConfig,
|
||||
};
|
||||
use crate::domain::registry::project_dir;
|
||||
use crate::domain::settings::claude_command;
|
||||
|
||||
@@ -27,7 +29,10 @@ pub struct Terminals(pub Mutex<HashMap<String, Session>>);
|
||||
/// das Terminal-Fenster hinter der aktiven App.
|
||||
#[tauri::command]
|
||||
pub fn open_terminal(app: AppHandle, project: String) -> Result<(), String> {
|
||||
let dir = project_dir(&Paths::real(), &project)?;
|
||||
// Prüft zugleich die Projekt-Identität: die config.json im registrierten
|
||||
// Ordner muss diese Projekt-ID tragen (verschobene/ersetzte Ordner fallen
|
||||
// hier auf, statt eine fremde Session zu starten).
|
||||
let dir = verify_project_dir_in(&Paths::real(), &project)?;
|
||||
if !dir.is_dir() {
|
||||
return Err(format!("Projektordner fehlt: {}", dir.display()));
|
||||
}
|
||||
@@ -61,10 +66,15 @@ fn theme_background(theme: &str) -> (u8, u8, u8) {
|
||||
pub fn build_window(
|
||||
app: &AppHandle,
|
||||
project: &str,
|
||||
cfg: &TerminalConfig,
|
||||
cfg: &ProjectConfig,
|
||||
) -> tauri::Result<()> {
|
||||
let (r, g, b) = theme_background(cfg.theme.as_deref().unwrap_or_default());
|
||||
let title = cfg.title.as_deref().unwrap_or(project);
|
||||
let (r, g, b) = theme_background(cfg.terminal.theme.as_deref().unwrap_or_default());
|
||||
let title = cfg
|
||||
.terminal
|
||||
.title
|
||||
.as_deref()
|
||||
.or(cfg.name.as_deref())
|
||||
.unwrap_or(project);
|
||||
let builder = WebviewWindowBuilder::new(
|
||||
app,
|
||||
format!("term-{project}"),
|
||||
@@ -369,9 +379,14 @@ pub async fn open_panel_window(app: AppHandle, project: String) -> Result<(), St
|
||||
let _ = w.set_focus();
|
||||
return Ok(());
|
||||
}
|
||||
let cfg = terminal_config(&project)?;
|
||||
let (r, g, b) = theme_background(cfg.theme.as_deref().unwrap_or_default());
|
||||
let title = cfg.title.as_deref().unwrap_or(project.as_str());
|
||||
let cfg = project_config(&project)?;
|
||||
let (r, g, b) = theme_background(cfg.terminal.theme.as_deref().unwrap_or_default());
|
||||
let title = cfg
|
||||
.terminal
|
||||
.title
|
||||
.as_deref()
|
||||
.or(cfg.name.as_deref())
|
||||
.unwrap_or(project.as_str());
|
||||
let builder = WebviewWindowBuilder::new(
|
||||
&app,
|
||||
&label,
|
||||
|
||||
Reference in New Issue
Block a user