Claude-skill-registry generate-resume
Generate a print-optimized, ATS-friendly single-page resume PDF from portfolio content. Use when user wants to create or regenerate their resume. (project)
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/generate-resume" ~/.claude/skills/majiayu000-claude-skill-registry-generate-resume && rm -rf "$T"
skills/data/generate-resume/SKILL.mdResume Generator
<purpose> Generate a single-page PDF resume using Puppeteer to render the `/resume` React page. Optimized for ATS (Applicant Tracking Systems) and print. </purpose><when_to_activate> Activate when the user:
- Asks to generate, create, or update their resume
- Says "create my resume", "make a resume", "export resume PDF"
- Wants to refresh the resume after updating portfolio content
- Asks about resume format or PDF generation
Trigger phrases: "resume", "generate resume", "PDF", "export resume", "make resume" </when_to_activate>
Critical Files
| File | Purpose |
|---|---|
| React component for print-optimized layout |
| Print/screen styles with theme isolation |
| Puppeteer PDF generation script |
| Name, email, location, tagline, stats |
| Jobs with highlights |
| Categorized skills |
| Default output file |
Design Principles
1. Never Cut Experience
Critical: Include ALL jobs from
content/experience/index.yaml. Missing experience (especially major companies) damages credibility more than a slightly longer resume.
- If page is too long → reduce highlights per job, NOT number of jobs
- Set
to match total jobs in experience fileMAX_JOBS - Every role adds signal; cutting roles removes career trajectory
2. Metrics Over Descriptions
Highlights should follow Action → Outcome format with quantified results:
❌ "Managed product development" ✅ "Shipped Advanced API from 0→1: 17 methods serving 1M+ daily requests"
3. ATS-First Design
- Plain text (no images, icons, or complex layouts)
- Standard fonts: Georgia, Times New Roman (serif) or Arial, Helvetica (sans)
- Clear section headers: Header, Summary, Experience, Skills
- All text must be selectable/copyable
4. Single Page Target
One-page resumes get 2x more callbacks. Fit content by:
- Reducing highlights per job (2-3 is sufficient)
- Tightening typography (9-10pt base)
- Never by cutting jobs
Format Guidelines
Layout Constants (ResumePage.tsx)
const RESUME_CONFIG = { SUMMARY_SKILL_CATEGORIES: 2, // Categories in impact summary SKILLS_PER_CATEGORY: 3, // Skills per category in summary SUMMARY_COMPANIES: 4, // Companies to list in summary MAX_JOBS: 6, // Include ALL jobs - adjust to match your experience MAX_HIGHLIGHTS_PER_JOB: 3, // Bullets per job (action → outcome format) };
Adjust
to match the total number of jobs in your experience file.MAX_JOBS
Resume Structure
- Header: Name / Current Role + contact info (email, location)
- Impact Summary: One-liner tagline + top skills + notable companies + key stats
- Professional Experience: Each job with company, role, period, location, and bullets
- Skills: 2-column grid organized by category
Skills Section Layout
Skills are displayed in a 2-column grid with category names in bold:
Category A: skill1, skill2, skill3... | Category B: skill1, skill2... Category C: skill1, skill2, skill3... | Category D: skill1, skill2...
Categories are pulled from
content/skills/index.yaml. Common category structures:
For Engineers:
- Languages & Frameworks, Infrastructure, Databases, Tools
For Product Managers:
- Domain Expertise, Product Leadership, Technical Execution, Tools
For Designers:
- Design Tools, Research Methods, Platforms, Collaboration
Typography (ResumePage.css)
- Font: Georgia / Times New Roman (ATS-safe serif)
- Base size: 9.5pt
- Line height: 1.35
- Page: Letter size (8.5in × 11in)
- Margins: 0.4in top/bottom, 0.5in left/right
Known Issues & Fixes
1. Black Box at Bottom of PDF
Cause: ThemeProvider applies dark background (#08080a) to body/#root, which bleeds into the PDF outside the
.resume-page container.
Fix: CSS must override parent elements in
@media print:
@media print { html, body, #root { background: white !important; min-height: auto !important; padding: 0 !important; margin: 0 !important; } }
2. PDF Exceeds One Page
Fix: Reduce
MAX_HIGHLIGHTS_PER_JOB in ResumePage.tsx. Do NOT reduce MAX_JOBS - missing experience is worse than a slightly longer resume.
3. Missing Experience/Jobs
Cause:
MAX_JOBS was set too low, cutting off important companies.
Fix: Always set
MAX_JOBS to the total number of jobs in content/experience/index.yaml. Count your jobs and update the config.
4. Yellow/Colored Underline on Role Title
Fix: Ensure
.resume-role-highlight has no border-bottom or background-color.
5. Theme Colors Bleeding Through
Fix: Reset all children with:
.resume-page * { background: transparent; color: inherit; }
6. Fonts Not Loading in PDF
Fix: The script waits for
document.fonts.ready + 500ms buffer. If fonts still don't load, increase POST_FONT_BUFFER_MS in generate-resume.ts.
Generation Workflow
Prerequisites
- Dev server running:
npm run dev - Content files populated:
(name, email, location, tagline, stats)content/profile.yaml
(jobs with highlights)content/experience/index.yaml
(categorized skills)content/skills/index.yaml
Steps
- Validate content:
npm run validate - Preview at http://localhost:5173/resume
- Verify single-page fit (no vertical scrollbar)
- Check all experience is included
- Generate:
npm run generate:resume
- Verify output at
public/resume.pdf
Custom Filename
npm run generate:resume -- --name "Jane Smith" # Output: public/jane-smith.pdf
Custom URL
npm run generate:resume -- --url http://localhost:3000 # Uses different dev server port
Troubleshooting
| Issue | Solution |
|---|---|
| "net::ERR_CONNECTION_REFUSED" | Start dev server: |
| PDF is blank | Check browser console at /resume for React errors |
| Wrong content displayed | Verify YAML files, run |
| Fonts look wrong | Increase in script |
| Two pages instead of one | Reduce , NOT |
| Dark background in PDF | Verify print CSS overrides html/body/#root |
| Jobs missing | Increase to match total in experience file |
| Skills look cramped | Reduce number of skills per category or categories |
After Generation
Update hero CTA in
content/profile.yaml to link to the resume:
hero: cta: secondary: label: "Download Resume" href: "/resume.pdf"
Technical Details
Puppeteer Configuration (generate-resume.ts)
const PAGE_DIMENSIONS = { LETTER: { WIDTH_PX: 816, // 8.5" at 96dpi HEIGHT_PX: 1056, // 11" at 96dpi }, }; const TIMING = { POST_FONT_BUFFER_MS: 500, // Wait after fonts.ready PAGE_LOAD_TIMEOUT_MS: 30000, // Navigation timeout };
PDF Export Settings
await page.pdf({ path: output, format: 'letter', printBackground: true, margin: { top: '0.4in', right: '0.5in', bottom: '0.4in', left: '0.5in', }, preferCSSPageSize: true, });
Content Sources
The resume pulls data from these content files:
| Data | Source | Field |
|---|---|---|
| Name | | |
| | |
| Location | | |
| Tagline | | |
| Stats | | |
| Jobs | | |
| Skills | | |
Quality Checklist
Before Generating
- Content YAML files pass validation (
)npm run validate - Preview at /resume shows correct info
- ALL jobs are included (count them!)
- Resume fits on single page (no scrollbar)
- All highlights follow "Action → Outcome" format
- Metrics are quantified (%, $, numbers)
After Generating
- Open PDF and verify visual appearance
- Check all text is selectable (ATS-friendly)
- Verify no dark backgrounds or visual artifacts
- Confirm all companies/roles are present
- Test PDF in an ATS simulator if available