| name | job-carousel |
| description | Transform a user's resume and target job description into a polished, recruiter-facing LinkedIn career carousel package. Use this when the user wants to create a social media career story, position themselves for a specific role, or highlight their strongest experiences for a target job. This is a fit analysis + strategic positioning engine, not a resume formatter. |
Purpose
Transform a user's resume and a target job description into a polished, strategically framed LinkedIn career carousel package. This is not a resume-to-slides converter. It is a fit analysis and strategic positioning engine that produces a premium, recruiter-facing social asset.
When to Use This Skill
Invoke this skill when a user:
- Wants to create a LinkedIn carousel or social media career story
- Has a resume (or raw experience text) and a target role or JD
- Wants to position themselves for a specific job, industry, or audience
- Needs help selecting and framing their strongest experiences for a role
Do not use this skill for general resume editing, cover letter writing, or interview prep (unless the user explicitly asks to extend it there).
Inputs Expected
Required:
- Resume — file path (
.pdf, .txt, .md) or pasted text
- Job description — file path or pasted text (or at minimum: job title + company + 2–3 sentences about the role)
Optional:
--mode recruiter | hiring-manager | personal-brand (default: auto-infer)
--theme clean | dark | bold (default: clean)
--slides 6 | 7 | 8 | 9 | 10 (default: 7; auto-bumps to 8 when --timeline is used)
--output <path> (default: output/job-carousel/)
--export canva — also generate a PPTX file (linkedin_carousel.pptx) for Canva import
--export figma — also generate SVG files (figma_export/slide_*.svg) for Figma import
--export canva,figma — generate both
--timeline — insert a visual career trajectory slide (horizontal timeline with highlighted roles) after the hook slide
--show-education auto | always | never (default: auto) — controls whether education nodes appear on the timeline slide; auto includes education if the candidate has < 6 years of experience or the degree is relevant to the JD domain
Full Workflow
Step 1 — Locate or Request Inputs
- Check if the user provided resume and JD paths or pasted text.
- If resume is missing: ask "Please share your resume text or file path."
- If JD is missing: ask "Please share the job description or job title + company + key requirements."
- Accept messy inputs — do not require clean formatting.
Step 2 — Parse and Normalize Inputs
Run the pipeline:
npx ts-node src/job-carousel/index.ts \
--resume <path> --jd <path> \
[--mode recruiter|hiring-manager|personal-brand] \
[--theme clean|dark|bold] \
[--slides 6-10] \
[--timeline] \
[--show-education auto|always|never] \
[--export canva,figma]
This calls resumeParser.ts and jobParser.ts to extract structured CandidateProfile and TargetRoleProfile objects.
From resume, extract:
- Roles, employers, dates
- Achievement bullets (especially those with metrics or ownership language)
- Tools, skills, technologies
- Domains/industries worked in
- Ownership indicators ("led", "owned", "built", "launched", "managed")
- Collaboration/stakeholder language
From JD, extract:
- Job title and seniority level
- Required and preferred skills
- Domain/industry signals
- Leadership and cross-functional expectations
- Recruiter priority signals (what the JD emphasizes most)
Step 3 — Run Fit Analysis
Call fitAnalysis.ts to produce a FitAnalysis object:
- Best fit story: The 1–2 sentence narrative of why this candidate is compelling for this role
- Strongest alignments: Skills/experiences that directly match the JD (score > 7)
- Moderate alignments: Partial matches, adjacent skills, transferable experience (score 4–7)
- Notable gaps: What the JD asks for that the resume doesn't clearly show
- Best achievements: Top 5–7 bullets ranked for this specific role
Reasoning rules:
- Weight recent roles more heavily than older ones
- Weight ownership language ("built X from scratch", "led a team") over participation language
- Weight quantified claims over unquantified ones, but do not penalize sparse metrics if the context is strong
- If the candidate is switching domains, look for transferable patterns, not perfect keyword matches
Step 4 — Rank Highlights
Call rankHighlights.ts using the scoring rubric (see rubric.md). Score each candidate bullet on:
- Role relevance (25%)
- Business impact (20%)
- Quantitative strength (15%)
- Technical depth (10%)
- Ownership (10%)
- Scale (5%)
- Uniqueness (5%)
- Recency (5%)
- Recruiter appeal (5%)
Select the top 4–6 highlights for slide content. Discard bullets that score < 3.5 total or that cannot be grounded in the source text.
Anti-fabrication rule: Never include a claim that cannot be traced to a specific bullet, project, metric, or phrase in the original resume. If evidence is weak, soften phrasing ("contributed to", "supported", "helped drive") rather than asserting direct ownership.
Step 5 — Choose Positioning Narrative
Call chooseNarrative.ts to generate 3 candidate positioning headlines. Score each on:
- Fit to target role (0–10)
- Clarity for a recruiter reading in 3 seconds (0–10)
- Distinctiveness vs. generic titles (0–10)
- Credibility based on resume evidence (0–10)
Select the highest-scoring angle. Persist in carousel.json.
Mode guidance:
recruiter: Emphasize clarity, fit signal, seniority, and business impact. Use action + outcome framing.
hiring-manager: Emphasize technical depth, hard problems, methods, and execution. Show how they work.
personal-brand: Emphasize distinctiveness, memorable framing, editorial voice. Make it shareable.
Step 6 — Generate 7-Slide Carousel Outline
Call buildOutline.ts. Default structure:
| # | Template | Purpose |
|---|
| 1 | HookSlide | Identity hook — powerful recruiter-facing headline |
| 2 | FitSlide | 3 concise strengths aligned to the JD |
| 3 | ProofSlide | Strongest role-relevant achievement |
| 4 | ProofSlide | Second strongest achievement |
| 5 | WorkStyleSlide | How they work / capability pattern |
| 6 | ValuePropSlide | Value proposition for this role |
| 7 | CtaSlide | Open to roles / connect / contact |
Step 7 — Write Polished Slide Copy
Call writeSlides.ts. Enforce copy limits:
- Title: 4–9 words
- Subtitle: ≤18 words
- Body: ≤30 words
- Bullets: max 3 per slide
- Metric hero: max 1 per slide
Copy style rules:
- Concise, premium, credible
- Not resume-dump, not buzzword soup
- No vague filler ("results-oriented", "passionate about")
- No invented facts or implied ownership unsupported by resume
- Compress bullets — keep the signal, cut the noise
Step 8 — Render and Export
The pipeline automatically:
- Renders each slide to HTML using React components + Tailwind
- Captures PNGs at 1080×1080 (square, LinkedIn-safe)
- Combines into
linkedin_carousel.pdf
- Writes
linkedin_caption.txt with 3 caption variants + hashtags
Output location: output/job-carousel/
Step 9 — Summarize Results
After generation, tell the user:
- Positioning angle chosen and why (score breakdown)
- Top 3 highlights selected with rationale
- Mode used (auto-inferred or user-specified)
- Files generated with paths
- Any gaps noted — what was missing from the resume vs. the JD
- Any softened claims — where evidence was weak and phrasing was deliberately hedged
Error Handling
- If resume is too sparse to score highlights: generate best possible carousel with explicit hedging in body copy; notify user
- If JD is just a title: infer domain priorities from the title, use generic but role-appropriate framing
- If a slide cannot be grounded: substitute a capability-pattern slide or remove it from the output
- If export fails (Playwright/Puppeteer not installed): write HTML files and notify user with install instructions
Output Files
output/job-carousel/
linkedin_carousel.pdf # Primary deliverable
linkedin_carousel.pptx # Canva-ready (--export canva)
slides_preview/
slide_01.png
slide_02.png
...
figma_export/ # Figma-ready (--export figma)
slide_01.svg
slide_02.svg
...
FIGMA_IMPORT_GUIDE.md
linkedin_caption.txt # 3 caption variants
carousel.json # Full structured document
carousel_manifest.json # Metadata
Canva Import
- Run with
--export canva
- Open Canva → Create a design → Import (
linkedin_carousel.pptx)
- Every text box and shape is editable in Canva
Figma Import
- Run with
--export figma
- Open Figma → drag all
figma_export/slide_*.svg files onto the canvas
- Each slide lands as a 1080×1080 frame with editable text and vector shapes
- See
figma_export/FIGMA_IMPORT_GUIDE.md for detailed instructions