Skip to content

Chrome extension port (stage 3) #16

Description

@perdrizat

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)

  1. 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").
  2. 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.
  3. 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."
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions