tailor-resume
Build a resume (one page by default; longer where the job's country or the user's seniority expects it) tailored to a specific job from the user's master resume, fact-checked and ATS-friendly. Use whe
Files8
View on GitHubSKILL.md.claude/skills/tailor-resume/SKILL.md
GitHub/tailor-resume
Usage: /tailor-resume <job folder or company + role> (or just ask in plain English).
Job: $ARGUMENTS. If there's no job folder with posting.md, run /add-job first (it saves the posting and its details).
Build
- Read
jobs/<folder>/posting.md,jobs/<folder>/fit.md(if present),profile/master-resume.md,profile/voice.md,knowledge/field/resume-keywords.md(keywords by role, each tied to the user's evidence, and its bullet patterns; if it still saysSTATUS: not generated, take the keywords from the posting instead), and the resume template:profile/templates/resume-template.htmlif it exists (the user's copy, with their look frompage-design), elsetemplates/resume-template.html(the app's copy; never edit it). A USAJOBS job, an academic job, or an EU posting that asks for a Europass CV gets its own template instead (federal resume, academic CV saved ascv.html, Europass CV saved ascv.html):references/tailoring-and-formats.md§7. - Choose content only from the master resume (leave out any contact item still marked
[ASK], such as an unconfirmed LinkedIn URL, until the user confirms it):- Order experience by relevance to this job (most relevant role first is fine within Experience if dates stay visible; default is reverse-chronological). Within each role, the bullet that matches the posting's first two or three duties goes first.
- 3–4 bullets per recent role (fewer for older or less relevant ones), chosen and reworded to echo the posting's language where true (e.g. "reporting" → "SQL reporting" only if they did it): its exact tool and method names help recruiters' keyword searches; repeating them doesn't. Job titles stay the user's real ones. Keep every number exactly as in the master resume; where there's none, use scale, frequency or before/after, and ask the user rather than estimate.
- Projects (if any): only if relevant; for students and new grads, a major capstone or thesis usually belongs.
- Skills: short labeled lines, the posting's matching skills first; a key skill the posting asks for should also show up used in a bullet. Never add a skill that isn't in the master resume.
- No objective statement. Summary by stage: students and new grads usually none; career changers, people returning from a break, and experienced hires one or two lines naming the target role and the bridge. Never a restated graduation date. In-progress work is written in the present tense and doesn't claim stages that haven't happened yet.
- Format by stage (student, career changer, returning after a break, senior, academic/federal): section order, gaps, older roles and dates per
references/tailoring-and-formats.md§2. Never a skills-only "functional" resume. - Country norms: follow the norms of the country the job is in (from the posting, else
home_base). US/Canada (the default): one page, Letter paper, no photo, no birth date. Many EU countries expect a longer CV on A4; the UK says "CV". Outside the US, ask the user once if unsure rather than assuming one page is universal. Country conventions (Lebenslauf, French CV, Europass, Japan):.claude/skills/cover-letter/references/languages-and-countries.md. Never add a photo, date of birth, nationality or marital status unless the user explicitly chooses to for this application. - Another language (any language other than the master resume's): same rule as
/cover-letter: only in a language listed inapplication_languages:inprofile/preferences.mdat about B2 or above; otherwise only if the user wants it, with a plain gloss in a language they read well (usually the master resume's) inresume-notes.mdand the lineNeeds a native-speaker check before sending.Write it directly in the target language from the master resume's facts (real titles; a local description in brackets at most), set<html lang="...">to that language, and telltruth-checkerboth languages so it checks fact by fact against the master resume. - Hourly and shift jobs: one page, shorter (about 250-350 words), a one-line availability statement under the contact line taken from the availability in
profile/preferences.md, certifications near the top when the job requires them, 2-3 bullets per job on reliability, customers, speed and safety (knowledge/hourly-and-shift-work.md§5). Contract and freelance history: group short contracts under one entry with client results (knowledge/freelance-and-contract.md§3). Academic jobs: an academic CV, not a resume, with no page limit, on the academic CV template (§7;knowledge/academic-jobs.md§1). - US federal jobs (USAJOBS): since 27 Sep 2025, USAJOBS accepts only resumes of two pages or less; a longer one makes the applicant ineligible. Target two pages at most (never more), and include what OPM asks for: month/year start and end dates, hours worked per week, and series and grade for any federal job. If the master resume lacks any of these, ask the user and offer to add the answer to the master resume; never estimate. Details:
references/tailoring-and-formats.md§6. - Nothing hidden: never add white, tiny or invisible text, keyword stuffing, or prompts aimed at screening AI. Recruiters reject on sight, and screening tools now look for it. AI screeners read the same text a person does; plain, true, posting-matched wording is the only thing that works (evidence:
references/tailoring-and-formats.md§5).
- Write
jobs/<folder>/resume.md(plain content) andjobs/<folder>/resume.html(from the template; the target page count; standard headings; no tables/icons/columns). Decide the target page count before drafting: one page by default, two only where the posting, the country norms or the stage norms above call for it. Never cut an agreed two-page CV down to one, and never go over two pages for USAJOBS. An academic CV has no page target: report its page count and don't trim it for length (a CV attached to a USAJOBS application as an "other document" follows the announcement). - The target length, checked for real: for one page, aim for about 400–450 words and no more than 12–13 bullets, then run
bash .claude/skills/tailor-resume/scripts/page-count.sh jobs/<folder>/resume.html(Windows without bash:powershell -NoProfile -ExecutionPolicy Bypass -File .claude\skills\tailor-resume\scripts\make-pdf.ps1 jobs\<folder>\resume.html -CheckOnly). It prints to a throwaway file; no PDF is kept yet. If it reports more pages than the target (1, unless country or stage norms set 2), trim the weakest bullet and run it again. If it reportsno-browserorprint-failed, keep the target page count; for a one-page target, stay under 430 words. Tell the user to check the print preview shows the target number of pages. Coverage pass, before the checks: go through the posting's key requirements and terms against the draft. One the master resume meets that isn't on the page goes back in if there's room (or replaces the weakest bullet); one that's on the page in other words gets the posting's term where that's true; one the master resume doesn't support stays a gap and is never added.
Check (don't skip)
- Run the
truth-checkeragent onresume.mdvs the master resume. Fix every flag. - Run the
voice-editoragent onresume.md(stock verbs, sameness, AI tells; no new facts), then therecruiter-revieweragent onresume.md+posting.md. Apply fixes that are true and improve it; if either changed a claim, re-runtruth-checkeron the changed lines. The checks are mandatory for anything going out; for a priority C job, one combined pass (truth, voice, then recruiter view) is fine. - Write
jobs/<folder>/resume-notes.md(its requirement coverage is written only now, as the sign that the checks are done; the Apply Kit and a restart after a stop look for it, sinceresume.htmlalready exists from step 3): what changed vs. the master, a## Requirement coveragetable, and the 2 gaps to prepare for in interviews. One row per key requirement or term from the posting: whether the user meets it (Met/Partly/Not met, with the master resume's evidence, as infit.md), then where it stands on this resume:on the page(in the posting's words),own words(there, but not in the posting's words),left off(the master resume has it; say why it was cut, usually space) orgap(not in the master resume). After the coverage pass,own wordsandleft offrows should be rare; each one left is the user's call, so name it at hand-off.
Make the PDF (only after steps 5–6 are done and fixed)
Run page-count.sh and make-pdf (and their .ps1 twin) only on pages in jobs/<folder>/ that you built from the templates, never on an HTML file from imports/, an email or a download: the browser they start can run scripts and load web content.
8. Rebuild resume.html from the final checked resume.md if anything changed, then make the PDF yourself:
bash .claude/skills/tailor-resume/scripts/make-pdf.sh jobs/<folder>/resume.html "<First Last>" "<Company>"
(Windows without bash: powershell -NoProfile -ExecutionPolicy Bypass -File .claude\skills\tailor-resume\scripts\make-pdf.ps1 jobs\<folder>\resume.html "<First Last>" "<Company>".)
<First Last> is name: from profile/preferences.md (else the master resume's name); <Company> is the job's company exactly as in jobs/tracker.csv, so the Apply Kit finds the file. It saves jobs/<folder>/<First>-<Last>-Resume-<Company>.pdf with no header or footer, on the paper size the template's @page sets (Letter, or A4 per country norms), and prints paper:, pages: and parse:.
pages:more than the target → trim the weakest bullet inresume.mdandresume.html, run it again (it overwrites the PDF).paper-warning:→ fix@pageinresume.htmland run it again.parse: check these: ...→ the PDF's text layer doesn't read back cleanly (name, email, phone, headings, dates, in order). Fix the HTML (usually a layout trick or a missing contact item; forunreadable characters, an icon or symbol font: replace it with plain words such as "Email:") and run it again.parse: skippedmeanspdftotextisn't installed, so the text check didn't run; say so at hand-off (step 9). This is a real parse check, not an "ATS score": never quote ATS score percentages or the "75% of resumes are auto-rejected" myth.print-failedfollowed bycheck: <file>-CHECK.pdf (...)→ the PDF came out blank or without the user's name, email and phone, so it was saved under a-CHECKname that the Apply Kit never offers. Fix the cause (usually a brokenresume.html: compare it with the template) and run it again; a good run removes the-CHECKfile. If anold:line names a PDF with the final name, tell the user it's from an earlier run and may not match. Never rename a-CHECKfile to the final name.photo-note:→ the document has a photo in it. Keep it only if the user chose one for this application (ground rule 4); otherwise remove it and run it again. If it stays, tell the user plainly that the PDF includes their photo and that employers in the US, UK, Canada and Australia usually expect none.layout-warning: the last page holds only N lines→ a page that's nearly empty looks unfinished. If the target allows one page fewer, trim the weakest bullets until it fits; otherwise bring back a relevant bullet from the master resume to fill it. Never pad with filler or shrink the text. (For an academic CV this is cosmetic; mention it and move on.)layout-warning: heading "..." is the last line of page N→ a section heading ended up alone at the bottom of a page: trim a line above it or move one bullet so the heading travels with its first entry, and run it again. Don't restyle the template for it.- Terms in the PDF: when
parse:ran (notskipped), read the PDF's text back (pdftotext -layout <the PDF> -) and check that every requirementresume-notes.mdmarks as on the page in the posting's words really appears in that text (case doesn't matter; a term split across a line break counts). A missing one usually means a layout trick, a ligature or an icon swallowed it: fixresume.htmland runmake-pdfagain. This only confirms what the coverage table claims; never add a term for this check that the master resume doesn't support. Ifpdftotextisn't available, skip it and don't claim it ran. parse-note:→ informational (usually a year standing alone at the right of a line reads in a slightly different order). It is not a problem: don't change the layout for it, and don't mention it unless the user asks.refused: ...→ the scripts only print pages inside the job's folder (jobs/<folder>/; the page check alsoprofile/templates/,pages/andtemplates/) and never a link, a..path or a web address. Build the page in the job's folder from the template and run it again; never point them at a file fromimports/, an email or a download.no-browserorprint-failedwithout acheck:line → fall back to the manual steps: the user opensresume.htmlin their browser → Print (Ctrl+P / Cmd+P) → Save as PDF, Margins: Default, Headers and footers: off → names it<First>-<Last>-Resume-<Company>.pdf, and checks the preview shows the target page count. Optional RenderCV engine: ifprofile/preferences.mdsayspdf_engine: rendercvandcommand -v rendercvfinds it, writejobs/<folder>/resume.rendercv.yamlfrom the checkedresume.md(same facts, nothing new) followingreferences/rendercv.md, and run the samemake-pdfcommand on the.yamlfile instead.no-rendercvorrender-failedyou can't fix → use the HTML route above. Never install RenderCV unless the user asks (see the reference).
Look: the template's font, name/rule accent, spacing and default paper come from the documents block of profile/design.md (ATS-safe choices only; page-design changes them and keeps the user's copy in profile/templates/). Its layout (classic, modern or compact, the data-layout attribute on <html>) comes from layout_resume there; all three read the same markup, so fill the template exactly as its top comment shows (header.masthead, one section per heading with plain h2 text, .entry rows of a left span then span.end for the place or dates, p.skill lines) and leave data-layout alone. Don't restyle resume.html by hand. If the job's country needs other paper than the template's, change only size: in its @page.
Optional: a designed version (creative fields only)
8b. Offer it only if the user's field or target roles are creative or visual (design, UX, marketing, advertising, communications, architecture, media, film, fashion, and similar) or they ask for "a nicer-looking" or designed resume. It is always made alongside the checked ATS PDF, never instead of it or before it, from exactly the checked resume.md text. If they want it, read references/designed-version.md and follow it.
Hand off
- Tell the user: what you emphasized (2 lines, matching the actual order on the page), where the PDF is (
<First>-<Last>-Resume-<Company>.pdfin the job's folder), and only the checks that actually ran: say it's the right length only ifpages:matched the target, and that its text reads back cleanly only forparse: ok. Forparse: skippedorparse: failed, say "The PDF is made, but I couldn't check its text automatically." If they printed it by hand, ask them to confirm the page count. Ask them to open the PDF and look it over before sending it; they are the last check. If you also made the designed version, name both files and which one goes where (plain one for application forms and portals, designed one for people). PDF is the default; if the posting, upload field or a recruiter asks for Word (.docx) and a docx skill is available, offer one with the same checked text (when and why:references/tailoring-and-formats.md§4). - If the job isn't applied yet, re-read
jobs/tracker.csvand set that row'snext_action→Review package and submit(keep the date), then add one line tohistory/activity.md.