Skip to content

feat(plugins): allow built-in provider branding per snapshot - #4801

Merged
steipete merged 5 commits into
steipete:mainfrom
KLIEBHAN:feat/plugin-icon-provider
Oct 31, 2026
Merged

steipete merged 5 commits into
steipete:mainfrom
KLIEBHAN:feat/plugin-icon-provider

Conversation

@KLIEBHAN

@KLIEBHAN KLIEBHAN commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Allow each plugin snapshot to choose a bundled provider logo with optional iconProvider, while keeping plugin identity, credentials and quota ownership unchanged. Omitting the hint restores the manifest logo. The field is validated on both plugin engines, survives snapshot copies/serialization, and is advertised through ctx.env.supportsIconProvider.

The menu bar and retained provider switcher refresh when only branding changes. Shared brand images are copied before switcher sizing. Thanks @KLIEBHAN!

Dependency

Land #4787 first. This head includes its selected-window observation fix at 7381b29222729a164b4a74598432946144d8371d and adds branding to the same signature helper.

Verification

Head: 0fb9d4289290d8269f4f795e21c84d4a4cf89c94.

swift test --build-system native --jobs 2 -Xswiftc -gnone --filter 'UserProviderPluginTests|UserProviderPluginPortableTests|UserPluginPercentWindowTests|ProviderPluginIconProviderTests|ProviderPluginMenuBarItemsTests|ProviderPluginRuntimeTests|ProviderPluginSnapshotContractTests|ProviderPluginTransportTests|ProviderPluginResultTests|ProviderArchitectureGatekeeperTests|StatusItem.*SignatureTests|MenuBarLayoutRendererTests|PluginMenuBarSummaryTests'

Result: Test run with 348 tests in 16 suites passed. Tests ran with the repository's scrubbed test environment through the shared build lock. make check passed: Found 0 violations, 0 serious in 3134 files. Catalog precheck and git diff --check passed. Independent P0–P2 review found no actionable issues.

CI: https://github.com/steipete/CodexBar/actions/runs/41056936003 — success on the exact head.

Synthetic branding proof

These are cropped logo areas from the synthetic controller test. The test separately asserts unchanged 75% remaining and retained-switcher refresh. No running-app screenshot, account data or credentials were used; capture hooks are not committed.

Manifest → Claude → Codex:

Manifest logo
Claude logo
Codex logo

Refs #4787, #4789. Full layout-token integration remains separate from branding.

@clawsweeper

clawsweeper Bot commented Oct 27, 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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-10-27T07:37:46.952366Z aa7862a PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@clawsweeper clawsweeper Bot added clawsweeper:intake:feature Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. 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. and removed clawsweeper:intake:feature Preliminary submission classification; full source review pending. labels Oct 27, 2026
@clawsweeper

clawsweeper Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge.

What this changes

This PR lets plugin snapshots select a bundled provider logo while preserving the plugin’s identity and usage source.

Example: An aggregator switches from Claude to Codex while usage remains at 75% remaining.

  • Before: The menu-bar and switcher logos remain fixed to the plugin manifest.
  • After: The logos follow iconProvider: "codex"; omitting the hint restores the manifest logo.

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) The scoped patch resolves the earlier defects and has useful regression coverage, but qualifying proof of the changed app behavior remains absent.
Proof confidence 🧂 unranked krab (1/6) Real behavior proof is necessary before merge. See Before merge.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Feature · Worth it: Needs a maintainer decision · Fix scope: Complete
User problem: An aggregator’s fixed plugin logo cannot follow the provider whose quota it currently displays.
Reason: The use case is concrete and the existing static SVG capability is insufficient, but adding public plugin fields requires an owner decision.

Merge readiness

⛔ Blocked before merge - 2 items remain

Keep this PR open for a maintainer decision on the additive plugin API; both earlier invalidation findings are fixed, and no further actionable code defect was found.

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

