Jobautopilot Tailor
by @jerronl
Tailors your resume and cover letter to a specific job description. Fetches the JD, rewrites bullet points to match keywords, and exports polished .docx file...
clawhub install jobautopilot-tailorπ About This Skill
name: jobautopilot-tailor description: Tailors your resume and cover letter to a specific job description. Fetches the JD, rewrites bullet points to match keywords, and exports polished .docx files β 100% based on your real experience, nothing invented. Picks up shortlisted jobs from jobautopilot-search and hands resume_ready entries to jobautopilot-submitter. author: jerronl version: "1.3.0" homepage: https://github.com/jerronl/jobautopilot tags: - resume - cover-letter - docx - job-search - career requires: tools: - web_search - browser python_packages: - python-docx - lxml env: - RESUME_DIR - RESUME_OUTPUT_DIR - RESUME_TEMPLATE - MD_TO_DOCX_SCRIPT - JOB_SEARCH_TRACKER - USER_FIRST_NAME - USER_LAST_NAME - USER_EMAIL - USER_PHONE - USER_LINKEDIN bins: - python3 metadata: clawdbot: emoji: "π" requires: env: - RESUME_DIR - RESUME_OUTPUT_DIR - RESUME_TEMPLATE - MD_TO_DOCX_SCRIPT - JOB_SEARCH_TRACKER - USER_FIRST_NAME - USER_LAST_NAME - USER_EMAIL - USER_PHONE - USER_LINKEDIN bins: - python3 pip: - python-docx - lxml files: - scripts/md_to_docx.py
Job Autopilot β Resume Tailor
Produces a tailored resume and cover letter for each shortlist job in the tracker. Delivers .docx files ready to attach and send.
Core principles
1. 100% truthful β never invent experience, inflate metrics, or fabricate credentials.
2. Resume content comes from the user's original files first β always read $RESUME_DIR before writing anything.
3. md before docx β complete markdown drafts for ALL shortlisted jobs first, then convert to docx in batch. Do not interleave md writing and docx conversion.
4. One job at a time for reporting β finish and report each job's result before moving to the next.
5. No silent spinning β if a job cannot be reliably completed within 30 minutes, mark it error with a clear reason and move on.
Setup
Add to ~/.openclaw/workspace/job_search/config.sh:
export RESUME_DIR="$HOME/Documents/jobs/" # your original resume files live here
export RESUME_OUTPUT_DIR="$HOME/Documents/jobs/tailored/" # where tailored files are saved
export RESUME_TEMPLATE="$HOME/.openclaw/workspace/job_sub_agent/scripts/sample_placeholders.docx"
Download template: https://github.com/jerronl/jobautopilot/raw/main/jobautopilot-tailor/scripts/sample_placeholders.docx
export MD_TO_DOCX_SCRIPT="$HOME/.openclaw/workspace/job_sub_agent/scripts/md_to_docx.py"
export JOB_SEARCH_TRACKER="$HOME/.openclaw/workspace/job_search/job_application_tracker.md"
export USER_FIRST_NAME="Your"
export USER_LAST_NAME="Name"
export USER_EMAIL="your@email.com"
export USER_PHONE="+1-555-000-0000"
export USER_LINKEDIN="https://linkedin.com/in/yourprofile"
mkdir -p "$RESUME_OUTPUT_DIR"
Session start
Read in order:
1. $RESUME_DIR β understand the user's full experience and skills
2. $JOB_SEARCH_TRACKER β find all shortlist entries to process
JD fetch order
For each shortlist job:
1. Use the exact URL from the tracker
2. Try web_search first to extract job responsibilities, skills, keywords, asset classes
3. If web_search returns no useful JD, use browser to open the URL directly
4. If the URL is broken, a generic careers page, or wrong role β mark tracker error and explain why
Content production order
For each job, strictly in this sequence:
Step 1 β Read source material
Read all files in $RESUME_DIR. The pool may contain:
| File type | What to extract |
|-----------|----------------|
| Master resume (.docx / .pdf) | Full work history, bullet points, metrics, dates. PDF text is extracted by the agent's built-in tools; the conversion script handles .docx and .md only. |
| Older tailored versions | Phrasing that worked well for similar roles |
| Cover letter drafts | Preferred voice, opening formulas, recurring themes |
| Skills list / bio (.md / .txt) | Certifications, tools, side projects, publications |
Extract everything factual β every bullet, every metric, every tool name. This is your raw material. Do not invent anything not present in these files.
Resume markdown format specification
The markdown file must follow this exact format. md_to_docx.py parses it structurally β any deviation will produce wrong or missing output.
Full Name
Email | Phone | LinkedIn | LocationSUMMARY
Two to three sentences summarizing the candidate.
CORE SKILLS
List of skills, tools, and technologies relevant to this role.
EXPERIENCE
Job Title β Company Name | City, ST | Jan 2022 β Present
β’ Accomplished X by doing Y, resulting in Z
β’ Another bullet point with a metric
Job Title β Company Name | City, ST | Jun 2019 β Dec 2021
β’ Bullet point
β’ Bullet point
EARLIER EXPERIENCE
Earlier Role β Company, YearβYear
Another Earlier Role β Company, YearβYear
EDUCATION
University Name β Degree, Major (Year)
Parsing rules the script enforces β follow these exactly:
| Element | Rule |
|---------|------|
| Line 1 | Full name, plain text, no # heading marker |
| Line 2 | Contact info, pipe-separated |
| Section headers | ALL CAPS, no ## β exactly SUMMARY, CORE SKILLS, EXPERIENCE, EARLIER EXPERIENCE, EDUCATION |
| Job header | Title β Company \| Location \| Date range β separator is β (em dash with spaces), fields separated by \| |
| Bullets | Start with β’ or -, one per line |
| Earlier experience | One line per entry: Role β Company, Years |
| Education | One line per entry: University β Degree |
What the script handles automatically:
Step 2 β Write resume markdown
Tailor bullet points to match the JD keywords. Prioritize:Save to: $RESUME_OUTPUT_DIR/${USER_FIRST_NAME}_
Self-check before converting to docx
Before running md_to_docx.py, verify the markdown against these rules:
# Line 1 must be plain name (no # prefix)
head -1 resume.mdLine 2 must contain pipes (contact info)
sed -n '2p' resume.md | grep '|'Section headers must be ALL CAPS with no ## prefix
grep -E '^[A-Z ]+$' resume.mdJob headers must match: Title β Company | Location | Date
grep -E '^.+ β .+ \| .+ \| .+$' resume.mdBullets must start with β’ or -
grep -E '^[β’\-]' resume.md
If any check fails, fix the markdown before proceeding β a malformed file will silently produce an incomplete docx.
Step 3 β Write cover letter markdown
Three paragraphs max: 1. Why this role + company 2. Most relevant experience match (2β3 specific points) 3. Brief closeSave to: $RESUME_OUTPUT_DIR/${USER_FIRST_NAME}_
Step 4 β Update tracker
Change status tomd_ready. Record md file paths.Step 5 β Generate docx files
Resume β use md_to_docx.py with the template:
python3 "$MD_TO_DOCX_SCRIPT" \
--input "$RESUME_OUTPUT_DIR/${USER_FIRST_NAME}___Resume_2026.md" \
--template "$RESUME_TEMPLATE" \
--output "$RESUME_OUTPUT_DIR/${USER_FIRST_NAME}___Resume_2026.docx"
Cover letter β use python-docx directly (plain text, no template):
from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_ALIGN_PARAGRAPHdoc = Document()
style = doc.styles['Normal']
style.font.name = 'Calibri'
style.font.size = Pt(11)
Add paragraphs from cover letter md content
for para in cover_letter_paragraphs:
p = doc.add_paragraph(para)doc.save(f"{output_dir}/{os.environ['USER_FIRST_NAME']}___Cover_Letter_2026.docx")
Step 6 β Verify docx
"Text looks right" is not the same as "file is deliverable." Both conditions must pass:
1. Content check β open the docx and compare section by section against the md:
- No missing sections
- No leftover {{PLACEHOLDER}} strings anywhere in the document
- Company name and job title are correct throughout
2. File check β the docx must open without errors, have non-zero file size, and be saved to $RESUME_OUTPUT_DIR
3. URL check β validate the job URL from the tracker is still reachable
Do not call partial verification "good enough." If any check fails, fix and re-verify before updating the tracker.
Step 7 β Update tracker
resume_ready, record docx pathserror, write reasonStep 8 β Report
After each job, report: company, title, files produced, any issues.File naming convention
${USER_FIRST_NAME}___Resume_2026.docx
${USER_FIRST_NAME}___Cover_Letter_2026.docx
Spaces β underscores. Keep company and title short (β€ 20 chars each if possible).
Tracker status flow
shortlist β md_ready β resume_ready
β error
Known failure modes to avoid
Scope
Resume tailoring only. Do not submit applications. Hand off resume_ready entries to the jobautopilot-submitter skill.
Support
If Job Autopilot saved you time: paypal.me/ZLiu308
βοΈ Configuration
Add to ~/.openclaw/workspace/job_search/config.sh:
export RESUME_DIR="$HOME/Documents/jobs/" # your original resume files live here
export RESUME_OUTPUT_DIR="$HOME/Documents/jobs/tailored/" # where tailored files are saved
export RESUME_TEMPLATE="$HOME/.openclaw/workspace/job_sub_agent/scripts/sample_placeholders.docx"
Download template: https://github.com/jerronl/jobautopilot/raw/main/jobautopilot-tailor/scripts/sample_placeholders.docx
export MD_TO_DOCX_SCRIPT="$HOME/.openclaw/workspace/job_sub_agent/scripts/md_to_docx.py"
export JOB_SEARCH_TRACKER="$HOME/.openclaw/workspace/job_search/job_application_tracker.md"
export USER_FIRST_NAME="Your"
export USER_LAST_NAME="Name"
export USER_EMAIL="your@email.com"
export USER_PHONE="+1-555-000-0000"
export USER_LINKEDIN="https://linkedin.com/in/yourprofile"
mkdir -p "$RESUME_OUTPUT_DIR"