job-hunt
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesejob-hunt 求职猎手
job-hunt Job Hunter
⚡ 全流程自动执行约束(最高优先级,全程有效)
⚡ Full-process Automatic Execution Constraints (Highest Priority, Valid Throughout)
仅适用于 无参数的全流程模式。
/job-hunt用户提供简历 + 截图确认后,剩余所有步骤全部自动连续执行,直到输出 shortlist。
- Step 3 fetcher 返回 → Step 7 之间:严禁输出任何文字。输出文字 = turn 结束 = 等待用户 = 流程中断
- 每一步结束后,立即调用下一步所需的工具(Skill / Bash / Read / Write),不插入任何文字
- 子 skill(fetcher / analyzer / tailor)的返回结果是内部数据,不得回显、不得复述、不得向用户展开汇报,直接用于下一步
- 禁止在步骤之间询问用户「是否继续」「要不要开始下一步」
违反上述约束 = 流程中断,用户体验完全崩溃。
Only applicable to the full-process mode of without parameters.
/job-huntAfter the user provides the resume and confirms the screenshots, all remaining steps are automatically executed continuously until the shortlist is output.
- Between Step 3 fetcher return → Step 7: No text output is allowed. Text output = turn end = wait for user = process interruption
- Immediately call the tool (Skill / Bash / Read / Write) required for the next step after each step ends, without inserting any text
- The return results of sub-skills (fetcher / analyzer / tailor) are internal data, must not be echoed, repeated, or reported to the user, and should be directly used for the next step
- Prohibited to ask the user "whether to continue" or "whether to start the next step" between steps
Violating the above constraints = process interruption, complete collapse of user experience.
子命令路由
Subcommand Routing
根据用户输入判断执行路径:
| 用户输入 | 执行 |
|---|---|
| 全流程(Step 1→7) |
| 只执行截图导入(Step 1+2+3) |
| 只执行分析(Step 1+4) |
| 执行排序(Step 5)+ 定制(Step 6) |
| 输出当前 run 状态(Step 7b) |
| 强制清理所有缓存和产物(Step 8) |
Determine the execution path based on user input:
| User Input | Execution |
|---|---|
| Full process (Step 1→7) |
| Only execute screenshot import (Step 1+2+3) |
| Only execute analysis (Step 1+4) |
| Execute sorting (Step 5) + customization (Step 6) |
| Output current run status (Step 7b) |
| Force clean all caches and products (Step 8) |
Step 1:确定工作目录与初始化
Step 1: Determine Working Directory and Initialization
work_dir./用 Bash 获取:,将结果作为 。
pwdwork_dirdata_dir<data_dir>/jobHuntSkillDatawork_dir确保以下目录存在(用 Bash 创建):
mkdir -p<data_dir>/.work/jd-pool/
<data_dir>/output/生成 (格式:,使用当前本地时间)。
创建目录 。
run_idYYYY-MM-DD-HHMM<data_dir>/output/<run_id>/初始化 :
<data_dir>/output/<run_id>/state.jsonjson
{
"run_id": "<run_id>",
"phase": "init",
"stages": {
"fetched": [],
"analyzed": [],
"analysis_errors": [],
"tailored": []
},
"last_error": null,
"checkpoint_at": "<当前 ISO 8601 时间>"
}后续所有步骤中凡涉及路径的地方,一律使用 代替 。传给子 skill 的 参数也传入 的值。
data_dirwork_dirwork_dirdata_dir子命令特殊处理:若当前子命令为 、 或 ,在生成新 run_id 之前,先扫描 下已有的 run 目录(格式 ),若存在则复用最新一个 run_id(不创建新目录,读取已有 state.json 继续使用);若不存在,则按上述流程创建新 run_id。
analyzetailorstatus<data_dir>/output/YYYY-MM-DD-HHMMwork_dir./Obtain with Bash: , use the result as .
pwdwork_dirdata_dir<data_dir>/jobHuntSkillDatawork_dirEnsure the following directories exist (create with Bash ):
mkdir -p<data_dir>/.work/jd-pool/
<data_dir>/output/Generate (format: , using current local time).
Create directory .
run_idYYYY-MM-DD-HHMM<data_dir>/output/<run_id>/Initialize :
<data_dir>/output/<run_id>/state.jsonjson
{
"run_id": "<run_id>",
"phase": "init",
"stages": {
"fetched": [],
"analyzed": [],
"analysis_errors": [],
"tailored": []
},
"last_error": null,
"checkpoint_at": "<current ISO 8601 time>"
}In all subsequent steps involving paths, use instead of . Pass the value of as the parameter to sub-skills.
data_dirwork_dirdata_dirwork_dirSubcommand special handling: If the current subcommand is , or , before generating a new run_id, first scan the existing run directories (format ) under . If they exist, reuse the latest run_id (do not create a new directory, read the existing state.json and continue using it); if not, create a new run_id according to the above process.
analyzetailorstatusYYYY-MM-DD-HHMM<data_dir>/output/Step 2:获取简历
Step 2: Obtain Resume
(全流程、fetch、analyze 子命令时执行)
检查 是否存在:
<data_dir>/.work/resume.md若已存在:告知用户:
「已检测到上次保存的简历,继续使用。
如需更换简历,直接把新简历发给我(支持文件 / 路径 / 粘贴文本),我会帮你替换并重新评估。
如果继续用当前简历,告诉我「继续」。」
停止执行,等待用户回复:
- 用户发来新简历 → 按下方「若不存在」的方式处理,覆盖保存 ,进入 Step 2.5 重新评估
resume.md - 用户说「继续」或其他非简历内容 → 跳过本步骤,跳过 Step 2.5,直接进入 Step 3
若不存在:提示用户提供简历:
「请提供你的简历,支持以下两种方式:
① 发送 格式简历文件,或告诉我文件的本地路径(如 )
② 直接将简历文字粘贴到消息框发送(最快最稳,从任意 PDF/Word 阅读器全选复制即可)
.md/Users/xxx/resume.md不支持直接上传 PDF/Word 等版式文件——这类格式跨环境解析容易失真或失败。请用方式 ② 直接贴文本。」
根据用户提供方式处理:
-
发文件(.md)/ 文件路径(.md):用 Read 工具或 Bash 读取文件内容
-
发文件 / 文件路径(其他格式,如 .pdf / .docx / .doc / .txt / .rtf 等):不要尝试任何形式的解析,直接告知用户:「暂不支持 PDF / Word 等版式文件上传(跨环境解析容易失真)。请改用: ① 用任意 PDF/Word 阅读器打开简历,全选(Cmd/Ctrl+A)→ 复制(Cmd/Ctrl+C)→ 粘贴到这里发给我 ② 或将简历另存为格式后重发」
.md停止执行,等待用户重新操作 -
粘贴文本:按下方「粘贴文本处理流程」执行
⛔ 伦理硬约束:无论用户提供什么格式,绝对禁止凭空编造、想象、推断简历内容。识别不了的格式就停止流程让用户重传,绝不生成假简历。
.md 文件分支处理:读取内容后直接写入 ,告知用户「✅ 简历已保存。」,进入 Step 2.5。
<data_dir>/.work/resume.md(Executed for full-process, fetch, analyze subcommands)
Check if exists:
<data_dir>/.work/resume.mdIf it exists: Inform the user:
"A resume saved from last time has been detected, continue using it.
If you need to replace the resume, directly send me the new resume (supports file / path / pasted text), and I will help you replace it and re-evaluate.
If you continue to use the current resume, tell me 'Continue'."
Stop execution and wait for user reply:
- User sends new resume → process according to the "If not exists" method below, overwrite and save , enter Step 2.5 for re-evaluation
resume.md - User says "Continue" or other non-resume content → skip this step, skip Step 2.5, directly enter Step 3
If it does not exist: Prompt the user to provide a resume:
"Please provide your resume, supporting the following two methods:
① Send a .md format resume file, or tell me the local path of the file (e.g., )
② Directly paste the resume text into the message box and send (fastest and most stable, select all and copy from any PDF/Word reader)
/Users/xxx/resume.mdDirect upload of PDF/Word and other layout files is not supported - cross-environment parsing of such formats is prone to distortion or failure. Please use method ② to paste text directly."
Process according to the user's provided method:
-
Send file (.md) / file path (.md): Read the file content using Read tool or Bash
-
Send file / file path (other formats, such as .pdf / .docx / .doc / .txt / .rtf, etc.): Do not attempt any form of parsing, directly inform the user:"PDF / Word and other layout file uploads are not supported temporarily (cross-environment parsing is prone to distortion). Please use: ① Open the resume with any PDF/Word reader, select all (Cmd/Ctrl+A) → copy (Cmd/Ctrl+C) → paste here and send ② Or save the resume as .md format and resend"Stop execution and wait for the user to re-operate
-
Paste text: Execute according to the "Pasted Text Processing Flow" below
⛔ Ethical Hard Constraint: No matter what format the user provides, absolutely prohibit fabricating, imagining, or inferring resume content out of thin air. If the format cannot be recognized, stop the process and let the user re-upload, never generate a fake resume.
.md File Branch Processing: After reading the content, directly write to , inform the user "✅ Resume saved.", enter Step 2.5.
<data_dir>/.work/resume.md粘贴文本处理流程
Pasted Text Processing Flow
仅当用户走「粘贴文本」分支时执行:
Only execute when the user takes the "paste text" branch:
步骤 1:保存原始留底
Step 1: Save Original Backup
将用户粘贴的原始内容(一字不改)写入 。这是任何后续清洗的回滚备份。
<data_dir>/.work/resume.raw.mdWrite the original content pasted by the user (without any modification) into . This is a rollback backup for any subsequent cleaning.
<data_dir>/.work/resume.raw.md步骤 2:启发式检测格式是否已 OK
Step 2: Heuristic Detection of Whether Format is Already OK
判断粘贴文本是否「已是结构化 Markdown」,必须同时满足以下条件:
- 包含 ≥ 2 处章节标记(行首是 、
#或##/1.这类有序列表标号)2. - 包含 ≥ 2 处列表标记(行首是 或
-或*后接空格)+ - 平均非空行长度 ≥ 15 个字符(说明没被一行一词强行断开)
- 不存在大量"单字孤立行"(连续 5 行以上每行只有 1-3 字符的情况)
全部满足:直接把原始内容写入 ,告知用户「✅ 简历已保存(格式良好,直接使用)。」,进入 Step 2.5。不询问、不清洗。
<data_dir>/.work/resume.md任一不满足:进入步骤 3。
Judge whether the pasted text is "already structured Markdown", which must simultaneously meet the following conditions:
- Contains ≥ 2 section markers (line starts with ,
#or ordered list numbers like##/1.)2. - Contains ≥ 2 list markers (line starts with or
-or*followed by a space)+ - Average non-empty line length ≥ 15 characters (indicating no forced line breaks per word)
- No large number of "single-word isolated lines" (more than 5 consecutive lines with only 1-3 characters per line)
All conditions met: Directly write the original content into , inform the user "✅ Resume saved (good format, used directly).", enter Step 2.5. No inquiry, no cleaning.
<data_dir>/.work/resume.mdAny condition not met: Enter Step 3.
步骤 3:询问用户选择
Step 3: Ask User for Selection
关键约束:
- 必须输出用户粘贴的完整简历原文(一字不少,不是预览、不是摘要、不是前 N 字截断)
- 简历原文之后才是 A/B 问题
- A/B 问题必须是整条消息的最后一段,让用户视线最后落点就是
👉 回复 A 或 B - 简历原文之前不要写任何说明文字(如"以下是你的简历""收到了"等开场白)
- 简历原文用代码块(``` 包裹)显示,避免 Markdown 渲染干扰原始格式
输出格式严格如下:
```
<用户粘贴的简历完整原文,一字不动>
```
---
📝 上面是你粘贴的简历内容。看起来格式有些问题——可能存在断行、缺章节标记等,常见于从 PDF/Word 复制带过来的。
两种处理方式:
A. **帮我整理一下** —— 只动格式:合并被断开的同段、还原项目符号、加章节标题;**不动一个字**
B. **保留我的原始格式** —— 我就要这样,不要改
👉 回复 A 或 B停止执行,等待用户回复。
禁止:
- 截断简历内容(即使简历很长也要全部贴出)
- 在 A/B 问题之后再追加任何文字
- 在简历原文上方加任何标题/说明(直接代码块开始)
Key Constraints:
- Must output the complete original resume text pasted by the user (no omissions, not a preview, not a summary, not truncated to first N words)
- The A/B question comes after the resume original text
- The A/B question must be the last paragraph of the entire message, so that the user's last line of sight falls on
👉 Reply A or B - Do not write any explanatory text above the resume original text (such as "The following is your resume" "Received" and other opening remarks)
- Display the resume original text in a code block (wrapped with ```) to avoid Markdown rendering interfering with the original format
Output format strictly as follows:
```
<Complete original resume text pasted by the user, unchanged>
```
---
📝 The above is the resume content you pasted. It seems there are some format issues - there may be line breaks, missing section markers, etc., which are common when copying from PDF/Word.
Two processing methods:
A. **Help me organize it** —— Only modify the format: merge broken lines of the same paragraph, restore project symbols, add section titles; **do not change a single word**
B. **Keep my original format** —— I want it this way, don't change it
👉 Reply A or BStop execution and wait for user reply.
Prohibited:
- Truncate resume content (even if the resume is very long, post it in full)
- Append any text after the A/B question
- Add any title/explanation above the resume original text (start directly with the code block)
步骤 4:按用户选择处理
Step 4: Process According to User's Selection
- 用户回 A(或语义等价:「整理」「清洗」「帮我弄」「随便」等)→ 进入步骤 5 做结构归一化
- 用户回 B(或语义等价:「不动」「原样」「保留」「不要改」等)→ 把原始内容写入 ,告知用户「✅ 已按你的原始格式保存。」,进入 Step 2.5
<data_dir>/.work/resume.md - 用户回模糊内容(如「?」「啥意思」)→ 简短重新解释一次 A/B 含义,再等回复
- 用户直接发了新简历→ 当作重新粘贴处理,回到步骤 1
- User replies A (or semantic equivalents: "organize", "clean", "help me fix", "whatever", etc.) → enter Step 5 for structure normalization
- User replies B (or semantic equivalents: "don't change", "keep as is", "retain", "don't modify", etc.) → write the original content into , inform the user "✅ Saved according to your original format.", enter Step 2.5
<data_dir>/.work/resume.md - User replies ambiguous content (such as "?" "What do you mean") → briefly re-explain the meaning of A/B once, then wait for reply
- User directly sends a new resume → treat as re-pasting, return to Step 1
步骤 5:执行结构归一化(仅 A 路径)
Step 5: Execute Structure Normalization (Only A Path)
严格只动格式,不动一个字。允许做和绝对禁止做的清单:
✅ 允许做:
| 操作 | 说明 |
|---|---|
| 合并被强行断开的同句行 | |
| 合并被拆散的标题/姓名 | |
| 移除连续空行 | 3 个及以上连续空行 → 保留 1 个 |
| 还原项目符号 | 段首孤立的 |
| 还原章节标题层级 | 识别"个人信息""工作经历""项目经历""项目经验""教育背景""专业技能""自我评价"等常见章节关键词,在前面加 |
| 规范缩进 | tab 字符 → 2 空格;行首过多空格统一为 2 空格倍数 |
| 修复编码异常 | 删除零宽字符 |
| 删除明显多栏混排导致的乱序片段 | 仅当能 100% 确定是多栏问题且能正确还原时;不确定就不要动 |
❌ 绝对禁止:
- 增加、删除、改写任何文字内容(哪怕一个字)
- 修正错别字(用户写「杭洲」就保留「杭洲」)
- 翻译、总结、精简、扩写
- 根据上下文推断补齐缺失信息
- 添加用户没提的章节、技能、经历
- 改变事件顺序、时间、数字
违反任何一条 ❌ 即触发伦理硬约束告警,必须停止并告知用户。
清洗完成后:
- 把清洗结果写入
<data_dir>/.work/resume.md - 简短告知用户清洗量:「📝 已整理简历格式:合并 N 处断行 / 还原 M 个项目符号 / 加 K 个章节标题。原始版本已留底(如不满意可说"还原原版")。」
- 进入 Step 2.5
Strictly only modify the format, do not change a single word. List of allowed and absolutely prohibited operations:
✅ Allowed:
| Operation | Description |
|---|---|
| Merge broken lines of the same sentence | |
| Merge split titles/names | |
| Remove consecutive blank lines | 3 or more consecutive blank lines → keep 1 |
| Restore project symbols | Isolated |
| Restore section title hierarchy | Identify common section keywords such as "Personal Information", "Work Experience", "Project Experience", "Educational Background", "Professional Skills", "Self-evaluation", add |
| Standardize indentation | tab characters → 2 spaces; excessive spaces at the beginning of lines unified to multiples of 2 spaces |
| Fix encoding exceptions | Delete invisible characters such as zero-width spaces |
| Delete out-of-order fragments caused by obvious multi-column layout | Only when it is 100% certain that it is a multi-column problem and can be correctly restored; do not modify if uncertain |
❌ Absolutely Prohibited:
- Add, delete, or rewrite any text content (even a single word)
- Correct typos (if the user writes "Hangzhou" as "杭洲", keep "杭洲")
- Translate, summarize, simplify, or expand
- Infer and fill in missing information based on context
- Add sections, skills, or experiences not mentioned by the user
- Change the order, time, or numbers of events
Violating any of the ❌ items triggers an ethical hard constraint alert, must stop and inform the user.
After cleaning is completed:
- Write the cleaned result into
<data_dir>/.work/resume.md - Briefly inform the user of the cleaning amount: "📝 Resume format organized: merged N broken lines / restored M project symbols / added K section titles. The original version has been backed up (say 'restore original version' if unsatisfied)."
- Enter Step 2.5
用户事后反悔(任何阶段)
User Regrets Afterwards (Any Stage)
当用户在后续流程中说出「还原原版」「用原版」「用我贴的那版」「不要清洗后的」等语义等价指令时:
- 检查 是否存在
<data_dir>/.work/resume.raw.md- 不存在 → 告知「未找到原始留底版本(可能本次简历没经过清洗)。如需更换,直接重新粘贴或发送新简历。」
- 存在 → 用 Bash 把 复制覆盖到
resume.raw.mdresume.md
- 告知用户「✅ 已切回原始版本。」
- 重新进入 Step 2.5 评估
When the user says semantic equivalent instructions such as "restore original version", "use original version", "use the version I pasted", "don't use the cleaned version" in subsequent processes:
- Check if exists
<data_dir>/.work/resume.raw.md- Does not exist → inform "Original backup version not found (maybe this resume was not cleaned). If you need to replace it, directly re-paste or send a new resume."
- Exists → use Bash to copy and overwrite
resume.raw.mdresume.md
- Inform the user "✅ Switched back to the original version."
- Re-enter Step 2.5 for evaluation
Step 2.5:简历质量评估
Step 2.5: Resume Quality Evaluation
(仅在用户本次会话中新提供了简历时执行;复用缓存的直接跳到 Step 3)
读取 ,找出所有可评估单元,逐一打分,输出结果。
<data_dir>/.work/resume.md⛔ 必须先过滤,再评估。以下三条规则是强制先决条件,不允许跳过或绕过:
- 在任何评估行为之前,必须完成规则一→二→三的完整筛选流程
- 不得根据公司名、职位名、部门名推断该段经历的工作内容进行评估——评估对象只能是简历中白纸黑字写出的行动动词和结果描述
- 只有通过规则三的文字内容,才能出现在「逐段分析」中;未通过筛选的区块/行,一律不出现
三条判断规则,按顺序执行:
规则一:整个区块跳过(不看内容,直接略过)
下列区块不论写了什么,整体跳过,不评估:
- 个人信息 / 基本信息 / 联系方式
- 专业技能 / 技能特长 / 技术能力 / 工具使用 / 技术栈
- 教育背景 / 教育经历 / 学历
- 自我评价 / 个人简介 / 求职意向
- 证书 / 奖项 / 荣誉
区块名不限于以上文字,只要语义属于上述类型(如「我的技能」「掌握的工具」「所获奖励」),同样整体跳过。
⚠️ 合并区块的处理:如果区块名同时包含工作和教育(如「工作及教育经历」「教育与工作背景」),不整体跳过,进入规则二逐行判断。其中属于教育条目的行(含学校名、专业名、学位、在校时间)按规则二同样会被跳过。
其他所有区块(工作经历、项目经历、实习经历、创业经历、兼职经历,或任何自定义名称的经历类区块)进入规则二。
规则二:区块内的标题行跳过
经历类区块内,每一行单独判断。如果这一行同时满足以下两点,跳过:
- 没有行动动词(负责、主导、设计、推动、搭建、优化、完成、实现、带领等)
- 没有结果描述(提升、降低、增长、减少、达到、超过、节省,或具体数字/百分比)
⚠️ 重要:职位名、部门名中含有的动词性词语不算行动动词。 例如"运营组""品牌部""设计科""管理岗"——这些是组织单元的名称标签,不是对个人行为的描述,不触发评估。判断依据是:这个词是在描述「这个人做了什么」,还是在说明「这个部门/岗位叫什么名字」。
例如:
- 「字节跳动 · 产品经理 · 2021.03—2023.06」→ ❌ 跳过(无动词无结果)
- 「某文化传媒公司 2023.7~2025.11 新媒体-运营组」→ ❌ 跳过("运营"是部门名,不是行动描述)
- 「某互联网科技公司 2022.6~2023.6 市场部-品牌组」→ ❌ 跳过("品牌"是部门名,不是行动描述)
- 「xx大学 2018.9~2022.6 新闻传播专业-本科」→ ❌ 跳过(教育条目,无行动无结果)
- 「项目名称:xxx 平台 | 角色:负责人 | 2022.01—2022.06」→ ❌ 跳过(无动词无结果)
⚠️ 空区块规则(规则二执行完后立即检查)
若某经历类区块经规则二处理后,全部行均被跳过(即该区块内无任何行含有行动动词或结果描述),则该区块不进入下方三维度打分,不得为该区块生成任何评估条目,也不得从其他区块借调内容来填充。
典型场景:「工作及教育经历」区块内只有公司名+时间+部门名三行头部信息,规则二全部跳过后,该区块不参与逐段打分。
📛 但空壳的工作/实习经历不能静默消失,必须显著警示:
在跳过这类区块时,记录其中属于工作/实习经历的空壳条目(公司名 + 时间段,例如「某文化传媒公司 2023.7~2025.11」)。只要存在至少一条,就必须在评估输出最顶部输出「空壳经历警示」块(见下方输出格式)。
原因:空壳工作经历是简历最致命的短板,且 tailor 阶段无法为它做任何改写(伦理红线禁止编造内容)。若这些空壳覆盖了用户的主要工作年限,补全它们比任何简历定制都重要——必须让用户清楚看到,而不是让它默默消失。教育条目空壳不在此警示范围(教育经历本就无需行动/结果)。
规则三:剩下的内容才评估
通过前两条规则筛选后剩下的句子/条目,即为可评估单元,进入下方三维度打分。
⚠️ 标题行与描述混写在同一行时,按规则二判断:只要含有行动动词或结果描述,就评估。
- 「在字节跳动担任产品经理期间主导了 xx 项目落地,DAU 提升 40%」→ ✅ 评估(含动词+结果)
(Only executed when the user provides a new resume in this session; skip directly to Step 3 if reusing cache)
Read , find all evaluable units, score them one by one, and output the results.
<data_dir>/.work/resume.md⛔ Must filter first, then evaluate. The following three rules are mandatory prerequisites, cannot be skipped or bypassed:
- Before any evaluation action, must complete the complete screening process of Rule 1→2→3
- Must not infer the work content of the experience based on company name, position name, or department name for evaluation —— The evaluation object can only be the action verbs and result descriptions written clearly in the resume
- Only the text content that passes Rule 3 can appear in the "Paragraph-by-Paragraph Analysis"; blocks/lines that fail the screening must not appear
Three judgment rules, executed in order:
Rule 1: Skip the entire block (ignore content, skip directly)
The following blocks are skipped entirely regardless of what is written, not evaluated:
- Personal Information / Basic Information / Contact Information
- Professional Skills / Skill Strengths / Technical Abilities / Tool Usage / Technology Stack
- Educational Background / Educational Experience / Academic Qualification
- Self-evaluation / Personal Profile / Job Intention
- Certificates / Awards / Honors
Block names are not limited to the above words, as long as the semantics belong to the above types (such as "My Skills", "Tools Mastered", "Awards Received"), they are also skipped entirely.
⚠️ Processing of merged blocks: If the block name contains both work and education (such as "Work and Educational Experience", "Educational and Work Background"), do not skip entirely, enter Rule 2 to judge line by line. Lines belonging to educational entries (including school name, major name, degree, school time) will also be skipped according to Rule 2.
All other blocks (Work Experience, Project Experience, Internship Experience, Entrepreneurship Experience, Part-time Experience, or any custom-named experience blocks) enter Rule 2.
Rule 2: Skip title lines within blocks
In experience blocks, judge each line individually. If this line meets both of the following two points, skip it:
- No action verbs (responsible for, led, designed, promoted, built, optimized, completed, implemented, led, etc.)
- No result descriptions (improved, reduced, increased, decreased, reached, exceeded, saved, or specific numbers/percentages)
⚠️ Important: Verbal words contained in position names and department names do not count as action verbs. For example, "Operation Group", "Brand Department", "Design Section", "Management Position" —— these are name tags of organizational units, not descriptions of personal behaviors, and do not trigger evaluation. Judgment basis: whether this word describes "what this person did" or "what this department/position is called".
Examples:
- "ByteDance · Product Manager · 2021.03—2023.06" → ❌ Skip (no verbs, no results)
- "A Cultural Media Company 2023.7~2025.11 New Media-Operation Group" → ❌ Skip ("Operation" is the department name, not an action description)
- "An Internet Technology Company 2022.6~2023.6 Marketing Department-Brand Group" → ❌ Skip ("Brand" is the department name, not an action description)
- "XX University 2018.9~2022.6 Journalism and Communication-Bachelor" → ❌ Skip (educational entry, no action, no result)
- "Project Name: xxx Platform | Role: Leader | 2022.01—2022.06" → ❌ Skip (no verbs, no results)
⚠️ Empty Block Rule (Check immediately after executing Rule 2)
If all lines in an experience block are skipped after Rule 2 processing (i.e., no line in the block contains action verbs or result descriptions), then this block does not enter the three-dimensional scoring below, must not generate any evaluation entries for this block, and must not borrow content from other blocks to fill it.
Typical scenario: The "Work and Educational Experience" block only has three lines of header information: company name + time + department name. After all are skipped by Rule 2, this block does not participate in paragraph-by-paragraph scoring.
📛 But empty work/internship experiences cannot disappear silently, must be prominently warned:
When skipping such blocks, record the empty entries belonging to work/internship experiences (company name + time period, e.g., "A Cultural Media Company 2023.7~2025.11"). If there is at least one such entry, must output the "Empty Experience Warning" block at the top of the evaluation output (see output format below).
Reason: Empty work experience is the most fatal shortcoming of a resume, and the tailor stage cannot make any rewrites for it (ethical red line prohibits fabricating content). If these empty experiences cover the user's main working years, completing them is more important than any resume customization —— must let the user see it clearly instead of letting it disappear silently. Empty educational entries are not within this warning scope (educational experience does not require action/results).
Rule 3: Evaluate the remaining content
The sentences/entries remaining after screening through the first two rules are evaluable units, enter the three-dimensional scoring below.
⚠️ When a title line and description are mixed in the same line, judge according to Rule 2: as long as it contains action verbs or result descriptions, evaluate it.
- "During my tenure as a Product Manager at ByteDance, I led the launch of the xx project, increasing DAU by 40%" → ✅ Evaluate (contains verb + result)
评估维度
Evaluation Dimensions
⛔ 只有通过上方规则三筛选的内容才能进入此步骤。 若某区块(如「工作及教育经历」)内所有行均被规则二跳过,该区块整体不生成任何评估条目——即使你能判断那是一段工作经历,也不评估,因为简历里没有写任何行动或结果。
每段描述内容按以下三个维度打分(✅ 合格 / ⚠️ 薄弱 / ❌ 缺失):
| 维度 | ✅ 合格 | ⚠️ 薄弱 | ❌ 缺失 |
|---|---|---|---|
| 场景/问题(S/P) | 有明确业务背景或要解决的问题 | 背景模糊,一笔带过 | 无任何场景描述 |
| 行动(A) | 具体描述「我做了什么」,有方法/手段 | 只写职责,没有行动细节 | 缺失 |
| 结果(R) | 有量化数字,或明确的业务价值 | 结果模糊(如"效果不错") | 无结果描述 |
额外检查:
- 是否大量使用「负责」「参与」「协助」等被动词(减分项,建议改为主动动词)
- 是否有明显可量化但留白的指标(tailor 阶段会插入 占位)
[请填写:xxx]
⛔ Only content that passes Rule 3 above can enter this step. If all lines in a block (such as "Work and Educational Experience") are skipped by Rule 2, no evaluation entries are generated for this block as a whole —— even if you can judge that it is a work experience, do not evaluate it because no actions or results are written in the resume.
Each section of descriptive content is scored according to the following three dimensions (✅ Qualified / ⚠️ Weak / ❌ Missing):
| Dimension | ✅ Qualified | ⚠️ Weak | ❌ Missing |
|---|---|---|---|
| Scenario/Problem (S/P) | Has clear business background or problem to solve | Background is vague and mentioned in passing | No scenario description at all |
| Action (A) | Specifically describes "what I did", with methods/means | Only writes responsibilities, no action details | Missing |
| Result (R) | Has quantified numbers, or clear business value | Result is vague (e.g., "good effect") | No result description |
Additional checks:
- Whether a large number of passive verbs such as "responsible for", "participated in", "assisted" are used (minus points, recommended to change to active verbs)
- Whether there are obvious quantifiable but blank indicators (the tailor stage will insert placeholder)
[Please fill in: xxx]
输出格式
Output Format
📋 简历质量评估
<【仅当检测到空壳工作/实习经历时,在最顶部输出此块;否则整块省略】
⚠️ 重要提醒:你有 <N> 段工作经历是空的
· <公司名> · <时间段>
· <公司名> · <时间段>
这几段只有公司名和时间,没写任何工作内容和成果。这是你简历最大的短板:
- 系统算匹配度时,这些经历因为没内容会被整体跳过,匹配分会明显偏低
- 定制简历时,AI 不会替你编造内容(伦理红线),这几段只能原样保留、无法优化
👉 补全这几段的「做了什么 + 拿到什么结果」,比任何简历定制都重要。强烈建议先选 A 补这部分。
>
整体:<一句话总结,如"行动描述较充分,但结果量化普遍缺失,建议优先补充">
逐段分析:
【公司名 · 职位名】
场景/问题 ✅ 行动 ⚠️ 结果 ❌
问题:<具体说明薄弱点>
建议:<一句话改写方向>
【项目名 · 角色】
场景/问题 ⚠️ 行动 ✅ 结果 ⚠️
问题:<说明>
建议:<建议>
(…其他段落)
⚡ 最值得优先改的 1-2 件事:
1. <最高优先级>
2. <次优先级>
🔧 专业技能板块诊断:
<独立于上方 STAR 评估,专项检查技能板块(语义识别板块,任意名称均适用;若无标题,按内容特征识别:连续排列的技能词/工具名/框架名)。按以下四类问题逐一检查,有问题输出具体条目,无问题省略该类;若整个技能板块无任何问题,省略「🔧 专业技能板块诊断」整节:>
- **虚浮词/空泛声称**:「精通」「熟练掌握」后面没有具体场景或工具,或「精通所有前端技术」这类大而无当的表述。
针对每条有问题的条目给出**改写示范**,例:
「精通 Python」→「熟练使用 Python(Flask/pandas,用于 xx 数据处理)」
- **缺工具名/过于宽泛**:只写了能力方向,没有写具体工具/平台/框架。例「熟悉数据分析」「了解前端开发」。
针对每条给出建议补全方向,例:
「熟悉数据分析」→「熟悉数据分析(SQL / Tableau / Power BI)」
- **无程度分层**:全部条目都是同一程度词(全是「熟悉」或全是「精通」),无法体现能力深浅。
如有此问题,提示按「熟练 / 熟悉 / 了解」或用户实际情况重新分级。
- **与目标岗位明显偏差**:<此项留空,tailor 阶段结合具体 JD 再给建议;Step 2.5 无 JD 上下文,不评估此项>
<仅当上述四类至少有一类有实质问题时,才输出「🔧 专业技能板块诊断」节;若技能板块写得合理(程度词有分层、有工具名、无大量空泛声称),整节省略,不输出任何占位文字。>
---
如何继续?
A. 我自己去改简历,改完发给你重新评估
B. 先不改,用当前简历继续📋 Resume Quality Evaluation
<【Only output this block at the top if empty work/internship experiences are detected; otherwise, omit the entire block】
⚠️ Important Reminder: You have <N> empty work experiences
· <Company Name> · <Time Period>
· <Company Name> · <Time Period>
These sections only have company names and time, no work content or achievements written. This is the biggest shortcoming of your resume:
- When calculating the matching degree, these experiences will be skipped entirely due to no content, and the matching score will be significantly lower
- When customizing the resume, AI will not fabricate content for you (ethical red line), these sections can only be kept as is and cannot be optimized
👉 Completing the "what I did + what results I achieved" for these sections is more important than any resume customization. It is strongly recommended to choose A to supplement this part first.
>
Overall: <One-sentence summary, e.g., "Action descriptions are relatively sufficient, but result quantification is generally missing, it is recommended to supplement first">
Paragraph-by-Paragraph Analysis:
【Company Name · Position Name】
Scenario/Problem ✅ Action ⚠️ Result ❌
Problem: <Specific description of weak points>
Suggestion: <One-sentence rewriting direction>
【Project Name · Role】
Scenario/Problem ⚠️ Action ✅ Result ⚠️
Problem: <Description>
Suggestion: <Suggestion>
(...Other paragraphs)
⚡ Top 1-2 Priority Changes:
1. <Highest priority>
2. <Second priority>
🔧 Professional Skills Section Diagnosis:
<Independent of the above STAR evaluation, special inspection of the skills section (semantic recognition section, applicable to any name; if no title, identify by content characteristics: continuously arranged skill words/tool names/framework names). Check one by one according to the following four types of problems, output specific entries if there are problems, omit the type if no problem; if there are no problems in the entire skills section, omit the entire "🔧 Professional Skills Section Diagnosis" section:>
- **Vague/Empty Claims**: "Proficient" "Skilled in" followed by no specific scenarios or tools, or broad statements such as "proficient in all frontend technologies".
Provide **rewriting examples** for each problematic entry, e.g.:
"Proficient in Python" → "Skilled in Python (Flask/pandas, used for xx data processing)"
- **Missing Tool Names/Too Broad**: Only writes ability directions, no specific tools/platforms/frameworks. E.g., "Familiar with data analysis" "Understand frontend development".
Provide suggested completion directions for each entry, e.g.:
"Familiar with data analysis" → "Familiar with data analysis (SQL / Tableau / Power BI)"
- **No Level Stratification**: All entries use the same level word (all "familiar" or all "proficient"), unable to reflect the depth of ability.
If there is this problem, prompt to re-classify according to "Skilled / Familiar / Understand" or the user's actual situation.
- **明显与目标岗位偏差**: <Leave blank, give suggestions in combination with specific JD in the tailor stage; no JD context in Step 2.5, do not evaluate this item>
<Only output the "🔧 Professional Skills Section Diagnosis" section if at least one of the above four types has substantial problems; if the skills section is written reasonably (level words are stratified, have tool names, no large number of empty claims), omit the entire section and do not output any placeholder text.>
---
How to continue?
A. I will revise my resume myself and send it to you for re-evaluation after revision
B. Do not revise for now, continue with the current resume用户选择处理
User Selection Processing
选 A(修改简历):
- 告知用户:「好的,修改完后直接把新简历发给我(支持文件 / 路径 / 粘贴文本)。」
- 停止执行,等待用户重新发送简历
- 收到后按 Step 2 同样方式处理,覆盖保存
resume.md - 重新执行 Step 2.5(循环,直到用户选 B)
选 B(继续):
- 告知用户:「好的,继续。」
- 执行 Step 3
Choose A (Revise Resume):
- Inform the user: "Okay, directly send me the new resume after revision (supports file / path / pasted text)."
- Stop execution and wait for the user to send the resume again
- After receiving, process in the same way as Step 2, overwrite and save
resume.md - Re-execute Step 2.5 (loop until the user chooses B)
Choose B (Continue):
- Inform the user: "Okay, continue."
- Execute Step 3
Step 3:岗位收集与导入
Step 3: Job Collection and Import
(全流程、fetch 子命令时执行)
提示用户:
「请上传你感兴趣的岗位,支持以下方式:
【方式一】直接发岗位详情页截图(任意招聘平台,Boss/智联/猎聘/拉勾等)
一次可发多张,📌 一张截图 = 一个岗位
岗位信息长请用长截图,截图里至少要有岗位名(公司名可选)
【方式二】告诉我截图所在的目录路径(如 /Users/xxx/Desktop/jobs)
我会自动读取该目录下的所有图片,以及 .jobs.json 文件(不递归子目录)
【方式三】用浏览器插件导出 .jobs.json 文件后一键拖进来(支持 Boss直聘 / 前程无忧 / 智联招聘 / 猎聘)
👉 没装插件?查看 README 安装说明」
发出上方提示后,停止执行,等待用户发送截图或消息。不得提前进入循环。
判断用户输入类型:
| 输入 | 处理分支 |
|---|---|
| 图片附件(一张或多张) | 分支 A:截图解析 |
文件路径,以 | 分支 C:JSON 导入 |
| 目录路径 | 分支 B:扫描目录(图片 + .jobs.json 混合) |
(Executed for full-process, fetch subcommands)
Prompt the user:
"Please upload the jobs you are interested in, supporting the following methods:
【Method 1】Directly send screenshots of job detail pages (any recruitment platform, Boss/Zhilian/Liepin/Lagou, etc.)
You can send multiple at a time, 📌 One screenshot = one job
If the job information is long, use a long screenshot, and the screenshot must at least contain the job name (company name is optional)
【Method 2】Tell me the directory path where the screenshots are located (e.g., /Users/xxx/Desktop/jobs)
I will automatically read all images and .jobs.json files in this directory (no recursive subdirectories)
【Method 3】Export the .jobs.json file with a browser plugin and drag it in with one click (supports Boss Zhipin / 51job / Zhilian Recruitment / Liepin)
👉 No plugin installed? Check the README installation instructions"
After sending the above prompt, stop execution and wait for the user to send screenshots or messages. Do not enter the loop in advance.
Judge user input type:
| Input | Processing Branch |
|---|---|
| Image attachments (one or more) | Branch A: Screenshot Parsing |
File path ending with | Branch C: JSON Import |
| Directory path | Branch B: Scan Directory (mixed images + .jobs.json) |
分支 A:截图解析
Branch A: Screenshot Parsing
调用 Skill 工具,加载 skill,传入:
job-hunt-fetcher- :<data_dir 的值>
work_dir - :<当前 run_id>
run_id - :<本批次截图>
screenshots
fetcher 内部处理(含分组确认交互),完成后写入 jd-pool。
Call the Skill tool, load the skill, pass in:
job-hunt-fetcher- : <value of data_dir>
work_dir - : <current run_id>
run_id - : <batch of screenshots>
screenshots
The fetcher processes internally (including grouping confirmation interaction), and writes to jd-pool after completion.
分支 B:扫描目录
Branch B: Scan Directory
用 Bash 验证目录存在:
ls "<目录路径>"若不存在,告知用户「目录不存在,请确认路径后重新发送。」并重新等待。
用 Bash 列出该目录下的图片文件和 .jobs.json 文件(只读当前目录,不递归子目录):
find "<目录>" -maxdepth 1 -type f \( -iname "*.png" -o -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.webp" -o -iname "*.jobs.json" \) | sort若结果为空,告知用户「该目录下没有找到图片或 .jobs.json 文件,请确认后重新发送。」并重新等待。
告知用户找到了哪些文件:「找到 <N> 张截图 + <M> 个 .jobs.json 文件,开始处理。」
按文件类型分别处理:
- 图片 → 分支 A(调 fetcher)
- 每个 .jobs.json → 分支 C(调 import_jobs.py)
Verify the directory exists with Bash:
ls "<directory path>"If it does not exist, inform the user "Directory does not exist, please confirm the path and resend." and wait again.
List image files and .jobs.json files in the directory with Bash (only read the current directory, no recursive subdirectories):
find "<directory>" -maxdepth 1 -type f \( -iname "*.png" -o -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.webp" -o -iname "*.jobs.json" \) | sortIf the result is empty, inform the user "No images or .jobs.json files found in this directory, please confirm and resend." and wait again.
Inform the user which files were found: "Found <N> screenshots + <M> .jobs.json files, starting processing."
Process by file type:
- Images → Branch A (call fetcher)
- Each .jobs.json → Branch C (call import_jobs.py)
分支 C:JSON 导入
Branch C: JSON Import
用 Bash 调用 import_jobs.py:
bash
if command -v python3 >/dev/null 2>&1; then PYBIN=python3; \
elif command -v python >/dev/null 2>&1; then PYBIN=python; \
else echo "PYTHON_MISSING"; exit 1; fi
"$PYBIN" "$HOME/.claude/skills/job-hunt/import_jobs.py" "<data_dir>" "<json_path>"预期 stdout:
- → 成功,继续
OK: 已导入 N 个岗位 -> ... - → 告知用户「.jobs.json 处理失败:<原因>。请检查文件后重发。」并重新等待
ERROR: ... - → 告知用户「需要 Python 3 才能处理 .jobs.json,请安装后重试。」并停止
PYTHON_MISSING
Call import_jobs.py with Bash:
bash
if command -v python3 >/dev/null 2>&1; then PYBIN=python3; \
elif command -v python >/dev/null 2>&1; then PYBIN=python; \
else echo "PYTHON_MISSING"; exit 1; fi
"$PYBIN" "$HOME/.claude/skills/job-hunt/import_jobs.py" "<data_dir>" "<json_path>"Expected stdout:
- → Success, continue
OK: Imported N jobs -> ... - → Inform the user "Failed to process .jobs.json: <reason>. Please check the file and resend." and wait again
ERROR: ... - → Inform the user "Python 3 is required to process .jobs.json, please install and try again." and stop
PYTHON_MISSING
公共后续
Common Follow-up
不论分支 A/B/C,全部处理完成后:
用 Bash 工具扫描 下所有 文件(排除 ),读取 frontmatter 中 等于当前 run_id 的文件(extension-import 也包含),提取其 字段,作为本批次 ID 列表;将 ID 列表追加到 的 ,更新 和 为 。
<data_dir>/.work/jd-pool/.md.analysis.mdrun_ididstate.jsonstages.fetchedcheckpoint_atphase"fetched"若子命令为 :告知用户「✅ JD 导入完成,共 <N> 个岗位。运行 /job-hunt analyze 开始分析。」并停止。
fetch【全流程】⚠️ 本步骤完成后到 Step 7 之间,严禁输出任何文字(包括不得回显或复述子 skill 的输出内容)。state.json 更新完毕后,下一个动作必须是 Skill 工具调用(执行 Step 4),不得有任何文字夹在中间。
Regardless of Branch A/B/C, after all processing is completed:
Use the Bash tool to scan all files under (exclude ), read the files where in the frontmatter equals the current run_id (extension-import is also included), extract their fields as the batch ID list; append the ID list to 's , update and to .
.md<data_dir>/.work/jd-pool/.analysis.mdrun_ididstate.jsonstages.fetchedcheckpoint_atphase"fetched"If the subcommand is : Inform the user "✅ JD import completed, total <N> jobs. Run /job-hunt analyze to start analysis." and stop.
fetch【Full Process】⚠️ No text output is allowed between the completion of this step and Step 7 (including echoing or repeating the output content of sub-skills). After updating state.json, the next action must be a Skill tool call (execute Step 4), no text can be inserted in between.
Step 4:分析(job-hunt-analyzer)
Step 4: Analysis (job-hunt-analyzer)
(全流程、analyze 子命令时执行)
确定待分析 JD 列表:
- 扫描 下所有
<data_dir>/.work/jd-pool/文件(排除.md结尾的文件).analysis.md - 读取每个文件的 frontmatter,筛选 的文件,提取其
status.analyzed: false字段id - 排除 中已记录失败的 ID
state.json.stages.analysis_errors
若列表为空,告知用户「jd-pool 中没有待分析的 JD,请先上传截图。」并停止。
调用 Skill 工具,加载 skill,传入:
job-hunt-analyzer- :<绝对路径>
work_dir - :
resume_path<data_dir>/.work/resume.md - :<待分析 JD ID 列表>
jd_ids - :
preferences{"soft_preferences": {"prefer_industries": [], "avoid_industries": [], "prefer_company_size": []}, "ranking": {"match_weight": 1.0, "preference_weight": 0.0}} - :<当前 run_id>
run_id
analyzer 返回后,用 Bash 工具更新 state.json 为 。
phase"analyzed"【全流程】⚠️ 不得回显或复述 analyzer 的返回内容,state.json 更新完毕后立即执行 Step 5,不得有任何文字输出。
(Executed for full-process, analyze subcommands)
Determine the list of JDs to be analyzed:
- Scan all files under
.md(exclude files ending with<data_dir>/.work/jd-pool/).analysis.md - Read the frontmatter of each file, filter files with , extract their
status.analyzed: falsefieldsid - Exclude IDs that have been recorded as failed in
state.json.stages.analysis_errors
If the list is empty, inform the user "No JDs to be analyzed in jd-pool, please upload screenshots first." and stop.
Call the Skill tool, load the skill, pass in:
job-hunt-analyzer- : <absolute path>
work_dir - :
resume_path<data_dir>/.work/resume.md - : <list of JD IDs to be analyzed>
jd_ids - :
preferences{"soft_preferences": {"prefer_industries": [], "avoid_industries": [], "prefer_company_size": []}, "ranking": {"match_weight": 1.0, "preference_weight": 0.0}} - : <current run_id>
run_id
After the analyzer returns, use the Bash tool to update 's to .
state.jsonphase"analyzed"【Full Process】⚠️ Do not echo or repeat the return content of the analyzer. Immediately execute Step 5 after updating state.json, no text output allowed.
Step 5:排序
Step 5: Sorting
(全流程或 tailor 子命令前执行,不调用 LLM)
⚠️ 本步骤全程使用 Bash / Read 工具操作,严禁输出任何文字(包括排序过程、中间结果、排名列表)。
用 Bash 读取 ,提取每个文件中的 字段,按降序排列,得到 JD ID 有序列表。所有已分析 JD 全部参与排序,不截断。
<data_dir>/.work/jd-pool/*.analysis.mdscores.total用 Bash 将排序结果写入 的 字段,同时保留在内存中供 Step 6 直接使用。Step 6 断点续跑时,若内存中无排序结果,从 读取。
state.jsonstages.sorted_idsstate.json.stages.sorted_ids【全流程】⚠️ state.json 更新完毕后立即调用 Skill 工具执行 Step 6,不得有任何文字输出。
(Executed before full-process or tailor subcommand, no LLM call)
⚠️ This step uses Bash / Read tools throughout, no text output allowed (including sorting process, intermediate results, ranking list).
Use Bash to read , extract the field from each file, sort in descending order to get the ordered list of JD IDs. All analyzed JDs participate in sorting, no truncation.
<data_dir>/.work/jd-pool/*.analysis.mdscores.totalUse Bash to write the sorting result into the 's field, and keep it in memory for direct use in Step 6. When resuming from a breakpoint in Step 6, if there is no sorting result in memory, read from .
state.jsonstages.sorted_idsstate.json.stages.sorted_ids【Full Process】⚠️ Immediately call the Skill tool to execute Step 6 after updating state.json, no text output allowed.
Step 6:定制简历(job-hunt-tailor)
Step 6: Customize Resume (job-hunt-tailor)
(全流程或 tailor 子命令时执行)
检查 是否存在,若不存在则执行 Step 2 获取简历流程后再继续。
<data_dir>/.work/resume.md取 Step 5 排序后的完整 JD ID 列表。
排除 state.json 中已在 的(断点续跑时跳过)。
stages.tailored调用 Skill 工具,加载 skill,传入:
job-hunt-tailor- :<绝对路径>
work_dir - :
resume_path<data_dir>/.work/resume.md - :<完整排序后的 JD ID 列表>
jd_ids - :<当前 run_id>
run_id
tailor 返回后,用 Bash 工具更新 state.json 为 。
phase"tailored"【全流程】⚠️ 不得回显或复述 tailor 的返回内容,state.json 更新完毕后立即执行 Step 7,不得有任何文字输出。
(Executed for full-process or tailor subcommands)
Check if exists, if not, execute Step 2 to obtain the resume first before continuing.
<data_dir>/.work/resume.mdTake the complete sorted JD ID list from Step 5.
Exclude those already in 's (skip when resuming from breakpoint).
state.jsonstages.tailoredCall the Skill tool, load the skill, pass in:
job-hunt-tailor- : <absolute path>
work_dir - :
resume_path<data_dir>/.work/resume.md - : <complete sorted JD ID list>
jd_ids - : <current run_id>
run_id
After the tailor returns, use the Bash tool to update 's to .
state.jsonphase"tailored"【Full Process】⚠️ Do not echo or repeat the return content of the tailor. Immediately execute Step 7 after updating state.json, no text output allowed.
Step 7:生成 shortlist.html
Step 7: Generate shortlist.html
(全流程最后一步,只产 HTML,不产 MD 文件)
执行顺序(严格按此顺序):
- 用 Bash 工具:探测 Python,调用 生成 shortlist.html
build_html.py - 用 Bash 工具:更新 的
state.json为phase"done" - 最后一步:在聊天里输出一条简短的完成消息(只含 HTML 链接 + 操作提示,不再输出排名 MD 概览,因为 HTML 视图就是用来看这些内容的)
执行命令:
bash
undefined(Last step of full-process, only generate HTML, no MD file)
Execution Order (Strictly Follow This Order):
- Use Bash tool: Detect Python, call to generate shortlist.html
build_html.py - Use Bash tool: Update 's
state.jsontophase"done" - Final Step: Output a short completion message in the chat (only contains HTML link + operation prompt, no longer output ranking MD overview, because the HTML view is for viewing these contents)
Execute command:
bash
undefined1. 探测可用的 Python 命令
1. Detect available Python command
if command -v python3 >/dev/null 2>&1; then
PYBIN=python3
elif command -v python >/dev/null 2>&1; then
兜底(Windows 上常见只有 python 没有 python3)
PYBIN=python
else
PYBIN=""
fi
if command -v python3 >/dev/null 2>&1; then
PYBIN=python3
elif command -v python >/dev/null 2>&1; then
Fallback (common on Windows where only python exists, no python3)
PYBIN=python
else
PYBIN=""
fi
2. 调用脚本,或在没有 Python 时输出降级标记
2. Call script, or output downgrade marker if no Python
if [ -n "$PYBIN" ]; then
"$PYBIN" "$HOME/.claude/skills/job-hunt/build_html.py" "<data_dir>" "<run_id>"
else
echo "PYTHON_MISSING"
fi
**Bash 输出解析规则**(决定最终向用户发的完成消息):
| 脚本 stdout 内容 | 状态 |
|---|---|
| `OK: ...`(无论后续 `OPENED` 或 `OPEN_FAILED`) | HTML 生成成功,提示用户复制链接到浏览器打开 |
| `SKIP: template not found` | 模板文件缺失(极少发生,提示重装) |
| `PYTHON_MISSING` | 系统没装 Python 3,引导用户安装(流程失败,因为现在只产 HTML) |
| `ERROR: ...`(stderr) | 其他错误,告知用户排查 |
**脚本设计原则**:
- LLM 完全不构造 JSON,由脚本自己扫描 jd-pool / tailored 目录读取所有字段
- 空文件优雅处理:tailored 文件不存在 → 该字段为空字符串
- 模板缺失优雅降级:template.html 不存在 → 打印 `SKIP:` 退出 0,主流程不中断
更新 state.json `phase` 为 `"done"` 之后,**必须**在聊天里输出最终消息——根据 Bash 输出的标记选对应文案。
**最终消息文案(4 种分支):**
- **HTML 生成成功**(Python 脚本输出 `OK: ...`):✅ 全部完成!共生成 <N> 份定制简历。
🌐 HTML 视图:file://<data_dir 绝对路径>/output/<run_id>/shortlist.html
💡 复制上面的 file:// 链接到浏览器地址栏打开,即可查看完整简历视图。页面支持:
· 按匹配度排序查看所有岗位
· 在网页上直接编辑简历(自动保存到浏览器本地)
· 一键导出为 PDF(中文字体跨平台一致)
· 切换查看每个岗位的简历 / 改动 / 开场白
其中 `<N>` 用 `state.json.stages.tailored` 数组长度填充。
- **HTML 模板缺失**(Python 脚本输出 `SKIP: ...`):⚠️ 流程已完成,但 HTML 视图未生成。
原因:未找到 ~/.claude/skills/job-hunt/template.html。
解决:请重新安装 skill(运行 install.sh 或 npx skills add)。
各岗位定制简历已写入:<data_dir 绝对路径>/output/<run_id>/tailored/
- **Python 不可用**(Bash 输出 `PYTHON_MISSING`):⚠️ 流程已完成,但 HTML 视图未生成。
原因:你的系统没有 Python 3。
📦 装上 Python 3 之后即可补生成 HTML 视图:
• Mac:终端跑 `xcode-select --install`(一次性,几分钟)
• Windows:访问 https://python.org/downloads/ 下载安装
⚠️ 安装时务必勾选「Add Python to PATH」
• Linux:通常已自带;若没有 `sudo apt install python3` 或 `sudo yum install python3`装完之后,跑这条命令补生成 HTML:
python3 ~/.claude/skills/job-hunt/build_html.py "<data_dir 绝对路径>" "<run_id>"各岗位定制简历已写入:<data_dir 绝对路径>/output/<run_id>/tailored/
- **其他错误**(脚本 stderr 输出 `ERROR: ...`):⚠️ HTML 生成失败。错误信息:<stderr 内容>
各岗位定制简历已写入:<data_dir 绝对路径>/output/<run_id>/tailored/
请检查文件或重新运行。
⚠️ **关键约束**:
- file:// 链接**不要用反引号包**——纯文本链接更容易让用户三击全选复制到浏览器
- 完成消息必须是整条回复的**最后一段**,不得放在中间
- **不再生成 shortlist.md**,也**不在聊天里输出 MD 内容概览**——HTML 视图就是给用户看的,重复输出冗余且占屏
---if [ -n "$PYBIN" ]; then
"$PYBIN" "$HOME/.claude/skills/job-hunt/build_html.py" "<data_dir>" "<run_id>"
else
echo "PYTHON_MISSING"
fi
**Bash Output Parsing Rules** (determine the final completion message sent to the user):
| Script stdout Content | Status |
|---|---|
| `OK: ...` (regardless of subsequent `OPENED` or `OPEN_FAILED`) | HTML generated successfully, prompt user to copy the link to open in browser |
| `SKIP: template not found` | Template file missing (rarely occurs, prompt reinstallation) |
| `PYTHON_MISSING` | Python 3 not installed on the system, guide user to install (process fails because only HTML is generated now) |
| `ERROR: ...` (stderr) | Other errors, inform user to troubleshoot |
**Script Design Principles**:
- LLM does not construct JSON at all, the script scans jd-pool / tailored directory to read all fields by itself
- Elegant handling of empty files: if tailored file does not exist → the field is empty string
- Elegant downgrade when template is missing: if template.html does not exist → print `SKIP:` and exit 0, main process does not interrupt
After updating `state.json`'s `phase` to `"done"`, **must** output the final message in the chat —— select the corresponding copy based on the marker output by Bash.
**Final Message Copy (4 Branches)**:
- **HTML Generated Successfully** (Python script outputs `OK: ...`):✅ All completed! <N> customized resumes generated in total.
🌐 HTML View: file://<absolute path of data_dir>/output/<run_id>/shortlist.html
💡 Copy the above file:// link to the browser address bar to open and view the complete resume view. The page supports:
· View all jobs sorted by matching degree
· Edit resumes directly on the webpage (automatically saved to browser local storage)
· Export to PDF with one click (consistent Chinese fonts across platforms)
· Switch to view resumes / changes / opening remarks for each job
Where `<N>` is filled with the length of `state.json.stages.tailored` array.
- **HTML Template Missing** (Python script outputs `SKIP: ...`):⚠️ Process completed, but HTML view not generated.
Reason: ~/.claude/skills/job-hunt/template.html not found.
Solution: Please reinstall the skill (run install.sh or npx skills add).
Customized resumes for each job have been written to: <absolute path of data_dir>/output/<run_id>/tailored/
- **Python Not Available** (Bash outputs `PYTHON_MISSING`):⚠️ Process completed, but HTML view not generated.
Reason: Your system does not have Python 3.
📦 Install Python 3 to generate HTML view:
• Mac: Run `xcode-select --install` in terminal (one-time, takes a few minutes)
• Windows: Visit https://python.org/downloads/ to download and install
⚠️ Be sure to check "Add Python to PATH" during installation
• Linux: Usually pre-installed; if not, run `sudo apt install python3` or `sudo yum install python3`After installation, run this command to generate HTML:
python3 ~/.claude/skills/job-hunt/build_html.py "<absolute path of data_dir>" "<run_id>"Customized resumes for each job have been written to: <absolute path of data_dir>/output/<run_id>/tailored/
- **Other Errors** (script outputs `ERROR: ...` in stderr):⚠️ HTML generation failed. Error message: <stderr content>
Customized resumes for each job have been written to: <absolute path of data_dir>/output/<run_id>/tailored/
Please check the files or re-run.
⚠️ **Key Constraints**:
- Do not wrap the file:// link with backticks —— plain text links are easier for users to select all with three clicks and copy to the browser
- The completion message must be the **last paragraph** of the entire reply, not placed in the middle
- **No longer generate shortlist.md**, and **no longer output MD content overview in the chat** —— the HTML view is for the user to view, repeated output is redundant and takes up screen space
---Step 7b(status 子命令):输出运行状态
Step 7b (status subcommand): Output Running Status
扫描 下所有子目录,找名字格式为 的目录,读取最新一个的 ,按以下格式输出:
<data_dir>/output/YYYY-MM-DD-HHMMstate.jsonJob-Hunt 状态报告
==================
Run ID:<run_id>
当前阶段:<phase>
工作目录:<data_dir>
进度统计:
已导入 JD:<stages.fetched 数量> 个
完成分析:<stages.analyzed 数量> 个
分析失败:<stages.analysis_errors 数量> 个
生成三件套:<stages.tailored 数量> 个
最后更新:<checkpoint_at>若无任何 run 记录,告知用户「尚未运行过 /job-hunt,请先运行完整流程。」
Scan all subdirectories under , find directories named in the format , read the of the latest one, and output according to the following format:
<data_dir>/output/YYYY-MM-DD-HHMMstate.jsonJob-Hunt Status Report
==================
Run ID: <run_id>
Current Phase: <phase>
Working Directory: <data_dir>
Progress Statistics:
Imported JDs: <number of stages.fetched> pieces
Completed Analysis: <number of stages.analyzed> pieces
Analysis Failures: <number of stages.analysis_errors> pieces
Generated Three-piece Set: <number of stages.tailored> pieces
Last Updated: <checkpoint_at>If there are no run records, inform the user "Have not run /job-hunt yet, please run the full process first."
Step 8(clean 子命令):强制清理
Step 8 (clean subcommand): Force Clean
删除 下所有文件(含 .analysis.md)。
删除 下所有 run 目录。
删除 (若存在)。
统计并告知用户清理了多少文件/目录。
<data_dir>/.work/jd-pool/<data_dir>/output/<data_dir>/.work/resume.mdDelete all files under (including .analysis.md).
Delete all run directories under .
Delete (if exists).
Count and inform the user how many files/directories have been cleaned.
<data_dir>/.work/jd-pool/<data_dir>/output/<data_dir>/.work/resume.md