Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ab7eb74
Use Chrome Profile Email
manuelgruber Apr 6, 2026
b54b008
Show detected Email address
manuelgruber Apr 7, 2026
969c03b
Add Plus-Addressing Mode
manuelgruber Apr 7, 2026
1846a8f
Add Email Provider Awareness
manuelgruber Apr 7, 2026
05fbb46
Unify status bar
manuelgruber Apr 7, 2026
49e27bb
Update bunfig.toml
manuelgruber Apr 7, 2026
e8da985
Restructure files
manuelgruber Apr 7, 2026
fb0b1c7
Add more Email Providers
manuelgruber Apr 7, 2026
dece70c
Add Regional Email Providers
manuelgruber Apr 7, 2026
76b12b6
Add Popup
manuelgruber Apr 7, 2026
dc88264
Create UI folder
manuelgruber Apr 7, 2026
56b83bf
Add History
manuelgruber Apr 7, 2026
5f322b4
Enhance Provider List
manuelgruber Apr 7, 2026
02ac4b9
Refactor GA Workflows
manuelgruber Apr 7, 2026
9ebfa11
Set GA Workflows to Manual
manuelgruber Apr 7, 2026
5518e9a
Update Options UI
manuelgruber Apr 7, 2026
c608c19
Setup MX Record Lookup for Email Provider Detection with Custom Domains
manuelgruber Apr 7, 2026
b018d5d
Reorganize src
manuelgruber Apr 8, 2026
99be4f7
Restructure TS
manuelgruber Apr 8, 2026
81367af
Update Icon
manuelgruber Apr 8, 2026
1ef5963
Add Detection Boxes
manuelgruber Apr 8, 2026
4a1cb57
Add support page for Catch-All
manuelgruber Apr 8, 2026
b73900e
Fix GitHub PR comments
manuelgruber Apr 8, 2026
65ca9e5
Enable Provider Detection for Domain-Only Input
manuelgruber Apr 8, 2026
4ce8e93
Implement Default Settings for First-Time Users
manuelgruber Apr 8, 2026
650874c
Add more Provider Icons
manuelgruber Apr 8, 2026
b7927b5
Redesign Settings
manuelgruber Apr 8, 2026
f84d40f
Add Store Content
manuelgruber Apr 8, 2026
e4f2374
Improve Settings page
manuelgruber Apr 8, 2026
17cc41f
Update Texts
manuelgruber Apr 8, 2026
4371692
Fix Error UI
manuelgruber Apr 12, 2026
eaf5551
Change bun commands
manuelgruber Apr 12, 2026
7c3bb04
Add Screenshots
manuelgruber Apr 13, 2026
f9e176f
Modify Screenshots
manuelgruber Apr 13, 2026
9dcaf43
Update bun
manuelgruber Apr 13, 2026
d82e7f9
Fix paths
manuelgruber Apr 13, 2026
c8c98c2
Strip query params from stored history URLs and skip malformed MX rec…
manuelgruber Apr 13, 2026
90e3289
Replace Screenshots
manuelgruber Apr 13, 2026
e7b8456
Update Store Listing
manuelgruber Apr 13, 2026
d0b17b5
Disable Catch-All Mode for Known Personal Email Providers
manuelgruber Apr 13, 2026
41ccda3
Optimize Mode Detection
manuelgruber Apr 13, 2026
e5a9025
Optimize Mode Detection
manuelgruber Apr 13, 2026
d5ffd5b
Update Bun
manuelgruber Apr 13, 2026
aa79e55
Fix Notification messages
manuelgruber Apr 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 73 additions & 32 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ Clean-Autofill is a Chrome extension that automatically generates email addresse
# Build extension (compile TypeScript + copy assets to dist/)
bun run build

# Run tests (119 tests with DOM support)
bun test src/
# Run tests (251 tests with DOM support)
bun run test

# Run tests in watch mode
bun run test:watch
Expand Down Expand Up @@ -49,14 +49,15 @@ bun run bump:major # 0.1.0 → 1.0.0

The extension follows Chrome Extension Manifest V3 architecture with three main components:

### 1. Service Worker (`src/background.ts`)
- Handles extension icon clicks via `chrome.action.onClicked`
### 1. Service Worker (`src/extension/background.ts`)
- Handles messages from popup via `chrome.runtime.onMessage`
- Generates email addresses using domain extraction logic in `generateEmailForTab()`
- Sends fill requests to content script and returns results to popup
- Saves generated emails to history via `src/ui/history.ts`
- Manages Chrome storage API for user settings
- Shows notifications for success/error states
- Opens options page on first install

### 2. Content Script (`src/content.ts`)
### 2. Autofill Script (`src/extension/autofill.ts`)
- Injected into all web pages (`<all_urls>`)
- Receives messages from service worker to fill email fields
- Smart field detection with priority order:
Expand All @@ -65,59 +66,99 @@ The extension follows Chrome Extension Manifest V3 architecture with three main
3. General text input fields
- Handles React/framework compatibility with native input events

