feat: add proper launcher script for NixOS with --doctor and Wayland support

The Nix build used makeWrapper which bypassed launcher-common.sh
entirely. NixOS users had no --doctor support, no CLAUDE_USE_WAYLAND
env var handling, no display detection, and no startup logging.

Replace makeWrapper with a full bash launcher script that sources
launcher-common.sh, matching the deb/RPM/AppImage launchers:
- --doctor diagnostic support
- CLAUDE_USE_WAYLAND env var for native Wayland mode
- Display backend auto-detection
- Stale lock and socket cleanup
- Startup logging to ~/.cache/claude-desktop-debian/launcher.log
- Cowork resources (smol-bin, plugin shim) installed to resources

Also adds 'nix' package type to build_electron_args for proper
--no-sandbox handling on Wayland.

Refs #282

Co-Authored-By: Claude <claude@anthropic.com>
This commit is contained in:
aaddrick
2026-03-19 08:37:28 -04:00
parent 645ad92c49
commit 99d91acb41
2 changed files with 75 additions and 9 deletions

View File

@@ -9,7 +9,6 @@
nodejs,
nodePackages,
makeDesktopItem,
makeWrapper,
python3,
bash,
getent,
@@ -65,7 +64,6 @@ stdenvNoCC.mkDerivation {
nodePackages.asar
icoutils
imagemagick
makeWrapper
bash
python3
getent
@@ -125,6 +123,15 @@ stdenvNoCC.mkDerivation {
cp -r build/electron-app/nix-resources/claude-ssh $out/lib/claude-desktop/resources/
fi
# Install cowork resources (smol-bin, plugin shim)
for cowork_res in build/electron-app/nix-resources/smol-bin.*.vhdx \
build/electron-app/nix-resources/cowork-plugin-shim.sh; do
if [ -f "$cowork_res" ]; then
cp "$cowork_res" $out/lib/claude-desktop/resources/
echo "Installed cowork resource: $(basename "$cowork_res")"
fi
done
# Install locale JSON files into resources (belt-and-suspenders;
# they're also packed inside app.asar at resources/i18n/)
for locale_json in build/claude-extract/lib/net45/resources/*-*.json; do
@@ -133,16 +140,74 @@ stdenvNoCC.mkDerivation {
fi
done
# Install shared launcher library
install -Dm755 ${sourceRoot}/scripts/launcher-common.sh \
$out/lib/claude-desktop/launcher-common.sh
# Install .desktop file
mkdir -p $out/share/applications
install -Dm644 ${desktopItem}/share/applications/* $out/share/applications/
# Create wrapper script
# Create launcher script (sources launcher-common.sh for --doctor,
# CLAUDE_USE_WAYLAND, display detection, and other shared features
# matching the deb/RPM/AppImage launchers)
mkdir -p $out/bin
makeWrapper ${electron}/bin/electron $out/bin/claude-desktop \
--add-flags "$out/lib/claude-desktop/resources/app.asar" \
--add-flags "--disable-features=CustomTitlebar" \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations}}"
cat > $out/bin/claude-desktop <<'LAUNCHER'
#!/usr/bin/env bash
# Claude Desktop launcher for NixOS
electron_exec="ELECTRON_PLACEHOLDER"
app_path="RESOURCES_PLACEHOLDER/app.asar"
source "LAUNCHER_LIB_PLACEHOLDER"
# Handle --doctor flag before anything else
if [[ "''${1:-}" == '--doctor' ]]; then
run_doctor "$electron_exec"
exit $?
fi
# Setup logging and environment
setup_logging || exit 1
setup_electron_env
cleanup_stale_lock
cleanup_stale_cowork_socket
# Log startup info
log_message '--- Claude Desktop Launcher Start (NixOS) ---'
log_message "Timestamp: $(date)"
log_message "Arguments: $@"
# Check for display
if ! check_display; then
log_message 'No display detected (TTY session)'
echo 'Error: Claude Desktop requires a graphical desktop environment.' >&2
echo 'Please run from within an X11 or Wayland session, not from a TTY.' >&2
exit 1
fi
# Detect display backend (handles CLAUDE_USE_WAYLAND)
detect_display_backend
# Build Electron arguments
build_electron_args 'nix'
# Add app path
electron_args+=("$app_path")
# Execute Electron
log_message "Executing: $electron_exec ''${electron_args[*]} $*"
"$electron_exec" "''${electron_args[@]}" "$@" >> "$log_file" 2>&1
exit_code=$?
log_message "Electron exited with code: $exit_code"
exit $exit_code
LAUNCHER
# Substitute placeholders with Nix store paths
substituteInPlace $out/bin/claude-desktop \
--replace-fail "ELECTRON_PLACEHOLDER" "${electron}/bin/electron" \
--replace-fail "RESOURCES_PLACEHOLDER" "$out/lib/claude-desktop/resources" \
--replace-fail "LAUNCHER_LIB_PLACEHOLDER" "$out/lib/claude-desktop/launcher-common.sh"
chmod +x $out/bin/claude-desktop
runHook postInstall
'';

View File

@@ -73,8 +73,9 @@ build_electron_args() {
return
fi
# Wayland: deb package needs --no-sandbox in both modes
[[ $package_type == 'deb' ]] && electron_args+=('--no-sandbox')
# Wayland: deb/nix packages need --no-sandbox in both modes
[[ $package_type == 'deb' || $package_type == 'nix' ]] \
&& electron_args+=('--no-sandbox')
if [[ $use_x11_on_wayland == true ]]; then
# Default: Use X11 via XWayland for global hotkey support