Skip to content

Add separate menu bar items per provider account - #3251

Open
Thinkscape wants to merge 3 commits into
steipete:mainfrom
Thinkscape:feature/split-account-menu-items
Open

Add separate menu bar items per provider account#3251
Thinkscape wants to merge 3 commits into
steipete:mainfrom
Thinkscape:feature/split-account-menu-items

Conversation

@Thinkscape

@Thinkscape Thinkscape commented Aug 28, 2026

Copy link
Copy Markdown

Summary

  • add a per-provider Menu bar items setting for providers with multiple accounts
  • keep the default combined provider item, or create one stable, account-scoped status item per account
  • refresh every account immediately when split mode is enabled and keep account menus isolated from sibling identities/data
  • disable split mode when merged provider icons are enabled

Menu bar items

Screenshot 2026-08-29 at 8 50 28 am
One for provider One per account
Account menu behavior
Combined menu Account-scoped menu

Account identifiers are redacted.

Verification

  • swift test --filter 'AccountMenuBarDisplayModeTests|StatusItemControllerSplitLifecycleTests|StatusMenuTokenAccountSwitcherTests|StatusMenuCodexSwitcherTests|StatusMenuCodexSeparateAccountTests|StatusItemIconObservationSignatureTests|ProvidersPaneCoverageTests|CodexAccountsSettingsSectionTests'
  • make format && make check
  • packaged with ad hoc signing and verified in the fresh app bundle with two Codex accounts: combined mode showed one item with the switcher; split mode showed two independently populated items without switchers, without manual refresh
  • full suite left to CI

@clawsweeper

clawsweeper Bot commented Aug 28, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

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

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

ℹ️ 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".

Comment on lines +43 to +46
let title = "\(Self.statusItemAccessibilityTitle) — " +
"\(self.store.metadata(for: key.provider).displayName) — \(context.displayName)"
existing.button?.setAccessibilityTitle(title)
existing.button?.toolTip = title

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Redact split-item labels when privacy mode is enabled

When “Hide personal information” is enabled and Codex uses separate account items, context.displayName still contains the account email and is assigned verbatim to the status item's tooltip and accessibility title. This makes the email visible on hover and through accessibility APIs even though the setting promises to obscure email addresses in the menu bar; redact or omit the account display name in both the creation and existing-item paths.

Useful? React with 👍 / 👎.

Comment on lines +498 to +500
let displayText = input.accountScoped && input.snapshot == nil
? nil
: self.menuBarDisplayText(for: input.provider, snapshot: input.snapshot)

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 brand-percent text account-scoped

When Codex is split into separate items and “Show brand icon with percentage” is enabled, this calls the provider-level menuBarDisplayText, whose .menuBar projection can attach the currently active account's live credits and historical pace data. An exhausted sibling can therefore display the active account's credit balance, and pace mode can evaluate the sibling window against the active account's history; use an account-scoped display-text path that suppresses provider-level adjuncts.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. 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: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: needs maintainer proof decision A ClawSweeper-authored PR needs a maintainer proof capture or override decision. labels Aug 28, 2026
@clawsweeper

clawsweeper Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codex review: needs changes before merge. Reviewed August 28, 2026, 6:56 PM ET / 22:56 UTC.

ClawSweeper review

What this changes

The branch adds an opt-in per-provider setting to show one macOS menu-bar item per account instead of one combined provider item.

Regression provenance

Possible regression — suspected (reviewed change). No predecessor PR is attributed.

Merge readiness

⚠️ Needs maintainer review before merge - 3 items remain

