cd /news/developer-tools/six-weeks-and-three-platform-rewrite… · home topics developer-tools article
[ARTICLE · art-106557] src=promptcube3.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Six weeks and three platform rewrites later

A developer's six-week effort to build a browser extension for tracking AI platform usage nearly failed due to context-switching design, Chrome Manifest V3 constraints, and selector rot, but recovered by shipping a minimal viable product and iterating based on user behavior. The extension, which injects a usage bar into Claude and ChatGPT interfaces, saw engagement spike after adding a weekly spend rollup in v1.2, while a token optimization tips panel built over two weeks received zero interactions.

read3 min views1 publishedAug 21, 2026
Six weeks and three platform rewrites later
Image: Promptcube3 (auto-discovered)

The context trap almost killed the product #

My first instinct was a backend dashboard — scrape rate limits, push to a server, let users check a separate tab. Three days into the API design I caught myself: why would anyone context-switch to a dashboard when they're staring at the rate limit error inside Claude? The fix was obvious once I stopped overthinking: inject a slim bar directly above the input box. Always visible, zero tab switching, problem solved where it actually happens.

Lesson learned: solve the friction in the exact context it appears. Every extra step is a failure point.

MV3 is hostile to rapid iteration #

Chrome's Manifest V3 constraints bit me in three specific ways:

CSP kills inline everything. Every onclick="handler()"

in my popup HTML failed silently. The fix: addEventListener

wired after DOMContentLoaded

for every single interaction. Took a day to trace because the errors don't surface in the console the way you'd expect.

Service workers die on you. Background scripts are now ephemeral — Chrome kills them between messages. Any state held in memory vanishes. Everything persistent must go through chrome.storage.local

. I learned this when users reported intermittent "limit not updating" bugs that I couldn't reproduce locally.

Message channels have a contract. chrome.runtime.onMessage

listeners must return true

if you'll call sendResponse

asynchronously, false

(or nothing) if you won't. Get this wrong and you get "message channel closed before response was received" — an error that appears randomly and leaves no stack trace.

// Correct async pattern
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.type === 'GET_USAGE') {
    fetchUsage().then(data => sendResponse(data))
    return true  // critical: tells Chrome we'll respond async
  }
  return false
})

Selector rot is inevitable — plan for it #

Every platform updates its frontend weekly. ChatGPT broke my content script three days post-launch. The only sustainable pattern is defensive selector arrays with explicit fallbacks:

const INPUT_SELECTORS = [
  '#prompt-textarea',                    // primary
  '[data-id="prompt-textarea"]',         // fallback 1
  'div[contenteditable="true"]',         // fallback 2
  'textarea[placeholder*="Message"]'     // fallback 3
]

function findInput() {
  for (const selector of INPUT_SELECTORS) {
    const el = document.querySelector(selector)
    if (el) return el
  }
  return null
}

Never trust a single selector. Always null-check before DOM operations. I now ship with 3-4 fallbacks per platform and a background job that logs selector failures so I know when to update.

I built a feature zero people used #

Spent two weeks on a "token optimization tips" panel in the popup — collapsible, categorized, pretty. Total interactions in week one: zero. Not a single piece of feedback mentioned it.

Meanwhile, the #1 request: "show me weekly spend across all platforms." I had per-conversation cost tracking but no rollup. Shipped the weekly summary in v1.2 — immediate engagement spike.

The lesson isn't "do user research" (I did). It's that users can't articulate what they need until they're using the product. The tips panel sounded useful in theory. The weekly view revealed itself from actual behavior.

Ship the minimum. Watch what they reach for. Build that.

Notifications took three rewrites #

First attempt: chrome.notifications.create()

for every limit warning. Result — notification spam during long coding sessions, users disabled permissions.

Second: in-page toast system. Better, but z-index fights with platform modals and the toasts got buried.

Third (current): a persistent but collapsible banner injected at the top of the chat viewport, color-coded by severity (yellow at 70%, orange at 90%, red at 95%). Dismissible per-session, respects prefers-reduced-motion

. Finally zero complaints.

The extension is live as TokenPulse if anyone wants to poke at the implementation. Happy to share the manifest config or the platform detection logic if it saves someone the MV3 learning curve.

Next After six months with Cursor, here's where the real leverage actually shows up →

a guide to making money with AI, with plenty of directly applicable cases.

── more in #developer-tools 4 stories · sorted by recency
── more on @claude 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/six-weeks-and-three-…] indexed:0 read:3min 2026-08-21 ·