Releases: msitarzewski/brew-browser
brew-browser 0.6.0 / native 0.2.0
brew-browser 0.6.0 / Brew Browser native 0.2.0 — feature-request batch
Signed + notarized release. Tauri is the macOS 13+ / Linux build; native is the
macOS 26 SwiftUI build. The two version numbers track the same feature batch
(native 0.2.0 ≙ Tauri 0.6.0); they differ only because each shell versions by
its own release history.
What's new
- Reverse dependencies in package detail. Package pages show which installed
packages require the selected formula ("Required by"). - Deprecated / disabled indicators. Rows and detail panels surface Homebrew's
deprecation and disablement metadata — with the upstream reason and any
replacement token — instead of hiding lifecycle state. - Manual vs Dependency Library filters. Library filtering separates packages
the user requested from formulae installed only as dependencies. - Per-package disk size. Package detail shows the on-disk Cellar/Caskroom
footprint for installed packages. - Discover sub-categories. Within a selected Discover category, members are
grouped by their co-assigned categories so broad buckets are easier to scan. - Friendlier failure notices. When a brew job fails, the Activity drawer now
shows a concise, actionable notice instead of a raw error code. Casks that
need an administrator password (e.g.docker-desktop) — which can't prompt
under brew-browser's non-interactive brew — now explain to run the upgrade in
Terminal, and name the cask.
Changes
- The Dashboard "Recent changes" card has been withdrawn for this release while
its presentation is reworked; it will return in a follow-up. No data is lost —
the full history remains in the Activity view. - Package metadata and docs aligned to the release train: Tauri
0.6.0,
native0.2.0.
Acknowledgments
- The Reddit feature-request feedback that shaped this batch.
brew-browser 0.5.1
brew-browser 0.5.1 — Reliability + a native sibling
Signed + notarized. macOS 13+, Apple Silicon. Auto-updates via the in-app updater.
This release also debuts a second build: a fully native Swift / SwiftUI
app for macOS 26 (Tahoe). Same features, samebrewintegration, same privacy
posture. See the README → "Two builds." The Tauri build below remains the
cross-platform one (macOS 13+ and Linux).
What's new
Live progress during installs and upgrades. Multi-package operations now show
a determinate progress bar with a per-package count — Pouring 10 of 32 — parsed
from brew's own ==> markers, instead of just a wall of streaming text. (#57)
The window remembers its size and position. Resize or move the window, quit,
and relaunch — it reopens exactly where and how you left it. (#17, #19)
The Dashboard fills in on launch. Your GitHub card, the vulnerability Exposure
card, and the sidebar badges now populate from cache on first paint, instead of
looking empty until you poked around.
Fresher catalog. The bundled Homebrew catalog was refreshed (8,404 formulae +
7,703 casks). Hit Refresh anytime for the latest.
Bug fixes
"Upgrade all" no longer cries failure when it succeeded. brew upgrade exits
non-zero on harmless post-install/link warnings even when every package upgraded;
the app treated that as a failure and nudged you to file an issue. Those non-fatal
cases are now reported as success — genuine failures still surface with a clear
message. (Resolves a large cluster of "[brew-browser] Upgrade-all failed" reports.)
"Top categories in your library" filters your library. Clicking a category in
that card now shows your installed packages in it, not the entire Discover
catalog. (#58)
GitHub sign-in is reliable and sticks. The credential is now stored as a single
Keychain item, so signing in is one prompt and the signed-in state persists across
launches (previously it could appear signed-in but not reflect in Settings). (#51)
Window stays draggable with Settings open. The Settings scrim no longer covers
the title bar's drag region. (#8, #10)
Acknowledgments
- @neodave — path-traversal hardening in Brewfile/snapshot handling (#46).
- @Arvuno — a friendly
brew serviceslaunchd-domain hint (#51). - @bytepl (Maciej Chojnacki) — window-state report (#17).
- @unluckyquote (Nik) — unmovable-window-with-Settings-open report (#8).
- Reddit feedback that shaped this release: u/arcadefx1 (operation progress
counts), u/HedgeHog2k and u/sikisabishii (library category filter).
v0.5.0 — Opt-in Vulnerability Scanning
brew-browser v0.5.0 — Opt-in vulnerability scanning
Signed + notarized. macOS 13+, Apple Silicon. Auto-updates from v0.4.0 via the in-app updater.
Highlights
You can now find out which of your installed Homebrew formulae have known CVEs — without leaving the app. v0.5.0 adds opt-in vulnerability scanning powered by the official brew vulns subcommand (Homebrew/homebrew-brew-vulns, by Andrew Nesbitt, published January 2026). When you turn it on, brew-browser shells out to brew vulns to query OSV.dev's GIT ecosystem for vulnerabilities matching your installed formula versions, then optionally enriches each finding with richer prose from the GitHub Advisories API.
Off by default. Both new toggles (vulnerability scanning + GitHub auth for enrichment) sit behind explicit consent in Settings → Network. No first-launch user generates a single OSV query without flipping the switch.
What's new
Opt-in vulnerability scanning. Settings → Network → Vulnerability Scanning toggles the feature on. When brew vulns isn't installed yet, the Settings card shows a one-click installer button that runs brew install homebrew/brew-vulns/brew-vulns for you and streams the output into the Activity drawer. After install, flip the toggle and the first scan kicks off automatically.
Dashboard Exposure card. A new card on the Dashboard shows your aggregate exposure: counts of critical / high / medium / low / unknown findings across all installed formulae, plus a "Scan now" button to force a refresh. When you're clean, the card shows a ✓ checkmark and "No known vulnerabilities" — the clean state IS the message, no collapsing.
Sidebar count badge. A small count badge on the Library nav item shows how many of your installed packages have at least one known CVE. The badge color tracks the highest severity (red for critical, orange for high, amber for medium, blue for low, grey for unknown). Hidden when the count is zero so the sidebar stays uncluttered.
PackageRow severity dots. Library rows get a small color-coded dot next to the installed pill when a package has known vulnerabilities. Hover for a tooltip; click through to the detail panel for the full list. The dots are synchronously hidden when the feature is off — no extra IPC chatter.
PackageDetail Security card. Open any installed formula's detail panel and you'll see a new Security card listing every CVE/GHSA finding for that package: severity pill, advisory ID (linked out to GHSA or OSV when there's a reference URL), summary text, and the version range where it's fixed. When the package is outdated AND at least one finding has a fixed_in range, an "Upgrade to fix" button is wired straight into the existing brew upgrade pipeline. A "Check vulnerabilities" button lets you force a per-package re-scan whenever you want.
Install-set fingerprint optimization. Daily scans on an unchanged install set serve from cache instantly. The backend records a SHA-256 fingerprint of your sorted kind:name:version lines alongside the scan results. On the next open, if nothing has changed, the cached report is returned without re-shelling brew vulns (which can take 60+ seconds with 200 packages). The "Scan now" button on the Dashboard Exposure card forces a full re-scan when you want the latest.
Refresh integration. When you click Refresh on the Dashboard or in Library — which now runs brew update, refreshes the catalog, AND reloads your installed list — the vuln scan re-runs as part of the same flow. So a refresh that learned about a new upstream version of openssl@3 and a new CVE for it shows you the security finding in the same beat as the new version number.
Post-mutation re-scans. Every install / upgrade / uninstall invalidates the affected cache entry and triggers a per-package re-scan, so the Security card and severity dot reflect reality immediately after you act — no stale ✓ from yesterday's pre-upgrade state.
How to enable
- Open Settings → Network → Vulnerability Scanning.
- If
brew vulnsisn't installed, click Installbrew vulns. The output streams into the Activity drawer. Takes ~10 seconds. - Flip the Enable vulnerability scanning toggle on.
- The first scan kicks off automatically. Larger install sets take longer; the Exposure card shows progress.
- Optional: in Settings → GitHub, sign in to GitHub if you want GHSA enrichment — richer summaries, patched-version ranges, and reference links from
api.github.com/advisories. Without GitHub auth, you still get full OSV data; GHSA is purely a UX upgrade.
To turn it off later: flip the same toggle. The on-disk cache stays around (in case you turn it back on) but no scans run and no UI surfaces show vulnerability information. Offline Mode hard-locks the feature regardless.
Trust boundary
This is the first feature that involves an outbound path opened by a subprocess, not by brew-browser itself. The architecture is explicit so the privacy story stays auditable:
api.osv.dev— OSV.dev's GIT-ecosystem query endpoint. POST'd bybrew vulns, not by brew-browser directly. We invoke the subprocess; the subprocess opens the socket. Same trust posture as every otherbrewcall (thebrew installyou ran yesterday also opens sockets to GitHub, OCI registries, and bottle mirrors — and you'd see them in the Activity drawer if you looked).github.com,gitlab.com,codeberg.org— source-URL and version-tag resolution bybrew vulnsso it can match your installed version against the vulnerable-version ranges OSV publishes. Same subprocess-as-origin posture.api.github.com/advisories/{GHSA_ID}— GHSA enrichment from brew-browser's own Rust code, only when both Vulnerability Scanning AND GitHub Sign-in are on. Three independent toggles must align for a single request to leave the box: master Offline Mode off, vulnerability-scanning toggle on, github-enabled toggle on. Failure (rate limit, network error) leaves the OSV record unchanged and logs without bothering you.
Full server-side audit in memory-bank/security.md §17. The gate-composition table, threat model, and pre-launch checklist all live there.
Known limitations (honest gaps)
- Casks aren't supported.
brew vulnsis formula-only. Cask packages render the same UI shell in the Security card but the body honestly says "Cask coverage isn't supported —brew vulnsis formula-only." This isn't fake clean state; we'd rather be honest about the gap than tell you a package is safe when we have no idea. - Formulae with tarball-only sources may show empty results.
brew vulnsresolves vulnerabilities by mapping source URLs to upstream version tags in OSV's GIT ecosystem. Formulae whose source is a tarball without a corresponding Git tag may not match cleanly. This is rare in practice (most Homebrew formulae point at GitHub/GitLab releases that have both tarball and tag), but worth knowing about if a formula you expected to see findings for shows none. - GHSA enrichment is best-effort. If you've enabled GitHub sign-in, GHSA gives you richer data than OSV alone. But if
api.github.comrate-limits you, throws a 5xx, or is unreachable, the enrichment quietly fails and you see the OSV record without the prose extras. No retry, no toast — the scan is reliable; the cherry on top isn't load-bearing.
What's NOT changed
- Without opting in, nothing changes about your outbound posture. No OSV traffic, no GHSA requests, no
brew vulnsinvocations. The previous ten outbound paths from v0.4.0 are unchanged. - The Settings UI keeps the same shape. The new Vulnerability Scanning section sits at the bottom of Network alongside the existing Updates and Enhanced Trending History subsections — same nested-subsection pattern, same "locked off" treatment when Offline Mode is on.
- No new dependencies in the frontend. The store, types, and components are pure additions.
- Two new Rust dependencies (
sha2,hex) for the install-set fingerprint. Both are widely used; SHA-256 is the right primitive here because Rust'sDefaultHasheris non-deterministic across process runs (its salt is randomized to defeat HashDoS) — a hash recorded to disk would mismatch every subsequent launch.
Under the hood
- +78 backend tests (507 → 585). Pin the new gates exhaustively: toggle off →
FeatureDisabled, paranoid on →ParanoidModeBlocked, FirstLaunch →FeatureDisabled(opt-in preserved), Corrupt settings →ParanoidModeBlocked(fail-closed), forward-compat for v0.4.x settings.json missing the new field, formula name validator rejects shell metas + empty + oversize, cache TTL is 6 hours, fingerprint is order-independent, GHSA enrichment short-circuits when github_enabled is off. +6 of those tests are a captured-fixture pin against realbrew vulns --jsonoutput — the live smoke test on a 326-package install caught five integration assumptions that were wrong (severity wire is UPPERCASE;fixed_versionsis an array not a string; install-detection neededbrew --prefix brew-vulns, notbrew commands;--include-aliasesneeds--quiet; brew-vulns exits 1 on findings per CI-scanner convention). All five are now regression-pinned and commented at the trap sites. - One new error variant
vulns_not_installedin the BrewError union, with a friendly message routing the user to the one-click installer (not a generic exit-non-zero toast). - Two on-disk caches at
~/Library/Application Support/brew-browser/:vulns_cache.json(1 MiB cap, 6h per-record TTL) for scan records + the install-set fingerprint;ghsa_cache.json(2 MiB cap) for the enrichment payloads. Both fail soft on corrupt + future-schema — no first-launch user can be wedged by a bad cache file.
Acknowledgements
brew vulnsby Andrew Nesbitt — [github.com/Homebrew/homebrew-brew-vulns](https://github.com/Homebrew/homeb...
v0.4.0 — Trending Velocity + Opt-in History Endpoint
brew-browser v0.4.0 — Velocity scoring + Star-History for Homebrew
Signed + notarized. macOS 13+, Apple Silicon. Auto-updates from v0.3.1 via the in-app updater.
Highlights
Trending now sorts by velocity, not raw count. The old Trending tab was a leaderboard of dep-pulled packages — ca-certificates, openssl@3, git always on top because everything depends on them. v0.4.0 fixes that by computing a per-package velocity index from the three rolling-window install counts Homebrew publishes (30d, 90d, 365d). The math is "this month's installs vs the prior eleven months' average month" — 1.0 is steady, 1.5+ is surging, 0.5 or below is cooling. The Trending tab defaults to sorting by velocity desc with 🔥 / ❄️ badges on each row. The result is what's actually accelerating right now, not what's already big — and packages with zero prior history are filtered out so a brand-new tap doesn't auto-pole-position the leaderboard.
install-on-request signal. The Trending tab now fetches Homebrew's install-on-request analytics endpoint in parallel with the primary install endpoint. The first counts installs users explicitly typed brew install <foo> for; the second includes everything pulled in as dependencies. Both numbers are available on each row internally, with the leaderboard-dominator metric (install) staying as the visible Installs column and the user-intent metric feeding the velocity computation underneath. Together they de-noise the trending signal dramatically.
Star-History for Homebrew (opt-in). When you enable Enhanced Trending History in Settings → Network, you get:
- Inline mini-sparklines on every Trending tab row, showing each package's install trajectory at a glance
- A full install-trend chart on each package's detail panel
- Server-precomputed velocity index that updates nightly (independent from the per-window-fetch computation)
This data comes from a new project-operated endpoint at brew-browser.zerologic.com/trending-history/*. It's the first outbound path in brew-browser's history that goes to infrastructure we control (rather than upstream Homebrew or GitHub), so it gets an explicit opt-in toggle and lives in its own section of the disclosure list at the bottom of Settings → Network. Off by default. Offline Mode hard-locks it off regardless. Only the package name you're viewing is sent (one HTTP GET per package); no IP is logged, no cookies, no fingerprinting. The Caddy log-redaction config that makes the privacy claim auditable is published in memory-bank/security.md §16.
The day-zero seed trick. When you opt in on day one, the historical chart isn't empty — the collector that runs on brew-browser.zerologic.com bootstraps three historical "buckets" per package from rolling-window subtraction (last 30 days, days 31–90, days 91–365). From that point forward, the nightly collector accumulates real daily snapshots; after ~30 days you have clean per-day install estimates. The historical bars fade into the background as the real daily resolution builds up on the right edge of every chart.
Settings → Network reorganization
New disclosure entry (10th in the list, was 9):
brew-browser.zerologic.com/trending-history
Enhanced trending history — opt-in, off by default
New nested subsection at the bottom of Network alongside the existing Updates panel. Single toggle, clear hint copy explaining what's sent, what's logged (nothing identifiable), what's not. Disabled with a "locked off" indicator when Offline Mode is on.
What's NOT changed
- Without opting in, nothing changes about your outbound posture. Velocity sorting and the 🔥/❄️ badges work entirely from the always-on Homebrew analytics endpoints. The only new behavior is "Trending sorts differently by default" — and you can still pick any other sort key from the column headers.
- The previous nine outbound paths are unchanged. README's disclosure section has been updated to enumerate all ten (path j = the new endpoint).
Under the hood
- +33 backend tests (473 → 506). Pin the new gates exhaustively: toggle off →
FeatureDisabled(distinct fromParanoidModeBlockedso toasts route correctly), paranoid on →ParanoidModeBlockedregardless of the per-feature toggle, FirstLaunch →FeatureDisabled(opt-in posture preserved), Corrupt settings →ParanoidModeBlocked(fail-closed via inner gate), URL builder for the per-package fetch rejects path traversal exhaustively (../, spaces,;, etc.). - One new dependency on the backend: none. Velocity math is pure Rust in
src-tauri/src/trending/velocity.rs; the parallelinstall+install-on-requestfetch reuses the existingreqwestclient. The history endpoint client is a thin GET wrapper. - One new dependency on the collector:
better-sqlite3. The collector is a separate Node 20+ ESM project attools/trending-collector/that ONLY runs onbrew-browser.zerologic.com— the brew-browser app itself doesn't pull this in. - New error variant
feature_disabledin the BrewError union, mirrored inBrewErrorPayloadwith a friendly message that routes the user to Settings → Network rather than the master Offline Mode switch.
Acknowledgements
Velocity-as-the-Trending-sort idea came from a user observation: "Trending needs more algo though. It's straight from the brew APIs. We need velocity, right?" The seed-from-rolling-windows bootstrap trick followed from "Use A to create B's first debut. Then we can watch with real data from then on?" — using the same three windows we already fetch to give the historical chart something to show on day zero.
Star-History inline-row sparkline aesthetic borrowed from star-history.com's trending repo list.
Issues & feedback
github.com/msitarzewski/brew-browser/issues. Every error toast in the app has a "Report" button that pre-fills the issue with your context. Use it liberally — it's literally what the button is for.
v0.3.1 — Magic search, real Refresh, cleaner identity
brew-browser v0.3.1 — Magic search, real Refresh, cleaner identity
Signed + notarized. macOS 13+, Apple Silicon. Auto-updates from v0.3.0 via the in-app updater.
Highlights
Magic search. Search now matches against everything brew-browser knows about — not just package names. Try queries like:
video player— finds VLC, mpv, MPlayer (matches AI summaries)password manager— finds 1Password, Bitwarden, KeePassXCAIorLLM— finds ollama, llm, openai-cli, llama.cppVideo & Audio— returns every package in that categoryterminal emulator— iTerm2, Alacritty, kitty, WezTerm
Behind the scenes: a new in-process local_search IPC scans the bundled catalog + AI summaries + friendly names + category labels + (eventually) Tier B tags, scores each hit by field weight (name > friendly > category > summary > desc > tag), and returns top results in well under 20ms — much faster than the previous brew search shell-out.
Unified Description + Version columns. Library, Discover, and Trending list views now share the same canonical row layout: (icon/rank) | NAME | DESCRIPTION | VERSION | TYPE | TRAIL. The Description column prefers the AI-generated summary when available, falls back to the upstream Homebrew desc. Friendly name still appears as a short subtitle below the token for scan-aid.
Curated Upgrade UX. The Updates card on the Dashboard gains a "Choose…" button next to "Upgrade all". Click it to see every outdated package with a checkbox, name, current → target version, and a pinned badge. Pick which ones to upgrade this round; the modal fires one batched brew upgrade <a> <b> ... streaming into the Activity drawer.
Refresh actually refreshes everything. The Refresh button now runs brew update (so brew learns about new upstream versions), refreshes the bundled catalog from formulae.brew.sh, AND reloads your installed list — in that order, streaming the brew update output to the Activity drawer. Previously Refresh only updated the catalog index, leaving outdated flags stale until you ran brew upgrade in a terminal.
Donut chart hover-with-counts. Hover any slice (or its matching legend row) on the Dashboard's "Top categories" donut: the slice fattens, the others dim, and the center text takes over with {count} / {label}. Click the legend row to jump straight to that category in Discover.
Report-to-brew-browser on every error. Error toasts now carry a "Report to brew-browser" button that opens a pre-filled GitHub new-issue URL with your brew-browser + Homebrew versions, the failing command, exit code, stderr excerpt, and the friendly message brew-browser tried to show you. Same button surfaces in the Activity drawer when a job fails.
Friendly error messages. Ten toast sites that previously rendered the raw error code (brew_exit_non_zero) now render the actual friendly message from the backend. Among other things, this means the shiva brew bundle dump topo-sort crash now surfaces with the "this is an upstream Homebrew bug, not a brew-browser issue" guidance it was always meant to.
Quieter improvements
- Bundle identifier cleaned up:
dev.openbrew.browser→com.zerologic.brew-browser. v0.3.0 users will be prompted to re-sign-in to GitHub once (Keychain ACLs are tied to the old identifier; no migration is possible without re-prompting anyway). One-click via the "Re-authorize" toast button that already ships. - Activity history is more durable. Cap raised from 50 jobs to 200.
startJobnow persists immediately instead of waiting for the 400ms debounce. Persist + hydrate failures now log to the console instead of silently swallowing. brew_listcache invalidation. Addingforce=trueto the IPC; the Refresh button uses it. Previously a staleinstalled_cachecould maskbrew upgraderuns from your terminal until process restart.- Stale "Paranoid mode is on" toast wording still slips through the central
brewErrorMessageforparanoid_mode_blocked. The rename to "Offline Mode" was applied everywhere else; this one was missed in Phase 15 and got carried forward — fix landed in this release.
Under the hood
- 473 backend tests passing.
CatalogEntrySummarygains aversion: Option<String>field so the new Version column can render without per-row IPC.- Activity drawer's failed-job footer gains a "Report to brew-browser" button next to the failure summary.
tauri-plugin-dialogwas already wired since v0.1.0 (catching up the realityCheck doc with a post-audit footnote).- Memory bank reorganized:
BUILD.md,PHILOSOPHY.md,PLAN.mdmoved from repo root todocs/;phase15-plan.mdmoved tomemory-bank/phases/now that Phase 15 has shipped.
Install
If you're on v0.3.0, click Refresh on the Dashboard or open Settings → Network → Updates → Check now. The in-app updater will pick this up, verify the signed .app.tar.gz against the embedded minisign pubkey, and replace your installed .app atomically. Click Relaunch now when it finishes.
For fresh installs, the .dmg is on the GitHub release page. Drag to Applications. macOS Gatekeeper accepts it cleanly (signed + notarized + stapled).
Acknowledgments
- @heyjawrsh for the issue-#1 flow that drove the friendly-message + Report-to-brew-browser work.
Full diff: v0.3.0...v0.3.1
v0.3.0 — In-app updater + GitHub coverage + issue #1 fixes
brew-browser v0.3.0 — In-app updater + GitHub coverage + issue #1 fixes
Signed + notarized. macOS 13+, Apple Silicon.
Highlights
In-app updater. brew-browser now tells you when a new version exists. A title-bar pill appears when a newer release is detected; Settings → Network → Updates owns the manual "Check now" button, the off-by-default daily auto-check, and the install action. Every artifact is verified against an embedded minisign public key before any on-disk side effect (sha256 first, then signature — mismatch aborts with no install). Skipping a version is per-release, so a future update re-triggers the notice.
"Offline Mode" instead of "Paranoid Mode." Same kill switch, friendlier name. Toggle in Settings → Network blocks every outbound feature: catalog refresh, trending, GitHub, updater. The internal field stays paranoid_mode to avoid migrating existing settings files.
GitHub coverage expansion. Packages like bat, fd, ripgrep, tealdeer — marketing-page homepages but GitHub-hosted source — now light up Star / Watch / File-issue / Stats. Backend walks homepage → urls.stable.url → urls.head.url (formula) or homepage → url (cask). The Dashboard's personal-stats card sees a bigger denominator.
GitHub Octocat status chip in the title bar. Green when signed in with required scopes, amber when a scope is missing (click → Settings → GitHub to re-authorize), hidden when signed out.
Actionable Re-authorize toast. If an action fails because your token doesn't carry the required scope (typical for tokens minted before v0.3.0 added notifications scope for Watch), the failure toast offers a one-click "Re-authorize" button. GitHub's consent screen shows only the missing scope. No sign-out needed.
Issue #1 fixes. Resolves the toast cascade on disconnect/reconnect that @heyjawrsh reported. Root cause was a cache loop in PackageDetail hammering Svelte's scheduler combined with a structural misuse of $effect for one-shot side effects. Star, Watch, File-issue, and the sign-in flow all work cleanly now.
Under the hood
- 473 backend tests passing (up from 411 in v0.2.1).
- Tauri 2 in-app updater plugin with embedded minisign pubkey + sha256 manifest verification.
- Per-action OAuth scope gating — Star/File-issue need
public_repo, Watch/Unwatch neednotifications. The gate runs server-side before any GitHub round-trip. - New
extract_github_repotolerant URL parser that handles archive + release URLs (.../archive/refs/tags/v1.2.3.tar.gz,.../releases/download/v1.2.3/foo.dmg) while applying every strict-parser defense (host, scheme, character set, path traversal). - Lazy Keychain probe preserved — fresh launches still don't trigger the macOS "wants to use your confidential information" prompt unless you actually use a GitHub feature.
Install
Download brew-browser_0.3.0_aarch64.dmg, double-click, drag to Applications. macOS Gatekeeper will accept the signed + notarized binary without warnings.
If you're on v0.2.1, the in-app updater will surface this release after you upgrade once — manual .dmg installs are still supported but the auto-updater path is the recommended cadence going forward.
Acknowledgments
- @heyjawrsh for filing issue #1 with a clear reproduction. Six hours of debugging surfaced two genuinely interesting Svelte 5 rabbit holes; the diagnosis is in
memory-bank/tasks/2026-05/14-issue-1-hunt-cache-loop.mdand15-github-integration-completion.mdfor the curious.
Full diff: v0.2.1...v0.3.0
brew-browser v0.2.1
brew-browser v0.2.1
Hotfix on top of v0.2.0 — addresses three GitHub-auth issues users hit immediately, plus a few quality-of-life touches.
Fixes
macOS Keychain prompt on every launch
v0.2.0 eagerly probed the Keychain on app start to know whether you were signed in to GitHub. macOS treats a new binary signature as a new app for ACL purposes, so fresh installs of v0.2.0 fired the "brew-browser wants to use your confidential information stored in dev.openbrew.browser" prompt on every launch — even users who'd never touched a GitHub feature.
v0.2.1 makes the Keychain probe lazy: the OS prompt only fires when you actually click Star / Watch / File-issue, or open Settings → GitHub. If you never use a GitHub feature, the Keychain is never touched, and the prompt never fires. When it does fire, it's contextual — you're about to use the token, the prompt is meaningful.
GitHub auth toast bugs
- "Signed in as @github user." — the post-sign-in success toast was reading
status.usernamebefore the username had been fetched. Fixed: status loads beforesigninStateflips to approved. - Stack of duplicate "Signed in to GitHub" toasts — the toast effect re-ran on every status hydration. Fixed:
untrack()wrapping in the Svelte 5 effect so it's pinned to one toast per real state transition.
Star / Watch / File-issue worked correctly when authed
v0.2.0 bounced authenticated users to Settings → GitHub instead of running the action. This is the same root cause as the Keychain prompt — fixed in the same patch (lazy probe in requireGithubSignIn).
Small things
- Real screenshots — the README and landing page now show actual product UI (Dashboard light/dark + Services). Landing's hero
<picture>usesprefers-color-schemeso visitors see the screenshot matching their system theme. - Accurate build credit — "Powered by Anthropic's Claude Opus 4.7 and the Claude Agent SDK" → "Powered by Claude Code in the terminal, running Opus 4.7 [1m]." Claude Code is the runtime (this CLI), Opus 4.7 [1m] is the model.
- gitleaks allowlist — added
.gitleaks.tomlallowlisting the public OAuth Device Flow client_id. Per RFC 8628 §3.1, Device Flow client_ids aren't credentials; the false-positive flag was the only thing gitleaks caught.
Security audit re-run
Full tool battery passed against the v0.2.0/v0.2.1 surface:
| Tool | Result |
|---|---|
cargo audit |
0 vulnerabilities |
cargo deny check |
advisories ok, bans ok, licenses ok, sources ok |
npm audit --omit=dev |
0 vulnerabilities |
semgrep (security-audit + OWASP-10 + Rust + TS, 113 rules, 104 targets) |
0 findings |
gitleaks |
0 leaks (after allowlist) |
Verdict: READY-FOR-SCRUTINY preserved. Full breakdown in memory-bank/security.md §14.
Install
Download the signed + notarized .dmg below, open, drag to Applications. No Gatekeeper warning. macOS 13 (Ventura) or newer · Apple Silicon.
Full changelog
Built with Agency Agents, by the creator of Agency Agents. Powered by Claude Code in the terminal, running Opus 4.7 [1m]. If brew-browser saves you time, sponsor on GitHub ♥.
brew-browser v0.2.0
brew-browser v0.2.0
A structural overhaul of the UI since v0.1.0 — title bar, sidebar, info popovers, and a smarter sign-in flow. Same MIT-licensed, telemetry-free, account-free desktop app on top of brew.
What's new
Native macOS title bar
- Unified title bar (36 px) above the main split — Mail / Notes / Messages-style chrome
- macOS traffic lights, sidebar toggle, and the active page title all centered on the same horizontal axis (via
trafficLightPosition) - Sidebar toggle position adapts: just inside the sidebar divider when expanded, next to the traffic lights when collapsed
- New right-side cluster: theme dropdown (☀ / 🌙 / 🖥 with a popover picker) + Settings gear + pink Donate heart, grouped as one rounded pill
- Right edge aligns with the panel content's right padding — nothing hangs over
Collapsible sidebar with persistent type-ahead search
- New search input at the top of the sidebar — debounced 300 ms against
brew_search; top 7 hits with kind pill + installed badge; ArrowUp/Down + Enter + Esc keyboard support - "See all results in Discover →" affordance at the bottom of the dropdown
- Dashboard is now the first nav item (the menu bar already identifies the app — no more redundant "brew-browser" brand)
- Sidebar collapses to a 56 px icon rail; nav items show a badge overlay, search hides, theme/Settings/Donate live in the title bar now
- Collapsed state persists across launches (localStorage)
Info popovers replace AI labels & "Wrong?" links
- New
(i)info button on every enriched field — Categories, Tags, Summary, "Why install this?", "Similar packages" - Hover-activated (mouse) + focus-activated (keyboard); auto-closes on scroll / Esc / outside-click
- Each popover discloses the AI provenance ("Generated offline at build time by Claude Haiku 4.5 — no network or LLM calls happen while you use brew-browser") and offers a "Report an issue on GitHub" action
- Removed the "AI-enriched" pill badges entirely — provenance is one tap away on every field, not bolted onto every label
Intent-based GitHub sign-in
- No more static "Sign in via Settings → GitHub to star, watch, or file issues." prompts on every package
- Star / Watch / File issue buttons render whenever the GitHub stats card is visible
- Clicking while signed-out deep-links to Settings → GitHub and toasts a hint (intent-based discovery)
- Settings now supports
ui.openSettings("github")-style deep-links so any caller can drop the user directly on a specific section - GitHub OAuth client_id is live — sign-in works out of the box (no
BUILD.mdsetup required)
Smaller fixes
- License-mismatch row wraps as prose instead of fragmenting into a column grid
- Every empty state in the app is vertically centered in its pane (not stuck at the top)
- Snapshots' inline "New Snapshot" / "Import Brewfile…" buttons removed from the empty state — the same actions live in the panel-head's top-right
- Selected row stays highlighted across Library / Trending / Discover / Services / Dashboard outdated while the detail panel is open
- Chip-filter clears when crossing panes (Productivity-in-Discover no longer silently filters Library to zero)
- App icon redesigned as a native macOS Tahoe square — no more white-corner artifacts from the OS auto-mask
Open-source posture (unchanged)
MIT licensed. No telemetry. No accounts. No CLA. No EULA.
Seven documented outbound network paths, all gated by Settings → Network → Paranoid Mode. Token (when you sign in) lives only in macOS Keychain, never returned to the frontend, never written to disk.
Built with Agency Agents, by the creator of Agency Agents. Powered by Anthropic's Claude Opus 4.7 and the Claude Agent SDK.
If brew-browser saves you time, sponsor on GitHub ♥.
Install
Download the signed + notarized .dmg below, open, drag to Applications. No Gatekeeper warning.
macOS 13 (Ventura) or newer · Apple Silicon.
Full changelog
- Commit range:
v0.1.0...v0.2.0 - Memory bank breakdown:
memory-bank/progress.md
v0.1.0 — initial release
brew-browser v0.1.0 — initial release
Native macOS GUI for Homebrew. Browse, search, install/uninstall/upgrade with live streaming output, snapshot to Brewfile and restore, browse trending packages from Homebrew's published analytics.
What's in this release
- 5 sidebar sections: Library / Discover / Trending / Snapshots / Activity
- Cmd+K command palette, Cmd+1…5 navigation, drag-resizable detail pane
- Cask icons from installed
.appbundles or homepage cascade - Brewfile snapshot/restore via
brew bundle - Trending tab via
formulae.brew.sh30/90/365-day analytics - 15,974 packages pre-categorized via
tools/categorize/
Posture
- MIT licensed, full source
- 0 critical / 0 high / 0 medium / 0 low security findings
(cargo audit,npm audit,osv-scanner,cargo deny,semgrep,gitleaks,cargo clippy -D warnings— all clean) - Zero
unsafeRust, notauri-plugin-shell - Four documented outbound network paths (see README "Open by default")
Install
Download brew-browser_0.1.0_aarch64.dmg below, open, drag to Applications. Signed and notarized — no Gatekeeper warning.
Apple Silicon only for now. macOS 13+.
Build from source
See README.md + BUILD.md in the repo.