Versioning rework for Google Play 3-field compatibility:
old: version.txt = "0.2" artifact = v0.2.<BUILD>
new: version.txt = "2.0" artifact = v2.1.<BUILD> (next build)
artifact = v2.2.<BUILD> (the one after)
...
MAJOR stays at 2 until a human bumps it for a real milestone. MINOR is
now owned by CI and incremented by 1 on every successful build. The
"Read and bump version" step writes version.txt locally and emits a
'bumped=yes' output; the final step commits the new version.txt back
to the branch with a "[skip ci]" marker.
Infinite-loop guards (3 layers):
1. Job-level `if:` filter skips builds triggered by [skip ci] commits
2. Step-level grep on HEAD commit message prevents double-bumps even
if a runner doesn't honor workflow-level [skip ci]
3. `git diff --quiet` sanity check before pushing — nothing to push if
version.txt wasn't actually modified
Push uses `secrets.GITHUB_TOKEN` (Forgejo auto-token) with the token
embedded in the HTTPS URL; no separate secret required.
Also: corrected the AppImage "+x stripped" wording on the site. Modern
Linux desktops often DO preserve the executable bit when the server
advertises application/vnd.appimage or when AppImageLauncher is
installed. The chmod step is now framed as a fallback, not a universal
requirement. BUILD_CONVENTIONS.md updated accordingly with the nginx
MIME-type snippet that enables the preserved-+x path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .forgejo/workflows | ||
| DOCS | ||
| scripts | ||
| site | ||
| src/patchy-cnb | ||
| .gitignore | ||
| LICENSE-APACHE | ||
| LICENSE-MIT | ||
| Makefile | ||
| README.md | ||
| version.txt | ||
claude-desktop-linux
Builds Claude Desktop for Linux by repackaging the official Windows release. Supports both Debian/Ubuntu (apt) and Fedora/RHEL (dnf) systems.
Each build step saves its output to disk so you can inspect or modify the intermediate files — extracted installer, patched asar contents, compiled native stub — before continuing.
Quick start
# 1. Install system dependencies (Debian/Ubuntu)
sudo apt-get install p7zip-full imagemagick icoutils wget
sudo pnpm install -g electron # or: npm install -g electron
# 1. Install system dependencies (Fedora/RHEL)
sudo dnf install p7zip p7zip-plugins ImageMagick icoutils wget
sudo pnpm install -g electron
# Also required: node, pnpm, cargo/rustc (see Dependencies section)
# 2. Build (all at once, or step by step)
make
# 3. Install
make install
# 4. Enable the Claude protocol handler (for Google login)
xdg-mime default claude-desktop.desktop x-scheme-handler/claude
Step-by-step workflow
Run steps individually to inspect intermediate files between each one:
make fetch # → assets/Claude-Setup-x64.exe (browse: ls assets/)
make extract # → build/extracted/ (browse: ls build/extracted/lib/net45/)
make stub # → build/patchy-cnb.node (verify: file build/patchy-cnb.node)
make patch # → build/app.asar.contents/ (edit JS here if needed)
make pack # → dist/lib/claude-desktop/app.asar
make icons # → dist/share/icons/
make desktop # → dist/bin/claude-desktop + .desktop entry
make install # → ~/.local/
After make patch you can freely edit any files in build/app.asar.contents/
before running make pack — no need to re-fetch or recompile the stub.
Directory layout
claude-desktop-linux/
├── Makefile ← all build logic
├── src/
│ └── patchy-cnb/ ← Rust NAPI stub source
│ ├── Cargo.toml
│ ├── package.json
│ └── src/lib.rs
├── LICENSE-MIT
└── LICENSE-APACHE
Generated at build time (gitignored):
├── assets/
│ └── Claude-Setup-x64.exe ← make fetch (persists across clean)
├── build/
│ ├── extracted/ ← make extract (inspectable)
│ ├── app.asar.contents/ ← make patch (modifiable before pack)
│ └── patchy-cnb.node ← make stub
└── dist/ ← make desktop (final installable tree)
├── bin/claude-desktop
├── lib/claude-desktop/app.asar
└── share/
Updating to a new Claude Desktop version
Anthropic's download URL embeds both the version number and a build hash — no auto-discovery is available. When a new release ships:
- Find the new URL (check community repos such as aaddrick/claude-desktop-debian or k3d3/claude-desktop-linux-flake)
- Edit the three lines at the top of
Makefile:CLAUDE_VERSION := <new-version> CLAUDE_HASH := <new-hash> CLAUDE_SHA256 := <new-sha256> - Rebuild:
make distclean && make
Make targets
| Target | Description |
|---|---|
make / make all |
Full build (default) |
make fetch |
Download installer to assets/ (idempotent, SHA256-verified) |
make extract |
Unpack exe + nupkg → build/extracted/ |
make stub |
Compile Rust NAPI stub → build/patchy-cnb.node |
make patch |
Extract asar, inject stub + i18n → build/app.asar.contents/ |
make pack |
Repack patched asar → dist/ |
make icons |
Extract + convert app icons → dist/share/icons/ |
make desktop |
Create .desktop entry + launcher → dist/ |
make install |
Copy dist/ → ~/.local/ |
make clean |
Remove build/ and dist/ (keeps assets/) |
make distclean |
Remove everything including assets/ |
make help |
List all targets with descriptions |
Dependencies
| Tool | Install |
|---|---|
7za |
apt: p7zip-full / dnf: p7zip p7zip-plugins |
node |
nodejs.org or nvm |
pnpm |
curl -fsSL https://get.pnpm.io/install.sh | sh - |
electron |
pnpm install -g electron |
cargo / rustc |
rustup.rs |
wrestool / icotool |
apt: icoutils / dnf: icoutils |
magick / convert |
apt: imagemagick / dnf: ImageMagick |
wget |
system |
How it works
The Windows installer is a Squirrel package. 7z extracts it to get the
.nupkg, which is extracted again to get app.asar and the raw resources.
app.asar is Electron's archive format. The patching step:
- Extracts it to
build/app.asar.contents/(fully browsable) - Replaces
claude-native-binding.node(a Windows-only native module) with the Linux stub compiled fromsrc/patchy-cnb/src/lib.rs - Copies tray icons and i18n JSON files into place
- Repacks the archive
The stub (patchy-cnb) implements the same NAPI interface that Claude Desktop
expects — keyboard simulation, mouse control, window info, monitor info — but
as Linux no-ops. This lets the app start cleanly on Linux while logging any
native calls to stdout.
Notes
- Wayland: Global shortcuts and some native features require X11. Wayland support is limited by the stub's no-op implementation.
- Disk space:
build/can reach several hundred MB during extraction. - Modifying the app: edit files in
build/app.asar.contents/aftermake patch, then runmake pack— no re-fetch or re-compile needed.
License
Dual-licensed under the MIT license and the Apache License (Version 2.0). See LICENSE-MIT and LICENSE-APACHE for details.
The Claude Desktop application itself is covered by Anthropic's Consumer Terms.