Skip to content

fix(logos): ship every provider mark as colour/light/dark PNG triplets - #190

Merged
jaywedgeworth22 merged 2 commits into
mainfrom
mm/accent-aware-selection
Oct 8, 2026
Merged

jaywedgeworth22 merged 2 commits into
mainfrom
mm/accent-aware-selection

Conversation

@jaywedgeworth22

Copy link
Copy Markdown
Collaborator

The symptom

The owner: "The logos are NOT SHOWING UP it seems like no matter what y'all do to fix it other than the custom logo for MiniMax I uploaded." Every bundled mark drew questionmark.square.dashed — the fallback glyph.

What four previous fixes got wrong

PRs #160, #167, #176 and #180 all assumed a bundle-resolution failure. Measurement ruled that out:

Checked Result
Marks present in the installed app? Yes — all 17
Do the SVGs decode? Yes — every one rasterises to real pixels (claude 274/576 opaque, cursor 306/576)
Does Bundle.url(forResource:) find them? Yes, every one, in the installed app
Does PlatformLogoImage.load return an image? Yes — all 18 provider keys, both styles
Is the owner on a stale build? No — installed build 156 is main HEAD, and already includes the #180 logo fix
Did the failure path log? Never in 48h — and that's meaningful, the app emits ~39k log entries/day

So resolution worked. Delivery didn't. Two defects, both found by measuring:

  1. The marks were SVGs, which come back as _NSSVGImageRep — a private AppKit class. The prior fixes were chasing the wrong layer.
  2. muse-code.png, muse.png and muse-assist.png ship a baked-in opaque white background, so they drew as a white box on any non-white surface.

The fix

Every mark now ships as three PNGs:

<base>-color.png   brand colours (Standard style)
<base>-light.png   silhouette in Theme.ink's Light value
<base>-dark.png    silhouette in Theme.ink's Dark value

Appearance is now chosen from data, not from the hardcoded monochromeKeys Set. That Set was the guesswork that made some marks invisible and others fine — it no longer decides which file loads.

Two more fixes found along the way:

  • Third-Party Antigravity resolved through templateResourceNames to a Muse mark. Both pools now map to their own star.
  • muse-code is rasterised from the Meta vector, not the shipped PNG, which was visibly soft at small sizes. Coverage went 100% → 19% once the white background was knocked out from the border inward (white that belongs to the mark is preserved).

The custom-mark path is untouched — an owner-supplied mark still wins over the bundled one and still adapts to Light/Dark. A first pass at this PR merged .custom into the .standard case and broke exactly that path; the 6 test failures caught it before merge.

Verification

  • 366 tests pass, 3 skipped, 0 failures, plus 4 new ones asserting that all 18 providers resolve in every style and appearance, every delivered mark is an NSBitmapImageRep rather than a private rep, none carries an opaque background, and Light and Dark are genuinely different files.
  • Those tests pin the contract, not an implementation, so a private rep cannot creep back in through any path.

Note

This does not touch the CodeCaps app icon or the menu bar mark.

@kody-ai

kody-ai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Code Review Completed! 🔥

The code review was successfully completed based on your current configurations.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug ✅
Performance ✅
Security ✅
Business Logic ✅

Access your configuration settings here.

​

@kody-ai

kody-ai Bot commented Oct 7, 2026

Copy link
Copy Markdown

kody code-review Kody Rules medium

Single ASCII space between sentences in the PR body collapses under GitHub-flavored markdown rendering, violating the owner's 2026-08-19 ruling that rendered agent-written paragraphs use &nbsp; followed by a normal space between sentences. Replace literal single spaces with &nbsp; at both transitions.

Kody rule violation: Use two spaces between sentences in every human-facing string and agent-written paragraph

@kody-ai

kody-ai Bot commented Oct 7, 2026

Copy link
Copy Markdown

kody code-review Business Logic medium

🤔 Insufficient Task Context

I found a task linked to this PR, but it only contains minimal information (title only, no description or acceptance criteria). To perform a meaningful business rules validation, I need more details.

🔍 What I need to validate:

  • Business requirements and acceptance criteria
  • Expected behavior and business rules
  • Edge cases and constraints to consider

💡 How to improve the task context:

  • Add a description to the linked ticket
  • Include acceptance criteria or business rules
  • Describe the expected behavior after the change

⚠️ Important:

A task title alone is not sufficient to determine whether the implementation is correct or complete.


💡 This validation runs automatically only on the first review of a pull request. To run it again, comment @kody -v business-logic.

