Icons zentral unter ~/.config/ai-control/icons (pool-/repo-unabhängig), nicht ladbares Icon crasht den Tray nicht mehr; Arbeitsordner nachträglich im ⚙︎-Dialog erfassbar (additionalDirectories + Edit-Permission); Import-Button umbenannt; claudeCommand konfigurierbar + CLAUDE_CONFIG_DIR aus Pool; Pool-Tabellen-Layout; README englisch mit Screenshots; MIT-Lizenz

This commit is contained in:
marcus.hinz
2026-07-05 15:19:58 +02:00
parent b5995da755
commit 0908385a9d
14 changed files with 329 additions and 83 deletions
+39
View File
@@ -156,6 +156,7 @@ interface TerminalSettings {
icon: string | null;
title: string;
todo: boolean;
workDirs: string[];
}
const settings = ref<TerminalSettings | null>(null);
@@ -163,18 +164,46 @@ const settings = ref<TerminalSettings | null>(null);
async function openSettings(p: Project) {
try {
const todo = await invoke<boolean>("todo_state", { project: p.name });
const workDirs = await invoke<string[]>("project_work_dirs", {
project: p.name,
});
settings.value = {
name: p.name,
theme: p.terminal.theme ?? "mocha",
icon: p.terminal.icon,
title: p.terminal.title ?? "",
todo,
workDirs,
};
} catch (e) {
error.value = String(e);
}
}
// Arbeitsordner schreiben direkt in die Projekt-settings.json
// (additionalDirectories + Edit-Permission) — kein Speichern-Schritt.
async function addWorkDir() {
const s = settings.value!;
const dir = await open({ directory: true, multiple: false });
if (typeof dir !== "string") return;
try {
await invoke("add_work_dir", { project: s.name, dir });
s.workDirs = await invoke<string[]>("project_work_dirs", { project: s.name });
} catch (e) {
error.value = String(e);
}
}
async function removeWorkDir(dir: string) {
const s = settings.value!;
try {
await invoke("remove_work_dir", { project: s.name, dir });
s.workDirs = await invoke<string[]>("project_work_dirs", { project: s.name });
} catch (e) {
error.value = String(e);
}
}
async function pickIcon() {
const file = await open({
multiple: false,
@@ -588,6 +617,16 @@ onUnmounted(() => window.clearInterval(timer));
<span v-else class="icon-path">{{ $t("projects.defaultIcon") }}</span>
</span>
</label>
<label class="field">
{{ $t("projects.workDir") }}
<span class="workdirs">
<span v-for="wd in settings.workDirs" :key="wd" class="icon-row">
<span class="icon-path">{{ wd }}</span>
<button @click="removeWorkDir(wd)">{{ $t("projects.remove") }}</button>
</span>
<button @click="addWorkDir">{{ $t("projects.addWorkDir") }}</button>
</span>
</label>
<label class="field">
{{ $t("projects.todo") }}
<span class="checkline">
+4 -2
View File
@@ -51,8 +51,9 @@ const de = {
needsPool: "Kein Pool zugeordnet",
needsKey: "Pool hat keinen API-Key",
newProject: "+ Projekt",
addFolder: "+ Ordner",
addFolder: "Projekt importieren …",
addFolderTitle: "Bestehenden Ordner als Projekt aufnehmen",
addWorkDir: "Ordner hinzufügen …",
wizardTitle: "Neues Projekt",
name: "Name",
projectDir: "Projektordner",
@@ -173,8 +174,9 @@ const en: typeof de = {
needsPool: "No pool assigned",
needsKey: "Pool has no API key",
newProject: "+ Project",
addFolder: "+ Folder",
addFolder: "Import project …",
addFolderTitle: "Add an existing folder as a project",
addWorkDir: "Add folder …",
wizardTitle: "New project",
name: "Name",
projectDir: "Project folder",
+9 -2
View File
@@ -205,7 +205,7 @@ button.danger:hover:not(:disabled) {
}
.row-actions .w-action {
width: 9.5rem;
width: 7.5rem;
}
/* Tooltip-Träger um den Löschen-Button: ein disabled Button empfängt keine
@@ -351,7 +351,7 @@ col.col-actions {
width: 15rem;
}
col.col-actions-wide {
width: 16rem;
width: 21rem;
}
col.col-type {
width: 7rem;
@@ -583,6 +583,13 @@ td select {
gap: 0.5rem;
}
.workdirs {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.35rem;
}
.icon-path {
font-family: var(--mono);
color: var(--overlay);