Decision needed

  • Question: Should user-plugin snapshots be allowed to select bundled provider branding independently of their plugin identity?
  • Recommendation: Accept the scoped branding API: Allow the optional, capability-detected hint while retaining plugin identity, credentials, quotas, and manifest fallback.
  • Why: This adds a public plugin capability, and neither the discussion nor recorded reviews contain maintainer acceptance.

Before merge

  • Add real behavior proof - The supplied ICON_LIFECYCLE output comes from the added controller test with synthetic store publications; the reported packaged CLI matrix does not demonstrate the app’s changed branding behavior. Provide screenshots, a recording, or app runtime diagnostics showing the refresh transitions through the shipped app, with private information redacted. After adding proof, update the PR body, then request a new review with @clawsweeper re-review. The PR author or someone with repository write access can request it.
  • Resolve maintainer decision - Resolve the maintainer decision shown above before merge.

Findings

None.

Tests

  • Missing end-to-end proof: Show a freshly built running app refreshing Claude → Codex → manifest at unchanged quota, with both the menu-bar logo and reopened switcher following the snapshot.
Agent review details

How this fits together

Plugin engines validate JavaScript results into UsageSnapshot values, which the app’s observation and menu owners render using cached bundled images.

flowchart LR
  A[Plugin snapshot] --> B[Shared snapshot mapper]
  B --> C[UsageSnapshot]
  C --> D[Icon observation]
  C --> E[Menu reuse signature]
  D --> F[Cached branding renderer]
  E --> F
Loading

Technical review

Best possible solution:

If accepted, keep the optional branding hint in the shared snapshot contract and retain the existing rendering, fallback, and invalidation owners.

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

This is a new capability: current main renders plugin branding from the manifest, and source inspection confirms it lacks per-snapshot logo selection.

Is this the best way to solve the issue?

The implementation is focused and preserves existing ownership: both engines use the shared validator, snapshot copies retain the hint, and existing observation signatures invalidate affected images.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 5f93dc3068b3.

Provenance checked

Testing

Proof path: in-process harness.

Security

None.

Evidence

What I checked:

Likely related people:

  • Peter Steinberger: Raw commit c286d34 adds Sources/CodexBar/StatusItemController+IconObservation.swift:49 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: c286d3428cd8; files: Sources/CodexBar/StatusItemController+IconObservation.swift)
  • Shivanath Devinarayanan: Raw commit ac30c44 adds Sources/CodexBar/StatusItemController+UserPlugins.swift:167 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: medium; commits: ac30c447f9d2; files: Sources/CodexBar/StatusItemController+UserPlugins.swift)
  • Fabian Kliebhan: Raw commit aa02921 adds Sources/CodexBarCore/Plugins/ProviderPluginSnapshotMapper.swift:180 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: medium; commits: aa029218d82e; files: Sources/CodexBarCore/Plugins/ProviderPluginSnapshotMapper.swift)

Review metrics

Metric Value Why it matters
Introduced scope Production +46/-4; tests +214; docs +20 The production change reuses existing owners; tests cover cross-engine validation, serialization, fallback, and both previously broken invalidation paths.

Labels

Label changes:

No label changes.

Label justifications:

  • P2: Optional aggregator branding has limited user impact and does not repair an urgent broken workflow.
  • merge-risk: 🚨 compatibility: The patch extends the public plugin snapshot and capability contracts; existing hosts reject the new snapshot field unless scripts use capability detection.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

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 execution lanes are retired.

History

Review history (1 earlier review cycle)
  • reviewed 2026-10-27T07:51:33.410Z sha aa7862a :: needs real behavior proof before merge. :: [P2] Include snapshot branding in the menu-bar redraw signature | [P2] Refresh captured switcher images when snapshot branding changes

Reviewed October 27, 2026, 5:00 AM ET / 09:00 UTC (Revision 2).

@KLIEBHAN

Copy link
Copy Markdown
Contributor Author

Addressed both invalidation findings in the current head:

  • The existing plugin icon observation signature includes snapshot branding in brand-icon mode, so an unchanged percentage no longer suppresses redraw.
  • The existing menu localization/reuse signature includes the branding hint, invalidating captured switcher images without adding another cache owner.
  • Switcher-sized copies no longer resize the shared bundled-image cache.

