feat: Projekt-Wechsel mit File-Browser + Nix-Wrapper Audio-Fixes [appimage]
All checks were successful
Build AppImage / build (push) Successful in 9m35s
All checks were successful
Build AppImage / build (push) Successful in 9m35s
- File-Browser Dialog (tauri-plugin-dialog) für Projektverzeichnis-Auswahl - Auto-Name aus Verzeichnisname beim Projekt-Hinzufügen - Nix-Wrapper: GStreamer Core-Plugins (valve) + ffmpeg-headless im PATH - Nix-Wrapper: Version 0.1.1 mit korrektem gstreamer.out Output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
68d2500037
commit
6efbd5de5f
8 changed files with 141 additions and 10 deletions
|
|
@ -52,15 +52,16 @@ let
|
||||||
];
|
];
|
||||||
|
|
||||||
gstPluginPath = pkgs.lib.concatMapStringsSep ":" (p: "${p}/lib/gstreamer-1.0") gstPlugins
|
gstPluginPath = pkgs.lib.concatMapStringsSep ":" (p: "${p}/lib/gstreamer-1.0") gstPlugins
|
||||||
|
+ ":${pkgs.gst_all_1.gstreamer.out}/lib/gstreamer-1.0"
|
||||||
+ ":${pkgs.pipewire}/lib/gstreamer-1.0";
|
+ ":${pkgs.pipewire}/lib/gstreamer-1.0";
|
||||||
|
|
||||||
# Laufzeit-Binaries die die App spawnen muss (node fuer claude-bridge.js,
|
# Laufzeit-Binaries die die App spawnen muss (node fuer claude-bridge.js,
|
||||||
# npm fuer apply_bundle_update, tar fuer Bundle-Extract)
|
# npm fuer apply_bundle_update, tar fuer Bundle-Extract)
|
||||||
runtimeBins = [ pkgs.nodejs_22 pkgs.gnutar pkgs.gzip ];
|
runtimeBins = [ pkgs.nodejs_22 pkgs.gnutar pkgs.gzip pkgs.ffmpeg-headless ];
|
||||||
in
|
in
|
||||||
pkgs.stdenv.mkDerivation {
|
pkgs.stdenv.mkDerivation {
|
||||||
pname = "claude-desktop";
|
pname = "claude-desktop";
|
||||||
version = "0.1.0";
|
version = "0.1.1";
|
||||||
# Keine Quelldateien — Wir packen nur Wrapper + Desktop-Entry
|
# Keine Quelldateien — Wir packen nur Wrapper + Desktop-Entry
|
||||||
dontUnpack = true;
|
dontUnpack = true;
|
||||||
|
|
||||||
|
|
|
||||||
10
package-lock.json
generated
10
package-lock.json
generated
|
|
@ -12,6 +12,7 @@
|
||||||
"@anthropic-ai/claude-code": "^0.2.0",
|
"@anthropic-ai/claude-code": "^0.2.0",
|
||||||
"@anthropic-ai/sdk": "^0.88.0",
|
"@anthropic-ai/sdk": "^0.88.0",
|
||||||
"@tauri-apps/api": "^2.0.0",
|
"@tauri-apps/api": "^2.0.0",
|
||||||
|
"@tauri-apps/plugin-dialog": "^2.7.0",
|
||||||
"@tauri-apps/plugin-shell": "^2.0.0",
|
"@tauri-apps/plugin-shell": "^2.0.0",
|
||||||
"marked": "^18.0.0",
|
"marked": "^18.0.0",
|
||||||
"mermaid": "^11.4.0",
|
"mermaid": "^11.4.0",
|
||||||
|
|
@ -1821,6 +1822,15 @@
|
||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tauri-apps/plugin-dialog": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-4nS/hfGMGCXiAS3LtVjH9AgsSAPJeG/7R+q8agTFqytjnMa4Zq95Bq8WzVDkckpanX+yyRHXnRtrKXkANKDHvw==",
|
||||||
|
"license": "MIT OR Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@tauri-apps/api": "^2.10.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tauri-apps/plugin-shell": {
|
"node_modules/@tauri-apps/plugin-shell": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.3.5.tgz",
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
"@anthropic-ai/claude-code": "^0.2.0",
|
"@anthropic-ai/claude-code": "^0.2.0",
|
||||||
"@anthropic-ai/sdk": "^0.88.0",
|
"@anthropic-ai/sdk": "^0.88.0",
|
||||||
"@tauri-apps/api": "^2.0.0",
|
"@tauri-apps/api": "^2.0.0",
|
||||||
|
"@tauri-apps/plugin-dialog": "^2.7.0",
|
||||||
"@tauri-apps/plugin-shell": "^2.0.0",
|
"@tauri-apps/plugin-shell": "^2.0.0",
|
||||||
"marked": "^18.0.0",
|
"marked": "^18.0.0",
|
||||||
"mermaid": "^11.4.0",
|
"mermaid": "^11.4.0",
|
||||||
|
|
|
||||||
68
src-tauri/Cargo.lock
generated
68
src-tauri/Cargo.lock
generated
|
|
@ -490,6 +490,7 @@ dependencies = [
|
||||||
"sha2",
|
"sha2",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
|
"tauri-plugin-dialog",
|
||||||
"tauri-plugin-shell",
|
"tauri-plugin-shell",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
|
|
@ -2743,6 +2744,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.11.0",
|
"bitflags 2.11.0",
|
||||||
"block2",
|
"block2",
|
||||||
|
"libc",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
@ -3618,6 +3620,30 @@ dependencies = [
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rfd"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672"
|
||||||
|
dependencies = [
|
||||||
|
"block2",
|
||||||
|
"dispatch2",
|
||||||
|
"glib-sys",
|
||||||
|
"gobject-sys",
|
||||||
|
"gtk-sys",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"objc2",
|
||||||
|
"objc2-app-kit",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-foundation",
|
||||||
|
"raw-window-handle",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.14"
|
version = "0.17.14"
|
||||||
|
|
@ -4637,6 +4663,48 @@ dependencies = [
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-dialog"
|
||||||
|
version = "2.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1fa4150c95ae391946cc8b8f905ab14797427caba3a8a2f79628e956da91809"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"raw-window-handle",
|
||||||
|
"rfd",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"tauri-plugin-fs",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-fs"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36e1ec28b79f3d0683f4507e1615c36292c0ea6716668770d4396b9b39871ed8"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"dunce",
|
||||||
|
"glob",
|
||||||
|
"log",
|
||||||
|
"objc2-foundation",
|
||||||
|
"percent-encoding",
|
||||||
|
"schemars 0.8.22",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"tauri-utils",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"toml 0.9.12+spec-1.1.0",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-shell"
|
name = "tauri-plugin-shell"
|
||||||
version = "2.3.5"
|
version = "2.3.5"
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ base64 = "0.22"
|
||||||
tokio-tungstenite = "0.23"
|
tokio-tungstenite = "0.23"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
sha2 = "0.10"
|
sha2 = "0.10"
|
||||||
|
tauri-plugin-dialog = "2.7.0"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
webkit2gtk = "2.0"
|
webkit2gtk = "2.0"
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
"shell:allow-execute",
|
"shell:allow-execute",
|
||||||
"shell:allow-spawn",
|
"shell:allow-spawn",
|
||||||
"shell:allow-stdin-write",
|
"shell:allow-stdin-write",
|
||||||
"shell:allow-kill"
|
"shell:allow-kill",
|
||||||
|
"dialog:allow-open"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ mod chat_window;
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.manage(Arc::new(Mutex::new(claude::ClaudeState::default())))
|
.manage(Arc::new(Mutex::new(claude::ClaudeState::default())))
|
||||||
.manage(guard::GuardState::new(Mutex::new(guard::GuardRails::new())))
|
.manage(guard::GuardState::new(Mutex::new(guard::GuardRails::new())))
|
||||||
.manage::<hooks::HookState>(Arc::new(Mutex::new(hooks::HookManager::default())))
|
.manage::<hooks::HookState>(Arc::new(Mutex::new(hooks::HookManager::default())))
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { listen, type UnlistenFn } from '@tauri-apps/api/event';
|
import { listen, type UnlistenFn } from '@tauri-apps/api/event';
|
||||||
|
import { open } from '@tauri-apps/plugin-dialog';
|
||||||
import { messages, clearAll, isProcessing, currentSessionId, setMessagesFromDb, type DbMessage } from '$lib/stores/app';
|
import { messages, clearAll, isProcessing, currentSessionId, setMessagesFromDb, type DbMessage } from '$lib/stores/app';
|
||||||
|
|
||||||
interface Session {
|
interface Session {
|
||||||
|
|
@ -53,6 +54,27 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function browseDir() {
|
||||||
|
try {
|
||||||
|
const selected = await open({
|
||||||
|
directory: true,
|
||||||
|
multiple: false,
|
||||||
|
title: 'Projektverzeichnis wählen',
|
||||||
|
defaultPath: '/mnt',
|
||||||
|
});
|
||||||
|
if (selected && typeof selected === 'string') {
|
||||||
|
newProjectDir = selected;
|
||||||
|
// Auto-Name aus Verzeichnisname wenn leer
|
||||||
|
if (!newProjectName.trim()) {
|
||||||
|
const parts = selected.replace(/\/+$/, '').split('/');
|
||||||
|
newProjectName = parts[parts.length - 1] || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fehler beim Verzeichnis-Dialog:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function addProject() {
|
async function addProject() {
|
||||||
const name = newProjectName.trim();
|
const name = newProjectName.trim();
|
||||||
const dir = newProjectDir.trim();
|
const dir = newProjectDir.trim();
|
||||||
|
|
@ -274,14 +296,18 @@
|
||||||
placeholder="Projektname"
|
placeholder="Projektname"
|
||||||
onkeydown={(e: KeyboardEvent) => e.key === 'Enter' && addProject()}
|
onkeydown={(e: KeyboardEvent) => e.key === 'Enter' && addProject()}
|
||||||
/>
|
/>
|
||||||
<input
|
<div class="dir-input-row">
|
||||||
type="text"
|
<input
|
||||||
bind:value={newProjectDir}
|
type="text"
|
||||||
placeholder="Verzeichnis (/mnt/...)"
|
bind:value={newProjectDir}
|
||||||
onkeydown={(e: KeyboardEvent) => e.key === 'Enter' && addProject()}
|
placeholder="Verzeichnis wählen..."
|
||||||
/>
|
onkeydown={(e: KeyboardEvent) => e.key === 'Enter' && addProject()}
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
|
<button class="btn-browse" onclick={browseDir} title="Verzeichnis wählen">📂</button>
|
||||||
|
</div>
|
||||||
<div class="project-add-buttons">
|
<div class="project-add-buttons">
|
||||||
<button class="btn-create" onclick={addProject}>Anlegen</button>
|
<button class="btn-create" onclick={addProject} disabled={!newProjectName.trim() || !newProjectDir.trim()}>Anlegen</button>
|
||||||
<button class="btn-cancel" onclick={() => { showProjectAdd = false; newProjectName = ''; newProjectDir = ''; }}>Abbrechen</button>
|
<button class="btn-cancel" onclick={() => { showProjectAdd = false; newProjectName = ''; newProjectDir = ''; }}>Abbrechen</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -541,6 +567,28 @@
|
||||||
padding: var(--spacing-xs) var(--spacing-sm);
|
padding: var(--spacing-xs) var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dir-input-row {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--spacing-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dir-input-row input {
|
||||||
|
flex: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-browse {
|
||||||
|
padding: var(--spacing-xs) var(--spacing-sm);
|
||||||
|
background: var(--accent);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-browse:hover {
|
||||||
|
background: var(--accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
.project-add-buttons {
|
.project-add-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--spacing-xs);
|
gap: var(--spacing-xs);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue