Skip to main content

AI-powered resume tailor — tailor your CV to any job posting with ATS-optimized PDFs

Project description

Chameleon — Resume Tailor

Python 3.10+ MIT License OpenCode Claude Code Codex

Tailor your master resume to any job posting with AI. Produces ATS-optimized PDFs without inventing experience. Works as a TUI, CLI, or via AI assistant (OpenCode / Claude Code / Codex).


Why Chameleon?

Problem Chameleon
Generic resume rejected by ATS Tailored keywords + invisible ATS injection
Fabricated skills get caught Strict no-fabrication rules enforced by AI and code
Lost track of applications Persistent analysis — JSON artifacts saved for reuse
Manual tailoring takes hours 4-pass pipeline runs in under 2 minutes
No feedback loop Score every CV against the JD with category breakdowns
Scattered job platforms 20-platform scanner with API, RSS, and scraping

Quick Start

Prerequisites

Install

git clone https://github.com/davidalecrim1/chameleon.git
cd chameleon
make install-tools          # creates .venv + installs rendercv

Makefile Targets

Target Usage Description
install-tools make install-tools Create .venv, install rendercv[full]
render make render FILE=<yaml> Render a CV YAML to PDF
tailor make tailor JD=<text> COMPANY=<name> Tailor CV for a job posting
score make score JD=<text> Score job match against profile
scan make scan QUERY=<query> Scan job platforms
scan-all make scan-all Scan all 20 platforms
scan-tier1 make scan-tier1 Scan Tier 1 platforms only
list-platforms make list-platforms List available scanner platforms

Three Ways to Use

1. TUI — Full Terminal UI

./tui.sh

Browse scored jobs from 20 platforms, tailor with Ctrl+T, view diffs between master and tailored YAML, and edit config live — all in the terminal.

6 Tabs:

Tab Shortcut Shows
Jobs Ctrl+1 Scanned/pasted jobs with scores, gap analysis, experience fit
Editor Ctrl+2 Inline nano-style editor for job descriptions
Profile Ctrl+3 GitHub profile (languages, tech stack, matching repos)
Scanner Ctrl+4 Live pipeline logs — scan progress, tailor phases, render status
Tailored Ctrl+5 Tailored CVs with diff view, scores, PDF links
Settings Ctrl+6 Live config editor — paths, scan queries, score weights, fonts, colors

Keybindings:

Key Action
Ctrl+Q Quit (with confirmation)
Ctrl+S Scan job platforms
Ctrl+Shift+S / F2 Custom scan with platform/query options
Ctrl+N Paste a job description
Ctrl+E Edit selected job description
Ctrl+T Tailor CV for selected job
Ctrl+R Re-score all jobs
Ctrl+D Delete selected job
Ctrl+O Open job URL in browser
Enter Show job detail or tailored CV diff
/ Focus search bar
F1 Help screen
F5 Refresh / re-score
↑/↓ Navigate rows

Full reference: docs/TUI.md


2. AI Assistant — Slash Commands

opencode     # or claude, or codex
Command What it does
/init-cv <path> Import master CV from PDF or YAML
/chameleon <url-or-text> Full pipeline: analyze → tailor → render
/tailor-cv --analysis <id> --cv <name> Tailor from saved analysis
/score-cv --analysis <id> --cv <path> Score against analysis
/cover-letter <url-or-text> Generate cover letter
/question "<text>" Answer screening question
/render-cv [file] Re-render a YAML to PDF
/scan-jobs [--query] Scan job platforms
/job-matcher score --job-url <url> Score job against your profile

3. CLI — Headless / Scripting

# ── Unified CLI (recommended) ──────────────────────────────────────────

# Tailor a CV from text
./chameleon tailor "Senior Rust Engineer at Acme Corp..." --company Acme

# Tailor from a URL (auto-crawls the job posting)
./chameleon tailor https://jobs.example.com/senior-rust-engineer

# Tailor from a file
./chameleon tailor jd.txt --company Acme --title "Rust Engineer"

# Pipe a job description via stdin
cat jd.txt | ./chameleon tailor --company Acme

# Score a job match against your profile
./chameleon score "Python developer, Django, PostgreSQL..."
./chameleon score https://jobs.example.com/python-dev --json

# Scan job platforms
./chameleon scan -q "rust engineer" --tier1
./chameleon scan -q "python" -p remoteok,remotive --json
./chameleon scan --all --limit 10 -o output/scans/results.json

# Render a YAML to PDF
./chameleon render templates/david_acme_rust_engineer_cv.yaml

