Skip to content

Repository files navigation

JobsHunt: AI-Powered Local Job Search & Resume Assistant.

Overview

JobsHunt is a local web app for organizing a job search around your own resume materials and LLM providers. A FastAPI server and React UI run on your computer. You add API credentials and model choices in config; the app never requires a hosted SaaS backend.

Typical flow: set a resume vault (directory or one file), capture a posting (URL or paste), then use the UI to draft, evaluate, refine, track applications in a pipeline, and export artifacts. Data stays under paths you control (YAML + JSON on disk).

Caution

This project is a work in progress. For security purposes, you should assume the current codebase contains vulnerabilities. Security enhancements, hardening, and bug fixes are ongoing. Run this software only in environments you trust.

Capabilities

  • Evaluation (structured JSON) — Overall score 1.0–5.0, dimension rows 1–5 with short labels and rationales, narrative fields (role summary, vault match, gaps, interview prep, story candidates), and a machine suggestion apply / maybe / skip plus rationale. Output quality depends on your materials, the posting text, and the model.
  • Drafting — Tailored draft from vault or optional vault summary plus job spec; optional ATS-style refine (rules + full-document LLM passes).
  • Fit & editing — Insights (heuristics ± LLM), apply selected insight lines, copilot chat with workspace context.
  • Exports — TXT always; PDF/DOCX with optional export install (pip install -e ".[export]").
  • Pipeline — Per-workspace rows (company, title, URL, status, scores, notes, run links).
  • Story bank — STAR-style pins; optional bounded use inside drafts.
  • Batch — Queue several jobs (server cap, commonly 15); items run one after another in a background job with polling.
  • Scout (optional) — Playwright visits URLs you list in YAML; collects links whose paths look like job postings (heuristic keywords such as /jobs/, and some ATS hostnames). Not a full ATS integration.
  • Outreach — Template + LLM personalization; copy only from the UI.
  • Workspaces — Separate summary, pipeline, batch, runs, and story bank per workspace.

Configuration paths and secrets belong in your machine only — see Configuration. Do not commit real config.yaml or keys; the repo ships config.example.yaml only.


Responsible use

Outputs are suggestions: AI-generated content can be inaccurate. Review every draft, evaluation, and recommendation before applying or sending materials to employers.

No Auto-Submission: The app does not submit applications for you. It is designed for manual oversight.

Apply-Helper Scripts: While an optional local apply-helper script exists, it is disabled by default. Do not enable or run any helper scripts unless you have audited the code and trust the execution environment.

Data Privacy: While JobsHunt is local-first, it communicates with third-party LLM providers via API. Ensure you are comfortable with the privacy policy of the providers you configure in your AI settings.


LLM setup in this app

Configure saved profiles and agent routing in the UI (/settings/ai). The JobsHunt agent uses a primary profile and optional fallbacks. Features such as draft, evaluation, vault-summary merge, refine, insights, copilot, and negotiate all call your provider through the same local stack; no third-party “app cloud” is required beyond the APIs you choose.


Getting useful results

Early runs can be vague if the vault or preferences are thin. Add solid resume text, preferences / archetype hints, maintain an optional vault summary, and pin stories as you go. Large language models can still be wrong about facts — check employers, titles, and requirements yourself.


Maturity

Area Status Notes
Vault (folder/file, limits, native pickers) Stable PDF/DOCX inputs need export extra. Native pickers on macOS and Windows; on Linux edit paths or YAML.
Vault summary Stable Optional; can block draft when manifest is stale.
Draft / compose Stable Vault or summary + job spec.
Insights + apply insight items Stable Sanitizes common paste noise from terminals.
Refine for ATS Stable Optional auto_refine_after_draft.
Copilot chat Stable Workspace-scoped; UI can confirm or auto-apply model actions.
Structured evaluation Stable Schema v1; config can weight dimensions.
Pipeline Stable JSON per workspace.
Story bank Stable Optional in draft.
Batch draft Stable Sequential worker; ~15 item cap.
Export TXT / PDF / DOCX Stable PDF/DOCX need export extra.
AI settings Stable Profiles + jobshunt agent bindings.
Scout Experimental scout extra + Playwright; opt-in; obey site rules.
Apply-helper subprocess Optional / advanced Gated in config; security-sensitive.
Multi-workspace Stable Registry + directories per workspace.
Multi-user / SSO / cloud sync Out of scope Single-user local design.
Auto-submit to employers Out of scope Manual copy or your own script only.

Table of contents

  1. Overview
  2. Responsible use
  3. LLM setup in this app
  4. Getting useful results
  5. Maturity
  6. Requirements
  7. Install prerequisites (macOS, Linux, Windows)
  8. Install JobsHunt
  9. GitHub Releases (desktop installers)
  10. Build the web UI
  11. Configuration
  12. Run
  13. First-time AI setup
  14. Feature reference (detailed)
  15. CLI reference
  16. Development
  17. Architecture
  18. Troubleshooting
  19. Git repository
  20. License

Requirements

Tool Version Role
Python 3.9+ Backend API, CLI (jobshunt)
Node.js 18+ (LTS recommended) Build the React UI (npm run build)
npm Bundled with Node UI dependencies

Optional

Tool Role
Git Clone and update the repository
Playwright (via scout extra) Experimental portal scout in a real browser

Install prerequisites (macOS, Linux, Windows)

macOS

  • Python 3.9+
  • Node.js 18+
    • nodejs.org LTS, or Homebrew: brew install node
    • Verify: node --version, npm --version

Linux (Debian / Ubuntu and derivatives)

  • Python 3.9+
    • Example: sudo apt update && sudo apt install python3 python3-venv python3-pip
    • Verify: python3 --version
  • Node.js 18+
    • Use NodeSource, nvm, fnm, or a distro package only if it provides Node ≥ 18.
    • Verify: node --version, npm --version

Linux (Fedora / RHEL-style)

  • Python: sudo dnf install python3 (or your distro’s Python 3.9+ package).
  • Node: Install Node 18+ via nvm, NodeSource, or equivalent if the default nodejs is too old.

Windows


Install JobsHunt

From the repository root (the folder that contains pyproject.toml):

GitHub Releases (desktop installers)

Pre-built desktop installers are published on GitHub Releases. The marketing site and stable download links expect these exact filenames (attach them to each release, or CI will not match .../releases/latest/download/...):

Asset Description
JobsHunt-mac.dmg macOS disk image (e.g. hdiutil create over packaging/pyinstaller/dist/JobsHunt.app after pyinstaller jobshunt.spec).
JobsHunt-Setup.exe Windows installer produced by Inno Setup from packaging/windows/JobsHunt.iss (OutputBaseFilename=JobsHunt-Setup).

If you ship a different layout temporarily (for example a .zip of the .app), rename consistently and update website/index.html to match.

App and installer icons are generated from packaging/icons/jobs-hunt-app.png (copy from website/assets/JobsHunt_Favicon.png when the mark changes); run packaging/icons/build_icons.sh (macOS; requires ImageMagick for multi-resolution .ico) to refresh JobsHunt.icns / JobsHunt.ico.

One-command install (recommended)

The installer detects your OS (Windows, macOS, or Linux), creates a .venv, installs [dev,export] with pip, builds the React UI only when src/jobshunt/static/ui/ is missing or you pass --rebuild-ui, then starts jobshunt serve by default. Missing Python 3.9+ (and Node 18+ when a UI build is required) can be installed automatically via winget, Homebrew, or apt/dnf where available; on errors it prints fix steps and lets you press Enter to retry (or use --non-interactive / env JOBSHUNT_INSTALL_NONINTERACTIVE=1 for CI).

Install and start the app (default — runs the server when install finishes):

macOS / Linux

./scripts/install.sh
# or: python3 install.py

Windows (PowerShell, from repo root)

.\scripts\install.ps1
# or: py -3 install.py

Relaunch only (after you close the browser or stop the server — skips pip/npm):

python3 install.py --serve-only
# Windows: py -3 install.py --serve-only

Install without starting the server (e.g. CI or scripting):

python3 install.py --install-only

Pass flags through to jobshunt serve after --, e.g. python3 install.py -- --port 8766. If that port is busy, jobshunt serve picks another free port and prints which one it chose.

Options: install.py --rebuild-ui, install.py --extras dev,export (default), install.py --venv .venv.

Advanced (manual steps)

macOS / Linux

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

Windows (PowerShell)

py -3 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip

Windows (cmd)

py -3 -m venv .venv
.venv\Scripts\activate.bat
python -m pip install --upgrade pip

Install the package

Core + dev tests + resume export libraries (recommended):

pip install -e ".[dev,export]"
  • export: adds ReportLab, python-docx, and pypdf so the app can read PDF/DOCX vault files and emit PDF/DOCX exports. Without it, some formats and export actions will tell you to install this extra.

Optional scout (Playwright)

pip install -e ".[scout]"
playwright install chromium

Use this only if you want the portal scout feature (browser automation). Respect each site’s terms and robots policies.


Build the web UI

The FastAPI app serves the UI from src/jobshunt/static/ui/ after a production build.

From the repo root you can rebuild via python3 install.py --rebuild-ui (or py -3 install.py --rebuild-ui on Windows) instead of the manual npm steps below.

cd ui
npm ci
npm run build
cd ..

If you do not yet have a lockfile workflow, npm install instead of npm ci is fine.

Released wheels include the built UI under jobshunt/static/ui/ (see python -m build after an ui build, and CI workflow .github/workflows/build-wheel.yml).

UI development (optional): from ui/, npm run dev starts Vite with a proxy to http://127.0.0.1:8765 — run jobshunt serve in another terminal so /api requests work.


Configuration

Where files live

macOS / Linux (default) Windows (default)
Config $XDG_CONFIG_HOME/jobshunt/config.yaml (often ~/.config/jobshunt/config.yaml) %APPDATA%\JobsHunt\config.yaml
Data $XDG_DATA_HOME/jobshunt (often ~/.local/share/jobshunt) %LOCALAPPDATA%\JobsHunt\data

Legacy paths (~/.config/jobhunt, ~/.local/share/jobhunt, %…%\JobHunt, JOBHUNT_HOME) are still used automatically when the newer jobshunt locations do not exist yet, so existing installs keep working without moving files.

Override both with environment variable JOBSHUNT_HOME (legacy JOBHUNT_HOME is also honored):

  • Config: $JOBSHUNT_HOME/config.yaml
  • Data: $JOBSHUNT_HOME/data/

On Windows, set JOBSHUNT_HOME via System Properties → Environment Variables, or for a single session in PowerShell:

$env:JOBSHUNT_HOME = "C:\Users\You\jobshunt-data"

Create your config

  1. Print the path the app will use:

    jobshunt config-path
  2. Copy config.example.yaml to that path (same filename config.yaml), then edit:

    • jobshunt.resume_vault_path — folder of resumes or one resume file (.txt, .md, .docx, .pdf with optional deps).
    • jobshunt.output_path — optional explicit folder for exports; if empty, exports go under the app data tree (…/jobshunt/exports or the legacy …/job_hunt/exports if you still use an older data directory).
    • http.host / http.port — bind address (default 127.0.0.1:8765).

Never commit config.yaml if it contains API keys or personal paths (this repo’s .gitignore already ignores common cases).


Run

jobshunt serve

By default the CLI opens a browser to the UI at http://127.0.0.1:8765/agents/jobshunt when using default host and port (your values may differ). If 8765 (or your configured port) is already in use, the server starts on another free port instead and prints which port it picked—use that URL if the first one does not load.

If you stopped the server or closed the terminal, start it again with python3 install.py --serve-only (from the repo root, with your venv already created) or activate .venv and run jobshunt serve.

If the UI was not built, visiting the root URL shows JSON with a hint to run cd ui && npm install && npm run build.


Desktop application (Applications / Program Files)

You can ship JobsHunt as a normal desktop app so users relaunch it from macOS Finder → Applications or Windows Start Menu / Program Files (no terminal).

Maintainers build a frozen bundle with PyInstaller, then:

  • macOS: Drag JobsHunt.app from packaging/pyinstaller/dist/ into /Applications (or distribute a .dmg of that app). Data and config still use the usual ~/Library / ~/.config locations (or %APPDATA% on Windows).
  • Windows: After running PyInstaller, open packaging/windows/JobsHunt.iss in Inno Setup and Compile to produce an installer that installs under Program Files and adds a Start Menu shortcut.

Quick path from repo root:

./packaging/build_desktop.sh

Or manually: build the UI (cd ui && npm ci && npm run build), install the project with extras (pip install -e ".[dev,export]" from the repo root), then cd packaging/pyinstaller && pyinstaller jobshunt.spec.

Details and prerequisites are in packaging/pyinstaller/jobshunt.spec. Optional: pip install -e ".[pack]" installs PyInstaller per pyproject.toml.

Code signing (macOS Gatekeeper / Windows SmartScreen) is not configured in-repo; for wide distribution you will need your own signing certificates.


First-time AI setup

JobsHunt calls your LLM through saved profiles (not the raw “form only”):

  1. Open AI settings in the UI (/settings/ai).
  2. Enter provider, Base URL, Model, optional API key, then save a row under My models (saved).
  3. Under JobsHunt model, choose Primary (and optional Fallbacks), then click Save agent routing.

Supported provider styles include OpenAI, Anthropic, Ollama, OpenAI-compatible proxies, and OpenRouter; path modes (/v1/chat/completions, responses-style paths, etc.) are configurable in the same screen.


Feature reference (detailed)

Below is what the JobsHunt UI and API support at a high level. All REST routes are under /api/agents/jobshunt/ unless noted.

Resume vault

  • Folder or single file: Config resume_vault_path can point to a directory (multiple resumes) or one file.
  • Formats: Plain text / Markdown always; PDF and DOCX need pip install -e ".[export]" (and libraries noted in error messages if missing).
  • Limits: max_vault_chars and max_vault_files avoid sending huge vaults to the model (see config.example.yaml).
  • Native folder/file pickers work on macOS and Windows (pick-vault-folder, pick-vault-file, pick-output-folder). On Linux, type paths in settings or edit config.yaml.

Vault summary (optional “master summary”)

When use_vault_summary_for_context is enabled, the app can maintain a single condensed summary of the vault plus a manifest of incorporated files to save tokens and surface pending changes.

  • Rescan — detect new/changed vault files vs manifest.
  • Rebuild / merge — LLM-assisted update of the summary text.
  • block_draft_when_vault_summary_stale — can block drafting until pending files are merged (configurable).

Paths default under data/jobshunt/; vault_summary_path can override the summary file location.

Workspace: job input, draft, insights, evaluation

  • Job URL or pasted posting — Fetched or pasted content is normalized into a job spec for downstream steps.
  • Draft / compose — Generates tailored resume text using vault (or vault summary) + job context.
  • Insights — Heuristic ATS-oriented signals plus optional LLM commentary (skills, gaps, tips). Job paste text is scrubbed of common bracketed-paste terminal noise before use.
  • Refine for ATS — POST /api/agents/jobshunt/refine-resume runs up to several heuristic → LLM full-resume revise rounds to clear non-good signals (line length, section headers, ASCII noise, etc.). Optional jobshunt.auto_refine_after_draft runs this automatically after each draft (extra LLM cost).
  • Apply insight items — POST /api/agents/jobshunt/apply-insight-items merges selected gaps / quick wins into the current draft (one target section or per-item placement).
  • JobsHunt copilot — POST /api/agents/jobshunt/chat with workspace_id: workspace-aware assistant that returns assistant_markdown plus optional client_actions (set_resume_text, set_job_paste, navigate_tab) and can execute refine / apply on the server when the model emits the corresponding actions.
  • Evaluation — Structured evaluation: dimensions, scores, role summary, match narrative, gaps, interview prep hints, story candidates, and a recommendation bucket — returned as structured JSON the UI renders.

Application pipeline

  • CRUD for pipeline rows: company, title, job URL, status (new, evaluated, drafted, exported, applied, rejected, archived), notes, scores, links to run IDs, etc.
  • Stored locally per workspace under data/jobshunt/workspaces/<workspace_id>/pipeline.json (see Workspaces).

Story bank

  • Pin structured “stories” (STAR-style) derived from evaluations or edits.
  • Optional inclusion in drafts when use_story_bank_in_draft is on.

Negotiation / outreach

  • Templates and LLM-personalized variants for recruiter or follow-up messages (copy from UI; no auto-send).

Batch draft

  • Queue multiple applications (cap enforced server-side, e.g. max 15) for draft generation; poll job status by job_id.

Portal scout (optional)

  • When scout_enabled and scout extra + Playwright browsers are installed, POST /scout can drive a browser session for supported flows.
  • Use responsibly and in line with site policies.

Export

  • POST /export produces run artifacts (e.g. Markdown/Text; PDF/DOCX with export extra) under the configured output / run layout.
  • GET /runs and GET /download/{run_id}/{filename} list and download prior run files.

Apply helper (advanced)

  • apply_helper_script plus allow_apply_subprocess can run a user-defined helper (e.g. open a URL or a local tool). This is off by default; only enable scripts you trust.

AI settings (global)

  • GET/PUT /api/settings/ai — LLM profiles, API keys (stored locally in YAML), headers, temperature, token limits, OpenAI path vs gateway URL modes.
  • Per–JobsHunt routing — Primary/fallback profile IDs for the jobshunt agent only.

Health

  • GET /api/health — Liveness and version JSON.

CLI reference

Command Description
jobshunt serve Start the API + static UI (opens browser). Options: --host, --port override config.
jobshunt config-path Print resolved config.yaml path.
jobshunt data-path Print resolved data root directory.
jobshunt --version Show version.

Development

pip install -e ".[dev,export]"
pytest

Optional linting: ruff is included in dev.


Architecture

See ARCHITECTURE.md for package layout, routers, and data flow.


Troubleshooting

  • jobshunt: command not found — Activate your virtual environment and run pip install -e . again. With the venv active, the jobshunt console script should be on PATH (Scripts on Windows). If not, invoke the installed script by full path, e.g. .venv/Scripts/jobshunt.exe on Windows or .venv/bin/jobshunt on Unix.
  • Blank or JSON homepage — Run npm run build in ui/ so src/jobshunt/static/ui/ exists.
  • 404 on /agents/... after refresh — Ensure you are on a recent build of jobshunt.app (SPA fallback serves index.html for client routes).
  • “Reading .pdf / .docx needs …” — Install export: pip install -e ".[export]".
  • Scout errors — Install scout and run playwright install chromium.
  • 400 / “No primary saved model” — Complete First-time AI setup: saved profile + Save agent routing.
  • Port in use — Change http.port in config.yaml or pass jobshunt serve --port ….

Git repository

If this folder is not yet a Git repo, from the project root:

git init
git add -A
git commit -m "Initial commit: JobsHunt local app"

.gitignore excludes virtualenvs, node_modules, local config.yaml, and generated *.egg-info/ — only commit config.example.yaml, not secrets.


License

MIT — see LICENSE.

About

Local-first job search automation tool using FastAPI, React, and LLMs. Private resume tailoring, ATS-optimized drafting, and structured job evaluation without a hosted backend.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages