dot
vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks
dd2e363
3 files changed +95 −5
modifiedmodules/nixos/apps.nix
@@ -34,11 +34,6 @@ | ||
| 34 | 34 | "L+ /usr/share/OVMF/OVMF_CODE_4M.fd - - - - /FV/OVMF_CODE.fd" |
| 35 | 35 | ]; |
| 36 | 36 | |
| 37 | - # The Code tab runs a claude binary the app downloads itself (into | |
| 38 | - # ~/.config/Claude/claude-code), built for generic Linux: it wants the loader | |
| 39 | - # at /lib64/ld-linux-x86-64.so.2, which nix-ld provides. | |
| 40 | - programs.nix-ld.enable = true; | |
| 41 | - | |
| 42 | 37 | # --- OpenDeck ------------------------------------------------------------------- |
| 43 | 38 | |
| 44 | 39 | # Lets your user open the Stream Deck (40-streamdeck.rules on CachyOS). |
@@ -1,0 +1,59 @@ | ||
| 1 | +# Claude Code at the exact version Claude Desktop is built against: the app's | |
| 2 | +# Code tab runs it. Unpatched, the app downloads this same file at run time | |
| 3 | +# into ~/.config/Claude/claude-code, where NixOS can't run it; default.nix | |
| 4 | +# points the app here instead. | |
| 5 | +# | |
| 6 | +# To update (after changing the app's version): the app's pin is in its | |
| 7 | +# app.asar, in the JSON with "baseUrl":"https://downloads.claude.ai/claude-code-releases". | |
| 8 | +# Take "version" and platforms."linux-x64".checksum from it: | |
| 9 | +# asar extract .../resources/app.asar /tmp/app | |
| 10 | +# grep -o '{"version":"[0-9.]*","manifest".\{0,1500\}' /tmp/app/.vite/build/*.js | |
| 11 | +# The app's build fails with a message if the two versions disagree. | |
| 12 | +{ | |
| 13 | + lib, | |
| 14 | + stdenv, | |
| 15 | + fetchurl, | |
| 16 | + zstd, | |
| 17 | + autoPatchelfHook, | |
| 18 | +}: | |
| 19 | + | |
| 20 | +stdenv.mkDerivation (finalAttrs: { | |
| 21 | + pname = "claude-code-for-desktop"; | |
| 22 | + version = "2.1.299"; | |
| 23 | + | |
| 24 | + src = fetchurl { | |
| 25 | + url = "https://downloads.claude.ai/claude-code-releases//linux-x64/claude.zst"; | |
| 26 | + sha256 = "20ca25213130255bacdcae3ed5df3fc99e1d8e86cdf46e9188b7ff9c1b478fa4"; | |
| 27 | + }; | |
| 28 | + | |
| 29 | + nativeBuildInputs = [ | |
| 30 | + zstd | |
| 31 | + autoPatchelfHook | |
| 32 | + ]; | |
| 33 | + | |
| 34 | + dontUnpack = true; | |
| 35 | + # The program's JavaScript is appended to the executable; strip would cut it. | |
| 36 | + dontStrip = true; | |
| 37 | + | |
| 38 | + installPhase = '' | |
| 39 | + runHook preInstall | |
| 40 | + install -d $out/bin | |
| 41 | + zstd -d $src -o $out/bin/claude | |
| 42 | + chmod 755 $out/bin/claude | |
| 43 | + runHook postInstall | |
| 44 | + ''; | |
| 45 | + | |
| 46 | + doInstallCheck = true; | |
| 47 | + installCheckPhase = '' | |
| 48 | + HOME=$TMPDIR $out/bin/claude --version | grep -F | |
| 49 | + ''; | |
| 50 | + | |
| 51 | + meta = { | |
| 52 | + description = "Claude Code, the version Claude Desktop's Code tab runs"; | |
| 53 | + homepage = "https://claude.com/claude-code"; | |
| 54 | + license = lib.licenses.unfree; | |
| 55 | + mainProgram = "claude"; | |
| 56 | + platforms = [ "x86_64-linux" ]; | |
| 57 | + sourceProvenance = [ lib.sourceTypes.binaryNativeCode ]; | |
| 58 | + }; | |
| 59 | +}) |
modifiedpkgs/claude-desktop/default.nix
@@ -7,11 +7,18 @@ | ||
| 7 | 7 | # |
| 8 | 8 | # Cowork also needs QEMU/KVM, the vhost_vsock module and OVMF firmware at the |
| 9 | 9 | # Debian path it looks for; modules/nixos/apps.nix provides those. |
| 10 | +# | |
| 11 | +# The Code tab runs Claude Code from the Nix store (claude-code.nix) rather than | |
| 12 | +# a copy the app downloads, and Python tools use nixpkgs' uv rather than one it | |
| 13 | +# downloads. After a version change, update claude-code.nix too: the build says | |
| 14 | +# so if the app pins a different Claude Code. | |
| 10 | 15 | { |
| 11 | 16 | lib, |
| 12 | 17 | stdenv, |
| 18 | + callPackage, | |
| 13 | 19 | fetchurl, |
| 14 | 20 | dpkg, |
| 21 | + asar, | |
| 15 | 22 | autoPatchelfHook, |
| 16 | 23 | makeWrapper, |
| 17 | 24 | wrapGAppsHook3, |
@@ -55,8 +62,12 @@ | ||
| 55 | 62 | socat, |
| 56 | 63 | bubblewrap, |
| 57 | 64 | openssh, |
| 65 | + uv, | |
| 58 | 66 | }: |
| 59 | 67 | |
| 68 | +let | |
| 69 | + claude-code = callPackage ./claude-code.nix { }; | |
| 70 | +in | |
| 60 | 71 | stdenv.mkDerivation (finalAttrs: { |
| 61 | 72 | pname = "claude-desktop"; |
| 62 | 73 | version = "2.42304.0"; |
@@ -68,6 +79,7 @@ | ||
| 68 | 79 | |
| 69 | 80 | nativeBuildInputs = [ |
| 70 | 81 | dpkg |
| 82 | + asar | |
| 71 | 83 | autoPatchelfHook |
| 72 | 84 | makeWrapper |
| 73 | 85 | wrapGAppsHook3 |
@@ -141,6 +153,27 @@ | ||
| 141 | 153 | # the user-namespace sandbox instead, which needs no helper. |
| 142 | 154 | rm $out/lib/claude-desktop/chrome-sandbox |
| 143 | 155 | |
| 156 | + # The app has an override for running a Claude Code that's already on disk | |
| 157 | + # instead of downloading one; release builds compile out the part that | |
| 158 | + # reads it. This puts it back, pointing at the store path. The app then | |
| 159 | + # also leaves Claude Code updates alone: they come with this package. | |
| 160 | + res=$out/lib/claude-desktop/resources | |
| 161 | + asar extract $res/app.asar app | |
| 162 | + pin=$(grep -l '"baseUrl":"https://downloads.claude.ai/claude-code-releases"' app/.vite/build/*.js) | |
| 163 | + if ! grep -qF '{"version":"${claude-code.version}","manifest"' $pin; then | |
| 164 | + echo "claude-desktop: the app pins another Claude Code than ${claude-code.version}; update claude-code.nix" >&2 | |
| 165 | + exit 1 | |
| 166 | + fi | |
| 167 | + hook='process.env.CLAUDE_CODE_LOCAL_BINARY}async initLocalBinary(' | |
| 168 | + if ! file=$(grep -lF "$hook" app/.vite/build/*.js); then | |
| 169 | + echo "claude-desktop: the app's Claude Code override has changed; see the comment above" >&2 | |
| 170 | + exit 1 | |
| 171 | + fi | |
| 172 | + substituteInPlace $file --replace-fail "$hook" \ | |
| 173 | + 'this.localBinaryInitPromise=this.initLocalBinary("${lib.getExe claude-code}")}async initLocalBinary(' | |
| 174 | + rm -r $res/app.asar $res/app.asar.unpacked | |
| 175 | + asar pack app $res/app.asar --unpack '{*.node,github-mcp-server}' | |
| 176 | + | |
| 144 | 177 | runHook postInstall |
| 145 | 178 | ''; |
| 146 | 179 | |
@@ -155,10 +188,13 @@ | ||
| 155 | 188 | socat |
| 156 | 189 | bubblewrap |
| 157 | 190 | openssh |
| 191 | + uv | |
| 158 | 192 | ] |
| 159 | 193 | } |
| 160 | 194 | ''; |
| 161 | 195 | |
| 196 | + passthru = { inherit claude-code; }; | |
| 197 | + | |
| 162 | 198 | meta = { |
| 163 | 199 | description = "Claude desktop app (official Linux beta build)"; |
| 164 | 200 | homepage = "https://claude.ai/download"; |