自由职业提案检查器
目标:撰写一段简短提案,让客户从头读到尾并回复,无论工作在哪个平台上,每一个声称都来自用户自己的事实文件。
检查器是此技能文件夹中的 scripts/lint-cover.mjs(需要 Node 20+,无依赖,无网络)。该文件与本仓库中 cover-letter-lint 技能的文件相同,这样此技能可以独立安装。使用其完整路径调用:在 Claude Code 中为 node ${CLAUDE_SKILL_DIR}/scripts/lint-cover.mjs,在其他 agent 中为技能文件夹路径,例如 node .claude/skills/freelance-proposal-lint/scripts/lint-cover.mjs。
1. 先获取事实
查找 facts.md、me/facts.md 或包含 "facts" 路径的 .cover-lint.json。声称只能来自这些文件。
如果未找到:提供此技能文件夹中的 templates/facts.md 模板,与用户一起填写(技能、角色、履历需与其个人资料完全一致、证明链接、禁止使用的短语)。不要杜撰任何内容。如果用户拒绝,则在不带 --facts 的情况下运行检查,并告知用户未验证声称。
2. 根据平台调整格式
如果用户未说明,询问是哪个平台。然后:
- Upwork:50-90 词的求职信加上任何筛选问题的回答。直接按顺序回答每个筛选问题。
- Freelancer.com、PeoplePerHour、Guru:报价会并排比较,包含价格和交付时间。将具体方案放在第一行,确保文本中的价格和天数与用户在报价表单中输入的数值一致。
- Fiverr brief 或 custom offer:买家已选择类别,因此以他们的确切交付物开头,然后说明套餐包含的内容和修订次数。
- Contra 或直接询盘:视为首次消息,使用
--mode message参数检查。
模仿客户风格:三行随意的回复对应三行随意的回复,另一种语言就用该语言回应。
3. 写作
使用简单句子,不要用项目符号或标题:
- 用客户的风格问候,然后提及他们帖子中的一个具体细节以及可能的原因或你的处理方式。绝不重述帖子内容。
- 从事实文件中选取一条真正匹配的证明。个人项目就称为个人项目。如果没有真实匹配,则省略证明。
- 用一两句话说明计划,如果用户给出了费率则包含小时数和价格。
- 提一个问题,即答案会影响范围或价格的那个问题。
- 单独一行写上用户的名字。
4. 检查并修复
node ${CLAUDE_SKILL_DIR}/scripts/lint-cover.mjs --facts facts.md --job job.md bid.md
- 表示从标准输入读取,--mode message 对回复关闭字数范围检查,--json 输出机器可读结果。修复所有错误并重新运行,直到返回 0。除非有原因,否则也要修复警告,并说明原因。
导致提案失败的错误:模板短语(如“I hope this finds you well”、“seamless”、“I'm excited to”)、“not just X, but Y”对比结构、em 破折号、[Your Name] 这样的占位符、邮箱地址、电话号码或“message me on WhatsApp”(大多数平台在合同签订前禁止向站外传递联系方式)、事实文件无法支持的链接和“N years”、“Never say”列表中的短语、cover 模式下超过 90 词。警告包括:事实文件和帖子中都没有的技术名称、缺少或出现第二个问题、列表、“Dear Sir”、“!!”、表情符号以及非常长的句子。每个项目的自定义配置放在 .cover-lint.json 中:
{"facts": "facts.md", "maxWords": 90, "minWords": 50, "extraPhrases": [], "allowPhrases": [], "disable": []}。
除非用户确认属实,否则绝不修改事实文件来让声称通过检查。
5. 交付提案
展示提案文本、其中标明的价格和交付时间,以及检查器的最后一行输出。然后亲自再次对照事实文件通读一遍:检查器只检查链接、年份和技术名称,并不是每个句子。由用户发送;绝不能代替用户提交任何内容。