v1.0.1 hotfix: toolbar icon, overlay suppression, ticker render#62
Conversation
Toolbar showed Chrome's default puzzle on v1.0.0 installs because
public/icon/{16,32,48,96,128}.png were the WXT scaffold placeholders,
not the Saar terracotta-S used in the CWS listing.
Regenerated all five sizes from SVG sources via rsvg-convert. Used the
existing icon.svg (S plus SAAR wordmark) for 48/96/128 to match the
CWS listing. Added icon-mark.svg (S only, larger glyph, no wordmark)
for 16/32 because the wordmark renders as an illegible smear at that
size; the toolbar reads as a clean orange S instead.
Built manifest now binds icons[16..128] to the new PNGs.
…-41]
The side panel and the in-page overlay were rendering the same data
(cost, health, weekly bar, totals, coaching) at the same time, with
the overlay overlapping the composer textarea and chat content. Both
DDIA's "two views of one truth" rule and basic UX hierarchy say to
pick one canonical surface per context, not to reposition the second
one. So when the side panel is open the overlay now steps aside.
Mechanism: side panel App.tsx opens a chrome.runtime.connect port on
mount and reconnects on disconnect (rides through SW idle restarts).
Background's onConnect handler mirrors port lifetime into
chrome.storage.session as sidePanelVisible. The content script reads
the flag on overlay setup and subscribes to onChanged for live
updates, calling overlay.setSuppressed.
Subtle bug found during E2E verification: chrome.storage.session
defaults to TRUSTED_CONTEXTS, which silently excludes content
scripts (reads return empty, onChanged never fires). Background now
calls setAccessLevel({ accessLevel: 'TRUSTED_AND_UNTRUSTED_CONTEXTS' })
at module load so the signal actually reaches the overlay.
Overlay refactor: render() and the new setSuppressed both go through
applyVisibility(), which reconciles a one-way shouldShow latch with
the externally-toggled suppressed flag into the actual display style.
Suppression always wins over the data-arrival latch.
Standalone case (no side panel) also fixed: bottom anchor lowered
from 88px (composer level) to 16px (viewport corner), so the overlay
no longer overlaps the textarea on its own.
… cleanly [GET-40] With one tracked turn, the flex-based row stretched that bar to fill 100% of the width AND 100% of the height (it is its own peak), which read as a solid orange wall instead of a per-turn histogram. Switched the bars container to a 12-column CSS grid (minmax(2px, 1fr)) so each bar is always 1/12 of the row regardless of count. Padded the remaining positions with faint .lco-ticker-slot rails so the row reads "this will fill in over time" instead of leaving raw negative space beside the real bar. Peak normalization for bar height is intentionally preserved. The relative-magnitude story (turn 5 was the biggest of the run) is the whole point of the ticker; the broken visual was width, not height. Grid column count (12) mirrors maxBars in TurnTicker.tsx; comment in the CSS calls this out so a future bump keeps the two in sync.
Bumps package.json (and via WXT, the built manifest) for the post-CWS hotfix bundle: - GET-39: replace WXT scaffold icons with Saar branded set so the Chrome toolbar shows the Saar S instead of the default puzzle. - GET-41: suppress the in-page overlay when the side panel is visible. Two surfaces showing the same data is a duplicate-view problem, not a positioning problem; the overlay defers to the panel. Standalone case (no side panel) also moves the overlay anchor from composer level to viewport corner. - GET-40: fix the TurnTicker rendering as a solid orange wall when only one turn is tracked. Bars now sit in a 12-column grid with faint placeholder rails for the remaining positions.
|
@DevanshuNEU is attempting to deploy a commit to the Dev's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Summary
Post-CWS hotfix bundle. Saar v1.0.0 was approved on the Chrome Web Store on 2026-05-09. Within hours of first install three user-visible bugs surfaced that this PR addresses.
GET-39: Toolbar showed Chrome's default puzzle icon because
public/icon/*shipped as WXT scaffold placeholders, not the Saar terracotta-S used in the CWS listing. Regenerated all five sizes fromdocs/cws-assets/icon.svg(used at 48/96/128) plus a new S-onlyicon-mark.svgfor 16/32 where the wordmark renders as an illegible smear.GET-41: The side panel and the in-page overlay rendered the same data simultaneously, with the overlay overlapping the composer textarea and chat content. Fix is architectural rather than positional: when the side panel is visible, the overlay defers. Mechanism is a
chrome.runtime.connectport from the side panel; background mirrors port lifetime intochrome.storage.session.sidePanelVisible, content script subscribes viastorage.onChangedand callsoverlay.setSuppressed. One subtle gotcha caught during E2E:chrome.storage.sessiondefaults toTRUSTED_CONTEXTSonly (silently excludes content scripts), so background also callssetAccessLevel({ accessLevel: 'TRUSTED_AND_UNTRUSTED_CONTEXTS' }). Standalone case (no side panel) also moved frombottom: 88pxtobottom: 16pxso the overlay isn't sitting at composer level on its own.GET-40: TurnTicker rendered a single tracked turn as a solid orange wall because the flex-based row stretched the only bar to 100% width AND 100% peak-normalized height. Switched the bar container to a 12-column CSS grid (
minmax(2px, 1fr)) with faint.lco-ticker-slotplaceholder rails for the unfilled positions, so the row reads "this will fill in over time" instead of "broken visualization."Architectural framing for GET-41: DDIA's "single source of truth" and basic UX hierarchy both pointed at deferring the secondary surface rather than repositioning it. A CSS-only reposition would have left the duplicate-view problem intact.
Test plan
1.0.1Closes GET-39, GET-40, GET-41.