Skip to main content

VITA — CV as Code : personal CV management CLI

Project description

VITA — CV as Code

One base CV. Infinite targeted variants. Zero duplicates.

vita-cv is a CLI tool that treats your resume like source code — versioned with git, branched per company, built from LaTeX, and sharpened with AI assistance.

VITA can generate targeted AI prompts or run an autonomous AI workflow to analyze job descriptions, identify gaps, improve keywords, and adapt your CV title, summary, skills, and experience for each application.

uv tool install vita-cv

How It Works

VITA manages your CV using git branches:

Branch Purpose
master Your canonical base — the CV you're always proud of
gen-<role> Domain-specific base (e.g. gen-swe, gen-ml)
etp-<company>-<role> Tailored CV for a specific application (e.g. etp-google-swe)

Every time you apply somewhere, you create a branch. VITA tracks that in a registry so you never accidentally send the wrong version or apply twice.


Prerequisites

  • uvinstall (pip install uv or curl -LsSf https://astral.sh/uv/install.sh | sh)
  • Python 3.10+ — managed automatically by uv
  • Git (must be in PATH)
  • LaTeXTeX Live or MiKTeX, with latexmk

Quick Start

# 1. Install vita from PyPI as a persistent tool
uv tool install vita-cv
# → vita is now available globally in your terminal

# 2. Create your CV project directory
mkdir my-cv && cd my-cv

# 3. Initialize VITA (creates .vita/ and git repo)
vita init

# 4. Edit .vita/config.json — set your name
#    "author": "yourname"

# 5. Create your LaTeX CV (see below)
# ... write main.tex, sections/, etc.

# 6. Commit your base CV
git add .
git commit -m "base: initial CV"

# 7. Apply to a company
vita new etp google "software engineer"
# → creates branch etp-google-swe, updates registry

# 8. Tailor your CV for this job, then build
vita build

Your CV Project Structure

After running vita init, your project should look like this:

my-cv/
├── main.tex              ← LaTeX entry point (you create this)
├── sections/             ← Modular CV sections (you create these)
│   ├── experience.tex
│   ├── education.tex
│   ├── skills.tex
│   └── ...
├── job.md                ← Paste job descriptions here (for AI prompts)
├── out/                  ← PDF output (auto-created on build)
│
└── .vita/                ← Auto-created by `vita init`
    ├── config.json       ← Your settings (author, output paths, etc.)
    ├── companies.json    ← Registry of all companies you've applied to
    ├── extensions.json   ← Your custom role aliases, languages, and LLM providers
    ├── .env              ← Local API keys for --auto mode
    ├── .env.example      ← Example API key file
    └── logs/             ← CLI activity log

.vita/ is gitignored — your registry and config stay local.


Files You Need to Create

VITA manages the .vita/ directory for you. You are responsible for the LaTeX files.

main.tex — Entry Point

Your main LaTeX file. VITA will compile this with latexmk. Example minimal structure:

\documentclass{article}

\begin{document}

\input{sections/experience}
\input{sections/education}
\input{sections/skills}

\end{document}

You can use any LaTeX CV class (e.g. moderncv, altacv, awesome-cv).

sections/ — Modular Content

Split your CV into files so each branch only touches relevant sections:

sections/
├── experience.tex   ← Work history (most frequently changed per company)
├── education.tex    ← Education
├── skills.tex       ← Skills (adjust keywords per role)
├── summary.tex      ← Optional: tailored headline
└── projects.tex     ← Optional

job.md — Job Description (for AI prompts)

When you run vita adapt or vita analyze, VITA looks for job.md in your project root. Paste the job posting there:

Company: Google
Role: Senior Software Engineer

[Paste full job description here]

Configuration Reference

vita init creates .vita/config.json with these defaults:

{
  "author": "",
  "output_dir": "out",
  "output_filename": "cv-{author}.pdf",
  "tex_entry": "main.tex",
  "build_mode": "auto",
  "default_base_branch": "master",
  "strict_mode": false,
  "allow_multiple_per_company": true,
  "warn_on_duplicate": true
}
Key What it does
author Your name — used in the PDF filename
output_dir Where the compiled PDF goes (out/ by default)
output_filename PDF name template. {author} is substituted automatically
tex_entry Your LaTeX entry file (default: main.tex)
build_mode Reserved build mode setting (auto by default)
default_base_branch The branch vita new checks out from if no base exists
strict_mode Reserved stricter workflow setting (false by default)
allow_multiple_per_company Reserved duplicate-policy setting
warn_on_duplicate If true, warns (but doesn't block) on duplicate company

CLI Commands

vita init

Initialize VITA in the current directory. Creates .vita/, scaffolds config files, and runs git init.

vita init          # first-time setup
vita init --force  # wipe and re-initialize

vita new etp <company> <role>

Create a new tailored CV branch for a job application.

vita new etp google "software engineer"
vita new etp openai ml
vita new etp stripe "backend engineer" --commit  # commit pending changes first
  • Normalizes the role (software engineerswe)
  • Creates branch etp-<company>-<role> off your base branch
  • Registers the company in .vita/companies.json
  • Warns if you've already applied to this company

vita status

See all companies, branches, and where you currently are.

vita status
VITA Status — yourname
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Current branch : etp-google-swe

Companies (2):
  google  [2 CVs]
    ├── etp-google-swe   base: gen-swe   ← you are here
    └── etp-google-ml    base: gen-ml

  meta  [1 CV] [LOCKED]
    └── etp-meta-swe     base: gen-swe

Base branches:
  gen-swe · gen-ml
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

vita sync

Reconcile the .vita directory and registry with your actual git branches. Useful if you created or deleted branches manually, or if local .vita files such as config.json, extensions.json, .env, or generated artifact directories are missing.

vita sync              # interactive
vita sync --dry-run    # preview only, no changes written
vita sync --auto       # apply all changes without prompting

vita save

Stage all changes, commit them, and push to the remote repository.

vita save
vita save -m "update Google CV"
vita save -r
  • -m/--message sets a custom commit message.
  • Without -m, VITA uses a generic commit message.
  • -r/--reconcile saves the current branch, checks out master, runs vita sync --auto, then saves master.

vita build

Compile your LaTeX CV to PDF using latexmk.

vita build

Output goes to out/cv-<author>.pdf (or whatever you configured).


vita diff <company>

Show what changed in a company branch versus its base.

vita diff google

vita lock / unlock <company>

Lock a company to prevent creating new CVs for it (e.g. you've accepted an offer).

vita lock amazon
vita unlock amazon

vita analyze

Generate an AI prompt to analyze your CV against the job in job.md.

vita analyze
vita analyze --auto
vita analyze --auto --provider codex

Without --auto, VITA saves the prompt to .vita/current_prompt.md; open it and give it to your AI assistant.

With --auto, VITA sends the prompt and local context to your configured LLM provider and saves the report to .vita/results/analyze.md.

job.md can contain one role, or multiple roles from the same company using # Job N sections:

# Job 1
Software Engineer, Infrastructure

# Job 2
Research Engineer, GenAI

When multiple jobs are detected, vita analyze --auto and vita run --auto produce one unified cross-role analysis with per-job scores and an overall match probability.


vita adapt [--language <code>]

Generate an AI prompt to tailor your CV to the job in job.md.

vita adapt               # English (default)
vita adapt --language fr # French
vita adapt --language ar # Arabic
vita adapt --auto --provider gemini

VITA adapts the CV title/headline, professional summary, experience, and skills based on the job description. For multi-job job.md files, it creates one coherent CV optimized for shared requirements across all listed roles instead of separate CV versions.


vita review

Generate an AI prompt to review and improve your CV in general.

vita review
vita review --auto

vita run

Run the full AI workflow: analyze → adapt → review.

vita run
vita run --auto
vita run --auto --provider codex
vita run --auto --provider gemini --language fr

Without --auto, this generates prompts. With --auto, VITA calls the configured LLM provider and writes outputs into .vita/results/, updating main.tex during the adapt step.


vita keys

Manage API keys for LLM providers.

vita keys list
vita keys set gemini <your-key>
vita keys remove gemini

Keys are stored locally in .vita/.env. Codex CLI support uses your local Codex login instead of an API key.


Typical Workflow

# Day 1 — Set up your CV project
uv tool install vita-cv
mkdir my-cv && cd my-cv
vita init
# → edit .vita/config.json (set author)
# → write main.tex and sections/

git add .
git commit -m "base: initial CV"

# Applying to a company
git checkout -b gen-swe         # create your domain baseline
# → tailor the CV for SWE roles generally
git add . && git commit -m "gen-swe: baseline"

vita new etp google "software engineer"
# → now on branch etp-google-swe

# Paste job description
echo "..." > job.md
vita analyze    # get analysis prompt
vita adapt      # get tailoring prompt
# → run prompts with AI, apply suggestions to sections/

# Or run the autonomous pipeline with a configured provider
vita run --auto --provider codex

vita build      # compile to PDF
# → out/cv-yourname.pdf

vita status     # review all companies

Building the PDF

VITA uses latexmk automatically. If you need to build manually:

# Standard
latexmk -pdf -outdir=out main.tex

# With bibliography (BibTeX/Biber)
pdflatex -output-directory=out main.tex
biber --input-directory=out --output-directory=out main
pdflatex -output-directory=out main.tex
pdflatex -output-directory=out main.tex

Extensibility

VITA ships with built-in role aliases, language codes, and LLM provider support. You can add your own in .vita/extensions.json (created by vita init):

{
  "llm_providers": {
    "codex": {
      "model": ""
    },
    "gemini": {
      "model": "gemini-2.0-flash"
    }
  },
  "role_aliases": {
    "research engineer": "re",
    "applied scientist": "as",
    "solutions architect": "sa"
  },
  "language_map": {
    "zh": "Chinese (Simplified)",
    "ja": "Japanese"
  }
}

Your entries are merged on top of the built-ins — your values win on conflict. Use --provider with --auto commands to choose a configured LLM provider.

See EXTENSIONS.md for the full list of built-in aliases and all format details.


AI Skills

VITA includes a library of AI agent skills for specialized tasks. Reference them when prompting your AI assistant:

Category Skills
Writing resume-writer, resume-bullet-writer, resume-quantifier
Reviewing resume-reviewer, resume-ats-optimizer
Targeting resume-tailor, job-description-analyzer, resume-section-builder
Documents cover-letter-generator, linkedin-profile-optimizer
Prep interview-prep-generator, salary-negotiation-prep, offer-comparison-analyzer
Specialized tech-resume-optimizer, executive-resume-writer, academic-cv-builder
Transitions career-changer-translator, creative-portfolio-resume

Example usage:

"Use the resume-tailor skill to update sections/experience.tex based on the job description I pasted in job.md."

"Run interview-prep-generator on my CV and generate 5 STAR stories for a Google interview."


Design Philosophy

  • Warn, don't block — duplicate CVs trigger a warning, not a hard stop (--force overrides, locked: true blocks permanently)
  • CLI enforces naming — roles are normalized automatically (data engineerde, machine learning engineerml)
  • Registry is the truth.vita/companies.json is the authoritative record; use vita sync if it drifts from git
  • User-extensible — role aliases and language codes are fully overridable via .vita/extensions.json
  • Local-first — prompt generation, git workflows, and LaTeX builds are local. --auto sends CV/job context to the LLM provider you configure.

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

vita_cv-2.0.2.tar.gz (110.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vita_cv-2.0.2-py3-none-any.whl (128.6 kB view details)

Uploaded Python 3

File details

Details for the file vita_cv-2.0.2.tar.gz.

File metadata

  • Download URL: vita_cv-2.0.2.tar.gz
  • Upload date:
  • Size: 110.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for vita_cv-2.0.2.tar.gz
Algorithm Hash digest
SHA256 b9b4b1d9dc285c3a73163b114f3d4f3aeed60232afe788477cbb9b9d49385d5c
MD5 72629cf5c055d7ab8b4c8300dc7c5e1d
BLAKE2b-256 ada497ccc62bfd1870cb56d0090e2e23388f778b012b071fb45a254e7c56480f

See more details on using hashes here.

File details

Details for the file vita_cv-2.0.2-py3-none-any.whl.

File metadata

  • Download URL: vita_cv-2.0.2-py3-none-any.whl
  • Upload date:
  • Size: 128.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for vita_cv-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d96d19ed1095b0f568d3b09e1d6bafbe9f135bb98b466d51c4afaa9d103335a9
MD5 36c5aa327e9639ecf181f1776133a2d3
BLAKE2b-256 09e9d7b169e0c4dd13aea7eeeebcaff8932a2e9cb032e92761a80b24dd4188fe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page