Skip to content

v1.0.1 hotfix: toolbar icon, overlay suppression, ticker render#62

Merged
DevanshuNEU merged 4 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:feat/v1-0-1-hotfix
May 12, 2026
Merged

v1.0.1 hotfix: toolbar icon, overlay suppression, ticker render#62
DevanshuNEU merged 4 commits into
OpenCodeIntel:mainfrom
DevanshuNEU:feat/v1-0-1-hotfix

Conversation

@DevanshuNEU

Copy link
Copy Markdown
Contributor

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 from docs/cws-assets/icon.svg (used at 48/96/128) plus a new S-only icon-mark.svg for 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.connect port from the side panel; background mirrors port lifetime into chrome.storage.session.sidePanelVisible, content script subscribes via storage.onChanged and calls overlay.setSuppressed. One subtle gotcha caught during E2E: chrome.storage.session defaults to TRUSTED_CONTEXTS only (silently excludes content scripts), so background also calls setAccessLevel({ accessLevel: 'TRUSTED_AND_UNTRUSTED_CONTEXTS' }). Standalone case (no side panel) also moved from bottom: 88px to bottom: 16px so 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-slot placeholder 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

  • Toolbar icon is the Saar S, not Chrome's default puzzle (GET-39)
  • Side panel pinned: no in-page overlay visible (GET-41)
  • Side panel closed: overlay shows at bottom-right corner, below composer level, not overlapping the textarea (GET-41)
  • Toggle side panel a few times: overlay responds within ~100ms, no stuck states (GET-41)
  • Service worker idle restart resilience: leave a tab idle ~1 min, reopen side panel, suppression resumes
  • New conversation with 1 turn: TurnTicker shows a small bar at 1/12 width on the left with faint placeholder rails to the right, not a solid orange wall (GET-40)
  • Growing conversation: bars climb across the grid, slots disappear as turns fill in (GET-40)
  • Enterprise account smoke (Northeastern): credit-tier card still renders cleanly with the spend trajectory
  • Pro account smoke: session + weekly bars render, weekly ETA still appears when data warrants
  • Manifest version reads 1.0.1
  • All 1808 unit tests pass

Closes GET-39, GET-40, GET-41.

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.
@vercel

vercel Bot commented May 11, 2026

Copy link
Copy Markdown

@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.

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@DevanshuNEU has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 23 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db23d1f2-869a-4195-be7b-b3a63e55fa49

📥 Commits

Reviewing files that changed from the base of the PR and between f3799e9 and 1592bbc.

⛔ Files ignored due to path filters (6)
  • docs/cws-assets/icon-mark.svg is excluded by !**/*.svg
  • public/icon/128.png is excluded by !**/*.png
  • public/icon/16.png is excluded by !**/*.png
  • public/icon/32.png is excluded by !**/*.png
  • public/icon/48.png is excluded by !**/*.png
  • public/icon/96.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • entrypoints/background.ts
  • entrypoints/claude-ai.content.ts
  • entrypoints/sidepanel/App.tsx
  • entrypoints/sidepanel/components/TurnTicker.tsx
  • entrypoints/sidepanel/dashboard.css
  • package.json
  • ui/overlay-styles.ts
  • ui/overlay.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel

vercel Bot commented May 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
getsaar Ready Ready Preview, Comment May 12, 2026 3:19am

@DevanshuNEU DevanshuNEU merged commit 03f988e into OpenCodeIntel:main May 12, 2026
6 of 7 checks passed
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