Skip to content

feat: add macOS menu-bar experience - #24

Merged
karngyan merged 2 commits into
mainfrom
feat/macos-menu-bar
Jul 16, 2026
Merged

feat: add macOS menu-bar experience#24
karngyan merged 2 commits into
mainfrom
feat/macos-menu-bar

Conversation

@karngyan

Copy link
Copy Markdown
Contributor

Claim

Gives the read-only macOS app the menu-bar presence the blueprint always
envisioned for 0.1.0: an always-available MenuBarExtra alongside the existing
main window, showing a live read-only summary of the open database even when the
window is closed.

What changed (apps/macos/** + docs/guides/macos-app.md only)

  • Menu-bar extra (MenuBarView, .menuBarExtraStyle(.window)): connection
    state (file + schema compatibility), quick counts (sessions, events,
    candidates), candidate counts by lifecycle state, the N most recent candidates
    with state/detector, and Open Autophagy / Refresh / Quit actions.
    Read-only, refresh-on-open, no daemon.
  • View-model in the testable core. DatabaseReader.menuBarSnapshot(...)
    assembles a pure MenuBarSnapshot from cheap COUNT/GROUP BY queries
    (mutationStateCounts, recentMutations); the SwiftUI layer stays thin. The
    app runs as a regular Dock app and a menu-bar extra (both scenes).
  • Opt-in menu-bar-only mode. A Settings toggle (AppSettings, UserDefaults)
    runs the app as an accessory (no Dock icon) via NSApplication.setActivationPolicy
    at runtime — no LSUIElement baked into the bundle, so the default stays a
    normal Dock app.
  • New read-only data surfaced. Mutation detail now shows the v0.2
    provenance block (provider / model name / revision / optional digest) when
    present, and the installation target (Codex vs Claude Code repo skill).
  • Read-only WAL fix. A database the engine left in WAL mode but cleanly
    checkpointed (its -wal/-shm sidecars removed — the normal state after a CLI
    run) could not be read: a read-only connection cannot build the shared-memory
    index WAL needs, so every query silently failed and the app showed the file as
    empty / "not an Autophagy database". Database now opens such files with
    SQLite immutable=1 (reading the fully checkpointed main file as a
    point-in-time snapshot) and opens normally when a live -wal sidecar is
    present. knownSchemaVersion was already 8 — nothing schema-related bumped.

Evidence

  • swift build clean (no warnings), swift test35 tests pass, including
    new coverage for provenance decode, install-target display, state counts, the
    menu-bar snapshot assembly (connected + disconnected), AppSettings, and a
    regression test for the checkpointed-WAL-without-sidecars case.
  • mise run check passes at repo root (fmt + lint + test + docs + ci; exit 0).
  • Smoke: built a demo DB via the CLI into /tmp (import fixtures →
    mutations propose, 3 candidates), then asserted the view-model state
    headlessly through AutophagyKit against that real, cleanly-closed DB — 14
    sessions, 22 events, 3 candidates, schema v8 supported.
  • make-app-bundle.sh still produces a working bundle with no LSUIElement
    (verified default remains a normal Dock app).

Privacy

Still strictly read-only. The menu bar reads the same local database through the
same read-only + query_only connection; it adds no write path and no export.
Provenance surfaces model identity only (never endpoints, keys, prompts, or
payloads). Nothing new leaves the machine.

Decision record

The menu-bar addition stays inside the read-only charter that ADR 0005 already
anticipated ("moving to ... a menu-bar presentation later is an additive
packaging change; it does not alter the read-only or CLI-mediation boundaries"),
so no new ADR is warranted.

🤖 Generated with Claude Code

karngyan and others added 2 commits July 17, 2026 02:58
Add an always-available menu-bar extra to the read-only macOS app: connection
state, quick counts, candidate counts by lifecycle state, the most recent
candidates, and Open/Refresh/Quit actions. Add an opt-in "menu-bar-only"
Dock-icon preference (runtime activation policy, no LSUIElement). Surface the
v0.2 model-synthesis provenance block and the install target in mutation
detail. Fix a read-only open bug for cleanly-checkpointed WAL databases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015LY7xtercMc3NtLeX2z4YV
- Re-open the read-only connection on reload()/refresh so an immutable
  point-in-time snapshot advances; a cleanly checkpointed DB is the common
  path, so Refresh now surfaces rows written after the reader was created.
- openReadable retries a failed immutable open once with a plain read-only
  open (canRead probe) before degrading to empty, guarding the
  concurrent-writer / changed-file case.
- recentMutations/mutations share a bounded LIMIT query using json_extract
  for the title instead of decoding every candidate package on the main actor.
- reload() computes overview() once and passes it into menuBarSnapshot.
- Restrict URI path encoding to ASCII unreserved characters.
- Update stale v6 fixture comment to v8; add a refresh-sees-new-rows test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015LY7xtercMc3NtLeX2z4YV
@karngyan
karngyan merged commit 6d06b01 into main Jul 16, 2026
2 checks passed
@karngyan
karngyan deleted the feat/macos-menu-bar branch July 16, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant