Add cross-browser popup status handling

This commit is contained in:
Jordan Wages 2026-08-24 23:32:27 -05:00
commit 7e17470356
38 changed files with 1242 additions and 199 deletions

View file

@ -2,6 +2,19 @@
VibeGuard is a local-first browser extension that hides toxic social-media posts. Content is classified on-device; post text is never sent to a classification service.
## Features
- Local toxicity classification using Transformers.js and a quantized ONNX model.
- Configurable toxicity threshold and filtering mode: collapse posts with a Show button or hide them completely.
- Optional toxicity scores on filtered-post placeholders.
- Declarative site definitions with URL patterns, selectors, and stable identifiers.
- Built-in support for the official Mastodon web interface.
- Import and export of custom site definitions as JSON.
- Toolbar popup with current-site status, matched definition, pause/resume control, and settings access.
- Firefox Manifest V2 and Chromium Manifest V3 builds.
The content script is loaded broadly so it can support navigation and dynamically rendered pages, but it does not inspect page content until a validated site definition matches the current page. Site definitions are data, not executable user code.
## Development
```sh
@ -34,8 +47,86 @@ Preparation writes the Transformers.js-compatible files and `model-manifest.json
If the model uses generic labels such as `LABEL_0` and `LABEL_1`, pass `--toxic-index` and `--non-toxic-index` to `prepare`; the command refuses to guess an ambiguous mapping.
The first release targets Reddit, X/Twitter, and Facebook. Site selectors are isolated under `src/content/parsers/` because these sites frequently change their DOM structures.
VibeGuard injects a lightweight content script on ordinary web pages, but reads and processes content only when a validated site definition matches the page. The extension includes a definition for the official Mastodon web interface; custom definitions and overrides are managed as JSON in the options page. Definitions are declarative selectors and URL patterns, never executable code.
## Runtime architecture
Firefox uses a persistent MV2 background page and inference worker. Chromium uses an MV3 service worker as a router, an offscreen document, and a worker-backed classifier. Both builds share one bounded, prioritized inference queue and in-memory text-result cache.
The high-level processing path is:
```text
Supported page
-> validated site definition
-> generic content discovery
-> shared inference queue
-> local classifier
-> threshold and filtering mode
```
The model is loaded once by the shared inference backend for each browser context. Content scripts send normalized text to the background runtime and apply the returned score to the matching DOM element. Results are cached in memory to avoid repeating work when dynamic sites recreate elements.
## Options page
Open the extensions options page to change the threshold, filtering mode, and score display. The Site definitions section accepts a JSON object containing `customDefinitions` and `disabledDefinitionIds`. Definitions can be imported from or exported to a file, and are validated before they are saved.
The options page uses the locally bundled [Bulma CSS](https://bulma.io/) v1.0.3 stylesheet. No options-page styling or runtime dependency is loaded from a CDN.
Click the toolbar icon to open the VibeGuard popup. It reports whether the current page is supported, names the matched site definition, and provides a persistent pause/resume control for that definition. Pausing immediately stops filtering in matching open tabs and removes VibeGuards current placeholders; resuming restarts discovery without requiring a page reload.
## Browser permissions
VibeGuard requests the following permissions:
- `storage` to save settings and definition configuration.
- `tabs` to associate inference requests with browser tabs.
- `<all_urls>` host access so supported sites can be detected and filtered.
- `offscreen` in the Chromium Manifest V3 build to host the long-lived inference document.
## Model and third-party licenses
The packaged toxicity model is distributed under the Apache License 2.0. Its source revision, label mapping, sequence length, and quantization details are recorded in `public/models/toxicity/model-manifest.json`.
VibeGuard also bundles [Bulma CSS v1.0.3](https://github.com/jgthms/bulma), which is distributed under the MIT License. The projects own code is licensed under the terms in [LICENSE](LICENSE).
## Repository layout
| Path | Purpose |
| --- | --- |
| `src/content/` | Generic site discovery and DOM filtering. |
| `src/background/` | Firefox and Chromium background runtimes. |
| `src/inference/` | Worker, classifier, queue, and model metadata. |
| `src/options/` | Options-page behavior and VibeGuard-specific styling. |
| `src/shared/` | Settings, site-definition validation, types, and shared utilities. |
| `public/` | Browser manifests, options HTML, bundled CSS, and model files. |
| `tests/` | Unit tests for queues, filtering, definitions, hashing, and model metadata. |
## Testing and packaging
Run the type checker and test suite before building a package:
```sh
npm run typecheck
npm test
```
Build the browser-specific packages with:
```sh
npm run build:firefox
npm run build:chromium
```
The generated directories are `dist/firefox/` and `dist/chromium/`. Each contains the browser manifest, bundled JavaScript, the local `bulma.css` asset, and the model files required by that build. Load the generated directory as a temporary/unpacked extension during development.
To build versioned install packages for both browsers, run the shell packaging script from any directory:
```sh
./build.sh
```
The script runs both browser builds and writes `release/vibeguard-firefox-<version>.zip` and `release/vibeguard-chromium-<version>.zip`. The archives contain the generated extension files at their root and are ignored by Git.
### Logo and icons
Place the source logo at `public/logo.png`. The options page displays the generated 64 px version, and `build.sh` uses ImageMagick to generate the browser icon sizes `16`, `32`, `48`, `64`, `96`, and `128` under `icons/` in each release package. Install ImageMagick before running the packaging script; it accepts either the `magick` or `convert` command.