Skip to content

sir-ad/knight

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

23 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Knight

CI Release GitHub release License: MIT Chrome MV3 Node 20+ Python 3.11+


Knight


The job application layer you've been missing.

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.


🌐 sir-ad.github.io/knight


Features

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

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           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.


Supported ATS Portals

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

Quick Start

One-line install

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).


Manual setup

1. Start the resume parser sidecar

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:43118

For scanned PDF support, install Tesseract:

# macOS
brew install tesseract

# Ubuntu / Debian
sudo apt-get install -y tesseract-ocr

2. Build the extension

cd ../careerflow
npm install
npm run build

3. Load in Chrome

  1. Open chrome://extensions
  2. Enable Developer Mode
  3. Click Load unpacked
  4. Select careerflow/build/chrome-mv3-prod

4. (Optional) Start Ollama for local LLM

OLLAMA_ORIGINS=chrome-extension://* ollama serve
ollama pull llama3.2:3b

Requirements

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

LLM Provider Setup

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.


Gmail Sync

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-id

Development

Extension

cd 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 -- --coverage

Sidecar

cd 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

Release gate (full validation)

# 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 -q

Repo Layout

Knight/
β”œβ”€β”€ 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

CI / CD

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

License

MIT

About

Privacy-first Chrome extension for local resume parsing, ATS autofill, Gmail tracking, and Ollama follow-ups

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors