Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
f90eb2b
Exclude extensions directory from root tsconfig and gitignore
mojoro Mar 19, 2026
1258297
Add Chrome extension project scaffold with Vite and CRXJS
mojoro Mar 19, 2026
fb67ae4
Add shared types and extractor utility functions
mojoro Mar 19, 2026
9862813
Add Greenhouse and Lever DOM extractors for job pages
mojoro Mar 19, 2026
c7f1f24
Add generic fallback extractor and extractor registry
mojoro Mar 19, 2026
1790674
Add Shortlist API client with Clerk cookie auth
mojoro Mar 19, 2026
a21ba0c
Add content script for page detection and extraction
mojoro Mar 19, 2026
07f2a68
Add background service worker for API coordination
mojoro Mar 19, 2026
5859091
Add React popup UI with auth, extraction, and import flow
mojoro Mar 19, 2026
dfd2752
Add placeholder SVG icons and development README
mojoro Mar 19, 2026
bc19bc5
Add extension package-lock.json for reproducible installs
mojoro Mar 19, 2026
89afdf4
Add extension status endpoint for auth checks
mojoro Mar 23, 2026
81713dd
Add extension profiles endpoint for profile listing
mojoro Mar 23, 2026
6e1cc7b
Add CORS handling for Chrome extension requests
mojoro Mar 23, 2026
ec4ebce
Add source and externalId to import schema for dedup
mojoro Mar 23, 2026
74bda8b
Add LinkedIn DOM extractor for job pages
mojoro Mar 23, 2026
b7aa619
Add Ashby DOM extractor for job pages
mojoro Mar 23, 2026
d199e10
Add USAJobs DOM extractor for federal job listings
mojoro Mar 23, 2026
4b2f69e
Add Indeed DOM extractor for job pages
mojoro Mar 23, 2026
d0b107d
Add Glassdoor DOM extractor for job pages
mojoro Mar 23, 2026
eadb3ae
Register all extractors and update manifest patterns
mojoro Mar 23, 2026
526a2ac
Add externalId extraction to all site-specific extractors
mojoro Mar 23, 2026
5c87cf5
Wire source and externalId through extension API client
mojoro Mar 23, 2026
4c85c3d
Add Alt+Shift+S keyboard shortcut to open extension popup
mojoro Mar 24, 2026
f34d400
Add import history storage to background service worker
mojoro Mar 24, 2026
615bd39
Show recent imports in extension popup
mojoro Mar 24, 2026
a97879b
Add React Vite plugin and generate PNG icons for build
mojoro Mar 24, 2026
b7197d4
Replace invalid Glassdoor host wildcard with explicit TLD patterns
mojoro Mar 24, 2026
7bb0648
Resolve popup URLs from storage and add localhost:3000 to host permis…
mojoro Mar 24, 2026
f64c153
Match LinkedIn collections and search pages in addition to direct view
mojoro Mar 24, 2026
c896536
Inject content script on all pages and always fall through to generic
mojoro Mar 24, 2026
80138bc
Fall back to scripting API when content script is not yet injected
mojoro Mar 24, 2026
f4dca89
Send innerHTML from generic extractor and run Turndown on HTML input
mojoro Mar 24, 2026
6d00786
Add Zod schemas for selector identification and normalization
mojoro Mar 24, 2026
40a3300
Add selector identification endpoint using Gemini Flash
mojoro Mar 24, 2026
b2962a9
Add extraction normalization endpoint using Haiku
mojoro Mar 24, 2026
8d1aa83
Add usage tracking to existing extract route
mojoro Mar 24, 2026
fbaf33f
Update extension types for two-step extraction flow
mojoro Mar 24, 2026
323f003
Rewrite generic extractor with DOM stripping and selector caching
mojoro Mar 24, 2026
5f2298b
Remove site-specific extractors and simplify registry
mojoro Mar 24, 2026
56da238
Add selector identification and normalization API helpers
mojoro Mar 24, 2026
8cc6041
Update service worker for two-step extraction messages
mojoro Mar 24, 2026
21a7d69
Update content script with async extraction and selector application
mojoro Mar 24, 2026
4817d63
Rewrite popup for multi-step extraction with status flow
mojoro Mar 24, 2026
9b95193
Apply selectors via scripting API when content script is unavailable
mojoro Mar 24, 2026
333f145
Make normalize schema lenient and fall back to raw fields on AI failure
mojoro Mar 24, 2026
1504218
Delete two-step extraction routes and unused schemas
mojoro Mar 24, 2026
2d597fa
Simplify extension types for direct extract-and-import flow
mojoro Mar 24, 2026
91d9959
Replace DOM skeleton extractor with simple HTML collector
mojoro Mar 24, 2026
63d302a
Simplify extension API client for extract and import
mojoro Mar 24, 2026
25a94cb
Simplify service worker for direct extract and import
mojoro Mar 24, 2026
1c314c2
Simplify content script to collect page HTML
mojoro Mar 24, 2026
84c875f
Rewrite popup for single-step extract then import flow
mojoro Mar 24, 2026
fc1a44e
Add duplicate detection, edit-in-app fallback, and auto-detect dev URL
mojoro Mar 24, 2026
f8f63cf
Return 409 for duplicate imports instead of silently upserting
mojoro Mar 24, 2026
67a347a
Replace extension icon with cyan checkmark matching app branding
mojoro Mar 24, 2026
20d2afa
Re-render extension icons at high density for crisp display
mojoro Mar 24, 2026
ca9336c
Add dark mode to popup matching app palette via OS preference
mojoro Mar 24, 2026
7d3ccd2
Add checkmark logo to popup header matching app branding
mojoro Mar 24, 2026
91beb7a
Reduce logo size and nudge down to align with header text
mojoro Mar 24, 2026
a20722c
Prepare extension v1.0.0 for Chrome Web Store submission
mojoro Mar 25, 2026
520722b
Remove content script injection in favor of scripting API only
mojoro Mar 25, 2026
cd3d59d
Skip onboarding redirect for Chrome extension API requests
mojoro Mar 25, 2026
67be5af
Add Chrome extension privacy policy as a static page
mojoro Mar 25, 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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# dependencies
/node_modules
extensions/*/node_modules
extensions/*/dist
/.pnp
.pnp.*
.yarn/*
Expand Down
118 changes: 118 additions & 0 deletions extensions/chrome/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Shortlist Chrome Extension

Import job listings into your Shortlist feed with one click while browsing any job board.

## Features

- **Greenhouse & Lever extractors** -- structured DOM extraction on supported job boards
- **Generic fallback** -- collects page content for AI extraction on any other site
- **One-click import** -- sends extracted data to the Shortlist API via your existing session
- **Profile selector** -- choose which search profile to import into

## Development Setup

### Prerequisites

- Node.js 18+
- pnpm (or npm)
- A running Shortlist app (for API calls)

### Install dependencies

```bash
cd extensions/chrome
npm install
```

### Generate icons

The `icons/` directory contains SVG source files. Chrome requires PNG icons. Convert them before loading:

```bash
# Using ImageMagick (or any SVG-to-PNG tool)
convert icons/icon16.svg icons/icon16.png
convert icons/icon48.svg icons/icon48.png
convert icons/icon128.svg icons/icon128.png
```

Or use an online converter. The PNGs must be exactly 16x16, 48x48, and 128x128 pixels.

### Build

```bash
npm run build
```

### Development mode (with hot reload)

```bash
npm run dev
```

### Load in Chrome

1. Open `chrome://extensions`
2. Enable "Developer mode" (top right)
3. Click "Load unpacked"
4. Select the `extensions/chrome/dist` directory
5. The Shortlist icon appears in your toolbar

### API base URL

By default the extension talks to `https://shortlist.johnmoorman.com`. For local development, open the extension's background page console and run:

```js
chrome.storage.local.set({ apiBaseUrl: "http://localhost:3001" });
```

To reset back to production:

```js
chrome.storage.local.remove("apiBaseUrl");
```

## Architecture

```
src/
manifest.json Manifest V3 configuration
popup/
popup.html Popup entry HTML
popup.tsx React popup UI
popup.css Popup styles
background/
service-worker.ts Background script -- coordinates API calls
content/
content.ts Content script -- extracts page data
lib/
api.ts Shortlist API client (fetch + Clerk cookies)
extractors/
index.ts Extractor registry
greenhouse.ts Greenhouse job page extractor
lever.ts Lever job page extractor
generic.ts Generic fallback (page text for AI extraction)
utils.ts Shared extraction utilities
types.ts Shared TypeScript types
```

### Message flow

1. Content script detects a job page and notifies the background worker (badge)
2. User clicks the extension icon, popup opens
3. Popup asks the background worker to check auth and fetch profiles
4. Popup asks the content script to extract job data from the DOM
5. User clicks "Import" -- popup tells the background worker to call the API
6. Background worker posts to `/api/jobs/import` (or `/api/jobs/extract` for generic pages)
7. Popup shows success/error

### Authentication

The extension uses Clerk session cookies -- no API keys needed. The user must be signed in to Shortlist in at least one browser tab. The background service worker makes `fetch()` calls with `credentials: "include"` to attach cookies automatically.

## Supported Sites

| Site | Extractor | Status |
|------|-----------|--------|
| Greenhouse (`boards.greenhouse.io`, `jobs.greenhouse.io`) | Structured | MVP |
| Lever (`jobs.lever.co`) | Structured | MVP |
| Any other page | Generic (AI extraction) | MVP |
Binary file added extensions/chrome/icons/icon128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions extensions/chrome/icons/icon128.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added extensions/chrome/icons/icon16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions extensions/chrome/icons/icon16.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added extensions/chrome/icons/icon48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions extensions/chrome/icons/icon48.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading