Turn your AI coding history into a versioned, reviewer-ready résumé — for the vibe coding era.
vibe-resume scans every AI assistant you use on macOS (Claude Code, Cursor, GitHub Copilot, Cline, Continue, Aider, Windsurf, Zed AI, ChatGPT / Claude.ai / Gemini / Grok / Perplexity / Mistral exports, ComfyUI, Midjourney, Suno, ElevenLabs, and your git commits) and synthesizes the usage trail into a Markdown / DOCX / PDF résumé with built-in git snapshots so every draft is diff-able and rollback-able.
| vibe-resume | Reactive Resume / OpenResume | Resume-LM / Resume Matcher | HackMyResume / JSON Resume | |
|---|---|---|---|---|
| Primary signal | AI tool sessions + git commits (auto-extracted) | User-typed content in WYSIWYG | Uploaded PDF + JD | User-typed JSON |
| Locales | 10 (en_US/en_EU/en_GB/zh_TW/zh_HK/zh_CN/ja_JP/ko_KR/de_DE/fr_FR) with culture-specific layouts | 1–2 | 1 | Theme-dependent |
| JP 履歴書 JIS Z 8303 grid | ✅ render/japan.py |
❌ | ❌ | ❌ |
| Europass labelled personal-info | ✅ en_EU template |
❌ | ❌ | ❌ |
| Reviewer audit | 8-point scorecard + trend sparkline | — | ATS score only | — |
| JD tailoring | enrich --tailor JD.txt (LLM prompt injection) |
— | ✅ LLM rewrite | — |
| Privacy | Fully local; claude -p headless; nothing leaves your machine |
Varies (OpenAI-key optional) | Cloud API required | Fully local |
| Shape | Python CLI pipeline | Web UI | Web UI | Node CLI |
| Agent-Skill hosts | 8 (Claude Code · Gemini CLI · Copilot CLI · Cursor · Warp · OpenClaw · OpenCode · Hermes) — single canonical SKILL.md | — | — | — |
Hiring in 2026 rewards engineers who can prove AI-assisted productivity with measurable outcomes — not just list "Claude Code" as a skill. Reviewers want to see architecture decisions, cross-stack breadth (frontend / backend / DevOps / bug-fix / deployment), and how fast you ship. Your AI tools already log this automatically. vibe-resume turns that exhaust into evidence.
| Source | Where |
|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl |
| Claude Code Archive | ~/ClaudeCodeArchive/current (optional rsync backup) |
| Cursor | ~/Library/Application Support/Cursor/User/**/state.vscdb |
| GitHub Copilot (VS Code) | workspaceStorage/**/chatSessions/ |
| Cline | globalStorage/saoudrizwan.claude-dev/ or ~/.cline/data/ |
| Continue.dev | ~/.continue/sessions/ |
| Aider | $HOME/**/.aider.chat.history.md |
| Windsurf / Cascade | ~/.codeium/windsurf/cascade/ |
| Zed AI | ~/.local/share/zed/threads/ |
| Claude Desktop | MCP config + extensions |
| Git commits | every .git in $HOME filtered by your author email |
ChatGPT · Claude.ai · Gemini Takeout · Grok · Perplexity · Mistral Le Chat · Poe
image_local (ComfyUI / A1111 PNG metadata) · midjourney (IPTC/XMP) · elevenlabs (history API) · suno (local MP3 ID3) · runway / heygen (stub)
- Task-type classifier — tags each session as frontend / backend / bug-fix / deployment / refactor / testing / etc.
- Capability breadth — counts distinct task categories per project; surfaces multi-skill engineers
- 30-day rolling stats — active-day ratio, daily avg, peak day, longest streak (aligned with Claude Code's 30-day cleanup)
- XYZ enricher — uses Claude Code CLI headlessly to turn raw activity into Google-style résumé bullets
- Tech stack canonicalization —
postgres→PostgreSQL,tailwind→Tailwind CSS - Domain-tag vs hard-skill separation — keeps ATS keywords clean
- Privacy filter — regex redaction + project blocklist + optional tech abstraction
- Versioned output — internal git repo under
data/resume_history/withlist-versions/diff v1 v2/rollback
Use as an Agent Skill (Claude Code · Gemini CLI · Copilot CLI · Cursor · Warp · OpenClaw · OpenCode)
Beyond the CLI, vibe-resume ships as an Agent Skill that drives the full extract → aggregate → enrich → render → review → trend pipeline from natural-language prompts. Inside any supported host you can just say:
"Generate my résumé from my AI usage." "Render my résumé in Japanese and German and review both." "Tailor my résumé for this JD: data/imports/lumen_labs.txt."
The skill follows the 2026 converged SKILL.md convention: one canonical file at skills/ai-used-resume/SKILL.md; every other host path (.claude/skills/, .gemini/skills/, .agents/skills/, .opencode/skills/) is a symlink pointing at it. For marketplace installs, .claude-plugin/plugin.json and .codex-plugin/plugin.json wrap the skill as a Claude Code / OpenAI Codex plugin.
| Host | Discovery | Setup in this repo |
|---|---|---|
| Claude Code | .claude/skills/ |
Canonical — auto-loaded |
| Gemini CLI (Google) | .gemini/skills/ |
Symlink → canonical |
| GitHub Copilot CLI | reads .claude/skills/ natively |
Zero config |
| Cursor CLI | reads AGENTS.md + .cursor/rules/ |
AGENTS.md points at SKILL.md |
| Warp (agentic terminal) | reads .claude/skills/ + .agents/skills/ + .warp/skills/ |
Zero config (.agents/skills/ symlink added defensively) |
| OpenClaw (250k⭐ in 60 days) | ~/.openclaw/skills/ (user scope only) |
User-scope symlink — see below |
| OpenCode (terminal CLI agent) | .opencode/skills/ + ~/.opencode/skills/ |
Project-scope symlink included |
| Hermes Agent (Nous Research) | repo skills/<name>/SKILL.md → installed to ~/.hermes/skills/<category>/<name>/ |
Native skill at skills/ai-used-resume/SKILL.md; hermes skills tap add easyvibecoding/vibe-resume && hermes skills install easyvibecoding/vibe-resume/ai-used-resume |
The 2026 agent-skills ecosystem has converged into four install paths —
pick the one that matches your agent, not eight separate ln -s commands.
Tier 0 — Plugin marketplaces (bundled install, namespaced skill)
# Claude Code (uses .claude-plugin/plugin.json)
/plugin marketplace add easyvibecoding/vibe-resume
/plugin install vibe-resume@vibe-resume
# OpenAI Codex ≥ 0.121 (uses .codex-plugin/{plugin,marketplace}.json)
codex plugin marketplace add easyvibecoding/vibe-resume
codex
/plugins # in the TUI: find vibe-resume and installCodex plugin support shipped in codex-cli v0.121.0 (2026-04-15). On older Codex, fall back to Tier 1 (npx skills add …). In the TUI's /plugins pane you can also add the marketplace interactively instead of the shell command.
Plugins wrap the skill plus future commands/agents/hooks/MCP servers in
one installable unit. Skill is exposed as /vibe-resume:ai-used-resume
(namespaced) instead of bare /ai-used-resume.
Tier 1 — 37+ agentskills.io-standard hosts (one line installs to all)
npx skills add easyvibecoding/vibe-resume --skill ai-used-resumenpx skills auto-detects every installed CLI/IDE agent on your machine and
routes the skill to the correct directory. This one command covers Claude
Code, Cursor, Windsurf, Gemini CLI, GitHub Copilot, Codex, Qwen Code, Kimi
Code, Roo Code, Kilo Code, Goose, Trae, OpenCode, Amp, Antigravity, Kiro,
Factory, Junie, and more. To restrict, pass -a <slug>:
npx skills add easyvibecoding/vibe-resume -a claude-code -a cursor -a windsurfFull list of Tier-1 agent slugs (for -a flag)
Slugs verified against skills@latest on 2026-04-22. Run npx skills add … -a unknown to have the CLI print the up-to-date list.
| Agent | slug | Agent | slug | |
|---|---|---|---|---|
| Amp | amp |
Kilo Code | kilo |
|
| Antigravity | antigravity |
Kimi Code CLI | kimi-cli |
|
| Augment | augment |
Kiro CLI | kiro-cli |
|
| Claude Code | claude-code |
Mistral Vibe | mistral-vibe |
|
| Cline | cline |
opencode | opencode |
|
| CodeBuddy | codebuddy |
OpenHands | openhands |
|
| Codex CLI | codex |
Pi | pi |
|
| Continue | continue |
Qoder | qoder |
|
| Cursor | cursor |
Qwen Code | qwen-code |
|
| Gemini CLI | gemini-cli |
Replit | replit |
|
| GitHub Copilot | github-copilot |
Roo | roo |
|
| Goose | goose |
Trae | trae / trae-cn |
|
| IBM Bob | bob |
Warp | warp |
|
| iFlow CLI | iflow-cli |
Windsurf | windsurf |
|
| Junie | junie |
Zencoder | zencoder |
Universal fallback: -a universal drops the skill under .agents/skills/, which Claude Code / Codex / Gemini CLI / Cursor / Warp / Amp / Cline / OpenCode / Antigravity read natively — one install covers all of them. Latest slug list: vercel-labs/skills.
Tier 2 — OpenClaw (own ClawHub marketplace + 5,400+ skill registry)
openclaw skills install easyvibecoding/vibe-resume/ai-used-resumeTier 3 — Hermes Agent (own skills.sh registry + native 5-section body format)
hermes skills tap add easyvibecoding/vibe-resume
hermes skills install easyvibecoding/vibe-resume/ai-used-resume --force --yesManual install / symlink fallback (no Node, custom paths, Windows)
If you can't run npx skills or want full control over symlink locations:
# Tier 1 hosts — symlink from this repo's canonical SKILL.md (at skills/)
mkdir -p ~/.claude/skills && ln -s "$(pwd)/skills/ai-used-resume" ~/.claude/skills/ai-used-resume
mkdir -p ~/.gemini/skills && ln -s "$(pwd)/skills/ai-used-resume" ~/.gemini/skills/ai-used-resume
mkdir -p ~/.warp/skills && ln -s "$(pwd)/skills/ai-used-resume" ~/.warp/skills/ai-used-resume
mkdir -p ~/.opencode/skills && ln -s "$(pwd)/skills/ai-used-resume" ~/.opencode/skills/ai-used-resume
# Cursor reads project-root AGENTS.md zero-config. For system-wide, copy to ~/.cursor/rules/.Windows (elevated PowerShell):
New-Item -ItemType SymbolicLink -Path $HOME\.claude\skills\ai-used-resume `
-Value (Resolve-Path .claude\skills\ai-used-resume)
# repeat for .gemini / .warp / .opencodeIn every 2026 host, the skill auto-fires when your prompt matches the description line of the SKILL.md frontmatter — so natural-language trigger phrases like "generate my résumé from my AI usage", "render my résumé in Japanese", "tailor my résumé for this JD", "score my résumé", or "show my résumé trend" are enough in most tools. Most hosts also expose an explicit invocation path:
| Host | Auto-trigger | Explicit invocation |
|---|---|---|
| Claude Code | ✅ via description match |
/ai-used-resume slash command |
| Gemini CLI | ✅ activate_skill tool loads on match |
after install, run /agents refresh once to index |
| GitHub Copilot CLI | ✅ description match | gh skill install easyvibecoding/vibe-resume (uses repo skills/ layout) |
| Cursor CLI | ✅ AGENTS.md at project root auto-applies |
content also copyable into .cursor/rules/ |
| Warp | ✅ agent picks from available skills | /ai-used-resume slash command or searchable skills menu |
| OpenClaw | ✅ matches description at load | /ai-used-resume or openclaw skills install easyvibecoding/vibe-resume |
| OpenCode | ✅ via internal SkillTool |
/ai-used-resume slash command |
| Hermes Agent | ✅ matches description | hermes chat -s ai-used-resume -q "generate my résumé" preload form |
A quick verification prompt for any host: "Walk me through generating my
résumé from AI usage — don't run anything, just describe the 6 commands in
order." If the skill is correctly loaded, the response names extract → aggregate → enrich → render → review → trend and matches uv run vibe-resume
syntax. End-to-end verified in Hermes with hermes chat -Q -s ai-used-resume.
See AGENTS.md for the full matrix, Windows symlink commands, and Hermes Agent install notes.
# 1. install
uv venv && uv pip install -e ".[dev]"
# 2. fill your profile
cp profile.example.yaml profile.yaml
$EDITOR profile.yaml # at least name / target_role
# config.yaml auto-bootstraps from config.example.yaml on first run
# 3. (optional) drop cloud ZIP exports into data/imports/<tool>/
# 4. run pipeline
uv run vibe-resume extract # parallel extract with progress bar
uv run vibe-resume aggregate # group by project + infer stack
uv run vibe-resume enrich # XYZ bullets via claude -p
uv run vibe-resume render -f all # md + docx + pdf + git snapshot| Command | What it does |
|---|---|
vibe-resume extract [--only NAME] |
run extractors, cache to data/cache/*.json |
vibe-resume aggregate |
group by project, classify task types, infer stack |
vibe-resume enrich [-n N] [--locale L] [--tailor JD.txt] [--persona KEY] |
generate summary + achievements (XYZ for en, noun-phrase for zh/ja/de/fr/ko); --tailor biases toward a JD's keywords; --persona biases toward a reviewer archetype (see § Reviewer personas) |
vibe-resume render -f md|docx|pdf|all [--locale L] |
render + git snapshot |
vibe-resume render --all-locales [-f FMT] |
fan out across every registered locale in one pass |
vibe-resume render --tailor data/imports/jd.txt |
tailor for a specific job description |
vibe-resume review [-v N | --file PATH] [--locale L] [--jd JD.txt] [--persona KEY] |
score against the 8-point checklist; --persona appends a persona-specific lens at the end of the report |
vibe-resume trend [--locale L] |
score history per locale with ASCII sparkline + mean + latest grade |
vibe-resume completion {bash|zsh|fish} [--install] |
print or install a shell completion script so --locale <tab> expands |
vibe-resume status |
show per-source activity counts |
vibe-resume list-versions / vibe-resume diff 1 2 |
resume version history |
vibe-resume ships per-locale templates so the same profile.yaml + project
data renders into reviewer-appropriate output in each market.
See docs/samples/ for illustrative outputs in
en_EU (Europass), ja_JP (職務経歴書), and zh_TW (繁中).
uv run vibe-resume render -f md --locale en_US # ATS-optimized US default
uv run vibe-resume render -f md --locale zh_TW # 台灣繁中履歷
uv run vibe-resume render -f all --locale ja_JP # 履歴書 (DOCX grid) + 職務経歴書 (md/pdf)
uv run vibe-resume render -f md --locale de_DE # Lebenslauf with Persönliche Daten block| Locale | Style | Photo | Headings | Special |
|---|---|---|---|---|
en_US (default) |
XYZ action-verb | forbidden | Summary / Skills / Experience / … | Flat ATS-friendly skills line |
en_EU |
XYZ action-verb | optional | Personal information / Work experience / Education and training / … | Europass-styled — labelled personal-info list, CEFR languages, GDPR-minimal (no DOB by default) |
en_GB |
XYZ action-verb | forbidden | Personal statement / … | UK spellings, CEFR languages |
zh_TW |
noun-phrase | optional | 自我介紹 / 技能專長 / 工作經歷 / … | 全形分隔, 中英技術混排 |
zh_HK |
noun-phrase | optional | Personal Profile 個人簡介 / Work Experience 工作經驗 / … | Bilingual EN + 繁 headings; CEFR; no HKID |
zh_CN |
noun-phrase | optional | 个人简介 / 专业技能 / … | 简体, 大厂偏美式 |
ja_JP |
noun-phrase | expected | 職務要約 / 職務経歴 / … | DOCX = JIS Z 8303 履歴書 grid (render/japan.py); md = 職務経歴書 |
ko_KR |
noun-phrase | expected | 자기소개 / 보유 기술 / 경력 / … | 자기소개서 left as separate doc |
de_DE |
noun-phrase | expected | Persönliche Daten / Berufserfahrung / … | Renders dob / nationality when set |
fr_FR |
noun-phrase | optional | Profil / Compétences / Expérience / … | 1 page jr / 2 pages senior |
UserProfile is extra="allow", so any <field>_<locale> key sits next to its
canonical English original and templates pick the right one via the
localized Jinja filter:
title: "Senior Full-stack Engineer"
title_zh_TW: "資深全端工程師"
title_ja_JP: "シニアフルスタックエンジニア"
summary: "Full-stack engineer who…"
summary_zh_TW: "全端工程師,熟悉 React / Next.js…"
experience:
- title: "Senior Full-stack Engineer"
title_zh_TW: "資深全端工程師"
company: "Lumen Labs"
company_zh_TW: "Lumen Labs(種子輪 AI SaaS)"
bullets:
- "Reduced query latency from 1.8s to 620ms..."
bullets_zh_TW:
- "查詢中位延遲從 1.8 秒降至 620 毫秒…"Optional locale-conditional personal fields (dob, gender, nationality,
mil_service, photo_path, marital_status) are documented in
profile.example.yaml. They render only when (a) the active locale's
personal_fields list includes them and (b) the value is non-empty.
The full design rationale and per-locale field matrix is in
docs/resume_locales.md.
The renderer picks a locale by checking four sources in order and stops at the first one that is set:
--localeon the CLI (highest priority)profile.preferred_localeinprofile.yamlconfig.render.localeinconfig.yamlen_USfallback
# profile.yaml — always render ja_JP unless CLI overrides
preferred_locale: ja_JP
# config.yaml — team default
render:
locale: en_US
all_locales_formats: ["md", "docx"] # what --all-locales produces per localeRunning vibe-resume render --locale zh_TW always wins over preferred_locale;
omit it and profile.preferred_locale takes over. The same chain applies
when enrich dispatches the LLM prompt, so the right language label is
injected regardless of which knob you turn.
For final-cut day when you need the full pack for different markets:
uv run vibe-resume render --all-locales # defaults to config.render.all_locales_formats
uv run vibe-resume render --all-locales -f docx # force a specific format
uv run vibe-resume render --all-locales --tailor jd.txt # one JD, every locale--all-locales iterates the full LOCALES registry (currently 10 locales).
Per-locale formats are controlled by config.render.all_locales_formats
(default ["md"]) — bump it to ["md", "docx", "pdf"] to cut full bundles.
--locale and --all-locales are mutually exclusive.
A résumé that wins a Tech Lead screen often loses an HR-first funnel, and
vice versa. --persona adds a third axis (orthogonal to locale and JD)
that biases how each bullet is phrased — same candidate, same activity
data, but re-voiced for the expected reader.
| Key | Reader | What this reader skims for |
|---|---|---|
tech_lead |
Staff+ engineer / Tech Lead | Named systems, specific perf numbers, trade-off verbs (migrated / replaced / introduced) |
hr |
HR manager / recruiter | Career trajectory, collaboration, plain-language business impact; acronym soup gets skipped |
executive |
VP / hiring manager | Business outcomes in $ / scale / team-size; each role's lead bullet should read as a headline |
startup_founder |
Early-stage founder | End-to-end ownership, shipping velocity, resourcefulness; enterprise-process framing gets discounted |
academic |
Research hiring committee | Methodological rigour, datasets, benchmarks, citation-style framing |
Compose with locale and JD freely — each dimension hits a different part of the prompt:
# Same person, three audiences, Japanese market
uv run vibe-resume enrich --persona tech_lead --locale ja_JP -n 3
uv run vibe-resume render -f all --locale ja_JP
uv run vibe-resume review --persona tech_lead --locale ja_JP
uv run vibe-resume enrich --persona hr --locale ja_JP -n 3
uv run vibe-resume render -f all --locale ja_JP # overwrites the draft
uv run vibe-resume review --persona hr --locale ja_JP
# Executive lens + JD-tailored + English
uv run vibe-resume enrich --persona executive --tailor data/imports/jd.txt --locale en_US -n 3
uv run vibe-resume render -f md --locale en_US --tailor data/imports/jd.txt
uv run vibe-resume review --persona executive --jd data/imports/jd.txtReviewer personas never fabricate — the bias is a re-voicing
instruction; numbers, people, and decisions that the raw activity
doesn't support stay out. The review --persona form appends a
short lens-specific advisory block at the bottom of the scorecard.
Pass comma-separated keys (or all) to produce parallel variants for
different audiences without re-extracting:
# Write three persona-specific enrich caches in one command
uv run vibe-resume enrich --persona tech_lead,hr,executive --locale en_US
# Render each persona's variant — filename includes the persona suffix
uv run vibe-resume render --persona tech_lead --locale en_US # → resume_vNNN_tech_lead.md
uv run vibe-resume render --persona all --locale en_US # fan out across every persona
# Side-by-side diff of bullets across personas (quality iteration)
uv run vibe-resume personas-compare -n 3Each persona writes to data/cache/_project_groups.<persona>.json so
variants don't clobber each other. The default _project_groups.json
is preserved for persona-less runs. Render filenames include a
_<persona> suffix when set.
personas-compare is the quality-iteration tool: it aligns the top-N
groups across every persona cache it finds and prints each group's
role label + bullets side by side. If two personas produce the same
output, the bias isn't biting — revise core/personas.py or the raw
activity until they differentiate.
70 bundled company profiles and 6 career-level archetypes let you
tailor enrich + review output against a specific hiring bar — orthogonal
to locale, persona, and JD tailor. Each profile is a YAML at
core/profiles/<key>.yaml with fact-check metadata (last_verified_at)
so stale data surfaces loudly instead of silently biasing résumés.
Inspect the bundled catalogue:
# Grouped by tier — frontier_ai / ai_unicorn / regional_ai / tw_local /
# us_tier2 / eu / jp / kr
uv run vibe-resume company list
uv run vibe-resume company list --tier jp
# Full profile in human-readable form (must-haves, red flags,
# keyword anchors, enrich_bias, review_tips, verified date)
uv run vibe-resume company show openai
# Age table across all 70 — flags profiles past the 90-day threshold
# (quarterly-refresh cadence matched to current AI-hiring market churn)
uv run vibe-resume company audit
uv run vibe-resume company audit --only-stale --stale-days 90Apply a company and level when enriching + reviewing:
# Tailor bullets for an OpenAI senior-IC résumé
uv run vibe-resume enrich --company openai --level senior --locale en_US -n 3
uv run vibe-resume render -f all --locale en_US
uv run vibe-resume review --company openai --level senior --locale en_US
# Same activity, different employer — each adds an employer-specific
# keyword-coverage score (0/10) to the review card on top of the 8-point
# base rubric
uv run vibe-resume review --company anthropic --level senior --locale en_US
uv run vibe-resume review --company rakuten --level senior --locale ja_JPEvery --company apply auto-checks verification age. If the profile
is older than 90 days, the CLI prints a loud warning and suggests the
refresh path — it never silently biases a résumé against stale research.
Refresh a stale profile:
# Delegate a fact-check to the claude CLI agent (max ~5 web queries).
# The report lands in data/verification_reports/<key>_<YYYY-MM-DD>.md.
uv run vibe-resume company verify openai
# If the agent returns VERDICT: clean, auto-bump the verified date:
uv run vibe-resume company verify openai --apply
# After a manual web-browser fact-check, bump the date yourself:
uv run vibe-resume company mark-verified openai
uv run vibe-resume company mark-verified openai --date 2027-01-15 --yesmark-verified rewrites only the one YAML line, preserving comments,
folded-string formatting, and any hand-edited fields. Adding a brand-new
profile is drop-in: write core/profiles/<key>.yaml, set
last_verified_at: "YYYY-MM-DD", and it is immediately registered,
packaged into the wheel, and consumable by --company.
Career levels (--level): new_grad · junior · mid · senior ·
staff_plus · research_scientist. Each archetype bakes in the
lead-bullet signal the reviewer expects at that bracket, so mid-level
bullets don't get promoted into staff claims the candidate cannot defend.
After rendering, score the output against the same 8-point checklist a real reviewer applies:
uv run vibe-resume review # latest version
uv run vibe-resume review -v 9 # specific version
uv run vibe-resume review -v 12 --jd jd.txt # add JD-keyword echo scoringEach draft is graded on:
- Top fold — name + target role + at least one concrete metric in the first ~12 lines
- Numbers per bullet — ≥60% of work-section bullets carry a metric
- Keyword echo (JD) — JD's top capitalized terms present in the draft (skipped without
--jd) - Action-verb first — past-tense verb at bullet start (XYZ locales)
- Density (noun-phrase) — bullets self-sufficient, no dangling pronouns (noun-phrase locales)
- Red flags — locale-aware photo / DOB / "References available upon request" / consecutive-heading checks
- Contact line width — header line fits printed page width without ugly wrap (CJK chars count double)
- Page count — line+wrap-based estimate vs locale target (US/UK ≤2, DE/JP/KR ≤3)
Outputs data/reviews/<draft>_review.md and .json for diffing across
iterations. A grade ≥ B/(80%) is the bar before sending the draft to a real
reviewer.
Every review run drops a JSON artefact into data/reviews/, and trend
folds them into one per-locale summary so you can see whether each market
version is improving or regressing as you iterate:
uv run vibe-resume trend # all locales
uv run vibe-resume trend --locale zh_TW Locale Runs First Latest Mean Grade Trend
en_US 6 58/80 v16: 78/80 91.0% A ▂▅▆▇██
ja_JP 3 50/80 v14: 72/80 82.5% A ▁▅█
zh_TW 4 42/80 v15: 74/80 85.0% A ▁▃▆█
The sparkline uses U+2581..U+2588 Unicode blocks so it renders in any monospace terminal. Columns: run count, first score, latest score (with version number), cross-run mean %, grade of the latest run, and the per-run trend.
Claude Code purges session JSONL transcripts older than 30 days by default. To keep history long-term:
# 1. extend retention
python3 -c "import json,pathlib; p=pathlib.Path.home()/'.claude/settings.json'; \
d=json.loads(p.read_text()); d['cleanupPeriodDays']=365; \
p.write_text(json.dumps(d,indent=2,ensure_ascii=False))"
# 2. periodic rsync backup (included)
chmod +x scripts/backup_claude_projects.sh
./scripts/backup_claude_projects.sh
# then register as launchd / cron for weekly backupscripts/backup_claude_projects.ps1 is the PowerShell-7 equivalent that uses
robocopy /MIR /XO to mirror %USERPROFILE%\.claude\projects into
%USERPROFILE%\ClaudeCodeArchive\current, with a dated snapshot on the side:
# one-off run
pwsh -NoProfile -File scripts\backup_claude_projects.ps1
# dry-run (also works on macOS/Linux — great for smoke-testing)
pwsh -NoProfile -File scripts\backup_claude_projects.ps1 -WhatIf
# register as a weekly task (Sundays 03:00)
schtasks /Create /TN "vibe-resume backup" /XML scripts\vibe-resume-backup.xmlscripts/vibe-resume-backup.xml is a ready-to-import Task Scheduler template.
Edit the <WorkingDirectory> path before importing to point at wherever you
cloned this repo. The PowerShell script is linted by PSScriptAnalyzer in CI
on windows-latest, and the -WhatIf branch is also exercised there.
vibe-resume/
├── profile.example.yaml # committed template — copy to profile.yaml
├── config.example.yaml # committed template — auto-copied to config.yaml on first run
├── profile.yaml # your PII (gitignored)
├── config.yaml # your extractor paths + privacy rules (gitignored)
├── cli.py # entry point (also installed as `vibe-resume`)
├── core/
│ ├── schema.py # Pydantic v2: Activity, ProjectGroup, UserProfile
│ ├── classifier.py # 18 task categories with bilingual regex
│ ├── tech_canonical.py # hard-skill vs domain-tag split
│ ├── stats.py # rolling window stats (30d/7d)
│ ├── privacy.py # redaction + blocklist + tech abstraction
│ ├── aggregator.py # grouping + headline + significance ranking
│ ├── enricher.py # claude -p → XYZ / noun-phrase bullets per locale
│ ├── review.py # 8-point scorecard + trend sparkline
│ ├── versioning.py # git snapshots of drafts
│ └── runner.py # ThreadPoolExecutor pipeline + rich.progress
├── extractors/
│ ├── local/ # 11 local extractors
│ ├── cloud_export/ # 7 ZIP importers
│ └── api/ # 6 AIGC extractors
├── render/
│ ├── renderer.py # md / docx / pdf
│ ├── japan.py # JIS Z 8303 履歴書 grid (ja_JP DOCX path)
│ ├── i18n.py # LOCALES registry + per-locale label dicts
│ └── templates/resume.<locale>.md.j2
├── scripts/
│ ├── backup_claude_projects.sh # macOS / Linux rsync
│ ├── backup_claude_projects.ps1 # Windows PowerShell 7 (robocopy)
│ ├── vibe-resume-backup.xml # Task Scheduler import template
│ └── com.vibe-resume.backup.plist # macOS launchd agent
├── data/
│ ├── imports/ # put downloaded ZIPs here (gitignored except sample_jd.txt)
│ ├── cache/ # per-source extracted JSON (gitignored)
│ ├── resume_history/ # rendered outputs + internal git (gitignored)
│ └── reviews/ # review reports + history (gitignored)
├── docs/samples/ # illustrative locale-specific sample outputs
├── skills/ai-used-resume/ # canonical Agent Skill (all 8 hosts, via symlinks)
│ ├── SKILL.md # 5-section body, agentskills.io compliant
│ └── references/ # strategic-resume · troubleshooting · extending
├── .claude/skills/ai-used-resume/ → symlink → skills/ai-used-resume/
├── .gemini/skills/ai-used-resume/ → symlink → skills/ai-used-resume/
├── .agents/skills/ai-used-resume/ → symlink → skills/ai-used-resume/ (Codex + Warp)
├── .opencode/skills/ai-used-resume/ → symlink → skills/ai-used-resume/
├── .claude-plugin/plugin.json # Claude Code plugin manifest (marketplace)
└── .codex-plugin/plugin.json # OpenAI Codex plugin manifest (marketplace)
# extractors/local/mytool.py
from core.schema import Activity, ActivityType, Source
NAME = "mytool"
def extract(cfg: dict) -> list[Activity]:
return [] # emit Activity objectsRegister in core/runner.py → LOCAL_EXTRACTORS and enable in config.yaml.
- Full
$HOMEscan (git_repos,aider) takes 1-3 min first run even with 4× parallel extractors — switch toscan.mode: whitelistto scope it._find_reposhas a 120s wall-clock deadline to survive FUSE mounts / broken symlinks. - Grok / Perplexity / Mistral export schemas are lenient parsed (schema not officially published); drop a real sample into
data/imports/if fields don't match. - Claude Desktop chat contents are encrypted in Local Storage — only MCP config + extensions are extractable.
- PDF rendering requires
pandoc+ XeLaTeX for CJK; falls back to plain pandoc otherwise.
MIT — see LICENSE.
Searched the 2026 landscape thoroughly — no direct competitor does all three of (1) multi-source AI-tool extraction, (2) 10-locale rendering, and (3) reviewer audit. The closest adjacent projects cover only one of the three:
- whoisjayd/gitresume — closest adjacent tool; extracts from local/remote GitHub repos → résumé bullets. Single-source (git only), single-language.
vibe-resumeadds 18 AI-tool extractors, 10 locales, and the reviewer audit. - AmirhosseinOlyaei/AI-Resume-Builder — generates bullets from PR descriptions and commit messages. Same thesis, narrower source (no Claude Code / Cursor / ChatGPT).
- AndreaCadonna/resumake-mcp — LaTeX résumé via MCP; render-only, no extraction layer. Complementary to our pipeline's render stage.
- javiera-vasquez/claude-code-job-tailor — YAML experience → JD-tailored PDF in Claude Code. Complementary at the JD-match stage; our
--tailoris the same idea but starts from extracted activity rather than hand-maintained YAML.
vibe-resume is the only tool in this list that extracts from multiple AI tools + renders in 10 culture-specific locales + includes reviewer audit with trend tracking.