### 3. Options Page (`src/options.html` + `src/options.ts`)
- Settings interface for configuring user's email domain
- Uses Chrome sync storage for cross-device settings

### 4. Shared Utilities (`src/utils.ts`)
### 3. Popup (`src/ui/popup.html` + `src/ui/popup.ts`)
- Opens on extension icon click
- Triggers email generation and autofill via message to background
- Displays the generated email with a Copy button
- Shows config prompt if email domain not set

### 4. Options Page (`src/ui/options.html` + `src/ui/options.ts`)
- Sidebar navigation with three pages: Home, Settings, History
- **Home**: Extension explanation and usage examples
- **Settings**: Email domain configuration, mode selection, Chrome profile import
- **History**: Searchable log of all generated emails with copy/delete actions
- Settings use Chrome sync storage; history uses Chrome local storage

### 5. History Module (`src/ui/history.ts`)
- CRUD operations for email history entries stored in `chrome.storage.local`
- `addEntry()` - Save new entry (prepend, enforce 10K limit)
- `getHistory()` - Query with optional search filter and pagination
- `deleteEntry()` / `clearHistory()` - Deletion

### 6. Shared Utilities (`src/email/utils.ts`)
- `extractMainDomain()` - Removes subdomains and handles special TLDs (.co.uk, .com.au, etc.)
- `isValidEmail()` - Basic email format validation
- `createTimeout()` - Promise-based timeout for async operations
- `debounce()` - Rate-limiting for input events

### 7. Provider Detection (`src/email/`)
- **`providers.ts`** - `getProviderStatus()` / `getProviderStatusWithMx()` for determining plus-addressing support
- **`provider-domains.ts`** - Static data: 500+ email domains categorized as plus-supported or unsupported
- **`mx-lookup.ts`** - DNS MX record lookup via Google DNS API with memory + storage caching

## File Structure

```
├── manifest.json # Extension configuration (MV3) - paths relative to dist/
├── package.json # NPM/Bun configuration
├── bunfig.toml # Bun test configuration (DOM support)
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI pipeline
├── toolkit/
│ ├── biome/
│ │ └── biome.json # Biome linter/formatter config
│ ├── bun/
│ │ └── bunfig.toml # Bun test configuration (DOM support)
│ ├── typescript/
│ │ └── tsconfig.json # TypeScript configuration
│ ├── husky/
│ │ └── pre-commit # Pre-commit hook (typecheck, lint, test)
│ ├── test/
│ │ └── test-setup.ts # DOM test setup (happy-dom)
│ └── scripts/ # Build scripts
│ ├── build.js # Compiles TS + copies assets to dist/
│ ├── pack.js # Creates distribution zip
│ ├── validate.js # Manifest validation
│ └── bump-version.js # Version management
├── src/ # TypeScript source (edit these)
│ ├── background.ts # Service worker
│ ├── background.test.ts # Service worker tests
│ ├── content.ts # Content script for email filling
│ ├── content.test.ts # Content script tests
│ ├── options.ts # Options page logic
│ ├── options.test.ts # Options page tests
│ ├── options.html # Options page UI
│ ├── utils.ts # Shared utilities
│ ├── utils.test.ts # Utility tests
│ ├── test-setup.ts # DOM test setup (happy-dom)
│ ├── extension/ # Chrome extension entry points
│ │ ├── background.ts # Service worker
│ │ ├── background.test.ts
│ │ ├── autofill.ts # Content script for email filling
│ │ └── autofill.test.ts
│ ├── email/ # Email/domain logic + utilities
│ │ ├── catch-all-instructions.ts # Provider-specific catch-all setup guides
│ │ ├── catch-all-instructions.test.ts
│ │ ├── providers.ts # Provider status functions
│ │ ├── providers.test.ts
│ │ ├── mx-lookup.ts # MX record DNS lookup + caching
│ │ ├── mx-lookup.test.ts
│ │ ├── provider-domains.ts # Static domain sets
│ │ ├── provider-domains.test.ts
│ │ ├── utils.ts # Shared utilities (domain extraction, validation)
│ │ └── utils.test.ts
│ ├── types/
│ │ └── index.ts # TypeScript type definitions
│ ├── ui/ # UI pages + data
│ │ ├── popup.html # Popup UI
│ │ ├── popup.ts # Popup logic
│ │ ├── popup.test.ts
│ │ ├── options.html # Options page UI (sidebar: Home, Settings, History)
│ │ ├── options.css # Options page styles
│ │ ├── options.ts # Options page logic
│ │ ├── options.test.ts
│ │ ├── options-preview.ts # Live email preview for options page
│ │ ├── options-preview.test.ts
│ │ ├── history.ts # Email history storage module
│ │ ├── history.test.ts
│ │ └── message-tokens.css # Shared CSS tokens for messages
│ └── icons/ # Extension icons (16, 32, 48, 128px)
└── dist/ # Build output (load this in Chrome)
├── background.js # Compiled service worker
├── content.js # Compiled content script
├── options.js # Compiled options page
├── utils.js # Compiled utilities
├── options.html # Copied from src/
├── manifest.json # Copied from root
├── extension/ # Compiled extension entry points
├── email/ # Compiled email/domain modules
├── ui/ # Compiled UI pages + history
├── icons/ # Copied from src/
├── manifest.json # Copied from root
└── Clean-Autofill.zip # Distribution package
```

