---
name: publish-fuwari-articles
description: 为 Fuwari CMS 撰写、润色、检查、上传和管理文章。通过 Fuwari MCP 或受 OAuth Bearer 保护的 JSON API 创建草稿、更新正文、上传媒体，以及在用户明确要求时发布、定时、撤回或归档。用户说“给 Fuwari 写一篇文章”“上传到 Fuwari”“保存、更新、发布或定时文章”或排查 Fuwari Markdown 时使用。
---

# Fuwari 文章写作与发布

为 Fuwari 生成符合站点格式的文章，并通过站点提供的 MCP/API 上传。用户明确要求“用 Fuwari Skill 写一篇文章”时，默认包含创建一篇 `draft`，除非用户说只要内容、先不要上传或不要保存。

## 只使用受保护接口

- 首选 Skill 配置的 Fuwari MCP 工具；MCP 不可用但已有受信任站点地址和 OAuth Bearer 客户端时，才使用同站点 `/api/v1/` JSON API。
- 不在浏览器后台中输入文章，不提交管理员 HTML 表单，不直接改数据库，也不调用旧 Markdown 种子、Front Matter、`src/content/posts/` 或 `pnpm new-post`。
- 不向用户索取管理员密码、会话 Cookie、CSRF Token 或数据库凭据。认证由 MCP/API 的 OAuth 2.1 授权码与 PKCE 流程完成。
- 首次连接时让客户端打开站点授权页供用户同意。客户端应安全保存访问令牌和刷新令牌、自动刷新并持续复用；不要为每篇文章或每次工具调用重新授权。
- 仅在授权被撤销、刷新令牌已失效，或用户要求了现有授权之外的新 scope 时重新打开授权页。
- 若 MCP/API 不可用或认证失败，停止网站写入并说明原因；不要回退到浏览器自动化或猜测接口。

## 判断用户意图

- “写一篇、给网站写、用这个 Skill 写”默认：撰写内容、接口预览、创建 `draft`、回读验证。
- “只写内容、先给我看、不要上传、不要保存”只产出可审阅内容，不创建 CMS 记录。
- “保存、上传、创建草稿”创建 `draft`。未明确发布时不得创建为其他状态。
- “修改、润色网站上的文章”先读取指定文章及 `revision`，只更新用户要求的字段，并保留原状态和发布时间。
- “发布、立即上线”才可设为 `published`；“定时发布”才可设为 `scheduled`，且必须有明确时间和时区。
- “撤回、归档、移入回收站”分别只授权改为 `draft`、`archived`、`trash`。
- 当前 AI API 不提供永久删除。用户要求硬删除时说明需在管理员后台人工完成，不得寻找绕过方法。
- 上传媒体必须是当前文章任务所需，或由用户明确要求。
- 站点、文章目标、状态或定时时间存在会实质改变结果的歧义时，在写入前询问。

## 按任务读取参考资料

- 撰写、润色或检查正文时，读取 [references/article-writing.md](references/article-writing.md)。
- 连接站点、调用工具或 JSON API 时，读取 [references/cms-api.md](references/cms-api.md)。
- 每次 CMS 写入前，读取 [references/api-verification-and-recovery.md](references/api-verification-and-recovery.md)。
- 纯内容任务不加载接口和写后验证参考。

若目标站点行为与参考资料冲突，停止写入并向用户说明差异；不要猜测新接口。

## 创建文章流程

1. 确认主题、读者、语言、篇幅、语气和事实要求。普通细节可合理推断；会改变核心结论的信息先询问。
2. 调用 `fuwari_get_capabilities`，确认目标站点、可用 scope、字段限制和服务版本。一次任务中不重复调用，除非服务提示能力已变化。
3. 生成标题、建议 slug、摘要、`bodyMarkdown`、语言、SEO 字段、封面、分类和标签建议。正文不含 Front Matter 或重复 H1。
4. 调用 `fuwari_preview_markdown` 检查渲染结果、标题结构、字数和扩展语法。修正错误后再写入。
5. 用户没有禁止上传时，调用 `fuwari_create_post_draft`。使用唯一幂等键；网络结果不确定时复用同一个键，不能换键盲目重建。
6. 用返回的 canonical 文章记录核对全部字段；必要时再调用 `fuwari_get_post` 回读。只有实际记录满足请求才报告成功。

## 更新与状态流程

1. 用 `fuwari_list_posts` 查找候选，并用 `fuwari_get_post` 读取精确 ID、完整字段和当前 `revision`。标题或 slug 匹配不唯一时让用户选择。
2. 更新正文前先预览最终 Markdown。调用 `fuwari_update_post` 时使用读取结果中的不透明 `id`（不要假定它的格式，也不要用 slug），提交 `expectedRevision`，保留未获授权改变的字段。
3. 状态改变使用 `fuwari_set_post_status`，同样使用不透明 `id` 并提交当前 `expectedRevision`。发布或定时需要 `posts:publish` scope；普通写作授权不得升级状态。
4. 收到 `409` 时重新读取。只有服务器改动和用户改动不冲突时才自动合并并重试一次；同字段冲突交给用户决定。
5. 写后按验证参考回读 canonical 状态和适用的公开地址。

## 媒体与分类标签

- 创建前优先调用 `fuwari_list_taxonomies` 复用已有分类和标签；只有用户意图明确且具备 `taxonomy:write` 时创建新词项。
- 上传前核对文件来源、类型、大小和用途。调用 `fuwari_upload_media` 后使用返回的媒体 ID 与站内 URL，不根据文件名猜测。
- 封面只使用图片媒体。正文图片要有准确替代文字；其他附件使用普通链接。

## 控制重试与权限

- `401`：让 OAuth 客户端尝试刷新一次；不要让用户重复同意。刷新失败才重新授权。
- `403 insufficient_scope`：只有用户当前请求确实需要更高权限时才发起增量授权；否则保持原权限并停止该操作。
- `409`：按 revision 冲突流程处理。`429`：遵守 `Retry-After`，不要密集重试。
- 创建或上传超时后，先用原幂等键重试或回读结果。更新、状态操作超时后先读取目标状态，不能盲目重复写入。
- 每个业务操作最多自动重放一次；仍不确定时报告 `unknown`。

## 完成标准

最终说明标题、实际 slug、状态、含时区发布时间、后台地址、公开地址、revision 和验证结果。结论使用 `verified`、`partially verified`、`failed` 或 `unknown`；不要把预期结果写成已完成，也不要泄露令牌或认证信息。