# ── Windows ─────────────────────────────────────────────────────────────
chameleon.bat tailor "Senior Rust Engineer..." --company Acme
chameleon.bat score "Python developer..."
chameleon.bat scan -q "rust engineer" --tier1

# ── Direct Python modules (alternative) ─────────────────────────────────

# Tailor a CV directly
python3 -m scripts.tailor_cv "Senior Rust Engineer at Acme..." --company Acme --title Engineer

# Score a job against your profile
python3 -m scripts.job_matcher "Python developer..." --json

# Scan job platforms
python3 -m scripts.job_scanner.scanner --query "rust engineer" --platforms remoteok,hn_hiring --json

# Render a YAML
make render FILE=templates/david_acme_rust_engineer_cv.yaml

# ── Make targets ────────────────────────────────────────────────────────

make tailor JD="Senior Rust Engineer..." COMPANY=Acme
make score JD="Python developer..."
make scan QUERY="rust engineer" PLATFORMS=remoteok,hn_hiring
make scan-all QUERY="python"
make scan-tier1
make list-platforms

Example Workflow

# 1. Import your master CV
/init-cv ~/Documents/resume.pdf
# → templates/david_cv.yaml

# 2. Tailor for a job posting
/chameleon https://jobs.example.com/senior-engineer-123
# → Analysis:      output/job_analyses/a7c19f2d__Acme__Rust_Engineer.json
# → Tailored YAML: templates/david_acme_rust_engineer_cv.yaml
# → PDF:           output/david_acme_rust_engineer_cv.pdf

# 3. Score the result against the same analysis
/score-cv --analysis a7c19f2d --cv templates/david_acme_rust_engineer_cv.yaml
# → Score: 85/100 (Languages: 22, Frameworks: 20, Domains: 23, CV Alignment: 20)

How It Works

4-Pass Pipeline

When you invoke a tailor (Ctrl+T or /chameleon), the pipeline runs in 4 passes:

Pass 1: TailoringBrief     Algorithmic JD analysis — seniority, gaps, repo matching
Pass 2: AI Tailor          LLM rewrites summary, reorders highlights/skills
Pass 3: AI Review          Double review with tiebreaker, applies corrections
Pass 4: Render             rendercv → PDF (+ optional ATS ghost injection)

ATS Ghost Injection

When ats_ghost_enabled is on, the PDF is post-processed to inject invisible keyword text (font-size: 1px, color: white) at the bottom of every page. This ensures ATS parsers see important keywords even if the layout is unusual. Extra terms can be configured in Settings.


Project Layout

.chameleon/              Config JSON, SQLite DB, fonts, cache
.claude/                 AI skills + agents (OpenCode / Claude Code)
.agents/                 AI skills + agents (Codex)
opencode.json            OpenCode project config (12 commands, permissions)
templates/               Master + tailored CV YAMLs
output/                  Rendered PDFs, job analysis JSONs
profiles/                GitHub profile data
chameleon.sh             CLI entry point (Unix/Mac)
chameleon.bat            CLI entry point (Windows)
scan.sh / scan.bat       Quick scanner wrapper
score.sh / score.bat     Quick scorer wrapper
tui.sh / tui.bat         TUI launcher
scripts/
  tui/                   Textual TUI (6 tabs, 19 keybindings)
  job_scanner/           20-platform job scanner
  tailor_cv.py           4-pass pipeline entry point
  tailor_brief.py        Algorithmic JD analysis
  tailor_prompts.py      AI prompt templates
  job_matcher.py         Scoring engine (4-category rubric)
  config.py              JSON-backed configuration
  db.py                  SQLite persistence
  render.py              RenderCV wrapper
  ats_ghost.py           Invisible ATS keyword injection
docs/
  ARCHITECTURE.md        Component architecture, data flow, config ref
  TUI.md                 Full TUI keybinding and tab reference

Configuration

All settings live in .chameleon/config.json. Editable live via the Settings tab.

