Claude-skill-registry format-resume
Intelligently format CV/resume content using semantic understanding and visual verification
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/format-resume" ~/.claude/skills/majiayu000-claude-skill-registry-format-resume && rm -rf "$T"
skills/data/format-resume/SKILL.mdFormat Resume Skill
Purpose
Format CV/resume content with intelligent style application based on semantic context. Uses a clean template with 19 semantic styles and learns from your corrections over time.
Usage
Format new content:
Format this CV: [paste content]
Format from file:
Format my-cv-draft.txt as a resume
How It Works
Key Principle: Intelligence lives in the skill (Claude analyzes text). Python code is just helpers.
-
Semantic Analysis: I (Claude) analyze your raw text to understand what each element represents
- I don't use regex patterns - I understand semantic context
- "Anthony Byrnes" at top → CV Name
- "EDUCATION" in caps → Section Header
- "2023 - Present California State University" → Timeline Entry + Institution
- "Romeo & Juliet" in productions → Play Title (not Job Title, even though both are bold italic!)
-
Create JSON Structure: Convert raw text to structured format with style assignments
-
User Confirmation: Show you my analysis, get confirmation or corrections
-
Apply Learned Patterns: Python helpers apply previously learned preferences
-
Generate Document: Create formatted .docx using template with page headers
-
Visual Preview: Show PDF preview images for review
-
Learn from Corrections: If you correct a style choice, I save it to learned-preferences.yaml
The 19 Styles
Paragraph Styles:
- CV Name - Your name at top
- Contact Name - Bold, 10pt (cover letter header)
- Contact Info - Regular, 10pt (phone/email)
- Recipient Address - Regular, 11pt (organization address)
- RE Line - Bold, 13pt, ORANGE (position/subject line)
- Date Line - Right-aligned, 11pt (document date)
- Section Header - Bold, ORANGE (11pt for CV, 13pt for cover letter)
- Body Text - Standard paragraphs, 11pt
- Timeline Entry - Date + institution with hanging indent (CV only)
- Page Header - Bold, 10pt (page 2+ headers)
- Bullet Standard, Bullet Gray, Bullet Emphasis - List variations
Character Styles (inline):
- Play Title - Bold italic for productions (most common!)
- Institution - Bold for school/company names
- Job Title - Bold italic for positions
- Orange Emphasis - Highlight text
- Gray Text - Dates, secondary info
Note: Shares template with format-cover-letter skill (career-documents-template.docx)
Workflow
Step 1: You Provide Raw Text
User: "Format this CV: [pastes raw text]"
Step 2: I (Claude) Analyze and Create JSON
I analyze your content using semantic understanding (not regex):
I see: - Name: "ANTHONY BYRNES" → CV Name style - Contact: "T: 213.305.3132" → Contact Info style - Section: "EDUCATION" → Section Header (orange, 11pt) - Timeline: "2020-2024 California State University, Long Beach" → Timeline Entry - inline: "California State University, Long Beach" → Institution (bold) - Position: "Interim Associate Dean, College of the Arts" → Body Text - inline: "Interim Associate Dean" → Job Title (bold italic) - Bullet: "Led $29M budget..." → Bullet Standard Here's my JSON interpretation: { "document_metadata": { "type": "cv", "author_name": "ANTHONY BYRNES", "document_title": "Curriculum Vitae", "page_header": { "enabled": true, "left": "ANTHONY BYRNES - Curriculum Vitae", "right": "page" } }, "content": [ {"text": "ANTHONY BYRNES", "style": "CV Name"}, {"text": "T: 213.305.3132", "style": "Contact Info"}, ... ] } Looks correct? (yes/show json/corrections)
Step 3: You Confirm or Correct
- Say "yes" → I proceed to formatting
- Say "Line 5 should be Gray Text" → I update JSON
- Say "show json" → I display full JSON for manual editing
Step 4: Apply Learned Patterns
Python helpers load learned-preferences.yaml and apply any previously learned style rules:
from cv_formatting.learning_system import LearningSystem learning = LearningSystem() content = learning.apply_learned_patterns(content)
This is simple pattern matching - the intelligence came from your previous corrections.
Step 5: Generate Document
I save the JSON and call Python helpers to create formatted .docx:
import json import subprocess from pathlib import Path # Save JSON structure mapping_file = "/tmp/cv_mapping.json" with open(mapping_file, 'w') as f: json.dump(content_mapping, f, indent=2) # Format document (Python helper just applies styles from JSON) result = subprocess.run([ "python3", "format_cv.py", mapping_file, output_path, "--document-type", "cv", "--preview" ], capture_output=True, text=True, cwd=str(Path.home() / "PycharmProjects/career-lexicon-builder"))
Step 6: Visual Preview
I convert to PDF and show you page images.
You can request changes: "That committee role should be gray text"
Step 7: Learn (if corrections made)
If you make corrections, I save them to learned-preferences.yaml:
learning.learn_correction( text="Graduate Studies Advisory Committee", context="service section", preferred_style="Gray Text" )
Next time I analyze a CV, I'll automatically suggest Gray Text for committee roles.
Step 8: Finalize
Once you're happy with the preview, I save the final document (e.g., "anthony-byrnes-cv.docx").
LLM-Based Analysis vs. Regex Patterns
Why LLM analysis (me, Claude) is better:
- ✅ Understands semantic context (not just patterns)
- ✅ Handles variations naturally ("PhD" vs "Ph.D." vs "Doctor of Philosophy")
- ✅ Distinguishes context: "Dean" in experience → Job Title, "Dean" in service → Gray Text
- ✅ Can explain reasoning to you
- ✅ Learns from corrections through conversation
Python helpers only:
- Load defaults from YAML
- Apply previously learned patterns (simple matching)
- Find files, generate dates
- NO semantic analysis in Python code
Example: Bold Italic Context Discrimination
I distinguish based on semantic context, not just formatting:
- "Interim Associate Dean" after "2023 - Present CSULB" → Job Title (follows employer)
- "Romeo & Juliet" in productions list → Play Title (in artistic works context)
Traditional regex can't do this because both are bold italic. I understand the context.
Learning System
Three-layer learning stored in
learned-preferences.yaml:
Layer 1: Style Corrections
style_rules: - pattern: "committee" context: "service section" preferred_style: "Gray Text" learned_date: "2025-11-11" example: "Graduate Studies Advisory Committee"
Layer 2: Metadata Patterns
metadata_defaults: document_title: "Curriculum Vitae" # not "Resume" page_header_enabled: true date_format: "MMMM YYYY"
Layer 3: Section Patterns
section_patterns: EDUCATION: order: ["Timeline Entry", "Body Text", "Bullet Standard"] inline_institution: true
Corrections are automatically saved. No "save preferences" button needed.
You: "That should be gray text, it's a committee role"
Me: "✓ Updated formatting rules: committee roles → Gray Text"
Next CV: Automatically applies gray to committee roles without asking.
Error Handling
If template missing:
- "Template not found. Run generate_cv_template.py first"
If LibreOffice/Poppler unavailable:
- "PDF preview not available (LibreOffice not installed)"
- "Continuing with .docx only..."
If style mapping unclear:
- "I'm not sure if this is a Job Title or Play Title - can you clarify?"
Files
- Shared template with 19 semantic stylescareer-documents-template.docx
- Main formatting scriptformat_cv.py
- Base semantic inference rulesstyle-mappings.yaml
- Your accumulated correctionslearned-preferences.yaml
Page Headers for Multi-Page CVs
CVs spanning multiple pages automatically get professional headers on page 2+:
- Format: "ANTHONY BYRNES - Curriculum Vitae page 2"
- Style: Helvetica 10pt, bold, gray (RGB 128, 128, 128)
- Alignment: Left text aligns with body, right text at 6.5 inches
- Clean first page: No header on page 1
- Same implementation as cover letters (already working!)
Metadata Inference
Python helpers load from
defaults.yaml and generate page header config:
from cv_formatting.metadata_inference import MetadataHelper helper = MetadataHelper() metadata = helper.infer_cv_metadata(content) # Returns: { "type": "cv", "author_name": "ANTHONY BYRNES", "document_title": "Curriculum Vitae", "last_updated": "November 2025", "version": "Academic", "page_header": { "enabled": true, "left": "ANTHONY BYRNES - Curriculum Vitae", "right": "page" } }
Detects:
- Contact Information: From defaults.yaml
- Document Title: "Curriculum Vitae", "Resume", or "CV" (from defaults or learned)
- Version: Academic, Industry, Arts, or General (simple keyword detection)
- Page Header Config: Generated automatically from template
Configuration Files
defaults.yaml - Your contact info and preferences:
contact: name: "ANTHONY BYRNES" phone: "213.305.3132" email: "anthonybyrnes@mac.com" cv_defaults: document_title: "Curriculum Vitae" page_header: enabled: true format: "{name} - {title}" preferences: version: "Academic"
learned-preferences.yaml - Three-layer learning system:
style_rules: [] # Layer 1: Style corrections metadata_defaults: {} # Layer 2: Metadata patterns section_patterns: {} # Layer 3: Section structures
JSON Export for Wrapper Application
After successfully formatting the resume and creating the output files, export structured metadata.
Write to:
resume-formatted-v1.json (increment version if exists)
Implementation:
- Check if
already exists in output directoryresume-formatted-v1.json - If exists, increment version number:
,resume-formatted-v2.json
, etc.resume-formatted-v3.json - Extract formatting metadata from the JSON structure and output files
- Write JSON file with proper formatting (2-space indentation)
- Save to same directory as formatted resume
Structure:
{ "metadata": { "created_at": "YYYY-MM-DDTHH:MM:SSZ", "version": 1, "skill": "format-resume", "input_file": "resume-content.md", "output_file": "resume-formatted.pdf" }, "formatting_metadata": { "template": "career-documents-template.docx", "document_type": "cv", "font": "Helvetica", "font_size": 11, "margins": { "top": 0.5, "bottom": 0.5, "left": 0.5, "right": 0.5 }, "line_spacing": 1.15, "section_spacing": 0.15, "page_header": { "enabled": true, "left": "ANTHONY BYRNES - Curriculum Vitae", "right": "page" } }, "sections": [ { "name": "Contact Information", "content_preview": "ANTHONY BYRNES\nT: 213.305.3132\nE: anthonybyrnes@mac.com", "styles_used": ["CV Name", "Contact Info"], "validation": "passed", "issues": [] }, { "name": "Professional Experience", "entries": 5, "styles_used": ["Section Header", "Timeline Entry", "Body Text", "Bullet Standard"], "validation": "passed", "issues": [] }, { "name": "Education", "entries": 3, "styles_used": ["Section Header", "Timeline Entry", "Body Text"], "validation": "passed", "issues": [] } ], "validation_results": { "total_checks": 15, "passed": 14, "failed": 0, "warnings": 1, "issues": [ { "type": "warning", "section": "Professional Summary", "message": "Summary slightly long (95 words, recommend <90)", "severity": "low" } ] }, "metrics": { "page_count": 2, "word_count": 542, "section_count": 7, "estimated_read_time_seconds": 130, "ats_compatibility_score": 0.92, "readability_score": 0.88, "visual_appeal_score": 0.90 }, "style_analysis": { "total_styles_used": 12, "paragraph_styles": ["CV Name", "Contact Info", "Section Header", "Timeline Entry", "Body Text", "Bullet Standard", "Bullet Gray"], "character_styles": ["Institution", "Job Title", "Play Title", "Gray Text"], "learned_corrections_applied": 3, "manual_overrides": 0 }, "output_files": [ { "type": "pdf", "path": "anthony-byrnes-cv.pdf", "size_bytes": 245632, "created_at": "YYYY-MM-DDTHH:MM:SSZ" }, { "type": "docx", "path": "anthony-byrnes-cv.docx", "size_bytes": 123456, "created_at": "YYYY-MM-DDTHH:MM:SSZ" } ] }
Present to user:
Formatting complete! Saved to: - anthony-byrnes-cv.docx (formatted document) - anthony-byrnes-cv.pdf (preview) - resume-formatted-v1.json (formatting metadata) Formatting summary: - Pages: 2 - Sections: 7 - Styles used: 12 (7 paragraph, 5 character) - Validation: 14/15 checks passed (1 warning) - ATS compatibility: 92% Would you like to: 1. Review the PDF preview 2. Make style corrections 3. Export a different format
Related
- Design:
docs/plans/2025-11-09-cv-style-extraction-and-formatting-design.md - CV Enhancements:
docs/plans/2025-11-11-cv-formatting-enhancements-design.md - Template generation:
python generate_cv_template.py - Validation:
python validate_template.py