npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

chameleon-cv

v0.1.0

Published

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

Readme

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.