Commit Graph
65 Commits
Author SHA1 Message Date
golemandClaude Opus 5.5 ef621d291c docs(license): replace the license with the Zavage Software Freeware License 1.0
The old LICENSE.txt was a stock business EULA. It allowed use only "for your
internal business purposes", banned copying and reverse engineering of code we
publish, named "Zavage Software inc." as licensor, and claimed users agreed by
installing.

The new text lets anyone use the extension free of charge, for any purpose,
and withholds republishing, forks and reuse of the code. It also covers
versions 1.0 to 1.3, which AMO shows under one shared license record. The
README, CHANGELOG and package.json follow suit.

The text went through three multi-agent review passes. The decisions behind
it and the AMO publishing steps are in
docs/superpowers/specs/2026-10-19-license-design.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 06:28:51 -06:00
zavage 5a628a77fb Merge pull request 'chore: prepare the 1.3.0 release' (#30) from chore/release-1.3.0 into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/30
2026-10-18 23:05:03 -06:00
golemandClaude Opus 5.5 8679267d53 chore: prepare the 1.3.0 release
Version 1.3.0 (manifest "1.3"): the options page rewrite adds features
without breaking changes, and addons.mozilla.org needs a version above
the live 1.2. The lockfile's root version moves with it. Unreleased
becomes the 1.3.0 section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 23:01:51 -06:00
golem ff61aff5b9 feat: rewrite the options page for first-time users (#23)
Rewrites the options page for first-time users without removing any setting. Customization in a lightweight package is what sets this extension apart. Design: `docs/superpowers/specs/2026-10-18-options-page-for-first-time-users-design.md`.

**User-visible changes**
- **Layout:** the description stays as the first line, followed by a **Usage instructions** section and the **Settings** section. Each section has a heading and a divider.
- **Usage instructions:** one labelled line per way to open ChatGPT, each with a small drawing:
  - **Address bar:** `<Ctrl>+L`, then `gpt`, a space and the question. The drawing shows a ChatGPT label because the address-bar code shipped in Firefox 157.0.1 enters search mode when an engine keyword is followed by a space. I checked that in its `omni.ja`, but it still needs confirming on screen; see the checks below.
  - **Right-click:** a drawing of the menu with Ask ChatGPT highlighted.
  - **Keyboard:** key caps for the user's actual shortcut, held down. The line is hidden when no shortcut is set.
  - **Toolbar:** the hovered button with the pointer, its tooltip, the puzzle-piece Extensions button, and a selected heading.
- **Drawings:** they are HTML/CSS and inline SVG, not screenshots, so they follow light and dark themes, stay sharp, and never go stale. They are centred. The package grows from 52.8 KB to 56.5 KB.
- **Settings:**
  - **Right-click menu** (was "Context menu") and **Open ChatGPT in** stay visible.
  - Choosing **Advanced** reveals a drawing of the Ask ChatGPT submenu (Ask normally, Explain, Summarize, Debug code). It lives in the block that only shows for Advanced, so it needs no script.
  - Prompt template, temporary chat and web search move under **More options**, whose heading names them. It opens by itself on load, or when a sync changes one of them, if one of them isn't at its default.
  - **Restore defaults** is right-aligned and red.
- **Bottom of the page:**
  - The keyword/default-engine and keyboard-shortcut notes become collapsed sections with numbered steps.
  - The project links are centred, and stack on narrow panels.
- **Hotkeys:** written as `<Ctrl>+L` and `<Alt>+<Shift>+G`, including the user's actual shortcut. Mac users see `<Cmd>`, `<Option>` and `<Return>`, detected with `runtime.getPlatformInfo`, which needs no permission.
- **Docs:**
  - Keyword wording is corrected in the options page and README: Firefox adds a custom keyword alongside `gpt` instead of replacing it.
  - README and AGENTS.md use the new setting names.
  - AGENTS.md records the keep-every-setting rule, the hotkey format and the "filled in, never sent" copy rule.

These still match the original options design spec: the temporary-chat and web-search wording, and the rule that copy never says the question is sent.

No permission, search URL, privacy or packaging changes.

**Checks**
- `npm test`: lint 0 errors / 0 warnings, 61/61 unit tests, build OK.
- New tests:
  - the key formatter, including the Mac names Firefox stores (Command, MacCtrl, Alt)
  - the page's written hotkeys match the formatter
  - the keyboard drawing's key caps follow the live shortcut
- Rendered in headless Firefox 157 with the extension APIs stubbed:
  - light and dark themes
  - 680 px and 360 px wide
  - Mac key names
  - More options opening for a customised prompt template
  - both bottom sections expanded

**Manual Firefox checks (`npm run dev` → about:addons → Preferences)**
- [x] Typing `gpt` and a space shows a ChatGPT label in the address bar, as drawn. If it doesn't, the drawing drops the label and shows plain `gpt how do magnets work?`
- [x] Light and dark themes, and a narrow about:addons width
- [x] Expanding More options and the two bottom sections grows the inline panel without clipping or scrolling
- [x] The Keyboard line and its key caps disappear when the shortcut is removed, and come back showing the new keys when one is set
- [x] More options opens by itself after changing the prompt template and reopening the page
- [x] Choosing Advanced shows the submenu drawing; Simple and Off hide it
- [x] Settings still save, and Restore defaults still works

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/23
Co-authored-by: golem <golem@zavage.net>
2026-10-18 22:53:27 -06:00
zavage f022f5e20d Merge pull request 'fix: use the bundled search engine icon' (#22) from fix/20-search-provider-downloads-its-icon-from into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/22
2026-10-18 11:06:57 -06:00
golemandClaude Opus 5.5 1866846d3b doc: shorten the bundled icon changelog entry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:00:09 -06:00
golemandClaude Opus 5.5 82fdf88b80 fix: use the bundled search engine icon
The search provider's favicon_url pointed at zavage-software.com, so Firefox
downloaded the icon from our server whenever it installed or updated the
engine. That contradicted the privacy policy's "Nothing is reported to Zavage
Software", would break if the site moved, and blocks a future MV3 move, which
requires a packaged favicon.

Without favicon_url, Firefox uses the manifest icons instead
(AddonSearchEngine#initFromManifest). The remote file was byte-identical to
icons/powered-by-openai-icon-48x48.png, so the artwork is unchanged.

Closes #20

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:58:16 -06:00
zavage 3f4b64374b Merge pull request 'chore: prepare the 1.2.0 release' (#13) from chore/release-1.2.0 into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/13
2026-10-18 02:52:32 -06:00
golem cf5e397d53 Merge remote-tracking branch 'origin/develop' into chore/release-1.2.0 2026-10-18 02:36:50 -06:00
golemandClaude Opus 5.5 8052c87c23 chore: prepare the 1.2.0 release
Version 1.2.0 (manifest "1.2"): the release adds features without
breaking changes, and 1.1.0 already exists in the changelog. The
lockfile's root version, still 1.0.0, moves with it.

Turn Unreleased into the 1.2.0 section, fold in the unheaded bullets
beneath it, add the template-limit entry, note that 1.1.0 never reached
addons.mozilla.org, and fix the stray ")" in the 1.0.0 heading. The
manifest description now covers the menu, toolbar button and shortcut.

Record in the design spec that ChatGPT auto-submits ?q= prompts again as
of 2026-10-18, and what that means for Appendix B's selection-smuggling
argument.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:27:54 -06:00
zavage 9f8a295a4f Merge pull request 'fix: limit the prompt template to 1,000 characters' (#12) from fix/template-length-limit into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/12
2026-10-18 02:26:43 -06:00
zavage 5a12663c92 Merge pull request 'refactor: remove the unused URL shortener' (#11) from refactor/remove-unused-shortener into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/11
2026-10-18 02:26:37 -06:00
zavage 384eca7589 Merge pull request 'ci: add a WIP-title gate to extension CI' (#10) from ci/8-wip-gate into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/10
2026-10-18 02:25:53 -06:00
zavage d96277ebd9 Merge pull request 'fix: cap huge selections before shortening' (#9) from fix/long-selection-cap into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/9
2026-10-18 02:25:44 -06:00
golemandClaude Opus 5.5 269e721fe8 fix: limit the prompt template to 1,000 characters
storage.sync rejects any item over 8192 bytes, and the options page
writes every field in one set(). An oversized template therefore made
every later save fail, including changes to unrelated settings, with
only a brief "Could not save settings".

Cap the template at 1,000 UTF-16 units: maxlength on the input, and
mergeSettings falls back to the default for a longer stored value, as it
does for other out-of-range settings. Even a template of pasted control
characters (six bytes each once JSON-escaped) stays under the quota; a
test pins that arithmetic and another ties the HTML maxlength to the
constant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:23:03 -06:00
golemandClaude Opus 5.5 cc68fe98b5 refactor: remove the unused URL shortener
buildChatGptUrl and its fitToBudget helpers have had no production
caller since prepareAction took over routing; the 2026-10-05 plan kept
them only for existing tests until then. They also shortened silently,
against the ask-before-shortening rule, so they were a trap to reuse.

Port the tests that guard live code onto applyTemplate and
serializePrompt, including the $&, $`, $' and $$ regressions (checked to
fail against the string-replacement form), and cover prepareAction's
whole-word cut, which nothing tested before.

Also drop getContext's inputType password check. menus.OnClickData has
no inputType, so it never fired; Firefox already withholds password
fields from selectionText via mozIsTextField(true) in SelectionUtils
(bug 565717).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:13:06 -06:00
golemandClaude Opus 5.5 39a3ac74f4 ci: use the github context for the WIP gate
Gitea treats github.* as an alias for gitea.*. The pattern was canaried
in this form, and pr-flow only detects a gate written this way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:09:04 -06:00
golemandClaude Opus 5.5 cb7da3a538 ci: add a WIP-title gate to extension CI
Every push to an open PR ran the full validate job, and pull_request
lacked the edited type, so removing WIP: would not start a run. pr-flow
therefore refused to open PRs early.

Skip validate on PRs titled WIP: or [WIP], add edited so un-WIP starts
the run, add workflow_dispatch for on-demand runs, and cancel superseded
PR runs (never push runs, since main's push uploads the package). The
workflow name and job id are unchanged, so the required check context
stays "Firefox Extension CI / validate (pull_request)".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:08:12 -06:00
golemandClaude Opus 5.5 519131c21f fix: cap huge selections before shortening
The shortcut and toolbar read window.getSelection() without a limit, so a
select-all on a very large page handed prepareAction millions of
characters. Every binary-search probe re-encoded the whole candidate
prefix: about 1.1 s for 5M characters, paid again by the dialog.

Each code point adds at least one character to the URL, so nothing past
the first MAX_URL_CHARS can fit. Cap there before any encoding. A capped
source never takes the ready path: renderPrompt trims, so a prefix of
mostly whitespace could fit and silently drop the rest without consent.

Output is unchanged: 2,000 random cases matched develop exactly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 01:32:22 -06:00
zavage 99bb58f7b7 Merge pull request 'doc: surface the sign-in and send hint' (#7) from doc/signin-send-hint into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/7
2026-10-12 22:38:45 -06:00
golemandClaude Opus 5.5 282eeab83d doc: surface the sign-in and send hint
ChatGPT can require signing in, and it does not always send a prefilled
prompt. The README and options panel mentioned pressing Enter only in
passing. Give both a prominent note covering sign-in and Enter or Send,
and drop the inline mentions it replaces.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 22:29:55 -06:00
zavage ce9522b2d2 Merge pull request 'build: add Serena project config' (#6) from build/serena-project-config into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/6
2026-10-12 18:47:12 -06:00
golemandClaude Opus 5.5 10e0b24f18 build: add Serena project config
Track the Serena project config so every checkout and VM shares it.
Serena's own .serena/.gitignore keeps the cache and project.local.yml
untracked. ignored_paths skips .worktrees/** so the symbol index does
not pick up duplicate copies of the tree from in-repo worktrees.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 13:46:09 -06:00
zavage bd23a83760 Merge pull request 'feat: add Ask ChatGPT toolbar action' (#5) from feat/toolbar-action into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/5
2026-10-12 12:52:49 -06:00
golem 78e94640e1 feat: add Ask ChatGPT toolbar action 2026-10-12 12:51:24 -06:00
zavage 5bc670b937 Merge pull request 'Feat/extension options panel' (#4) from feat/extension-options-panel into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/4
2026-10-05 21:10:04 -06:00
golem 833db7b6dc Merge remote-tracking branch 'origin/feat/extension-options-panel' into feat/extension-options-panel 2026-10-05 15:38:16 -06:00
golem 5308932bf1 feat: add advanced context actions and optional translation 2026-10-05 15:38:16 -06:00
golem 33c4dad00f doc: specify advanced context menu design 2026-10-05 00:19:54 -06:00
zavage 496c2c3ea4 Merge branch 'develop' into feat/extension-options-panel 2026-09-07 21:59:14 -06:00
golem 17bccc1ade fix: derive the model maxlength and document the frame-focus cases
maxlength was hard-coded to 200 in the markup while MAX_MODEL_CHARS lives
in lib/defaults.js; lowering the constant would have left the input
accepting values mergeSettings() silently discards. It is now set from the
constant at render time.

Also records the hasFocus() gate's four manual frame cases in AGENTS.md,
including the findbar trade-off, and notes that fitToBudget()'s budget
guarantee assumes mergeSettings-validated input.
2026-08-01 23:21:45 -06:00
golem 8fcc93c541 doc: record the $-pattern and frame-focus corrections
The spec prescribed replaceAll's string form and the plan hard-coded it,
so the $-substitution defect originated in the design documents rather
than in execution. Both now specify the function replacer.

Also replaces the spec's frame-reporting idea with the document.hasFocus()
gate that shipped; frame provenance was only ever needed for auto-submit,
which Appendix B rejects.
2026-08-01 23:17:23 -06:00
golem 51bf4d5c01 fix: prefer the focused frame, bound model length, drop dead flag 2026-08-01 23:15:46 -06:00
golem d7821e3dc7 fix: stop $ sequences in selected text corrupting the prompt 2026-08-01 23:15:39 -06:00
golem 1106f4e315 doc: correct the README npm test description 2026-08-01 23:00:23 -06:00
golemandClaude Opus 5 dc5bd8e00d doc: document options panel, entry points, and the ChatGPT prefill limitation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 22:53:26 -06:00
golem 5548216645 doc: sync plan options-panel code with the shipped fixes
Records the doctype, the render() activeElement guard, and the blur in the
Restore handler. storage.onChanged fires for this page's own writes, so
every autosave re-entered the listener and could overwrite in-progress
typing; the guard closes that.
2026-08-01 22:51:15 -06:00
golem 5e56503244 fix: add doctype and stop self-echoed saves overwriting active edits 2026-08-01 22:47:20 -06:00
golem b42b11755c feat: add options panel embedded in about:addons 2026-08-01 22:35:17 -06:00
golem 6bedd700e8 doc: record the omitted strict_min_version and rejection guards
The plan pinned strict_min_version to 112.0 for the ES-module background
floor, but the existing data_collection_permissions key requires Firefox
140 desktop / 142 Android, so addons-linter warned and warningsAsErrors
failed 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.
Omitting excludes nobody and degrades gracefully below 112.

Also syncs the plan's background.js block with the rejection guards added
in 22fc754, and reworks two of those comments for clarity.
2026-08-01 22:33:29 -06:00
golem 22fc754636 fix: swallow rejections on the tab-open and menu-registration paths 2026-08-01 22:30:37 -06:00
golem f683f2e841 feat: add context menu and keyboard shortcut entry points 2026-08-01 22:21:06 -06:00
golem 5365ec881e feat: add pure ChatGPT URL builder with unit tests 2026-08-01 22:04:31 -06:00
golem c49f6415af feat: add settings defaults and validation with unit tests 2026-08-01 21:59:47 -06:00
golemandClaude Opus 5 b59648d900 doc: add implementation plan for the options panel
Five tasks, each ending in an independently testable deliverable: tooling
plus settings validation, the pure URL builder, manifest and background
wiring, the options panel, then docs and release metadata.

Complete code for every file, 27 unit tests written out in full, and exact
commands with expected output. Global Constraints carries the spec's
verified values verbatim -- the exact permission set, strict_min_version
112.0, MAX_URL_CHARS 8000, and the copy rules that keep user-facing text
honest about ChatGPT only prefilling.

Records the traps verification found so an implementer cannot walk into
them: executeScript resolving silently to [null] on parent-process about:
pages, commands.getAll() reporting a shortcut registered when Firefox has
overridden it, and node --test exiting 0 with zero tests discovered.

Closes with an out-of-scope list so a well-meaning implementer does not
re-add auto-submit or omnibox, and a pre-PR reminder about the open AMO
data-collection question.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 08:00:35 -06:00
golemandClaude Opus 5 3d5ce6a9f4 doc: revise options spec after empirical verification
Two verification passes, driving real Firefox 153.0.1 under Xvfb rather than
reading docs, changed several load-bearing decisions.

Added back: the keyboard shortcut now acts on selected text. activeTab adds
no install-prompt line (confirmed by running Firefox's own
formatPermissionStrings: ["activeTab","storage","menus"] yields msgs: []),
and ext-commands.js grants activeTab before firing onCommand. Records the
three failure shapes of executeScript, one of which resolves silently to
[null] on parent-process about: pages, and that commands.getAll() reports a
suggested_key as registered even when Firefox has silently overridden it.

Rejected with evidence, in Appendix B: auto-submitting the prompt. The
scheme authenticated navigation provenance when auto-submit needs text
provenance, and a hostile page can smuggle ~16 KB of invisible instructions
into info.selectionText. webNavigation.transitionType is not a security
boundary either -- the marker is consumed on commit, so an uncommitted
urlbar navigation leaves it armed for the next navigation to inherit
(demonstrated at 10.47s), and its freshness guard is dead code. Prefill-only
keeps the human checkpoint that makes the context menu safe.

Also rejected: a bundled extension page as search_url (Firefox refuses to
install), and browser.omnibox -- which works and needs no permissions, but
moves the transmitter of search terms from Firefox to extension code, the
change that puts data_collection_permissions ["none"] at risk. Declined to
minimise AMO exposure.

New Risk 6 records the residual AMO question and that it should be asked
before submission, since a forced searchTerms declaration would add the
install line this design exists to avoid.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 07:51:43 -06:00
zavage a005b642ca Merge pull request 'build: add CLAUDE.md pointing at AGENTS.md' (#3) from build/add-claude-code-guidance into develop
Firefox Extension CI / validate (push) Canceled after 0s
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/3
2026-07-29 22:38:50 -06:00
golemandClaude Opus 5 f057c66155 doc: add extension options panel design spec
Design for an options panel reachable from about:addons, configuring a
context-menu entry on selected text and an Alt+Shift+G shortcut. Adds
storage and menus permissions only, both in Firefox's no-prompt class, so
the install dialog gains no lines and data_collection_permissions stays
"none". The gpt <query> search provider is deliberately untouched.

Technical claims were verified rather than assumed: MV2 background
type:"module" works from Firefox 112 (tested in 153.0.1), so no background
HTML shim is needed; package.json needs "type":"module" or node --test
fails on Node 22.0-22.6; the ChatGPT model/hints/temporary-chat params are
undocumented and unreliable, so every label is written at hint strength.
q= no longer auto-submits, only prefills.

Also excludes docs/ and test/ from the packaged ZIP. Verified: without
this the spec doc itself shipped inside the extension, and a bare glob
alone leaves empty directory entries behind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 20:35:25 -06:00
golemandClaude Opus 5 fb5b7c5539 build: add CLAUDE.md pointing at AGENTS.md
Claude Code reads CLAUDE.md by convention. Rather than duplicate the
contributor guidance already in AGENTS.md, this is a thin pointer so
there is a single source of truth and no drift between the two.

Because web-ext-config.mjs uses sourceDir "." and packages by exclusion,
CLAUDE.md is added to ignoreFiles alongside AGENTS.md and README.md so it
is not shipped inside the extension ZIP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 19:03:15 -06:00
zavage 5edb288681 Merge pull request 'GPT-2: add Firefox development foundation' (#2) from build/firefox-development-foundation into develop
Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/2
2026-07-29 16:18:17 -06:00