Tabsmith-lint catches Chrome Web Store rejections before you submit

rsub1221 pts0 comments

GitHub - rsub122/tabsmith-lint: Pre-submission compliance linter for Manifest V3 Chrome extensions — catch Chrome Web Store rejection risks before you submit · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

rsub122

tabsmith-lint

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>1 Commit<br>1 Commit

.github/workflows

.github/workflows

corpus

corpus

fixtures

fixtures

scripts

scripts

src

src

test

test

.gitignore

.gitignore

LICENSE

LICENSE

README.md

README.md

package-lock.json

package-lock.json

package.json

package.json

tsconfig.json

tsconfig.json

vitest.config.ts

vitest.config.ts

View all files

Repository files navigation

tabsmith-lint

A pre-submission compliance linter for browser extensions. v0.1 analyzes an unpacked<br>Manifest V3 Chrome extension directory and reports likely Chrome Web Store rejection<br>risks before you submit — unused/excessive permissions, missing permissions, MV3<br>violations, and broken file references — with a clear verdict and actionable fixes.

Catch the "Purple Potassium" permission rejection before you submit. The most<br>common Chrome Web Store rejection is excessive/unused permissions — declaring tabs,<br>bookmarks, cookies, or your code never actually uses. tabsmith-lint<br>statically checks your manifest against your code and maps findings to the violations<br>Chrome reviewers flag:

Violation ID<br>What it means<br>tabsmith rules

Purple Potassium<br>Excessive / unused permissions<br>PERM001, PERM003, PERM004, PERM005

Blue Argon<br>Remotely hosted code / string execution<br>MV3001, MV3002

Yellow Magnesium<br>Functionality / broken packaging<br>FUNC001, FUNC002

npx tabsmith-lint ./my-extension<br>npx tabsmith-lint ./my-extension --format json<br>npx tabsmith-lint ./my-extension --min-severity reject

Exit codes: 0 pass · 1 needs fixes · 2 high rejection risk · 3 tool error.

No install needed — npx runs the latest published version. Or install it: npm i -g tabsmith-lint.

Develop

npm install<br>npm test # vitest: unit + e2e (one fixture per rule)<br>npm run build # tsc → dist/<br>node dist/cli.js ./my-extension

Validate against real extensions

Beyond the unit/e2e fixtures, the linter is validated on real extensions —<br>both Google's clean MV3 samples and real published, built/minified OSS<br>extensions (uBlock Origin, Dark Reader, Stylus, ...). All fetched on demand — see<br>corpus/:

npm run build # required first — the scripts use dist/<br>npm run validate # robustness: ~100 clean extensions, gate on 0 crashes<br>npm run score # accuracy: PERM001 false-positive rate vs ground truth<br>npm run validate:releases # robustness on real minified extensions<br>npm run score:releases # accuracy on the messy corpus<br>npm run demo # print reports for recognizable real extensions

npm run score gates promoting PERM001 to reject: under 5% false positives.<br>Across 28 hand-labeled extensions (22 samples + 6 minified releases): 0% false<br>positives, 0 false negatives, all verdicts matched — independently audited.<br>Building this corpus caught and fixed six real false positives (plus a<br>prototype-safety crash) the synthetic fixtures missed — see corpus/README.md. CI<br>runs the suite and all validation gates on every push (.github/workflows/ci.yml).

PERM001 accuracy gate

PERM001 (declared-but-unused permission) is the flagship rule, and its<br>false-positive rate is make-or-break — a wrong "remove this permission" suggestion<br>destroys trust. In v0.1 it ships at fix severity, never reject (the single<br>constant PERM001_SEVERITY in src/rules/permissions.ts). Promoting it to reject<br>is gated on validating under 5% false positives against a hand-labeled corpus of<br>20–30 real extensions, where the label is "permission actually used by<br>implementation" — not "extension passed review". That corpus is deferred; until it<br>exists, leave the severity at fix.

Status

v0.1. Chrome-only, directory input, 10 rules (PERM001-005, MV3001-003, FUNC001-002).

Firefox/Edge, ZIP/CRX input, SARIF, and a GitHub Action are on the roadmap.

Two rules are intentionally...

tabsmith extensions lint chrome corpus json

Related Articles