# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

秒填鸭 is a Chrome extension that uses LLM-powered semantic matching to automatically fill web forms with user-stored personal information. Data stays local (IndexedDB + chrome.storage). Works with any OpenAI-compatible API.

## Commands

```bash
npm run dev              # Start Chrome extension dev mode (HMR)
npm run dev:firefox      # Firefox dev mode
npm run build            # Production build
npm run zip              # Package as .zip for Chrome Web Store
npm run compile          # Type-check only (tsc --noEmit)
```

No test framework is configured. No linter is configured.

## Architecture

Built with **WXT** (browser extension framework on top of Vite). Convention over configuration — entrypoints auto-generate manifest entries.

### Extension Components

| Layer | File | Role |
|-------|------|------|
| Background service worker | `entrypoints/background.ts` | Message routing, orchestrates scan/fill workflow, calls LLM matching |
| Content script | `entrypoints/content.ts` | Runs on all pages; scans DOM form fields, fills matched values using native setters (React-compatible) |
| Popup | `entrypoints/popup/` | User-facing UI: scan → review matches → fill. State machine: idle → scanning → result → filling → filled |
| Options | `entrypoints/options/` | Extension-internal settings page (opened from popup) for managing personal info and API config. **No external web pages** — everything runs inside the extension. |

### Data Flow

1. User enters personal info (key-value pairs) in Options page → `utils/db.ts` (IndexedDB)
2. User configures API endpoint/key/model → `utils/storage.ts` (chrome.storage.local)
3. Popup "scan" → background messages content script → content extracts form fields with labels/placeholders/names
4. Background sends fields + user data to LLM via `utils/matcher.ts` (OpenAI-compatible `/chat/completions`)
5. LLM returns semantic matches as JSON → Popup displays for user confirmation → content script fills values

### Key Modules

- `utils/db.ts` — IndexedDB wrapper (`textFields` store for personal info, `fileRecords` store for uploaded files)
- `utils/storage.ts` — `chrome.storage.local` wrapper for `ApiConfig { baseUrl, apiKey, model }`
- `utils/matcher.ts` — Builds prompt with field clues (label, placeholder, aria-label, name, id) and user data, parses LLM JSON response into `MatchResult[]`

### Message Protocol

Components communicate via `chrome.runtime.sendMessage`:
- `startScan` (popup → background → content): scans page fields, returns matches
- `startFill` (popup → background → content): fills selected fields
- `scan` / `fill` (background → content): direct content script commands

### UI

Vanilla HTML/CSS/TS, no framework. Popup uses imperative DOM rendering with a view state machine. Primary color: `#257FFD`.

## WXT Conventions

- `entrypoints/` contains all extension entry points (background, content, popup, options)
- `utils/` for shared utilities (imported via `@/utils/`)
- `public/` for static assets (icons, etc.)
- `@` alias resolves to project root
- Use `defineBackground()`, `defineContentScript()` exports from WXT globals
- `.wxt/` directory is auto-generated by `wxt prepare` (postinstall hook)
