Render resume JSON to print-ready HTML using Jinja templates.
Project description
cv-claw
Render a resume JSON file into a print-ready, self-contained HTML document via Jinja2 templates. The primary user is Claude (or any shell-capable agent): produce JSON, then run one command to hand the user a real artifact — no browser, no dev server required.
A small live-preview dev server is available behind an optional extra.
Install
This project uses uv.
uv sync
To include the optional dev server and PDF backends:
uv sync --all-extras
Quickstart
uv run cv-claw render resumes/example.json
# → writes resumes/example.html next to the JSON
The dev repo keeps its example JSON under resumes/, but in your own
workspace the JSON can live anywhere — cv-claw just renders whichever
path you give it. To keep generated HTML out of the way:
uv run cv-claw render path/to/resume.json --output-dir build/
# → writes build/resume.html
Open the HTML in a browser and use the browser's print dialog to export to PDF.
CLI
render
cv-claw render <input.json> [flags]
Validate the JSON, look up the template, and write a standalone HTML
file. By default the output lands next to the input with an .html
suffix.
| Flag | Default | Description |
|---|---|---|
-o, --output <path> |
<input>.html |
Single explicit output file. Wins over --output-dir. |
--output-dir <dir> |
— | Output directory; filename is <input-stem>.html. Directory is created if missing. |
--template <name> |
from JSON | Override the template field in the resume JSON for this render only. |
--templates-dir <dir> |
auto-discover | Replace the default search roots (workspace + bundled) with a single directory. |
list-templates
cv-claw list-templates [flags]
Print discovered template names, one per line. Default output annotates
each entry with its source: (workspace) for templates under
./.cvclaw/templates/, (bundled) for those shipped inside cv-claw.
| Flag | Default | Description |
|---|---|---|
--templates-dir <dir> |
auto-discover | Replace the default search roots with a single directory; drops the source annotation. |
validate
cv-claw validate <input.json>
Run schema validation only. Exits 0 on success, non-zero on failure. Useful as a sanity check before rendering.
serve
cv-claw serve [flags]
Run a small live-reload dev server. Requires the optional [serve]
extra (uv sync --all-extras or pip install 'cv-claw[serve]').
| Flag | Default | Description |
|---|---|---|
--host <addr> |
127.0.0.1 |
Host to bind to. |
-p, --port <int> |
8000 |
Port to listen on. |
--resumes-dir <dir> |
CWD | Directory of resume JSON files to serve. |
--templates-dir <dir> |
auto-discover | Replace the default template search roots with a single dir. |
Global
| Flag | Description |
|---|---|
--version |
Show version and exit. |
Schema
A resume is a JSON document with a template, a header, and a list of
sections. Each section is one of four kinds — prose, keyvalue,
list, or timeline — and is dispatched to the matching renderer in
the template.
Using the skill in your own workspace
The skills/cv-claw/ directory ships a single
Agent Skill covering three resume tasks —
ingest (PDF/image/text → JSON), tailor (adapt for a job description),
and create-template (new Jinja2 layout). The main SKILL.md stays
small; each task lives under references/ and is loaded on demand.
To use:
- Install cv-claw in your workspace:
uv add cv-claw(orpip install cv-claw). - Copy
skills/cv-claw/into your workspace's skills directory. - Point your agent at it and start producing resume JSON.
Templates
Templates live in two roots, both auto-discovered:
- Bundled — ship inside the cv-claw package (e.g.
classic). Read-only; they come down withpip install cv-claw. - Workspace — under
./.cvclaw/templates/<name>/in your current working directory. Optional; created on first use by the skill.
A workspace template shadows a bundled template of the same name —
that's the supported way to fork. The .cvclaw/ prefix is reserved for
cv-claw workspace state; today it holds templates/, and future
versions may add cache or config under the same prefix.
A typical workspace tree:
my-resume-workspace/
├── resumes/ # or wherever you keep your JSON
│ └── default.json
└── .cvclaw/
└── templates/
└── minimalist/
├── minimalist.html.j2 # entry point
├── minimalist.css # inlined into the rendered HTML
└── _macros.html.j2 # optional section renderers
Files and directories starting with _ are treated as partials and are
skipped by template discovery. Add a new template by dropping in a new
folder with the same shape (the create-template task
automates the scaffolding).
Resume JSON conventions
cv-claw doesn't impose a directory for your resume JSON — pass any
path on the CLI and it just works. The bundled skill (used by Claude
Code and other agent surfaces) asks the user once where resume JSON
should live and can record the answer in your workspace CLAUDE.md
under a ## cv-claw: resume location heading so future sessions don't
re-ask.
Development
make install # uv sync --all-extras
make lint # ruff check
make format # ruff format
make check # ruff check + ruff format --check
make render # render resumes/example.json
make clean # remove caches and build artifacts
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cv_claw-0.1.0.tar.gz.
File metadata
- Download URL: cv_claw-0.1.0.tar.gz
- Upload date:
- Size: 12.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c90b93db61262d2d956321a59cfd431fce18e9703ae32d75eb4fb6e503f0252
|
|
| MD5 |
af0d1fa8aee0a58a4f6ba3799d6f23a9
|
|
| BLAKE2b-256 |
5fdf47ba20a59cb50a355d26377f699ea6b8e65d9f5a5f93d70aa6e21ada6e65
|
Provenance
The following attestation bundles were made for cv_claw-0.1.0.tar.gz:
Publisher:
release.yml on farhan0167/cv-claw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cv_claw-0.1.0.tar.gz -
Subject digest:
7c90b93db61262d2d956321a59cfd431fce18e9703ae32d75eb4fb6e503f0252 - Sigstore transparency entry: 1551983591
- Sigstore integration time:
-
Permalink:
farhan0167/cv-claw@8c1f90cfd0dbe605d31a12d83a8d1b0b7bbfb246 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/farhan0167
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8c1f90cfd0dbe605d31a12d83a8d1b0b7bbfb246 -
Trigger Event:
release
-
Statement type:
File details
Details for the file cv_claw-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cv_claw-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b97b12a64c2822bca67d727361e801bafa4ab85fca04371f00ff11cd79933578
|
|
| MD5 |
ab3835bb8bc87e9686bb610a9256e580
|
|
| BLAKE2b-256 |
6249e895909565815f487cd89c91413f068c0f2ff0a8c72242fb454bbcc14e6c
|
Provenance
The following attestation bundles were made for cv_claw-0.1.0-py3-none-any.whl:
Publisher:
release.yml on farhan0167/cv-claw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cv_claw-0.1.0-py3-none-any.whl -
Subject digest:
b97b12a64c2822bca67d727361e801bafa4ab85fca04371f00ff11cd79933578 - Sigstore transparency entry: 1551983602
- Sigstore integration time:
-
Permalink:
farhan0167/cv-claw@8c1f90cfd0dbe605d31a12d83a8d1b0b7bbfb246 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/farhan0167
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8c1f90cfd0dbe605d31a12d83a8d1b0b7bbfb246 -
Trigger Event:
release
-
Statement type: