Skip to content

feat(menubar): finish opt-in provider colors - #4321

Merged
steipete merged 7 commits into
steipete:mainfrom
aronchick:fm/codexbar-provider-color
Oct 8, 2026
Merged

steipete merged 7 commits into
steipete:mainfrom
aronchick:fm/codexbar-provider-color

Conversation

@aronchick

@aronchick aronchick commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add a single Color by provider toggle to the existing menu bar settings. It defaults off and overlays the selected Critters, Meter bars, or Icon & percent style, including each provider's own stacked row. Saved layouts, the existing style picker, and Usage & Spend's Brand/Monochrome artwork remain unchanged.

Provider colors fall back to monochrome during menu tracking, stale data, system Increase Contrast, and the inactive-display contrast preference. Menu close restores color immediately. Accents must pass a 2:1 threshold against conservative reference backgrounds: 25% sRGB gray in dark appearance and 85% in light appearance. This does not sample wallpaper or claim WCAG text conformance. Pace colors keep their separate meaning, and VoiceOver labels do not depend on color.

The maintainer follow-up preserves @aronchick's commits, simplifies the duplicated tint logic, covers standard and vibrant AppKit appearances, adds rendered-pixel and lifecycle regressions, and localizes the one toggle label in every catalog. Thanks @aronchick!

Verification

All Swift runs use source Scripts/test_environment.sh and the native backend.

  • swift test --build-system native --jobs 4 -Xswiftc -gnone --no-parallel --filter 'MenuBarProviderColorTests|MenuBarLayoutRendererTests|MergedIconPresentationTests|MenuBarLayoutDisplayOptionsTests|MenuBarPaceColorSettingsTests|SettingsStoreMergeIconStackedTests|StatusMenuAppearanceTests|StatusItemAnimationSignatureTests|PreferencesDocumentTests|LocalizationLanguageCatalogTests|ProviderIconResourcesTests': 192 tests in 12 suites passed.
  • Regression runs against the original contribution reproduced contrast/accessibility/lifecycle failures; the final tests pass. A separate red test caught vibrantLight and actual accessibility appearance names before the classifier repair.
  • make check: 0 violations, 0 serious, 2,844 Swift files, with repository checks passing. An unchanged process-cleanup fixture timed out on the shared host during an earlier attempt; the retry passed.
  • Independent Codex autoreview: no actionable P0–P2 findings.
  • swift test --build-system native --jobs 4 -Xswiftc -gnone --no-parallel --filter ProviderArchitectureGatekeeperTests: 48 tests passed. The extracted Warp blink helper retains the same behavior; its exact gatekeeper anchor is updated.
  • CODEXBAR_TEST_SUITE_TIMEOUT=600 ./Scripts/test.sh --swift-command <native-wrapper> --direct-workers 4: full inventory of 1,592 selections / 144 groups, with 14,080 discovered methods verified against the direct runtime. The native wrapper forwards test and build to Swift with --build-system native --jobs 4 -Xswiftc -gnone.
  • The fail-fast run completed 95 groups. Kimi and Kiro transport retries passed, and a large cost-storage group passed all 12 isolated selections. A Kiro PTY cleanup deadline stopped scheduling later groups; swift test --skip-build --build-system native --jobs 4 -Xswiftc -gnone --no-parallel --filter KiroStatusProbeTests then passed 57 tests.
  • The remaining original groups 96–144 were run through Scripts/direct_swift_test_groups.py after revalidating the same complete runtime inventory: 49 groups / 546 selections passed, with 0 failures, 0 retries, 0 timeouts. All original selections are covered on the final head, with 0 unresolved failures. This is aggregate full-suite proof, not a claim that the initial fail-fast command exited successfully.

Synthetic rendered proof

Real renderer and AppKit drawing with fixture values, including pixel assertions in light/dark and fallback cases. This is offscreen proof, not a desktop capture or a live-account/app relaunch.

Provider colors off/on in light and dark appearances, with monochrome fallbacks

Refs #3533
Refs #3628
Refs #4294

@clawsweeper

clawsweeper Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

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

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Oct 7, 2026
@clawsweeper

clawsweeper Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed October 7, 2026, 10:42 PM ET / October 8, 2026, 02:42 UTC (Revision 4).

ClawSweeper review

What this changes

Adds a default-off Color by provider preference across existing menu-bar styles, with monochrome fallbacks for tracking, stale data, and accessibility states.

Example: Enable Color by provider for Claude

  • Before: The menu-bar layout displays “5h 25% W 60%” in monochrome.
  • After: The same layout uses Claude’s orange accent in supported light and dark appearances.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) Useful implementation with earlier defects resolved and regression completion recorded, but proof still stops at offscreen rendering.
