Browser Extension
Structure
- Framework: Vue 3 + Vuetify, Pinia, vue-router (auto-generated routes).
- Build system: Vite 7 (separate bundles for popup/side panel, background, and content script).
- Scripts (see
apps/extension/package.json):dev,dev-firefox,dev:*– development server plus background/content bundles.build,build-firefox– production build (emitsapps/extension/extension/).pack:zip,pack:crx,pack:xpi– distribution artifacts.start:chromium,start:firefox–web-ext runwith built assets.
Local Build & Load
bash
pnpm --filter @source-taster/extension dev # Chromium
pnpm --filter @source-taster/extension dev-firefox- Dev mode creates
apps/extension/extension/manifest.jsonand stub HTML files for HMR. - Chrome/Edge:
chrome://extensions→ enable Developer Mode → “Load unpacked” →apps/extension/extension. - Firefox:
about:debugging#/runtime/this-firefox→ “Load Temporary Add-on” →apps/extension/extension/manifest.json.
Production Build & Packaging
bash
pnpm --filter @source-taster/extension build
pnpm --filter @source-taster/extension pack:zip # Chrome Web Store
pnpm --filter @source-taster/extension pack:xpi # Firefox Add-on (web-ext build)pack:crxproduces a locally signed CRX (testing only, not for store upload).- Version bumps happen via
pnpm --filter @source-taster/extension release(bumpp). Keep the manifest version in sync withpackage.json.
Manifest (MV3)
manifest_version: 3, icons inassets/icon*.png.- Popup (
dist/popup/index.html) and options (dist/options/index.html). - Side panel:
- Chromium:
side_panel.default_path - Firefox:
sidebar_action.default_panel
- Chromium:
- Background script:
- Chromium: service worker
dist/background/index.mjs - Firefox: module script
dist/background/index.mjs
- Chromium: service worker
- Permissions:
storage,activeTab,contextMenus, optionalsidePanel(Chromium).- Host permissions:
http://*/*,https://*/*.
- Content script:
dist/contentScripts/index.global.js, stylesdist/contentScripts/style.css. - CSP: development allows Vite HMR (
script-src self http://localhost:3303). default_locale: "en"; translations insrc/locales/en.jsonandde.json.
The manifest is generated by scripts/prepare.ts (esno scripts/manifest.ts). Adjust it for new permissions or pages.
Features & Flows
- Context menus (
background/main.ts)check-bibliography: loads the side panel and pre-fills the selected text.openSidePanel: toggles the side panel; disabled while the panel is visible.
- Side panel vs. popup: stored in
browser.storage.sync(displayOption), managed by the options UI. - WebExtension storage:
useWebExtensionStoragewrapsstorage.localwith cross-context synchronisation. - PDF import:
extractTextFromPdfFile(unpdf) parses PDFs into plain text. - Verification workflow:
useVerificationorchestrates AnyStyle conversion → search → matching with optional early termination. - Settings: Pinia store
settings(WebExtension storage) usesDEFAULT_UI_SETTINGSfrom shared types.
Communication
webext-bridgecurrently powers messaging inbackground/main.ts(e.g. side panel visibility updates).- The side panel notifies the background script with
SIDE_PANEL_OPENED/CLOSEDso context menus stay in sync.
QA & Testing
- Lint:
pnpm --filter @source-taster/extension lint - Type check:
pnpm --filter @source-taster/extension typecheck - TODO: Add automated UI tests (Cypress or Playwright).
Release Checklist
- Bump version (
pnpm --filter @source-taster/extension release). - Build production assets (
pnpm --filter @source-taster/extension build). - Generate store artifacts (
pack:zip,pack:xpi). - Upload to Chrome Web Store / AMO.
- Create a release tag (
git tag vX.Y.Z, push) so GitHub Actions runsrelease.yml.
Security & Privacy
- The extension never stores API keys locally; everything is saved via
/api/user/ai-secretson the server (encrypted). - All requests point to
VITE_API_BASE_URL(env.ts, defaulthttp://localhost:8000). - TODO: Revisit CSP and permissions whenever new providers or APIs are added.