Skip to content

Restore four commits dropped by the squash merge of #129 - #130

Merged
forgetso merged 5 commits into
masterfrom
restore-dropped-commits
Sep 21, 2026
Merged

forgetso merged 5 commits into
masterfrom
restore-dropped-commits

Conversation

@forgetso

@forgetso forgetso commented Sep 21, 2026 •

Copy link
Copy Markdown
Owner

#129 was squash-merged at 10:56, but four commits were pushed to the branch after that point and so are not on master. This restores them unchanged.

Spotted because master still declares the tabs permission while the 2.4.0 release asset does not — the two disagree, and the asset is correct.

Recovered

commit why it matters
Package releases with the manifest at the zip root npm run release zipped ./dist, nesting everything under dist/. The Chrome Web Store rejects a zip whose manifest.json is not at the root, so the script as merged cannot produce an uploadable artifact. It now zips the contents of dist, and builds first so an artifact cannot be cut from a stale dist.
Record the Chrome Web Store permission justifications Adds docs/permission-justifications.md.
Trim the permission justifications to dashboard length Shortens them to paste into the Developer Dashboard fields.
Drop the tabs permission The important one — see below.

Why tabs has to go

It was added in the unreleased 2.1.0 and was never needed. In manifest v3 a tab's url is exposed to an extension holding the tabs permission or a host permission matching that tab, and http://*/* and https://*/* are already declared.

The published 2.0.9 build is the proof. It declares only activeTab, storage and notifications, yet its background script already reads tab.url to match saved rules:

const [n] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
... new RegExp(e.url).test(n.url || "")

and has been doing so in production.

Keeping tabs would add the "Read your browsing history" warning, which Chrome shows on update and which disables the extension until every existing user approves it. Without it, 2.4.0 adds only scripting, which carries no warning, so the update installs silently.

One consequence: the injection query now uses the host permission patterns rather than the content script's matches, which also include file:///*. Without a host permission for file URLs those tabs cannot be queried or injected, so file:// pages still need a manual reload after install or update.

Version

Bumped to 2.4.1. master was merged carrying 2.4.0 with the tabs permission still in the manifest, so that number would describe two different builds. Nothing was ever published as 2.4.0 — the release was still a draft and no tag existed — so 2.4.1 is simply what ships. The draft release has been retagged accordingly, with a rebuilt asset.

Verification

npm run checks passes: typecheck across three projects, lint, format, 614 unit tests, build. The resulting manifest.json is byte-identical to the one in the already-uploaded 2.4.0 release asset.

Worth merging before publishing the 2.4.0 draft, so the tag matches what ships.

🤖 Generated with Claude Code

forgetso and others added 5 commits September 21, 2026 11:37
The release script zipped ./dist, so every entry was nested under dist/
and the Chrome Web Store rejects an upload whose manifest.json is not at
the root. It now zips the contents of dist instead, and builds first so
an artifact cannot be cut from a stale dist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The 2.4.0 submission adds the tabs and scripting permissions, so the
store asks for a justification for each. Keeping them in the repo next to
the code they describe means they can be checked against it and reused on
the next submission.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The tabs permission was added in the unreleased 2.1.0. It is not needed:
in manifest v3 a tab's url is exposed to an extension holding either the
tabs permission or a host permission matching that tab, and this extension
already declares http://*/* and https://*/*.

The published 2.0.9 build is the proof. It declares only activeTab,
storage and notifications, yet its background script already reads
tab.url to match saved rules against the current page, and has been doing
so in production.

Keeping tabs would have added the "Read your browsing history" warning,
which Chrome shows on update and which disables the extension until the
user approves it. Relative to the live build, 2.4.0 now adds only
`scripting`, which carries no warning at all.

The injection query now uses the host permission patterns rather than the
content script's `matches`, which also include file:///*. Without a host
permission for file URLs those tabs cannot be queried or injected, so
file:// pages still need a manual reload.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
master was merged carrying 2.4.0 with the tabs permission still in the
manifest, so that version number would describe two different builds.
2.4.1 is what actually ships: no tabs permission, and a release script
that produces a zip the Chrome Web Store will accept.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@forgetso
forgetso merged commit ebdb00a into master Sep 21, 2026
5 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