After the AMO release (3.0.0) bakes, port NewTab PowerTools to Chrome on top of the chrome-prep program (2.5.0). References issue #15.
The chrome-prep program (see CONTRIBUTING.md "Decisions of record" and git history/CHANGELOG.md for the completed C0–C6 arcs) deliberately reduced this port to a bounded, reviewable set of changes:
What's already done (prerequisites, chrome-prep program)
- Background DOM-guard, typed monoliths, feature-module split, the
api capability seam (webextension/api.js page-side, webextension/lib/platform.js background-side — a live Proxy over globalThis.browser ?? chrome), and two-target manifest authoring (manifest/base.json + manifest/firefox.json + manifest/chrome.json, merged by scripts/build-manifest.mjs).
- Full divergence audit:
audit/2026-07-11-chrome-api-divergence.md (29 portable surfaces, 6 divergent-wrap, 4 Firefox-only). The 6 wrappers (storage.session, capture-availability, search-shape, action/theme-icons, menus presence-gate, getBrowserInfo short-circuit) are implemented and Firefox-verified, but their Chrome-side branches are written and dormant — no Chrome manifest has ever exercised them.
- Two design decisions settled up front and already encoded in the seam:
- Decision 1 (context menus): Chrome ships WITHOUT dynamic context menus — the in-tile action row (edit/never-capture/pin/remove) is the Chrome interaction.
menus registration is already presence-gated on api.menus in both lib/background-main.js and newTab.js.
- Decision 2 (theme):
prefers-color-scheme is the base theme source on both platforms; browser.theme is a Firefox-only bonus layered on top. syncActionIconWithTheme is already a Chrome-dormant no-op stub.
What's left (this issue)
- Fork the seam implementations. The
api Proxy and its 6 wrappers already branch on globalThis.browser ?? chrome; verify each Chrome branch against a real Chrome install (currently unvalidated beyond "the code compiles/typechecks").
- Write the OffscreenCanvas thumbnail-image.js.
lib/thumbnail-image.js is the one file in lib/ allowed to touch DOM/canvas (guarded by the C1 ESLint rule) — Chrome's MV3 service worker has no DOM, so the capture pipeline needs an OffscreenCanvas-based sibling implementation, selected via the same capability-seam pattern.
- Activate the Chrome manifest overlay.
manifest/chrome.json exists and pnpm build chrome already stages and zips a dormant build (dist/*-chrome.zip) — this issue is about validating it against a real Chrome install and unretiring it from "dormant."
- New test surface. Decide how Chrome gets covered by the test tiers (a second E2E/UAT target is a real design question — the current tiers are Firefox-only by design) before this ships.
Non-goals
- Long-lived Chrome branch — explicitly rejected (
CONTRIBUTING.md "Decisions of record": single-source/dual-build, not parallel branches).
- The previous maintainer's
chrome branch is historical reference only — do not merge it.
After the AMO release (3.0.0) bakes, port NewTab PowerTools to Chrome on top of the chrome-prep program (2.5.0). References issue #15.
The chrome-prep program (see
CONTRIBUTING.md"Decisions of record" and git history/CHANGELOG.mdfor the completed C0–C6 arcs) deliberately reduced this port to a bounded, reviewable set of changes:What's already done (prerequisites, chrome-prep program)
apicapability seam (webextension/api.jspage-side,webextension/lib/platform.jsbackground-side — a live Proxy overglobalThis.browser ?? chrome), and two-target manifest authoring (manifest/base.json+manifest/firefox.json+manifest/chrome.json, merged byscripts/build-manifest.mjs).audit/2026-07-11-chrome-api-divergence.md(29 portable surfaces, 6 divergent-wrap, 4 Firefox-only). The 6 wrappers (storage.session, capture-availability, search-shape, action/theme-icons, menus presence-gate, getBrowserInfo short-circuit) are implemented and Firefox-verified, but their Chrome-side branches are written and dormant — no Chrome manifest has ever exercised them.menusregistration is already presence-gated onapi.menusin bothlib/background-main.jsandnewTab.js.prefers-color-schemeis the base theme source on both platforms;browser.themeis a Firefox-only bonus layered on top.syncActionIconWithThemeis already a Chrome-dormant no-op stub.What's left (this issue)
apiProxy and its 6 wrappers already branch onglobalThis.browser ?? chrome; verify each Chrome branch against a real Chrome install (currently unvalidated beyond "the code compiles/typechecks").lib/thumbnail-image.jsis the one file inlib/allowed to touch DOM/canvas (guarded by the C1 ESLint rule) — Chrome's MV3 service worker has no DOM, so the capture pipeline needs anOffscreenCanvas-based sibling implementation, selected via the same capability-seam pattern.manifest/chrome.jsonexists andpnpm build chromealready stages and zips a dormant build (dist/*-chrome.zip) — this issue is about validating it against a real Chrome install and unretiring it from "dormant."Non-goals
CONTRIBUTING.md"Decisions of record": single-source/dual-build, not parallel branches).chromebranch is historical reference only — do not merge it.