Skip to content

Add notch hover usage overlay - #3164

Open
wdmitchelluk wants to merge 5 commits into
steipete:mainfrom
wdmitchelluk:notch-usage-overlay
Open

Add notch hover usage overlay#3164
wdmitchelluk wants to merge 5 commits into
steipete:mainfrom
wdmitchelluk:notch-usage-overlay

Conversation

@wdmitchelluk

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in notch hover usage overlay with its own Settings → Notch page. Off by default.

  • Hovering the camera notch on a built-in notched display (or pressing an optional shortcut, Toggle or Hold mode) expands a panel centered under the notch with one tile per enabled provider — first-party and user plugins — showing up to four bars each: session, weekly, tertiary, and one extra named window falling back to spend / Codex monthly credits.
  • Tiles flow into 1–4 columns (left to right, then down), optionally with matched row heights (SwiftUI Grid), and are drag-to-reorder in settings. Providers are opt-out: newly enabled providers appear without revisiting the pane.
  • Running agent sessions are their own section: a full-width band above or below the grid, its rows spread over the same column count.
  • The provider grid and the session band each have an independent maximum height; whichever overflows scrolls internally without pushing the other out of view.
  • The panel measures its own width and height, and re-measures live as usage snapshots land while it is open.

Design notes

  • No global event monitor, no Accessibility permission. One borderless, non-activating NSPanel at .statusBar level with two frames; hover detection is an NSTrackingArea on its own content view. The collapsed hit area is exactly the camera housing, so menu extras that sit flush against it stay clickable.
  • Sizing is self-reported, not predicted. Each section publishes the height its content wants from inside its own scroll view (NotchGridHeightKey / NotchBandHeightKey); the controller sums the two reports, each clamped by its ceiling. Measuring a detached copy drifted from what SwiftUI actually laid out — that approach is gone. The frame re-applies under withObservationTracking, so late-arriving snapshots resize the open panel.
  • items is typed to provider rows and the session band is a separate SessionsBand value, so “the band never joins the grid” is guaranteed by construction rather than by convention.
  • Details in docs/notch-usage-summary.md.

Screenshots

Expanded overlay — 3 columns, matched row heights, agent-session band pinned below (real data, debug build on a notched MacBook):

Expanded overlay

Settings → Notch — overlay, shortcut, agent-session, and provider sections:

Settings pane

Behaviour verified live on a notched display: the panel is content-sized (356×741 at 1 column → 875×283 at 3 columns), the provider cap alone changes the panel (337 → 488 for 200 → 600), a capped grid scrolls while the band stays pinned, and both above/below placements render full width across the configured columns.

Commands run

make check          # SwiftFormat + SwiftLint clean, 22 locale catalogs × 1515 keys OK
make test           # full sharded suite
swift test --filter 'Notch'   # 26 tests, 4 suites, all passing
./Scripts/compile_and_run.sh  # bundle-level launch verification

Notes for review

  • New settings keys: notchUsageSummaryEnabled, notchColumnCount, notchMatchesRowHeights, notchProvidersMaxHeight, notchSessionsMaxHeight, notchItemOrder, notchHiddenProviders, notchShowsAgentSessions, notchSessionsPlacement, notchHotkeyMode, plus the showNotchOverlay shortcut name.
  • Localization: all 23 catalogs populated for every new key.
  • Keychain-safe: no live probes in tests; settings tests use testSettingsStore fixtures and Noop* token stores.
  • Row reordering uses .onDrag/.onDrop with a plain-text payload (a custom Transferable UTI can’t round-trip without an Info.plist declaration, which SwiftPM debug builds don’t have). The reorder logic itself is unit-tested; a manual drag check on the packaged app is welcome.

@clawsweeper

clawsweeper Bot commented Aug 24, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Aug 24, 2026
@clawsweeper

clawsweeper Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed August 24, 2026, 4:22 AM ET / 08:22 UTC.

ClawSweeper review

What this changes

Adds an opt-in macOS notch-hover dashboard for provider usage and agent sessions, with persisted layout, visibility, sizing, shortcut, localization, documentation, and regression-test support.

Merge readiness

⚠️ Ready for maintainer review - 2 items remain

Keep open for maintainer product-direction review: this is a substantial new opt-in native surface, not a fix already present on main. The previously raised shortcut, lifecycle, accessibility, and credit-fallback concerns are addressed on the current head; no new blocking code defect was found.

