From 586b0217b01d35ca390c53cdbf778da14f8dd7c8 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Wed, 16 Sep 2026 07:58:19 -0700 Subject: [PATCH] slab 1.0: a download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release build goes universal. `swift build -c release` on an Apple silicon Mac produces an arm64-only binary, and the Info.plist advertises macOS 11 — which includes plenty of Intel machines, where an arm64 binary does not degrade, it refuses to launch. The studio build can stay native because every Mac here is Apple silicon. A download cannot assume that about anybody, so release-solo.sh now builds both slices and refuses to continue if it somehow gets one. The self-containment check caught its own bug on the way: a fat binary makes `otool -L` print a " (architecture …):" header per slice, so dropping the first line leaves the second header behind and the binary reads as its own non-system dependency. Dependency lines are the indented ones. Slab-1.0.dmg is on assets.aesthetic.computer, 6.6 MB, universal, notarized and stapled. Verified as a stranger gets it: downloaded over HTTPS, marked with a Safari quarantine flag, ticket validated offline, Gatekeeper accepting both the image and the app inside it, and the download byte-identical to what was notarized. The page stops saying it is not packaged. The button reads manifest.json rather than hardcoding a version, so the next release is one file to edit; the markup keeps a working href in case that fetch never lands. The build-it-yourself instructions stay, below, for anyone who would rather have the symlinked studio copy. Published knowing what has not been tested: no Mac here has launched this without a repo install already on it, so the first-run dialog and the two TCC prompts have been reasoned about but not watched. Co-Authored-By: Claude Opus 5 (1M context) --- slab/menubar-swift/bin/verify-solo-bundle.sh | 15 +++- slab/menubar-swift/release-solo.sh | 17 +++- system/public/slab/index.html | 94 +++++++++++++++++++- system/public/slab/manifest.json | 14 +++ 4 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 system/public/slab/manifest.json diff --git a/slab/menubar-swift/bin/verify-solo-bundle.sh b/slab/menubar-swift/bin/verify-solo-bundle.sh index afff75971..74f48c2cb 100755 --- a/slab/menubar-swift/bin/verify-solo-bundle.sh +++ b/slab/menubar-swift/bin/verify-solo-bundle.sh @@ -72,8 +72,21 @@ else printf ' %s\n' ${LEAKS} fi +# ── Universal binary ────────────────────────────────────────────────────── +# Info.plist advertises macOS 11, which includes Intel Macs. An arm64-only +# binary there does not degrade, it refuses to launch. +SLICES="$(lipo -archs "${BIN}" 2>/dev/null)" +if [[ "${SLICES}" == *arm64* && "${SLICES}" == *x86_64* ]]; then + pass "universal (${SLICES})" +else + fail "not universal — got '${SLICES}'" +fi + # ── Linked libraries are all system ─────────────────────────────────────── -NONSYSTEM="$(otool -L "${BIN}" 2>/dev/null | tail -n +2 | awk '{print $1}' \ +# A fat binary prints one " (architecture x86_64):" header per slice, so +# dropping just the first line is not enough — the header repeats. Dependency +# lines are the indented ones; the headers are not. +NONSYSTEM="$(otool -L "${BIN}" 2>/dev/null | grep -E '^[[:space:]]' | awk '{print $1}' \ | grep -vE '^(/usr/lib/|/System/)' | sort -u)" if [[ -z "${NONSYSTEM}" ]]; then pass "links only system libraries" diff --git a/slab/menubar-swift/release-solo.sh b/slab/menubar-swift/release-solo.sh index 8f599d9d4..bc6052fec 100755 --- a/slab/menubar-swift/release-solo.sh +++ b/slab/menubar-swift/release-solo.sh @@ -50,12 +50,21 @@ for arg in "$@"; do done # ── 1. Build ────────────────────────────────────────────────────────────── -say "building release binary" +# Universal, not native. `swift build -c release` on this Mac produces an +# arm64-only binary that an Intel Mac cannot launch at all — and the Info.plist +# advertises macOS 11, which includes plenty of Intel machines. The studio +# build can be native because every Mac here is Apple silicon; a download +# cannot make that assumption about anybody. +say "building release binary (universal)" cd "${SCRIPT_DIR}" -swift build -c release >/dev/null -BUILT="$(swift build -c release --show-bin-path)/slab-menubar-swift" +ARCHS=(--arch arm64 --arch x86_64) +swift build -c release "${ARCHS[@]}" >/dev/null +BUILT="$(swift build -c release "${ARCHS[@]}" --show-bin-path)/slab-menubar-swift" [[ -x "${BUILT}" ]] || { err "no binary at ${BUILT}"; exit 1; } -ok "built $(du -h "${BUILT}" | awk '{print $1}')" +SLICES="$(lipo -archs "${BUILT}")" +[[ "${SLICES}" == *arm64* && "${SLICES}" == *x86_64* ]] \ + || { err "expected a universal binary, got: ${SLICES}"; exit 1; } +ok "built $(du -h "${BUILT}" | awk '{print $1}') (${SLICES})" VERSION="$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${SCRIPT_DIR}/Info.plist")" diff --git a/system/public/slab/index.html b/system/public/slab/index.html index 11f7c04d6..9f8311c15 100644 --- a/system/public/slab/index.html +++ b/system/public/slab/index.html @@ -264,6 +264,56 @@ max-width: 62ch; } + /* ── Download ─────────────────────────────────────────────────────── */ + .download { margin: 4px 0 26px; } + .dl-button { + display: inline-flex; + flex-direction: column; + align-items: center; + gap: 2px; + padding: 16px 34px; + border-radius: 14px; + text-decoration: none; + color: #fff; + background: linear-gradient(180deg, #7a4cc4 0%, #5b34a0 100%); + box-shadow: + 0 1px 0 rgba(255,255,255,0.22) inset, + 0 10px 28px -10px rgba(122, 76, 196, 0.9), + 0 0 0 1px rgba(255,255,255,0.08); + transition: transform 120ms var(--ease, ease), box-shadow 120ms ease; + } + .dl-button:hover { + transform: translateY(-1px); + box-shadow: + 0 1px 0 rgba(255,255,255,0.28) inset, + 0 14px 34px -10px rgba(122, 76, 196, 1), + 0 0 0 1px rgba(255,255,255,0.14); + } + .dl-button:active { transform: translateY(1px); } + .dl-main { + font-family: var(--mono); + font-size: 19px; + letter-spacing: 0.01em; + } + .dl-meta { + font-size: 12.5px; + opacity: 0.82; + font-variant-numeric: tabular-nums; + } + .dl-fine { + font-size: 13.5px; + color: var(--ink-dim); + margin: 12px 0 0; + line-height: 1.55; + max-width: 52ch; + } + .dl-hash { + font-family: var(--mono); + font-size: 11px; + word-break: break-all; + opacity: 0.75; + } + /* ── Recent changes ───────────────────────────────────────────────── */ #recent-commits { list-style: none; padding: 0; margin: 0; max-width: 72ch; } #recent-commits li { @@ -399,14 +449,29 @@

