job-search
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Warn
- process.env — Environment variable access in .agents/skills/freehire-search/cli/src/helpers.ts
- network request — Outbound network request in .agents/skills/freehire-search/cli/src/helpers.ts
- process.env — Environment variable access in .agents/skills/freehire-search/cli/tests/helpers.ts
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Multi-agent job application system: YAML profile, universal rules, LaTeX CV generation (1-page, ATS-safe). Works with Claude Code, Codex, OpenCode, or any agent with file+shell access.
🎯 Job Search — Multi-Agent Job Application System
A job search framework that runs on your own machine, with any coding agent.
Searches for jobs, evaluates fit, generates a LaTeX CV (1-page A4, ATS-safe),
and tracks applications — all driven by your profile in YAML. No
candidate data lives in the engine: swap the profile and the same pipeline
works for any track (backend, frontend, mobile, IoT, data...) and any coding
agent with file + shell access (Claude Code, Codex, OpenCode, Cursor, Cline,
or even a plain chat without tool-use for the manual path).
⚠️ Only the search is automated. Applying is always manual. The
pipeline finds jobs, scores fit, and generates the CV — it never submits
anything to a job board or company on your behalf, and never will. At the
end of/apply-batchand/compile-todayyou get a URL; you open it,
fill out the form, and upload the CV yourself. No auto-apply, no bot
submitting on your account, ever.
This repo is a working instance for one person's job search. Everything
that drives the pipeline — the generic engine (AGENTS.md,rules/,workflows/,profile/) and the day-to-day command files (CLAUDE.md,.claude/commands/,.opencode/commands/) — is in English, so any dev can
reuse it as-is. The one exception is generated output meant to be read or
spoken by a human in a specific interview (e.g.documents/applications/*/roteiro.md), which stays in whatever language
that candidate actually interviews in.
5-minute checklist (new here? start here)
If you've never used this kind of agent-driven repo before, follow these in
order — nothing else to read first:
- Clone this repo (or use "Use this template" on GitHub)
- Run
python3 scripts/check_setup.py— it tells you exactly what's
missing (Bun, LaTeX, PyYAML...) and asks whether to install everything
now. Automatic installation currently supports Debian/Ubuntu and
recovers interrupteddpkgconfiguration before installing packages. -
cp profile/candidate.example.yaml profile/candidate.yaml - Open
profile/candidate.yamland replace every value with your own
real data (name, email, skills, experience — seeprofile/candidate.schema.yamlif a field is unclear). Never leave
the example's placeholder data in there — see the warning below,
the pipeline will refuse to run if you do. - Run
python3 scripts/validate_profile.py— fix anything it flags - Install the search CLIs (step 2 in "Getting started" below)
- Open your coding agent (Claude Code, Codex, OpenCode...) in this
folder and type/daily - When you get a compiled CV and a URL: open the URL yourself and
submit it by hand — this tool never applies for you, see the
warning above
That's it — the agent takes it from there and tells you what to do next at
every step.
How it works
/daily /apply-batch <n> /compile-today 👤 YOU APPLY /confirm <n>
│ │ │ MANUALLY │
▼ ▼ ▼ (open URL, fill form, ▼
Search jobs Generate LaTeX CV Compile → PDF upload CV yourself) Register in
(LinkedIn+freehire) for chosen job ATS check, archive tracker (Notion/
Rank by fit (gate: deal-breaker CSV/none)
+ score ≥60%)
Everything left of "👤 YOU APPLY" is automated. Everything from there on is
you, by hand, on the job board's own site — the pipeline only hands you the
URL and a ready CV.
Every step reads profile/candidate.yaml (your data) + rules/ (universal
CV/fit/ATS rules) — nothing hardcoded in the engine. See AGENTS.md
for the full architecture.
Prerequisites
- A coding agent with file + shell access (Claude Code, Codex, OpenCode...)
- Python 3 + PyYAML — check with
python3 -c "import yaml" - Bun — for the job search CLIs
- LaTeX (
pdflatex) +pdftotext/pdfinfo(poppler-utils) — to compile and ATS-check jq— reads fields out of the metadata JSON during compilation
Run python3 scripts/check_setup.py to check all of these at once. If
anything is missing, it reports the dependencies and asks before installing
them. Detailed manual install steps: SETUP.md.
Getting started
# 0. Check your environment first
python3 scripts/check_setup.py # interactive check
python3 scripts/check_setup.py --install # install without the question
python3 scripts/check_setup.py --no-prompt # diagnostics/CI only
# 1. Your profile (never invent data — leave blank what you don't know)
cp profile/candidate.example.yaml profile/candidate.yaml
# fill in profile/candidate.yaml with your real data — name, email, everything
python3 scripts/validate_profile.py
⚠️ validate_profile.py will refuse to pass if you forgot to replace the
example's placeholder name/email/handles — this is not a style suggestion,
it's a hard block. If you just copy the template and run the pipeline
without editing it, you'll get a clear error telling you exactly what's
still unedited, instead of silently generating a CV with someone else's
contact info.
# 2. Job search CLIs
cd .agents/skills/linkedin-search/cli && bun install && cd ../../../..
cd .agents/skills/freehire-search/cli && bun install && cd ../../../..
Then, inside your coding agent:
/daily → search jobs, rank by fit score
/apply-batch 1,2,3 → generate CVs for the jobs you picked
/compile-today → compile, run ATS check, archive
/confirm 1,2,3 → register the sent application in the tracker
Commands
| Command | What it does |
|---|---|
/daily |
Scrape LinkedIn + freehire, deduplicate, rank by fit score |
/apply-batch <indices|url> |
Generate a .tex CV for chosen jobs — blocks on deal-breaker or score < 60% before spending effort |
/compile-today |
Compile .tex → PDF, run ATS check, archive — never touches the tracker |
/confirm <indices> |
Only command that registers "Applied" in the tracker |
/interview-prep <company> |
Generate an HR/behavioral interview script + honest fit analysis for an already-confirmed job — not technical-round prep, that varies too much per company to generalize |
Architecture
| Folder | Content |
|---|---|
profile/ |
Your data (candidate.yaml, gitignored) — start from candidate.example.yaml |
rules/ |
Universal rules: CV, fit score, ATS, interview — no one's personal data |
workflows/ |
Operational steps for each command above |
templates/ |
Generic LaTeX template (placeholders resolved from the profile) |
scripts/ |
Environment setup, dependency installation, profile validation, batch compilation, CSV tracker |
.agents/skills/ |
Job search CLIs (LinkedIn, freehire) |
Full detail, including why each folder exists: AGENTS.md.
Tests
python3 -m unittest discover -s tests
Covers scripts/validate_profile.py, scripts/track_append.py,scripts/check_setup.py, and scripts/check_roteiro.py (stdlib unittest,
zero extra dependency), plus a guard that profile/candidate.example.yaml
always passes validation.
Troubleshooting
Setup / environment
| Symptom | Where to look |
|---|---|
| Not sure what's wrong with your setup | Run python3 scripts/check_setup.py first — it checks everything at once and tells you exactly what's missing |
dpkg was interrupted |
Rerun python3 scripts/check_setup.py and accept the installation; the installer repairs pending package configuration before continuing |
bash: bun: command not found |
Bun isn't installed — curl -fsSL https://bun.sh/install | bash, then open a new terminal (or source your shell config) so it's on your PATH |
pdflatex: command not found |
LaTeX isn't installed — see SETUP.md; on Debian/Ubuntu you need texlive-latex-extra specifically, not just texlive-latex-base (the template uses titlesec, which isn't in the base set) |
ModuleNotFoundError: No module named 'yaml' |
PyYAML isn't installed — pip install pyyaml (or pip3 install pyyaml depending on your system) |
jq: command not found |
sudo apt install jq (or brew install jq on macOS) — used to read fields out of the metadata JSON during compilation |
Your coding agent doesn't recognize /daily as a command |
Not every agent has slash-command support. Just say it in plain language instead: "read AGENTS.md, then workflows/daily.md, and run the steps using profile/candidate.yaml" |
Not sure what to put in tracker.backend |
Use csv unless you specifically already use Notion and know your database ID — csv needs nothing installed and works out of the box |
Day-to-day usage
| Symptom | Where to look |
|---|---|
python3 scripts/validate_profile.py fails right after copying the example |
That's expected the first time — it's telling you which placeholder fields (name, email, handles) you still need to replace with your real data. Fix each line it lists, then run it again |
/daily finds no jobs |
LinkedIn may have blocked scraping — try freehire only, or paste the URL directly into /apply-batch |
| CV came out longer than 1 page | /compile-today already blocks this on its own (won't register, won't archive, shows up in the report) — trim content following rules/cv-rules.md and rerun /compile-today |
/compile-today failed to compile |
The pdflatex log shows up in the report — usually an unescaped special character |
| A job showed up before | /daily filters against the tracker and local files (documents/applications/, daily/*/*.json) to catch an in-progress application that hasn't been confirmed yet — this works even with tracker.backend: none, see workflows/confirm.md |
Forgot to run /confirm |
No problem — the CV is already compiled and archived locally, the tracker just stays out of date until you run /confirm <number>; doesn't have to be the same day |
Other documents
- AGENTS.md — full architecture, agent/LLM-agnostic
- SETUP.md — installing dependencies
- OPENCODE.md — OpenCode's free models and which to use for each task
- documents/README.md — how the applications folder is organized (local, gitignored)
Credits
The job search CLIs (.agents/skills/linkedin-search/, .agents/skills/freehire-search/)
were adapted from parts of MadsLorentzen/ai-job-search
(not a fork) — including the choice of running them on Bun.
The Notion tracker (tracker.backend: notion) was inspired by
Leticia Coelho's
"Rastreador de vagas"
template — this repo's version adds more properties (stack, gaps, level,
CV version) but the core idea (company/role/status/link columns) traces
back to hers.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found