skill
job-seeker
The offline, honesty-bound, script-agnostic resume toolkit. Any format in, clean LaTeX/PDF/DOCX out — every writing system first-class (CJK, Cyrillic, Arabic, Hebrew, Devanagari, Greek, Latin…), no su
Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/Cavaradossi/job-seeker itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 17, 2026job-seeker — 申职器
Tailor a clean LaTeX resume to any job description in minutes — then convert it between Markdown / DOCX / PDF / LaTeX, and optionally prefill job applications behind a hard human-in-the-loop safety gate. Ships with bundled CJK fonts (compiles out of the box) and an Agent Skill that teaches your AI editor the whole workflow.
MIT · cross-platform (macOS · Linux · Windows) · LaTeX + pandoc + Playwright
How job-seeker is different. Most AI job-search tools bundle a paid agent subscription, scrape job boards, and auto-pilot submissions. job-seeker goes the other way: offline, no subscription, scrapes nothing, and never auto-submits — and it is built script-agnostic: every writing system is a first-class citizen — Han (CJK), Latin, Cyrillic, Arabic, Hebrew, Devanagari, Greek, and more. Bring a resume in any format and any language; get a clean LaTeX / PDF / DOCX with pixel-perfect CJK typography (the hardest case we solve best — if xelatex + CJK fonts work, the rest is font + bidi work, not a rewrite), and stay in control. Works with whatever AI editor you already use (Cursor / Codex / WorkBuddy).
✨ Why job-seeker?
Sending the same resume to every job gets you filtered out. Hand-tailoring one per JD is slow, keeping .tex / DOCX / Markdown in sync is painful, and submitting applications is error-prone. job-seeker turns that into one coherent flow:
- Bring any format, get any format. Start from
.tex,.md,.docx, or.pdf— convert freely between all four without manual sync. - JD-aware variant picking. Paste a JD, get a recommended resume variant.
- Apply without losing control. A browser assistant prefills forms but never auto-submits — every submission waits for your explicit
y. - Honest resumes by design. A built-in Skill enforces anti-inflation rules (no invented metrics, no inflated titles).
🚀 Features
- Clean LaTeX template with bundled Adobe CJK fonts — no system font install needed.
- Cross-platform build scripts (
build_resumes.sh/.ps1) with page-count reporting. - Any-to-any format conversion (
convert/): LaTeX ↔ Markdown ↔ DOCX ↔ PDF — upload a resume in any of the four formats and convert to any other, via an adapter pattern with automatic BFS routing (PDF text is ingested with PyMuPDF). - JD → variant recommender (
apply/): rule-based keyword matching picks the right resume for the role. - Browser-assisted application with site adapters (Boss直聘 / LinkedIn / generic ATS) and a human-in-the-loop confirm gate.
- Application tracker (CSV) + history audit log — every action recorded.
- Agent Skill (Codex / Cursor / WorkBuddy / editor-agnostic) that encodes the workflow and honesty boundaries.
- CI compiles the sample resume on every push/PR.
🧭 How it works
flowchart TD
subgraph ANY["1 · Bring any format"]
direction LR
tex[".tex"]:::fmt
md[".md"]:::fmt
docx[".docx"]:::fmt
pdf[".pdf"]:::fmt
end
conv["convert/ — any-to-any conversion<br/>10 direct edges · BFS routing"]:::core
ANY --> conv
bank["experience_bank.md<br/>(private, gitignored)"] --> vars["LaTeX_Resume_CN / EN<br/>(your variants)"]
conv --> vars
jd["Job description<br/>URL · paste · file"] --> rec["recommend_variant<br/>(rule-based)"]:::core
vars --> rend["render_variant → PDF"]:::core
rec --> rend
rend --> gate{"confirm()<br/>human-in-the-loop"}:::gate
gate -- "y" --> app["apply/<br/>prefill form — never auto-submit"]:::core
gate -- "N" --> cancel["cancel"]
app --> track["tracker.csv + history/"]:::core
classDef fmt fill:#eef,stroke:#88a,color:#225;
classDef core fill:#e9f7ec,stroke:#5b9,color:#163;
classDef gate fill:#fdeef0,stroke:#e88,color:#721;
Four formats interconvert freely; PDF enters as text-only (PyMuPDF). The apply
path is gated — no submission ever happens without your explicit y.
📦 Installation
Prerequisites
| Tool | Required for | Notes |
|---|---|---|
TeX Live (xelatex) | Compiling PDFs | Windows: MiKTeX — docs/BUILD_WINDOWS.md · macOS: docs/BUILD_MAC.md |
| Python 3.10+ | convert/ and apply/ | |
| pandoc | DOCX / Markdown conversion | PDF works with just xelatex; brew install pandoc |
| Playwright (optional) | Live browser prefill in apply/ | pip install playwright && playwright install chromium |
Setup
git clone https://github.com/Cavaradossi/job-seeker.git
cd job-seeker
python3 -m venv .venv && source .venv/bin/activate # Windows: .\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
⚡ Quick start
1. Compile the sample resume
cd resume_template
xelatex -interaction=nonstopmode sample-resume-en_US-zh_CN.tex
# → sample-resume-en_US-zh_CN.pdf (CJK fonts included, no extra setup)
2. Convert between formats
# The input format is inferred from the extension — start from ANY of .tex / .md / .docx / .pdf
python -m convert --input resume_template/sample-resume-en_US-zh_CN.tex --output outputs/sample.pdf
python -m convert --input resume_template/sample-resume-en_US-zh_CN.tex --output outputs/sample.docx
python -m convert --input my_resume.pdf --output outputs/my_resume.md # PDF → Markdown (text extracted with PyMuPDF)
python -m convert --input my_resume.docx --output outputs/my_resume.tex # DOCX → LaTeX
python -m convert --list-routes # see every supported conversion
3. Tailor to a JD & rehearse the apply flow
python -m apply --jd-file apply/samples/sample_jd.html --dry-run # read JD → recommend variant → render PDF
python -m apply --url https://example.com/jobs/123 --dry-run # fetch a live JD from the web
python -m apply --jd-file apply/samples/sample_jd.html --rehearse # feel the confirmation gate pause
💡 Usage examples
Make a JD-specific variant. Copy the general template, change only the headline, compile:
cp resume_template/sample-resume-en_US-zh_CN.tex LaTeX_Resume_CN/resume-zh_jd_acme.tex
# edit \centerline{...} headline to match the JD, then:
./build_resumes.sh
Convert a Markdown draft to PDF (uses pandoc's default template — not a resume layout, handy for drafts):
python -m convert --input notes.md --output notes.pdf
Apply to a public ATS posting (generic adapter; live prefill needs Playwright):
export JOB_SEEKER_NAME="Your Name"
export JOB_SEEKER_EMAIL="you@example.com"
python -m apply --url https://boards.greenhouse.io/acme/jobs/123 --variant resume_job_en
# → browser opens, fields prefilled, then it PAUSES for your [y/N] before submitting
⚙️ Configuration
- Apply profile — set via env vars (never stored in the repo):
JOB_SEEKER_NAME,JOB_SEEKER_EMAIL,JOB_SEEKER_PHONEJOB_SEEKER_CONFIRM=yes|no— auto-answer the confirm gate (for scripting/tests only)
- Resume variants — drop your
.texfiles intoLaTeX_Resume_CN/orLaTeX_Resume_EN/; the renderer searches those plusresume_template/. - Tool discovery —
convert/tools.pyfindspandoc/xelatex/latexmkonPATHfirst, then falls back to common install locations (MacTeX,~/texlive/*/bin/*, Homebrew,~/.local/bin), so the CLI works even in non-interactive shells. - ToS-aware adapters — Boss直聘 and LinkedIn set
tos_blocks_automation = True, soapplydegrades to "open page + show prefill data" instead of automating them.
📁 Project structure
job-seeker/
├── resume_template/ Clean LaTeX template + bundled CJK fonts + fontawesome
├── convert/ Phase 2: format conversion pipeline (MD/DOCX/PDF/LaTeX)
│ ├── adapters/ One adapter per conversion (pandoc / xelatex)
│ ├── pipeline.py BFS routing + chained adapters
│ └── cli.py python -m convert ...
├── apply/ Phase 3: browser-assisted application
│ ├── adapters/ Site adapters (generic / boss_zhipin / linkedin)
│ ├── mapping/ JD→variant recommender + variant renderer
│ ├── confirm.py Human-in-the-loop gate (submit() always blocks here)
│ ├── audit.py Tracker CSV + history log
│ └── cli.py python -m apply ...
├── docs/ Build guide, open-source plan, tracker schema, example bank
├── docs/skill/job-seeker/ Portable Agent Skill source (sync target)
├── .codex/skills/job-seeker/ Codex project skill
├── .cursor/skills/job-seeker/ Cursor project skill (open repo → ready)
├── .workbuddy/skills/job-seeker/ WorkBuddy project skill
├── build_resumes.sh/.ps1 Cross-platform build scripts
└── requirements.txt Python deps for convert/ + apply/
❓ FAQ
Do I need to install system fonts?
No. The template bundles Adobe CJK fonts in resume_template/fonts/, so it compiles identically on any machine.
Do I need pandoc?
Only for DOCX / Markdown conversion. tex → pdf works with just xelatex.
Will it auto-submit my job applications?
Never. submit() always calls confirm() and blocks. Nothing is submitted without an explicit y. For Boss直聘 / LinkedIn (whose ToS prohibit automation), it doesn't even try — it opens the page and shows you the data to paste manually.
Is my personal data safe in the public repo?
Yes by design. outputs/ (compiled PDFs + tracker CSV), history/, docs/experience_bank.md, and your real .tex variants are all gitignored. The public repo contains only the clean template + code, using YOUR_NAME / your-email@example.com placeholders.
Which editors does the Skill support?
Codex — project skill is under .codex/skills/job-seeker/; start from AGENTS.md and docs/skill/CODEX.md. Cursor — open the repo; skill is under .cursor/skills/job-seeker/ (English + Chinese). See docs/skill/CURSOR.md. WorkBuddy loads from .workbuddy/skills/. Sync after edits: .\scripts\sync_skills.ps1 (Windows) or ./scripts/sync_skills.sh.
Can I start from a PDF or Word doc instead of LaTeX?
Yes. Upload any of .tex / .md / .docx / .pdf and convert to any other — the pipeline routes automatically. PDF is text-only on the way in (extracted with PyMuPDF): a scanned/image PDF has no text layer and will be rejected, and layout/styling is not recovered. Treat PDF-in as "recover the content, then re-typeset with the LaTeX template."
The conversion to DOCX looks lossy — why?
LaTeX ↔ DOCX is fundamentally lossy: custom resume macros (\name, \centerline, \datedsubsection, icons) don't survive. The DOCX is an editable text mirror, never a layout-accurate render. The .tex → .pdf path is the source of truth. (The CLI prints a WARNING on every lossy step.)
🤝 Contributing
Contributions are welcome — and there's plenty to do! A few good first areas:
- New site adapter for an ATS you use (Workday / Greenhouse / Lever variants welcome) — see
apply/adapters/workday_generic.pyas a template. - New conversion adapter (e.g. HTML → PDF, or OCR for scanned PDFs) — implement the
AdapterABC inconvert/adapters/. - More JD → variant rules in
apply/mapping/jd_to_variant.py. - Better field-detection heuristics for the prefill step.
Before opening a PR:
- Read the open-source plan for direction and the privacy strategy.
- Respect the honesty boundaries in
docs/skill/job-seeker/SKILL.md§6 — no resume inflation, no invented metrics. - Add a test under
convert/tests/orapply/tests/and runpytest(33 tests should stay green). - Use placeholders (
YOUR_NAME,your-email@example.com) in any example content — never real personal data.
⭐ Star History
📄 License
MIT — see LICENSE.
The resume_template/ directory is derived from billryan/resume (also MIT). All bundled fonts retain their original licenses.