aboutsummaryrefslogtreecommitdiffstats
path: root/.extras/docs/superpowers/specs/2026-07-09-claude-desktop-bin-slackbuild-design.md
blob: 97c5d8d97cba92b530355789efc36757941f7c2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
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`).