Skip to content

Restore OpenRouter balance in menu bar layouts - #2870

Merged
steipete merged 5 commits into
steipete:mainfrom
yuansaysay:fix/openrouter-layout-balance
Aug 12, 2026
Merged

Restore OpenRouter balance in menu bar layouts#2870
steipete merged 5 commits into
steipete:mainfrom
yuansaysay:fix/openrouter-layout-balance

Conversation

@yuansaysay

@yuansaysay yuansaysay commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a provider-aware Balance token to the menu-bar layout editor
  • source the value only from the active OpenRouter snapshot
  • preserve the legacy OpenRouter Automatic balance when settings migrate to a stored layout
  • include balance changes in the icon observation signature so stored layouts refresh immediately
  • cover rendering, provider isolation, legacy migration, persistence, and refresh behavior

Fixes #2866

Root cause and implementation

The legacy OpenRouter menu-bar path rendered the Remaining detail row for Automatic mode, but the composable layout system had no equivalent token. Saving or migrating a layout therefore lost an established provider-specific value.

This patch adds a Balance token at the shared layout boundary while keeping its value provider-scoped: only OpenRouter resolves the Remaining row. Legacy OpenRouter Automatic settings migrate to Icon plus Balance, the editor exposes a synthetic preview only for OpenRouter, and the status-item observation signature includes the balance only when a stored layout actually uses that token.

Real behavior proof

A fresh Developer ID-signed build from head f2f0a5a3fae8a45f04f371af6de12c6eaaf97a35 was exercised through the production stored-layout renderer and a real NSStatusBarButton.

  • Private live proof used an actual OpenRouter API-backed snapshot and confirmed the real balance rendered in the status item. The credential and value were not captured or uploaded.
  • The public artifact below uses a synthetic $12.34 snapshot through the same production status-button path, so it is safe to share while proving the actual AppKit surface rather than only the SwiftUI editor preview.

OpenRouter balance in the real status item

Validation

  • make check
  • focused layout, renderer, editor, and status-item signature tests: 65 tests across 4 suites
  • provider architecture gatekeeper: 38 tests
  • isolated cold-cache-sensitive project usage suite: 33 tests
  • full make test: 840 selections across 70 groups, all passed with no retries or timeouts
  • branch secret scan: clean
  • independent branch review: no accepted or actionable finding
  • Developer ID release package built successfully
  • packaged app launch smoke passed with the checkout made unreadable
  • codesign --verify --deep --strict --verbose=4 CodexBar.app
  • spctl --assess --type execute --verbose=4 CodexBar.app

The final bundle is signed by Developer ID Application: Peter Steinberger (Y5PE65HELJ), accepted by Gatekeeper, and was rebuilt after all temporary proof hooks had been removed.

@clawsweeper

clawsweeper Bot commented Aug 11, 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. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 11, 2026
@clawsweeper

clawsweeper Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed August 12, 2026, 1:21 AM ET / 05:21 UTC.

ClawSweeper review

What this changes

The PR adds an OpenRouter-only Balance token to stored menu-bar layouts, preserves the legacy Automatic balance during migration, and refreshes the status item when that value changes.

Regression provenance

Possible regression — probable (reviewed change; known regression link). No predecessor PR is attributed.

Merge readiness

⚠️ Ready for maintainer review - 1 item remains

This active PR is a focused, proof-positive repair for the linked OpenRouter layout regression. The prior migration finding is resolved and no new correctness or security issue was found on the current head.

Priority: P2
Reviewed head: f2f0a5a3fae8a45f04f371af6de12c6eaaf97a35

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused repair with strong visible runtime proof, targeted regression coverage, and no actionable review finding.
Proof confidence 🦞 diamond lobster (5/6) ✨ media proof bonus Sufficient (screenshot): The PR body includes an after-fix screenshot of the production stored-layout renderer in a real status item, plus a described live OpenRouter-backed verification.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (screenshot): The PR body includes an after-fix screenshot of the production stored-layout renderer in a real status item, plus a described live OpenRouter-backed verification.
Evidence reviewed 6 items Existing behavior contract: Current main’s legacy status-item path renders OpenRouter’s Remaining detail value whenever its metric preference is Automatic, establishing the behavior this PR restores for stored layouts.
Current-main gap: Current main’s token enum and migration logic contain no balance token, so a stored layout cannot represent the legacy OpenRouter Automatic output.
Branch implementation: The proposed head introduces a provider-gated resolver, maps legacy OpenRouter Automatic layouts to Icon plus Balance, supplies renderer data, and includes the value in the stored-layout refresh signature.
Findings None None.
Security None None.

How this fits together

CodexBar converts provider usage snapshots and saved menu-bar layout tokens into the macOS status-item title. The editor persists layouts, while the renderer and observation signature determine what text is shown and when it refreshes.

flowchart LR
  A[OpenRouter usage snapshot] --> B[Balance resolver]
  C[Legacy or stored layout] --> D[Layout migration and editor]
  D --> E[Menu-bar renderer]
  B --> E
  E --> F[Status item title]
  B --> G[Refresh signature]
  G --> F
Loading

Before merge

  • Complete next step (P2) - This active linked PR already owns the bounded repair and needs ordinary maintainer merge review rather than a separate fix lane.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch scope production +46/-1, tests +119/-11, docs +3/-2 across 11 files The implementation is bounded and test growth exceeds production growth for the migration and refresh paths.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #2866
Summary: This PR is the active candidate fix for the reported loss of OpenRouter balance in stored menu-bar layouts.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Technical review

Best possible solution:

Merge this focused repair after the normal required checks complete, then let the linked regression close through the PR’s existing closing reference.

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

