diff --git a/profile/README.md b/profile/README.md index 9d5dbaf..eec579e 100644 --- a/profile/README.md +++ b/profile/README.md @@ -2,53 +2,45 @@ # md2wechat -面向 AI Agent 的微信公众号创作与发布 CLI,也是连接 Markdown、公众号排版、图片、预览校验和草稿流程的开放生态。 +md2wechat 是面向 AI Agent 的微信公众号创作与发布 CLI。 + +把 Markdown 变成适合微信公众号的内容:你可以在线排版,也可以用 CLI 或 Skill 在自己的工作流中完成检查、预览、转换,以及在授权后创建草稿。 [在线编辑器](https://www.md2wechat.cn) · [CLI / Skill](https://github.com/geekjourneyx/md2wechat-skill) · [使用指南](https://github.com/md2wechat/md2wechat-guide) · [可执行模板](https://github.com/md2wechat/md2wechat-templates) -## 按任务选择入口 - -| 你要完成的任务 | 推荐入口 | 边界 | -|---|---|---| -| 在线编辑 Markdown 并复制微信富文本 | [在线编辑器](https://www.md2wechat.cn) | 人工编辑、预览和复制 | -| 在 Codex、Claude Code 等 Agent 中完成公众号工作流 | [md2wechat CLI / Skill](https://github.com/geekjourneyx/md2wechat-skill) | 核心产品与 Agent 运行协议 | -| 将 Markdown 转成微信兼容 HTML | [Convert API](https://www.md2wechat.cn/api-docs) | 只转换内容,不创建公众号草稿 | -| 接入素材与公众号草稿服务 | [Publishing API](https://md2wechat.com/api/v1) | 涉及外部写操作,需要凭证和用户确认 | -| 按步骤完成安装、发现、检查、预览和发布 | [Guide](https://github.com/md2wechat/md2wechat-guide) | 稳定任务教程 | -| 复用企业办公与创作者内容骨架 | [md2wechat Templates](https://github.com/md2wechat/md2wechat-templates) | 可验证的 Markdown 模板 | -| 查找微信 Markdown、发布、Skill 和 MCP 工具 | [Awesome](https://github.com/md2wechat/awesome-wechat-markdown) | 中立生态目录 | -| 核对版本事实、术语和平台证据 | [Wiki](https://github.com/md2wechat/md2wechat-wiki) | 事实来源与复核记录 | +## 选择使用方式 -## 最短可验证路径 +| 你想做什么 | 从这里开始 | +|---|---| +| 在线编辑 Markdown、预览并复制微信富文本 | [在线编辑器](https://www.md2wechat.cn) | +| 在本地工作流中处理公众号内容 | [md2wechat CLI / Skill](https://github.com/geekjourneyx/md2wechat-skill) | +| 将 Markdown 转为微信兼容 HTML | [Convert API](https://www.md2wechat.cn/api-docs):只转换 HTML,不创建草稿 | +| 上传素材并创建公众号草稿 | [Publishing API](https://md2wechat.com/api/v1):创建草稿不等于群发 | -具体命令、主题和 Layout 能力以当前安装版本的 Discovery 输出为准: +## 第一次使用 -```bash -md2wechat version --json -md2wechat capabilities --json -md2wechat skills read md2wechat --json -``` +想先看看排版效果,可直接打开[在线编辑器](https://www.md2wechat.cn),粘贴 Markdown 后预览并复制内容。 -推荐流程:安装 → Discovery → 结构检查 → 排版 → 本地/API 预览 → 用户确认后的草稿操作。创建草稿不等于群发。 +想把流程放进本地项目或日常写作工具,请从 [CLI / Skill](https://github.com/geekjourneyx/md2wechat-skill) 开始,再按 [Guide](https://github.com/md2wechat/md2wechat-guide) 的步骤安装和使用。 -## 产品关系 +## 在 AI 工具中使用 -- **CLI / Skill**:Agent 原生的公众号创作与发布入口。 -- **在线编辑器**:适合人工编辑、实时预览和复制 HTML。 -- **Convert API**:`POST https://www.md2wechat.cn/api/convert`,负责 Markdown 到微信兼容 HTML 的转换。 -- **Publishing API**:`https://md2wechat.com/api/v1`,负责需要授权的素材和草稿副作用服务。 +能够运行本地命令的 AI 工具,可以通过 md2wechat 的 [Skill / CLI](https://github.com/geekjourneyx/md2wechat-skill) 接入内容工作流。不同工具的安装方法与使用记录请查看 [Guide](https://github.com/md2wechat/md2wechat-guide) 和 [Wiki](https://github.com/md2wechat/md2wechat-wiki)。 -## 平台兼容性 +## 文档与生态 -办公 Agent 和技能市场变化很快。平台是否可安装、是否完成真实 smoke、是否能创建草稿,必须分开记录;组织主页不直接宣布未经复核的支持关系。查看 [Wiki 的状态与证据](https://github.com/md2wechat/md2wechat-wiki/tree/main/evidence)。 +- [Guide](https://github.com/md2wechat/md2wechat-guide):安装、排版、预览和发布的分步说明 +- [md2wechat Templates](https://github.com/md2wechat/md2wechat-templates):可复用的内容骨架 +- [Awesome](https://github.com/md2wechat/awesome-wechat-markdown):微信 Markdown、发布、Skill 和 MCP 工具目录 +- [Wiki](https://github.com/md2wechat/md2wechat-wiki):版本事实、术语与使用记录 -## 参与维护 +## 反馈 - CLI、渲染、安装和发布问题:[主项目 Issues](https://github.com/geekjourneyx/md2wechat-skill/issues) - 教程错误:[Guide Issues](https://github.com/md2wechat/md2wechat-guide/issues) - 生态项目新增或更正:[Awesome Issues](https://github.com/md2wechat/awesome-wechat-markdown/issues) -- 版本、术语或证据问题:[Wiki Issues](https://github.com/md2wechat/md2wechat-wiki/issues) +- 版本或术语问题:[Wiki Issues](https://github.com/md2wechat/md2wechat-wiki/issues) -提交问题前请删除 AppID、AppSecret、API Key、Cookie、草稿 ID 和未公开文章内容。 +请勿在 Issue 中粘贴 AppID、AppSecret、API Key、Cookie、草稿 ID 或未公开文章内容。 diff --git a/scripts/validate-facts.mjs b/scripts/validate-facts.mjs index fdf448c..fa550ef 100644 --- a/scripts/validate-facts.mjs +++ b/scripts/validate-facts.mjs @@ -182,8 +182,16 @@ export function validateProfile(profile, facts) { if (claim.test(profile)) { errors.push("profile contains an evidence-gated platform support claim") } - if (/Convert API.{0,16}(?:创建|生成).{0,8}草稿/s.test(profile)) { - errors.push("profile confuses Convert API with draft creation") + const convertDraftClaims = profile.match(/Convert API[^。!?\n]*/g) ?? [] + for (const sentence of convertDraftClaims) { + const withoutNegativeClaims = sentence.replaceAll( + /(?:不|不会|不能|不提供|未)(?:创建|生成)[^。!?\n]{0,8}草稿/g, + "", + ) + if (/(?:创建|生成)[^。!?\n]{0,8}草稿/.test(withoutNegativeClaims)) { + errors.push("profile confuses Convert API with draft creation") + break + } } return errors } diff --git a/tests/validate-facts.test.mjs b/tests/validate-facts.test.mjs index f9f3ce0..a997fdb 100644 --- a/tests/validate-facts.test.mjs +++ b/tests/validate-facts.test.mjs @@ -42,6 +42,50 @@ test("the validator accepts the repository contracts and rendered profile", () = assert.equal(result.status, 0, result.stderr || result.stdout) }) + +test("public profile uses reader-facing language", () => { + const profile = readFileSync(new URL("profile/README.md", root), "utf8") + const internalTerms = [ + "最短可验证路径", + "产品关系", + "平台兼容性", + "smoke", + "publiclySupported", + "Discovery 输出", + "失效条件", + "核验基线", + "状态注册表", + "副作用", + "未经复核的支持关系", + "状态与证据", + ] + for (const term of internalTerms) { + assert.equal(profile.includes(term), false, `profile must not contain internal term: ${term}`) + } +}) + +test("public profile uses real Markdown line breaks", () => { + const profile = readFileSync(new URL("profile/README.md", root), "utf8") + assert.equal(profile.includes("\\n"), false, "profile must not contain literal escaped line breaks") +}) + +test("profile guard distinguishes negative Convert API draft wording from claims", () => { + const facts = readJson("facts/product-routes.json") + for (const profile of [ + "Convert API 不创建草稿", + "Convert API 只转换内容,不会生成草稿", + ]) { + assert.doesNotMatch( + validator.validateProfile(profile, facts).join("\n"), + /profile confuses Convert API with draft creation/, + ) + } + assert.match( + validator.validateProfile("Convert API 可以创建草稿", facts).join("\n"), + /profile confuses Convert API with draft creation/, + ) +}) + test("the validator reports immutable source SHA drift", () => { const fixture = JSON.stringify({ schemaVersion: 1,