Community写作与编辑github.com

atokim4/cover-letter-lint

撰写或检查自由职业求职信、提案、出价或客户消息,确保读起来像人写的,并且每项声明都有用户事实文件支撑。当用户要求为职位(Upwork、Fiverr、PeoplePerHour、Freelancer.com、招聘网站)撰写求职信、提案或出价,或要求检查、改进,或询问‘这听起来像AI吗’时使用。运行一个Node linter,标记AI短语、长破折号、‘不是X而是Y’、占位符、站外联系方式、50-90词范围、结尾问题以及用户事实文件中缺失的声明。

cover-letter-lint 是什么?

这是一个用于自由职业求职信、提案和投标的专业linter技能,其核心目标是让每次沟通都读起来像真人撰写,同时确保所有声明均可追溯来源。该技能包含一个基于Node 20+的linter脚本`scripts/lint-cover.mjs`,支持Claude Code(通过$CLAUDE_SKILL_DIR变量)、项目安装(`.claude/skills/cover-letter-lint/`)或全局安装(`~/.claude/skills/`)。技能的工作流程分为四个步骤:首先查找项目中的`facts.md`或`.cover-lint.json`配置,读取用户的技能、角色和资质证据;然后根据职位发布内容撰写50-90词的简洁求职信,包含具体细节、一条匹配的证据、含工时和价格(如有)的计划以及一个关键问题;接着运行linter检查AI模板短语、长破折号、`不是X而是Y`结构、占位符、站外联系方式、未证实声明、禁止词汇等十余种错误和警告,用户需修复所有错误至零退出码;最后展示信件和linter结果,让用户自行发送。该技能特别适合Upwork、Fiverr等自由职业平台的投标场景,也支持普通招聘网站的求职信撰写,其独特之处在于通过facts文件将用户的真实能力与每句声明绑定,避免了AI写作常见的空泛和不可信问题。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/atokim4/cover-letter-lint/tree/HEAD/skills/cover-letter-lint

Installed? Explore more 写作与编辑 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

求职信linter

目标:一封50-90词、忙碌客户能读到最后并回复的求职信,信中每项声明都基于用户自己的事实文件。

linter是该技能文件夹中的scripts/lint-cover.mjs(Node 20+,无依赖)。在Claude Code(也适用于插件安装)中通过完整路径调用:node ${CLAUDE_SKILL_DIR}/scripts/lint-cover.mjs。其他agent不会填充该变量,因此对于项目安装请使用类似node .claude/skills/cover-letter-lint/scripts/lint-cover.mjs的路径,对于全局安装则使用node ~/.claude/skills/cover-letter-lint/scripts/lint-cover.mjs。

1. 查找事实文件

在当前项目中查找facts.md、me/facts.md或包含"facts"路径的.cover-lint.json。

  • 找到:读取它。声明只能来自该文件。
  • 未找到:提供从该技能文件夹中的templates/facts.md创建facts.md的选项,并让用户填写内容(技能、角色、过往成绩、证据链接、绝不提及的事项)。不要编造任何内容。如果用户拒绝,则在不带--facts的情况下运行linter,并告知他们声明未经检查。

2. 撰写(如果用户已提供草稿,则跳过此步骤)

如果用户粘贴了职位发布内容,则将其保存到一个文件中(例如job.md)。然后以纯句子形式撰写,不使用项目符号或标题:

  1. 用客户风格的问候语开头,然后提及客户帖子的一个具体细节(bug、技术栈、截止日期),以及可能的原因或你打算如何处理它。绝不重述帖子内容。
  2. 从事实文件中选取一条真正匹配的证据(类似的工作、角色、演示链接)。个人项目就称为个人项目。如果没有诚实的匹配项,则省略证据。
  3. 用一两句话描述计划,如果用户提供了费率,则加上工时和价格。
  4. 提出一个问题,一个答案会改变项目范围或价格的问题。
  5. 将用户的名字单独放在一行。

模仿帖子的风格:三行随意的帖子用三行随意的回复,其他语言的帖子用该语言回复。

3. Lint并修复

node ${CLAUDE_SKILL_DIR}/scripts/lint-cover.mjs --facts facts.md --job job.md proposal.md

(-表示读取stdin;--mode message用于客户回复,此类回复没有字数范围;--json用于机器输出。) 修复每一个错误并重新运行,直到退出码为0。对于警告:除非有理由,否则也修复它们,并说明理由。对于unlisted-skill,要么移除该声明,要么询问用户是否要将该技能添加到事实文件中。切勿为了通过声明而编辑事实文件,除非用户承认该声明确实属实。

规则级别检测内容
ai-phrase错误约75个模板短语:“I hope this finds you well”、“seamless”、“I'm excited to”、“the key is”……
not-x-but-y错误“This is not just X, but Y”之类的对比句式
dash错误长破折号以及用作长破折号的连字符
placeholder错误[Your Name]、{{name}}、<client>、TODO、lorem ipsum
off-platform错误电子邮件、电话号码、“message me on WhatsApp”、市场平台外付款
unbacked-claim错误事实文件中不存在的链接和“N years”
never-say错误事实文件中“Never say”(绝不提及)部分列出的短语
word-count错误/警告超过90词(错误),低于50词(警告)——仅在信件模式下
unlisted-skill警告信件中提到的、既不在事实文件也不在职位发布中的框架或服务
question警告没有问题,或问题超过一个
list, greeting, exclamation, emoji, long-sentence, i-start警告列表、“Dear Sir”、“!!”、表情符号、35词以上的句子、过多以“I”开头的句子

每个项目的调整配置放在.cover-lint.json中(所有键均可选): {"facts": "facts.md", "maxWords": 90, "minWords": 50, "extraPhrases": [], "allowPhrases": [], "disable": []}。

4. 交付

展示信件以及linter的最后一行输出。明确说明你设定的价格和你选择的问题,以便用户能够修改。然后你自己再对照事实文件通读一遍:linter检查的是链接、年份和技术名称,而不是每一个句子。由用户发送;切勿替用户提交任何内容。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能