Added a native controller lifecycle regression using in-memory defaults/stores and synthetic snapshots. It publishes Claude → Codex → manifest at the same 75% remaining and the same timestamp, waits for the real store observer to update the status button (no manual redraw for the transitions), checks its pixels, calls the real menu populate/reuse path, and checks the recreated switcher image. An unchanged follow-up keeps the switcher. This test failed before the fix at both signatures and switcher reuse, and passes now.

Runtime output:

ICON_LIFECYCLE provider=codex remaining=75 redraw=true switcherRebuilt=true
ICON_LIFECYCLE provider=manifest remaining=75 redraw=true switcherRebuilt=true

Compatibility proof: a pre-icon serialized snapshot and version-1 plugin configuration (including opaque plugin settings/secrets) decode and round-trip without losing their data. A separate sandboxed integration run exercised the actual CPAMC consumer against old and new packaged CLIs, both engines, auto and all four provider choices: 20 cases passed, with networking and writes to the real home denied.

Focused tests now pass 3 app tests and 5 plugin tests; changed-file strict lint/format and diff checks pass. The initial complete LC_ALL=C make check passed. No real account/provider probes were run.

The public API direction still needs maintainer acceptance; I am not treating that as approved or merging this PR.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@KLIEBHAN

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added clawsweeper:intake:feature Preliminary submission classification; full source review pending. and removed clawsweeper:intake:feature Preliminary submission classification; full source review pending. labels Oct 27, 2026
@KLIEBHAN

Copy link
Copy Markdown
Contributor Author

The reviewed head is now also packaged and running as a local 0.82.1 build, with the capability-gated aggregator consumer enabled. Installation preserved the existing plugin configuration and approval file unchanged. Bundle integrity and packaged resource/startup checks passed; the controller lifecycle regression and 20 old/new-CLI offline compatibility cases pass on this head.

I cannot capture the real menu-bar transitions from the target Mac without its screen-recording permission, so I am not claiming that the requested screenshot/recording proof is complete. The PR remains open for that evidence and maintainer acceptance of the additive API. No further code findings were reported in the latest review.

steipete and others added 2 commits October 27, 2026 14:35
Consolidate signature construction while preserving built-in redraw dependencies and the plugin meter fallback.

Co-authored-by: Vincent Peng <mail@vincentpeng.me>
Integrate the reviewed selected-window refresh fix while retaining branding-only invalidation for the menu bar and switcher.

Co-authored-by: Fabian Kliebhan <fabi@mac-mini.tatex-gmbh.de>
steipete added a commit that referenced this pull request Oct 31, 2026
…mmaries and selected-window refresh (#4787, #4801, #4802)

Lands the reviewed plugin stack as one merge so each contributor PR keeps its own commits:

- #4787: the saved plugin percentage window now feeds the menu-bar icon's observation signature, so a change in only that quota (for example a monthly one) redraws instead of showing a stale percentage.
- #4801: plugin snapshots can opt into a built-in provider's branding per snapshot on both plugin engines; branding is display metadata only and never borrows another provider's identity or usage.
- #4802: plugins can publish a compact multi-quota menu-bar summary (ordered window-backed items with per-item logos, genuine zero distinct from unavailable, one status item and menu); an empty or omitted summary falls back to the saved percentage window.

Co-authored-by: Vincent Peng <mail@vincentpeng.me>
Co-authored-by: Fabian Kliebhan <fabi@mac-mini.tatex-gmbh.de>
@steipete
steipete merged commit 7cb9ab2 into steipete:main Oct 31, 2026
9 checks passed
@steipete

Copy link
Copy Markdown
Owner

Landed as part of the plugin stack merge #4802 (754e3fd), which carries this branch's commits unchanged. Thank you @KLIEBHAN: per-snapshot provider branding ships in the next release.

@KLIEBHAN
KLIEBHAN deleted the feat/plugin-icon-provider branch October 31, 2026 09:01
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. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants