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
|
||||
+ ":${pkgs.gst_all_1.gstreamer.out}/lib/gstreamer-1.0"
|
||||
+ ":${pkgs.pipewire}/lib/gstreamer-1.0";
|
||||
|
||||
# Laufzeit-Binaries die die App spawnen muss (node fuer claude-bridge.js,
|
||||
# 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
|
||||
pkgs.stdenv.mkDerivation {
|
||||
pname = "claude-desktop";
|
||||
version = "0.1.0";
|
||||
version = "0.1.1";
|
||||
# Keine Quelldateien — Wir packen nur Wrapper + Desktop-Entry
|
||||
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/sdk": "^0.88.0",
|
||||
"@tauri-apps/api": "^2.0.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.7.0",
|
||||
"@tauri-apps/plugin-shell": "^2.0.0",
|
||||
"marked": "^18.0.0",
|
||||
"mermaid": "^11.4.0",
|
||||
|
|
@ -1821,6 +1822,15 @@
|
|||
"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": {
|
||||
"version": "2.3.5",
|
||||
"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/sdk": "^0.88.0",
|
||||
"@tauri-apps/api": "^2.0.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.7.0",
|
||||
"@tauri-apps/plugin-shell": "^2.0.0",
|
||||
"marked": "^18.0.0",
|
||||
"mermaid": "^11.4.0",
|
||||
|
|
|
|||
68
src-tauri/Cargo.lock
generated
68
src-tauri/Cargo.lock
generated
|
|
@ -490,6 +490,7 @@ dependencies = [
|
|||
"sha2",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-shell",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
|
|
@ -2743,6 +2744,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
|
|||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2",
|
||||
"libc",
|
||||
"objc2",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
|
@ -3618,6 +3620,30 @@ dependencies = [
|
|||
"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]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
|
|
@ -4637,6 +4663,48 @@ dependencies = [
|
|||
"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]]
|
||||
name = "tauri-plugin-shell"
|
||||
version = "2.3.5"
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ base64 = "0.22"
|
|||
tokio-tungstenite = "0.23"
|
||||
futures-util = "0.3"
|
||||
sha2 = "0.10"
|
||||
tauri-plugin-dialog = "2.7.0"
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
webkit2gtk = "2.0"
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"shell:allow-execute",
|
||||
"shell:allow-spawn",
|
||||
"shell:allow-stdin-write",
|
||||
"shell:allow-kill"
|
||||
"shell:allow-kill",
|
||||
"dialog:allow-open"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ mod chat_window;
|
|||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.manage(Arc::new(Mutex::new(claude::ClaudeState::default())))
|
||||
.manage(guard::GuardState::new(Mutex::new(guard::GuardRails::new())))
|
||||
.manage::<hooks::HookState>(Arc::new(Mutex::new(hooks::HookManager::default())))
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { onMount, onDestroy } from 'svelte';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
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';
|
||||
|
||||
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() {
|
||||
const name = newProjectName.trim();
|
||||
const dir = newProjectDir.trim();
|
||||
|
|
@ -274,14 +296,18 @@
|
|||
placeholder="Projektname"
|
||||
onkeydown={(e: KeyboardEvent) => e.key === 'Enter' && addProject()}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
bind:value={newProjectDir}
|
||||
placeholder="Verzeichnis (/mnt/...)"
|
||||
onkeydown={(e: KeyboardEvent) => e.key === 'Enter' && addProject()}
|
||||
/>
|
||||
<div class="dir-input-row">
|
||||
<input
|
||||
type="text"
|
||||
bind:value={newProjectDir}
|
||||
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">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -541,6 +567,28 @@
|
|||
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 {
|
||||
display: flex;
|
||||
gap: var(--spacing-xs);
|
||||
|
|
|
|||
Loading…
Reference in a new issue