Add CLAUDE.md
This commit is contained in:
59
CLAUDE.md
Normal file
59
CLAUDE.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# 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](https://claude.ai) 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`](https://git.lair.cafe/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
|
||||||
|
|
||||||
|
1. **poll-upstream** (`.gitea/workflows/poll-upstream.yml`) — cron every 6h. Reads the upstream apt `Packages` index for the latest version. If the corresponding RPMs don't exist (and aren't indexed) on `rpm.lair.cafe` for fc43 & fc44, and no build is in-flight, dispatches `build-release`.
|
||||||
|
2. **build-release** (`.gitea/workflows/build-release.yml`) — two-stage pipeline, matrix over Fedora 43 & 44:
|
||||||
|
- **package** (`runs-on: rpm`) — resolves the `.deb` URL + SHA256 from the apt `Packages` index, downloads and verifies it, then `rpmbuild -bb rpm/claude-desktop.spec` with `--define claude_desktop_version` and `--define "dist .fcNN"`.
|
||||||
|
- **publish** (`runs-on: rpm`) — OpenPGP-signs the RPMs (`rpm --addsign`), rsyncs to `rpm.lair.cafe`, runs `createrepo_c --update`, regenerates `packages.json`. `createrepo`/`packages.json` are wrapped in `flock /var/www/rpm/.publish.lock` to serialise against other package repos publishing into the same tree.
|
||||||
|
|
||||||
|
### 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 `.deb` with `ar` + `tar` in `%prep` (no `dpkg` dependency). Explicitly `chmod 4755` the setuid-root `chrome-sandbox` in `%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 with `RPM_SIGNING_KEY_ID` at publish time.
|
||||||
|
- `script/generate-packages-json.py` — regenerates the whole tree's `packages.json` from repodata (verbatim copy of the sibling repo's script; keep in sync).
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
Build an RPM locally from the upstream `.deb`:
|
||||||
|
```bash
|
||||||
|
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.cafe` on host `oolon.kosherinata.internal`.
|
||||||
|
- Stable repos: `rpm.lair.cafe/fedora/{43,44}/x86_64/` (shared with other `lair` packages).
|
||||||
|
- Publish uses rsync over SSH as the `gitea_ci` user.
|
||||||
|
- Required Actions secrets: `DISPATCH_TOKEN`, `RPM_SIGNING_KEY`, `RPM_SIGNING_KEY_ID`, `RSYNC_SSH_KEY` (org-level on `lair` if 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`, or `sysctl kernel.unprivileged_userns_clone=1`.
|
||||||
Reference in New Issue
Block a user