getting it

-

Slab is not packaged yet.

-

There is no download, no App Store listing, no one-line installer. It lives inside the Aesthetic Computer monorepo and is built from source on each Mac. If that does not put you off:

+

Free, signed, and about seven megabytes.

+ +
+ + Download Slab + for macOS + +

+ macOS 11 or later, Intel and Apple Silicon. Notarized by Apple, so it opens without a warning. +
+ +

+
+ +

Drag it to Applications and launch it. On first run it asks once whether it may add its hooks to your Claude Code settings, which is how it learns when a session starts, stops, or wants you. It backs up that file before touching it, and the Slab menu can take the hooks back out again.

+

macOS will ask for Accessibility the first time Slab moves a window, and for Screen Recording only if you ask it for a frame. Both live in System Settings under Privacy & Security, and Slab tells you when it needs one.

+

This is the first public build, and it is honest about its age. The fleet half of Slab, the parts that reach across machines, stays quiet until it is configured. If something is wrong, the source is right there and so am I.

+ +

Rather build it yourself? The repo is the studio version, symlinked so an edit lands immediately:

git clone https://github.com/whistlegraph/aesthetic-computer.git
 cd aesthetic-computer/slab
 ./install.sh --prompt-host        # hooks + session markers; no audio, no sudo
 ./menubar-swift/install.sh        # builds and launches the menu bar
-

It wants macOS on Apple silicon, the Xcode command line tools, and Claude Code. Codex and Easel sessions are tracked too. The installer merges hooks into ~/.claude/settings.json, installs a launchd agent, and asks for Accessibility so it can move Terminal windows. Screen Recording is only requested the first time something asks for a frame. ./uninstall.sh takes it all back out.

-

The lid ambient, the fleet ledger and the multi-Mac navigation are tuned to one studio's machines right now. Expect to read a shell script or two. A build you can just download is the next thing, and interest is what moves it up the list.

view source · read the README

@@ -464,6 +529,27 @@ cd aesthetic-computer/slab poll(); })(); + // The download button reads manifest.json rather than hardcoding a + // version, so publishing a new build is one file to edit and the page + // follows. The href in the markup is the fallback if this never lands. + (function download() { + const button = document.getElementById('dl'); + const meta = document.getElementById('dl-meta'); + const hash = document.getElementById('dl-hash'); + if (!button) return; + fetch('/slab/manifest.json', { cache: 'no-store' }) + .then((r) => r.ok ? r.json() : Promise.reject(new Error('HTTP ' + r.status))) + .then((data) => { + const latest = (data.versions || []).find((v) => v.version === data.latest); + if (!latest || !latest.dmg) return; + button.href = latest.dmg; + const mb = (latest.size / (1024 * 1024)).toFixed(1); + if (meta) meta.textContent = `${latest.version} · ${mb} MB · macOS`; + if (hash && latest.sha256) hash.textContent = `sha256 ${latest.sha256}`; + }) + .catch(() => { /* the markup's own href still works */ }); + })(); + // Recent changes: the last commits that touched slab/, from the same // endpoint the Menu Band page uses. (function recentChanges() { diff --git a/system/public/slab/manifest.json b/system/public/slab/manifest.json new file mode 100644 index 000000000..816bbaf6d --- /dev/null +++ b/system/public/slab/manifest.json @@ -0,0 +1,14 @@ +{ + "_comment": "Release index for the Slab direct download, served by lith at /slab/manifest.json and read by the download button on /slab. The DMG itself lives on assets.aesthetic.computer; this file is the bookkeeping that points at it. Written alongside slab/menubar-swift/release-solo.sh — see slab/README.md. Keep older versions in versions[] so an archival link never dies.", + "latest": "1.0", + "versions": [ + { + "version": "1.0", + "dmg": "https://assets.aesthetic.computer/slab/Slab-1.0.dmg", + "size": 6924404, + "sha256": "5db38b4faf957e6669a3c5dd18c10e05dfe1ea29cd37e5fbd87178f83d3b9365", + "releasedAt": "2026-09-16", + "requirements": "macOS 11+ · Universal (Intel + Apple Silicon)" + } + ] +} -- 2.51.2