Local-first job search tooling for discovering roles, evaluating fit, tracking pipeline state, and generating reviewable resume/cover-letter drafts.
The repository is designed to keep reusable tooling in Git while keeping candidate-specific data local.
- Scans supported job sources.
- Extracts structured job descriptions.
- Scores jobs against a search profile.
- Tracks application state in a terminal dashboard.
- Builds draft candidate profiles from CV/resume sources.
- Generates draft resume and cover-letter material for human review.
It does not auto-submit applications.
Do not commit private candidate data.
Ignored by default:
.envapplications/- generated tracker CSV files in
data/ - generated profile-builder outputs under
profile_build/ - built dashboard binaries
The important contract is documented in DATA_CONTRACT.md.
skills/ Python command-line tools
dashboard/ Go Bubble Tea terminal UI
statuses.yaml Canonical application statuses
DATA_CONTRACT.md User-data vs system-code boundary
profile_build/README.md Profile-builder output notes
interview-prep/ Story-bank scaffold
Local-only data normally lives in:
resume.yaml
search_profile.yaml
companies.yaml
applications/
data/applications.csv
profile_build/
.env
Python:
- Python 3.10+
- PyYAML for YAML-backed commands
pdftotextfor PDF profile ingestion
Go dashboard:
- Go 1.18+
Local model:
- The Python tools expect an OpenAI-compatible local LLM endpoint.
- Configure it through
.envor environment variables used byskills/_common.py.
Run a profile-driven search:
skills/find_jobs.py profile --limit 10Draft resume and cover-letter material for selected applications:
skills/apply_to.py applications/example-role-YYYY-MM-DDRender final polished markdown files to PDFs:
skills/render_pdf.py applications/example-role-YYYY-MM-DDLog an outcome:
skills/log_outcome.py applications/example-role-YYYY-MM-DD --outcome applied --source "Company site"Build the dashboard:
cd dashboard
go build -o career-dashboard .Run it:
dashboard/career-dashboard --path .Useful keys:
j/k move
h/l switch status tabs
/ search
s cycle sort
c change status
a run apply_to.py
p run render_pdf.py
r refresh
q quit
Build draft profile artifacts from CV/resume-like sources:
skills/build_profile.py ingest resume.pdf linkedin.html old-cv.mdOutputs are written under profile_build/:
profile.json
resume.draft.yaml
search_profile.draft.yaml
evidence_catalog.yaml
evidence_catalog.md
profile_notes.md
These are review artifacts. Merge only verified facts into real profile files.
The builder is domain-neutral. It uses cheap deterministic extraction for obvious facts, then asks the local model to infer appropriate domains, role buckets, proof points, resume variants, cover-letter angles, and verification items.
Job source adapters currently include:
- Ashby
- Greenhouse
- Lever
- RemoteOK
Watched company configuration lives in companies.yaml.
Search targeting lives in search_profile.yaml.
- Review generated material before using it.
- Keep
.env, resumes, applications, PDFs, and tracker outputs out of Git. - Treat profile-builder output as draft evidence, not truth.
- Do not claim skills, credentials, dates, or metrics unless verified.
- Prefer updating the evidence catalog before tuning resume and cover-letter prompts.
Syntax-check Python tools:
PYTHONDONTWRITEBYTECODE=1 python3 -c 'import ast, pathlib; [ast.parse(pathlib.Path(p).read_text()) for p in pathlib.Path("skills").glob("*.py")]'Build dashboard:
cd dashboard && go build -o career-dashboard .Smoke-check dashboard data loading:
dashboard/career-dashboard --check --path .