# 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:
     ```ts
     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.
