Your manifest, read the way Chrome's loader and a store reviewer read it
Paste your manifest.json — and the service worker and content script beside it.
The browser reads all of it for free: it parses the manifest the way Chrome's loader does, validates
every match pattern, names the permission your code never calls and the API you call with no
permission behind it. Then pick a lane.
Both examples ship with a saved result for every lane, so you can see a whole lane — findings, tables, justification text and the fixed manifest — without signing in and without spending a credit.
Findings
Key by key, against the MV3 rules
Reader reconciliation
Every flag the free reader raised, and what the run did with it. A flag set aside with a reason is a real answer; a flag the run never mentions is the thing this panel exists to catch.
Artifacts
Next steps
Assumptions
Open questions
Summary
What the free reader does, before any model runs
It parses the manifest the way Chrome does
Chrome reads manifest.json as strict JSON: one comment or one trailing comma and
the extension does not load at all. Both are reported with their line, and then stripped so the
other forty checks can still run on the file you actually have.
The permission ledger, both directions
A permission nothing in your code calls is an install warning you are paying for and not
spending. A chrome.* namespace you call with no permission behind it is a
TypeError on first use. The reader lists both, from your own files.
What the install dialog will say
Not a count of permissions — the actual sentences. “Read your browsing history”
for tabs, “Read and change all your data on all websites” for a broad
host pattern. That is the screen where users abandon the install.
The eviction, replayed
A service worker is restarted for every event and killed about thirty seconds later. The reader
finds the listeners registered inside a callback (a restart never sees them), the top-level state
written after startup (gone with the worker), the timer longer than the eviction window, and the
async onMessage handler that closes the port before it replies.