claude-desktop/nix/default.nix
Eddy 384888ccd8
All checks were successful
Build AppImage / build (push) Successful in 8m40s
Nix-Wrapper: whisper-cpp zu runtimeBins hinzugefügt für lokale Transkription [appimage]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 16:20:06 +02:00

186 lines
6.7 KiB
Nix
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Claude Desktop — Nix-Wrapper-Paket
#
# Liefert:
# $out/bin/claude-desktop — Launcher mit LD_LIBRARY_PATH
# $out/bin/claude-desktop-install — Installer (kopiert Binary nach ~/.local/share)
# $out/share/applications/… — Desktop-Entry
# $out/share/icons/… — Icon
#
# Das eigentliche Binary lebt unter ~/.local/share/claude-desktop/bin/claude-desktop
# (writable), damit der Auto-Updater es ersetzen kann. Nix-Store ist read-only und
# waere deshalb inkompatibel mit dem Rename-Trick in apply_update().
#
# Einbinden in /etc/nixos/configuration.nix:
#
# environment.systemPackages = [
# (import /pfad/zum/claude-desktop/nix/default.nix { inherit pkgs; })
# ];
#
# Oder per home-manager:
# home.packages = [ (import ./claude-desktop/nix/default.nix { inherit pkgs; }) ];
{ pkgs ? import <nixpkgs> {} }:
let
# Alle Laufzeit-Libs, die das Tauri-Binary braucht (parallel zu shell.nix).
runtimeLibs = with pkgs; [
webkitgtk_4_1
libappindicator-gtk3
librsvg
gtk3
glib
cairo
pango
gdk-pixbuf
libsoup_3
at-spi2-atk
openssl
# GStreamer + PipeWire fuer WebKitGTK Audio (Mikrofon, getUserMedia)
gst_all_1.gstreamer
gst_all_1.gst-plugins-base
gst_all_1.gst-plugins-good
gst_all_1.gst-plugins-bad
pipewire
alsa-lib
];
# GStreamer-Plugins fuer WebKitGTK (Audio/Video, WebRTC, Mikrofon via PipeWire)
gstPlugins = with pkgs.gst_all_1; [
gst-plugins-base
gst-plugins-good
gst-plugins-bad
];
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 pkgs.ffmpeg-headless pkgs.whisper-cpp ];
in
pkgs.stdenv.mkDerivation {
pname = "claude-desktop";
version = "0.1.2";
# Keine Quelldateien — Wir packen nur Wrapper + Desktop-Entry
dontUnpack = true;
nativeBuildInputs = [ pkgs.makeWrapper ];
installPhase = ''
runHook preInstall
mkdir -p $out/bin $out/share/applications $out/share/icons/hicolor/256x256/apps
# 1) Launcher: startet das User-Binary mit Nix-LD_LIBRARY_PATH
cat > $out/bin/claude-desktop <<'LAUNCHER'
#!${pkgs.bash}/bin/bash
# Claude Desktop NixOS-Launcher
set -e
APP_DIR="$HOME/.local/share/claude-desktop"
BIN="$APP_DIR/bin/claude-desktop"
if [ ! -x "$BIN" ]; then
echo " Claude-Desktop-Binary nicht gefunden: $BIN" >&2
echo "" >&2
echo "Erst installieren (aus fertigem Build in /tmp/claude-target):" >&2
echo " claude-desktop-install" >&2
echo "" >&2
echo "Oder neu bauen im Repo:" >&2
echo " CARGO_TARGET_DIR=/tmp/claude-target \\" >&2
echo " nix-shell shell.nix --run 'npm ci && npm run tauri build'" >&2
echo " claude-desktop-install" >&2
exit 1
fi
# Marker fuer update.rs: wir laufen unter Nix-Wrapper
export CLAUDE_DESKTOP_NIX_WRAPPER=1
export CLAUDE_DESKTOP_BIN="$BIN"
# HiDPI/Fractional-Scaling GTK3 unter Wayland kann kein natives fractional
# scaling. Workaround: Xwayland erzwingen (der Compositor skaliert das Fenster)
# und GDK_DPI_SCALE aus Xft.dpi ableiten, damit Fonts scharf bleiben.
# Override-bar ueber CLAUDE_DESKTOP_SCALE (z.B. "1.5") oder komplett
# deaktivierbar mit CLAUDE_DESKTOP_SCALE=off.
if [ "''${CLAUDE_DESKTOP_SCALE:-}" != "off" ]; then
SCALE="''${CLAUDE_DESKTOP_SCALE:-}"
if [ -z "$SCALE" ] && command -v xrdb >/dev/null 2>&1 && [ -n "''${DISPLAY:-}" ]; then
DPI="$(xrdb -query 2>/dev/null | awk -F':\\s*' '/^Xft.dpi:/ {print $2; exit}')"
if [ -n "$DPI" ] && [ "$DPI" -gt 96 ] 2>/dev/null; then
# bash-only float-Division: auf 2 Stellen runden
SCALE="$(awk -v d="$DPI" 'BEGIN { printf "%.2f", d/96 }')"
fi
fi
if [ -n "$SCALE" ] && [ "$SCALE" != "1.00" ] && [ "$SCALE" != "1.0" ]; then
export GDK_DPI_SCALE="$SCALE"
# Unter Wayland: Xwayland nutzen, damit der Compositor-Scale greift
if [ "''${XDG_SESSION_TYPE:-}" = "wayland" ]; then
export GDK_BACKEND="''${GDK_BACKEND:-x11}"
fi
fi
fi
# GStreamer/PipeWire: Wenn PipeWire NICHT laeuft, pipewiresrc runterranken
# damit WebKitGTK auf pulsesrc zurueckfaellt (sonst haengt getUserMedia endlos)
if ! pgrep -x pipewire >/dev/null 2>&1; then
export GST_PLUGIN_FEATURE_RANK="pipewiresrc:0,pipewiresink:0"
fi
exec "$BIN" "$@"
LAUNCHER
chmod +x $out/bin/claude-desktop
# LD_LIBRARY_PATH + PATH dauerhaft ans Launcher-Script binden
# PATH: node/npm/tar muessen fuer die Bridge und apply_bundle_update verfuegbar sein
# GST_PLUGIN_SYSTEM_PATH_1_0: GStreamer-Plugins fuer WebKitGTK (Mikrofon/PipeWire)
wrapProgram $out/bin/claude-desktop \
--prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath runtimeLibs} \
--prefix PATH : ${pkgs.lib.makeBinPath runtimeBins} \
--prefix GST_PLUGIN_SYSTEM_PATH_1_0 : ${gstPluginPath} \
--prefix XDG_DATA_DIRS : ${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name} \
--prefix XDG_DATA_DIRS : ${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}
# 2) Installer: kopiert ein frisch gebautes Binary an den Ziel-Ort
cat > $out/bin/claude-desktop-install <<'INSTALLER'
#!${pkgs.bash}/bin/bash
set -e
SRC="''${1:-/tmp/claude-target/release/claude-desktop}"
DEST_DIR="$HOME/.local/share/claude-desktop/bin"
DEST="$DEST_DIR/claude-desktop"
if [ ! -x "$SRC" ]; then
echo " Quelle nicht gefunden oder nicht ausfuehrbar: $SRC" >&2
echo "" >&2
echo "Erst bauen:" >&2
echo " cd <repo>; CARGO_TARGET_DIR=/tmp/claude-target \\" >&2
echo " nix-shell shell.nix --run 'npm ci && npm run tauri build'" >&2
exit 1
fi
mkdir -p "$DEST_DIR"
cp "$SRC" "$DEST"
chmod +x "$DEST"
echo " Claude Desktop installiert nach $DEST"
echo " Starten mit: claude-desktop (oder aus KDE-Menue)"
INSTALLER
chmod +x $out/bin/claude-desktop-install
# 3) Desktop-Entry
cp ${./claude-desktop.desktop} $out/share/applications/claude-desktop.desktop
# 4) Icon
cp ${../src-tauri/icons/icon.png} $out/share/icons/hicolor/256x256/apps/claude-desktop.png
runHook postInstall
'';
meta = with pkgs.lib; {
description = "Native Desktop-App fuer Claude Code (Wrapper-Paket, Binary in ~/.local/share)";
homepage = "https://git.data-it-solution.de/data/claude-desktop";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "claude-desktop";
};
}