Expand All @@ -126,15 +167,15 @@ The extension follows Chrome Extension Manifest V3 architecture with three main
1. Edit TypeScript files in `src/`
2. Run `bun run build` to compile to `dist/`
3. Load `dist/` folder in Chrome (chrome://extensions, Developer mode)
4. Run `bun test src/` to verify changes
4. Run `bun run test` to verify changes
5. Run `bun run check` before committing

## Testing

Tests are colocated with source files (`*.test.ts`). DOM testing is supported via happy-dom.

```bash
bun test src/ # Run all 119 tests
bun run test # Run all 251 tests
bun run test:watch # Watch mode
bun run test:coverage # Coverage report (98%+ line coverage)
```
Expand All @@ -158,8 +199,8 @@ GitHub Actions runs on push/PR to main:

## Development Notes

- Extension requires minimal permissions: activeTab, storage, notifications
- Uses Chrome's sync storage for cross-device settings persistence
- Extension permissions: activeTab, storage, notifications, identity, identity.email
- Uses Chrome's sync storage for settings, local storage for email history
- Domain extraction handles edge cases like localhost, IP addresses, and special TLDs
- Content script uses multiple fallback strategies for reliable field detection
- TypeScript source in `src/`, compiled output in `dist/`
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Workflows

| # | Workflow | File | Trigger | Purpose |
|---|---------|------|---------|---------|
| W1 | Test | `W1-Test.yml` | Push/PR to `main` | Typecheck, lint, test, build, validate |
| W2 | Build | `W2-Build.yml` | Push/PR to `main`, manual | Build, package, upload artifact |
| W3 | Release | `W3-Release-Chrome-Web-Store.yml` | Manual only | Run W1 + W2, then upload & publish to Chrome Web Store |

## Dependencies

```text
W3 → W1 (CI gate) → W2 (build + package) → release job
```

W1 and W2 are also independently triggered on push/PR.

## Comparison

| Step | W1 Test | W2 Build | W3 Release |
|---|:---:|:---:|:---:|
| Typecheck | yes | - | via W1 |
| Lint & format | yes | - | via W1 |
| Tests | yes | - | via W1 |
| `bun run validate` | yes | - | via W1 |
| Build + package | yes | yes | via W2 |
| Upload artifact | - | yes (30d) | yes (90d) |
| Build report summary | - | yes | via W2 |
| Version match check | - | - | yes |
| Upload to Chrome Web Store | - | - | yes |
| Publish to Chrome Web Store | - | - | if input |
| GitHub Release | - | - | if input |
8 changes: 3 additions & 5 deletions .github/workflows/ci.yml → .github/workflows/W1-Test.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
name: CI
name: W1 Test

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
workflow_call:

jobs:
test:
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/W2-Build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: W2 Build

on:
workflow_dispatch:
workflow_call:

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Package extension
run: bun run pack

- name: Upload extension artifact
uses: actions/upload-artifact@v4
with:
name: Clean-Autofill
path: dist/Clean-Autofill.zip
retention-days: 30

- name: Generate build report
run: |
echo "## Build Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Extension Details" >> $GITHUB_STEP_SUMMARY
echo "- **Package**: dist/Clean-Autofill.zip" >> $GITHUB_STEP_SUMMARY
echo "- **Size**: $(du -h dist/Clean-Autofill.zip | cut -f1)" >> $GITHUB_STEP_SUMMARY
echo "- **Files**: $(unzip -l dist/Clean-Autofill.zip | tail -1 | awk '{print $2}')" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Manifest Info" >> $GITHUB_STEP_SUMMARY
python3 -c "
import json
with open('manifest.json', 'r') as f:
m = json.load(f)
print(f\"- **Version**: {m.get('version')}\")
print(f\"- **Name**: {m.get('name')}\")
print(f\"- **Permissions**: {', '.join(m.get('permissions', []))}\")
" >> $GITHUB_STEP_SUMMARY
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Release to Chrome Web Store
name: W3 Release

on:
workflow_dispatch:
Expand All @@ -15,36 +15,14 @@ concurrency:

jobs:
ci:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Type check
run: bun run typecheck
uses: ./.github/workflows/W1-Test.yml

- name: Lint and format check
run: bun run check

- name: Run tests
run: bun run test

- name: Build extension
run: bun run build

- name: Validate extension
run: bun run validate
build:
needs: ci
uses: ./.github/workflows/W2-Build.yml

release:
needs: ci
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down Expand Up @@ -76,16 +54,11 @@ jobs:
fi
echo "extension_id=$EXTENSION_ID" >> $GITHUB_OUTPUT

- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Download build artifact
uses: actions/download-artifact@v4
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Package extension
run: bun run pack
name: Clean-Autofill
path: dist

- name: Upload to Chrome Web Store
id: upload
Expand Down
Loading