Category Key Default Description
Paths master_cv_path templates/my_cv.yaml Master CV YAML
profile_path profiles/github_repos.json GitHub profile JSON
opencode_bin_path ~/.opencode/bin/opencode Path to opencode binary
Scan scan_queries ["python", "rust", "ai engineer"] Default scan queries
scan_platforms "remoteok,remotive,hn_hiring" Default platforms
Scoring score_weight_* 25 each Category weights (total 100)
score_threshold_strong 80 Minimum score for "strong match"
score_threshold_good 60 Minimum score for "good match"
score_threshold_moderate 40 Minimum score for "moderate match"
CV Design cv_font_family "Source Sans Pro" Font for rendered PDF
cv_font_size_body 9.5pt Body font size
cv_line_spacing 0.8em Line spacing
cv_entry_spacing 0.2cm Space between entries
cv_primary_color #2b3a67 Primary accent color
cv_secondary_color #3a5a8c Secondary accent color
cv_page_margin_* 1.0-1.5cm Page margins
ATS ats_ghost_enabled true Invisible keyword injection
ats_ghost_extra_terms "django, flutter, ..." Extra ATS keywords
ats_ghost_font_size 1 Font size for ghost text (px)
ats_ghost_color #ffffff Font color for ghost text

Constraints

  • Never fabricate experience, skills, metrics, titles, or dates
  • Preserve all facts — company names, titles, locations, dates are immutable
  • Never edit the master CV — always write a new file to templates/
  • Match JD language — if the JD says "CI/CD" and your CV says "continuous integration", use "CI/CD"
  • 2 pages max — drop lower-impact bullets before adding new ones

Troubleshooting

Symptom Likely Cause Fix
Ctrl+T does nothing No job selected Select a row in the Jobs tab first
Tailor hangs / never completes opencode binary not found Set opencode_bin_path in Settings tab
Tailor hangs / never completes opencode timeout (180s default) Wait — long prompts take time; check Scanner tab for progress
make render fails RenderCV not installed Run make install-tools
Scan returns no results Platform parser needs update Try --platforms hn_hiring (most stable parser)
Tailored tab is empty Tailor never succeeded Check Scanner tab for error messages
Ctrl+T says "already in progress" Previous tailor still running Wait for completion or restart the TUI
PDF has no content / blank Incompatible YAML schema Run /init-cv on your master CV to normalize
AI assistant command not found Skill not loaded Check opencode.json has .claude/skills in skills array
ATS ghost not working Feature disabled Enable ats_ghost_enabled in Settings tab
Job URLs not opening No open/xdg-open on system Install xdg-utils (Linux) or check OS path

Architecture

┌──────────┐  ┌──────────┐  ┌──────────────────┐
│   TUI    │  │   CLI    │  │  AI Assistant     │
│ (Textual)│  │ (Python) │  │ (Claude/Codex/OC) │
└────┬─────┘  └────┬─────┘  └────────┬─────────┘
     │             │                  │
┌────┴─────────────┴──────────────────┴──────────┐
│              Python Backend                      │
│  tailor_cv.py  tailor_brief.py  job_matcher.py   │
│  config.py     db.py            render.py         │
│  job_scanner/  ats_ghost.py                      │
└──────────────────────────────────────────────────┘
     │             │                  │
┌────┴─────────────┴──────────────────┴──────────┐
│              Storage                             │
│  .chameleon/   templates/   output/   profiles/  │
└──────────────────────────────────────────────────┘

Key design decisions:

  • Layered architecture — interfaces never touch storage directly
  • Subprocess kill registry — no orphan processes on crash
  • TeeStream — stdout from background threads appears in TUI log in real time
  • Crash-safe notifications — debug toasts never throw, even during shutdown

See docs/ARCHITECTURE.md for full detail.


OpenCode Integration

This project provides opencode.json at the root — OpenCode auto-loads it on open:

  • 12 slash commands registered with usage hints (/chameleon, /tailor-cv, /score-cv, etc.)
  • Skill paths: .claude/skills/ and .agents/skills/ scanned for SKILL.md definitions
  • All standard tools pre-authorized (read, edit, bash, glob, grep, task, webfetch, websearch, question, skill)
  • Batch tool enabled for parallel operations
  • Instructions: AGENTS.md loaded as project context

For Claude Code: CLAUDE.md (synced copy of AGENTS.md) is auto-loaded on open.


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

chameleon_cv-0.1.0.tar.gz (90.0 kB view details)

Uploaded Source

File details

Details for the file chameleon_cv-0.1.0.tar.gz.

File metadata

  • Download URL: chameleon_cv-0.1.0.tar.gz
  • Upload date:
  • Size: 90.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for chameleon_cv-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8c980281a6cdb277fe13d28cfe43434d42b70fcc93a907c9cc6c744033233c84
MD5 b19a9513c1cd5b6c2c96195d10ad1fa6
BLAKE2b-256 dc07a5fc20b28a096600f656c4ff4f3e1b1f8f9e6fc8e8ea97c69bd4bd42a4aa

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