Comment thread Sources/CodeCaps/PlatformLogo.swift
@jaywedgeworth22
jaywedgeworth22 enabled auto-merge (squash) October 8, 2026 01:32
jaywedgeworth22 and others added 2 commits October 7, 2026 21:11
The owner reported that no provider logo drew at all except the one custom
mark on disk, and that repeated fixes had not moved it. Every bundled mark
showed questionmark.square.dashed — the fallback glyph.

Four prior attempts (#160, #167, #176, #180) all assumed a bundle-resolution
failure. Measurement ruled that out:

- All 17 marks are present and decode; every SVG rasterises to real pixels.
- Bundle.url(forResource:) finds each one in the installed app.
- PlatformLogoImage.load returns a valid image for all 18 provider keys.
- Installed build 156 IS main HEAD, and already includes the #180 logo fix.
- noteFailure had never logged in 48h, and that silence is meaningful: the
  app emits ~39k unified-log entries a day.

So resolution worked and delivery did not. Two things were wrong with the
delivery, both found by measuring rather than assuming:

1. The marks were SVGs, which come back as _NSSVGImageRep — a PRIVATE AppKit
   class. Three separate fixes had chased the wrong layer.
2. muse-code.png, muse.png and muse-assist.png shipped a baked-in opaque
   white background, so they drew as a white box on any non-white surface.

Every mark now ships as three PNGs — <base>-color, <base>-light, <base>-dark —
and appearance is chosen from data instead of the hardcoded monochromeKeys
Set. That Set was the guesswork that made some marks invisible and others
fine; it no longer decides which file gets loaded.

Also fixed while in there: the Third-Party Antigravity pool resolved through
templateResourceNames to a Muse mark, which was simply wrong. Both pools now
map to their own star. muse-code is rasterised from the Meta vector because
the shipped PNG was visibly soft at small sizes.

muse-code coverage went from 100% (opaque white box) to 19% once the
background was knocked out from the border inward, so white that belongs to
the mark is preserved.

The custom-mark path is untouched: an owner-supplied mark still wins over the
bundled one, and still adapts to Light/Dark. A first pass at this merged
.ccustom into the .standard case and broke exactly that path; the 6 failures
it caused caught it.

Verified: 366 tests pass, 3 skipped, 0 failures, plus 4 new ones asserting
all 18 providers resolve in every style and appearance, every delivered mark
is an NSBitmapImageRep rather than a private rep, none carries an opaque
background, and Light and Dark are genuinely different files.
A hint equal to a provider base name like "claude" was passed to
imageFromBundle as a filename, which always missed and logged
"is mapped for ... but was not found". Route known keys through
variantFile so the colour/light/dark PNG is loaded instead.
@jaywedgeworth22
jaywedgeworth22 force-pushed the mm/accent-aware-selection branch from c63091d to efd503c Compare October 8, 2026 02:11
@jaywedgeworth22
jaywedgeworth22 merged commit 954c9f7 into main Oct 8, 2026
3 checks passed
jaywedgeworth22 added a commit that referenced this pull request Oct 9, 2026
…the logo (#193)

* feat(pip): drop the header band, and let the platform name go before the logo

Owner's PiP batch, 2026-10-08.  Board f324ec6.

The raised strip above the rows read as a stray silver tab.  It is gone, and
with it the app's own mark and the word "CodeCaps": the provider logos are
what identify a row now.  The close/back control floats over the rows'
top-right corner instead, still only while the pointer is over the window,
so it never occupies permanent space above the numbers.

The width ladder gained a `logoOnly` level.  The logo and the name used to
drop together at `minimal`, which left a nameless AND unidentifiable row;
the owner's instruction was that the name goes first and the logo stays, so
that is now its own rung between the named single-meter row and the
identity-free one.  His condition for this — "ASSUMING WE FINALLY CAN MAKE
THE LOGOS ACTUALLY SHOW UP" — is met by #190, which ships the marks as
colour/light/dark PNG triplets rather than SVGs.

Panel metrics follow the header's removal: `minHeight` is one row plus
padding, and the fit and visible-row maths no longer reserve a band.

Verified: swift build clean; swift test 370 passed / 3 skipped / 0 failures,
including a new testThePlatformNameDropsBeforeTheLogo that pins the order
and the real width band that selects it.  Two tests that asserted the old
header contract were updated rather than deleted silently: the fit-height
test no longer counts a header, and the header-text test is gone with the
header.

* fix(pip): inset the floating control so it stops overlapping the first row

Kody caught this on #193: the 18x18 close control sat flush in the panel's
top-trailing corner and overlapped the first row's right-edge percentage by
about 8x12pt.  controlInset existed for exactly this offset but nothing
consumed it, so the contract was declared and then not honoured.

Honours the constant rather than removing it, so the corner offset it was
designed for is now actually enforced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant