Every application is the same form. Different URL, same twenty fields β name, email, phone, work history, education β pasted by hand into Workday, Greenhouse, Lever, and a dozen other portals that share nothing between them. Most autofill tools break on anything beyond a basic text input, or quietly ship your resume to a hosted AI pipeline to do the parsing.
Knight fixes this without the tradeoffs. Your resume is parsed entirely on your own machine by a local Python service. Field mapping runs through whichever LLM you choose β local Ollama or a cloud provider you configure. Before a single character is written to any form, you see a diff of every proposed change and confirm it. Your data stays on your device.
| Capability | Detail |
|---|---|
| Resume parsing | PDF (digital + scanned OCR), DOCX, TXT, or pasted text |
| Local-first | PyMuPDF + optional Tesseract OCR in a local Python sidecar |
| Autofill | 14 named ATS adapters + generic DOM fallback |
| Review overlay | Inline diff of what will be filled β confirm before anything is written |
| Application log | Local status history with auto-detection from Gmail |
| Gmail sync | Read-only OAuth β spots confirmations, interviews, rejections, offers |
| Follow-up drafts | Generates follow-up emails from your application context |
| LLM providers | Ollama Β· OpenAI Β· Anthropic Β· Gemini Β· OpenRouter |
ββββββββββββββββββββββββββββββββββββββββββββ
β Chrome Extension (MV3) β
β β
β ββββββββββββ βββββββββββ ββββββββββ β
β β Service β β Content β β Popup β β
β β Worker ββββ Script β β UI β β
β β (bus + β β(inject/ β β(React) β β
β β LLM hub) β β fill) β β β β
β ββββββ¬ββββββ βββββββββββ ββββββββββ β
βββββββββΌβββββββββββββββββββββββββββββββββββ
β HTTP (localhost only)
βΌ
βββββββββββββββββββββββββ
β Resume Parser Sidecarβ http://127.0.0.1:43118
β FastAPI Β· Python β
β PyMuPDF Β· Tesseract β
β LangExtract β
βββββββββββββββββββββββββ
All LLM calls from the extension route through the service worker β content scripts never call APIs directly. The sidecar handles heavy file parsing outside the browser sandbox.
| Portal | Match pattern |
|---|---|
| Workday | *.myworkdayjobs.com, *.workday.com |
| Greenhouse | boards.greenhouse.io, *.greenhouse.io |
| Lever | jobs.lever.co, *.lever.co |
| Naukri | *.naukri.com |
| iCIMS | *.icims.com |
| SmartRecruiters | *.smartrecruiters.com |
| Oracle Taleo | *.taleo.net |
| SAP SuccessFactors | *.successfactors.com, *.successfactors.eu |
| LinkedIn Easy Apply | *.linkedin.com/jobs/* |
| Indeed | *.indeed.com/apply/* |
| Wellfound / AngelList | *.wellfound.com/jobs/*, *.angel.co/jobs/* |
| Ashby | *.ashbyhq.com |
| Rippling | *.rippling.com/jobs/* |
| Generic fallback | Any form with standard labels, placeholders, or aria-label metadata |
bash <(curl -fsSL https://raw.githubusercontent.com/sir-ad/knight/main/install.sh)Clones the repo, builds the extension, and sets up the Python sidecar in one shot. Then follow the printed instructions to load the unpacked extension in Chrome.
Set KNIGHT_DIR to change the install location (default: ~/knight).
git clone https://github.com/sir-ad/knight.git
cd knight/resume-parser-sidecar
./scripts/setup-venv.sh # one-time: creates .venv and installs deps
./scripts/run.sh # starts on http://127.0.0.1:43118For scanned PDF support, install Tesseract:
# macOS
brew install tesseract
# Ubuntu / Debian
sudo apt-get install -y tesseract-ocrcd ../careerflow
npm install
npm run build- Open
chrome://extensions - Enable Developer Mode
- Click Load unpacked
- Select
careerflow/build/chrome-mv3-prod
OLLAMA_ORIGINS=chrome-extension://* ollama serve
ollama pull llama3.2:3b| Component | Requirement |
|---|---|
| Node.js | 20+ |
| Python | 3.11+ |
| Chrome | 115+ (MV3) |
| Ollama | Any recent version β for the local-first path |
| Tesseract | Optional β only needed for scanned PDF resumes |
Knight uses the provider you configure in Settings. Ollama is the default and requires no API key.
| Provider | Key required | Notes |
|---|---|---|
| Ollama | No | Default. Runs 100% locally. |
| OpenAI | Yes | Supports GPT-4o, GPT-4.1 series |
| Anthropic | Yes | Supports claude-haiku-3-5, claude-sonnet-4-5 |
| Google Gemini | Yes | Supports gemini-2.0-flash |
| OpenRouter | Yes | Routes to any supported model |
Store keys in Settings β the extension keeps them in local Chrome storage and never includes them in exports.
Ollama endpoint: enter the host root only β
http://localhost:11434. Do not append/api.
Knight requests a read-only Gmail OAuth scope (gmail.readonly). It scans for emails from known ATS domains and classifies them as confirmation, interview invite, rejection, or offer β updating your local application log automatically.
To enable Gmail sync, set your OAuth client ID before building:
# careerflow/.env.local
PLASMO_PUBLIC_GOOGLE_CLIENT_ID=your-google-oauth-client-idcd careerflow
npm run dev # Plasmo dev server with hot reload
npm run typecheck # TypeScript check
npm test # Jest tests
npm test -- --testPathPattern=<file> # Single file
npm test -- --coveragecd resume-parser-sidecar
source .venv/bin/activate
python -m uvicorn resume_parser_sidecar.app:app --host 127.0.0.1 --port 43118 --reload
pytest tests -q
pytest tests/test_service.py # Single file# Extension
cd careerflow
npx tsc --noEmit && npm test -- --runInBand && npm run build && npm run package
# Sidecar
cd ../resume-parser-sidecar
source .venv/bin/activate && pytest tests -qKnight/
βββ careerflow/ # Chrome extension (TypeScript Β· React Β· Plasmo)
β βββ src/background/ # Service worker β message bus, LLM calls, Gmail sync
β βββ src/content/ # Content scripts β ATS detection, autofill, overlay
β βββ src/lib/ # Shared utilities β types, LLM providers, storage
β βββ src/popup/ # React popup β Profile / Dashboard / Settings tabs
βββ resume-parser-sidecar/ # Local FastAPI service (Python 3.11+)
β βββ resume_parser_sidecar/ # app, extraction, langextract runner, providers
βββ docs/ # GitHub Pages site
βββ .github/workflows/ # CI, release packaging, Pages deploy
| Workflow | Trigger | What it does |
|---|---|---|
ci.yml |
Push / PR to main |
typecheck β tests β build β package (extension); pytest (sidecar) |
release.yml |
Version tags (v*) |
Builds and attaches the extension zip to GitHub Releases |
pages.yml |
Push to main |
Deploys docs/ to GitHub Pages |