4.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Purpose
This repo repackages Claude Desktop into RPMs for Fedora 43 & 44 / x86_64. It does not contain the app source — it downloads the upstream .deb from Anthropic's apt repository, repackages the prebuilt Electron bundle as an RPM (no recompile), signs it, and publishes to a self-hosted dnf repo at rpm.lair.cafe. Modelled on the sibling repo lair/mistralrs-package.
Why this exists
Claude Desktop's in-app updater uses Electron's native autoUpdater, which is macOS/Windows only — it is inert on Linux. Anthropic's only Linux update channel is an apt repo (Debian/Ubuntu). This repo is the dnf-equivalent so Fedora hosts stay current via dnf upgrade.
Architecture
Pipeline flow
- poll-upstream (
.gitea/workflows/poll-upstream.yml) — cron every 6h. Reads the upstream aptPackagesindex for the latest version. If the corresponding RPMs don't exist (and aren't indexed) onrpm.lair.cafefor fc43 & fc44, and no build is in-flight, dispatchesbuild-release. - build-release (
.gitea/workflows/build-release.yml) — two-stage pipeline, matrix over Fedora 43 & 44:- package (
runs-on: rpm) — resolves the.debURL + SHA256 from the aptPackagesindex, downloads and verifies it, thenrpmbuild -bb rpm/claude-desktop.specwith--define claude_desktop_versionand--define "dist .fcNN". - publish (
runs-on: rpm) — OpenPGP-signs the RPMs (rpm --addsign), rsyncs torpm.lair.cafe, runscreaterepo_c --update, regeneratespackages.json.createrepo/packages.jsonare wrapped inflock /var/www/rpm/.publish.lockto serialise against other package repos publishing into the same tree.
- package (
Upstream source of truth
https://downloads.claude.ai/claude-desktop/apt/stable/dists/stable/main/binary-amd64/Packages — each stanza carries Version, Filename, and SHA256. The .deb download URL is ${APT_BASE}/${Filename}.
Key files
rpm/claude-desktop.spec— RPM spec. Prebuilt Electron bundle; extracts the.debwithar+tarin%prep(nodpkgdependency). Explicitlychmod 4755the setuid-rootchrome-sandboxin%install(GNU tar drops setuid bits when not run as root); drops the Debian AppArmor/apt maintainer scripts (Fedora uses SELinux + dnf).rpm/rpmmacros—%_openpgp_sign_id @GPG_NAME@;@GPG_NAME@is sed-replaced withRPM_SIGNING_KEY_IDat publish time.script/generate-packages-json.py— regenerates the whole tree'spackages.jsonfrom repodata (verbatim copy of the sibling repo's script; keep in sync).
Commands
Build an RPM locally from the upstream .deb:
rpmdev-setuptree
VERSION=1.17377.2
curl -fsSL -o ~/rpmbuild/SOURCES/claude-desktop_${VERSION}_amd64.deb \
"https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/claude-desktop/claude-desktop_${VERSION}_amd64.deb"
rpmbuild -bb rpm/claude-desktop.spec \
--define "claude_desktop_version ${VERSION}" \
--undefine dist --define "dist .fc44"
Infrastructure
- CI runs on Gitea Actions (self-hosted), not GitHub Actions.
- RPM repo hosted at
rpm.lair.cafeon hostoolon.kosherinata.internal. - Stable repos:
rpm.lair.cafe/fedora/{43,44}/x86_64/(shared with otherlairpackages). - Publish uses rsync over SSH as the
gitea_ciuser. - Required Actions secrets:
DISPATCH_TOKEN,RPM_SIGNING_KEY,RPM_SIGNING_KEY_ID,RSYNC_SSH_KEY(org-level onlairif configured; otherwise set per-repo).
Consuming the repo
On a Fedora host, drop a .repo file pointing at https://rpm.lair.cafe/fedora/$releasever/x86_64/ (see lair/mistralrs-package for the existing client .repo convention), then dnf install claude-desktop. Subsequent dnf upgrade picks up new versions automatically.
Runtime notes
- If Chromium's sandbox misbehaves on a host with restricted user namespaces:
claude-desktop --no-sandbox, orsysctl kernel.unprivileged_userns_clone=1.