Yes—current source proves the legacy OpenRouter Automatic path renders Remaining, while the stored-layout token model lacks an equivalent; the linked report supplies the user-facing setup path.

Is this the best way to solve the issue?

Yes—the provider-gated token reuses the existing Remaining value, preserves it during legacy migration, and refreshes only layouts that render it.

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P2: This repairs a bounded regression in the OpenRouter menu-bar configuration workflow.
  • 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): The PR body includes an after-fix screenshot of the production stored-layout renderer in a real status item, plus a described live OpenRouter-backed verification.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes an after-fix screenshot of the production stored-layout renderer in a real status item, plus a described live OpenRouter-backed verification.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body includes an after-fix screenshot of the production stored-layout renderer in a real status item, plus a described live OpenRouter-backed verification.

Evidence

What I checked:

Likely related people:

  • steipete: Introduced the menu-bar layout editor and has the strongest current-main history on the editor and observation paths. (role: layout editor author and recent area contributor; confidence: high; commits: 0f070a38fa7f, 15a855a2132a; files: Sources/CodexBar/MenuBarLayout.swift, Sources/CodexBar/MenuBarLayoutEditor.swift, Sources/CodexBar/StatusItemController+IconObservation.swift)
  • Giuseppe Bisemi: Authored the historical provider-balance feature whose OpenRouter Automatic behavior is preserved here. (role: introduced legacy balance behavior; confidence: high; commits: 34730cf1c60d; files: Sources/CodexBar/StatusItemController+Animation.swift)

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 (3 earlier review cycles)
  • reviewed 2026-08-11T15:43:01.262Z sha 34ae789 :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-11T17:05:17.706Z sha 34ae789 :: needs changes before merge. :: [P2] Preserve OpenRouter balance during layout migration
  • reviewed 2026-08-11T17:24:27.235Z sha 5b82592 :: 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: 34ae789d89

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

case resetCountdown
case resetAbsolute
case runsOut
case balance

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve OpenRouter balance during layout migration

For OpenRouter users who are still on the legacy automatic metric, the legacy renderer shows the $ balance via menuBarDisplayText, but MenuBarLayout.migrated(.percent, .automatic, provider: .openrouter) still builds .percent(.automatic). The editor uses that migrated layout when no stored layout exists, and changing size/gap or adding any token activates it, so a simple layout tweak replaces the always-visible balance with a usage percentage unless the user manually discovers and adds this new token. Consider mapping the OpenRouter automatic legacy layout to the balance token when introducing it.

Useful? React with 👍 / 👎.

@yuansaysay

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added 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. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 11, 2026
@yuansaysay

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@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 11, 2026
@steipete
steipete force-pushed the fix/openrouter-layout-balance branch from 5b82592 to f2f0a5a Compare August 12, 2026 05:17
@steipete

Copy link
Copy Markdown
Owner

@clawsweeper re-review

@steipete

Copy link
Copy Markdown
Owner

@codex review

@clawsweeper

clawsweeper Bot commented Aug 12, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@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: f2f0a5a3fa

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

let icon: MenuBarLayoutToken = .icon
// Provider-specific by design: OpenRouter Automatic historically renders remaining credit balance.
if provider == .openrouter, metricPreference == .automatic {
return MenuBarLayout(lines: [[icon, .balance]])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep Balance out of global layout seeds

When OpenRouter is the representative/first provider in the All layout editor and no stored layout exists, this migrated layout is what MenuBarLayoutEditorPersistence.setSize/setGap persists with provider: nil, so a harmless global size or gap change saves [.icon, .balance] as the global layout. Every non-OpenRouter provider that inherits that global layout then renders Balance unavailable/ because the balance resolver only returns a value for OpenRouter. Consider keeping this migration provider-scoped instead of letting it seed the All-provider layout.

Useful? React with 👍 / 👎.

@steipete
steipete merged commit bd79f10 into steipete:main Aug 12, 2026
9 checks passed
@steipete

Copy link
Copy Markdown
Owner

Landed and verified.

Proof:

  • make check passed.
  • Focused menu-bar layout, renderer, editor, and status-item signature coverage passed: 65 tests across 4 suites.
  • Provider architecture gatekeeper passed: 38 tests.
  • The cold-cache-sensitive local project usage suite passed in isolation: 33 tests.
  • Full make test passed: 840 selections across 70 groups, with no retries or timeouts.
  • A Developer ID-signed release bundle was rebuilt from clean source after removing the temporary proof hooks. The checkout-independent packaged launch smoke, deep strict signature verification, and Gatekeeper assessment all passed.
  • Private live validation used a real OpenRouter API-backed snapshot and confirmed the actual balance rendered through the production stored-layout path in a real NSStatusBarButton; neither the credential nor the live value was uploaded.
  • Public synthetic status-button proof is in the PR body: https://github.com/user-attachments/assets/ae3a6145-d893-4742-b8e4-81aaa5e8d90b
  • Exact-head CI passed on f2f0a5a3fae8a45f04f371af6de12c6eaaf97a35: https://github.com/steipete/CodexBar/actions/runs/31566071146
  • Exact-head Codex review returned no suggestions, and ClawSweeper reported no actionable correctness or security finding.

Merged as bd79f101a7e8cfd056e785fdae00a37af8a5a047. The separate maintainer changelog credit thanking @yuansaysay landed as 6e0a50001f98fe48ff9ff949bf85e391b801c0f1; final-main CI passed: https://github.com/steipete/CodexBar/actions/runs/31567543139

No release, tag, appcast, package, or artifact publication was performed.

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.

Regression: OpenRouter balance cannot be displayed with the Menu Bar Layout editor

2 participants