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.
- Resume content comes from the user's original files first — always read
$RESUME_DIR before writing anything. - 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.
- One job at a time for reporting — finish and report each job's result before moving to the next.
- 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:
CODEBLOCK0
Session start
Read in order:
- 1.
$RESUME_DIR — understand the user's full experience and skills - INLINECODE6 — find all
shortlist entries to process
JD fetch order
For each shortlist job:
- 1. Use the exact URL from the tracker
- Try
web_search first to extract job responsibilities, skills, keywords, asset classes - If
web_search returns no useful JD, use browser to open the URL directly - 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.
CODEBLOCK1
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:
- - More jobs than template slots → clones the last job's formatting
- Fewer jobs than template slots → removes unused placeholders
- Same logic for bullets, earlier experience, and education entries
Step 2 — Write resume markdown
Tailor bullet points to match the JD keywords. Prioritize:
- - Skills explicitly mentioned in JD
- Quantified achievements relevant to the role
- Asset classes, systems, or methodologies named in JD
Save to: INLINECODE33
Self-check before converting to docx
Before running md_to_docx.py, verify the markdown against these rules:
CODEBLOCK2
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
- Most relevant experience match (2–3 specific points)
- Brief close
Save to: INLINECODE35
Step 4 — Update tracker
Change status to
md_ready. Record md file paths.
Step 5 — Generate docx files
Resume — use md_to_docx.py with the template:
CODEBLOCK3
Cover letter — use python-docx directly (plain text, no template):
CODEBLOCK4
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 INLINECODE39
- 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
- - Success →
resume_ready, record docx paths - Cannot reliably complete →
error, write reason
Step 8 — Report
After each job, report: company, title, files produced, any issues.
File naming convention
CODEBLOCK5
Spaces → underscores. Keep company and title short (≤ 20 chars each if possible).
Tracker status flow
CODEBLOCK6
Known failure modes to avoid
- - Do not call partial verification "good enough"
- Do not treat "text looks right" as equivalent to "docx is deliverable"
- Do not spend more than 30 minutes on a single job without reporting status
- Do not write a generic script to handle all cases; get the md layer working first
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
职位自动导航 — 简历定制
为追踪器中每个shortlist职位生成定制简历和求职信。输出可直接附上发送的.docx文件。
核心原则
- 1. 100%真实 — 绝不虚构经历、夸大指标或伪造资质。
- 简历内容优先来自用户原始文件 — 在撰写任何内容前,始终先读取$RESUME_DIR。
- 先写markdown再转docx — 先完成所有shortlist职位的markdown草稿,再批量转换为docx。不要交错进行md编写和docx转换。
- 每次报告一个职位 — 完成并报告一个职位的结果后,再处理下一个。
- 不静默空转 — 如果某个职位无法在30分钟内可靠完成,标记为error并写明原因,然后继续。
设置
添加到~/.openclaw/workspace/job_search/config.sh:
bash
export RESUME_DIR=$HOME/Documents/jobs/ # 原始简历文件存放位置
export RESUMEOUTPUTDIR=$HOME/Documents/jobs/tailored/ # 定制文件保存位置
export RESUMETEMPLATE=$HOME/.openclaw/workspace/jobsubagent/scripts/sampleplaceholders.docx
下载模板:https://github.com/jerronl/jobautopilot/raw/main/jobautopilot-tailor/scripts/sample_placeholders.docx
export MD
TODOCX
SCRIPT=$HOME/.openclaw/workspace/jobsub
agent/scripts/mdto_docx.py
export JOB
SEARCHTRACKER=$HOME/.openclaw/workspace/job
search/jobapplication_tracker.md
export USER
FIRSTNAME=Your
export USER
LASTNAME=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
OUTPUTDIR
会话开始
按顺序读取:
- 1. $RESUMEDIR — 了解用户的完整经验和技能
- $JOBSEARCH_TRACKER — 查找所有待处理的shortlist条目
JD获取顺序
对于每个shortlist职位:
- 1. 使用追踪器中的确切URL
- 首先尝试websearch提取职位职责、技能、关键词、资产类别
- 如果websearch未返回有用的JD,使用浏览器直接打开URL
- 如果URL已失效、指向通用招聘页面或错误职位 → 在追踪器中标记error并说明原因
内容生成顺序
对于每个职位,严格按以下顺序执行:
步骤1 — 阅读源材料
读取$RESUME_DIR中的所有文件。文件池可能包含:
| 文件类型 | 提取内容 |
|---|
| 主简历(.docx / .pdf) | 完整工作经历、要点、指标、日期。PDF文本由代理的内置工具提取;转换脚本仅处理.docx和.md。 |
| 旧版定制简历 |
针对类似职位效果良好的措辞 |
| 求职信草稿 | 偏好的语气、开场公式、反复出现的主题 |
| 技能列表/个人简介(.md / .txt) | 认证、工具、副项目、出版物 |
提取所有事实性内容 — 每个要点、每个指标、每个工具名称。这是你的原始素材。不要捏造这些文件中不存在的任何内容。
简历markdown格式规范
markdown文件必须遵循以下精确格式。mdtodocx.py按结构解析 — 任何偏差都会导致输出错误或缺失。
markdown
Full Name
Email | Phone | LinkedIn | Location
SUMMARY
两到三句话总结候选人。
CORE SKILLS
与该职位相关的技能、工具和技术列表。
EXPERIENCE
Job Title — Company Name | City, ST | Jan 2022 – Present
• 通过做Y实现了X,带来了Z
• 另一个带有指标的要点
Job Title — Company Name | City, ST | Jun 2019 – Dec 2021
• 要点
• 要点
EARLIER EXPERIENCE
Earlier Role — Company, Year–Year
Another Earlier Role — Company, Year–Year
EDUCATION
University Name — Degree, Major (Year)
脚本强制执行的解析规则 — 请严格遵循:
联系信息,用竖线分隔 |
| 章节标题 | 全部大写,无## — 必须为SUMMARY、CORE SKILLS、EXPERIENCE、EARLIER EXPERIENCE、EDUCATION |
| 职位标题 | Title — Company \| Location \| Date range — 分隔符为 — (带空格的长破折号),字段由 \| 分隔 |
| 要点 | 以•或-开头,每行一个 |
| 早期经历 | 每行一个条目:Role — Company, Years |
| 教育背景 | 每行一个条目:University — Degree |
脚本自动处理的内容:
- - 职位多于模板插槽 → 克隆最后一个职位的格式
- 职位少于模板插槽 → 移除未使用的占位符
- 要点、早期经历和教育背景条目同理
步骤2 — 编写简历markdown
定制要点以匹配JD关键词。优先考虑:
- - JD中明确提及的技能
- 与职位相关的量化成就
- JD中提到的资产类别、系统或方法论
保存至:$RESUMEOUTPUTDIR/${USERFIRSTNAME}
Resume2026.md
转换为docx前的自检
在运行mdtodocx.py之前,根据以下规则验证markdown:
bash
第1行必须是纯文本姓名(无#前缀)
head -1 resume.md
第2行必须包含竖线(联系信息)
sed -n 2p resume.md | grep |
章节标题必须全部大写且无##前缀
grep -E ^[A-Z ]+$ resume.md
职位标题必须匹配:Title — Company | Location | Date
grep -E ^.+ — .+ \| .+ \| .+$ resume.md
要点必须以•或-开头
grep -E ^[•\-] resume.md
如果任何检查失败,在继续前修复markdown — 格式错误的文件会静默生成不完整的docx。
步骤3 — 编写求职信markdown
最多三段:
- 1. 为什么选择该职位+公司
- 最相关的经验匹配(2-3个具体点)
- 简短结尾
保存至:$RESUMEOUTPUTDIR/${USERFIRSTNAME}
CoverLetter_2026.md
步骤4 — 更新追踪器
将状态更改为md_ready。记录md文件路径。
步骤5 — 生成docx文件
简历 — 使用mdtodocx.py配合模板:
bash
python3 $MDTODOCX_SCRIPT \
--input $RESUMEOUTPUTDIR/${USERFIRSTNAME}
Resume2026.md \
--template $RESUME_TEMPLATE \
--output $RESUMEOUTPUTDIR/${USERFIRSTNAME}Resume2026.docx
求职信 — 直接使用python-docx(纯文本,无模板):
python
from docx import Document
from docx.shared import Pt
from docx.enum.text import WDALIGNPARAGRAPH
doc = Document()
style = doc.styles[Normal]
style.font.name = Calibri
style.font.size = Pt(11)
从求职信md内容添加段落
for para in coverletterparagraphs:
p = doc.add_paragraph(para)
doc.save(f{outputdir}/{os.environ[USERFIRSTNAME]}CoverLetter2026.docx)
步骤6 — 验证docx
文本看起来没问题不等于文件可交付。 两个条件都必须通过:
- 1. 内容检查 — 打开docx并逐节与md比较:
- 无缺失章节
- 文档中无残留的{{PLACEHOLDER}}字符串
- 公司名称和职位标题通篇正确
- 2. 文件检查 — docx必须能无错误打开,文件大小非零,并保存到$RESUMEOUTPUTDIR
- URL检查 — 验证追踪器中的职位URL仍然可访问
不要