From 6a3aae64e26a3759ac4d75adb8be7fbbfed3e77f Mon Sep 17 00:00:00 2001 From: Alexis Williams Date: Sat, 28 Feb 2026 15:26:03 -0800 Subject: [PATCH] fix: address PR review feedback for Nix flake integration - Filter sourceRoot with lib.cleanSourceWith to exclude build-reference/, logs/, test-build/, squashfs-root/, and result* from the Nix store - Add -n guard for node_pty_build_dir in finalize_app_asar elif branch - Update Nix package to version 1.1.4498 with current URLs and SRI hashes - Download SRI hash inputs to temp files to catch partial download failures - Extract nested command substitutions into variables for CI sed patterns - Add structural assumption comment for range-based sed hash updates - Validate --source-dir and --node-pty-dir paths early with clear errors - Support SSH helpers in nix builds via nix-resources staging directory Co-Authored-By: Claude --- .github/workflows/check-claude-version.yml | 21 ++++++++++++---- build.sh | 24 +++++++++++-------- nix/claude-desktop.nix | 28 ++++++++++++++++------ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/.github/workflows/check-claude-version.yml b/.github/workflows/check-claude-version.yml index 09dc87c..970fd14 100644 --- a/.github/workflows/check-claude-version.yml +++ b/.github/workflows/check-claude-version.yml @@ -165,12 +165,19 @@ jobs: AMD64_URL="${{ steps.resolve_urls.outputs.amd64_url }}" ARM64_URL="${{ steps.resolve_urls.outputs.arm64_url }}" - # Download and compute SHA256 in SRI format - AMD64_HASH=$(curl -fsSL "$AMD64_URL" | sha256sum | awk '{print $1}' | xxd -r -p | base64 -w0) + # Download to temp files first so a partial download doesn't + # produce a valid-looking but wrong SRI hash. + amd64_tmp=$(mktemp) + curl -fsSL -o "$amd64_tmp" "$AMD64_URL" || { echo "AMD64 download failed"; exit 1; } + AMD64_HASH=$(sha256sum "$amd64_tmp" | awk '{print $1}' | xxd -r -p | base64 -w0) + rm "$amd64_tmp" echo "amd64_sri=sha256-$AMD64_HASH" >> $GITHUB_OUTPUT if [ -n "$ARM64_URL" ]; then - ARM64_HASH=$(curl -fsSL "$ARM64_URL" | sha256sum | awk '{print $1}' | xxd -r -p | base64 -w0) + arm64_tmp=$(mktemp) + curl -fsSL -o "$arm64_tmp" "$ARM64_URL" || { echo "ARM64 download failed"; exit 1; } + ARM64_HASH=$(sha256sum "$arm64_tmp" | awk '{print $1}' | xxd -r -p | base64 -w0) + rm "$arm64_tmp" echo "arm64_sri=sha256-$ARM64_HASH" >> $GITHUB_OUTPUT fi @@ -189,12 +196,16 @@ jobs: sed -i "s/version = \"[^\"]*\"/version = \"$CLAUDE_VERSION\"/" "$NIX_FILE" # Update amd64 URL and hash - sed -i "s|releases/win32/x64/[^\"]*|$(echo "$NEW_AMD64_URL" | sed 's|.*releases/|releases/|')|" "$NIX_FILE" + AMD64_PATH=$(echo "$NEW_AMD64_URL" | sed 's|.*releases/|releases/|') + sed -i "s|releases/win32/x64/[^\"]*|$AMD64_PATH|" "$NIX_FILE" + # Range assumes each arch block (x86_64-linux/aarch64-linux) contains + # exactly one `hash = "..."` line before its closing `};`. sed -i "/x86_64-linux/,/};/{s|hash = \"[^\"]*\"|hash = \"$AMD64_SRI\"|}" "$NIX_FILE" # Update arm64 URL and hash if [ -n "$NEW_ARM64_URL" ]; then - sed -i "s|releases/win32/arm64/[^\"]*|$(echo "$NEW_ARM64_URL" | sed 's|.*releases/|releases/|')|" "$NIX_FILE" + ARM64_PATH=$(echo "$NEW_ARM64_URL" | sed 's|.*releases/|releases/|') + sed -i "s|releases/win32/arm64/[^\"]*|$ARM64_PATH|" "$NIX_FILE" sed -i "/aarch64-linux/,/};/{s|hash = \"[^\"]*\"|hash = \"$ARM64_SRI\"|}" "$NIX_FILE" fi diff --git a/build.sh b/build.sh index 6fedb3c..1e859bc 100755 --- a/build.sh +++ b/build.sh @@ -240,6 +240,15 @@ parse_arguments() { build_format="${build_format,,}" cleanup_action="${cleanup_action,,}" + if [[ ! -d $source_dir ]]; then + echo "Error: --source-dir path does not exist: $source_dir" >&2 + exit 1 + fi + if [[ -n $node_pty_dir && ! -d $node_pty_dir ]]; then + echo "Error: --node-pty-dir path does not exist: $node_pty_dir" >&2 + exit 1 + fi + if [[ $build_format != 'deb' && $build_format != 'rpm' && $build_format != 'appimage' && $build_format != 'nix' ]]; then echo "Invalid build format specified: '$build_format'. Must be 'deb', 'rpm', 'appimage', or 'nix'." >&2 exit 1 @@ -1195,7 +1204,7 @@ finalize_app_asar() { local pty_release_dir='' if [[ -n $node_pty_dir && -d $node_pty_dir/build/Release ]]; then pty_release_dir="$node_pty_dir/build/Release" - elif [[ -d $node_pty_build_dir/node_modules/node-pty/build/Release ]]; then + elif [[ -n $node_pty_build_dir && -d $node_pty_build_dir/node_modules/node-pty/build/Release ]]; then pty_release_dir="$node_pty_build_dir/node_modules/node-pty/build/Release" fi @@ -1330,12 +1339,7 @@ copy_ssh_helpers() { section_header 'SSH Helpers' local ssh_src="$claude_extract_dir/lib/net45/resources/claude-ssh" - local ssh_dest - if [[ $build_format == 'nix' ]]; then - ssh_dest="$app_staging_dir/ssh-helpers/claude-ssh" - else - ssh_dest="$electron_resources_dest/claude-ssh" - fi + local ssh_dest="$electron_resources_dest/claude-ssh" local binary_name="claude-ssh-linux-$architecture" if [[ ! -d "$ssh_src" ]]; then @@ -1572,9 +1576,9 @@ main() { copy_locale_files else # Nix installPhase handles Electron staging and locale files. - # Set a tray icon destination so process_icons has somewhere to - # write them; the Nix installPhase picks them up from here. - electron_resources_dest="$app_staging_dir/tray-icons" + # Set a resources destination so process_icons and copy_ssh_helpers + # have somewhere to write; the Nix installPhase picks them up. + electron_resources_dest="$app_staging_dir/nix-resources" mkdir -p "$electron_resources_dest" || exit 1 fi process_icons diff --git a/nix/claude-desktop.nix b/nix/claude-desktop.nix index 0aca68d..c7e6444 100644 --- a/nix/claude-desktop.nix +++ b/nix/claude-desktop.nix @@ -17,22 +17,31 @@ }: let pname = "claude-desktop"; - version = "1.1.4328"; + version = "1.1.4498"; srcs = { x86_64-linux = fetchurl { - url = "https://downloads.claude.ai/releases/win32/x64/${version}/Claude-d8e39139e1c50f5530ac3da3af80e689710c8ea1.exe"; - hash = "sha256-ngFY1mYwBIZLOYD5I7Lz/v5OexUKNe4MUHcq8VOejI4="; + url = "https://downloads.claude.ai/releases/win32/x64/${version}/Claude-24f7682cc400dec8d91fc28e444aa02743ab79dd.exe"; + hash = "sha256-4Mp9vYwz9Pp+s1hoor7voJoahBq0AUncRneEZYewpd8="; }; aarch64-linux = fetchurl { - url = "https://downloads.claude.ai/releases/win32/arm64/${version}/Claude-d8e39139e1c50f5530ac3da3af80e689710c8ea1.exe"; - hash = "sha256-PvKw6JpfLIhzbcrfogLltHNKyZfJtHOpOrGb+vcOkSM="; + url = "https://downloads.claude.ai/releases/win32/arm64/${version}/Claude-24f7682cc400dec8d91fc28e444aa02743ab79dd.exe"; + hash = "sha256-YOES86CgNfeJZFoDswZWvgAqG9xzqR2Qb+yu/imi1Ak="; }; }; src = srcs.${stdenvNoCC.hostPlatform.system} or (throw "Unsupported system: ${stdenvNoCC.hostPlatform.system}"); - sourceRoot = ./..; + sourceRoot = lib.cleanSourceWith { + src = ./..; + filter = path: type: + let rel = lib.removePrefix (toString ./.. + "/") path; + in !(lib.hasPrefix "build-reference" rel) + && !(lib.hasPrefix "logs" rel) + && !(lib.hasPrefix "test-build" rel) + && !(lib.hasPrefix "squashfs-root" rel) + && !(lib.hasPrefix "result" rel); + }; desktopItem = makeDesktopItem { name = "claude-desktop"; @@ -105,12 +114,17 @@ stdenvNoCC.mkDerivation { done # Install tray icons into resources - for tray_icon in build/electron-app/tray-icons/Tray*; do + for tray_icon in build/electron-app/nix-resources/Tray*; do if [ -f "$tray_icon" ]; then cp "$tray_icon" $out/lib/claude-desktop/resources/ fi done + # Install SSH helpers into resources + if [ -d build/electron-app/nix-resources/claude-ssh ]; then + cp -r build/electron-app/nix-resources/claude-ssh $out/lib/claude-desktop/resources/ + fi + # 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