scripts/install.sh picks the binary for the machine (musl on Alpine, native arm64 under Rosetta), verifies it against the release's SHA256SUMS and installs to ~/.local/bin. qqq.rb and qqq.json follow the qctl tap and bucket shapes; scripts/update-packaging.mjs fills their version and checksums from the uploaded release so nobody pastes sums by hand. The formula writes its own #compdef zsh file because the output of qqq completion zsh is an eval script, not an fpath file. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Packaging the qqq CLI
Every install path ships the same single-file binaries that npm run binaries
(scripts/build-binaries.mjs) writes to dist/, uploaded to a GitHub release tagged cli-v<version>
together with SHA256SUMS. The npm packages (@qrun-io/qqq-cli on GitHub Packages) are the other
route, for machines that already have Node 20+.
| File | What | Where it goes |
|---|---|---|
scripts/install.sh |
curl installer: picks qqq-<os>-<arch>[-musl], checks it against SHA256SUMS, installs to ~/.local/bin (--dir, --version) |
served from main: curl -fsSL https://raw.githubusercontent.com/QRun-IO/qqq-cli/main/scripts/install.sh | sh |
qqq.rb |
Homebrew formula draft (macOS arm64 and x64, Linux arm64 and x64), same shape as qctl.rb, with bash, zsh and fish completions |
Formula/qqq.rb in a QRun-IO tap |
qqq.json |
Scoop manifest draft (Windows x64), same shape as qctl's, with checkver and autoupdate reading SHA256SUMS |
bucket/qqq.json in a QRun-IO Scoop bucket |
Release steps
node scripts/release.mjson a clean tree; it prints the tag and publish commands.- Tag
cli-v<version>and create the GitHub release withdist/qqq-*anddist/SHA256SUMS(gh release create, printed by step 1). - Download that release's
SHA256SUMSand runnode scripts/update-packaging.mjs <path>; it writes the version and the checksums intoqqq.rbandqqq.json. Use the uploaded sums, not a local rebuild: each build stamps its commit into the binary, so checksums differ between builds. - Copy
qqq.rbto the tap andqqq.jsonto the bucket and open a pull request on each.
Where the formula and manifest live
QRun-IO has one tap today, QRun-IO/homebrew-qctl
(brew tap QRun-IO/qctl), and qctl's Scoop manifest lives in qctl/packaging/scoop. Two options:
- Add
qqqto the existing tap:brew install qrun-io/qctl/qqq. No new repository; the tap name reads oddly. - A general tap and bucket (
QRun-IO/homebrew-tap,QRun-IO/scoop-bucket) holding both qctl and qqq:brew install qrun-io/tap/qqq,scoop bucket add qrun https://github.com/QRun-IO/scoop-bucket. The qqq-orb already has ahomebrew-tapprofile for such a repository. Recommended before 1.0 final.
Platform notes
- macOS: Bun signs the binaries ad hoc, which is enough for Homebrew and curl installs (neither sets
the quarantine flag). A binary downloaded with a browser is quarantined;
xattr -d com.apple.quarantine qqqclears it. Developer ID signing and notarization are not done yet. - Linux musl (Alpine):
qqq-linux-<arch>-muslneedsapk add libstdc++ libgcc. The installer picks the musl build on Alpine and other musl hosts. - x64: built on Bun's baseline runtime, so the binaries run on CPUs without AVX2 and under Rosetta 2 or QEMU.
- Windows:
qqq-windows-x64.exeis cross-compiled and not signed (Authenticode, per the KofTwentyTwo release standard, is a follow-up). Sign-ins use DPAPI through PowerShell. No Windows CI lane runs it yet; seedocs/ci-lanes.md. - Binaries are 85 to 111 MB (the Bun runtime is embedded); about 37 to 53 MB gzipped.