diff --git a/background/background.js b/background/background.js index 575b88a..8d473a4 100644 --- a/background/background.js +++ b/background/background.js @@ -67,8 +67,9 @@ async function openChatGpt(query) { await browser.tabs.create({ url, active: settings.openIn !== "background-tab" }); } catch { - // Silence rejections silently — the user expects either a tab to open or - // nothing, not an error log. Every failure path must degrade gracefully. + // Nothing useful to say and nowhere useful to say it: the user expects a + // tab or nothing at all. Both call sites invoke this without awaiting, so + // without this catch a failure would log an unhandled rejection. } } @@ -102,6 +103,7 @@ if (browser.commands) { } registerMenu().catch(() => { - // Silence rejections from menus.removeAll() — it cannot prevent menu creation - // on retry, so degrade gracefully with no unhandled rejection logged. + // menus.removeAll() is promise-based and can reject; a failed re-registration + // cannot be retried usefully from here. (menus.create() is callback-based and + // cannot reject, so it needs no guard.) }); diff --git a/docs/superpowers/plans/2026-07-30-extension-options-panel.md b/docs/superpowers/plans/2026-07-30-extension-options-panel.md index b3673f7..3881717 100644 --- a/docs/superpowers/plans/2026-07-30-extension-options-panel.md +++ b/docs/superpowers/plans/2026-07-30-extension-options-panel.md @@ -20,7 +20,13 @@ Every task's requirements implicitly include this section. Values are copied ver - **Manifest stays V2.** Do not migrate to MV3. Keep the code MV3-portable: ES-module background, `persistent: false`, never `browser_style: true`. - **Permissions are exactly `["storage", "menus", "activeTab"]`.** Do not add host permissions, `optional_permissions`, `tabs`, `webNavigation`, `notifications`, or `contentScripts`. All three chosen permissions add no install-prompt line; `tabs` and `notifications` do. - **Never read `tab.url`, `tab.title`, or `tab.favIconUrl`.** Reading them requires the `tabs` permission. Only `tab.id` may be read. -- **`strict_min_version` is `"112.0"`.** +- **`strict_min_version` is omitted.** Corrected during execution: the plan + originally pinned `"112.0"` (the ES-module background floor), but the existing + `data_collection_permissions` key requires Firefox 140 / Android 142, so + `addons-linter` warns on any lower value and `warningsAsErrors: true` fails the + build. Measured: `112.0` → 2 warnings, `140.0` → 1, `142.0` → clean, omitted → + clean. `142.0` was rejected because it locks out ESR 140. Below Firefox 112 the + `gpt` keyword still works and only the two new entry points are inert. - **No new runtime or dev dependencies.** `node:test` is built in. - **`lint.warningsAsErrors: true`** — a single addons-linter warning fails the build. `npx web-ext lint` must stay at 0 errors / 0 warnings / 0 notices. - **Two-space indentation** in JSON, YAML, and JavaScript. Lowercase, hyphenated filenames. @@ -48,7 +54,7 @@ Every task's requirements implicitly include this section. Values are copied ver | `options/options.js` | **Create.** Renders settings, debounced auto-save, live re-sync on `storage.onChanged`. | | `test/build-url.test.js` | **Create.** Unit tests for the URL builder. | | `test/settings.test.js` | **Create.** Unit tests for `mergeSettings`. | -| `manifest.json` | **Modify.** Add `permissions`, `background`, `options_ui`, `commands`, `strict_min_version`; bump version. | +| `manifest.json` | **Modify.** Add `permissions`, `background`, `options_ui`, `commands`; bump version. | | `package.json` | **Modify.** Add `"type": "module"`, a `test:unit` script; bump version. | | `README.md` | **Modify.** Options section, the double-Enter limitation, revised privacy wording. | | `AGENTS.md` | **Modify.** Project structure, commands, manual test checklist. | @@ -614,7 +620,6 @@ Replace the whole file. `browser_style: false` is set **explicitly** — omittin "browser_specific_settings": { "gecko": { "id": "{24644f0c-bfcb-4ebd-a16b-bc8a7d154288}", - "strict_min_version": "112.0", "data_collection_permissions": { "required": [ "none" @@ -718,20 +723,30 @@ async function readSelection() { return ""; } +// Corrected during execution: the whole body is wrapped, because both call +// sites invoke this without awaiting. Without the outer catch a rejection from +// the final tabs.create surfaces as an unhandled promise rejection, which the +// "degrade silently" constraint above forbids. The inner catch stays nested so +// a windows.create failure still falls through to a tab. async function openChatGpt(query) { - const settings = await load(); - const url = buildChatGptUrl(settings, query); + try { + const settings = await load(); + const url = buildChatGptUrl(settings, query); - if (settings.openIn === "new-window") { - try { - await browser.windows.create({ url }); - return; - } catch { - // Fall through to a tab rather than doing nothing. + if (settings.openIn === "new-window") { + try { + await browser.windows.create({ url }); + return; + } catch { + // Fall through to a tab rather than doing nothing. + } } - } - await browser.tabs.create({ url, active: settings.openIn !== "background-tab" }); + await browser.tabs.create({ url, active: settings.openIn !== "background-tab" }); + } catch { + // Nothing useful to say and nowhere useful to say it: the user expects a + // tab or nothing at all. + } } // removeAll() first, so a background event page waking up and re-running this @@ -763,7 +778,12 @@ if (browser.commands) { }); } -registerMenu(); +// Corrected during execution: menus.removeAll() is promise-based in Firefox, so +// an unguarded call here can log an unhandled rejection. (menus.create() is +// callback-based and cannot reject.) +registerMenu().catch(() => { + // A failed re-registration cannot be retried usefully from here. +}); ``` - [ ] **Step 3: Verify lint and packaging still pass** diff --git a/docs/superpowers/specs/2026-07-29-extension-options-design.md b/docs/superpowers/specs/2026-07-29-extension-options-design.md index d9e8c64..4ffcfc4 100644 --- a/docs/superpowers/specs/2026-07-29-extension-options-design.md +++ b/docs/superpowers/specs/2026-07-29-extension-options-design.md @@ -115,9 +115,21 @@ ES modules work in an MV2 background script via needed. The options page is a normal extension page and can use `