Changelog
May 9, 2026 · View on GitHub
User-facing changes per release. Format follows Keep a Changelog; dates are when the tag was cut.
[0.1.4] - 2026-05-09
A polish + hardening release. One user-visible fix in Settings; the rest is interior work — perf, refactor, and three release-pipeline guardrails that exist so a botched future release doesn't silently brick auto-update.
Fixed
- Settings → Providers now shows auth errors instead of
0%. When Claude or Codex can't be reached (auth missing, expired, rate-limited), the row used to rendersynced 2m ago · 0% / 0%— the most authoritative diagnostic surface in the app silently masked the real reason. It now shows⚠ auth required — run claude(or whichever error fired) in place of the0%, per window.
Internal
IslandRootViewdecomposed. The root view used to observe seven stores; any@Publishedemission re-evaluated the whole tree, including every overlay and gesture closure. Split intoGlowLayer,LogoOverlay, andPeekPillOverlaychildren, each subscribed to only what they read. Up to 8 redundant body re-evals per poll cycle eliminated.AppEnvironmentcentralizes mode flags.CODEXISLAND_DEMO/CODEXISLAND_DEBUGwere checked across eight files via rawProcessInfo.processInfo.environment["..."]lookups. Resolved once at launch into a typed enum (AppEnvironment.isDemo,.isDebug); a typo in any one literal can no longer silently miss the mode.- Generic
LogParseCache<Event>shared by both log readers.ClaudeLogReaderandCodexLogReaderpreviously duplicated ~70-80% of their cache + file-walk scaffolding. Extracted to one generic. Net −218 LOC across the two reader files. As a behavioral side effect, the Codex reader now uses the same 64 KB chunked streaming reader as Claude, closing a peak-RSS spike during 30-day rollout scans. Cache JSON shape is byte-identical, so existing caches survive the upgrade.
Release pipeline
These all guard against silent bricks of Sparkle auto-update or the Homebrew cask. None affect the running app — but if any one of them ever fires, you'll get a loud failure at release time instead of a silently broken update channel weeks later.
build.shandrelease.shreject non-semverVERSION. AVERSIONof1or1.0parses as[1]under Apple's component-wise comparator, which is larger than0.0.99— Sparkle would never offer any update to the affected installs. Tagging now fails loud aterror: VERSION must be X.Y.Z.release.shaborts on empty EdDSA signature.set -euo pipefaildoesn't catch a zero-exit with malformedsign_updateoutput. An appcast withsparkle:edSignature=""is rejected silently by every Sparkle client. The release now fails before the appcast is written.- CI uses an explicit DMG path for SHA-256. A glob that matched no
files would silently produce an empty SHA, which then
sed'd into the Homebrew cask without changing it —brew installmismatched on every user. The path is now derived from the tag and existence-checked. build.shpropagates Sparkle XPC codesign failures. Previously swallowed via2>/dev/null || true, surfacing only at the user's first Check Now click as "The updater failed to start." The path-existence guard kept the original "tolerate missing helpers" behavior; real signing errors now fail the build.
[0.1.0] - 2026-05-05
Three changes on top of the 0.0.10 baseline. The minor-version bump signals that the 0.0.x bootstrap series is over — not that this single release is big. Per-tag detail for the 0.0.x series lives on the GitHub Releases page.
Added
- Token counting toggle. Settings → Providers → Tokens picks between All tokens (input + output + cache_creation + cache_read — ccusage parity, the prior default and the only mode in 0.0.x) and Input + output (matches Anthropic's claude.ai stats panel, which excludes cache reads). Both totals are computed every scan and cached, so flipping the segment is instant — no rescan.
CHANGELOG.md. Going forward, each release ships with a curated user-facing changelog in this file.
Changed
- Continuous (squircle) corners on the island silhouette. Replaces the
hand-rolled circular-arc + straight-line path with
UnevenRoundedRectangle(style: .continuous), eliminating the small kink at the tangent point that was visible against the hardware notch. - Peek pill always shows window context. When a provider didn't return
an active
resetAt, the pill used to drop the separator and render bare percentage — making the layout shift between hovers. It now always renders<percent> · <label>. With an active countdown the label is the live time remaining at full opacity; otherwise it falls back to the window length (5h) at reduced opacity, so countdown vs. passive label stays visually distinct without changing geometry.
Internal
MacIsland.costCache.v2→v3. First launch on 0.1.0 backfills the billable-tokens column with one fresh local-log scan; existing dollar + total-tokens rollups remain valid.