Files
Kordant/tasks/shieldai-unified-restructure/27-browser-extension-move.md
2026-05-25 12:23:23 -04:00

6.1 KiB

27. Browser Extension — Move to browser-ext/ and Update API Client

meta: id: shieldai-unified-restructure-27 feature: shieldai-unified-restructure priority: P1 depends_on: [shieldai-unified-restructure-23] tags: [extension, browser, api, migration]

objective:

  • Move the browser extension from packages/extension/ to browser-ext/, update its build configuration, and rewrite the API client to communicate with the unified monolith's tRPC endpoints instead of the legacy Fastify API.

deliverables:

  • browser-ext/ directory with all extension code:
    • src/background/index.ts — Service worker (MV3)
    • src/content/index.ts — Content script for phishing detection
    • src/popup/popup.html + popup.ts — Extension popup UI
    • src/options/options.html + options.ts — Options page
    • src/lib/api-client.ts — Updated API client
    • src/lib/phishing-detector.ts — Phishing detection logic (preserved)
    • src/lib/cache.ts — Request caching (preserved)
    • src/lib/settings.ts — Extension settings (preserved)
    • src/types/index.ts — TypeScript types
    • public/manifest.json — Manifest V3
    • public/icons/ — Extension icons
    • vite.config.ts — Build config
    • package.json — Dependencies
  • Updated browser-ext/src/lib/api-client.ts:
    • Communicates with https://api.shieldai.com/api/trpc (or local dev URL)
    • Uses tRPC HTTP batch link for efficient requests
    • Authenticates with API key (x-api-key header) or JWT
    • Endpoints:
      • spamshield.checkNumber — check phone number reputation
      • spamshield.classifySMS — classify SMS text
      • extension.getAuthStatus — check if user is linked
      • extension.linkDevice — link extension to user account
    • Error handling with retry logic
  • Updated browser-ext/package.json:
    • Dependencies: @trpc/client, superjson (for serialization)
    • Build scripts for Chrome/Firefox
  • Updated manifest:
    • Permissions: activeTab, storage, declarativeNetRequest, notifications
    • Host permissions: https://api.shieldai.com/*, https://*.shieldai.com/*

steps:

  1. Create browser-ext/ directory at project root.
  2. Move all files from packages/extension/ to browser-ext/:
    • git mv packages/extension/src browser-ext/src
    • git mv packages/extension/public browser-ext/public
    • git mv packages/extension/vite.config.ts browser-ext/
    • git mv packages/extension/package.json browser-ext/
    • Copy tests: cp -r packages/extension/tests browser-ext/
  3. Update browser-ext/package.json:
    • Change name to @shieldai/browser-ext
    • Update dependencies: add @trpc/client, remove legacy API client deps
    • Update build scripts
  4. Update browser-ext/src/lib/api-client.ts:
    • Remove old Fastify REST client code
    • Create tRPC proxy client:
      import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
      import type { AppRouter } from '../../../web/src/server/api/root';
      
      export const api = createTRPCProxyClient<AppRouter>({
        links: [httpBatchLink({ url: API_URL, headers: { 'x-api-key': API_KEY } })],
      });
      
    • Note: Type import from web/ may need a shared types package or copy types. For now, use a generated type file.
  5. Update background script:
    • On install: call api.extension.linkDevice with extension ID
    • On SMS received (if API available): call api.spamshield.classifySMS
    • On call received: call api.spamshield.checkNumber
    • Cache results using existing cache.ts
  6. Update popup UI:
    • Show auth status (linked/unlinked)
    • Show recent spam detections
    • Quick actions: "Check number", "Report spam"
    • Use ShieldAI theme colors (import theme tokens or hardcode for now)
  7. Update content script:
    • Preserve phishing detection logic
    • Report detected phishing to api.extension.reportPhishing
  8. Update options page:
    • Settings for API key, notification preferences
    • Link/unlink account flow
  9. Update build config:
    • vite.config.ts should output to dist/ with correct manifest
    • Add scripts for build:chrome and build:firefox if needed
  10. Test extension:
    • Load unpacked extension in Chrome
    • Verify popup renders
    • Test API calls against local dev server

steps:

  • Unit: API client creates correct tRPC requests
  • Unit: Background script caches API responses
  • Integration: Extension popup successfully calls spamshield.checkNumber
  • E2E: Install extension, link device, verify API key auth works

acceptance_criteria:

  • Extension code lives in browser-ext/ and builds successfully
  • API client uses tRPC instead of legacy REST endpoints
  • Background script handles install, SMS, and call events
  • Popup UI shows auth status and recent detections
  • Content script preserves phishing detection and reports to tRPC
  • Options page allows API key configuration and account linking
  • Extension works with both local dev and production API URLs
  • All existing tests pass after migration

validation:

  • cd browser-ext && pnpm build completes without errors
  • Load browser-ext/dist/ as unpacked extension in Chrome
  • Open popup and verify UI renders
  • Test API call by entering a phone number → verify tRPC request in Network tab
  • Run cd browser-ext && pnpm test for extension tests

notes:

  • Reference legacy: packages/extension/src/
  • The extension cannot directly import from web/ due to build isolation. Options for tRPC types:
    1. Generate a standalone type file from the web app's router and copy it to browser-ext/src/types/trpc.ts
    2. Create a shared @shieldai/types package (but we're unifying, so avoid new packages)
    3. Use any for the router type in extension (not recommended) Recommended: Option 1 — generate types as part of web build.
  • The extension's popup UI is currently plain HTML/TS. Consider using a lightweight framework (e.g., SolidJS for popup) for consistency with the web app, but this is optional.
  • For Manifest V3, service workers have limited lifetime. Ensure API calls complete before worker sleeps.
  • The declarativeNetRequest API can block requests at the network level without a persistent background script. Consider using it for known phishing domains.