In the browser
Content scripts on each marketplace, the side panel, and a
service worker. State lives in chrome.storage, so
the worker can stop and restart without losing the session.
Service manual · v3.1.0
Car Analyst AI is a Chrome extension that reads a used-car listing, sends the details to an AI model, and answers questions about that specific car. This page walks through the moving parts, the problems that took the most care, and how this website was made.
Specifications
New cars in the US carry a window sticker that lists what’s inside. Here’s the one for Car Analyst AI.
The request path
What happens between clicking Analyze and reading the verdict. Each step names the file where it lives.
A content script pulls the price, mileage, VIN, and trim. Embedded page data comes first, then a site adapter, then JSON-LD to fill gaps.
vehicleAnalyzer/extractor.js
The side panel asks the page for the extracted details and renders the vehicle card, including the VIN and, on Manheim, the condition report.
sidepanel/sidepanel.js
The service worker attaches a vehicle snapshot, picks one of six prompt modes, and sends the first message plus the latest 29.
background/background.js
A Cloud Function checks a 24-hour window in Firestore, then calls Gemini. Failed calls retry twice with backoff.
functions/index.js
The reply lands in the panel. Recalls and complaints load from NHTSA in parallel, and repair estimates arrive as JSON.
sidepanel/vehicleHistory.js
Content scripts on each marketplace, the side panel, and a
service worker. State lives in chrome.storage, so
the worker can stop and restart without losing the session.
One HTTPS function proxies every AI call, so the API key never ships in the extension. Firestore stores usage counts only.
NHTSA’s recalls and complaints APIs, queried by make, model, and year, straight from the extension.
Engineering notes
Six problems that shaped the code, how each one is handled, and where to find it.
| Problem | Why it’s hard | Approach | In the code |
|---|---|---|---|
| Nine marketplaces, nine different pages | Every site lays out a listing differently. Some hide details in shadow DOM or behind auto-generated class names. | Layered extraction with a dedicated adapter per site. Each field records where it came from and how confident the match is, and missing fields are reported. The Cars.com adapter reads through shadow DOM. Manheim condition severity is read from swatch colors. | vehicleAnalyzer/extractor.js |
| Keeping the chat about this car | Shoppers jump between listings. An answer about the previous car is worse than no answer. | Every message carries a snapshot of the vehicle, and the prompt uses the newest one. Running Analyze resets the chat. Run IDs discard async results that arrive after the shopper has moved on. | content/chat.jsbackground/background.js |
| Opening the side panel from the page | Chrome opens a side panel only in direct response to a user gesture. Any async step before the call loses that permission. | The floating button on the listing messages the service worker, which opens the panel synchronously inside the gesture. Panel state is kept per window in session storage and broadcast to every view. | content/toggle.jsbackground/background.js |
| A service worker that can stop at any time | Manifest V3 shuts down idle service workers, so anything held in memory can disappear mid-session. | State lives in extension storage, not in variables. Context writes go through a promise chain, so overlapping updates can’t overwrite each other. The error log is capped and de-duplicated. | background/background.js |
| Free limits without forcing sign-up | Each AI call costs money, but asking for an account before the first answer drives people away. | Signed-in users get a SHA-256-hashed Google ID, and everyone else gets an anonymous one. The Cloud Function keeps a 24-hour sliding window of timestamps per ID and returns a 429 after 100 calls. | services/identityService.jsfunctions/index.js |
| Numbers a chat model can’t get wrong | Repair estimates need parts and labor figures the panel can total, but the model returns free text. | A JSON-only prompt mode, tolerant parsing of the reply, and totals recomputed in the panel instead of trusting the model’s arithmetic. | content/chat.jsvehicleAnalyzer/formatter.js |
This website
caranalyst.ai is plain HTML, CSS, and JavaScript, served as static assets from a Cloudflare Worker. The interactive demo runs entirely in the page.
aria-hidden copy, so screen readers get the real
value.
fetchpriority="high". Gallery images load lazily, and
the page’s own script is two small files with no framework.
On the roadmap
Where the extension goes from here.
Free to install. No account needed to analyze.