diff options
Diffstat (limited to '.extras/docs')
| -rw-r--r-- | .extras/docs/superpowers/plans/2026-07-09-claude-desktop-bin-slackbuild.md | 622 | ||||
| -rw-r--r-- | .extras/docs/superpowers/specs/2026-07-09-claude-desktop-bin-slackbuild-design.md | 212 |
2 files changed, 834 insertions, 0 deletions
diff --git a/.extras/docs/superpowers/plans/2026-07-09-claude-desktop-bin-slackbuild.md b/.extras/docs/superpowers/plans/2026-07-09-claude-desktop-bin-slackbuild.md new file mode 100644 index 0000000..97bb713 --- /dev/null +++ b/.extras/docs/superpowers/plans/2026-07-09-claude-desktop-bin-slackbuild.md @@ -0,0 +1,622 @@ +# claude-desktop-bin SlackBuild Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Repackage Anthropic's official `claude-desktop` Debian `.deb` into a Slackware `.txz` package named `claude-desktop-bin`. + +**Architecture:** Binary repack. Extract the deb's `data.tar.xz` into `$PKG`, drop the Debian maintainer scripts (apt-repo, AppArmor), reproduce only the chrome-sandbox setuid, and package with `makepkg`. Same pattern as the existing `megasync-bin` package in this repo. + +**Tech Stack:** bash SlackBuild, `ar`/`tar` for deb extraction, `makepkg`, sbo-maintainer-tools (sbolint/sbodl/sbopkglint), nvchecker. + +**Spec:** `.extras/docs/superpowers/specs/2026-07-09-claude-desktop-bin-slackbuild-design.md` + +**Note on "tests":** this is a packaging repo, not a code repo. Verification is `sbolint` / `sbodl` / `sbopkglint` / build / launch, not a unit-test framework. Each task's verification step names the exact command and expected result. + +--- + +## File Structure + +All under a new `claude-desktop-bin/` package directory, plus repo-level edits: + +``` +claude-desktop-bin/ + claude-desktop-bin.SlackBuild # build script (repack logic) + claude-desktop-bin.info # metadata: 1 amd64 deb DOWNLOAD + MD5SUM + claude-desktop-bin.nvchecker # cmd stanza, shipped into /usr/doc + README # description, notes, NVCHECKER section + slack-desc # 11-line package description + doinst.sh # desktop-db, mime-db, icon-cache, sandbox chmod +.extras/nvchecker.toml # add [claude-desktop-bin] stanza +~/.config/nvchecker/nvchecker.toml# add same stanza (local, not committed) +README.md # add package-table row +``` + +Package facts (from spec): +- `PRGNAM=claude-desktop-bin`, `SRCNAM=claude-desktop`, `VERSION=1.18286.2` +- x86_64 only, `REQUIRES=""` +- Source: `https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/claude-desktop/claude-desktop_1.18286.2_amd64.deb` +- MD5SUM: `853168e12c721d6bc6ce9566bbd5348e` + +--- + +### Task 1: Create the package directory and .info file + +**Files:** +- Create: `claude-desktop-bin/claude-desktop-bin.info` + +- [ ] **Step 1: Create the directory and .info file** + +```bash +mkdir -p claude-desktop-bin +``` + +Create `claude-desktop-bin/claude-desktop-bin.info`: + +``` +PRGNAM="claude-desktop-bin" +VERSION="1.18286.2" +HOMEPAGE="https://claude.ai/download" +DOWNLOAD="https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/claude-desktop/claude-desktop_1.18286.2_amd64.deb" +MD5SUM="853168e12c721d6bc6ce9566bbd5348e" +DOWNLOAD_x86_64="" +MD5SUM_x86_64="" +REQUIRES="" +MAINTAINER="danix" +EMAIL="danix@danix.xyz" +``` + +- [ ] **Step 2: Verify the download + checksum with sbodl** + +Run: +```bash +cd claude-desktop-bin && sbodl ; cd .. +``` +Expected: downloads the deb and reports `md5sum matches OK`. (~138 MB download.) +If it reports a mismatch, the repo has published a newer version: re-fetch the +latest `Version:`/`MD5sum:`/`Filename:` from +`https://downloads.claude.ai/claude-desktop/apt/stable/dists/stable/main/binary-amd64/Packages`, +update `VERSION`, `MD5SUM`, and the `DOWNLOAD` filename, then re-run. + +- [ ] **Step 3: Remove the symlink sbodl created** + +`sbodl` symlinks the downloaded deb into the package dir. It must not be committed. + +Run: +```bash +find claude-desktop-bin -type l -delete +``` +Expected: no output. The real deb stays in sbodl's cache; the symlink is gone. + +--- + +### Task 2: Write the SlackBuild script + +**Files:** +- Create: `claude-desktop-bin/claude-desktop-bin.SlackBuild` + +- [ ] **Step 1: Write the SlackBuild** + +Create `claude-desktop-bin/claude-desktop-bin.SlackBuild`: + +```bash +#!/bin/bash + +# Slackware build script for claude-desktop (binary repack) + +# Copyright 2026 danix <danix@danix.xyz> +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +cd $(dirname $0) ; CWD=$(pwd) + +PRGNAM=claude-desktop-bin +SRCNAM=claude-desktop +VERSION=${VERSION:-1.18286.2} +BUILD=${BUILD:-1} +TAG=${TAG:-_SBo} +PKGTYPE=${PKGTYPE:-tgz} + +if [ -z "$ARCH" ]; then + case "$( uname -m )" in + *) ARCH=$( uname -m ) ;; + esac +fi + +if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then + echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" + exit 0 +fi + +# Upstream ships x86_64 only. +if [ "$ARCH" != "x86_64" ]; then + echo "$ARCH is not supported: Claude Desktop is x86_64 only." + exit 1 +fi + +TMP=${TMP:-/tmp/SBo} +PKG=$TMP/package-$PRGNAM +OUTPUT=${OUTPUT:-/tmp} + +set -e + +rm -rf $PKG +mkdir -p $TMP $PKG $OUTPUT + +# Extract the upstream .deb (an ar archive holding a data.tar.xz payload with +# the real file tree) into $PKG. The Debian control scripts (postinst/postrm: +# apt-repo registration + AppArmor userns profile) are intentionally NOT +# carried over -- neither applies to Slackware. +( cd $TMP && ar x $CWD/${SRCNAM}_${VERSION}_amd64.deb data.tar.xz \ + && tar xf data.tar.xz -C $PKG && rm -f data.tar.xz ) + +# Drop Debian-only cruft. +rm -rf $PKG/usr/share/lintian + +# Defensive: the deb ships its bundled chromium libs mode 0755 already, but +# guard against a future deb regressing to 0644 (the "ELF libs 0644" Debian +# convention that trips sbopkglint's 20-arch test). Do NOT strip: these are +# prebuilt Electron/Chromium binaries and upstream ships them unstripped. +find $PKG/usr/lib/$SRCNAM -maxdepth 1 -name '*.so*' -type f -print0 \ + | xargs -0 -r chmod 755 + +# Docs: keep the upstream copyright, add the SlackBuild and nvchecker stanza. +mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION +if [ -f $PKG/usr/share/doc/$SRCNAM/copyright ]; then + cp -a $PKG/usr/share/doc/$SRCNAM/copyright $PKG/usr/doc/$PRGNAM-$VERSION/ +fi +rm -rf $PKG/usr/share/doc +cat $CWD/README > $PKG/usr/doc/$PRGNAM-$VERSION/README +cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild +cat $CWD/$PRGNAM.nvchecker > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.nvchecker + +mkdir -p $PKG/install +cat $CWD/slack-desc > $PKG/install/slack-desc +cat $CWD/doinst.sh > $PKG/install/doinst.sh + +chown -R root:root $PKG +find -L $PKG \ + \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \ + -o -perm 511 \) -exec chmod 755 {} \+ -o \ + \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \ + -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \+ + +# chrome-sandbox needs setuid root (4755) for Chromium's SUID sandbox. Set it +# LAST, after the find -L perm-normalize above would otherwise strip it. +chmod 4755 $PKG/usr/lib/$SRCNAM/chrome-sandbox + +cd $PKG +/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE +``` + +- [ ] **Step 2: Set mode 0644 and syntax-check** + +SBo requires the `.SlackBuild` to be mode 0644 (sbolint errors on 0755); it is +invoked as `bash x.SlackBuild`, not executed directly. + +Run: +```bash +chmod 0644 claude-desktop-bin/claude-desktop-bin.SlackBuild +bash -n claude-desktop-bin/claude-desktop-bin.SlackBuild && echo "syntax OK" +``` +Expected: `syntax OK`. + +--- + +### Task 3: Write the nvchecker stanza + +**Files:** +- Create: `claude-desktop-bin/claude-desktop-bin.nvchecker` + +- [ ] **Step 1: Write the nvchecker file** + +Create `claude-desktop-bin/claude-desktop-bin.nvchecker`: + +```toml +# Claude Desktop has no github/pypi release feed; the source of truth is the +# Anthropic apt repo Packages index. nvchecker has no native apt/deb source, +# so use the cmd source to parse the highest Version: out of the index. +[claude-desktop-bin] +source = "cmd" +cmd = "curl -fsSL https://downloads.claude.ai/claude-desktop/apt/stable/dists/stable/main/binary-amd64/Packages | awk '/^Version:/{print $2}' | sort -V | tail -1" +``` + +- [ ] **Step 2: Verify the command resolves a version** + +Run: +```bash +curl -fsSL https://downloads.claude.ai/claude-desktop/apt/stable/dists/stable/main/binary-amd64/Packages | awk '/^Version:/{print $2}' | sort -V | tail -1 +``` +Expected: a dotted version string, `1.18286.2` or newer. + +--- + +### Task 4: Write slack-desc + +**Files:** +- Create: `claude-desktop-bin/slack-desc` + +- [ ] **Step 1: Write slack-desc** + +Create `claude-desktop-bin/slack-desc` (the `|` under the `:` must line up on the +`handy-ruler` line; exactly 11 description lines): + +``` +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. +# Line up the first '|' above the ':' following the base package name, and +# the '|' on the right side marks the last column you can put a character in. +# You must make exactly 11 lines for the formatting to be correct. It's also +# customary to leave one space after the ':' except on otherwise blank lines. + + |-----handy-ruler------------------------------------------------------| +claude-desktop-bin: claude-desktop-bin (official desktop client for Claude.ai) +claude-desktop-bin: +claude-desktop-bin: Claude Desktop is Anthropic's Electron desktop application for +claude-desktop-bin: Claude.ai, with support for the claude:// URL scheme, quick chat +claude-desktop-bin: and Claude Code session launchers. +claude-desktop-bin: +claude-desktop-bin: This is a binary repack of Anthropic's official Debian package. +claude-desktop-bin: It bundles its own Chromium runtime and is x86_64 only. +claude-desktop-bin: +claude-desktop-bin: +claude-desktop-bin: Homepage: https://claude.ai/download +``` + +- [ ] **Step 2: Verify line count and prefix** + +Run: +```bash +grep -c '^claude-desktop-bin:' claude-desktop-bin/slack-desc +``` +Expected: `11`. + +--- + +### Task 5: Write doinst.sh + +**Files:** +- Create: `claude-desktop-bin/doinst.sh` + +- [ ] **Step 1: Write doinst.sh** + +Create `claude-desktop-bin/doinst.sh`. The chrome-sandbox setuid is shipped in +the package (Task 2); this line is a belt-and-suspenders re-assert in case +`makepkg` did not preserve the setuid bit (relative path, no leading slash, so +`--root`/`$ROOT` installs stay correct): + +```bash +if [ -x /usr/bin/update-desktop-database ]; then + /usr/bin/update-desktop-database -q usr/share/applications >/dev/null 2>&1 +fi + +if [ -x /usr/bin/update-mime-database ]; then + /usr/bin/update-mime-database usr/share/mime >/dev/null 2>&1 +fi + +if [ -e usr/share/icons/hicolor/icon-theme.cache ]; then + if [ -x /usr/bin/gtk-update-icon-cache ]; then + /usr/bin/gtk-update-icon-cache -f -q usr/share/icons/hicolor >/dev/null 2>&1 + fi +fi + +# Chromium's SUID sandbox helper must be setuid root. Re-assert in case the +# package did not preserve the 4755 bit. +chmod 4755 usr/lib/claude-desktop/chrome-sandbox 2>/dev/null +``` + +- [ ] **Step 2: Syntax-check** + +Run: +```bash +bash -n claude-desktop-bin/doinst.sh && echo "syntax OK" +``` +Expected: `syntax OK`. + +--- + +### Task 6: Write README + +**Files:** +- Create: `claude-desktop-bin/README` + +- [ ] **Step 1: Write README** + +Create `claude-desktop-bin/README` (SBo READMEs are plain text, wrapped ~72 cols): + +``` +Claude Desktop is Anthropic's official Electron desktop application for +Claude.ai. It bundles its own Chromium runtime, registers the claude:// +URL scheme handler, and provides desktop actions for starting a new chat +or a new Claude Code session. + +This is a binary repack of Anthropic's official Debian package pulled from +the Anthropic apt repository (https://downloads.claude.ai/claude-desktop). +No build from source is performed. The package is x86_64 only and installs +to roughly 480 MB. + +The Debian package's apt-repository registration and AppArmor userns +profile are Debian/Ubuntu specific and are not reproduced here. Chromium's +SUID sandbox helper (chrome-sandbox) is shipped setuid root so the sandbox +works without --no-sandbox. + +There are no SBo dependencies: the Debian runtime dependencies (gtk3, nss, +notify, atspi, drm, gbm, secret, xtst, xdg-utils, xdg-desktop-portal) are +all satisfied by a stock Slackware install, and Chromium's own libraries +are bundled inside the package. + + +NVCHECKER +--------- +An nvchecker configuration file is installed alongside this README at: + + /usr/doc/claude-desktop-bin-VERSION/claude-desktop-bin.nvchecker + +nvchecker (https://github.com/lilydjwg/nvchecker) is a tool for checking +new versions of software. Copy or include this file in your nvchecker +configuration to be notified when Anthropic publishes a new Claude Desktop +release. +``` + +- [ ] **Step 2: Verify no line exceeds 80 columns** + +Run: +```bash +awk 'length > 80 {print FILENAME":"NR": "length" cols"}' claude-desktop-bin/README +``` +Expected: no output. + +--- + +### Task 7: Lint the sources + +**Files:** +- All of `claude-desktop-bin/` + +- [ ] **Step 1: Run sbolint** + +Run: +```bash +cd claude-desktop-bin && sbolint ; cd .. +``` +Expected: no errors. If sbolint flags the `.nvchecker` file as an unexpected +extra file, that is acceptable (r8125 and UrbanTerror ship the same and pass); +fix any real errors it reports about the SlackBuild, .info, README, or slack-desc. + +--- + +### Task 8: Build the package + +**Files:** +- Produces: `/tmp/claude-desktop-bin-1.18286.2-x86_64-1_SBo.tgz` + +- [ ] **Step 1: Build** + +Run (needs the deb present; sbodl in Task 1 fetched it — if the build cannot +find `claude-desktop_1.18286.2_amd64.deb` in the package dir, symlink or copy it +from sbodl's cache into `claude-desktop-bin/` first): +```bash +cd claude-desktop-bin && sudo bash claude-desktop-bin.SlackBuild ; cd .. +``` +Expected: ends with `Slackware package .../claude-desktop-bin-1.18286.2-x86_64-1_SBo.tgz created.` + +- [ ] **Step 2: Confirm chrome-sandbox setuid in the built package** + +Run: +```bash +tar tvf /tmp/claude-desktop-bin-1.18286.2-x86_64-1_SBo.tgz \ + | grep chrome-sandbox +``` +Expected: mode shows setuid, e.g. `-rwsr-xr-x root/root`. Also check whether +`makepkg` moved the bit into `install/doinst.sh` (some versions do); note which +happened for the commit message. + +- [ ] **Step 3: Remove any symlink left in the package dir before staging** + +Run: +```bash +find claude-desktop-bin -type l -delete +``` +Expected: no output. + +--- + +### Task 9: Lint the built package + +**Files:** +- `/tmp/claude-desktop-bin-1.18286.2-x86_64-1_SBo.tgz` + +- [ ] **Step 1: Run sbopkglint** + +Run: +```bash +cd claude-desktop-bin && sbopkglint /tmp/claude-desktop-bin-1.18286.2-x86_64-1_SBo.tgz ; cd .. +``` +Expected: green. A warning about the setuid `chrome-sandbox` is expected and +acceptable (it is required for the Chromium sandbox); any hard error about +non-executable ELF (the 20-arch test) means the `chmod 755` guard in the +SlackBuild needs to cover more files — investigate and fix. + +--- + +### Task 10: Install and smoke-test on -current + +**Files:** none + +- [ ] **Step 1: Install** + +Run: +```bash +sudo /sbin/upgradepkg --install-new /tmp/claude-desktop-bin-1.18286.2-x86_64-1_SBo.tgz +``` +Expected: installs cleanly, doinst.sh runs. + +- [ ] **Step 2: Confirm installed sandbox perms and launch** + +Run: +```bash +ls -l /usr/lib/claude-desktop/chrome-sandbox +``` +Expected: `-rwsr-xr-x 1 root root ...` (setuid preserved after install). + +Then launch (from a graphical session): +```bash +claude-desktop +``` +Expected: the app window opens with the sandbox enabled (no `--no-sandbox` +needed). Close it after confirming. + +--- + +### Task 11: Add nvchecker stanza to the repo config + +**Files:** +- Modify: `.extras/nvchecker.toml` +- Modify: `~/.config/nvchecker/nvchecker.toml` (local, not committed) + +- [ ] **Step 1: Append the stanza to both configs** + +Append to `.extras/nvchecker.toml`: + +```toml +[claude-desktop-bin] +source = "cmd" +cmd = "curl -fsSL https://downloads.claude.ai/claude-desktop/apt/stable/dists/stable/main/binary-amd64/Packages | awk '/^Version:/{print $2}' | sort -V | tail -1" +``` + +Append the identical stanza to `~/.config/nvchecker/nvchecker.toml`. + +- [ ] **Step 2: Verify nvchecker resolves the entry** + +Run: +```bash +nvchecker -c .extras/nvchecker.toml 2>&1 | grep claude-desktop-bin +``` +Expected: a line showing `claude-desktop-bin` with the current upstream version +(`1.18286.2` or newer). No error. + +--- + +### Task 12: Add the package to the README table + +**Files:** +- Modify: `README.md` (after the `megasync-bin` row, line ~63) + +- [ ] **Step 1: Insert the table row** + +After the `megasync-bin` row in the package table, add: + +``` +| claude-desktop-bin | ✅ | not tested | ❌ | 1.18286.2 | 1.18286.2 | +``` + +(Update the `-current` / `15.0` cells to ✅ once each target is actually built +and tested per Tasks 8–10; leave `not tested` for a target you have not run.) + +- [ ] **Step 2: Verify the row renders (column count)** + +Run: +```bash +grep 'claude-desktop-bin' README.md +``` +Expected: one row with 6 `|`-separated cells matching the table header. + +--- + +### Task 13: Commit + +**Files:** all of the above. + +- [ ] **Step 1: Stage and commit the package** + +The pre-commit hook runs sbolint automatically. `.nvchecker` and the deb must +not be staged as real files (the hook blocks staged source archives; symlinks +are auto-removed). + +Run: +```bash +git add claude-desktop-bin/ .extras/nvchecker.toml README.md +git status # confirm no .deb and no symlink is staged +git commit -m "claude-desktop-bin: add version 1.18286.2 + +Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>" +``` +Expected: pre-commit sbolint passes, commit is created and GPG-signed. + +- [ ] **Step 2: Verify the commit is signed** + +Run: +```bash +git log --format='%h %G? %s' -1 +``` +Expected: `<hash> G claude-desktop-bin: add version 1.18286.2`. + +- [ ] **Step 3: Push** + +Run: +```bash +git push +``` +Expected: pushes to all three remotes (slackware_forge, github, danix_git). + +--- + +### Task 14: Save a memory note + +**Files:** +- Create: `~/.claude/projects/-home-danix-Programming-GIT-GITHUB-my-slackbuilds/memory/claude-desktop-bin-package.md` +- Modify: the memory `MEMORY.md` index + +- [ ] **Step 1: Write the memory** + +Record the non-obvious facts: official Anthropic apt-repo deb (versioned URL, +so md5 is stable, unlike megasync-bin's versionless URL); PRGNAM has `-bin` +suffix but SRCNAM keeps `claude-desktop`; Debian apt-repo/AppArmor scripts +dropped; chrome-sandbox shipped setuid 4755; nvchecker uses a `cmd` source +parsing the apt `Packages` index; nvchecker stanza shipped in-package like +r8125/UrbanTerror. Link `[[deb-repack-elf-perms]]`. + +Add a one-line pointer to `MEMORY.md`. + +--- + +## Self-Review + +**Spec coverage:** +- PRGNAM/SRCNAM/VERSION/x86_64/REQUIRES → Task 1, 2. ✓ +- Versioned URL, stable md5 → Task 1, memory Task 14. ✓ +- Drop Debian control scripts (apt/AppArmor) → Task 2 (comment + no carry-over). ✓ +- Drop lintian → Task 2. ✓ +- No stripping, defensive chmod 755 on libs → Task 2. ✓ +- chrome-sandbox setuid in SlackBuild, last after find -L → Task 2; verify → Task 8; doinst fallback → Task 5. ✓ +- Docs via cat, not cp → Task 2. ✓ +- doinst hooks (desktop/mime/icon) → Task 5. ✓ +- nvchecker cmd stanza, shipped in-package, both configs → Task 3, 11. ✓ +- README + NVCHECKER section → Task 6. ✓ +- slack-desc → Task 4. ✓ +- README.md table row → Task 12. ✓ +- Testing (sbolint/sbodl/sbopkglint/build/launch) → Tasks 1, 7, 8, 9, 10. ✓ +- Memory note → Task 14. ✓ + +**Placeholder scan:** no TBD/TODO; all file contents are literal. ✓ + +**Type/name consistency:** `PRGNAM=claude-desktop-bin` and `SRCNAM=claude-desktop` +used consistently; deb filename `claude-desktop_1.18286.2_amd64.deb`; sandbox +path `usr/lib/claude-desktop/chrome-sandbox` identical in SlackBuild, doinst.sh, +and verification steps. ✓ diff --git a/.extras/docs/superpowers/specs/2026-07-09-claude-desktop-bin-slackbuild-design.md b/.extras/docs/superpowers/specs/2026-07-09-claude-desktop-bin-slackbuild-design.md new file mode 100644 index 0000000..97c5d8d --- /dev/null +++ b/.extras/docs/superpowers/specs/2026-07-09-claude-desktop-bin-slackbuild-design.md @@ -0,0 +1,212 @@ +# claude-desktop-bin SlackBuild — Design Spec + +Date: 2026-07-09 +Package: `claude-desktop-bin` +Type: binary repack of the official Anthropic Debian package + +--- + +## Summary + +Repackage Anthropic's official `claude-desktop` Debian `.deb` into a Slackware +`.txz`. Claude Desktop is the Electron desktop client for Claude.ai. Anthropic +publishes an official apt repository at `https://downloads.claude.ai/claude-desktop/apt/stable` +carrying prebuilt `amd64` and `arm64` `.deb` packages; this SlackBuild consumes +the `amd64` deb and re-lays its payload into a Slackware package. Build from +source is rejected: Anthropic ships an official signed binary, and rebuilding +the Electron/Chromium app offline is slow and fragile with no gain. + +## Package facts + +- `PRGNAM=claude-desktop-bin` +- `VERSION=1.18286.2` (latest amd64 in the apt repo at spec time) +- `SRCNAM=claude-desktop` (deb filename + installed `/usr/bin/claude-desktop` + keep the upstream name; only the SlackBuild package name gets the `-bin` + suffix, matching this repo's convention: megasync-bin, kitty-bin, + opencode-bin, claude-code-bin) +- `ARCH`: **x86_64 only**. The apt repo also serves `arm64`, but this repo + targets x86_64; the SlackBuild exits with an error on any other arch. +- `REQUIRES=""`. The Debian `Depends` (libgtk-3-0, libnss3, libnotify4, + libatspi, libdrm, libgbm, libsecret, libxtst, xdg-utils, xdg-desktop-portal, + libc6) are all satisfied by stock Slackware. Chromium's own libs + (libEGL, libGLESv2, libffmpeg, libvulkan, libvk_swiftshader) are bundled + inside the payload. No SBo dependencies. +- Name `claude-desktop-bin` is free on SlackBuilds.org (only `claude-code*` + exists there). Does not clash with the unrelated `claude-code-bin` already in + this repo. + +## Source + +- URL: `https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/claude-desktop/claude-desktop_1.18286.2_amd64.deb` +- MD5SUM: `853168e12c721d6bc6ce9566bbd5348e` +- Size: ~138 MB deb, ~480 MB installed. + +The download path is **versioned** (`pool/main/c/claude-desktop/claude-desktop_<version>_amd64.deb`), +so a given version's file is immutable and the MD5SUM is stable. This is unlike +megasync-bin's versionless URL: the checksum does not drift here. + +## Payload layout (from the deb `data.tar.xz`) + +``` +usr/bin/claude-desktop -> ../lib/claude-desktop/claude-desktop (symlink) +usr/lib/claude-desktop/ Electron app + bundled chromium + claude-desktop main ELF binary (~208 MB) + chrome-sandbox SUID sandbox helper (4755 in deb) + chrome_crashpad_handler + libEGL.so libGLESv2.so libffmpeg.so + libvulkan.so.1 libvk_swiftshader.so + *.pak icudtl.dat *.bin locales/ resources/ version + LICENSES.chromium.html vk_swiftshader_icd.json +usr/share/applications/claude-desktop.desktop +usr/share/icons/hicolor/{16,32,48,128,256}x*/apps/claude-desktop.png +usr/share/doc/claude-desktop/copyright +usr/share/lintian/... (Debian-only, dropped) +``` + +The upstream `.desktop` is kept as-is: `Exec=claude-desktop %U`, registers the +`x-scheme-handler/claude` MIME handler and `NewChat` / `NewCode` desktop +actions. No Slackware-specific `.desktop` is written. + +## What is discarded from the deb + +The Debian maintainer scripts (`control.tar.xz`: postinst, postrm) are **not** +carried over. They do three Debian-specific things, none of which apply to +Slackware: + +1. **apt repo registration** — writes the Anthropic apt source + keyring so + `apt upgrade` tracks updates. Irrelevant on Slackware. +2. **AppArmor userns profile** — works around + `kernel.apparmor_restrict_unprivileged_userns=1` on Ubuntu 24.04+, which + blocks `CLONE_NEWUSER` for unconfined processes. Slackware does not set this + restriction, so Chromium's userns/SUID sandbox works without the profile. +3. **chrome-sandbox setuid** — the only piece we must reproduce (see below). + +`usr/share/lintian/` is dropped. + +## chrome-sandbox setuid + +Chromium's SUID sandbox helper must be owned root:root and mode `4755` for the +sandbox to initialize; without it Claude Desktop fails to start unless launched +with `--no-sandbox` (which weakens security). + +**Decision:** set `chmod 4755` on `chrome-sandbox` in the SlackBuild itself, +inside `$PKG` before `makepkg`, so the package ships the setuid bit directly. +This tests two things at build time: + +- whether `sbopkglint` flags the shipped setuid binary, and +- whether `makepkg` auto-extracts the setuid bit into an `install/doinst.sh` + `chmod` line (some makepkg versions do this for non-0755 modes). + +If linting objects or makepkg does not preserve the bit, fall back to a +`chmod 4755 usr/lib/claude-desktop/chrome-sandbox` line in `doinst.sh` (relative +path, no leading slash, so `--root`/`$ROOT` installs stay correct). The fallback +is a known-good path; the in-SlackBuild approach is tried first to learn +makepkg/lint behavior. + +## SlackBuild flow + +Base: SBo template + the megasync-bin binary-repack pattern in this repo. + +1. `set -e`; honor `$TMP $OUTPUT $PKG $TAG`; ARCH guard (exit on non-x86_64). +2. Unpack the deb: `ar x $CWD/claude-desktop_${VERSION}_amd64.deb`, then + `tar xf data.tar.xz -C $PKG`. +3. Remove Debian-only cruft: `usr/share/lintian`. +4. **No stripping.** These are prebuilt Electron/Chromium binaries; stripping + risks breaking them and upstream ships them unstripped. Skip the strip pass. + (This also means the "ELF libs are 0644" megasync gotcha does not bite: the + deb already ships its libs 0755. A defensive `chmod 755` over the bundled + `*.so` files is still applied in case a future deb regresses.) +5. `chmod 4755 usr/lib/claude-desktop/chrome-sandbox` (setuid, per above). +6. Install docs to `usr/doc/$PRGNAM-$VERSION/`: move the upstream `copyright` + there, and pipe in the SlackBuild and nvchecker stanza with `cat` (never + `cp`, see below): + `cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild` + `cat $CWD/$PRGNAM.nvchecker > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.nvchecker` + Remove the Debian `usr/share/doc/claude-desktop` dir after copying. +7. Standard `find -L $PKG` chown/chmod cleanup block (root:root, sane dir/file + modes) — applied **before** the chrome-sandbox chmod so it does not clobber + the setuid bit. Order matters: perm-normalize first, setuid last. +8. Install package metadata with `cat` into `$PKG/install/`: + `cat $CWD/slack-desc > $PKG/install/slack-desc` + `cat $CWD/doinst.sh > $PKG/install/doinst.sh` +9. `makepkg -l y -c n`. + +**Always `cat` source files into `$PKG`, never `cp`.** Standard SBo procedure: +`cat src > dest` writes through a fresh dest so the umask/root ownership of the +build controls the resulting perms, whereas `cp` would carry the source tree's +mode/ownership into the package. This matters here because the working copy is +checked out from git with the user's perms. + +## doinst.sh + +Trimmed from the SBo template. Keep only the hooks the payload needs: + +- `update-desktop-database` (has a `.desktop`) +- `update-mime-database` (registers `x-scheme-handler/claude`) +- `gtk-update-icon-cache` (ships hicolor icons) + +No `config()` block (no config files shipped). The chrome-sandbox `chmod` +line is added here only as the fallback if step 5 above does not survive +`makepkg`/lint. + +## nvchecker + +Anthropic publishes no GitHub releases for the desktop app; the source of truth +is the apt repo `Packages` index. nvchecker has no native apt/deb source, so use +the `cmd` source to parse it: + +```toml +[claude-desktop-bin] +source = "cmd" +cmd = "curl -fsSL https://downloads.claude.ai/claude-desktop/apt/stable/dists/stable/main/binary-amd64/Packages | awk '/^Version:/{print $2}' | sort -V | tail -1" +``` + +`awk` extracts every `Version:` value from the index; `sort -V | tail -1` +returns the highest. Verified to resolve to `1.18286.2` at spec time. Added to +both `.extras/nvchecker.toml` and `~/.config/nvchecker/nvchecker.toml`. + +**Ship the stanza with the package.** This is a "no github/pypi feed" package, +same class as `r8125` and `UrbanTerror`, both of which ship a per-package +`<pkg>.nvchecker` file. Follow that precedent: + +- Add `claude-desktop-bin.nvchecker` to the package directory containing the + `[claude-desktop-bin]` cmd stanza above. +- The SlackBuild installs it to `/usr/doc/$PRGNAM-$VERSION/`: + `cat $CWD/$PRGNAM.nvchecker > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.nvchecker` +- README gets an `NVCHECKER` section pointing at the installed path, worded + like r8125's (a user copies the stanza into their own nvchecker config to be + notified of new Anthropic releases). + +## Files produced + +``` +claude-desktop-bin/ + claude-desktop-bin.SlackBuild + claude-desktop-bin.info # single amd64 deb DOWNLOAD + MD5SUM, REQUIRES="" + claude-desktop-bin.nvchecker # cmd stanza, installed to /usr/doc/<pkg>-<ver>/ + README + slack-desc # official Anthropic Electron client, x86_64 only + doinst.sh # desktop-db, mime-db, icon-cache (+ sandbox fallback) +``` + +Plus: nvchecker entry (both configs), README package-table row, a memory note. + +## README notes + +- Official Anthropic build (not a community port), Electron/Chromium based. +- x86_64 only; ~480 MB installed. +- chrome-sandbox ships setuid root for Chromium's sandbox. +- No SBo dependencies; all libs are stock Slackware or bundled. +- Registers the `claude://` URL scheme handler. +- `NVCHECKER` section: points at the shipped + `/usr/doc/claude-desktop-bin-VERSION/claude-desktop-bin.nvchecker` stanza, + worded like r8125/UrbanTerror. + +## Testing + +- `sbolint` clean on the sources. +- Build on -current (buildsystem VM) and 15.0 (sbo-batch-test overlay). +- `sbopkglint` on the built package — note whether it flags the setuid + chrome-sandbox, and whether makepkg moved the bit into doinst.sh. +- Launch on -current, confirm the app starts with the sandbox enabled (no + `--no-sandbox`). |
