Recently Written · git

sbm-extension

sbm bookmarks for Firefox and Chrome: fuzzy search, add the page, sync with bm and the sbm app

git clone https://github.com/equwal/sbm-extension

Log | Files | Refs


commit f5dbed7267a957ade84e53e921ba726cf043aabb
equwal <truex@equwal.com>
2026-09-22 19:04:14 -0700

Build a separate zip for addons.mozilla.org

The linter of addons.mozilla.org warned that Firefox ignores
background.service_worker. Chrome needs that key, so one zip cannot
satisfy both stores. npm run build:firefox now makes
sbm_bookmarks-<version>-firefox.zip from a copy whose manifest.json
leaves the key out. npm run lint checks that copy, with no warnings.

The store texts get the version notes and the notes to the reviewer
for addons.mozilla.org.

 .gitignore         |  1 +
 README.md          |  9 +++++++--
 firefox.mjs        | 17 +++++++++++++++++
 package.json       |  5 +++--
 store/listing.md   | 33 +++++++++++++++++++++++++--------
 web-ext-config.mjs |  2 ++
 6 files changed, 55 insertions(+), 12 deletions(-)
diff --git a/.gitignore b/.gitignore
index 70a1f6a..b9a5500 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 node_modules/
 web-ext-artifacts/
+build/
diff --git a/README.md b/README.md
index 8b80225..ccc9c43 100644
--- a/README.md
+++ b/README.md
@@ -56,8 +56,13 @@ The add-on needs no build: load this directory as an unpacked extension
 
     npm install
     npm test          # property tests of the file format and the search
-    npm run lint      # the checks of addons.mozilla.org
-    npm run build     # the zip for the stores, in web-ext-artifacts/
+    npm run lint      # the checks of addons.mozilla.org, on the Firefox package
+    npm run build     # the zip for the Chrome Web Store, in web-ext-artifacts/
+    npm run build:firefox  # the zip for addons.mozilla.org
+
+The two zips have the same files. Only the manifest.json of the Firefox zip
+has no `background.service_worker`: Firefox ignores it and warns about it,
+and Chrome needs it.
 
 ## License
 
diff --git a/firefox.mjs b/firefox.mjs
new file mode 100644
index 0000000..181bdc0
--- /dev/null
+++ b/firefox.mjs
@@ -0,0 +1,17 @@
+// Stages the package for addons.mozilla.org in build/firefox. Firefox
+// ignores background.service_worker, and the linter of addons.mozilla.org
+// warns about it, so the staged manifest.json leaves it out. Chrome needs
+// it, so manifest.json keeps it. "npm run build:firefox" builds the zip from
+// the staged copy.
+import { cpSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
+
+const out = "build/firefox";
+const skip = new Set(["build", "node_modules", "web-ext-artifacts", ".git"]);
+
+rmSync(out, { recursive: true, force: true });
+for (const name of readdirSync(".")) {
+  if (!skip.has(name)) cpSync(name, `${out}/${name}`, { recursive: true });
+}
+const manifest = JSON.parse(readFileSync(`${out}/manifest.json`, "utf8"));
+delete manifest.background.service_worker;
+writeFileSync(`${out}/manifest.json`, JSON.stringify(manifest, null, 2) + "\n");
diff --git a/package.json b/package.json
index ff5b4a1..fcfe65c 100644
--- a/package.json
+++ b/package.json
@@ -5,8 +5,9 @@
   "license": "AGPL-3.0-only",
   "scripts": {
     "test": "node --test test/*.test.js",
-    "lint": "npx --yes web-ext lint --self-hosted=false",
-    "build": "npx --yes web-ext build"
+    "lint": "node firefox.mjs && npx --yes web-ext lint --self-hosted=false --source-dir build/firefox",
+    "build": "npx --yes web-ext build",
+    "build:firefox": "node firefox.mjs && npx --yes web-ext build --source-dir build/firefox --filename sbm_bookmarks-{version}-firefox.zip"
   },
   "devDependencies": {
     "fast-check": "^4.3.0"
diff --git a/store/listing.md b/store/listing.md
index 0db630a..67f98b2 100644
--- a/store/listing.md
+++ b/store/listing.md
@@ -1,8 +1,12 @@
 # Store listings: Chrome Web Store and addons.mozilla.org
 
-Package: `npm run build` makes `web-ext-artifacts/sbm_bookmarks-<version>.zip`.
-Upload the same zip to both stores. It has no build step and no minified
-code, so no separate source upload is necessary.
+Packages: `npm run build` makes `web-ext-artifacts/sbm_bookmarks-<version>.zip`
+for the Chrome Web Store. `npm run build:firefox` makes
+`web-ext-artifacts/sbm_bookmarks-<version>-firefox.zip` for
+addons.mozilla.org. The two zips have the same files. Only the manifest.json
+of the Firefox zip has no `background.service_worker`, which Firefox ignores
+and warns about. Neither zip has a build step or minified code, so no
+separate source upload is necessary.
 
 The declarations are yours: read each answer before you submit it.
 
@@ -74,8 +78,21 @@ Chrome Web Store asks for them when an add-on leads to payments)
 - Data collection: the manifest declares none as required, and bookmarks,
   personally identifying information and authentication information as
   optional. Firefox asks the user at sign-in.
-- Notes to reviewer: "No build step: the zip is the source. To test sync,
-  open the options, keep the server https://sbm.subread.space and sign in
-  with the review account below." Give the account from
-  `Desktop\sbm-android-signing\play-review-account.txt` (it holds demo
-  bookmarks only).
+- Upload `sbm_bookmarks-<version>-firefox.zip`. Compatible: Firefox and
+  Firefox for Android.
+- Version notes (0.2.0): "The options page has a new section, Plan. It
+  shows the plan of your sync account and its payment options: subscribe,
+  manage billing, become a supporter, and the terms of sale. Stripe takes all
+  payments on its own pages, in a new tab. The add-on never sees your card.
+  Sync on sbm.subread.space stays free. The add-on also has fuzzy search as
+  you type (Alt+Shift+M), the address bar keyword bm, Add this page with
+  tags, and sync with bm and the sbm app for Android."
+- Notes to reviewer: "No build step: the zip is the source code of
+  https://github.com/equwal/sbm-extension at tag v0.2.0. Only manifest.json
+  is different: it has no background.service_worker, which only Chrome uses.
+  To test sync, open the options page, keep the server
+  https://sbm.subread.space, and sign in with the review account below. The
+  account holds demo bookmarks only. After the sign-in, the Plan section
+  shows "Sync is on." and the payment links of the server. Sync is free, so
+  no payment is necessary for the test." Then add the email and the password
+  from `Desktop\sbm-android-signing\play-review-account.txt`.
diff --git a/web-ext-config.mjs b/web-ext-config.mjs
index e7b0ad2..82e83f2 100644
--- a/web-ext-config.mjs
+++ b/web-ext-config.mjs
@@ -2,6 +2,8 @@
 // only, not its tests and tools.
 export default {
   ignoreFiles: [
+    "build",
+    "firefox.mjs",
     "test",
     "icons/make-icons.ps1",
     "package.json",