Keep open: the visual proof is sufficient and earlier privacy/data-isolation findings are addressed, but separate account items bypass saved custom menu-bar layouts, creating a P1 compatibility regression.

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

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The feature has strong visual proof and focused coverage, but one established display-preference path still regresses in split mode.
Proof confidence 🦞 diamond lobster (5/6) ✨ media proof bonus Sufficient (screenshot): The changed production owner is the StatusItemController's separate-account lifecycle and menu population. Four supplied redacted after-fix screenshots show one combined item with its switcher, then two independently populated account items and an account-scoped menu without that switcher; they do not exercise the remaining custom-layout defect.
Patch quality 🦐 gold shrimp (3/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Verified Sufficient (screenshot): The changed production owner is the StatusItemController's separate-account lifecycle and menu population. Four supplied redacted after-fix screenshots show one combined item with its switcher, then two independently populated account items and an account-scoped menu without that switcher; they do not exercise the remaining custom-layout defect.
Evidence reviewed 5 items Introduced account render path: The PR adds a separate-account icon path which reads the account snapshot and immediately invokes the legacy generic renderer, bypassing saved layout handling.
Existing saved-layout contract: The established renderer resolves saved global or provider-specific layouts and applies their rendered content to the status item whenever icon-and-percent mode is active.
Settings and tests establish persisted layouts: Settings resolve per-provider overrides before a global stored layout, and existing tests persist both kinds of layout; the split-item tests contain no corresponding layout case.
Findings 1 actionable finding [P1] Render saved layouts for separate account items
Security None None.

How this fits together

CodexBar polls provider account usage and renders it in macOS menu-bar status items. The new preference changes the status-item controller from a combined provider item to account-scoped items, icons, and menus.

flowchart LR
A[Provider accounts] --> B[Saved menu-bar preference]
B --> C[Status item controller]
D[Account usage snapshots] --> C
C --> E[Combined provider item]
C --> F[Separate account items]
F --> G[Account-scoped menus]
Loading

Decision needed

Question Recommendation
Should CodexBar adopt an opt-in persistent mode that adds one menu-bar item per provider account after its existing layout contract is preserved? Sponsor the opt-in mode: Keep the feature direction, repair saved-layout compatibility, and review the resulting focused implementation.

Why: This PR adds a user-facing configuration mode and status-item behavior beyond a narrow bug fix; maintainers must decide whether that permanent product surface belongs in CodexBar.

Before merge

  • Render saved layouts for separate account items (P1) - The ordinary provider path calls applyStoredMenuBarLayoutIfNeeded when icon-and-percent mode is active, but this introduced account path goes directly to renderProviderIcon. A saved global or provider layout is therefore discarded when the user selects “One per account”. Route this path through the saved-layout renderer with the account snapshot and add regression coverage.
  • Resolve merge risk (P1) - Until repaired, users with a saved global or provider-specific menu-bar layout lose that preference for every account item when enabling split mode.

Findings

  • [P1] Render saved layouts for separate account items — Sources/CodexBar/StatusItemController+Animation.swift:531-567
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch surface 36 files, +1,749 / −642 lines The feature spans preferences, account lifecycle, rendering, tests, documentation, and four screenshots.
Production versus tests production +1,306 / −640; tests +436 / −1 The substantial production refactor has a clear feature purpose, but lacks split-mode saved-layout coverage.

Merge-risk options

Maintainer options:

  1. Preserve custom layouts in split mode (recommended)
    Use the established saved-layout renderer for each account-scoped item and test that a saved provider layout remains visible after enabling split mode.
  2. Accept the legacy-only limitation
    Merge while documenting that split account items use legacy rendering even when a custom layout is saved.
  3. Pause the feature
    Hold this PR if the layout contract cannot be preserved without weakening account-data isolation.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Preserve saved custom menu-bar layouts for separate account items and add focused regression coverage; keep account data scoped to each item.

Technical review

Best possible solution:

Reuse the saved-layout renderer for account-scoped items with each item’s own snapshot, preserve account-data isolation, and add regression coverage for a stored provider layout.

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

Yes. Set icon-and-percent mode and save a global or provider-specific layout, then enable separate items for a provider with two accounts; the new account path skips the saved-layout renderer.

Is this the best way to solve the issue?

No. The account path should use the existing layout renderer with account-scoped inputs rather than silently falling back to the legacy renderer.

Full review comments:

  • [P1] Render saved layouts for separate account items — Sources/CodexBar/StatusItemController+Animation.swift:531-567
    The ordinary provider path calls applyStoredMenuBarLayoutIfNeeded when icon-and-percent mode is active, but this introduced account path goes directly to renderProviderIcon. A saved global or provider layout is therefore discarded when the user selects “One per account”. Route this path through the saved-layout renderer with the account snapshot and add regression coverage.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.99

AGENTS.md: found and applied where relevant.

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

Labels

Label changes:

  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The changed production owner is the StatusItemController's separate-account lifecycle and menu population. Four supplied redacted after-fix screenshots show one combined item with its switcher, then two independently populated account items and an account-scoped menu without that switcher; they do not exercise the remaining custom-layout defect.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🦐 gold shrimp, so this older rating label is no longer current.
  • remove status: needs maintainer proof decision: Current PR status label is status: ⏳ waiting on author.

Label justifications:

  • P2: This is an opt-in user-facing feature with a concrete compatibility defect that needs normal-priority review.
  • merge-risk: 🚨 compatibility: The new split mode bypasses existing saved layout preferences for affected providers.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The changed production owner is the StatusItemController's separate-account lifecycle and menu population. Four supplied redacted after-fix screenshots show one combined item with its switcher, then two independently populated account items and an account-scoped menu without that switcher; they do not exercise the remaining custom-layout defect.
  • proof: sufficient: Contributor real behavior proof is sufficient. The changed production owner is the StatusItemController's separate-account lifecycle and menu population. Four supplied redacted after-fix screenshots show one combined item with its switcher, then two independently populated account items and an account-scoped menu without that switcher; they do not exercise the remaining custom-layout defect.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The changed production owner is the StatusItemController's separate-account lifecycle and menu population. Four supplied redacted after-fix screenshots show one combined item with its switcher, then two independently populated account items and an account-scoped menu without that switcher; they do not exercise the remaining custom-layout defect.

Evidence

Acceptance criteria:

  • [P1] swift test --filter 'StatusItemControllerSplitLifecycleTests|MenuBarLayoutTests'.
  • [P1] make check.

What I checked:

Likely related people:

  • William Mitchell: Introduced and extended the stored menu-bar layout surface that separate account items must preserve. (role: recent menu-bar layout contributor; confidence: high; commits: bc3c4b304e39, 4615951172fe; files: Sources/CodexBar/StatusItemController+MenuBarLayout.swift)
  • Peter Steinberger: Has several recent commits maintaining status-item menu lifecycle and related menu-bar rendering. (role: recent controller lifecycle contributor; confidence: high; commits: 7dcfd4143841, 07ed3facdd4e, d5a5796a9844; files: Sources/CodexBar/StatusItemController.swift, Sources/CodexBar/StatusItemController+MenuBarLayout.swift)

Rank-up moves

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

  • Preserve stored custom layouts for every account item and add a focused regression test using a saved provider layout.

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-28T02:51:10.041Z sha e1338e0 :: needs real behavior proof before merge. :: [P1] Redact split-item accessibility labels | [P2] Keep split-item brand text account-scoped
  • reviewed 2026-08-28T05:13:46.171Z sha 500f5db :: needs real behavior proof before merge. :: [P1] Preserve split-account preferences when enabling merged icons
  • reviewed 2026-08-28T05:42:20.949Z sha eaf24d0 :: needs real behavior proof before merge. :: [P1] Render saved layouts for separate account items

@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Aug 28, 2026
@clawsweeper clawsweeper Bot added 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 maintainer proof decision A ClawSweeper-authored PR needs a maintainer proof capture or override decision. labels Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant