A local-first job-search command center. Aggregate listings from multiple sources, score them against your resume, track a pipeline, generate tailored cover letters & CVs, and auto-fill application forms in your own browser — all on your machine.
Built for job seekers who want automation without the risk. The app never auto-submits: it does the tedious 90% (find, match, pre-fill) and leaves the final click to you.
Türkçe dokümantasyon için → README.tr.md · The app UI itself is bilingual (English / Türkçe) — switch with the 🌐 item in the ⚙ menu or in Settings.
┌────────────────────────────────────────────────────────────────────┐
│ Profile + Resume ─► Hybrid Matcher ─► Scored Jobs ─► Pipeline │
│ ▲ ▲ │ │
│ │ ┌─────┴─────┐ ▼ │
│ .docx/.pdf │ Embeddings │ Cover Letter + CV │
│ auto-parsed │ or TF-IDF │ (your chosen AI) │
│ └───────────┘ │ │
│ Personas ── preferences learning ──► ▼ │
│ (multi-role matching, gets smarter) Browser Extension ⚡ │
│ (fills forms, you submit) │
└────────────────────────────────────────────────────────────────────┘
- Multi-source aggregation — RemoteOK, Arbeitnow, Jobicy, RSS feeds, and more via the Sources page. Job age capped at 60 days; cross-source duplicates merged by content fingerprint.
- Hybrid matching — semantic similarity (45%) + skill overlap with a curated synonym taxonomy (35%) + title match (20%). Runs fully offline: local embeddings (sentence-transformers or Ollama) with a pure-Python TF-IDF fallback — it always works.
- Personas — multiple active role profiles (e.g. "SOC Analyst" and "Pentester") scored in parallel; each job shows which persona it fits.
- Preference learning — the app learns from your interactions (saved / applied / rejected / hidden) and adjusts future scores (capped ±15%).
- Visa & relocation awareness — describe your work authorization once; postings are tagged 🟢 sponsorship / 🔴 no sponsorship and down-ranked (never hidden) when they're unrealistic for you.
- LLM precision-rerank (optional) — your chosen AI re-scores the top candidates in a background pass.
- Cover letters with hard quality gates — banned-opener stripping, required concrete hook, metric-in-proof checks, de-AI pass. Export as text, PDF, or Word.
- Tailored CV per persona — AI-generated, downloadable as PDF.
- Browser extension (Chrome / Edge / Opera) — the ⚡ panel in your real browser:
- ⚡ Fill form fields from your profile (never uploads your CV — parsing sites can wipe fields)
- 🔄 Smart fill (CV-first, then fill gaps) for sites that populate from the resume
- 📄 Upload CV as a separate action
- ✉ Cover letter — generate with a word-count target, paste into the form, or attach as PDF; honors a global "instructions for the generator" setting
- 💬 Ask the AI — chat about the job with full JD context; the conversation is saved to the app's Chat page
- 📋 Collect job listings from any page into your pool (deduped, scored)
- Answer memory — remembered answers to recurring custom questions ("How did you hear about us?"); EEOC self-identification fields are always skipped
- In-app AI chat — an agent that can search/filter your jobs, manage the tracker, draft letters, and open pre-filled application forms (Playwright, optional).
- Local-first SQLite (WAL) — your DB, your keys, your machine. Nothing leaves except the API calls you configure.
- Any AI provider — Ollama (local), OpenAI, Anthropic, Groq, Cerebras, OpenRouter, NVIDIA, or any OpenAI-compatible endpoint. Free-tier presets included.
- Auto-backup — daily, keeps the last 7, restore or download from Settings.
- Benchmark harness — recall@k / NDCG over a golden set, so matching changes are measurable, not vibes.
Double-click start-gui.bat for the native desktop window (no console), or start.bat for browser mode. On any platform:
pip install -r requirements.txt
python app.py # → http://127.0.0.1:5000Optional extras:
pip install playwright && playwright install chromium # in-app form pre-fill
# Ollama users: Settings → Ollama server can start it and pull models for you- Settings → Browser extension → Download ZIP (or use the
extension/folder directly) - Unzip, then load it as an unpacked extension (
opera://extensions/chrome://extensions→ Developer mode → Load unpacked) - Copy the pairing token from the same Settings card into the extension popup → Save & test
The extension talks only to 127.0.0.1:5000, authenticated by that token.
- Local (Ollama) — resume and chats stay on your computer.
- Cloud providers (OpenAI/Anthropic/Groq/…) — only the messages you send via that provider. Keys live in your local DB only.
- Job fetching — the only regular outbound traffic is to the job-board APIs you enable.
- No telemetry, no accounts, no cloud sync. Delete
jobhunt.db+uploads/and everything is gone.
app.py Flask routes (UI + localhost API for the extension)
config.py Paths + settings
core/ db, models, matcher, i18n (EN/TR), scheduler, dedup, …
ai/ provider layer, embeddings, agent
apply/ cover letters (gates), CV generator/export, Playwright drivers
collectors/ source registry + fetch pipeline
extension/ the browser extension (MV3)
templates/ static/ UI
tests/ + test_*.py pytest suite
python -m pytest -qMIT — see LICENSE.