Priority: P2
Reviewed head: 8fb9030afb439aff9399cca3d461e8ab18cba46a
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) Strong direct UI proof and focused coverage support a good patch rating; the remaining gate is product ownership, not a demonstrated defect.
Proof confidence 🦞 diamond lobster (5/6) ✨ media proof bonus Sufficient (screenshot): Two prepared, after-fix screenshots directly show the expanded overlay and its settings pane; the contributor also reports live verification on a notched MacBook.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (screenshot): Two prepared, after-fix screenshots directly show the expanded overlay and its settings pane; the contributor also reports live verification on a notched MacBook.
Evidence reviewed 5 items Current-head lifecycle implementation: The overlay controller starts only once, observes display changes, removes its shortcut handlers on stop, and creates the panel only when enabled on a notched screen.
Provider and session data remain separated: The overlay builds provider rows from enabled provider instances and keeps agent sessions in a distinct band; Codex credit fallback is explicitly constrained to the Codex provider.
Focused regression coverage: The settings tests cover default-off persistence, handler installation/removal across restarts, ordering, sizing, sessions, and credit fallback.
Findings None None.
Security None None.

Live Verification

Command: ./Scripts/compile_and_run.sh

Result: FAIL (failed) — execution before step 1 run: sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.23.0.tgz

sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.23.0.tgz

Assertions:

  • FAIL expect_output: OK: CodexBar is running.

How this fits together

CodexBar collects provider usage snapshots and optional agent-session state, then presents them in native macOS surfaces. This PR adds a non-activating panel anchored to a built-in display’s camera notch and driven by the same data sources and settings store.

flowchart LR
A[Provider usage snapshots] --> C[Overlay model]
B[Agent session state] --> C
D[Notch settings and shortcut] --> E[Overlay controller]
F[Built-in display notch] --> E
C --> E
E --> G[Non-activating hover panel]
G --> H[Usage tiles and session band]
Loading

Decision needed

Question Recommendation
Should CodexBar adopt this opt-in, configurable notch dashboard as a supported native feature? Sponsor the dashboard: Approve the notch-specific presentation surface and proceed with ordinary merge review.

Why: The branch introduces a new persistent macOS UI mode and settings surface rather than repairing an established contract.

Before merge

  • Resolve merge risk (P1) - Merging commits CodexBar to maintaining a sizeable notch-specific settings and localization surface; that scope choice is not settled by the implementation alone.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production vs test growth production +1,732, tests +751 The sizable new native surface has substantial focused model, geometry, shortcut, and settings coverage.
Localized settings 23 locale catalogs updated The new settings pane is translated across the app’s existing localization surface.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    If sponsored, retain the default-off design and land this as the supported notch presentation surface with its focused regression coverage and native-display proof.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

If sponsored, retain the default-off design and land this as the supported notch presentation surface with its focused regression coverage and native-display proof.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this PR proposes a new opt-in capability rather than reporting a broken existing behavior.

Is this the best way to solve the issue?

Unclear: the implementation is internally coherent and default-off, but only a maintainer can decide whether this notch-specific UI belongs in CodexBar’s supported product scope.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against fa50cf2dcdb6.

Labels

Label justifications:

  • P2: This is a substantial, opt-in product improvement with no evidence of an urgent user-facing regression.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): Two prepared, after-fix screenshots directly show the expanded overlay and its settings pane; the contributor also reports live verification on a notched MacBook.
  • proof: sufficient: Contributor real behavior proof is sufficient. Two prepared, after-fix screenshots directly show the expanded overlay and its settings pane; the contributor also reports live verification on a notched MacBook.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. Two prepared, after-fix screenshots directly show the expanded overlay and its settings pane; the contributor also reports live verification on a notched MacBook.

Evidence

What I checked:

Likely related people:

  • Peter Steinberger: Recent merged work maintained the shared agent-session refresh and menu behavior consumed by the new session band. (role: recent area contributor; confidence: high; commits: 6072edc2bfbc, 0954a74a0b9d; files: Sources/CodexBar/AgentSessionsStore.swift, Sources/CodexBar/StatusItemController+AgentSessions.swift)
  • Urda: Recent merged usage-presentation settings work is adjacent to the new persisted layout and display preferences. (role: adjacent settings contributor; confidence: medium; commits: b2264c0c6ef4; files: Sources/CodexBar/SettingsStore+Defaults.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Obtain a maintainer decision on adopting the new notch dashboard as a supported product surface.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (4 earlier review cycles)
  • reviewed 2026-08-24T01:21:10.530Z sha d2f342e :: found issues before merge. :: [P2] Restore the collapsed frame after a shortcut collapse
  • reviewed 2026-08-24T01:34:34.016Z sha f3b6fec :: found issues before merge. :: [P2] Include visible usage values in synthesized accessibility labels
  • reviewed 2026-08-24T01:55:13.286Z sha ab83688 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-24T02:42:12.133Z sha 4521c61 :: needs maintainer review before merge. :: none

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2f342ed97

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/NotchUsageOverlayController.swift
Comment thread Sources/CodexBar/NotchUsageOverlayView.swift Outdated
@wdmitchelluk

Copy link
Copy Markdown
Contributor Author

Both review findings are fixed in f3b6fec, and the branch is rebased onto current main (merge state is clean now):

  • Shortcut collapse frame — the collapse animation task now restores the collapsed frame whenever the panel is still collapsed, instead of gating on pointer position. A toggle-collapse under a hovering pointer can no longer leave the expanded frame behind as an invisible click target; re-expansion cancels the task, so it never fights a reopened panel.
  • Hotkey with no notched screenhandleHotkeyDown() returns before mutating hotkey or view state when no panel exists, so isExpanded can't be stranded while the lid is closed.
  • VoiceOver — provider tiles now announce name, status, and every bar via ProviderRow.accessibilitySummary (unit-tested).

make check clean, 27 notch tests pass. @clawsweeper please re-review.

@wdmitchelluk

Copy link
Copy Markdown
Contributor Author

Fixed in ab83688: all three bar factories (makeBar, makeCostBar, makeCreditBar) now derive the accessibility label from the visible pieces — title, percentText, and resetText when present — through one shared helper, so VoiceOver hears the same figures a sighted user sees. Tests go through bars() as requested: bar accessibility labels speak the visible values asserts the derived labels (including the reset text and the no-reset case), and the summary test now composes ProviderRow from factory-built bars instead of injecting pre-detailed labels.

make check clean, 28 notch tests pass. @clawsweeper please re-review.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 24, 2026

@steipete steipete left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice work overall — the self-reported sizing approach and the no-global-monitor/no-AX design are exactly right, and the focused suites plus make check all pass on a merge with latest main. Four findings before this can land, two of them blocking:

P1 — Disabled feature still registers a global shortcut. NotchUsageOverlayController.swift:54 installs the KeyboardShortcuts handlers unconditionally, and the dependency registers any saved shortcut system-wide the moment a handler is attached. Disabling the overlay never unregisters it, and PreferencesNotchPane.swift:38 allows recording a shortcut while the feature is off. That breaks the off-by-default guarantee and can steal shortcuts from other apps. Handlers should only exist while the overlay is enabled.

P1 — Any settings change destroys an expanded overlay. The activation observation (NotchUsageOverlayController.swift:123) reads a computed property backed by the whole observable defaults struct, so unrelated preference changes re-fire it; at line 143 an existing panel is preserved only when collapsed — an expanded panel is closed and recreated, losing hover/shortcut state. Please narrow the observation to the fields that actually affect activation, and preserve an expanded panel across benign changes.

P2 — Controller restarts accumulate shortcut handlers. Handlers registered at line 71 are never removed on stop; each stop/start adds another callback, and in Toggle mode two callbacks make one press open-and-immediately-close the panel. The dependency ships KeyboardShortcuts.removeHandler(for:) for exactly this lifecycle.

P2 — Codex credits aren't actually a fallback. NotchUsageOverlayModel.swift:191 appends monthly credits whenever fewer than four bars exist, even when the extra window/spend bar was already chosen — a Codex account with two ordinary windows shows both, contradicting the documented mutually-exclusive fallback. Gate the append on the fallback slot being unfilled.

Happy to merge once these are addressed — the feature itself is a great addition.

@wdmitchelluk

Copy link
Copy Markdown
Contributor Author

Addressed all four findings in 8fb9030 (rebased onto current main):

  1. Disabled feature / global shortcut — handler installation now follows isStarted && notchUsageSummaryEnabled; disabling removes and unregisters the handlers. The shortcut recorder now explicitly drives RecorderCocoa.isEnabled, so it cannot record while the feature is off.
  2. Broad activation observation / expanded-panel teardown — the controller observes a dedicated notchActivationRevision, incremented only when enablement actually changes, rather than the whole value-type defaults state. Same-screen activation checks now update collapsed or expanded panels in place; a pure lifecycle seam covers both states.
  3. Restart handler accumulationstop() calls KeyboardShortcuts.removeHandler(for:); installation removes any stale handler before registering and is guarded by hotkeyHandlersInstalled. A serialized regression test verifies disabled → enabled → stop → restart → stop registration state.
  4. Credits fallback — monthly Codex credits append only when neither a known extra window nor valid spend projection has occupied the mutually-exclusive other slot. Regression coverage exercises extra-window, spend, and true-credit-fallback cases through the full overlay model.

Verification on the rebased head:

  • 32 notch tests across 4 suites pass
  • ProviderArchitectureGatekeeperTests: 38 pass
  • make check: formatting clean, 22 locale catalogs OK, 0 lint violations

@clawsweeper please re-review the current head.

@wdmitchelluk
wdmitchelluk requested a review from steipete August 24, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants