perf(install): gzip binaries (~60MB → ~20MB download)#38
Conversation
Bun --compile embeds the full runtime, so each binary is ~60MB — the download looked frozen and was slow. release.yml now gzips the unix binaries (Bun compresses ~3×); install.sh fetches <asset>.gz and gunzips, with a raw-binary fallback for older releases. Checksums cover the DECOMPRESSED artifact (what runs), so integrity still verifies end-to-end. Windows .exe stays raw (manual download). Verified the gzip→verify flow locally. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GMbAe5K1RfwaAcge5inX7P
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
jwfing
left a comment
There was a problem hiding this comment.
Summary
Gzips the unix release binaries (~60MB → ~20MB) and teaches install.sh to prefer <asset>.gz (gunzip + verify) with a raw-binary fallback; the SHA256SUMS/verify invariant is handled correctly. Clean, well-scoped change.
Requirements context
No matching spec/plan found — this repo has no docs/ (or docs/superpowers/ / docs/specs/) directory at the PR head, so I assessed against the PR description and linked context (#37) alone. No requirements were invented.
Findings
Critical
(none)
Suggestion
Functionality / robustness — the .gz HEAD probe is load-bearing, and its fallback is dead for new releases — install.sh:89-96
On a new release, only the .gz unix assets exist: release.yml:72 runs gzip -f, which replaces each raw insta-<os>-<arch> with insta-<os>-<arch>.gz, and release.yml:97 uploads dist-bin/insta-* (i.e. the .gz files + the raw Windows .exe). So the raw unix asset is no longer published. That means the curl -fsSL -I "$base/$asset.gz" probe must succeed for new releases — if it ever returns a false negative (e.g. a signed-redirect target that rejects HEAD, a proxy that strips/blocks HEAD, a transient error), the else branch downloads the raw $asset, which 404s, and the user sees a misleading error: download failed ($base/$asset) even though the correct .gz asset was right there. The raw fallback only actually helps older releases that predate gzip.
Consider folding detection into the download instead of a separate probe — attempt the .gz download and fall back to raw only on failure — which removes the extra round-trip and the signed-URL-HEAD dependency. At minimum, make the fallback failure message point at both attempted URLs so the real cause isn't hidden.
Software engineering / tests — no automated regression for the gzip→gunzip→verify path — install.sh:88-97, release.yml:64-74
The PR was validated manually (per the description), and the repo's test suite is vitest/TS with no shell-installer harness, so this isn't a convention violation. But "SHA256SUMS lists the decompressed hash and install.sh verifies post-gunzip" is exactly the invariant that silently breaks if either side changes. A tiny CI smoke step (gzip a fixture → run the install.sh download/verify block against a local file:// or a dry-run) would guard it cheaply. Non-blocking.
Information
- Manual verification UX —
release.yml:67-69:SHA256SUMSlists raw-binary names/hashes while the published unix assets are.gz.install.shhandles this correctly (it verifies after decompressing), but a user runningsha256sum -c SHA256SUMSdirectly against the downloaded release assets will get failures, since the on-disk files are*.gzand the listed raw names aren't present. Worth a one-line note in the release notes/README that SHA256SUMS is verified against the decompressed binary. - Partial-build edge —
release.yml:72:for f in insta-darwin-* insta-linux-*assumes every matrix target produced an artifact. Withfail-fast: false(release.yml:21), a single failed target would leave the glob unmatched andgzipwould error the release step. This is a pre-existing property of thesha256sum insta-*line too, and a partial release is already broken, so it's informational only. - Security — no new security-relevant surface. Integrity is preserved: the decompressed artifact is SHA256-verified against
SHA256SUMSbeforechmod +x/install (install.sh:99-117), gunzip's CRC catches transport corruption, transport is HTTPS from GitHub, and no secrets/tokens/PII are added or logged.insta upgrade(binary channel) delegates to this sameinstall.sh(src/commands/upgrade.ts:76), so it inherits the fix rather than needing a parallel update. - Performance — strongly positive: ~3× smaller download for the common path. The only cost is one extra HEAD round-trip per install (see the Suggestion above), which is negligible next to the ~40MB saved.
Verdict
approved (informational — a human still gives the explicit GitHub approval via the approve flow). Zero Critical findings. The two Suggestions are worth addressing, particularly the load-bearing HEAD probe, but none block merge.
Why it looked stuck / slow: Bun
--compileembeds the whole runtime, so each binary is ~60MB (vs Railway's ~20-30MB Rust binary). #37 added the progress bar (visibility); this halves-and-then-some the actual bytes.release.yml gzips the unix binaries (Bun compresses ~3× → ~20MB); install.sh prefers
<asset>.gzand gunzips, with a raw-binary fallback for older/pinned releases. SHA256SUMS covers the decompressed artifact, so integrity verifies what actually runs (validated the gzip→verify flow locally). Windows .exe stays raw. install.sh is served from main → the download logic is live on merge; the compressed assets appear on the next release tag.🤖 Generated with Claude Code
https://claude.ai/code/session_01GMbAe5K1RfwaAcge5inX7P
Summary by cubic
Gzip macOS/Linux release binaries and update the installer to prefer
<asset>.gz, gunzip, and verify the SHA256 of the uncompressed binary. This cuts downloads from ~60MB to ~20MB, falls back to raw binaries for older releases, and leaves the Windows.exeuncompressed.Written for commit 229b3fc. Summary will update on new commits.