Proof confidence 🦐 gold shrimp (3/6) Needs stronger real behavior proof before merge: The inspected screenshot exercises the production renderer and button-content application with fixture values in offscreen NSButtons, showing orange output and monochrome fallbacks. It does not exercise the running app’s settings-to-StatusItemController path or native menu-close recovery. Existing-state compatibility is source-verified: absent keys remain false, older imports preserve the preference, and saved layouts are unchanged. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Feature · Worth it: Yes · Fix scope: Complete
User problem: Users cannot distinguish menu-bar providers by their accent colors.
Reason: One optional preference supplies provider identity cues without changing saved layouts or existing defaults. The later owner-authored follow-up supplies direction for this scope.

Merge readiness

⛔ Blocked before merge - 2 items remain

Keep open; this PR needs real behavior proof before merge. Earlier functional findings are addressed and completed regression coverage is now recorded, but the supplied screenshot still demonstrates only offscreen rendering.

Priority: P3
Reviewed head: 6524e1fdb378f3855dca27a4e972d6b302363da2

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: The inspected screenshot exercises the production renderer and button-content application with fixture values in offscreen NSButtons, showing orange output and monochrome fallbacks. It does not exercise the running app’s settings-to-StatusItemController path or native menu-close recovery. Existing-state compatibility is source-verified: absent keys remain false, older imports preserve the preference, and saved layouts are unchanged. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Complete next step (P2) - Provide proof from a freshly built native application covering the toggle, provider colors, menu-close restoration, and accessibility fallback. Screenshots, recordings, logs, or live output are acceptable; redact account details, IP addresses, keys, and private endpoints. Updating the PR body triggers a fresh review; otherwise a maintainer can comment @clawsweeper re-review.

Findings

None.

Provenance

  • Sources/CodexBar/StatusItemController+MenuTracking.swift: tracking refresh lifecycle: original intent not found (unknown: Feature-history logs and the menu-session refactor were inspected; exact introduction searches failed on missing historical blobs with HTTP 403.)
  • Sources/CodexBar/MenuBarLayoutEditor.swift: preview appearance: original intent not found (unknown: The historical content search for the preview appearance failed because the promisor remote returned HTTP 403 for a required blob.)
  • Sources/CodexBar/StatusItemController+Animation.swift: Warp blink extraction: original intent not found (unknown: The historical content search failed on a missing blob with HTTP 403; source comparison shows the extracted calculation retains its existing loading condition and fallback.)

Tests

  • Low-value test Tests/CodexBarTests/MenuBarProviderColorTests.swift: contrast policy falls back when highlighted stale or under high contrast: Repeats helper guard assertions already covered by rendered fallback, pixel, and lifecycle tests; remove this redundant helper-only test.
  • Missing end-to-end proof: The supplied evidence does not show a freshly built application enabling the toggle, coloring native status items, restoring color after menu closure, and responding to Increase Contrast. Reviewer execution of a base-failing/head-passing regression was excluded by the read-only contract.
Agent review details

How this fits together

CodexBar displays provider usage in native macOS menu-bar items. Saved preferences, provider accents, and usage snapshots determine the icons, percentages, and spoken accessibility labels.

flowchart TD
 A[Saved display preferences] --> C[Menu-bar controller]
 B[Provider usage and accent] --> C
 C --> D[Appearance and tracking checks]
 D --> E{Provider color allowed?}
 E -->|Yes| F[Colored native content]
 E -->|No| G[Monochrome native content]
Loading

Technical review

Best possible solution:

Retain the shared optional tint path and establish its settings, native menu tracking, and accessibility behavior in a freshly built application.

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

Not applicable to a new appearance capability; the inspected screenshot establishes offscreen colored output, while native application behavior remains unproven.

Is this the best way to solve the issue?

Yes at the implementation level: the shared renderer and existing accent palette provide one color source while preserving layouts and defaults.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 844b0e19bbbb.

