Documentation
Zero learning curve: resumable is a single command that handles the entire workspace initialization, resume data import, job description tailoring, and document rendering workflow. You work from a single folder and let the interactive command guide you.
Install
The installer detects your OS and architecture and downloads the matching prebuilt binary from GitHub Releases into ~/.local/bin. No Rust toolchain required.
curl -fsSL https://resumable-cli.towhid.space/install.sh | bash
Supported platforms
- macOS —
x86_64(Intel) andarm64(Apple Silicon) - Linux —
x86_64andarm64(glibc) - Windows — use WSL
Environment overrides
| Variable | Default | Purpose |
|---|---|---|
RESUMABLE_INSTALL_DIR | ~/.local/bin | Where the binary is installed |
RESUMABLE_REPO | itsTowhid/resumable-cli | GitHub repo to pull releases from |
RESUMABLE_VERSION | latest | Release tag to install (e.g. v0.1.0) |
Build from source
Prefer to compile it yourself? Clone the repo and build with Cargo:
$ git clone https://github.com/itsTowhid/resumable-cli $ cd resumable-cli $ cargo build --release # binary at target/release/resumable
Quick start (Zero Learning Curve)
To run the entire workflow end-to-end, you only need to run a single command:
$ mkdir job-hunt && cd job-hunt $ resumable
The interactive wizard will automatically guide you through configuring your settings, importing your resume data, tailoring it for a job posting, rendering it to PDF/HTML, and opening the resulting folder. Simply run resumable again at any point to pick up where you left off.
Prerequisites
- One AI CLI installed and logged in, auto-detected in this order:
agy— Antigravity CLI (default / highest priority)claude— Claude Codecodex— OpenAI Codex CLI
- For PDF output: a Chromium-based browser (Google Chrome, Chromium, or Microsoft Edge). A puppeteer-downloaded Chrome (
~/.cache/puppeteer) is also detected.
No AI CLI installed? Install the free Antigravity CLI (agy) from antigravity.google.
Commands
Every subcommand at a glance. Bare resumable runs the interactive workflow or resumes where you left off.
| Command | What it does |
|---|---|
resumable | Runs interactive setup, import, tailor, or render flow |
resumable init | Scaffold a workspace: writes .config/resumable.config.json |
resumable tailor | Tailor your resume to a job description; writes resume.md only |
resumable render | Render a folder, .md, or resume .json to HTML/PDF — no AI |
resumable import | Parse a pdf/docx/txt/md/json into .config/user_data.json |
resumable templates | List available templates with status (✓/✗) |
resumable --version | Print the installed version |
resumable --help | Show help for any command |
init
Set up a workspace: writes .config/resumable.config.json (the user data file is created during the import step).
resumable init [--dir <path>] [--force]
| Flag | Default | Description |
|---|---|---|
--dir <path> | . | Directory to initialise |
--force | off | Overwrite existing files |
$ mkdir job-hunt && cd job-hunt $ resumable init
tailor
Tailor your resume to a job description. Provide the JD in one of three ways (in priority order):
--url <url>— fetch a job posting URL and extract readable text from the HTML--jd <file>— read the JD from a local file- Interactive menu — when neither flag is given, choose from: enter a URL, read from
job_description.txt(if it exists), or paste the JD text
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, then prints the exact render command to run.
resumable tailor [--url <url> | --jd <file>] [--resume <file>] [--ai claude|codex|agy] [--force]
| Flag | Default | Description |
|---|---|---|
--url <url> | — | Fetch the job description from a URL (e.g. a job posting link) |
--jd <file> | — | Read the job description from a file |
--resume <file> | from config | Override the resume data file |
--ai <backend> | auto-detect | Force a specific AI CLI: claude, codex, or agy |
--force | off | Overwrite output files if they already exist |
--url and --jd are mutually exclusive — pass one or the other (or neither for the interactive menu).
$ resumable tailor --url https://jobs.example.com/senior-engineer $ resumable tailor --jd role.txt --ai claude $ resumable tailor # interactive menu $ resumable # bare command == tailor
render (no AI)
Render an already-tailored resume, or preview your data, without touching the AI. 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>.
resumable render <input> [--template <name>] [--html] [--pdf] [--photo <file>] [--force]
| Arg / flag | Default | Description |
|---|---|---|
<input> | — | Company folder, a .md file, or a resume .json |
--template <name> | from config, else compact | Render a single design instead of all enabled |
--html | off | Render a styled HTML file |
--pdf | on (when neither flag given) | Render a PDF |
--photo <file> | from config | Embed a profile photo |
--force | off | Overwrite output files if they already exist |
With no --template, it renders every template enabled in the config (so you can compare designs); --template <name> forces a single one. PDF is the default when neither --html nor --pdf is given.
$ resumable render Bright-Labs # one PDF per enabled template $ resumable render Bright-Labs/resume.md --template elegant --html $ resumable render .config/user_data.json --pdf # straight from resume data
import
Already have a résumé? import reads a PDF / Word doc / text file and produces .config/user_data.json. The AI only structures the text it finds; it does not invent data, and leaves unknown fields empty.
resumable import --from <file> [--out <file>] [--ai claude|codex|agy] [--force]
| Flag | Default | Description |
|---|---|---|
--from <file> | — | Source file to read (required) |
--out <file> | .config/user_data.json | Output JSON path |
--ai <backend> | auto-detect | Force a specific AI CLI |
--force | off | Overwrite the output file if it already exists |
Supported sources: .pdf, .docx, .txt, .md, .json, and any UTF-8 text file. (Legacy .doc — export to PDF/DOCX/TXT first.)
$ resumable import --from old_resume.pdf $ resumable import --from cv.docx --out .config/user_data.json
templates
List available design templates with status (✓/✗), or manage customization via subcommands.
resumable templates [set | import | eject <name>]
Subcommands
- set — Interactive checklist to enable or disable templates.
- import — Extract visual style from a URL or file path (image/text document) into
.config/custom.css. Includes a guardrail that validates the source has resume-like content, and allows a custom instructions prompt to guide the AI for precise styling corrections. - eject <name> — Eject a built-in template's CSS stylesheet to customize it.
$ resumable templates
Available templates:
✗ classic Traditional serif, centered header — safe for any industry
✗ modern Clean sans-serif with a blue accent — tech / startup
✗ minimal Airy, light weights, lots of whitespace
✗ two-column Two-column layout with a dark sidebar
✗ elegant Serif headings over a sans body, warm accent rule
✓ compact Dense layout for maximizing content per page
Configuration
resumable init writes .config/resumable.config.json:
{
"resumeData": ".config/user_data.json",
"templates": {
"classic": false,
"modern": false,
"minimal": false,
"two-column": false,
"elegant": false,
"compact": true,
"custom": false
},
"customTemplate": null,
"formats": { "markdown" : true, "html": false, "pdf": true },
"photo": "avatar.png",
"ai": null
}
| Key | Meaning |
|---|---|
resumeData | Your resume data JSON file (defaults to .config/user_data.json) |
templates | Designs to render — enable as many as you like; render produces one file per enabled template (defaults to compact) |
customTemplate | Optional path to a custom CSS template file (defaults to .config/custom.css on import) |
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 (prioritizing agy) |
Design templates
Six print-optimized CSS themes. Enable any number under templates in the config (each renders its own file), or pass --template <name> to render just one.
| Template | Description |
|---|---|
classic | Traditional serif, centered header — safe for any industry |
modern | Clean sans-serif with a blue accent — tech / startup |
minimal | Airy, light weights, lots of whitespace |
two-column | Two-column layout with a dark sidebar |
elegant | Serif headings over a sans body, warm accent rule |
compact | Dense layout for maximizing content per page |
Add your own by dropping a .css file in templates/ and registering it in src/templates.rs.
Two-Column Custom Layouts: The renderer can dynamically transform the document into a sidebar + main column layout. By defining --layout: two-column; and --sidebar-sections: "contact, skills, etc"; on :root in your custom CSS, the renderer will automatically extract the specified sections into a .sidebar div and the rest into a .content div.
Resume data formats
The resume JSON is auto-detected as either shape:
- camelCase Profile (app shape): top-level
personalInfo,education,experience, … — this is whatinit/importwrite. - snake_case seed: top-level
profilewithfull_name,field_of_study, …
App-only fields (ids, completeness, template/photo preferences) are ignored.
Notes & guarantees
- 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. - Always review
resume.mdbefore rendering — the AI can misread your data (wrong emphasis, dropped details, or reworded facts).