A CLI that tailors your resume to a job description and renders it as Markdown, styled HTML, and PDF — driven by whichever AI CLI is installed locally.
You work from a single folder: initialise it once, keep your data and preferences there, then run tailor for each job. Every application gets its own subfolder.
- Rust toolchain (
cargo) - One of these AI CLIs installed and logged in (auto-detected in this order):
claude— Claude Codecodex— OpenAI Codex CLIagy— Antigravity CLI
- For PDF output: a Chromium-based browser (Google Chrome, Chromium, or Microsoft Edge). A puppeteer-downloaded Chrome (
~/.cache/puppeteer) is also detected.
cd cli
cargo build --release
# binary at target/release/resumablemkdir job-hunt && cd job-hunt
resumable init # creates resumable.config.json + user_data.json
# fill in user_data.json (or: resumable import --from old_resume.pdf)
resumable tailor # paste a job description, press Ctrl-Dtailor reads your config, asks the AI for the company name, and creates a folder for the application containing the job description and the tailored Markdown — it does not render a PDF yet, so you can review the Markdown first:
job-hunt/
resumable.config.json
user_data.json
Bright-Labs/
job_description.txt
resume.md
It then prints a caution to review resume.md and the exact command to render it. When you're happy:
resumable render Bright-Labs
# -> Bright-Labs/resume_<template>.pdf for each template enabled in configresumable init writes resumable.config.json:
{
"resumeData": "user_data.json",
"templates": { "classic": true, "modern": true, "minimal": false, "elegant": false, "compact": false },
"formats": { "markdown": true, "html": false, "pdf": true },
"photo": "avatar.png",
"ai": null
}| Key | Meaning |
|---|---|
resumeData |
Your resume data JSON file |
templates |
Designs to render — enable as many as you like; render produces one file per enabled template |
formats |
Which outputs render produces (html, pdf) |
photo |
Profile photo embedded in HTML/PDF ("" = none) |
ai |
Backend to use ("claude"/"codex"/"agy"), or null to auto-detect |
If no AI CLI is installed, install the free Antigravity CLI (agy): https://antigravity.google.
resumable init [--dir .] [--force]
resumable import --from <file> [--out user_data.json] # document -> resume JSON (uses AI)
resumable tailor [--jd <file>] [--ai .. --resume .. --force] # writes resume.md only
resumable render <path> [--template .. --html --pdf --photo .. --force] # no AI
resumable templates
resumable # same as `resumable tailor`Paste the job description when prompted (or pass --jd <file> for non-interactive use). It saves the JD to job_description.txt in the company folder and writes the tailored resume.md — nothing else. It does not render a PDF, because AI output should be reviewed first. It prints a caution and the render command to run once you've checked the Markdown.
Render an already-tailored resume, or preview your data, without touching the AI:
resumable render Bright-Labs # renders Bright-Labs/resume.md, one PDF per enabled template
resumable render Bright-Labs/resume.md --template elegant --html
resumable render user_data.json --pdf # straight from resume datarender accepts a company folder (renders its resume.md), a .md file, or a resume .json (formatted to Markdown deterministically). Output is written next to the input as <name>_<template>.<ext>. With no --template, it renders every template enabled in the config (so you can compare designs); --template <name> forces a single one. Photo defaults to the config; PDF is the default when neither --html nor --pdf is given.
Already have a résumé? import reads a PDF / Word doc / text file and produces user_data.json:
resumable import --from old_resume.pdf
resumable import --from cv.docx --out user_data.jsonSupported sources: .pdf, .docx, .txt, .md, .json, and any UTF-8 text file. (Legacy .doc — export to PDF/DOCX/TXT first.) The AI only structures the text it finds; it does not invent data, and leaves unknown fields empty.
The resume JSON is auto-detected as either shape:
- camelCase Profile (app shape,
fe/src/lib/data/types.ts): top-levelpersonalInfo,education,experience, … — this is whatinit/importwrite. - snake_case seed (
scripts/resume_data.json): top-levelprofilewithfull_name,field_of_study, …
App-only fields (ids, completeness, template/photo preferences) are ignored.
classic, modern, minimal, elegant, compact — run resumable templates for descriptions. Each is a print-optimized CSS theme in templates/; add your own by dropping a .css file there and registering it in src/templates.rs.
- The tailoring prompt forbids fabrication: the model may only reword, reorder, emphasize, or omit the supplied data.
- Markdown output is cleaned (code fences unwrapped, preamble before the first
#heading dropped) before writing. - HTML/PDF are produced from the Markdown wrapped in the chosen template's CSS; the PDF is rendered by a headless Chromium browser.
- Existing output files are not overwritten unless
--forceis passed.