Provenance checked

  • Sources/CodexBar/MenuBarLayoutRenderer.swift: attachment tinting changes intended behavior with a stated reason (89b42bc: Restore explicit foreground tinting because text attachments draw template images directly; Fix custom layout provider icon rendering #2334 explains the native drawing boundary.)
  • Sources/CodexBar/MenuBarLayoutRenderer.swift: pace-token colors keeps the original intent (Add optional colors for menu bar quota pace #3429: Optional green/red pace colors communicate reserve versus usage ahead of pace while neutral values and existing layouts retain their behavior.)
  • Sources/CodexBar/StatusItemController+MenuBarLayout.swift: stacked provider rows keeps the original intent (feat(menu): add stacked two-provider icon style #3628: Each provider uses its first effective layout row while retaining the existing status item, placement, independent updates, and saved preferences.)

Testing

Proof path: in-process harness. Added test files: 45.

Security

None.

Evidence

What I checked:

  • Applicable repository policy: Read the complete root AGENTS.md; no nested AGENTS.md or maintainer-notes directory was found. Applied native-bundle validation, isolated settings, and provider-separation guidance. Builds and tests were not executed under the read-only contract. (AGENTS.md:1, 6524e1fdb378)
  • Pinned scope and current-main overlap: Read the pinned feature hunks and independently compared tree objects: 155 of 199 introduced paths have identical blobs on fetched main. Current main lacks the provider-color preference; the existing pace-color setting and Usage & Spend artwork address different behavior. Endpoint differences in unrelated current-main work were not attributed to this PR. (Sources/CodexBar/PreferencesMenuBarPane.swift:58, 6524e1fdb378)
  • Later owner direction: The owner declined a separate color mode on CodexBar menu bar color mode #3533, then authored the later follow-up explicitly adopting one default-off preference with contrast and tracking fallbacks. That newer recorded direction covers this implementation. (fc046bfd8aae)
  • Prior functional findings resolved: The tint policy rejects highlighted, stale, high-contrast, and accessibility states and checks the documented 25%/85% gray backgrounds. Tracking start/end refresh content; classification follows the tracking session and merged refresh bypasses tracking deferral. No earlier finding remains actionable. (Sources/CodexBar/MenuBarLayoutRenderer.swift:973, 6524e1fdb378)
  • Prepared screenshot inspected: Inspected the downloaded image at https://github.com/user-attachments/assets/8334eaec-6257-4f96-928b-d6cc17d8ed47. It visibly shows orange Claude output and monochrome fallback panels and explicitly identifies itself as synthetic offscreen proof. The source constructs NSButtons with fixture values rather than exercising the shipped settings-to-status-item path. (Tests/CodexBarTests/MenuBarProviderColorTests.swift:348, 6524e1fdb378)
  • Existing-state compatibility: An absent defaults key resolves to false. Import only changes the preference when the optional key exists, preserving older documents and current values. The change neither rewrites saved layouts nor requires a stored-data migration. (Sources/CodexBar/SettingsStore+PreferencesDocument.swift:39, 6524e1fdb378)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • ysyyork: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Jon Brown: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Review metrics

Metric Value Why it matters
Current-main overlap 155 of 199 introduced paths have identical current-main blobs Much of the headline branch size consists of already-integrated upstream work.
Provider-color code growth Production +208/-27; tests +549/-3 versus fetched main The shared tint path and rendering regressions justify the bounded growth; production includes 46 localization lines.

Labels

Label changes:

No label changes.

Label justifications:

  • P3: This is an optional appearance improvement with no reported broken core workflow.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The inspected screenshot exercises the production renderer and button-content application with fixture values in offscreen NSButtons, showing orange output and monochrome fallbacks. It does not exercise the running app’s settings-to-StatusItemController path or native menu-close recovery. Existing-state compatibility is source-verified: absent keys remain false, older imports preserve the preference, and saved layouts are unchanged. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence.

Rank-up moves

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

  • Add redacted native application screenshots, a recording, or runtime output showing the toggle, provider colors, menu-close restoration, and accessibility fallback.
  • Remove the redundant helper-only fallback test.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only; repair and merge need explicit maintainer commands such as @clawsweeper autofix or @clawsweeper automerge.

History

Review history (3 earlier review cycles)
  • reviewed 2026-10-07T07:01:10.520Z sha bb64180 :: needs real behavior proof before merge. :: [P2] Include system Increase Contrast in the tint fallback | [P2] Refresh provider colors after clearing open-menu tracking | [P2] Evaluate contrast against the supported menu-bar background
  • reviewed 2026-10-08T01:04:01.696Z sha fc046bf :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-08T01:49:23.102Z sha 6524e1f :: needs real behavior proof before merge. :: none

Keep Color by provider as one default-off preference across the existing
styles and stacked provider rows. Share the tint path and preserve pace
colors and spoken labels. Repair menu tracking recovery, system contrast
handling, and contrast checks for light, dark, and vibrant appearances.

Retain the contributor history, add pixel and lifecycle regressions,
localize the single toggle, and document its conservative fallback policy.
Refs steipete#4321.

Co-authored-by: David Aronchick <aronchick@gmail.com>
@steipete steipete changed the title feat(menubar): add opt-in color by provider mode feat(menubar): finish opt-in provider colors Oct 8, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Oct 8, 2026
@steipete
steipete marked this pull request as ready for review October 8, 2026 02:35
@steipete
steipete merged commit fe95bfd into steipete:main Oct 8, 2026
@steipete

steipete commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Thanks @aronchick! Merged in fe95bfd with your commits preserved. Color by provider ships as a single opt-in toggle on the menu bar layout (default off), tinting each provider slot with its brand colour on top of the active layout and icon style; the maintainer follow-ups made VoiceOver labels independent of colour, repaired the menu-close fallback, and fixed the contrast failure with rendered-colour regressions for both appearances. Ships in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants