{"id":"da21743b-c882-4978-8871-b8d44e676d43","entityType":"agent","slug":"clawhub-aiworkskills-aws-wechat-article-main","name":"aws-wechat-article-main","canonicalUrl":"https://www.xpersona.co/agent/clawhub-aiworkskills-aws-wechat-article-main","canonicalPath":"/agent/clawhub-aiworkskills-aws-wechat-article-main","generatedAt":"2026-10-10T10:43:55.081Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:43:04.445Z","emptyReason":null},"description":"公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继续上次的」「接着之前的进度」；**显式模型新写**「用 GPT 写一篇」「用 DeepSeek 写一篇」「把提纲写成文章」。子 skill（topics/writing/review/formatting/images/publish/sticker/assets）单独触发仅限对**已有产物**的修改场景（如\"改标题\"\"润色这段\"\"排版\"\"审稿\"\"加封面\"\"发布\"）；新做/策划/多环节串联一律走本入口。","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.6K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s170f08a9xbhfkfp1vjv33y1ph842r9a:aws-wechat-article-main","sourceUrl":"https://clawhub.ai/aiworkskills/aws-wechat-article-main","homepage":"https://clawhub.ai/aiworkskills/skills/aws-wechat-article-main","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/aiworkskills/aws-wechat-article-main","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/aiworkskills/skills/aws-wechat-article-main","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":64,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"aws-wechat-article-main technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:43:04.445Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:43:04.445Z","emptyReason":null},"stars":null,"forks":null,"downloads":1583,"packageName":null,"latestVersion":"1.0.27","tractionLabel":"1.6K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:43:04.415Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T07:43:04.445Z","lastCrawledAt":"2026-10-10T07:43:04.415Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T07:43:04.415Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.27","createdAt":"2026-09-07T16:07:10.539Z","changelog":"本篇预设落盘新增 default_format_scheme（排版配色）；选排版模版与配色时要求先跑 format.py --list-themes 按「适合/不适合」对本篇题材，不再只看名字。config.example.yaml 同步加 default_format_scheme / custom_format_scheme。","fileCount":24,"zipByteSize":40139},{"version":"1.0.26","createdAt":"2026-09-06T07:23:31.615Z","changelog":"统一 {python} 解释器占位符并补 Windows 探测（Windows 用 py -3 -X utf8）；引入 .aws-article/products/{产品名}/ 业务资料库的读+写双向规则；封面裁剪框接入发布链路；修「跑错目录被报成模型未配置」等一批误报。","fileCount":24,"zipByteSize":40069},{"version":"1.0.25","createdAt":"2026-04-25T14:36:34.606Z","changelog":"移除 first-time-setup.md 的'快速通道'段：scanner 把'main 推荐用户从特定外部域名导入凭证'判为远程导入风险。assets skill 的 .aws 导入功能不受影响（在 assets SKILL.md 里完整文档化）。","fileCount":24,"zipByteSize":39699},{"version":"1.0.24","createdAt":"2026-04-25T14:18:55.131Z","changelog":"新增：导入 .aws 预设包时密钥字段（wechat_appid/secret、writing_model.api_key、image_model.api_key）按映射表增量写入仓库根 aws.env，覆盖前自动备份 aws.env.bak.{ts}，stderr 仅打印键名不打印值。SKILL.md 完整披露写入策略与字段映射表。main 的 first-time-setup.md 增加 .aws 快速通道引导。","fileCount":23,"zipByteSize":38675},{"version":"1.0.23","createdAt":"2026-04-24T13:03:48.203Z","changelog":"引入 .aws-article/products/{产品名}/ 业务资料库：涉及自家产品的写稿/配图前先查 products/；AI 生成的业务介绍引导保存到 products/{产品名}/*.md。assets 的图片入库脚本重命名 stock_image_ingest.py → product_image_ingest.py（按产品分目录）。","fileCount":23,"zipByteSize":38454},{"version":"1.0.22","createdAt":"2026-04-22T23:23:41.081Z","changelog":"软化版套件完整性提示：说明工作流会读跨 skill 共享文档、单独安装时会 file-not-found；纯信息性语气，无 shell 循环、无 Agent 强指令","fileCount":23,"zipByteSize":37943},{"version":"1.0.21","createdAt":"2026-04-22T22:44:41.365Z","changelog":"修 scanner 新点名的 credential-in-chat antipattern：移除 first-time-setup.md 里'您可直接把缺失配置发给我'话术；改为引导用户自己在编辑器中编辑 aws.env；强化原则：Agent 不索取/接收对话里粘贴的密钥","fileCount":23,"zipByteSize":37862},{"version":"1.0.20","createdAt":"2026-04-22T22:35:10.454Z","changelog":"修 scanner 精准点名：移除'不外传/不读仓库外'假陈述；补凭证/内容外发披露；sticker+review 补 WECHAT 凭证声明；空 env 的 skill 移除 primaryEnv；3 个脚本不再遍历父目录","fileCount":23,"zipByteSize":37390}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s170f08a9xbhfkfp1vjv33y1ph842r9a:aws-wechat-article-main","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s170f08a9xbhfkfp1vjv33y1ph842r9a:aws-wechat-article-main` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/aiworkskills/aws-wechat-article-main before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T10:43:55.077Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-main/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:43:04.445Z","emptyReason":null},"readme":"Skill: aws-wechat-article-main\n\nOwner: aiworkskills\n\nSummary: 公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继续上次的」「接着之前的进度」；**显式模型新写**「用 GPT 写一篇」「用 DeepSeek 写一篇」「把提纲写成文章」。子 skill（topics/writing/review/formatting/images/publish/sticker/assets）单独触发仅限对**已有产物**的修改场景（如\"改标题\"\"润色这段\"\"排版\"\"审稿\"\"加封面\"\"发布\"）；新做/策划/多环节串联一律走本入口。\n\nTags: ai:1.0.17, aigc:1.0.17, all-in-one:1.0.17, chinese:1.0.17, claude-code:1.0.17, content-pipeline:1.0.17, latest:1.0.27, skill-suite:1.0.17, wechat:1.0.17, wechat-official-account:1.0.17\n\nVersion history:\n\nv1.0.27 | 2026-09-07T16:07:10.539Z | user\n\n本篇预设落盘新增 default_format_scheme（排版配色）；选排版模版与配色时要求先跑 format.py --list-themes 按「适合/不适合」对本篇题材，不再只看名字。config.example.yaml 同步加 default_format_scheme / custom_format_scheme。\n\nv1.0.26 | 2026-09-06T07:23:31.615Z | user\n\n统一 {python} 解释器占位符并补 Windows 探测（Windows 用 py -3 -X utf8）；引入 .aws-article/products/{产品名}/ 业务资料库的读+写双向规则；封面裁剪框接入发布链路；修「跑错目录被报成模型未配置」等一批误报。\n\nv1.0.25 | 2026-04-25T14:36:34.606Z | user\n\n移除 first-time-setup.md 的'快速通道'段：scanner 把'main 推荐用户从特定外部域名导入凭证'判为远程导入风险。assets skill 的 .aws 导入功能不受影响（在 assets SKILL.md 里完整文档化）。\n\nv1.0.24 | 2026-04-25T14:18:55.131Z | user\n\n新增：导入 .aws 预设包时密钥字段（wechat_appid/secret、writing_model.api_key、image_model.api_key）按映射表增量写入仓库根 aws.env，覆盖前自动备份 aws.env.bak.{ts}，stderr 仅打印键名不打印值。SKILL.md 完整披露写入策略与字段映射表。main 的 first-time-setup.md 增加 .aws 快速通道引导。\n\nv1.0.23 | 2026-04-24T13:03:48.203Z | user\n\n引入 .aws-article/products/{产品名}/ 业务资料库：涉及自家产品的写稿/配图前先查 products/；AI 生成的业务介绍引导保存到 products/{产品名}/*.md。assets 的图片入库脚本重命名 stock_image_ingest.py → product_image_ingest.py（按产品分目录）。\n\nv1.0.22 | 2026-04-22T23:23:41.081Z | user\n\n软化版套件完整性提示：说明工作流会读跨 skill 共享文档、单独安装时会 file-not-found；纯信息性语气，无 shell 循环、无 Agent 强指令\n\nv1.0.21 | 2026-04-22T22:44:41.365Z | user\n\n修 scanner 新点名的 credential-in-chat antipattern：移除 first-time-setup.md 里'您可直接把缺失配置发给我'话术；改为引导用户自己在编辑器中编辑 aws.env；强化原则：Agent 不索取/接收对话里粘贴的密钥\n\nv1.0.20 | 2026-04-22T22:35:10.454Z | user\n\n修 scanner 精准点名：移除'不外传/不读仓库外'假陈述；补凭证/内容外发披露；sticker+review 补 WECHAT 凭证声明；空 env 的 skill 移除 primaryEnv；3 个脚本不再遍历父目录\n\nv1.0.19 | 2026-04-22T16:35:40.883Z | user\n\n能力披露：frontmatter 加 metadata.openclaw.requires；body 加 Capabilities 段；降温前置依赖块（去 shell 循环与强指令语气）；article_init.py 不再读 Path.home()\n\nv1.0.18 | 2026-04-22T15:52:38.758Z | user\n\n清理 tags 只留 latest；frontmatter 加 homepage+url；main/publish 加 automation 关键词\n\nv1.0.17 | 2026-04-22T08:44:42.597Z | user\n\n加前置依赖检查：任一 skill 启动前要求 9 个套件全装，否则停止工作流\n\nv1.0.16 | 2026-04-22T05:12:50.666Z | user\n\n压缩 description 做 SEO 密度优化\n\nv1.0.15 | 2026-04-22T04:48:25.909Z | user\n\nSEO 优化：补关键词/友好名/价值主张/GitHub 链接\n\nv1.0.14 | 2026-04-22T04:34:28.735Z | user\n\n对齐 git tag v1.0.14\n\nv1.0.1 | 2026-04-22T04:25:52.712Z | user\n\n首发/补套件说明：跨 skill 相对引用需同 skills/ 目录一起安装\n\nv1.0.0 | 2026-04-01T03:44:52.615Z | auto\n\naws-wechat-article-main 1.0.0 初始发布。管理微信公众号从选题到发布的完整内容流程。\n\n- 明确定义从选题、写稿、审稿、排版、配图到发布的严格顺序及流程，必须逐步推进，每步完成才能进入下一步。\n- 新增详细的配置检查机制，执行操作前强制校验关键配置文件与环境（config.yaml、aws.env），不合规时阻断流程。\n- 支持区别草稿发布、正式发布与跳过微信发布三种模式，依据 config.yaml 中 publish_method 配置字段自动切换行为。\n- 用户在流程任一关键环节都需明确确认，智能体不得自行跳步、假定流程、或代用户决定关键发布动作。\n- 增加详细的交互顺序与行为约束说明，对配置、账号约束、任务切换、新建/续写等场景有明确指令。\n- 文档内容全面指导首次配置、每日运营、\n\nArchive index:\n\nArchive v1.0.27: 24 files, 40139 bytes\n\nFiles: references/articlescreening-schema.md (6318b), references/config.example.yaml (11697b), references/env.example.yaml (511b), references/first-time-setup.md (11601b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7177b), skill-card.md (2512b), skill.json (693b), SKILL.md (31616b), _meta.json (143b)\n\nFile v1.0.27:SKILL.md\n\n---\nname: aws-wechat-article-main\ndescription: 公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继续上次的」「接着之前的进度」；**显式模型新写**「用 GPT 写一篇」「用 DeepSeek 写一篇」「把提纲写成文章」。子 skill（topics/writing/review/formatting/images/publish/sticker/assets）单独触发仅限对**已有产物**的修改场景（如\"改标题\"\"润色这段\"\"排版\"\"审稿\"\"加封面\"\"发布\"）；新做/策划/多环节串联一律走本入口。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WRITING_MODEL_API_KEY\n        - IMAGE_MODEL_API_KEY\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 公众号运营总览\n\n**一键式公众号 AI 内容流水线** —— 从选题到上架 8 个子 skill 串联，公众号小编 / 自媒体 / 品牌内容团队一键产出整篇图文。\n\n> **套件说明** · `aws-wechat-article-*` 是公众号一条龙套件，共 9 个 slug：`aws-wechat-article-main / topics / writing / review / formatting / images / publish / assets`，外加 `aws-wechat-sticker`。跨 skill 的相对引用依赖同一 `skills/` 根目录；推荐 `clawhub sync` 或逐个 `clawhub install` 一次性全装。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 作为一条龙套件**编排入口**；真正调用外部 API 的是子 skill（writing / images / publish / sticker / review）。**本入口自身的 `validate_env.py` 脚本**行为：\n\n- **凭证读取**：读取仓库根 `aws.env` 的 `WRITING_MODEL_API_KEY` / `IMAGE_MODEL_API_KEY` / `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`，**仅用于校验键是否存在且非空**，值不用于任何网络请求\n- **网络**：本入口脚本无外发请求；**子 skill 有外发**（详见各子 skill 的能力披露）\n- **文件读**：仓库内 `aws.env`、`.aws-article/config.yaml`、本篇 `article.yaml`\n- **文件写**：仓库内 —— `.aws-article/`（首次引导创建目录结构）、本篇 `article.yaml` 状态字段\n- **shell**：仅 `{python} {baseDir}/scripts/validate_env.py`（`{python}` = 本机 Python 3 解释器，由下文**第 0 步**探测得出：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n> **注意**：整体套件（含子 skill）会调用外部 LLM、图像 API 与微信 API，并在调用时外发 API key 与本篇内容。完整行为见各子 skill 的「能力披露」。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的入口，编排 8 个子 skill：`topics / writing / review / formatting / images / publish / assets` 以及 `aws-wechat-sticker`。\n\n- **装齐全部 9 个 slug** 到同一 `skills/` 根目录，才能走完整一条龙流程（选题→写稿→审稿→排版→配图→发布）。\n- 只装 main 一个时，仍可用于环境校验（`validate_env.py`）；进入内容流水线会因对应子 skill 缺失而无法执行相关步骤（工作流里的跨 skill 脚本调用 / 文档读取会遇到 `file not found`）。\n\n完整 9 slug 清单与安装指引见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。\n\n## 配置检查 ⛔ BLOCKING\n\n**进入交互顺序「2) 全局账号约束」「3) 本篇准备」及内容流水线前**须完成 **第 0～2.5 步**配置检测（任一步失败则 **不得** 继续）。**第 3 步**是**调用 `publish.py` 前**的核对（非流水线起点）：**`.aws-article/config.yaml`** 中 **`publish_method`** 默认为 **`draft`**（**`publish.py full`** 只把图文写入**公众号草稿箱**）；仅当用户明确要求「发出去 / 对外发布」时，再将该键改为 **`published`**（或使用 **`full --publish`** 临时强制发布）。**微信**：**`validate_env.py`** 默认要求公众号账号配齐（见第 2 步）；用户**明确不接微信**时，先将 **`publish_method`** 设为 **`none`** 再过校验（脚本会跳过微信组），之后 **`publish.py full`** 仍直接跳过。要走草稿/发布，须补全 **`aws.env`** 与 **`config.yaml`** 微信槽位，并建议 **`check-wechat-env`**。`wechat_N_name` 只用于展示，写作/图片模型是可选项，这三项缺失时只警告。文风与账号约束以 **`config.yaml`** 为准，发文元数据以本篇 **`article.yaml`** 为准。\n\n### 第 0 步：判断操作系统与 Python 解释器\n\n智能体在执行下列检测命令前，**先判断当前环境**：\n\n- **Linux / macOS**：使用 Bash 命令（`test`、`echo` 等）。\n- **Windows**：使用 **PowerShell** 命令（`Test-Path` 等）。\n\n**再确定 `{python}`**——本套件所有文档里的 `{python}` 都是占位符，不是可直接执行的命令，须先探测出本机实际可用的 Python 3 解释器再代入。**本次会话探测一次即可**，之后所有 `{python}` 统一代入该结果。\n\n**Linux / macOS：**\n\n```bash\npython3 --version\n```\n\n输出 `Python 3.x.x` → `{python}` = `python3`。命令不存在则改试 `python --version`，同样要求输出 `Python 3.`；都不行 → 提示用户安装 Python 3.10+ 后再继续，**不得**继续后续步骤。\n\n**Windows（PowerShell）：**\n\n```powershell\npy -3 --version\n```\n\n输出 `Python 3.x.x` → `{python}` = `py -3 -X utf8`。`py` 不可用时改试 `python --version`，通过则 `{python}` = `python -X utf8`。\n\n⛔ **Windows 上不要探测 `python3`**：未安装 Python 时它是系统预置的应用执行别名，会**静默打开 Microsoft Store** 而不报错——你会拿到一个空输出、看不出失败原因。始终优先 `py -3`（python.org 官方安装器默认附带 py launcher，且不受该别名影响）。\n\n⛔ **Windows 上的 `-X utf8` 不可省略**：本套件脚本输出大量中文，Windows 上 Python 的 stdout 编码默认跟随系统 locale（简体中文机器为 GBK），省略后你读到的会是乱码，进而误判脚本成败。\n\n**版本要求 Python 3.10+**。`--version` 显示低于 3.10 时先提示用户升级，再继续。\n\n### 第 1 步：`.aws-article/config.yaml` 与 `aws.env` 是否存在\n\n在**仓库根目录**（当前工作目录为项目根）执行：\n\n**Linux / macOS：**\n\n```bash\ntest -f .aws-article/config.yaml && test -f aws.env && echo \"ok\" || echo \"missing\"\n```\n\n**Windows（PowerShell）：**\n\n```powershell\nif ((Test-Path -LiteralPath \".aws-article\\config.yaml\") -and (Test-Path -LiteralPath \"aws.env\")) { \"ok\" } else { \"missing\" }\n```\n\n⛔ 输出为 `missing`（任一文件不存在）→ 按 [首次引导](references/first-time-setup.md) 创建或补全：可参考 **`{baseDir}/references/config.example.yaml`** 得到 **`config.yaml`**，在仓库根创建 **`aws.env`**（仅密钥与微信 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 等，键名可与 `{baseDir}/references/env.example.yaml` 对照）。\n\n**初始化约束**：新建 **`.aws-article/config.yaml`** 时，`publish_method` 默认必须为 **`draft`**；除非用户明确指定不接微信，否则禁止初始化或改写为 `none`。\n\n### 第 2 步：校验配置内容（`validate_env.py`）\n\n两文件均存在后，在仓库根运行：\n\n```bash\n{python} {baseDir}/scripts/validate_env.py\n```\n\n（默认读取 **`.aws-article/config.yaml`** 与 **`aws.env`**；可用 `--config` / `--env` 指定路径。）\n\n脚本检查（规则摘要，具体交互文案统一以 [首次引导](references/first-time-setup.md) 为准）：\n\n- **微信公众号**：`wechat_accounts`、`wechat_api_base` 与 **`aws.env`** 中每个槽位的 **`WECHAT_{i}_APPID` / `WECHAT_{i}_APPSECRET`** 须完整；否则 **`failed`** + **`微信公众号配置不完整`**，**退出码 1**。`wechat_{i}_name` 仅用于展示与按名选择，未填时只警告。**例外**：**`publish_method: none`** 时跳过微信组校验。\n- **写作模型**：`writing_model.base_url` / `model` 与 **`WRITING_MODEL_API_KEY`** 仅供外部写作 API 使用；未配置时输出警告，不影响退出码，Agent 可通过 `write.py prompt` 获取约束后代写。\n- **图片模型**：`image_model.base_url` / `model` 与 **`IMAGE_MODEL_API_KEY`** 仅供外部生图 API 使用；未配置时输出警告，不影响退出码。\n\n**退出码 0**：微信组通过，或已声明 **`publish_method: none`** 跳过微信组 → **`True`** + **`配置校验通过`**；三个可选项缺失会同时输出警告。**退出码 1**：微信必要配置未通过 → 不得进入一条龙默认流水线，并引导 [首次引导](references/first-time-setup.md) 补全或设为 **`publish_method: none`** 后重跑。\n\n### 第 2.5 步：创建预设与运行目录（硬性前置，必须执行）\n\n**仅当第 2 步退出码为 0** 才执行本步；执行成功后才允许进入「2) 全局账号约束」与后续流水线。  \n目录要求与命令以 [首次引导第 2 步](references/first-time-setup.md) 为准（需覆盖 `presets/*` 与 `tmp`）。**业务资料库 `.aws-article/products/{产品名}/`** 不在本步建——由 AI 写第一份业务介绍时按 [assets skill](../aws-wechat-article-assets/SKILL.md) 自动 mkdir。\n\n- **禁止**因为“环境检查通过”就跳过本步直接写稿。\n- 若目录已存在，可视为本步通过；若缺失，必须立即补建并继续校验。\n\n### 第 3 步：调用 `publish.py` 前（`publish_method` + 微信）\n\n- **`publish_method`**（**`draft`** / **`published`** / **`none`**）写在 **`config.yaml`**，**默认 `draft`**。**`none`** = 用户明确不填微信：**`full`** 不调 API。要「发布出去」→ **`published`** 或 **`full --publish`**。\n- **微信**：在 **`aws.env`**；槽位在 **`config.yaml`**。**`draft`/`published`** 走 **`full`** 前须就绪；**`none`** 下不调用微信。\n- 运行 **`publish.py full`** 前：确认 **`publish_method`** 合法（小写）；**非 `none`** 时建议 **`check-wechat-env`**。\n\n### 智能体行为约束（禁止自作主张）\n\n检测到 **`.aws-article/config.yaml` 或 `aws.env` 缺失**、**`validate_env.py` 退出码 1**（微信配置不完整，且未声明 **`publish_method: none`**），或用户**已要求调用 `publish.py`** 而微信槽位 / 凭证未就绪时：\n\n- **禁止**在未询问用户、未取得用户**明确文字确认**的情况下，自行决定：跳过微信配置、仅出 prompt 却继续宣称「一条龙已完成」、或继续排版/发布并假装配置已就绪。\n- **必须先**：向用户说明**具体缺哪一类**（脚本 **`failed`** 下的 **`微信公众号配置不完整`**；或即将 **`publish.py`** 但微信未配齐），并**统一按** [首次引导](references/first-time-setup.md) 中「校验失败时的配置引导」文案执行。\n- **输出约束**：该场景下除”环境检查结果”可按实际失败项替换外，其余引导文案须与首次引导保持一致。\n- 用户在本地编辑器中填好 `aws.env` 与 `config.yaml` 并保存后，智能体协助重跑 **`validate_env.py`** 复检；若用户明确声明本次例外，按首次引导与本节约束继续处理。\n- **凭证处理原则**：Agent **不得索取、不得接收**用户在对话里粘贴的 `APPSECRET` / `API_KEY` 等任何密钥；所有密钥由用户自己在编辑器里写入 `aws.env`（或通过 `https://aiworkskills.cn/` 平台配置）。Agent 只校验存在性、不读取值、不外发值。\n\n> **模型配置是可选项**：默认校验不因写作/图片模型缺失而阻断。进入对应阶段时，有外部 API 配置则可由脚本调用；没有时，写作由 Agent 根据 `write.py prompt` 执行，配图则根据当前 Agent 能力执行或再向用户说明。\n\n> **单步子 skill**：用户只触发某一子能力（如仅排版、仅审稿）且**未走本总览流水线**时，仍以各子 skill 内说明为准；**一条龙 / 完整流程 / 从选题到发布** 必须满足本节 BLOCKING 与上条「禁止自作主张」。\n\n## 主要配置文件（不要混用）\n\n| 文件 | 位置 | 作用 |\n|------|------|------|\n| `aws.env` | **仓库根** | **密钥**：写作/图片 `*_API_KEY`、微信 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 等（键名见 `references/env.example.yaml`；与 `config.yaml` 一起由 `validate_env.py` 校验） |\n| `.aws-article/config.yaml` | 仓库内 | **非密钥配置**：账号文风、模型 `provider`/`base_url`/`model`、微信槽位数与 `wechat_api_base`、各槽位展示名等（模板见 `references/config.example.yaml`） |\n| `references/env.example.yaml` | 仓库内示例 | **仅文档**：`aws.env` 键名说明 |\n| `references/config.example.yaml` | 仓库内示例 | **仅文档**：`config.yaml` 结构示例 |\n| `article.yaml` | **本篇目录** `drafts/YYYYMMDD-标题slug/` | **发文元数据**（标题/作者/摘要/封面等）及状态字段：**`image_source`**（仅 `generated` / `user`；默认 `generated`，用户上传配图时改为 `user`）与 **`publish_completed`**（新建 **`false`**，发布闭环结束 **`true`**），与 **`config.yaml`** 分工 |\n\n### 发布方式与时间线\n\n1. **账号与发布策略**：**文风、选题边界、`publish_method`（默认 **`draft`**）、微信槽位元数据**等均在 **`.aws-article/config.yaml`** 维护；**密钥**仅在 **`aws.env`**。\n2. **本篇准备**（须先完成交互顺序 **「2) 全局账号约束」**）：在 **定题与 slug** 之后新建 `drafts/YYYYMMDD-标题slug/`，并**优先**创建 **`article.yaml`**（含 **`publish_completed: false`**、标题/作者/摘要等；通常为本目录内**首个**应落盘的文件），再进入内容流水线。\n3. **执行原则（严格顺序）**：必须按下述流水线顺序依次执行，**不能跳过任何部分**；每到一步若缺少必要输入（目录、元数据、主题、用户选择、发布意图等），要**先及时询问用户并获得确认**，再进入下一步，除非用户指出基于某个历史任务继续创作，那么需要智能体根据中间产物判断从哪个阶段开始。\n4. **内容流水线**（子 skill 串行，详见下文 **「交互顺序」第 4 步** 与 **「流程」** 表）：**选题**（[topics](../aws-wechat-article-topics/SKILL.md)）→ **写稿**（[writing](../aws-wechat-article-writing/SKILL.md)）→ **审稿（内容审）**（[review](../aws-wechat-article-review/SKILL.md)）→ **排版**（[formatting](../aws-wechat-article-formatting/SKILL.md)）→ **配图**（[images](../aws-wechat-article-images/SKILL.md)）→ **审稿（终审）**（review）。**内容审**产出的 **`article.md` 定稿须满足 [review 第 5 步](../aws-wechat-article-review/SKILL.md)（文末 **`{embed:…}`**，⛔ BLOCKING）后再排版。全程以 **`.aws-article/config.yaml`** 为账号与文风约束；典型产物依次为 `topic-card.md` / `draft.md` → `article.md` → `article.html` 与 `imgs/` 等。\n5. **发布**（[publish](../aws-wechat-article-publish/SKILL.md)）：**`draft`** → **`full`** 仅**草稿箱**；**`published`** 或 **`full --publish`** → 再**提交发布**；**`none`** → **`full`** **立即跳过**、不调微信。前两档需微信凭证。\n\n**再强调**：**`aws.env`** = 密钥；**`config.yaml`** = 账号/文风/模型与微信元数据及 **`publish_method`**；**本篇 `article.yaml`** = 发文元数据。\n\n## 交互顺序（一步步，最小提问）\n\n按以下顺序与用户交互，**上一步完成再进下一步**；上一环节就绪后再进入下一环节。\n\n### 1) 配置自检（必做）\n\n- 按上文 **配置检查** 完成：**`config.yaml` 与 `aws.env` 均存在** → 运行 **`validate_env.py`** **且退出码 0**。**退出码 1** 时按 [首次引导](references/first-time-setup.md) 补全微信必要配置；用户明确不接微信时可设为 **`publish_method: none`** 后重跑。\n- **`validate_env.py` 退出码 0 后，必须立即执行「第 2.5 步目录创建」**（可复用 [首次引导第 2 步](references/first-time-setup.md) 命令）；该步完成前，**禁止**进入「2) 全局账号约束」与任何写稿流程。\n- **退出码 0 + 可选项警告**：流程**不阻断**，可直接进入下一步；不得要求用户先配置外部写作/图片模型。\n- **退出码 1（微信不完整）时**：只展示 [首次引导](references/first-time-setup.md) 中的 **配置选项**，**不要**在同一轮回复里再问「写哪篇 / 继续哪篇草稿 / 新选题」等；须等配置闭环（重跑校验通过或「本次例外」已书面确认）后，**再**进入下方 **「2) 全局账号约束」**。\n- **`validate_env.py` 不检查** `article_category`、`target_reader`、`default_author`；须在 **「2) 全局账号约束」** 中单独检查并落盘。\n\n### 2) 全局账号约束（`.aws-article/config.yaml`）⛔\n\n**在 `validate_env.py` 已通过**（或已按总览完成「本次例外」）**之后、进入「3) 本篇准备」之前**，**必须**打开 **`.aws-article/config.yaml`**，检查下列键 **trim 后是否非空**：\n\n- **`article_category`**、**`target_reader`**、**`default_author`**\n\n任一项缺失或空白：**逐项询问用户**（1.账号领域2.目标读者3.作者名字），取得**用户当轮明确答复**后再**写回** **`.aws-article/config.yaml`**，再进入 **「3) 本篇准备」**。**禁止**仅在对话里口头确认却不写入文件。**禁止**跳过本步直接假定可写稿。\n\n**⛔ 禁止擅自填写（必须写进行为约束）**\n\n- **不得**从本篇或其它目录的 **`article.yaml`**、历史草稿、**`topic-card.md`**、对话记忆或仓库内任意文件**静默抄录、推断或「顺手补全」**后写入 **`article_category` / `target_reader` / `default_author`**。对 **`tone`** 等与账号画像强相关的全局项，要直接询问用户，**同样禁止**未询问就写盘。\n- **允许的做法**：向用户说明「当前为空」，**请用户填写或确认**；若你想根据某篇 `article.yaml` 给**建议**，只能**展示为待选文案**，并问「是否采用 / 要改哪几个字」，**用户明确同意后再写入** `config.yaml`。\n- **顺序**：在尚未完成 **「3) 本篇准备」** 中「续旧 / 新开」的确认前，**禁止**用某一 `drafts/…/article.yaml` **反推**全局三键，避免误把单篇元数据当成整号定位。\n\n### 3) 本篇准备（二选一，默认「新建一篇」）\n\n**在完成「2) 全局账号约束」之后**，**在不了解用户是要续写既有草稿还是新开一篇时**（例如未指定 `drafts/…` 路径、且仓库 **`drafts/`** 下存在进行中目录或多个候选）：**须先询问**并让用户选定 **「继续哪一篇」** 或 **「新开一篇」**，**再**进入下列 A/B 或调用写作脚本。**禁止**默认「最近修改」目录、未确认就运行写作脚本、或假定沿用上一轮路径。\n\n**业务素材双向规则（涉及用户自身业务时强制，详见 [assets skill](../aws-wechat-article-assets/SKILL.md)）**：\n\n- **读**：若本篇涉及用户自家业务（产品/软件/服务），**先 `ls .aws-article/products/`** 看有无相关产品目录，进入后必读根下 `*.md`（业务介绍）作为底稿来源；`images/` 子目录里有现成业务配图则优先复用。\n- **写**：本流程中产生的内容若**语义属于业务介绍**（不是文章主体而是侧重产品/服务自介），由 AI 主动引导用户保存到 `.aws-article/products/{产品名}/{文件名}.md`（用 Write 工具直接落库；目录不存在时同时创建 `images/`），下次涉及业务的文章自动用上。\n\n#### A. 新建一篇（**严格子顺序**，勿跳步）\n\n1. **写作意图** ⛔ **BLOCKING**：必须问清用户 **本篇要写什么**（具体主题、角度、体裁或目标）。若用户只想「帮我出选题」，须**明确确认**后再当无方向模式处理。  \n   - **禁止**在用户未回答本步（且当前对话也未等价说明）之前：**调用 web_search**、**执行 topics 的调研**、**批量生成选题或标题**。  \n   - 用户已在当次对话中说清楚「写什么」的，可本步口头确认一句即可，不必重复盘问。\n2. **定题与 slug**：在写作意图已明确的前提下，确定**发文章标题**——用户从候选中选一个，或**自定义标题**；据此生成 **slug**，目录名为 `YYYYMMDD-标题slug`（slug 规则：小写、连字符、与项目习惯一致即可）。\n3. **建目录与 `article.yaml`**：创建 `{drafts_root}/YYYYMMDD-标题slug/`（`drafts_root` 以 **`config.yaml`** 为准，默认 `drafts/`）。随即初始化本篇 **`article.yaml`**（含 **`publish_completed: false`**，及标题、作者、摘要等；目录内**宜最先写入**；可用 `{baseDir}/../aws-wechat-article-publish/scripts/article_init.py`）。\n   - **`publish_method`**：默认 **`draft`**；要发出去 → **`published`** 或 **`full --publish`**；用户明确不填微信 → **`none`**。\n4. **本篇预设单选落盘（必做）**：初始化后按场景执行：**新建首轮**以 **`.aws-article/config.yaml`** 为来源，按 **`custom_* > default_*`** 结合本篇主题/选题卡，为以下字段各选**单一预设**并写回本篇 **`article.yaml`** 为**单元素列表**：`default_structure`、`default_closing_block`、`default_title_style`、`default_format_preset`、`default_format_scheme`、`default_cover_image_style`、`default_article_image_style`、`default_sticker_style`。选排版模版与配色时**不要只看名字**：先跑 **`format.py --list-themes`**，按其中「适合 / 不适合」对本篇题材，再按配色说明选一档（未选则用模版默认色）。**续写/重入**时若本篇 `article.yaml` 对应字段已为单元素列表，视为本篇已选并优先保留，不重选不覆盖。若 `config.yaml` 不存在或候选为空，可保持 `[]`。\n5. 至此才进入 **第 4 步内容流水线**。\n\n#### B. 我已有目录\n\n- 用户给出路径。必读 **`.aws-article/config.yaml`**（账号与发布策略）；本篇目录内需有 **`article.yaml`**（或按用户状态后补）。若已有 `article.html`/`cover.jpg` 可直接从流水线中靠后的步骤接入。\n- 若用户意图是「发布后换图并重发草稿箱」，也走本分支：指定既有目录后，从 **配图（用户供图分支）** 接入，再执行 **终审 → 发布**。\n\n### 4) 内容流水线（子 skill）\n\n须已具备 **本篇目录** 与 **`article.yaml`**（「已有目录」分支按上条处理）；账号侧约束以 **`config.yaml`** 为准。\n\n**确认轮次优化**：全局三键已非空时静默通过；`publish_method` 已为合法值时不重复盘问；多个待确认项可合并为一轮提问。用户意图明确时（如给出主题 + \"写一篇文章\"），理想轮次为 **1 轮**（确认标题/摘要）+ **写完后展示结果**。配图方案在用户无特殊要求时按默认风格自动执行，不单独确认。\n\n```\n选题 → 写稿 → 审稿(内容审) → 排版 → 配图 → 审稿(终审)\n```\n\n- **topics**：仅在 **写作意图已明确**（见上 3-A-1）之后执行；仍须遵守 **aws-wechat-article-topics** 中「展示后等用户选」等规则。\n- **writing**：结合 **`.aws-article/config.yaml`** 与 `topic-card.md`（或用户素材）；**`publish_method`** 见 **`config.yaml`**（上文「发布方式与时间线」）；产物 `draft.md` → 内容审后 `article.md`。\n- **review（内容审）**：定稿 **`article.md` 前**须按 [review 第 5 步 ⛔ BLOCKING](../aws-wechat-article-review/SKILL.md) 完成文末 **`{embed:…}`**（或规则允许的省略并留痕）；**未完成不得进入 formatting**。\n- **formatting**：`article.md` → `article.html`（用户当次指定排版主题可覆盖默认）。\n- **images**：按 **aws-wechat-article-images**（配置与行为约束以本节「配置检查」为准）。\n- **review（终审）**：检查 `article.html` 与 `imgs/`；有问题给出清单，等用户确认或修复。\n\n### 5) 发布\n\n- 以 **`config.yaml`** 的 **`publish_method`** 为准；**`draft`** / **`published`** / **`none`** 含义见上文。**`none`** 时运行 **`full`** 会无操作退出。\n- **`draft`/`published`**：**微信**须配齐后再调 **`publish.py`**；建议 **`check-wechat-env`**。**`none`**：不调微信，说明即可。\n- 完成后输出小结与回执，目录按需移至 `published_root`。\n\n### 6) 发布后换图重发（补充分支）\n\n当用户说「草稿箱里图不满意，换我上传的图重新发」：\n\n1. 锁定目标 `drafts/…` 目录；\n2. 将新图放入本篇 `imgs/`，生成/更新 `img_analysis.md`（封面仅 1 张）；\n   - 同步更新本篇 `article.yaml`：`image_source: user`；\n   - 开始重做流程前，将 `publish_completed` 置回 `false`；\n3. 依据分析结果更新 `article.md` 图片映射（允许重排）；\n4. 重新执行 `format.py` 生成 `article.html`；\n5. 终审通过后执行 `publish.py full`（`draft` 写草稿箱）；\n6. 发布命令成功且回执可用后，写回 `publish_completed: true`。\n\n## 流程\n\n```\n选题 → 写稿 → 审稿(内容审) → 排版 → 配图 → 审稿(终审) → 发布\n```\n\n## 中间产物门禁（缺啥补啥）⛔\n\n进入下一步前，必须先检查本步所需中间产物；缺什么就先补什么，禁止跳步并宣称已完成。\n\n| 阶段 | 必要产物（最小集合） | 缺失时动作 |\n|------|----------------------|------------|\n| 写稿完成 | `article.md` 存在且非空 | 继续写稿或回滚到 writing |\n| 排版完成 | `article.html` 存在，且由当前 `article.md` 重新生成 | 先执行 formatting 重转 |\n| 配图完成 | 文章目录存在 `cover.(png/jpg/jpeg/webp)`；`article.md` 与 `article.html` 不含 `placeholder` | 先执行 images 生成并替换（`image_source=user` 时走用户供图映射与重排） |\n| 发布就绪 | `article.yaml` 含 `title/author/digest/content_source`；发布环境检查通过 | 先补齐元数据或环境 |\n| 发布闭环 | 发布命令成功且回执可用 | 才允许写回 `publish_completed: true` |\n\n**禁止**：仅凭单一信号（如“草稿创建成功”）就宣称全流程完成。若正文仍有 `placeholder`，状态必须标记为“草稿已提交，正文配图未完成”。\n\n| 步骤 | 子 skill | 读取 | 产出 |\n|------|---------|------|------|\n| 选题 | topics | **`.aws-article/config.yaml`**、`aws.env`、web_search | `topic-card.md` `research.md` |\n| 写稿 | writing | `topic-card.md`、**`.aws-article/config.yaml`**、`aws.env`（专用写作 API） | `draft.md` |\n| 审稿 | review | `draft.md`、`aws.env`、**`.aws-article/config.yaml`** | `review.md` → `article.md`（定稿须含文末 embed，见 [review 第 5 步](../aws-wechat-article-review/SKILL.md)） |\n| 排版 | formatting | `article.md`、**`.aws-article/config.yaml`** | `article.html` |\n| 配图 | images | `article.md`、`aws.env`、**`.aws-article/config.yaml`** | `imgs/` |\n| 终审 | review | `article.html`、`imgs/`、**`.aws-article/config.yaml`** | `review.md` |\n| 发布 | publish | `article.html`+`imgs/`、**`config.yaml`**、`aws.env`（调用 publish.py 时） | 草稿 media_id / 发布 publish_id、URL、`out/` 记录 |\n\n**账号与文风约束**：以 **`.aws-article/config.yaml`** 为准。\n\n**topics / `web_search`**：须满足上文 **3-A-1**（用户已说明本篇写什么，或已确认「只帮忙出选题」）之后才可调研与生成选题；不得默认跳过提问直接搜索。\n\n> 提示：发布前需就绪本篇 `article.yaml`（标题/作者/摘要/封面等元数据；`content_source` 默认 `article.html`）。可用 `{baseDir}/../aws-wechat-article-publish/scripts/article_init.py` 快速初始化或更新。\n\n## 路由\n\n**默认**：与长文发文相关时 **优先 main**，由本 skill 按步编排；不要因用户说了「写」「选题」「发」就跳过 main 直连子 skill。\n\n**何时直连子 skill**（可跳过 main 入口）：用户**明确只要该步产物**、且不隐含「从零到发出」整条链。例如：已有 `article.md` 只要排版；已有稿只要审稿清单；已有 `article.html`+`imgs/` 只要发布前检查或提交；已有选题卡只要扩写等。\n\n| 用户说法 | 路由到 |\n|---------|--------|\n| 从0开始、从零、从头、一条龙、完整流程、帮我发一篇、发到公众号（含各前置步）、今天发什么/写什么好（要成文并发）、不确定从哪步开始 | **main** |\n| **只要**选题卡、标题、摘要、排期、系列策划（明确不做后续编排） | topics |\n| **只要**在已有选题/大纲/草稿上写稿、改写、润色、续写（明确不要全流程） | writing |\n| **只要**审稿/校对/合规清单（成稿或已定版 HTML） | review |\n| 「能不能发」且含代为发布、或要从稿到发出整条收尾 | **main** |\n| **只要**排版、换主题、转 HTML | formatting |\n| **只要**长文封面/正文配图（有正文或插图位） | images |\n| 贴图、图片消息、多图推送、九宫格（非长文图文链路） | **sticker** |\n| **只要**执行发布/提交/群发（已有约定产物） | publish |\n\n## 运行模式\n\n### 一条龙\n\n用户说「一条龙」「完整流程」时启用。按 **交互顺序** 的 1→2→3→4→5 执行；**3-A** 内子步骤亦须逐步完成。流水线中每步完成后**暂停**等用户确认。审稿有 🔴 项时进入修改循环。\n\n### 单步\n\n用户**明确只要某一步**且已有对应输入产物（或声明不做全流程）时，可仅执行该步骤；若表述含糊、可能还要后续发文，仍从 **main** 问起或按一条龙拆步确认。\n\n### 贴图\n\n路由到独立的 **aws-wechat-sticker** skill。\n\n## 配置与自定义\n\n- **`aws.env`**（仓库根，密钥）与 **`.aws-article/config.yaml`**（非密钥与模型/微信元数据及 **`publish_method`**）：校验 **`{baseDir}/scripts/validate_env.py`**；`aws.env` 键名见 **`references/env.example.yaml`**\n- **`config.yaml` / `article.yaml` / `aws.env` 字段说明**：[references/articlescreening-schema.md](references/articlescreening-schema.md)\n- 发布前微信：**`{baseDir}/../aws-wechat-article-publish/scripts/publish.py check-wechat-env`**（仓库根执行，试换微信 **access_token**；凭证在 **`aws.env`**）\n\nFile v1.0.27:references/presets/closing-blocks/README.md\n\n# 文末区块预设\n\n本目录下的 `.md` 文件为**文末固定引导区块**。写作时按 config 的 `custom_closing_block` > `default_closing_block` 或 config 中的 `closing_block` 字符串加载。\n\n## Schema\n\n- 每个文件为一段 Markdown，用于文章末尾：关注引导、公众号名片、往期推荐、行动号召等。\n- 可使用嵌入标记：`{embed:profile:名称}`、`{embed:miniprogram:名称}`、`{embed:miniprogram_card:名称}`、`{embed:link:名称}`。名片与小程序以 **`.aws-article/config.yaml`** 的 `embeds` 为准；**仅往期链接**可在本篇 `article.yaml` 写 `embeds.related_articles` 与全局合并（详见 [formatting SKILL](../../../../aws-wechat-article-formatting/SKILL.md)）。\n- 文件名即预设名（不含后缀），如 `brand.md` → 预设名 `brand`。在 config 中设置 `default_closing_block` 或 `custom_closing_block`（`custom_*` 优先）即可使用。\n\n## 示例\n\n见 `simple.example.md`。复制后重命名并按需修改。\n\nFile v1.0.27:references/presets/cover-styles/README.md\n\n# 封面配图风格预设（仓库侧说明）\n\n内置封面预设随 **`aws-wechat-article-images`** 提供，路径为 **`references/cover-styles/`**。本目录说明如何在仓库里**扩展或覆盖**封面风格。\n\n## 放置位置\n\n- **日常自定义**：`.aws-article/presets/cover-styles/<名>.md`\n- **`.aws` 预设包**：包内包含 **`cover-styles/`** 目录，由 `import_presets_aws.py` 合并到上述路径。\n\n## 配置键\n\n- **`default_cover_image_style`**：账号级默认候选（YAML 字符串列表）\n- **`custom_cover_image_style`**：非空时覆盖同名 **`default_*`**\n- **本篇 `article.yaml`**：同名键再覆盖全局\n\n合并后须收窄为**单元素列表**再跑配图流程。完整规则见 [articlescreening-schema.md](../../articlescreening-schema.md) 与 **`config.example.yaml`**。\n\n## Schema 与示例\n\n字段结构与内置一致，见 [cover-styles/README.md](../../../../aws-wechat-article-images/references/cover-styles/README.md)。可将本目录下的 `*.example.md` 复制到 `.aws-article/presets/cover-styles/` 后去掉 `.example` 再按需修改。\n\nFile v1.0.27:references/presets/image-styles/README.md\n\n# 正文配图风格预设\n\n本目录下的 `.md` 文件为**正文配图风格预设**。生成正文配图时按 **`custom_article_image_style`**（本篇 **`article.yaml`** > **`config.yaml`**；**须为 YAML 字符串列表**；多候选须在本篇改为**单元素列表**）加载对应 `.md`；未配置时按用户指定或自动推荐。\n\n> **封面风格预设**在 `skills/aws-wechat-article-images/references/cover-styles/`，与正文配图预设分开管理。\n\n## Schema\n\n- 每个文件描述一种视觉风格：风格名、描述、适用场景、**prompt 要点或关键词**（供 Agent/脚本生成图片时使用）。\n- 正文配图风格库见 [styles.md](../../../../aws-wechat-article-images/references/image-styles/styles.md)。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `flat-vector.example.md`。复制后重命名并按需修改。\n\nFile v1.0.27:references/presets/sticker-styles/README.md\n\n# 贴图风格预设\n\n本目录下的 `.md` 文件为**贴图/多图推送风格预设**。创作贴图时按 config 的 `custom_sticker_style` > `default_sticker_style`（`custom_*` 优先）或用户指定加载。\n\n## Schema\n\n- 每个文件描述多图推送的视觉风格与排版偏好：风格名、画面调性、张数建议、配文风格等。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `default.example.md`。复制后重命名并按需修改。\n\nFile v1.0.27:references/presets/structures/README.md\n\n# 文章结构预设\n\n本目录下的 `.md` 文件为**文章结构预设**。写作时按 **`config.yaml`**（及本篇 **`article.yaml`** 覆盖）的 `custom_structure` > `default_structure` 或用户指定加载。\n\n## Schema\n\n- 每个文件为一篇 Markdown，描述**标准结构**：标题、摘要、开头类型、正文小标题与段落节奏、结尾类型、配图密度建议。\n- 可引用 [writing 内置结构模板](../../../aws-wechat-article-writing/references/structure-template.md)，在其基础上做增减或改写。\n- 文件名即预设名（不含后缀），如 `listing.md` → 预设名 `listing`。在 **`config.yaml`** 中写 `default_structure` 或 `custom_structure`（`custom_*` 优先）；多候选时写多项，须在本篇 **`article.yaml`** 同键改为单元素列表后再运行 **`write.py`**（勿用字符串标量）。\n\n## 示例\n\n见 `listing.example.md`。复制为 `listing.md`（或自定义文件名）后按需修改。\n\nFile v1.0.27:references/presets/title-styles/README.md\n\n# 标题风格预设\n\n本目录下的 `.md` 文件为**标题风格预设**。选题生成标题时按 **`custom_title_style`** > **`default_title_style`**（**须为 YAML 字符串列表**；`custom_*` 非空时优先；多候选时由智能体择一，写回本篇 **`article.yaml`** 为**单元素列表**）或用户指定加载。\n\n## Schema\n\n- 每个文件描述一种标题风格：风格名、特点、适用场景、**示例句式或模板**（可含占位符如 XX、N）。\n- 选题 skill 会混合多种风格生成标题候选；若指定本目录下的预设名，则优先按该风格的示例生成。\n- 文件名即预设名（不含后缀）。内置风格见 [title-presets](../../../aws-wechat-article-topics/references/title-presets.md)：悬念型、干货型、数字型、反问型、故事型。\n\n## 示例\n\n见 `suspense.example.md`。复制后重命名并按需修改。\n\nFile v1.0.27:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-main\",\n  \"version\": \"1.0.27\",\n  \"publishedAt\": 1788797230539\n}\n\nFile v1.0.27:references/articlescreening-schema.md\n\n# 配置字段说明（`config.yaml` + `article.yaml`）\n\n**账号与流程级** → **`.aws-article/config.yaml`**；**本篇发文与发布状态** → **`article.yaml`**；**密钥** → 仓库根 **`aws.env`**。\n\n路径与模板：\n\n| 用途 | 路径 | 模板 / 示例 |\n|------|------|-------------|\n| 账号、文风、模型 endpoint、微信元数据、发布方式等 | **`.aws-article/config.yaml`** | **`config.example.yaml`**（同目录） |\n| 本篇标题、摘要、封面、**发布是否完成**等 | **`{drafts_root}/YYYYMMDD-标题slug/article.yaml`** | **`article_init.py` 初稿；字段见下文「本篇 article.yaml 字段」** |\n| API Key、微信 AppID/AppSecret | **`aws.env`**（仓库根） | **`env.example.yaml`**（同目录） |\n\n全局校验与首次引导：[first-time-setup.md](first-time-setup.md)；总览流程：[SKILL.md](../SKILL.md)。\n\n**优先级**：用户当次说法 > 本篇 **`article.yaml`**（仅本篇字段）> **`.aws-article/config.yaml`**（`custom_*` 覆盖 `default_*`）> 各 skill 内置默认。\n\n---\n\n## `.aws-article/config.yaml` 字段（按模板分组）\n\n**完整字段与分组**以仓库内 **`config.example.yaml`**（同目录）为准（含逐行注释）。本文不重复粘贴整段 YAML，避免与模板更新分叉。可按项目在该示例基础上增删键；未出现的键由各子 skill 使用内置默认。\n\n**说明**：**`publish_completed`** 请放在本篇 **`article.yaml`**（见下节），勿写在全局 **`config.yaml`**；若旧稿或历史模板仍把「是否发完」放在 config 里，以 **`article.yaml`** 为准并逐步从 config 中清理。\n\n**配图风格**：**封面**预设目录为 **`cover-styles/`**（内置随 `aws-wechat-article-images` + **`.aws-article/presets/cover-styles/`**）；**正文配图**为 **`presets/image-styles/`** 下同名 `.md`。配置键：**`default_cover_image_style`** / **`default_article_image_style`**（账号默认候选）与 **`custom_cover_image_style`** / **`custom_article_image_style`**（覆盖层）；**`custom_*` 非空时优先于同名 `default_*`**。\n\n**预设候选列表**：**`default_structure`**、**`default_closing_block`**、**`default_title_style`**、**`default_format_preset`**、**`default_cover_image_style`**、**`default_article_image_style`**（及 **`default_sticker_style`**）**须为 YAML 字符串列表**：`[]`、单元素 `[名]`，或多项候选；**多项时**智能体须在本篇 **`article.yaml`** 同键改为**单元素列表**后，再运行 **`write.py`**（结构/文末）与 **`format.py`**（排版主题）。**勿使用字符串标量。** 配图风格字段（`custom_cover_image_style`、`custom_article_image_style` 及对应的 `default_*`）同理。\n\n**`custom_*` 覆盖层**：`default_structure`、`default_closing_block` 等字段均有对应的 `custom_*`（如 `custom_structure`、`custom_format_preset` 等），格式相同。当 `custom_*` 非空时，优先于同名 `default_*`。合并优先级：**`article.yaml` > `custom_*` > `default_*`**；配图风格在解析完上述合并后的列表后，再按 skill 规则从内置与用户 **`cover-styles` / `image-styles`** 目录加载预设文件。\n\n---\n\n## 本篇 `article.yaml` 字段\n\n路径：`{drafts_root}/YYYYMMDD-标题slug/article.yaml`。初始化可用 **`skills/aws-wechat-article-publish/scripts/article_init.py`**。\n\n| 键 | 说明 |\n|----|------|\n| `title` | 文章标题 |\n| `author` | 作者；可空时部分流程会回退 **`config.yaml`** 的 **`default_author`** |\n| `digest` | 摘要（微信 digest 上限 128 字） |\n| `cover_image` | 封面路径或 URL（强烈建议） |\n| `pic_crop_235_1` | 可选。2.35:1 封面裁剪框，`X1_Y1_X2_Y2` 归一化 0~1；留空由 `publish.py` 按封面尺寸自动居中计算 |\n| `pic_crop_1_1` | 可选。1:1 封面裁剪框，格式同上；两者裁出的宽高比须与目标比例一致，否则接口报 53402 |\n| `content_source` | 正文 HTML 来源，默认 **`article.html`** |\n| `need_open_comment` | 是否开启留言（与微信能力一致） |\n| `only_fans_can_comment` | 是否仅粉丝可留言 |\n| **`publish_completed`** | **`false`** / **`true`**。新建本篇为 **`false`**；**发布闭环结束后**由智能体改为 **`true`**。**`publish.py` 不读写此键**；用于对话分流与运营备忘。 |\n| **`default_structure`** / **`custom_structure`** 等全局同名预设键 | 可选。与 **`config.yaml`** 合并时**本篇覆盖**（`custom_*` 优先于 `default_*`）；若全局某键为**多元素候选列表**，须在本篇写入**单元素列表** `[名]`，再运行 **`write.py`** / **`format.py`**。 |\n\n---\n\n## `aws.env`（仓库根）\n\n与 **`validate_env.py`**、**`publish.py`** 共用。键名见 **`env.example.yaml`**（同目录）。\n\n| 用途 | 典型键 |\n|------|--------|\n| 写作模型 | `WRITING_MODEL_API_KEY` |\n| 图片模型 | `IMAGE_MODEL_API_KEY` |\n| 微信 | `NUMBER_ACCOUNTS`（与 `publish.py` 一致）、`WECHAT_{i}_NAME`、`WECHAT_{i}_APPID`、`WECHAT_{i}_APPSECRET`、可选 `WECHAT_{i}_API_BASE` |\n\n**`validate_env.py`**（环境检测）：微信槽位、AppID/AppSecret 缺失时 **`failed`**、退出码 1；**`publish_method: none`** 时跳过微信组。写作/图片模型与 `wechat_N_name` 缺失时仅警告。详见脚本 docstring。\n\n---\n\n## 发布相关（`publish_method`、`publish_completed`、槽位）\n\n| 键 | 所在文件 | 说明 |\n|----|-----------|------|\n| **`publish_method`** | **`config.yaml`** | **`draft`**（默认）：**`full`** 仅写入**公众号草稿箱**。**`published`**：草稿后再**提交发布**。**`none`**：用户明确不填微信时写入；**`full`** 不调接口、直接跳过。 **`full --publish`** 在 `draft` 下可单次强制发布；**`none`** 下仍会跳过。 |\n| **`publish_completed`** | **`article.yaml`** | 新建 **`false`**；发布真正结束后由智能体写 **`true`**。 |\n| **`wechat_publish_slot`** | **`config.yaml`**（可选） | 多账号时指定本篇默认槽位 **1..N**；与 **`publish.py --account`** 二选一，**命令行优先**。 |\n| 微信凭证 | **`aws.env`** | **`WECHAT_{i}_APPID`** / **`WECHAT_{i}_APPSECRET`** 等；**`validate_env.py`** 默认要求配齐，除非 **`publish_method: none`**。 |\n\nFile v1.0.27:references/config.example.yaml\n\n# Account & workflow config (template)\n# Copy to .aws-article/config.yaml; secrets go in aws.env at repo root (see env.example.yaml in this directory)\n# Per-article metadata & publish_completed go in each article.yaml; field docs: skills/aws-wechat-article-main/references/articlescreening-schema.md\n\n# ── Account & positioning ──\narticle_category:        # Account niche / positioning (e.g. tech / education / lifestyle); affects overall style & topic selection\ntarget_reader: \"\"            # Target reader persona (e.g. college students / beginners / dev managers); determines vocabulary depth & examples\ntone:                    # Tone (casual / professional / formal / sharp / humorous); affects voice & sentence style\nupdate_frequency:        # Publishing frequency (e.g. daily / weekly / biweekly); used for scheduling hints\ndefault_author: \"\"           # Default author name; falls back to this when a single article has no author set\n\n# ── Topics & titles ──\ntopic_direction: \"不写XX\"          # Topic direction or exclusions (e.g. \"avoid XX\" / \"more case studies\"); guides topic generation boundaries\ntitle_style: 干货型          # Title style preset (e.g. practical / story / listicle); preference for title generation\ntitle_max_length: 25         # Max title length (in Chinese characters)\nsummary_length: \"80-128\"     # Target summary word count range (for model prompts & self-check; WeChat digest max 128 chars)\nforbidden_title_phrases: []  # Banned title words / phrases (list); prevents clickbait or sensitive terms\n\n# ── Writing ──\nwriting_style: 口语化        # Writing style (conversational / formal / methodology / case-study / narrative); affects structure & expression\nparagraph_preference: 短段为主 # Paragraph preference (short / long / mixed); affects layout & line breaks\nheading_density: 每节必有小标题 # Subheading density (required per section / moderate / minimal); used for structure validation\ntarget_word_count: \"\"        # Target word count (e.g. \"1800-2500\" or \"2000\"); used for writing & validation\nclosing_block: \"\"            # Global closing block (Markdown string); leave empty if using a preset\nforbidden_words: []          # Banned words list for body text; used in review & self-check\noriginal_attribution: \"\"     # Attribution style (e.g. \"original / authorized reprint / references\")\n\n# ── Preset defaults ──\n# Presets live in .aws-article/presets/{type}/; see each directory's README.md\n# Format: must be YAML string lists. [] = no default; single item = use directly; multiple items = candidate pool —\n#   the agent must narrow to a single-item list in this article's article.yaml before running write.py / format.py\n#   (write validates structure/closing; format validates format_preset). Do not use scalar strings.\n# Priority: article.yaml > custom_* > default_*\ndefault_structure:                # e.g. single or multiple candidates\n  - AI Skill 爆款教程结构\n  - AI Skills 实操爆文结构\ndefault_closing_block: []         # e.g. - brand\ndefault_title_style:\n  - 技术实操指南型\ndefault_format_preset:                # Template names → presets/themes|formatting/ (亲和 / 资讯 / 书卷 / 杂志 …)\n  - 资讯\ndefault_format_scheme: []             # Color scheme of the chosen template; see `format.py --list-themes`\ndefault_cover_image_style: []   # Cover preset names → cover-styles/ (built-in + .aws-article/presets/cover-styles/)\ndefault_article_image_style: [] # Body image preset names → presets/image-styles/\ndefault_sticker_style: []         # e.g. - storyboard; sticker workflow — agent picks one from the list\n\n# ── Custom presets (override defaults) ──\n# Same format as default_*: YAML string lists. When set, takes priority over default_*.\n# article.yaml still takes highest priority over both.\ncustom_structure: []\ncustom_closing_block: []\ncustom_title_style: []\ncustom_format_preset: []\ncustom_format_scheme: []          # Overrides default_format_scheme\ncustom_cover_image_style: []      # Overrides default_cover_image_style; same paths as default_cover_image_style\ncustom_article_image_style: []    # Overrides default_article_image_style; loads from presets/image-styles/\ncustom_sticker_style: []\n\n# ── Images ──\n# Cover presets: cover-styles/ (separate from body presets/image-styles/). Lists: default_* then custom_* then article.yaml.\nimage_source: generated       # generated | user; user = use uploaded images directly (skip image_create.py)\ncover_aspect: \"2.35:1\"       # Cover image aspect ratio (e.g. 2.35:1 / 1.91:1 / 16:9); used for generation & crop reference\ncover_style: 简约             # Broad preference alongside cover presets; minimal / illustration / photo / brand-color\nimage_density: 每节一图       # In-article image density (one per section / moderate / few / optional)\ncaption_style: 有图注         # Caption style (with captions / no captions / key images only)\nmulti_image_count: 6          # Default image count for multi-image scenarios (for generation or layout reference)\n# Business assets (product intros, screenshots, brand images) go in .aws-article/products/{product-name}/\n\n# ── Review ──\nreview_required:              # Required review checks (checked items appear in self-check / review report)\n  - 敏感词                    # Example: check for sensitive words\n  - 错别字                    # Example: typos / common misspellings\n  - 链接                      # Example: external link format / availability\n  - 原创标注                  # Example: whether original / reprint attribution is present\ncustom_sensitive_words: []    # Custom sensitive words list (overrides the general list)\nreview_output_format: 分块详细 # Review output format (brief / detailed-by-section); affects report presentation\n\n\n# ── Embeds ──\n# Articles can reference {embed:profile:name}, {embed:miniprogram:name}, {embed:miniprogram_card:name}, {embed:link:name}\n# Per-article article.yaml should only set embeds.related_articles (e.g. manual); deep-merged with global related_articles.\n# Do not duplicate profile / miniprogram config in article.yaml.\nembeds:\n  profiles:                   # WeChat official account cards (for {embed:profile:name})\n    - nickname: \"\"            # Matches the placeholder; also used as data-nickname\n      alias: \"\"               # Only for gh_ legacy format; new format uses id/headimg instead\n      id: \"\"                  # data-id (when both id & headimg are set, outputs mp-common-profile)\n      profile_id: \"\"          # Same as id; use either one\n      headimg: \"\"             # data-headimg (official account avatar URL)\n      signature: \"\"           # data-signature\n      service_type: \"2\"       # data-service_type\n  miniprograms:               # {embed:miniprogram:…} text links\n    - title: \"\"               # Matches the placeholder; also used as link text when applink is set\n      appid: \"\"               # Mini Program AppID\n      path: \"pages/index/index\" # Launch path\n      applink: \"\"             # When set, generates a weapp text link\n      image: \"\"               # Thumbnail for legacy mp-miniprogram card (when no applink)\n  miniprogram_cards:          # {embed:miniprogram_card:…} mp-common-miniprogram cards (separate from the above)\n    - title: \"\"               # Matches the placeholder\n      appid: \"\"\n      path: \"pages/index/index\"\n      applink: \"\"\n      card_title: \"\"          # Card title (defaults to title)\n      avatar: \"\"              # Mini Program avatar URL\n      imageurl: \"\"            # Card cover image URL\n      imageurlback: \"\"        # Optional: back-side image URL\n  related_articles:           # Past / related article links (for {embed:link:name}; actual list usually merged from article.yaml's manual)\n    manual:\n       - name: \"第一篇的占位名\"\n         url: \"https://...\"\n       - name: \"第二篇的占位名\"\n         url: \"https://...\"              # Manually pinned article list [{name, url}]; used by {embed:link:name}\n\n# ── Paths ──\ndrafts_root: drafts/          # Local drafts root directory (one subdirectory per article)\npublished_root: posts/published/ # Local published archive directory (for backup / sync; does not affect live content)\nseries_root: series/          # Series / topic root directory (holds series config & assets)\n\n\n# ── Publishing & comments (WeChat credentials in aws.env under WECHAT_N_*; this section only selects method & slot) ──\nENABLE_WECHAT:                # Whether WeChat account is configured; true / false\npublish_method: draft         # draft | published | none; none = no WeChat config, publish.py full skips API calls\nwechat_publish_slot: 1        # Multi-account: which WeChat slot to use (1..wechat_accounts); single account can omit or set 1\nneed_open_comment: 1          # 1 = enable comments on publish; 0 = disable (subject to WeChat backend / API capability)\nonly_fans_can_comment: 0      # 1 = only followers can comment; 0 = everyone can comment (requires comments enabled)\n\n# Whether publishing is complete\npublish_completed: false      # true / false; whether publishing is done\n# Assets and presets are stored under .aws-article/; see .aws-article/README.md\n\n# ── Writing model (third-party LLM) ──\n# Supports any OpenAI-compatible endpoint (official, proxy, or self-hosted)\n# Writing spec: see .aws-article/writing-spec.md (copy from writing-spec.example.md in this directory)\nwriting_model:\n  provider: \"\"                    # Optional; auto-detected from base_url / model if empty (openai | volcengine | qwen | gemini)\n  base_url: \"\"\n  model: \"\"                  # e.g. qwen-plus / qwen-turbo / qwen-max\n  temperature: 0.7\n  max_tokens: 4000\n\n# ── Image generation model ──\n# base_url must be the FULL endpoint path (script detects mode from path suffix):\n#   - https://xxx.com/v1/images/generations   (DALL-E / gpt-image)\n#   - https://xxx.com/v1/chat/completions     (Gemini etc. via proxy)\n#   - Gemini native / Qwen native / Volcengine: use their full endpoint URL\nimage_model:\n  provider: \"\"                    # Optional; auto-detected from base_url path if empty (openai | volcengine | qwen | gemini)\n  base_url: \"\"                    # Full endpoint URL (see examples above)\n  model: \"\"\n  default_size: \"1024x1024\"\n  default_quality: \"standard\"\n  # How to request an aspect ratio on /v1/chat/completions endpoints.\n  #   auto (default) — send Gemini's extra_body.imageConfig only for Gemini-family models\n  #                    (gemini / nano-banana / imagen); other models keep the text hint and\n  #                    get the target ratio by post-generation crop.\n  #   imageconfig    — always send it (for a proxy serving Gemini under a custom model name)\n  #   none           — never send it (for strict gateways that reject unknown body fields)\n  # Ignored by /v1/images/generations, Volcengine and Qwen endpoints, which have their own size params.\n  aspect_mode: auto\n\n# ── WeChat accounts ──\nwechat_accounts: 1                       # Number of WeChat accounts; default 1\nwechat_api_base: \"https://wechat.aiworkskills.cn\"   # WeChat API base URL. Official api.weixin.qq.com enforces an\n                                         # IP allowlist, which blocks calls from a laptop; this\n                                         # reverse proxy avoids that. Set it to\n                                         # https://api.weixin.qq.com to talk to WeChat directly.\nwechat_1_name: \"\"                                                # WeChat account 1 display name\nwechat_2_name: \"\"                                                   # WeChat account 2 display name\n\nFile v1.0.27:references/env.example.yaml\n\n# Key names for aws.env at repo root (this file is valid YAML, for reference only; actual secrets go in aws.env, one KEY=value per line)\n---\n# Writing model (pairs with writing_model in config.yaml)\nWRITING_MODEL_API_KEY: \"\"\n\n# Image model (pairs with image_model in config.yaml)\nIMAGE_MODEL_API_KEY: \"\"\n\n# WeChat official account (slot count determined by wechat_accounts in config.yaml; set to 2 requires filling WECHAT_2_*)\nWECHAT_1_APPID: \"\"\nWECHAT_1_APPSECRET: \"\"\nWECHAT_2_APPID: \"\"\nWECHAT_2_APPSECRET: \"\"\n\nFile v1.0.27:references/first-time-setup.md\n\n# 首次引导 ⛔ BLOCKING\n\n任何操作执行前，必须执行以下 **「检测顺序」** 中的检查步骤。\n\n---\n\n一条龙 / 总览流水线：**先具备仓库根 `aws.env`、`.aws-article/config.yaml`，并通过 `validate_env.py`**，再按总览 [SKILL.md](../SKILL.md) 交互顺序完成 **「2) 全局账号约束」**：**`article_category` / `target_reader` / `default_author` 须由用户确认后再写入** `config.yaml`（**禁止**从某篇 `article.yaml` 擅自抄录），再进入 **「3) 本篇准备」**。\n\n总览规则见 [SKILL.md](../SKILL.md)「配置检查」。\n\n---\n\n## 检测顺序（智能体先判断 OS）\n\n- **Linux / macOS**：下文用 Bash。\n- **Windows**：下文用 PowerShell。\n\n下文命令中的 `{python}` 是**占位符**，须先探测出本机可用的 Python 3 解释器再代入（每次会话探测一次）：\n\n- **Linux / macOS**：`python3 --version` 输出 `Python 3.x.x` → `{python}` = `python3`；不存在则试 `python --version`。\n- **Windows**：`py -3 --version` 输出 `Python 3.x.x` → `{python}` = `py -3 -X utf8`；`py` 不可用则试 `python --version`，通过则用 `python -X utf8`。\n\n⛔ **Windows 上不要探测 `python3`**——未安装 Python 时它是系统预置的应用执行别名，会静默打开 Microsoft Store 而不报错。`-X utf8` 也不可省略，否则脚本的中文输出在简体中文机器上会以 GBK 编码吐出，读到的是乱码。\n\n要求 **Python 3.10+**；版本更低时先提示用户升级。详见 [SKILL.md 第 0 步](../SKILL.md)。\n\n### 1）`.aws-article/config.yaml` 与 `aws.env` 是否存在（仓库根）\n\n```bash\ntest -f .aws-article/config.yaml && test -f aws.env && echo ok || echo missing\n```\n\n```powershell\nif ((Test-Path -LiteralPath \".aws-article\\config.yaml\") -and (Test-Path -LiteralPath \"aws.env\")) { \"ok\" } else { \"missing\" }\n```\n\n⛔ 若为 `missing`，按示例各建一份即可：\n\n1. **`.aws-article/config.yaml`**：复制 **`skills/aws-wechat-article-main/references/config.example.yaml`** 为 **`.aws-article/config.yaml`**。\n2. **`aws.env`**：复制 **`skills/aws-wechat-article-main/references/env.example.yaml`** 为仓库根 **`aws.env`**（内容格式为 `KEY=value`）。\n\n**初始化约束**：新建 **`.aws-article/config.yaml`** 时，**`publish_method` 必须初始化为 `draft`**；除非用户明确指定「不接微信/不走上传」，否则禁止初始化为 `none`。\n\n上述两个文件都创建并保存后，在仓库根运行 **`validate_env.py`**（见下节）。\n\n### 2）`validate_env.py`\n\n在**仓库根**执行：\n\n```bash\n{python} skills/aws-wechat-article-main/scripts/validate_env.py\n```\n\n（默认读取 **`.aws-article/config.yaml`** 与 **`aws.env`**；可用 `--config`、`--env` 指定路径。）\n\n**脚本运行结果**\n\n- **成功（退出码 0）**：输出 **`True`**、**`配置校验通过`**。写作模型、图片模型或 `wechat_N_name` 未配置时会附带警告，但不影响退出码。\n- **失败（退出码 1）**：先输出 **`failed`**，再输出微信必要配置的实际缺失项。\n\n#### 校验失败时的配置引导（必须严格执行）\n\n`validate_env.py` 会完成全部检查后统一输出结果。**当退出码为 1** 时，按实际失败项说明：\n\n环境检查结果：公众号必要配置不完整\n\n1. **必填项**：`wechat_accounts`、`wechat_api_base`，以及每个槽位的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET`。\n2. **配置方式（二选一，**不要把密钥粘贴到聊天里**）**：\n   - **方式 A（推荐）**：在仓库根用编辑器打开 **`aws.env`** 填入 `WECHAT_1_APPID` / `WECHAT_1_APPSECRET` 等，并在 **`.aws-article/config.yaml`** 填入 `wechat_accounts` / `wechat_api_base` 等非密钥项，保存后告诉我「已填好」我来复检。\n   - **方式 B**：前往平台 **`https://aiworkskills.cn/`** 在网页上配。\n\n**原则**：Agent **不向用户索取密钥**、**不代替用户粘贴密钥到文件**。密钥只由用户在本地编辑器中写入 `aws.env`；validate_env 只做非空校验，不读值外发。\n\n**额外操作**：若用户明确表示不配置微信账号，可将 **`config.yaml`** 中 **`publish_method`** 设为 **`none`**，重跑后跳过微信组校验。写作和图片模型均为可选项。\n\n**⛔ 配置与写稿分两阶段（必须遵守）**\n\n- **`validate_env.py` 退出码 1** 时：**本轮只谈环境配置**——按当前失败分支展示 **环境检查结果 + 三条 + 额外操作** 即可，**结束在该主题**；**禁止**在同一条回复（或同一轮未闭环配置前）里再接：写哪篇文章、是否继续某篇草稿、`drafts/` 路径、选题、定题、`topic-card`、审稿、排版等**任何写稿向流程**。\n- **`validate_env.py` 退出码 0（含可选项警告）** 时：流程**不阻断**，可直接进入下一阶段。\n- **下一阶段**：用户按上文配置引导完成落盘并重跑校验至 **退出码 0** 后，先完成总览 **「2) 全局账号约束」**，再进入 **「3) 本篇准备」**、写稿等。\n  - **在不了解用户是要续写旧稿还是新开一篇时**（含刚闭环配置后接写稿）：须按总览 **「3) 本篇准备」** 开头规则**先问再动**，**禁止**直接假定某一 `drafts/…` 目录并调用写作脚本。\n\n---\n\n## `validate_env.py` 在做什么（摘要）\n\n| 组别 | `config.yaml` | `aws.env` | 缺失时行为 |\n|------|----------------|-----------|------------|\n| 微信公众号 | `wechat_accounts`（≥1）、`wechat_api_base` | `WECHAT_{i}_APPID`、`WECHAT_{i}_APPSECRET` | **阻断**：`failed` + 退出码 1 |\n| 公众号展示名 | `wechat_{i}_name` | — | **警告**，不阻断 |\n| 写作模型 | `writing_model.base_url`、`model`（`provider` 可选） | `WRITING_MODEL_API_KEY` | **警告**，不阻断 |\n| 图片模型 | `image_model.base_url`、`model`（`provider` 可选） | `IMAGE_MODEL_API_KEY` | **警告**，不阻断 |\n\n模型与公众号展示名均为可选项。微信槽位与 AppID/AppSecret 保持原有必填规则；`publish_method: none` 时保持原有的跳过微信组逻辑。\n\n---\n\n## 阻断规则\n\n⛔ **缺少 `.aws-article/config.yaml` 或 `aws.env`**，或 **`validate_env.py` 退出码 1**（微信必要配置不完整）：\n\n- 禁止进入一条龙默认流水线（除非先设 **`publish_method: none`** 并重跑校验通过）。\n- 禁止宣称环境已就绪或一条龙已完成。\n\n写作/图片模型或 `wechat_N_name` 缺失只产生警告，不触发阻断。\n\n---\n\n## 引导流程（简版）\n\n### 第 1 步：说明可选策略\n\n- **环境与密钥**：写作/生图的 **URL 与模型名**在 **`config.yaml`**，**API Key** 在 **`aws.env`**；微信 **AppID/AppSecret** 在 **`aws.env`**，槽位展示名与 **`wechat_api_base`** 等在 **`config.yaml`**。  \n- **`validate_env.py` 退出码 0** 表示微信必要配置已通过，或已通过 **`publish_method: none`** 跳过微信组；写作/图片模型或展示名可带警告通过。发布前建议再运行 **`check-wechat-env`**。\n\n### 第 2 步：检查通过以后检查并创建预设目录（这个必须执行）\n\n通过环境检查后，必须先判断以下目录是否存在；**不存在就立即创建**：\n\n- `.aws-article/presets/structures`\n- `.aws-article/presets/closing-blocks`\n- `.aws-article/presets/title-styles`\n- `.aws-article/presets/formatting`\n- `.aws-article/presets/cover-styles`\n- `.aws-article/presets/image-styles`\n- `.aws-article/presets/sticker-styles`\n- `.aws-article/tmp`\n\n> **业务资料库 `.aws-article/products/{产品名}/`**：**不在首次引导创建**——产品名由用户在写第一份业务介绍时决定，AI 用 Write 工具落库时同时 `mkdir -p` 包括 `images/`，详见 [assets skill 一、业务介绍 .md 入库](../../aws-wechat-article-assets/SKILL.md#一业务介绍-md-入库product-intro)。\n\n可按操作系统执行：\n\n```bash\n# Linux / macOS\nmkdir -p .aws-article/presets/structures .aws-article/presets/closing-blocks \\\n  .aws-article/presets/title-styles .aws-article/presets/formatting \\\n  .aws-article/presets/cover-styles .aws-article/presets/image-styles \\\n  .aws-article/presets/sticker-styles \\\n  .aws-article/tmp\n```\n\n```powershell\n# Windows PowerShell\n$dirs = @(\n  \".aws-article/presets/structures\",\n  \".aws-article/presets/closing-blocks\",\n  \".aws-article/presets/title-styles\",\n  \".aws-article/presets/formatting\",\n  \".aws-article/presets/cover-styles\",\n  \".aws-article/presets/image-styles\",\n  \".aws-article/presets/sticker-styles\",\n  \".aws-article/tmp\"\n)\nforeach ($d in $dirs) {\n  if (-not (Test-Path -LiteralPath $d)) {\n    New-Item -ItemType Directory -Path $d -Force | Out-Null\n  }\n}\n```\n\n### 第 3 步：全局 vs 本篇文件\n\n| 文件 | 时机 | 说明 |\n|------|------|------|\n| **`aws.env`** | 首次 / 改密钥时 | 仓库根；写作/图片 API Key、微信 AppID/AppSecret 等|\n| **`.aws-article/config.yaml`** | 首次 / 改账号策略时 | 文风、模型 endpoint、微信槽位元数据、**`publish_method`** 等 |\n| **`article.yaml`** | 每篇、临近发布 | 本篇标题/作者/摘要/封面等；内含 **`publish_completed`**（新建为 **`false`**，发布闭环结束后再改为 **`true`**，便于发布流程分流）；可用 `skills/aws-wechat-article-publish/scripts/article_init.py` |\n\n首次引导**不**创建某篇目录，只保证 **`config.yaml` + `aws.env` 存在**，且 **`validate_env.py` 退出码 0**（微信必要配置完整，或 **`publish_method: none`**；可选项可带警告通过）。\n\n### 第 4 步：确认并继续\n\n摘要提示用户（勿打印完整密钥）：\n\n- **`validate_env.py` 退出码 0**：环境检测通过，可按总览进入流水线。**要走 `publish.py`（非 none）** 前建议 **`check-wechat-env`**。  \n\n可提示：写作规范可复制 **`skills/aws-wechat-article-main/references/writing-spec.example.md`** → **`.aws-article/writing-spec.md`**；预设见 **`.aws-article/presets/`**。\n\n---\n\n## 非首次运行\n\n**每次**进入一条龙、或**仅**触发写作 / 配图 / 发布检查前，都须在仓库根执行：\n\n```bash\n{python} skills/aws-wechat-article-main/scripts/validate_env.py\n```\n\n**智能体**：若退出码非 0，根据终端 **`failed`** 下列出的汇总句，按上文 **「校验失败时的配置引导」** 文案**原样输出**（含三条配置引导 + **额外操作**）；用户补全并落盘后重跑 **`validate_env.py`**。若用户**明确声明本次例外**，按总览 [SKILL.md](../SKILL.md)「智能体行为约束」处理。**禁止**未获补全或明确例外确认就宣称已通过环境校验或一条龙已完成。**禁止**因「上次已通过」而跳过本节命令。\n\n---\n\n## 每次发文目录与顺序（摘要）\n\n- 目录：`drafts/YYYYMMDD-标题slug/`（`drafts_root` 以 **`config.yaml`** 为准时从其读取，否则默认 `drafts/`）。  \n- 建议内含：`draft.md`、`article.md`、`article.html`、`article.yaml`、`imgs/`、`out/` 等（按需生成）。  \n- 流程：定题 → 选题 → 写稿 → 审 → 排版 → 配图 → 终审 → **按需发布**：**`draft`** / **`published`** / **`none`** 见 schema；**`none`** 时 **`full`** 直接跳过；**`draft`/`published`** 须微信就绪（**`check-wechat-env`**）。  \n\n本篇 **`article.yaml`** 必填项：`title`、`author`、`digest`、`content_source`（默认 `article.html`）、**`publish_completed`**（新建 **`false`**，发布成功后再改为 **`true`**）；**`cover_image`** 强烈建议填写。\n\nArchive v1.0.26: 24 files, 40069 bytes\n\nFiles: references/articlescreening-schema.md (6318b), references/config.example.yaml (11422b), references/env.example.yaml (511b), references/first-time-setup.md (11601b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7177b), skill-card.md (2558b), skill.json (693b), SKILL.md (31385b), _meta.json (143b)\n\nFile v1.0.26:SKILL.md\n\n---\nname: aws-wechat-article-main\ndescription: 公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继续上次的」「接着之前的进度」；**显式模型新写**「用 GPT 写一篇」「用 DeepSeek 写一篇」「把提纲写成文章」。子 skill（topics/writing/review/formatting/images/publish/sticker/assets）单独触发仅限对**已有产物**的修改场景（如\"改标题\"\"润色这段\"\"排版\"\"审稿\"\"加封面\"\"发布\"）；新做/策划/多环节串联一律走本入口。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WRITING_MODEL_API_KEY\n        - IMAGE_MODEL_API_KEY\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 公众号运营总览\n\n**一键式公众号 AI 内容流水线** —— 从选题到上架 8 个子 skill 串联，公众号小编 / 自媒体 / 品牌内容团队一键产出整篇图文。\n\n> **套件说明** · `aws-wechat-article-*` 是公众号一条龙套件，共 9 个 slug：`aws-wechat-article-main / topics / writing / review / formatting / images / publish / assets`，外加 `aws-wechat-sticker`。跨 skill 的相对引用依赖同一 `skills/` 根目录；推荐 `clawhub sync` 或逐个 `clawhub install` 一次性全装。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 作为一条龙套件**编排入口**；真正调用外部 API 的是子 skill（writing / images / publish / sticker / review）。**本入口自身的 `validate_env.py` 脚本**行为：\n\n- **凭证读取**：读取仓库根 `aws.env` 的 `WRITING_MODEL_API_KEY` / `IMAGE_MODEL_API_KEY` / `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`，**仅用于校验键是否存在且非空**，值不用于任何网络请求\n- **网络**：本入口脚本无外发请求；**子 skill 有外发**（详见各子 skill 的能力披露）\n- **文件读**：仓库内 `aws.env`、`.aws-article/config.yaml`、本篇 `article.yaml`\n- **文件写**：仓库内 —— `.aws-article/`（首次引导创建目录结构）、本篇 `article.yaml` 状态字段\n- **shell**：仅 `{python} {baseDir}/scripts/validate_env.py`（`{python}` = 本机 Python 3 解释器，由下文**第 0 步**探测得出：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n> **注意**：整体套件（含子 skill）会调用外部 LLM、图像 API 与微信 API，并在调用时外发 API key 与本篇内容。完整行为见各子 skill 的「能力披露」。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的入口，编排 8 个子 skill：`topics / writing / review / formatting / images / publish / assets` 以及 `aws-wechat-sticker`。\n\n- **装齐全部 9 个 slug** 到同一 `skills/` 根目录，才能走完整一条龙流程（选题→写稿→审稿→排版→配图→发布）。\n- 只装 main 一个时，仍可用于环境校验（`validate_env.py`）；进入内容流水线会因对应子 skill 缺失而无法执行相关步骤（工作流里的跨 skill 脚本调用 / 文档读取会遇到 `file not found`）。\n\n完整 9 slug 清单与安装指引见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。\n\n## 配置检查 ⛔ BLOCKING\n\n**进入交互顺序「2) 全局账号约束」「3) 本篇准备」及内容流水线前**须完成 **第 0～2.5 步**配置检测（任一步失败则 **不得** 继续）。**第 3 步**是**调用 `publish.py` 前**的核对（非流水线起点）：**`.aws-article/config.yaml`** 中 **`publish_method`** 默认为 **`draft`**（**`publish.py full`** 只把图文写入**公众号草稿箱**）；仅当用户明确要求「发出去 / 对外发布」时，再将该键改为 **`published`**（或使用 **`full --publish`** 临时强制发布）。**微信**：**`validate_env.py`** 默认要求公众号账号配齐（见第 2 步）；用户**明确不接微信**时，先将 **`publish_method`** 设为 **`none`** 再过校验（脚本会跳过微信组），之后 **`publish.py full`** 仍直接跳过。要走草稿/发布，须补全 **`aws.env`** 与 **`config.yaml`** 微信槽位，并建议 **`check-wechat-env`**。`wechat_N_name` 只用于展示，写作/图片模型是可选项，这三项缺失时只警告。文风与账号约束以 **`config.yaml`** 为准，发文元数据以本篇 **`article.yaml`** 为准。\n\n### 第 0 步：判断操作系统与 Python 解释器\n\n智能体在执行下列检测命令前，**先判断当前环境**：\n\n- **Linux / macOS**：使用 Bash 命令（`test`、`echo` 等）。\n- **Windows**：使用 **PowerShell** 命令（`Test-Path` 等）。\n\n**再确定 `{python}`**——本套件所有文档里的 `{python}` 都是占位符，不是可直接执行的命令，须先探测出本机实际可用的 Python 3 解释器再代入。**本次会话探测一次即可**，之后所有 `{python}` 统一代入该结果。\n\n**Linux / macOS：**\n\n```bash\npython3 --version\n```\n\n输出 `Python 3.x.x` → `{python}` = `python3`。命令不存在则改试 `python --version`，同样要求输出 `Python 3.`；都不行 → 提示用户安装 Python 3.10+ 后再继续，**不得**继续后续步骤。\n\n**Windows（PowerShell）：**\n\n```powershell\npy -3 --version\n```\n\n输出 `Python 3.x.x` → `{python}` = `py -3 -X utf8`。`py` 不可用时改试 `python --version`，通过则 `{python}` = `python -X utf8`。\n\n⛔ **Windows 上不要探测 `python3`**：未安装 Python 时它是系统预置的应用执行别名，会**静默打开 Microsoft Store** 而不报错——你会拿到一个空输出、看不出失败原因。始终优先 `py -3`（python.org 官方安装器默认附带 py launcher，且不受该别名影响）。\n\n⛔ **Windows 上的 `-X utf8` 不可省略**：本套件脚本输出大量中文，Windows 上 Python 的 stdout 编码默认跟随系统 locale（简体中文机器为 GBK），省略后你读到的会是乱码，进而误判脚本成败。\n\n**版本要求 Python 3.10+**。`--version` 显示低于 3.10 时先提示用户升级，再继续。\n\n### 第 1 步：`.aws-article/config.yaml` 与 `aws.env` 是否存在\n\n在**仓库根目录**（当前工作目录为项目根）执行：\n\n**Linux / macOS：**\n\n```bash\ntest -f .aws-article/config.yaml && test -f aws.env && echo \"ok\" || echo \"missing\"\n```\n\n**Windows（PowerShell）：**\n\n```powershell\nif ((Test-Path -LiteralPath \".aws-article\\config.yaml\") -and (Test-Path -LiteralPath \"aws.env\")) { \"ok\" } else { \"missing\" }\n```\n\n⛔ 输出为 `missing`（任一文件不存在）→ 按 [首次引导](references/first-time-setup.md) 创建或补全：可参考 **`{baseDir}/references/config.example.yaml`** 得到 **`config.yaml`**，在仓库根创建 **`aws.env`**（仅密钥与微信 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 等，键名可与 `{baseDir}/references/env.example.yaml` 对照）。\n\n**初始化约束**：新建 **`.aws-article/config.yaml`** 时，`publish_method` 默认必须为 **`draft`**；除非用户明确指定不接微信，否则禁止初始化或改写为 `none`。\n\n### 第 2 步：校验配置内容（`validate_env.py`）\n\n两文件均存在后，在仓库根运行：\n\n```bash\n{python} {baseDir}/scripts/validate_env.py\n```\n\n（默认读取 **`.aws-article/config.yaml`** 与 **`aws.env`**；可用 `--config` / `--env` 指定路径。）\n\n脚本检查（规则摘要，具体交互文案统一以 [首次引导](references/first-time-setup.md) 为准）：\n\n- **微信公众号**：`wechat_accounts`、`wechat_api_base` 与 **`aws.env`** 中每个槽位的 **`WECHAT_{i}_APPID` / `WECHAT_{i}_APPSECRET`** 须完整；否则 **`failed`** + **`微信公众号配置不完整`**，**退出码 1**。`wechat_{i}_name` 仅用于展示与按名选择，未填时只警告。**例外**：**`publish_method: none`** 时跳过微信组校验。\n- **写作模型**：`writing_model.base_url` / `model` 与 **`WRITING_MODEL_API_KEY`** 仅供外部写作 API 使用；未配置时输出警告，不影响退出码，Agent 可通过 `write.py prompt` 获取约束后代写。\n- **图片模型**：`image_model.base_url` / `model` 与 **`IMAGE_MODEL_API_KEY`** 仅供外部生图 API 使用；未配置时输出警告，不影响退出码。\n\n**退出码 0**：微信组通过，或已声明 **`publish_method: none`** 跳过微信组 → **`True`** + **`配置校验通过`**；三个可选项缺失会同时输出警告。**退出码 1**：微信必要配置未通过 → 不得进入一条龙默认流水线，并引导 [首次引导](references/first-time-setup.md) 补全或设为 **`publish_method: none`** 后重跑。\n\n### 第 2.5 步：创建预设与运行目录（硬性前置，必须执行）\n\n**仅当第 2 步退出码为 0** 才执行本步；执行成功后才允许进入「2) 全局账号约束」与后续流水线。  \n目录要求与命令以 [首次引导第 2 步](references/first-time-setup.md) 为准（需覆盖 `presets/*` 与 `tmp`）。**业务资料库 `.aws-article/products/{产品名}/`** 不在本步建——由 AI 写第一份业务介绍时按 [assets skill](../aws-wechat-article-assets/SKILL.md) 自动 mkdir。\n\n- **禁止**因为“环境检查通过”就跳过本步直接写稿。\n- 若目录已存在，可视为本步通过；若缺失，必须立即补建并继续校验。\n\n### 第 3 步：调用 `publish.py` 前（`publish_method` + 微信）\n\n- **`publish_method`**（**`draft`** / **`published`** / **`none`**）写在 **`config.yaml`**，**默认 `draft`**。**`none`** = 用户明确不填微信：**`full`** 不调 API。要「发布出去」→ **`published`** 或 **`full --publish`**。\n- **微信**：在 **`aws.env`**；槽位在 **`config.yaml`**。**`draft`/`published`** 走 **`full`** 前须就绪；**`none`** 下不调用微信。\n- 运行 **`publish.py full`** 前：确认 **`publish_method`** 合法（小写）；**非 `none`** 时建议 **`check-wechat-env`**。\n\n### 智能体行为约束（禁止自作主张）\n\n检测到 **`.aws-article/config.yaml` 或 `aws.env` 缺失**、**`validate_env.py` 退出码 1**（微信配置不完整，且未声明 **`publish_method: none`**），或用户**已要求调用 `publish.py`** 而微信槽位 / 凭证未就绪时：\n\n- **禁止**在未询问用户、未取得用户**明确文字确认**的情况下，自行决定：跳过微信配置、仅出 prompt 却继续宣称「一条龙已完成」、或继续排版/发布并假装配置已就绪。\n- **必须先**：向用户说明**具体缺哪一类**（脚本 **`failed`** 下的 **`微信公众号配置不完整`**；或即将 **`publish.py`** 但微信未配齐），并**统一按** [首次引导](references/first-time-setup.md) 中「校验失败时的配置引导」文案执行。\n- **输出约束**：该场景下除”环境检查结果”可按实际失败项替换外，其余引导文案须与首次引导保持一致。\n- 用户在本地编辑器中填好 `aws.env` 与 `config.yaml` 并保存后，智能体协助重跑 **`validate_env.py`** 复检；若用户明确声明本次例外，按首次引导与本节约束继续处理。\n- **凭证处理原则**：Agent **不得索取、不得接收**用户在对话里粘贴的 `APPSECRET` / `API_KEY` 等任何密钥；所有密钥由用户自己在编辑器里写入 `aws.env`（或通过 `https://aiworkskills.cn/` 平台配置）。Agent 只校验存在性、不读取值、不外发值。\n\n> **模型配置是可选项**：默认校验不因写作/图片模型缺失而阻断。进入对应阶段时，有外部 API 配置则可由脚本调用；没有时，写作由 Agent 根据 `write.py prompt` 执行，配图则根据当前 Agent 能力执行或再向用户说明。\n\n> **单步子 skill**：用户只触发某一子能力（如仅排版、仅审稿）且**未走本总览流水线**时，仍以各子 skill 内说明为准；**一条龙 / 完整流程 / 从选题到发布** 必须满足本节 BLOCKING 与上条「禁止自作主张」。\n\n## 主要配置文件（不要混用）\n\n| 文件 | 位置 | 作用 |\n|------|------|------|\n| `aws.env` | **仓库根** | **密钥**：写作/图片 `*_API_KEY`、微信 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 等（键名见 `references/env.example.yaml`；与 `config.yaml` 一起由 `validate_env.py` 校验） |\n| `.aws-article/config.yaml` | 仓库内 | **非密钥配置**：账号文风、模型 `provider`/`base_url`/`model`、微信槽位数与 `wechat_api_base`、各槽位展示名等（模板见 `references/config.example.yaml`） |\n| `references/env.example.yaml` | 仓库内示例 | **仅文档**：`aws.env` 键名说明 |\n| `references/config.example.yaml` | 仓库内示例 | **仅文档**：`config.yaml` 结构示例 |\n| `article.yaml` | **本篇目录** `drafts/YYYYMMDD-标题slug/` | **发文元数据**（标题/作者/摘要/封面等）及状态字段：**`image_source`**（仅 `generated` / `user`；默认 `generated`，用户上传配图时改为 `user`）与 **`publish_completed`**（新建 **`false`**，发布闭环结束 **`true`**），与 **`config.yaml`** 分工 |\n\n### 发布方式与时间线\n\n1. **账号与发布策略**：**文风、选题边界、`publish_method`（默认 **`draft`**）、微信槽位元数据**等均在 **`.aws-article/config.yaml`** 维护；**密钥**仅在 **`aws.env`**。\n2. **本篇准备**（须先完成交互顺序 **「2) 全局账号约束」**）：在 **定题与 slug** 之后新建 `drafts/YYYYMMDD-标题slug/`，并**优先**创建 **`article.yaml`**（含 **`publish_completed: false`**、标题/作者/摘要等；通常为本目录内**首个**应落盘的文件），再进入内容流水线。\n3. **执行原则（严格顺序）**：必须按下述流水线顺序依次执行，**不能跳过任何部分**；每到一步若缺少必要输入（目录、元数据、主题、用户选择、发布意图等），要**先及时询问用户并获得确认**，再进入下一步，除非用户指出基于某个历史任务继续创作，那么需要智能体根据中间产物判断从哪个阶段开始。\n4. **内容流水线**（子 skill 串行，详见下文 **「交互顺序」第 4 步** 与 **「流程」** 表）：**选题**（[topics](../aws-wechat-article-topics/SKILL.md)）→ **写稿**（[writing](../aws-wechat-article-writing/SKILL.md)）→ **审稿（内容审）**（[review](../aws-wechat-article-review/SKILL.md)）→ **排版**（[formatting](../aws-wechat-article-formatting/SKILL.md)）→ **配图**（[images](../aws-wechat-article-images/SKILL.md)）→ **审稿（终审）**（review）。**内容审**产出的 **`article.md` 定稿须满足 [review 第 5 步](../aws-wechat-article-review/SKILL.md)（文末 **`{embed:…}`**，⛔ BLOCKING）后再排版。全程以 **`.aws-article/config.yaml`** 为账号与文风约束；典型产物依次为 `topic-card.md` / `draft.md` → `article.md` → `article.html` 与 `imgs/` 等。\n5. **发布**（[publish](../aws-wechat-article-publish/SKILL.md)）：**`draft`** → **`full`** 仅**草稿箱**；**`published`** 或 **`full --publish`** → 再**提交发布**；**`none`** → **`full`** **立即跳过**、不调微信。前两档需微信凭证。\n\n**再强调**：**`aws.env`** = 密钥；**`config.yaml`** = 账号/文风/模型与微信元数据及 **`publish_method`**；**本篇 `article.yaml`** = 发文元数据。\n\n## 交互顺序（一步步，最小提问）\n\n按以下顺序与用户交互，**上一步完成再进下一步**；上一环节就绪后再进入下一环节。\n\n### 1) 配置自检（必做）\n\n- 按上文 **配置检查** 完成：**`config.yaml` 与 `aws.env` 均存在** → 运行 **`validate_env.py`** **且退出码 0**。**退出码 1** 时按 [首次引导](references/first-time-setup.md) 补全微信必要配置；用户明确不接微信时可设为 **`publish_method: none`** 后重跑。\n- **`validate_env.py` 退出码 0 后，必须立即执行「第 2.5 步目录创建」**（可复用 [首次引导第 2 步](references/first-time-setup.md) 命令）；该步完成前，**禁止**进入「2) 全局账号约束」与任何写稿流程。\n- **退出码 0 + 可选项警告**：流程**不阻断**，可直接进入下一步；不得要求用户先配置外部写作/图片模型。\n- **退出码 1（微信不完整）时**：只展示 [首次引导](references/first-time-setup.md) 中的 **配置选项**，**不要**在同一轮回复里再问「写哪篇 / 继续哪篇草稿 / 新选题」等；须等配置闭环（重跑校验通过或「本次例外」已书面确认）后，**再**进入下方 **「2) 全局账号约束」**。\n- **`validate_env.py` 不检查** `article_category`、`target_reader`、`default_author`；须在 **「2) 全局账号约束」** 中单独检查并落盘。\n\n### 2) 全局账号约束（`.aws-article/config.yaml`）⛔\n\n**在 `validate_env.py` 已通过**（或已按总览完成「本次例外」）**之后、进入「3) 本篇准备」之前**，**必须**打开 **`.aws-article/config.yaml`**，检查下列键 **trim 后是否非空**：\n\n- **`article_category`**、**`target_reader`**、**`default_author`**\n\n任一项缺失或空白：**逐项询问用户**（1.账号领域2.目标读者3.作者名字），取得**用户当轮明确答复**后再**写回** **`.aws-article/config.yaml`**，再进入 **「3) 本篇准备」**。**禁止**仅在对话里口头确认却不写入文件。**禁止**跳过本步直接假定可写稿。\n\n**⛔ 禁止擅自填写（必须写进行为约束）**\n\n- **不得**从本篇或其它目录的 **`article.yaml`**、历史草稿、**`topic-card.md`**、对话记忆或仓库内任意文件**静默抄录、推断或「顺手补全」**后写入 **`article_category` / `target_reader` / `default_author`**。对 **`tone`** 等与账号画像强相关的全局项，要直接询问用户，**同样禁止**未询问就写盘。\n- **允许的做法**：向用户说明「当前为空」，**请用户填写或确认**；若你想根据某篇 `article.yaml` 给**建议**，只能**展示为待选文案**，并问「是否采用 / 要改哪几个字」，**用户明确同意后再写入** `config.yaml`。\n- **顺序**：在尚未完成 **「3) 本篇准备」** 中「续旧 / 新开」的确认前，**禁止**用某一 `drafts/…/article.yaml` **反推**全局三键，避免误把单篇元数据当成整号定位。\n\n### 3) 本篇准备（二选一，默认「新建一篇」）\n\n**在完成「2) 全局账号约束」之后**，**在不了解用户是要续写既有草稿还是新开一篇时**（例如未指定 `drafts/…` 路径、且仓库 **`drafts/`** 下存在进行中目录或多个候选）：**须先询问**并让用户选定 **「继续哪一篇」** 或 **「新开一篇」**，**再**进入下列 A/B 或调用写作脚本。**禁止**默认「最近修改」目录、未确认就运行写作脚本、或假定沿用上一轮路径。\n\n**业务素材双向规则（涉及用户自身业务时强制，详见 [assets skill](../aws-wechat-article-assets/SKILL.md)）**：\n\n- **读**：若本篇涉及用户自家业务（产品/软件/服务），**先 `ls .aws-article/products/`** 看有无相关产品目录，进入后必读根下 `*.md`（业务介绍）作为底稿来源；`images/` 子目录里有现成业务配图则优先复用。\n- **写**：本流程中产生的内容若**语义属于业务介绍**（不是文章主体而是侧重产品/服务自介），由 AI 主动引导用户保存到 `.aws-article/products/{产品名}/{文件名}.md`（用 Write 工具直接落库；目录不存在时同时创建 `images/`），下次涉及业务的文章自动用上。\n\n#### A. 新建一篇（**严格子顺序**，勿跳步）\n\n1. **写作意图** ⛔ **BLOCKING**：必须问清用户 **本篇要写什么**（具体主题、角度、体裁或目标）。若用户只想「帮我出选题」，须**明确确认**后再当无方向模式处理。  \n   - **禁止**在用户未回答本步（且当前对话也未等价说明）之前：**调用 web_search**、**执行 topics 的调研**、**批量生成选题或标题**。  \n   - 用户已在当次对话中说清楚「写什么」的，可本步口头确认一句即可，不必重复盘问。\n2. **定题与 slug**：在写作意图已明确的前提下，确定**发文章标题**——用户从候选中选一个，或**自定义标题**；据此生成 **slug**，目录名为 `YYYYMMDD-标题slug`（slug 规则：小写、连字符、与项目习惯一致即可）。\n3. **建目录与 `article.yaml`**：创建 `{drafts_root}/YYYYMMDD-标题slug/`（`drafts_root` 以 **`config.yaml`** 为准，默认 `drafts/`）。随即初始化本篇 **`article.yaml`**（含 **`publish_completed: false`**，及标题、作者、摘要等；目录内**宜最先写入**；可用 `{baseDir}/../aws-wechat-article-publish/scripts/article_init.py`）。\n   - **`publish_method`**：默认 **`draft`**；要发出去 → **`published`** 或 **`full --publish`**；用户明确不填微信 → **`none`**。\n4. **本篇预设单选落盘（必做）**：初始化后按场景执行：**新建首轮**以 **`.aws-article/config.yaml`** 为来源，按 **`custom_* > default_*`** 结合本篇主题/选题卡，为以下字段各选**单一预设**并写回本篇 **`article.yaml`** 为**单元素列表**：`default_structure`、`default_closing_block`、`default_title_style`、`default_format_preset`、`default_cover_image_style`、`default_article_image_style`、`default_sticker_style`。**续写/重入**时若本篇 `article.yaml` 对应字段已为单元素列表，视为本篇已选并优先保留，不重选不覆盖。若 `config.yaml` 不存在或候选为空，可保持 `[]`。\n5. 至此才进入 **第 4 步内容流水线**。\n\n#### B. 我已有目录\n\n- 用户给出路径。必读 **`.aws-article/config.yaml`**（账号与发布策略）；本篇目录内需有 **`article.yaml`**（或按用户状态后补）。若已有 `article.html`/`cover.jpg` 可直接从流水线中靠后的步骤接入。\n- 若用户意图是「发布后换图并重发草稿箱」，也走本分支：指定既有目录后，从 **配图（用户供图分支）** 接入，再执行 **终审 → 发布**。\n\n### 4) 内容流水线（子 skill）\n\n须已具备 **本篇目录** 与 **`article.yaml`**（「已有目录」分支按上条处理）；账号侧约束以 **`config.yaml`** 为准。\n\n**确认轮次优化**：全局三键已非空时静默通过；`publish_method` 已为合法值时不重复盘问；多个待确认项可合并为一轮提问。用户意图明确时（如给出主题 + \"写一篇文章\"），理想轮次为 **1 轮**（确认标题/摘要）+ **写完后展示结果**。配图方案在用户无特殊要求时按默认风格自动执行，不单独确认。\n\n```\n选题 → 写稿 → 审稿(内容审) → 排版 → 配图 → 审稿(终审)\n```\n\n- **topics**：仅在 **写作意图已明确**（见上 3-A-1）之后执行；仍须遵守 **aws-wechat-article-topics** 中「展示后等用户选」等规则。\n- **writing**：结合 **`.aws-article/config.yaml`** 与 `topic-card.md`（或用户素材）；**`publish_method`** 见 **`config.yaml`**（上文「发布方式与时间线」）；产物 `draft.md` → 内容审后 `article.md`。\n- **review（内容审）**：定稿 **`article.md` 前**须按 [review 第 5 步 ⛔ BLOCKING](../aws-wechat-article-review/SKILL.md) 完成文末 **`{embed:…}`**（或规则允许的省略并留痕）；**未完成不得进入 formatting**。\n- **formatting**：`article.md` → `article.html`（用户当次指定排版主题可覆盖默认）。\n- **images**：按 **aws-wechat-article-images**（配置与行为约束以本节「配置检查」为准）。\n- **review（终审）**：检查 `article.html` 与 `imgs/`；有问题给出清单，等用户确认或修复。\n\n### 5) 发布\n\n- 以 **`config.yaml`** 的 **`publish_method`** 为准；**`draft`** / **`published`** / **`none`** 含义见上文。**`none`** 时运行 **`full`** 会无操作退出。\n- **`draft`/`published`**：**微信**须配齐后再调 **`publish.py`**；建议 **`check-wechat-env`**。**`none`**：不调微信，说明即可。\n- 完成后输出小结与回执，目录按需移至 `published_root`。\n\n### 6) 发布后换图重发（补充分支）\n\n当用户说「草稿箱里图不满意，换我上传的图重新发」：\n\n1. 锁定目标 `drafts/…` 目录；\n2. 将新图放入本篇 `imgs/`，生成/更新 `img_analysis.md`（封面仅 1 张）；\n   - 同步更新本篇 `article.yaml`：`image_source: user`；\n   - 开始重做流程前，将 `publish_completed` 置回 `false`；\n3. 依据分析结果更新 `article.md` 图片映射（允许重排）；\n4. 重新执行 `format.py` 生成 `article.html`；\n5. 终审通过后执行 `publish.py full`（`draft` 写草稿箱）；\n6. 发布命令成功且回执可用后，写回 `publish_completed: true`。\n\n## 流程\n\n```\n选题 → 写稿 → 审稿(内容审) → 排版 → 配图 → 审稿(终审) → 发布\n```\n\n## 中间产物门禁（缺啥补啥）⛔\n\n进入下一步前，必须先检查本步所需中间产物；缺什么就先补什么，禁止跳步并宣称已完成。\n\n| 阶段 | 必要产物（最小集合） | 缺失时动作 |\n|------|----------------------|------------|\n| 写稿完成 | `article.md` 存在且非空 | 继续写稿或回滚到 writing |\n| 排版完成 | `article.html` 存在，且由当前 `article.md` 重新生成 | 先执行 formatting 重转 |\n| 配图完成 | 文章目录存在 `cover.(png/jpg/jpeg/webp)`；`article.md` 与 `article.html` 不含 `placeholder` | 先执行 images 生成并替换（`image_source=user` 时走用户供图映射与重排） |\n| 发布就绪 | `article.yaml` 含 `title/author/digest/content_source`；发布环境检查通过 | 先补齐元数据或环境 |\n| 发布闭环 | 发布命令成功且回执可用 | 才允许写回 `publish_completed: true` |\n\n**禁止**：仅凭单一信号（如“草稿创建成功”）就宣称全流程完成。若正文仍有 `placeholder`，状态必须标记为“草稿已提交，正文配图未完成”。\n\n| 步骤 | 子 skill | 读取 | 产出 |\n|------|---------|------|------|\n| 选题 | topics | **`.aws-article/config.yaml`**、`aws.env`、web_search | `topic-card.md` `research.md` |\n| 写稿 | writing | `topic-card.md`、**`.aws-article/config.yaml`**、`aws.env`（专用写作 API） | `draft.md` |\n| 审稿 | review | `draft.md`、`aws.env`、**`.aws-article/config.yaml`** | `review.md` → `article.md`（定稿须含文末 embed，见 [review 第 5 步](../aws-wechat-article-review/SKILL.md)） |\n| 排版 | formatting | `article.md`、**`.aws-article/config.yaml`** | `article.html` |\n| 配图 | images | `article.md`、`aws.env`、**`.aws-article/config.yaml`** | `imgs/` |\n| 终审 | review | `article.html`、`imgs/`、**`.aws-article/config.yaml`** | `review.md` |\n| 发布 | publish | `article.html`+`imgs/`、**`config.yaml`**、`aws.env`（调用 publish.py 时） | 草稿 media_id / 发布 publish_id、URL、`out/` 记录 |\n\n**账号与文风约束**：以 **`.aws-article/config.yaml`** 为准。\n\n**topics / `web_search`**：须满足上文 **3-A-1**（用户已说明本篇写什么，或已确认「只帮忙出选题」）之后才可调研与生成选题；不得默认跳过提问直接搜索。\n\n> 提示：发布前需就绪本篇 `article.yaml`（标题/作者/摘要/封面等元数据；`content_source` 默认 `article.html`）。可用 `{baseDir}/../aws-wechat-article-publish/scripts/article_init.py` 快速初始化或更新。\n\n## 路由\n\n**默认**：与长文发文相关时 **优先 main**，由本 skill 按步编排；不要因用户说了「写」「选题」「发」就跳过 main 直连子 skill。\n\n**何时直连子 skill**（可跳过 main 入口）：用户**明确只要该步产物**、且不隐含「从零到发出」整条链。例如：已有 `article.md` 只要排版；已有稿只要审稿清单；已有 `article.html`+`imgs/` 只要发布前检查或提交；已有选题卡只要扩写等。\n\n| 用户说法 | 路由到 |\n|---------|--------|\n| 从0开始、从零、从头、一条龙、完整流程、帮我发一篇、发到公众号（含各前置步）、今天发什么/写什么好（要成文并发）、不确定从哪步开始 | **main** |\n| **只要**选题卡、标题、摘要、排期、系列策划（明确不做后续编排） | topics |\n| **只要**在已有选题/大纲/草稿上写稿、改写、润色、续写（明确不要全流程） | writing |\n| **只要**审稿/校对/合规清单（成稿或已定版 HTML） | review |\n| 「能不能发」且含代为发布、或要从稿到发出整条收尾 | **main** |\n| **只要**排版、换主题、转 HTML | formatting |\n| **只要**长文封面/正文配图（有正文或插图位） | images |\n| 贴图、图片消息、多图推送、九宫格（非长文图文链路） | **sticker** |\n| **只要**执行发布/提交/群发（已有约定产物） | publish |\n\n## 运行模式\n\n### 一条龙\n\n用户说「一条龙」「完整流程」时启用。按 **交互顺序** 的 1→2→3→4→5 执行；**3-A** 内子步骤亦须逐步完成。流水线中每步完成后**暂停**等用户确认。审稿有 🔴 项时进入修改循环。\n\n### 单步\n\n用户**明确只要某一步**且已有对应输入产物（或声明不做全流程）时，可仅执行该步骤；若表述含糊、可能还要后续发文，仍从 **main** 问起或按一条龙拆步确认。\n\n### 贴图\n\n路由到独立的 **aws-wechat-sticker** skill。\n\n## 配置与自定义\n\n- **`aws.env`**（仓库根，密钥）与 **`.aws-article/config.yaml`**（非密钥与模型/微信元数据及 **`publish_method`**）：校验 **`{baseDir}/scripts/validate_env.py`**；`aws.env` 键名见 **`references/env.example.yaml`**\n- **`config.yaml` / `article.yaml` / `aws.env` 字段说明**：[references/articlescreening-schema.md](references/articlescreening-schema.md)\n- 发布前微信：**`{baseDir}/../aws-wechat-article-publish/scripts/publish.py check-wechat-env`**（仓库根执行，试换微信 **access_token**；凭证在 **`aws.env`**）\n\nFile v1.0.26:references/presets/closing-blocks/README.md\n\n# 文末区块预设\n\n本目录下的 `.md` 文件为**文末固定引导区块**。写作时按 config 的 `custom_closing_block` > `default_closing_block` 或 config 中的 `closing_block` 字符串加载。\n\n## Schema\n\n- 每个文件为一段 Markdown，用于文章末尾：关注引导、公众号名片、往期推荐、行动号召等。\n- 可使用嵌入标记：`{embed:profile:名称}`、`{embed:miniprogram:名称}`、`{embed:miniprogram_card:名称}`、`{embed:link:名称}`。名片与小程序以 **`.aws-article/config.yaml`** 的 `embeds` 为准；**仅往期链接**可在本篇 `article.yaml` 写 `embeds.related_articles` 与全局合并（详见 [formatting SKILL](../../../../aws-wechat-article-formatting/SKILL.md)）。\n- 文件名即预设名（不含后缀），如 `brand.md` → 预设名 `brand`。在 config 中设置 `default_closing_block` 或 `custom_closing_block`（`custom_*` 优先）即可使用。\n\n## 示例\n\n见 `simple.example.md`。复制后重命名并按需修改。\n\nFile v1.0.26:references/presets/cover-styles/README.md\n\n# 封面配图风格预设（仓库侧说明）\n\n内置封面预设随 **`aws-wechat-article-images`** 提供，路径为 **`references/cover-styles/`**。本目录说明如何在仓库里**扩展或覆盖**封面风格。\n\n## 放置位置\n\n- **日常自定义**：`.aws-article/presets/cover-styles/<名>.md`\n- **`.aws` 预设包**：包内包含 **`cover-styles/`** 目录，由 `import_presets_aws.py` 合并到上述路径。\n\n## 配置键\n\n- **`default_cover_image_style`**：账号级默认候选（YAML 字符串列表）\n- **`custom_cover_image_style`**：非空时覆盖同名 **`default_*`**\n- **本篇 `article.yaml`**：同名键再覆盖全局\n\n合并后须收窄为**单元素列表**再跑配图流程。完整规则见 [articlescreening-schema.md](../../articlescreening-schema.md) 与 **`config.example.yaml`**。\n\n## Schema 与示例\n\n字段结构与内置一致，见 [cover-styles/README.md](../../../../aws-wechat-article-images/references/cover-styles/README.md)。可将本目录下的 `*.example.md` 复制到 `.aws-article/presets/cover-styles/` 后去掉 `.example` 再按需修改。\n\nFile v1.0.26:references/presets/image-styles/README.md\n\n# 正文配图风格预设\n\n本目录下的 `.md` 文件为**正文配图风格预设**。生成正文配图时按 **`custom_article_image_style`**（本篇 **`article.yaml`** > **`config.yaml`**；**须为 YAML 字符串列表**；多候选须在本篇改为**单元素列表**）加载对应 `.md`；未配置时按用户指定或自动推荐。\n\n> **封面风格预设**在 `skills/aws-wechat-article-images/references/cover-styles/`，与正文配图预设分开管理。\n\n## Schema\n\n- 每个文件描述一种视觉风格：风格名、描述、适用场景、**prompt 要点或关键词**（供 Agent/脚本生成图片时使用）。\n- 正文配图风格库见 [styles.md](../../../../aws-wechat-article-images/references/image-styles/styles.md)。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `flat-vector.example.md`。复制后重命名并按需修改。\n\nFile v1.0.26:references/presets/sticker-styles/README.md\n\n# 贴图风格预设\n\n本目录下的 `.md` 文件为**贴图/多图推送风格预设**。创作贴图时按 config 的 `custom_sticker_style` > `default_sticker_style`（`custom_*` 优先）或用户指定加载。\n\n## Schema\n\n- 每个文件描述多图推送的视觉风格与排版偏好：风格名、画面调性、张数建议、配文风格等。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `default.example.md`。复制后重命名并按需修改。\n\nFile v1.0.26:references/presets/structures/README.md\n\n# 文章结构预设\n\n本目录下的 `.md` 文件为**文章结构预设**。写作时按 **`config.yaml`**（及本篇 **`article.yaml`** 覆盖）的 `custom_structure` > `default_structure` 或用户指定加载。\n\n## Schema\n\n- 每个文件为一篇 Markdown，描述**标准结构**：标题、摘要、开头类型、正文小标题与段落节奏、结尾类型、配图密度建议。\n- 可引用 [writing 内置结构模板](../../../aws-wechat-article-writing/references/structure-template.md)，在其基础上做增减或改写。\n- 文件名即预设名（不含后缀），如 `listing.md` → 预设名 `listing`。在 **`config.yaml`** 中写 `default_structure` 或 `custom_structure`（`custom_*` 优先）；多候选时写多项，须在本篇 **`article.yaml`** 同键改为单元素列表后再运行 **`write.py`**（勿用字符串标量）。\n\n## 示例\n\n见 `listing.example.md`。复制为 `listing.md`（或自定义文件名）后按需修改。\n\nFile v1.0.26:references/presets/title-styles/README.md\n\n# 标题风格预设\n\n本目录下的 `.md` 文件为**标题风格预设**。选题生成标题时按 **`custom_title_style`** > **`default_title_style`**（**须为 YAML 字符串列表**；`custom_*` 非空时优先；多候选时由智能体择一，写回本篇 **`article.yaml`** 为**单元素列表**）或用户指定加载。\n\n## Schema\n\n- 每个文件描述一种标题风格：风格名、特点、适用场景、**示例句式或模板**（可含占位符如 XX、N）。\n- 选题 skill 会混合多种风格生成标题候选；若指定本目录下的预设名，则优先按该风格的示例生成。\n- 文件名即预设名（不含后缀）。内置风格见 [title-presets](../../../aws-wechat-article-topics/references/title-presets.md)：悬念型、干货型、数字型、反问型、故事型。\n\n## 示例\n\n见 `suspense.example.md`。复制后重命名并按需修改。\n\nFile v1.0.26:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-main\",\n  \"version\": \"1.0.26\",\n  \"publishedAt\": 1788679411615\n}\n\nFile v1.0.26:references/articlescreening-schema.md\n\n# 配置字段说明（`config.yaml` + `article.yaml`）\n\n**账号与流程级** → **`.aws-article/config.yaml`**；**本篇发文与发布状态** → **`article.yaml`**；**密钥** → 仓库根 **`aws.env`**。\n\n路径与模板：\n\n| 用途 | 路径 | 模板 / 示例 |\n|------|------|-------------|\n| 账号、文风、模型 endpoint、微信元数据、发布方式等 | **`.aws-article/config.yaml`** | **`config.example.yaml`**（同目录） |\n| 本篇标题、摘要、封面、**发布是否完成**等 | **`{drafts_root}/YYYYMMDD-标题slug/article.yaml`** | **`article_init.py` 初稿；字段见下文「本篇 article.yaml 字段」** |\n| API Key、微信 AppID/AppSecret | **`aws.env`**（仓库根） | **`env.example.yaml`**（同目录） |\n\n全局校验与首次引导：[first-time-setup.md](first-time-setup.md)；总览流程：[SKILL.md](../SKILL.md)。\n\n**优先级**：用户当次说法 > 本篇 **`article.yaml`**（仅本篇字段）> **`.aws-article/config.yaml`**（`custom_*` 覆盖 `default_*`）> 各 skill 内置默认。\n\n---\n\n## `.aws-article/config.yaml` 字段（按模板分组）\n\n**完整字段与分组**以仓库内 **`config.example.yaml`**（同目录）为准（含逐行注释）。本文不重复粘贴整段 YAML，避免与模板更新分叉。可按项目在该示例基础上增删键；未出现的键由各子 skill 使用内置默认。\n\n**说明**：**`publish_completed`** 请放在本篇 **`article.yaml`**（见下节），勿写在全局 **`config.yaml`**；若旧稿或历史模板仍把「是否发完」放在 config 里，以 **`article.yaml`** 为准并逐步从 config 中清理。\n\n**配图风格**：**封面**预设目录为 **`cover-styles/`**（内置随 `aws-wechat-article-images` + **`.aws-article/presets/cover-styles/`**）；**正文配图**为 **`presets/image-styles/`** 下同名 `.md`。配置键：**`default_cover_image_style`** / **`default_article_image_style`**（账号默认候选）与 **`custom_cover_image_style`** / **`custom_article_image_style`**（覆盖层）；**`custom_*` 非空时优先于同名 `default_*`**。\n\n**预设候选列表**：**`default_structure`**、**`default_closing_block`**、**`default_title_style`**、**`default_format_preset`**、**`default_cover_image_style`**、**`default_article_image_style`**（及 **`default_sticker_style`**）**须为 YAML 字符串列表**：`[]`、单元素 `[名]`，或多项候选；**多项时**智能体须在本篇 **`article.yaml`** 同键改为**单元素列表**后，再运行 **`write.py`**（结构/文末）与 **`format.py`**（排版主题）。**勿使用字符串标量。** 配图风格字段（`custom_cover_image_style`、`custom_article_image_style` 及对应的 `default_*`）同理。\n\n**`custom_*` 覆盖层**：`default_structure`、`default_closing_block` 等字段均有对应的 `custom_*`（如 `custom_structure`、`custom_format_preset` 等），格式相同。当 `custom_*` 非空时，优先于同名 `default_*`。合并优先级：**`article.yaml` > `custom_*` > `default_*`**；配图风格在解析完上述合并后的列表后，再按 skill 规则从内置与用户 **`cover-styles` / `image-styles`** 目录加载预设文件。\n\n---\n\n## 本篇 `article.yaml` 字段\n\n路径：`{drafts_root}/YYYYMMDD-标题slug/article.yaml`。初始化可用 **`skills/aws-wechat-article-publish/scripts/article_init.py`**。\n\n| 键 | 说明 |\n|----|------|\n| `title` | 文章标题 |\n| `author` | 作者；可空时部分流程会回退 **`config.yaml`** 的 **`default_author`** |\n| `digest` | 摘要（微信 digest 上限 128 字） |\n| `cover_image` | 封面路径或 URL（强烈建议） |\n| `pic_crop_235_1` | 可选。2.35:1 封面裁剪框，`X1_Y1_X2_Y2` 归一化 0~1；留空由 `publish.py` 按封面尺寸自动居中计算 |\n| `pic_crop_1_1` | 可选。1:1 封面裁剪框，格式同上；两者裁出的宽高比须与目标比例一致，否则接口报 53402 |\n| `content_source` | 正文 HTML 来源，默认 **`article.html`** |\n| `need_open_comment` | 是否开启留言（与微信能力一致） |\n| `only_fans_can_comment` | 是否仅粉丝可留言 |\n| **`publish_completed`** | **`false`** / **`true`**。新建本篇为 **`false`**；**发布闭环结束后**由智能体改为 **`true`**。**`publish.py` 不读写此键**；用于对话分流与运营备忘。 |\n| **`default_structure`** / **`custom_structure`** 等全局同名预设键 | 可选。与 **`config.yaml`** 合并时**本篇覆盖**（`custom_*` 优先于 `default_*`）；若全局某键为**多元素候选列表**，须在本篇写入**单元素列表** `[名]`，再运行 **`write.py`** / **`format.py`**。 |\n\n---\n\n## `aws.env`（仓库根）\n\n与 **`validate_env.py`**、**`publish.py`** 共用。键名见 **`env.example.yaml`**（同目录）。\n\n| 用途 | 典型键 |\n|------|--------|\n| 写作模型 | `WRITING_MODEL_API_KEY` |\n| 图片模型 | `IMAGE_MODEL_API_KEY` |\n| 微信 | `NUMBER_ACCOUNTS`（与 `publish.py` 一致）、`WECHAT_{i}_NAME`、`WECHAT_{i}_APPID`、`WECHAT_{i}_APPSECRET`、可选 `WECHAT_{i}_API_BASE` |\n\n**`validate_env.py`**（环境检测）：微信槽位、AppID/AppSecret 缺失时 **`failed`**、退出码 1；**`publish_method: none`** 时跳过微信组。写作/图片模型与 `wechat_N_name` 缺失时仅警告。详见脚本 docstring。\n\n---\n\n## 发布相关（`publish_method`、`publish_completed`、槽位）\n\n| 键 | 所在文件 | 说明 |\n|----|-----------|------|\n| **`publish_method`** | **`config.yaml`** | **`draft`**（默认）：**`full`** 仅写入**公众号草稿箱**。**`published`**：草稿后再**提交发布**。**`none`**：用户明确不填微信时写入；**`full`** 不调接口、直接跳过。 **`full --publish`** 在 `draft` 下可单次强制发布；**`none`** 下仍会跳过。 |\n| **`publish_completed`** | **`article.yaml`** | 新建 **`false`**；发布真正结束后由智能体写 **`true`**。 |\n| **`wechat_publish_slot`** | **`config.yaml`**（可选） | 多账号时指定本篇默认槽位 **1..N**；与 **`publish.py --account`** 二选一，**命令行优先**。 |\n| 微信凭证 | **`aws.env`** | **`WECHAT_{i}_APPID`** / **`WECHAT_{i}_APPSECRET`** 等；**`validate_env.py`** 默认要求配齐，除非 **`publish_method: none`**。 |\n\nFile v1.0.26:references/config.example.yaml\n\n# Account & workflow config (template)\n# Copy to .aws-article/config.yaml; secrets go in aws.env at repo root (see env.example.yaml in this directory)\n# Per-article metadata & publish_completed go in each article.yaml; field docs: skills/aws-wechat-article-main/references/articlescreening-schema.md\n\n# ── Account & positioning ──\narticle_category:        # Account niche / positioning (e.g. tech / education / lifestyle); affects overall style & topic selection\ntarget_reader: \"\"            # Target reader persona (e.g. college students / beginners / dev managers); determines vocabulary depth & examples\ntone:                    # Tone (casual / professional / formal / sharp / humorous); affects voice & sentence style\nupdate_frequency:        # Publishing frequency (e.g. daily / weekly / biweekly); used for scheduling hints\ndefault_author: \"\"           # Default author name; falls back to this when a single article has no author set\n\n# ── Topics & titles ──\ntopic_direction: \"不写XX\"          # Topic direction or exclusions (e.g. \"avoid XX\" / \"more case studies\"); guides topic generation boundaries\ntitle_style: 干货型          # Title style preset (e.g. practical / story / listicle); preference for title generation\ntitle_max_length: 25         # Max title length (in Chinese characters)\nsummary_length: \"80-128\"     # Target summary word count range (for model prompts & self-check; WeChat digest max 128 chars)\nforbidden_title_phrases: []  # Banned title words / phrases (list); prevents clickbait or sensitive terms\n\n# ── Writing ──\nwriting_style: 口语化        # Writing style (conversational / formal / methodology / case-study / narrative); affects structure & expression\nparagraph_preference: 短段为主 # Paragraph preference (short / long / mixed); affects layout & line breaks\nheading_density: 每节必有小标题 # Subheading density (required per section / moderate / minimal); used for structure validation\ntarget_word_count: \"\"        # Target word count (e.g. \"1800-2500\" or \"2000\"); used for writing & validation\nclosing_block: \"\"            # Global closing block (Markdown string); leave empty if using a preset\nforbidden_words: []          # Banned words list for body text; used in review & self-check\noriginal_attribution: \"\"     # Attribution style (e.g. \"original / authorized reprint / references\")\n\n# ── Preset defaults ──\n# Presets live in .aws-article/presets/{type}/; see each directory's README.md\n# Format: must be YAML string lists. [] = no default; single item = use directly; multiple items = candidate pool —\n#   the agent must narrow to a single-item list in this article's article.yaml before running write.py / format.py\n#   (write validates structure/closing; format validates format_preset). Do not use scalar strings.\n# Priority: article.yaml > custom_* > default_*\ndefault_structure:                # e.g. single or multiple candidates\n  - AI Skill 爆款教程结构\n  - AI Skills 实操爆文结构\ndefault_closing_block: []         # e.g. - brand\ndefault_title_style:\n  - 技术实操指南型\ndefault_format_preset:\n  - 金融蓝\ndefault_cover_image_style: []   # Cover preset names → cover-styles/ (built-in + .aws-article/presets/cover-styles/)\ndefault_article_image_style: [] # Body image preset names → presets/image-styles/\ndefault_sticker_style: []         # e.g. - storyboard; sticker workflow — agent picks one from the list\n\n# ── Custom presets (override defaults) ──\n# Same format as default_*: YAML string lists. When set, takes priority over default_*.\n# article.yaml still takes highest priority over both.\ncustom_structure: []\ncustom_closing_block: []\ncustom_title_style: []\ncustom_format_preset: []\ncustom_cover_image_style: []      # Overrides default_cover_image_style; same paths as default_cover_image_style\ncustom_article_image_style: []    # Overrides default_article_image_style; loads from presets/image-styles/\ncustom_sticker_style: []\n\n# ── Images ──\n# Cover presets: cover-styles/ (separate from body presets/image-styles/). Lists: default_* then custom_* then article.yaml.\nimage_source: generated       # generated | user; user = use uploaded images directly (skip image_create.py)\ncover_aspect: \"2.35:1\"       # Cover image aspect ratio (e.g. 2.35:1 / 1.91:1 / 16:9); used for generation & crop reference\ncover_style: 简约             # Broad preference alongside cover presets; minimal / illustration / photo / brand-color\nimage_density: 每节一图       # In-article image density (one per section / moderate / few / optional)\ncaption_style: 有图注         # Caption style (with captions / no captions / key images only)\nmulti_image_count: 6          # Default image count for multi-image scenarios (for generation or layout reference)\n# Business assets (product intros, screenshots, brand images) go in .aws-article/products/{product-name}/\n\n# ── Review ──\nreview_required:              # Required review checks (checked items appear in self-check / review report)\n  - 敏感词                    # Example: check for sensitive words\n  - 错别字                    # Example: typos / common misspellings\n  - 链接                      # Example: external link format / availability\n  - 原创标注                  # Example: whether original / reprint attribution is present\ncustom_sensitive_words: []    # Custom sensitive words list (overrides the general list)\nreview_output_format: 分块详细 # Review output format (brief / detailed-by-section); affects report presentation\n\n\n# ── Embeds ──\n# Articles can reference {embed:profile:name}, {embed:miniprogram:name}, {embed:miniprogram_card:name}, {embed:link:name}\n# Per-article article.yaml should only set embeds.related_articles (e.g. manual); deep-merged with global related_articles.\n# Do not duplicate profile / miniprogram config in article.yaml.\nembeds:\n  profiles:                   # WeChat official account cards (for {embed:profile:name})\n    - nickname: \"\"            # Matches the placeholder; also used as data-nickname\n      alias: \"\"               # Only for gh_ legacy format; new format uses id/headimg instead\n      id: \"\"                  # data-id (when both id & headimg are set, outputs mp-common-profile)\n      profile_id: \"\"          # Same as id; use either one\n      headimg: \"\"             # data-headimg (official account avatar URL)\n      signature: \"\"           # data-signature\n      service_type: \"2\"       # data-service_type\n  miniprograms:               # {embed:miniprogram:…} text links\n    - title: \"\"               # Matches the placeholder; also used as link text when applink is set\n      appid: \"\"               # Mini Program AppID\n      path: \"pages/index/index\" # Launch path\n      applink: \"\"             # When set, generates a weapp text link\n      image: \"\"               # Thumbnail for legacy mp-miniprogram card (when no applink)\n  miniprogram_cards:          # {embed:miniprogram_card:…} mp-common-miniprogram cards (separate from the above)\n    - title: \"\"               # Matches the placeholder\n      appid: \"\"\n      path: \"pages/index/index\"\n      applink: \"\"\n      card_title: \"\"          # Card title (defaults to title)\n      avatar: \"\"              # Mini Program avatar URL\n      imageurl: \"\"            # Card cover image URL\n      imageurlback: \"\"        # Optional: back-side image URL\n  related_articles:           # Past / related article links (for {embed:link:name}; actual list usually merged from article.yaml's manual)\n    manual:\n       - name: \"第一篇的占位名\"\n         url: \"https://...\"\n       - name: \"第二篇的占位名\"\n         url: \"https://...\"              # Manually pinned article list [{name, url}]; used by {embed:link:name}\n\n# ── Paths ──\ndrafts_root: drafts/          # Local drafts root directory (one subdirectory per article)\npublished_root: posts/published/ # Local published archive directory (for backup / sync; does not affect live content)\nseries_root: series/          # Series / topic root directory (holds series config & assets)\n\n\n# ── Publishing & comments (WeChat credentials in aws.env under WECHAT_N_*; this section only selects method & slot) ──\nENABLE_WECHAT:                # Whether WeChat account is configured; true / false\npublish_method: draft         # draft | published | none; none = no WeChat config, publish.py full skips API calls\nwechat_publish_slot: 1        # Multi-account: which WeChat slot to use (1..wechat_accounts); single account can omit or set 1\nneed_open_comment: 1          # 1 = enable comments on publish; 0 = disable (subject to WeChat backend / API capability)\nonly_fans_can_comment: 0      # 1 = only followers can comment; 0 = everyone can comment (requires comments enabled)\n\n# Whether publishing is complete\npublish_completed: false      # true / false; whether publishing is done\n# Assets and presets are stored under .aws-article/; see .aws-article/README.md\n\n# ── Writing model (third-party LLM) ──\n# Supports any OpenAI-compatible endpoint (official, proxy, or self-hosted)\n# Writing spec: see .aws-article/writing-spec.md (copy from writing-spec.example.md in this directory)\nwriting_model:\n  provider: \"\"                    # Optional; auto-detected from base_url / model if empty (openai | volcengine | qwen | gemini)\n  base_url: \"\"\n  model: \"\"                  # e.g. qwen-plus / qwen-turbo / qwen-max\n  temperature: 0.7\n  max_tokens: 4000\n\n# ── Image generation model ──\n# base_url must be the FULL endpoint path (script detects mode from path suffix):\n#   - https://xxx.com/v1/images/generations   (DALL-E / gpt-image)\n#   - https://xxx.com/v1/chat/completions     (Gemini etc. via proxy)\n#   - Gemini native / Qwen native / Volcengine: use their full endpoint URL\nimage_model:\n  provider: \"\"                    # Optional; auto-detected from base_url path if empty (openai | volcengine | qwen | gemini)\n  base_url: \"\"                    # Full endpoint URL (see examples above)\n  model: \"\"\n  default_size: \"1024x1024\"\n  default_quality: \"standard\"\n  # How to request an aspect ratio on /v1/chat/completions endpoints.\n  #   auto (default) — send Gemini's extra_body.imageConfig only for Gemini-family models\n  #                    (gemini / nano-banana / imagen); other models keep the text hint and\n  #                    get the target ratio by post-generation crop.\n  #   imageconfig    — always send it (for a proxy serving Gemini under a custom model name)\n  #   none           — never send it (for strict gateways that reject unknown body fields)\n  # Ignored by /v1/images/generations, Volcengine and Qwen endpoints, which have their own size params.\n  aspect_mode: auto\n\n# ── WeChat accounts ──\nwechat_accounts: 1                       # Number of WeChat accounts; default 1\nwechat_api_base: \"https://wechat.aiworkskills.cn\"   # WeChat API base URL. Official api.weixin.qq.com enforces an\n                                         # IP allowlist, which blocks calls from a laptop; this\n                                         # reverse proxy avoids that. Set it to\n                                         # https://api.weixin.qq.com to talk to WeChat directly.\nwechat_1_name: \"\"                                                # WeChat account 1 display name\nwechat_2_name: \"\"                                                   # WeChat account 2 display name\n\nFile v1.0.26:references/env.example.yaml\n\n# Key names for aws.env at repo root (this file is valid YAML, for reference only; actual secrets go in aws.env, one KEY=value per line)\n---\n# Writing model (pairs with writing_model in config.yaml)\nWRITING_MODEL_API_KEY: \"\"\n\n# Image model (pairs with image_model in config.yaml)\nIMAGE_MODEL_API_KEY: \"\"\n\n# WeChat official account (slot count determined by wechat_accounts in config.yaml; set to 2 requires filling WECHAT_2_*)\nWECHAT_1_APPID: \"\"\nWECHAT_1_APPSECRET: \"\"\nWECHAT_2_APPID: \"\"\nWECHAT_2_APPSECRET: \"\"\n\nFile v1.0.26:references/first-time-setup.md\n\n# 首次引导 ⛔ BLOCKING\n\n任何操作执行前，必须执行以下 **「检测顺序」** 中的检查步骤。\n\n---\n\n一条龙 / 总览流水线：**先具备仓库根 `aws.env`、`.aws-article/config.yaml`，并通过 `validate_env.py`**，再按总览 [SKILL.md](../SKILL.md) 交互顺序完成 **「2) 全局账号约束」**：**`article_category` / `target_reader` / `default_author` 须由用户确认后再写入** `config.yaml`（**禁止**从某篇 `article.yaml` 擅自抄录），再进入 **「3) 本篇准备」**。\n\n总览规则见 [SKILL.md](../SKILL.md)「配置检查」。\n\n---\n\n## 检测顺序（智能体先判断 OS）\n\n- **Linux / macOS**：下文用 Bash。\n- **Windows**：下文用 PowerShell。\n\n下文命令中的 `{python}` 是**占位符**，须先探测出本机可用的 Python 3 解释器再代入（每次会话探测一次）：\n\n- **Linux / macOS**：`python3 --version` 输出 `Python 3.x.x` → `{python}` = `python3`；不存在则试 `python --version`。\n- **Windows**：`py -3 --version` 输出 `Python 3.x.x` → `{python}` = `py -3 -X utf8`；`py` 不可用则试 `python --version`，通过则用 `python -X utf8`。\n\n⛔ **Windows 上不要探测 `python3`**——未安装 Python 时它是系统预置的应用执行别名，会静默打开 Microsoft Store 而不报错。`-X utf8` 也不可省略，否则脚本的中文输出在简体中文机器上会以 GBK 编码吐出，读到的是乱码。\n\n要求 **Python 3.10+**；版本更低时先提示用户升级。详见 [SKILL.md 第 0 步](../SKILL.md)。\n\n### 1）`.aws-article/config.yaml` 与 `aws.env` 是否存在（仓库根）\n\n```bash\ntest -f .aws-article/config.yaml && test -f aws.env && echo ok || echo missing\n```\n\n```powershell\nif ((Test-Path -LiteralPath \".aws-article\\config.yaml\") -and (Test-Path -LiteralPath \"aws.env\")) { \"ok\" } else { \"missing\" }\n```\n\n⛔ 若为 `missing`，按示例各建一份即可：\n\n1. **`.aws-article/config.yaml`**：复制 **`skills/aws-wechat-article-main/references/config.example.yaml`** 为 **`.aws-article/config.yaml`**。\n2. **`aws.env`**：复制 **`skills/aws-wechat-article-main/references/env.example.yaml`** 为仓库根 **`aws.env`**（内容格式为 `KEY=value`）。\n\n**初始化约束**：新建 **`.aws-article/config.yaml`** 时，**`publish_method` 必须初始化为 `draft`**；除非用户明确指定「不接微信/不走上传」，否则禁止初始化为 `none`。\n\n上述两个文件都创建并保存后，在仓库根运行 **`validate_env.py`**（见下节）。\n\n### 2）`validate_env.py`\n\n在**仓库根**执行：\n\n```bash\n{python} skills/aws-wechat-article-main/scripts/validate_env.py\n```\n\n（默认读取 **`.aws-article/config.yaml`** 与 **`aws.env`**；可用 `--config`、`--env` 指定路径。）\n\n**脚本运行结果**\n\n- **成功（退出码 0）**：输出 **`True`**、**`配置校验通过`**。写作模型、图片模型或 `wechat_N_name` 未配置时会附带警告，但不影响退出码。\n- **失败（退出码 1）**：先输出 **`failed`**，再输出微信必要配置的实际缺失项。\n\n#### 校验失败时的配置引导（必须严格执行）\n\n`validate_env.py` 会完成全部检查后统一输出结果。**当退出码为 1** 时，按实际失败项说明：\n\n环境检查结果：公众号必要配置不完整\n\n1. **必填项**：`wechat_accounts`、`wechat_api_base`，以及每个槽位的 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET`。\n2. **配置方式（二选一，**不要把密钥粘贴到聊天里**）**：\n   - **方式 A（推荐）**：在仓库根用编辑器打开 **`aws.env`** 填入 `WECHAT_1_APPID` / `WECHAT_1_APPSECRET` 等，并在 **`.aws-article/config.yaml`** 填入 `wechat_accounts` / `wechat_api_base` 等非密钥项，保存后告诉我「已填好」我来复检。\n   - **方式 B**：前往平台 **`https://aiworkskills.cn/`** 在网页上配。\n\n**原则**：Agent **不向用户索取密钥**、**不代替用户粘贴密钥到文件**。密钥只由用户在本地编辑器中写入 `aws.env`；validate_env 只做非空校验，不读值外发。\n\n**额外操作**：若用户明确表示不配置微信账号，可将 **`config.yaml`** 中 **`publish_method`** 设为 **`none`**，重跑后跳过微信组校验。写作和图片模型均为可选项。\n\n**⛔ 配置与写稿分两阶段（必须遵守）**\n\n- **`validate_env.py` 退出码 1** 时：**本轮只谈环境配置**——按当前失败分支展示 **环境检查结果 + 三条 + 额外操作** 即可，**结束在该主题**；**禁止**在同一条回复（或同一轮未闭环配置前）里再接：写哪篇文章、是否继续某篇草稿、`drafts/` 路径、选题、定题、`topic-card`、审稿、排版等**任何写稿向流程**。\n- **`validate_env.py` 退出码 0（含可选项警告）** 时：流程**不阻断**，可直接进入下一阶段。\n- **下一阶段**：用户按上文配置引导完成落盘并重跑校验至 **退出码 0** 后，先完成总览 **「2) 全局账号约束」**，再进入 **「3) 本篇准备」**、写稿等。\n  - **在不了解用户是要续写旧稿还是新开一篇时**（含刚闭环配置后接写稿）：须按总览 **「3) 本篇准备」** 开头规则**先问再动**，**禁止**直接假定某一 `drafts/…` 目录并调用写作脚本。\n\n---\n\n## `validate_env.py` 在做什么（摘要）\n\n| 组别 | `config.yaml` | `aws.env` | 缺失时行为 |\n|------|----------------|-----------|------------|\n| 微信公众号 | `wechat_accounts`（≥1）、`wechat_api_base` | `WECHAT_{i}_APPID`、`WECHAT_{i}_APPSECRET` | **阻断**：`failed` + 退出码 1 |\n| 公众号展示名 | `wechat_{i}_name` | — | **警告**，不阻断 |\n| 写作模型 | `writing_model.base_url`、`model`（`provider` 可选） | `WRITING_MODEL_API_KEY` | **警告**，不阻断 |\n| 图片模型 | `image_model.base_url`、`model`（`provider` 可选） | `IMAGE_MODEL_API_KEY` | **警告**，不阻断 |\n\n模型与公众号展示名均为可选项。微信槽位与 AppID/AppSecret 保持原有必填规则；`publish_method: none` 时保持原有的跳过微信组逻辑。\n\n---\n\n## 阻断规则\n\n⛔ **缺少 `.aws-article/config.yaml` 或 `aws.env`**，或 **`validate_env.py` 退出码 1**（微信必要配置不完整）：\n\n- 禁止进入一条龙默认流水线（除非先设 **`publish_method: none`** 并重跑校验通过）。\n- 禁止宣称环境已就绪或一条龙已完成。\n\n写作/图片模型或 `wechat_N_name` 缺失只产生警告，不触发阻断。\n\n---\n\n## 引导流程（简版）\n\n### 第 1 步：说明可选策略\n\n- **环境与密钥**：写作/生图的 **URL 与模型名**在 **`config.yaml`**，**API Key** 在 **`aws.env`**；微信 **AppID/AppSecret** 在 **`aws.env`**，槽位展示名与 **`wechat_api_base`** 等在 **`config.yaml`**。  \n- **`validate_env.py` 退出码 0** 表示微信必要配置已通过，或已通过 **`publish_method: none`** 跳过微信组；写作/图片模型或展示名可带警告通过。发布前建议再运行 **`check-wechat-env`**。\n\n### 第 2 步：检查通过以后检查并创建预设目录（这个必须执行）\n\n通过环境检查后，必须先判断以下目录是否存在；**不存在就立即创建**：\n\n- `.aws-article/presets/structures`\n- `.aws-article/presets/closing-blocks`\n- `.aws-article/presets/title-styles`\n- `.aws-article/presets/formatting`\n- `.aws-article/presets/cover-styles`\n- `.aws-article/presets/image-styles`\n- `.aws-article/presets/sticker-styles`\n- `.aws-article/tmp`\n\n> **业务资料库 `.aws-article/products/{产品名}/`**：**不在首次引导创建**——产品名由用户在写第一份业务介绍时决定，AI 用 Write 工具落库时同时 `mkdir -p` 包括 `images/`，详见 [assets skill 一、业务介绍 .md 入库](../../aws-wechat-article-assets/SKILL.md#一业务介绍-md-入库product-intro)。\n\n可按操作系统执行：\n\n```bash\n# Linux / macOS\nmkdir -p .aws-article/presets/structures .aws-article/presets/closing-blocks \\\n  .aws-article/presets/title-styles .aws-article/presets/formatting \\\n  .aws-article/presets/cover-styles .aws-article/presets/image-styles \\\n  .aws-article/presets/sticker-styles \\\n  .aws-article/tmp\n```\n\n```powershell\n# Windows PowerShell\n$dirs = @(\n  \".aws-article/presets/structures\",\n  \".aws-article/presets/closing-blocks\",\n  \".aws-article/presets/title-styles\",\n  \".aws-article/presets/formatting\",\n  \".aws-article/presets/cover-styles\",\n  \".aws-article/presets/image-styles\",\n  \".aws-article/presets/sticker-styles\",\n  \".aws-article/tmp\"\n)\nforeach ($d in $dirs) {\n  if (-not (Test-Path -LiteralPath $d)) {\n    New-Item -ItemType Directory -Path $d -Force | Out-Null\n  }\n}\n```\n\n### 第 3 步：全局 vs 本篇文件\n\n| 文件 | 时机 | 说明 |\n|------|------|------|\n| **`aws.env`** | 首次 / 改密钥时 | 仓库根；写作/图片 API Key、微信 AppID/AppSecret 等|\n| **`.aws-article/config.yaml`** | 首次 / 改账号策略时 | 文风、模型 endpoint、微信槽位元数据、**`publish_method`** 等 |\n| **`article.yaml`** | 每篇、临近发布 | 本篇标题/作者/摘要/封面等；内含 **`publish_completed`**（新建为 **`false`**，发布闭环结束后再改为 **`true`**，便于发布流程分流）；可用 `skills/aws-wechat-article-publish/scripts/article_init.py` |\n\n首次引导**不**创建某篇目录，只保证 **`config.yaml` + `aws.env` 存在**，且 **`validate_env.py` 退出码 0**（微信必要配置完整，或 **`publish_method: none`**；可选项可带警告通过）。\n\n### 第 4 步：确认并继续\n\n摘要提示用户（勿打印完整密钥）：\n\n- **`validate_env.py` 退出码 0**：环境检测通过，可按总览进入流水线。**要走 `publish.py`（非 none）** 前建议 **`check-wechat-env`**。  \n\n可提示：写作规范可复制 **`skills/aws-wechat-article-main/references/writing-spec.example.md`** → **`.aws-article/writing-spec.md`**；预设见 **`.aws-article/presets/`**。\n\n---\n\n## 非首次运行\n\n**每次**进入一条龙、或**仅**触发写作 / 配图 / 发布检查前，都须在仓库根执行：\n\n```bash\n{python} skills/aws-wechat-article-main/scripts/validate_env.py\n```\n\n**智能体**：若退出码非 0，根据终端 **`failed`** 下列出的汇总句，按上文 **「校验失败时的配置引导」** 文案**原样输出**（含三条配置引导 + **额外操作**）；用户补全并落盘后重跑 **`validate_env.py`**。若用户**明确声明本次例外**，按总览 [SKILL.md](../SKILL.md)「智能体行为约束」处理。**禁止**未获补全或明确例外确认就宣称已通过环境校验或一条龙已完成。**禁止**因「上次已通过」而跳过本节命令。\n\n---\n\n## 每次发文目录与顺序（摘要）\n\n- 目录：`drafts/YYYYMMDD-标题slug/`（`drafts_root` 以 **`config.yaml`** 为准时从其读取，否则默认 `drafts/`）。  \n- 建议内含：`draft.md`、`article.md`、`article.html`、`article.yaml`、`imgs/`、`out/` 等（按需生成）。  \n- 流程：定题 → 选题 → 写稿 → 审 → 排版 → 配图 → 终审 → **按需发布**：**`draft`** / **`published`** / **`none`** 见 schema；**`none`** 时 **`full`** 直接跳过；**`draft`/`published`** 须微信就绪（**`check-wechat-env`**）。  \n\n本篇 **`article.yaml`** 必填项：`title`、`author`、`digest`、`content_source`（默认 `article.html`）、**`publish_completed`**（新建 **`false`**，发布成功后再改为 **`true`**）；**`cover_image`** 强烈建议填写。\n\nArchive v1.0.25: 24 files, 39699 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10465b), references/env.example.yaml (511b), references/first-time-setup.md (15954b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill-card.md (2474b), skill.json (693b), SKILL.md (30201b), _meta.json (143b)\n\nFile v1.0.25:SKILL.md\n\n---\nname: aws-wechat-article-main\ndescription: 公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继续上次的」「接着之前的进度」；**显式模型新写**「用 GPT 写一篇」「用 DeepSeek 写一篇」「把提纲写成文章」。子 skill（topics/writing/review/formatting/images/publish/sticker/assets）单独触发仅限对**已有产物**的修改场景（如\"改标题\"\"润色这段\"\"排版\"\"审稿\"\"加封面\"\"发布\"）；新做/策划/多环节串联一律走本入口。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WRITING_MODEL_API_KEY\n        - IMAGE_MODEL_API_KEY\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 公众号运营总览\n\n**一键式公众号 AI 内容流水线** —— 从选题到上架 8 个子 skill 串联，公众号小编 / 自媒体 / 品牌内容团队一键产出整篇图文。\n\n> **套件说明** · `aws-wechat-article-*` 是公众号一条龙套件，共 9 个 slug：`aws-wechat-article-main / topics / writing / review / formatting / images / publish / assets`，外加 `aws-wechat-sticker`。跨 skill 的相对引用依赖同一 `skills/` 根目录；推荐 `clawhub sync` 或逐个 `clawhub install` 一次性全装。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 作为一条龙套件**编排入口**；真正调用外部 API 的是子 skill（writing / images / publish / sticker / review）。**本入口自身的 `validate_env.py` 脚本**行为：\n\n- **凭证读取**：读取仓库根 `aws.env` 的 `WRITING_MODEL_API_KEY` / `IMAGE_MODEL_API_KEY` / `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`，**仅用于校验键是否存在且非空**，值不用于任何网络请求\n- **网络**：本入口脚本无外发请求；**子 skill 有外发**（详见各子 skill 的能力披露）\n- **文件读**：仓库内 `aws.env`、`.aws-article/config.yaml`、本篇 `article.yaml`\n- **文件写**：仓库内 —— `.aws-article/`（首次引导创建目录结构）、本篇 `article.yaml` 状态字段\n- **shell**：仅 `python3 {baseDir}/scripts/validate_env.py`\n\n> **注意**：整体套件（含子 skill）会调用外部 LLM、图像 API 与微信 API，并在调用时外发 API key 与本篇内容。完整行为见各子 skill 的「能力披露」。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的入口，编排 8 个子 skill：`topics / writing / review / formatting / images / publish / assets` 以及 `aws-wechat-sticker`。\n\n- **装齐全部 9 个 slug** 到同一 `skills/` 根目录，才能走完整一条龙流程（选题→写稿→审稿→排版→配图→发布）。\n- 只装 main 一个时，仍可用于环境校验（`validate_env.py`）；进入内容流水线会因对应子 skill 缺失而无法执行相关步骤（工作流里的跨 skill 脚本调用 / 文档读取会遇到 `file not found`）。\n\n完整 9 slug 清单与安装指引见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。\n\n## 配置检查 ⛔ BLOCKING\n\n**进入交互顺序「2) 全局账号约束」「3) 本篇准备」及内容流水线前**须完成 **第 0～2.5 步**配置检测（任一步失败则 **不得** 继续）。**第 3 步**是**调用 `publish.py` 前**的核对（非流水线起点）：**`.aws-article/config.yaml`** 中 **`publish_method`** 默认为 **`draft`**（**`publish.py full`** 只把图文写入**公众号草稿箱**）；仅当用户明确要求「发出去 / 对外发布」时，再将该键改为 **`published`**（或使用 **`full --publish`** 临时强制发布）。**微信**：**`validate_env.py`** 默认要求公众号账号配齐（见第 2 步）；用户**明确不接微信**时，先将 **`publish_method`** 设为 **`none`** 再过校验（脚本会跳过微信组），之后 **`publish.py full`** 仍直接跳过。要走草稿/发布，须补全 **`aws.env`** 与 **`config.yaml`** 微信槽位，并建议 **`check-wechat-env`**。文风与账号约束以 **`config.yaml`** 为准，发文元数据以本篇 **`article.yaml`** 为准。\n\n### 第 0 步：判断操作系统\n\n智能体在执行下列检测命令前，**先判断当前环境**：\n\n- **Linux / macOS**：使用 Bash 命令（`test`、`echo` 等）。\n- **Windows**：使用 **PowerShell** 命令（`Test-Path` 等）。\n\n### 第 1 步：`.aws-article/config.yaml` 与 `aws.env` 是否存在\n\n在**仓库根目录**（当前工作目录为项目根）执行：\n\n**Linux / macOS：**\n\n```bash\ntest -f .aws-article/config.yaml && test -f aws.env && echo \"ok\" || echo \"missing\"\n```\n\n**Windows（PowerShell）：**\n\n```powershell\nif ((Test-Path -LiteralPath \".aws-article\\config.yaml\") -and (Test-Path -LiteralPath \"aws.env\")) { \"ok\" } else { \"missing\" }\n```\n\n⛔ 输出为 `missing`（任一文件不存在）→ 按 [首次引导](references/first-time-setup.md) 创建或补全：可参考 **`{baseDir}/references/config.example.yaml`** 得到 **`config.yaml`**，在仓库根创建 **`aws.env`**（仅密钥与微信 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 等，键名可与 `{baseDir}/references/env.example.yaml` 对照）。\n\n**初始化约束**：新建 **`.aws-article/config.yaml`** 时，`publish_method` 默认必须为 **`draft`**；除非用户明确指定不接微信，否则禁止初始化或改写为 `none`。\n\n### 第 2 步：校验配置内容（`validate_env.py`）\n\n两文件均存在后，在仓库根运行：\n\n```bash\npython {baseDir}/scripts/validate_env.py\n```\n\n（默认读取 **`.aws-article/config.yaml`** 与 **`aws.env`**；可用 `--config` / `--env` 指定路径。）\n\n脚本检查（规则摘要，具体交互文案统一以 [首次引导](references/first-time-setup.md) 为准）：\n\n- **写作模型**：`config.yaml` 中 `writing_model.base_url` / `model` 与 `aws.env` 中 **`WRITING_MODEL_API_KEY`** 须同时非空（`provider` 可选，不填按 URL/模型名自动识别）；否则 **`failed`** + **`写作模型配置不完整`**，**退出码 1**。\n- **图片模型**：`image_model.base_url` / `model` 与 **`IMAGE_MODEL_API_KEY`** 须同时非空（`provider` 可选，不填按 URL/模型名自动识别）；否则同上，**退出码 1**。\n- **微信公众号**：`wechat_accounts`、`wechat_api_base`、各槽位名与 **`aws.env`** 中 **`WECHAT_{i}_APPID` / `WECHAT_{i}_APPSECRET`** 须成对完整；否则 **`failed`** + **`微信公众号配置不完整`**，**退出码 1**。**例外**：**`config.yaml`** 中 **`publish_method: none`**（用户明确不接微信）时，**跳过**微信组校验，仍输出 **`True`**（并附一行说明已跳过）。\n\n**退出码 0**：写作、图片均通过，且（未声明 **`none`** 时）微信也通过 → **`True`** + **`配置校验通过`**。**退出码 1**：任一组未通过 → 不得进入一条龙默认流水线，并引导 [首次引导](references/first-time-setup.md) 补全或 **`publish_method: none`** 后重跑。\n\n### 第 2.5 步：创建预设与运行目录（硬性前置，必须执行）\n\n**仅当第 2 步退出码为 0** 才执行本步；执行成功后才允许进入「2) 全局账号约束」与后续流水线。  \n目录要求与命令以 [首次引导第 2 步](references/first-time-setup.md) 为准（需覆盖 `presets/*` 与 `tmp`）。**业务资料库 `.aws-article/products/{产品名}/`** 不在本步建——由 AI 写第一份业务介绍时按 [assets skill](../aws-wechat-article-assets/SKILL.md) 自动 mkdir。\n\n- **禁止**因为“环境检查通过”就跳过本步直接写稿。\n- 若目录已存在，可视为本步通过；若缺失，必须立即补建并继续校验。\n\n### 第 3 步：调用 `publish.py` 前（`publish_method` + 微信）\n\n- **`publish_method`**（**`draft`** / **`published`** / **`none`**）写在 **`config.yaml`**，**默认 `draft`**。**`none`** = 用户明确不填微信：**`full`** 不调 API。要「发布出去」→ **`published`** 或 **`full --publish`**。\n- **微信**：在 **`aws.env`**；槽位在 **`config.yaml`**。**`draft`/`published`** 走 **`full`** 前须就绪；**`none`** 下不调用微信。\n- 运行 **`publish.py full`** 前：确认 **`publish_method`** 合法（小写）；**非 `none`** 时建议 **`check-wechat-env`**。\n\n### 智能体行为约束（禁止自作主张）\n\n检测到 **`.aws-article/config.yaml` 或 `aws.env` 缺失**、**`validate_env.py` 退出码 1**（微信配置不完整，且未声明 **`publish_method: none`**），或用户**已要求调用 `publish.py`** 而微信槽位 / 凭证未就绪时：\n\n- **禁止**在未询问用户、未取得用户**明确文字确认**的情况下，自行决定：跳过微信配置、仅出 prompt 却继续宣称「一条龙已完成」、或继续排版/发布并假装配置已就绪。\n- **必须先**：向用户说明**具体缺哪一类**（脚本 **`failed`** 下的 **`微信公众号配置不完整`**；或即将 **`publish.py`** 但微信未配齐），并**统一按** [首次引导](references/first-time-setup.md) 中「校验失败时的配置引导」文案执行。\n- **输出约束**：该场景下除”环境检查结果”可按实际失败项替换外，其余引导文案须与首次引导保持一致。\n- 用户在本地编辑器中填好 `aws.env` 与 `config.yaml` 并保存后，智能体协助重跑 **`validate_env.py`** 复检；若用户明确声明本次例外，按首次引导与本节约束继续处理。\n- **凭证处理原则**：Agent **不得索取、不得接收**用户在对话里粘贴的 `APPSECRET` / `API_KEY` 等任何密钥；所有密钥由用户自己在编辑器里写入 `aws.env`（或通过 `https://aiworkskills.cn/` 平台配置）。Agent 只校验存在性、不读取值、不外发值。\n\n> **模型未配置例外**：写作模型默认阻断；仅当**用户明确同意**由 Agent 代写并传入 `--agent-writing-approved` 时，写作模型未配置才降为警告。图片模型同理，仅在**用户明确同意**使用 Agent 代生图并传入 `--agent-image-capable` 时降为警告；未获用户明确同意时，模型未配置均按阻断处理。须告知用户当前使用的方式。\n\n> **单步子 skill**：用户只触发某一子能力（如仅排版、仅审稿）且**未走本总览流水线**时，仍以各子 skill 内说明为准；**一条龙 / 完整流程 / 从选题到发布** 必须满足本节 BLOCKING 与上条「禁止自作主张」。\n\n## 主要配置文件（不要混用）\n\n| 文件 | 位置 | 作用 |\n|------|------|------|\n| `aws.env` | **仓库根** | **密钥**：写作/图片 `*_API_KEY`、微信 `WECHAT_N_APPID` / `WECHAT_N_APPSECRET` 等（键名见 `references/env.example.yaml`；与 `config.yaml` 一起由 `validate_env.py` 校验） |\n| `.aws-article/config.yaml` | 仓库内 | **非密钥配置**：账号文风、模型 `provider`/`base_url`/`model`、微信槽位数与 `wechat_api_base`、各槽位展示名等（模板见 `references/config.example.yaml`） |\n| `references/env.example.yaml` | 仓库内示例 | **仅文档**：`aws.env` 键名说明 |\n| `references/config.example.yaml` | 仓库内示例 | **仅文档**：`config.yaml` 结构示例 |\n| `article.yaml` | **本篇目录** `drafts/YYYYMMDD-标题slug/` | **发文元数据**（标题/作者/摘要/封面等）及状态字段：**`image_source`**（仅 `generated` / `user`；默认 `generated`，用户上传配图时改为 `user`）与 **`publish_completed`**（新建 **`false`**，发布闭环结束 **`true`**），与 **`config.yaml`** 分工 |\n\n### 发布方式与时间线\n\n1. **账号与发布策略**：**文风、选题边界、`publish_method`（默认 **`draft`**）、微信槽位元数据**等均在 **`.aws-article/config.yaml`** 维护；**密钥**仅在 **`aws.env`**。\n2. **本篇准备**（须先完成交互顺序 **「2) 全局账号约束」**）：在 **定题与 slug** 之后新建 `drafts/YYYYMMDD-标题slug/`，并**优先**创建 **`article.yaml`**（含 **`publish_completed: false`**、标题/作者/摘要等；通常为本目录内**首个**应落盘的文件），再进入内容流水线。\n3. **执行原则（严格顺序）**：必须按下述流水线顺序依次执行，**不能跳过任何部分**；每到一步若缺少必要输入（目录、元数据、主题、用户选择、发布意图等），要**先及时询问用户并获得确认**，再进入下一步，除非用户指出基于某个历史任务继续创作，那么需要智能体根据中间产物判断从哪个阶段开始。\n4. **内容流水线**（子 skill 串行，详见下文 **「交互顺序」第 4 步** 与 **「流程」** 表）：**选题**（[topics](../aws-wechat-article-topics/SKILL.md)）→ **写稿**（[writing](../aws-wechat-article-writing/SKILL.md)）→ **审稿（内容审）**（[review](../aws-wechat-article-review/SKILL.md)）→ **排版**（[formatting](../aws-wechat-article-formatting/SKILL.md)）→ **配图**（[images](../aws-wechat-article-images/SKILL.md)）→ **审稿（终审）**（review）。**内容审**产出的 **`article.md` 定稿须满足 [review 第 5 步](../aws-wechat-article-review/SKILL.md)（文末 **`{embed:…}`**，⛔ BLOCKING）后再排版。全程以 **`.aws-article/config.yaml`** 为账号与文风约束；典型产物依次为 `topic-card.md` / `draft.md` → `article.md` → `article.html` 与 `imgs/` 等。\n5. **发布**（[publish](../aws-wechat-article-publish/SKILL.md)）：**`draft`** → **`full`** 仅**草稿箱**；**`published`** 或 **`full --publish`** → 再**提交发布**；**`none`** → **`full`** **立即跳过**、不调微信。前两档需微信凭证。\n\n**再强调**：**`aws.env`** = 密钥；**`config.yaml`** = 账号/文风/模型与微信元数据及 **`publish_method`**；**本篇 `article.yaml`** = 发文元数据。\n\n## 交互顺序（一步步，最小提问）\n\n按以下顺序与用户交互，**上一步完成再进下一步**；上一环节就绪后再进入下一环节。\n\n### 1) 配置自检（必做）\n\n- 按上文 **配置检查** 完成：**`config.yaml` 与 `aws.env` 均存在** → 运行 **`validate_env.py`**（默认不加 `--agent-image-capable`）**且退出码 0**。**退出码 1** 时按 [首次引导](references/first-time-setup.md) 补全环境；仅当用户**明确表示不接微信**时才可设 **`none`**；走**本次例外**需用户明确书面确认。\n- **`validate_env.py` 退出码 0 后，必须立即执行「第 2.5 步目录创建」**（可复用 [首次引导第 2 步](references/first-time-setup.md) 命令）；该步完成前，**禁止**进入「2) 全局账号约束」与任何写稿流程。\n- **退出码 0 + 模型警告**：流程**不阻断**，可直接进入下一步。模型警告仅在用户已明确同意并传入对应参数时出现：写作模型用 `--agent-writing-approved`，图片模型用 `--agent-image-capable`。\n- **禁止擅自加参数**：未获用户明确同意前，禁止自行追加 `--agent-image-capable` 或宣称可按代生图模式继续。\n- **退出码 1（微信不完整）时**：只展示 [首次引导](references/first-time-setup.md) 中的 **配置选项**，**不要**在同一轮回复里再问「写哪篇 / 继续哪篇草稿 / 新选题」等；须等配置闭环（重跑校验通过或「本次例外」已书面确认）后，**再**进入下方 **「2) 全局账号约束」**。\n- **`validate_env.py` 不检查** `article_category`、`target_reader`、`default_author`；须在 **「2) 全局账号约束」** 中单独检查并落盘。\n\n### 2) 全局账号约束（`.aws-article/config.yaml`）⛔\n\n**在 `validate_env.py` 已通过**（或已按总览完成「本次例外」）**之后、进入「3) 本篇准备」之前**，**必须**打开 **`.aws-article/config.yaml`**，检查下列键 **trim 后是否非空**：\n\n- **`article_category`**、**`target_reader`**、**`default_author`**\n\n任一项缺失或空白：**逐项询问用户**（1.账号领域2.目标读者3.作者名字），取得**用户当轮明确答复**后再**写回** **`.aws-article/config.yaml`**，再进入 **「3) 本篇准备」**。**禁止**仅在对话里口头确认却不写入文件。**禁止**跳过本步直接假定可写稿。\n\n**⛔ 禁止擅自填写（必须写进行为约束）**\n\n- **不得**从本篇或其它目录的 **`article.yaml`**、历史草稿、**`topic-card.md`**、对话记忆或仓库内任意文件**静默抄录、推断或「顺手补全」**后写入 **`article_category` / `target_reader` / `default_author`**。对 **`tone`** 等与账号画像强相关的全局项，要直接询问用户，**同样禁止**未询问就写盘。\n- **允许的做法**：向用户说明「当前为空」，**请用户填写或确认**；若你想根据某篇 `article.yaml` 给**建议**，只能**展示为待选文案**，并问「是否采用 / 要改哪几个字」，**用户明确同意后再写入** `config.yaml`。\n- **顺序**：在尚未完成 **「3) 本篇准备」** 中「续旧 / 新开」的确认前，**禁止**用某一 `drafts/…/article.yaml` **反推**全局三键，避免误把单篇元数据当成整号定位。\n\n### 3) 本篇准备（二选一，默认「新建一篇」）\n\n**在完成「2) 全局账号约束」之后**，**在不了解用户是要续写既有草稿还是新开一篇时**（例如未指定 `drafts/…` 路径、且仓库 **`drafts/`** 下存在进行中目录或多个候选）：**须先询问**并让用户选定 **「继续哪一篇」** 或 **「新开一篇」**，**再**进入下列 A/B 或调用写作脚本。**禁止**默认「最近修改」目录、未确认就运行写作脚本、或假定沿用上一轮路径。\n\n**业务素材双向规则（涉及用户自身业务时强制，详见 [assets skill](../aws-wechat-article-assets/SKILL.md)）**：\n\n- **读**：若本篇涉及用户自家业务（产品/软件/服务），**先 `ls .aws-article/products/`** 看有无相关产品目录，进入后必读根下 `*.md`（业务介绍）作为底稿来源；`images/` 子目录里有现成业务配图则优先复用。\n- **写**：本流程中产生的内容若**语义属于业务介绍**（不是文章主体而是侧重产品/服务自介），由 AI 主动引导用户保存到 `.aws-article/products/{产品名}/{文件名}.md`（用 Write 工具直接落库；目录不存在时同时创建 `images/`），下次涉及业务的文章自动用上。\n\n#### A. 新建一篇（**严格子顺序**，勿跳步）\n\n1. **写作意图** ⛔ **BLOCKING**：必须问清用户 **本篇要写什么**（具体主题、角度、体裁或目标）。若用户只想「帮我出选题」，须**明确确认**后再当无方向模式处理。  \n   - **禁止**在用户未回答本步（且当前对话也未等价说明）之前：**调用 web_search**、**执行 topics 的调研**、**批量生成选题或标题**。  \n   - 用户已在当次对话中说清楚「写什么」的，可本步口头确认一句即可，不必重复盘问。\n2. **定题与 slug**：在写作意图已明确的前提下，确定**发文章标题**——用户从候选中选一个，或**自定义标题**；据此生成 **slug**，目录名为 `YYYYMMDD-标题slug`（slug 规则：小写、连字符、与项目习惯一致即可）。\n3. **建目录与 `article.yaml`**：创建 `{drafts_root}/YYYYMMDD-标题slug/`（`drafts_root` 以 **`config.yaml`** 为准，默认 `drafts/`）。随即初始化本篇 **`article.yaml`**（含 **`publish_completed: false`**，及标题、作者、摘要等；目录内**宜最先写入**；可用 `{baseDir}/../aws-wechat-article-publish/scripts/article_init.py`）。\n   - **`publish_method`**：默认 **`draft`**；要发出去 → **`published`** 或 **`full --publish`**；用户明确不填微信 → **`none`**。\n4. **本篇预设单选落盘（必做）**：初始化后按场景执行：**新建首轮**以 **`.aws-article/config.yaml`** 为来源，按 **`custom_* > default_*`** 结合本篇主题/选题卡，为以下字段各选**单一预设**并写回本篇 **`article.yaml`** 为**单元素列表**：`default_structure`、`default_closing_block`、`default_title_style`、`default_format_preset`、`default_cover_image_style`、`default_article_image_style`、`default_sticker_style`。**续写/重入**时若本篇 `article.yaml` 对应字段已为单元素列表，视为本篇已选并优先保留，不重选不覆盖。若 `config.yaml` 不存在或候选为空，可保持 `[]`。\n5. 至此才进入 **第 4 步内容流水线**。\n\n#### B. 我已有目录\n\n- 用户给出路径。必读 **`.aws-article/config.yaml`**（账号与发布策略）；本篇目录内需有 **`article.yaml`**（或按用户状态后补）。若已有 `article.html`/`cover.jpg` 可直接从流水线中靠后的步骤接入。\n- 若用户意图是「发布后换图并重发草稿箱」，也走本分支：指定既有目录后，从 **配图（用户供图分支）** 接入，再执行 **终审 → 发布**。\n\n### 4) 内容流水线（子 skill）\n\n须已具备 **本篇目录** 与 **`article.yaml`**（「已有目录」分支按上条处理）；账号侧约束以 **`config.yaml`** 为准。\n\n**确认轮次优化**：全局三键已非空时静默通过；`publish_method` 已为合法值时不重复盘问；多个待确认项可合并为一轮提问。用户意图明确时（如给出主题 + \"写一篇文章\"），理想轮次为 **1 轮**（确认标题/摘要）+ **写完后展示结果**。配图方案在用户无特殊要求时按默认风格自动执行，不单独确认。\n\n```\n选题 → 写稿 → 审稿(内容审) → 排版 → 配图 → 审稿(终审)\n```\n\n- **topics**：仅在 **写作意图已明确**（见上 3-A-1）之后执行；仍须遵守 **aws-wechat-article-topics** 中「展示后等用户选」等规则。\n- **writing**：结合 **`.aws-article/config.yaml`** 与 `topic-card.md`（或用户素材）；**`publish_method`** 见 **`config.yaml`**（上文「发布方式与时间线」）；产物 `draft.md` → 内容审后 `article.md`。\n- **review（内容审）**：定稿 **`article.md` 前**须按 [review 第 5 步 ⛔ BLOCKING](../aws-wechat-article-review/SKILL.md) 完成文末 **`{embed:…}`**（或规则允许的省略并留痕）；**未完成不得进入 formatting**。\n- **formatting**：`article.md` → `article.html`（用户当次指定排版主题可覆盖默认）。\n- **images**：按 **aws-wechat-article-images**（配置与行为约束以本节「配置检查」为准）。\n- **review（终审）**：检查 `article.html` 与 `imgs/`；有问题给出清单，等用户确认或修复。\n\n### 5) 发布\n\n- 以 **`config.yaml`** 的 **`publish_method`** 为准；**`draft`** / **`published`** / **`none`** 含义见上文。**`none`** 时运行 **`full`** 会无操作退出。\n- **`draft`/`published`**：**微信**须配齐后再调 **`publish.py`**；建议 **`check-wechat-env`**。**`none`**：不调微信，说明即可。\n- 完成后输出小结与回执，目录按需移至 `published_root`。\n\n### 6) 发布后换图重发（补充分支）\n\n当用户说「草稿箱里图不满意，换我上传的图重新发」：\n\n1. 锁定目标 `drafts/…` 目录；\n2. 将新图放入本篇 `imgs/`，生成/更新 `img_analysis.md`（封面仅 1 张）；\n   - 同步更新本篇 `article.yaml`：`image_source: user`；\n   - 开始重做流程前，将 `publish_completed` 置回 `false`；\n3. 依据分析结果更新 `article.md` 图片映射（允许重排）；\n4. 重新执行 `format.py` 生成 `article.html`；\n5. 终审通过后执行 `publish.py full`（`draft` 写草稿箱）；\n6. 发布命令成功且回执可用后，写回 `publish_completed: true`。\n\n## 流程\n\n```\n选题 → 写稿 → 审稿(内容审) → 排版 → 配图 → 审稿(终审) → 发布\n```\n\n## 中间产物门禁（缺啥补啥）⛔\n\n进入下一步前，必须先检查本步所需中间产物；缺什么就先补什么，禁止跳步并宣称已完成。\n\n| 阶段 | 必要产物（最小集合） | 缺失时动作 |\n|------|----------------------|------------|\n| 写稿完成 | `article.md` 存在且非空 | 继续写稿或回滚到 writing |\n| 排版完成 | `article.html` 存在，且由当前 `article.md` 重新生成 | 先执行 formatting 重转 |\n| 配图完成 | 文章目录存在 `cover.(png/jpg/jpeg/webp)`；`article.md` 与 `article.html` 不含 `placeholder` | 先执行 images 生成并替换（`image_source=user` 时走用户供图映射与重排） |\n| 发布就绪 | `article.yaml` 含 `title/author/digest/content_source`；发布环境检查通过 | 先补齐元数据或环境 |\n| 发布闭环 | 发布命令成功且回执可用 | 才允许写回 `publish_completed: true` |\n\n**禁止**：仅凭单一信号（如“草稿创建成功”）就宣称全流程完成。若正文仍有 `placeholder`，状态必须标记为“草稿已提交，正文配图未完成”。\n\n| 步骤 | 子 skill | 读取 | 产出 |\n|------|---------|------|------|\n| 选题 | topics | **`.aws-article/config.yaml`**、`aws.env`、web_search | `topic-card.md` `research.md` |\n| 写稿 | writing | `topic-card.md`、**`.aws-article/config.yaml`**、`aws.env`（专用写作 API） | `draft.md` |\n| 审稿 | review | `draft.md`、`aws.env`、**`.aws-article/config.yaml`** | `review.md` → `article.md`（定稿须含文末 embed，见 [review 第 5 步](../aws-wechat-article-review/SKILL.md)） |\n| 排版 | formatting | `article.md`、**`.aws-article/config.yaml`** | `article.html` |\n| 配图 | images | `article.md`、`aws.env`、**`.aws-article/config.yaml`** | `imgs/` |\n| 终审 | review | `article.html`、`imgs/`、**`.aws-article/config.yaml`** | `review.md` |\n| 发布 | publish | `article.html`+`imgs/`、**`config.yaml`**、`aws.env`（调用 publish.py 时） | 草稿 media_id / 发布 publish_id、URL、`out/` 记录 |\n\n**账号与文风约束**：以 **`.aws-article/config.yaml`** 为准。\n\n**topics / `web_search`**：须满足上文 **3-A-1**（用户已说明本篇写什么，或已确认「只帮忙出选题」）之后才可调研与生成选题；不得默认跳过提问直接搜索。\n\n> 提示：发布前需就绪本篇 `article.yaml`（标题/作者/摘要/封面等元数据；`content_source` 默认 `article.html`）。可用 `{baseDir}/../aws-wechat-article-publish/scripts/article_init.py` 快速初始化或更新。\n\n## 路由\n\n**默认**：与长文发文相关时 **优先 main**，由本 skill 按步编排；不要因用户说了「写」「选题」「发」就跳过 main 直连子 skill。\n\n**何时直连子 skill**（可跳过 main 入口）：用户**明确只要该步产物**、且不隐含「从零到发出」整条链。例如：已有 `article.md` 只要排版；已有稿只要审稿清单；已有 `article.html`+`imgs/` 只要发布前检查或提交；已有选题卡只要扩写等。\n\n| 用户说法 | 路由到 |\n|---------|--------|\n| 从0开始、从零、从头、一条龙、完整流程、帮我发一篇、发到公众号（含各前置步）、今天发什么/写什么好（要成文并发）、不确定从哪步开始 | **main** |\n| **只要**选题卡、标题、摘要、排期、系列策划（明确不做后续编排） | topics |\n| **只要**在已有选题/大纲/草稿上写稿、改写、润色、续写（明确不要全流程） | writing |\n| **只要**审稿/校对/合规清单（成稿或已定版 HTML） | review |\n| 「能不能发」且含代为发布、或要从稿到发出整条收尾 | **main** |\n| **只要**排版、换主题、转 HTML | formatting |\n| **只要**长文封面/正文配图（有正文或插图位） | images |\n| 贴图、图片消息、多图推送、九宫格（非长文图文链路） | **sticker** |\n| **只要**执行发布/提交/群发（已有约定产物） | publish |\n\n## 运行模式\n\n### 一条龙\n\n用户说「一条龙」「完整流程」时启用。按 **交互顺序** 的 1→2→3→4→5 执行；**3-A** 内子步骤亦须逐步完成。流水线中每步完成后**暂停**等用户确认。审稿有 🔴 项时进入修改循环。\n\n### 单步\n\n用户**明确只要某一步**且已有对应输入产物（或声明不做全流程）时，可仅执行该步骤；若表述含糊、可能还要后续发文，仍从 **main** 问起或按一条龙拆步确认。\n\n### 贴图\n\n路由到独立的 **aws-wechat-sticker** skill。\n\n## 配置与自定义\n\n- **`aws.env`**（仓库根，密钥）与 **`.aws-article/config.yaml`**（非密钥与模型/微信元数据及 **`publish_method`**）：校验 **`{baseDir}/scripts/validate_env.py`**；`aws.env` 键名见 **`references/env.example.yaml`**\n- **`config.yaml` / `article.yaml` / `aws.env` 字段说明**：[references/articlescreening-schema.md](references/articlescreening-schema.md)\n- 发布前微信：**`{baseDir}/../aws-wechat-article-publish/scripts/publish.py check-wechat-env`**（仓库根执行，试换微信 **access_token**；凭证在 **`aws.env`**）\n\nFile v1.0.25:references/presets/closing-blocks/README.md\n\n# 文末区块预设\n\n本目录下的 `.md` 文件为**文末固定引导区块**。写作时按 config 的 `custom_closing_block` > `default_closing_block` 或 config 中的 `closing_block` 字符串加载。\n\n## Schema\n\n- 每个文件为一段 Markdown，用于文章末尾：关注引导、公众号名片、往期推荐、行动号召等。\n- 可使用嵌入标记：`{embed:profile:名称}`、`{embed:miniprogram:名称}`、`{embed:miniprogram_card:名称}`、`{embed:link:名称}`。名片与小程序以 **`.aws-article/config.yaml`** 的 `embeds` 为准；**仅往期链接**可在本篇 `article.yaml` 写 `embeds.related_articles` 与全局合并（详见 [formatting SKILL](../../../../aws-wechat-article-formatting/SKILL.md)）。\n- 文件名即预设名（不含后缀），如 `brand.md` → 预设名 `brand`。在 config 中设置 `default_closing_block` 或 `custom_closing_block`（`custom_*` 优先）即可使用。\n\n## 示例\n\n见 `simple.example.md`。复制后重命名并按需修改。\n\nFile v1.0.25:references/presets/cover-styles/README.md\n\n# 封面配图风格预设（仓库侧说明）\n\n内置封面预设随 **`aws-wechat-article-images`** 提供，路径为 **`references/cover-styles/`**。本目录说明如何在仓库里**扩展或覆盖**封面风格。\n\n## 放置位置\n\n- **日常自定义**：`.aws-article/presets/cover-styles/<名>.md`\n- **`.aws` 预设包**：包内包含 **`cover-styles/`** 目录，由 `import_presets_aws.py` 合并到上述路径。\n\n## 配置键\n\n- **`default_cover_image_style`**：账号级默认候选（YAML 字符串列表）\n- **`custom_cover_image_style`**：非空时覆盖同名 **`default_*`**\n- **本篇 `article.yaml`**：同名键再覆盖全局\n\n合并后须收窄为**单元素列表**再跑配图流程。完整规则见 [articlescreening-schema.md](../../articlescreening-schema.md) 与 **`config.example.yaml`**。\n\n## Schema 与示例\n\n字段结构与内置一致，见 [cover-styles/README.md](../../../../aws-wechat-article-images/references/cover-styles/README.md)。可将本目录下的 `*.example.md` 复制到 `.aws-article/presets/cover-styles/` 后去掉 `.example` 再按需修改。\n\nFile v1.0.25:references/presets/image-styles/README.md\n\n# 正文配图风格预设\n\n本目录下的 `.md` 文件为**正文配图风格预设**。生成正文配图时按 **`custom_article_image_style`**（本篇 **`article.yaml`** > **`config.yaml`**；**须为 YAML 字符串列表**；多候选须在本篇改为**单元素列表**）加载对应 `.md`；未配置时按用户指定或自动推荐。\n\n> **封面风格预设**在 `skills/aws-wechat-article-images/references/cover-styles/`，与正文配图预设分开管理。\n\n## Schema\n\n- 每个文件描述一种视觉风格：风格名、描述、适用场景、**prompt 要点或关键词**（供 Agent/脚本生成图片时使用）。\n- 正文配图风格库见 [styles.md](../../../../aws-wechat-article-images/references/image-styles/styles.md)。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `flat-vector.example.md`。复制后重命名并按需修改。\n\nFile v1.0.25:references/presets/sticker-styles/README.md\n\n# 贴图风格预设\n\n本目录下的 `.md` 文件为**贴图/多图推送风格预设**。创作贴图时按 config 的 `custom_sticker_style` > `default_sticker_style`（`custom_*` 优先）或用户指定加载。\n\n## Schema\n\n- 每个文件描述多图推送的视觉风格与排版偏好：风格名、画面调性、张数建议、配文风格等。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `default.example.md`。复制后重命名并按需修改。\n\nFile v1.0.25:references/presets/structures/README.md\n\n# 文章结构预设\n\n本目录下的 `.md` 文件为**文章结构预设**。写作时按 **`config.yaml`**（及本篇 **`article.yaml`** 覆盖）的 `custom_structure` > `default_structure` 或用户指定加载。\n\n## Schema\n\n- 每个文件为一篇 Markdown，描述**标准结构**：标题、摘要、开头类型、正文小标题与段落节奏、结尾类型、配图密度建议。\n- 可引用 [writing 内置结构模板](../../../aws-wechat-article-writing/references/structure-template.md)，在其基础上做增减或改写。\n- 文件名即预设名（不含后缀），如 `listing.md` → 预设名 `listing`。在 **`config.yaml`** 中写 `default_structure` 或 `custom_structure`（`custom_*` 优先）；多候选时写多项，须在本篇 **`article.yaml`** 同键改为单元素列表后再运行 **`write.py`**（勿用字符串标量）。\n\n## 示例\n\n见 `listing.example.md`。复制为 `listing.md`（或自定义文件名）后按需修改。\n\nFile v1.0.25:references/presets/title-styles/README.md\n\n# 标题风格预设\n\n本目录下的 `.md` 文件为**标题风格预设**。选题生成标题时按 **`custom_title_style`** > **`default_title_style`**（**须为 YAML 字符串列表**；`custom_*` 非空时优先；多候选时由智能体择一，写回本篇 **`article.yaml`** 为**单元素列表**）或用户指定加载。\n\n## Schema\n\n- 每个文件描述一种标题风格：风格名、特点、适用场景、**示例句式或模板**（可含占位符如 XX、N）。\n- 选题 skill 会混合多种风格生成标题候选；若指定本目录下的预设名，则优先按该风格的示例生成。\n- 文件名即预设名（不含后缀）。内置风格见 [title-presets](../../../aws-wechat-article-topics/references/title-presets.md)：悬念型、干货型、数字型、反问型、故事型。\n\n## 示例\n\n见 `suspense.example.md`。复制后重命名并按需修改。\n\nFile v1.0.25:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-main\",\n  \"version\": \"1.0.25\",\n  \"publishedAt\": 1777127794606\n}\n\nFile v1.0.25:references/articlescreening-schema.md\n\n# 配置字段说明（`config.yaml` + `article.yaml`）\n\n**账号与流程级** → **`.aws-article/config.yaml`**；**本篇发文与发布状态** → **`article.yaml`**；**密钥** → 仓库根 **`aws.env`**。\n\n路径与模板：\n\n| 用途 | 路径 | 模板 / 示例 |\n|------|------|-------------|\n| 账号、文风、模型 endpoint、微信元数据、发布方式等 | **`.aws-article/config.yaml`** | **`config.example.yaml`**（同目录） |\n| 本篇标题、摘要、封面、**发布是否完成**等 | **`{drafts_root}/YYYYMMDD-标题slug/article.yaml`** | **`article_init.py` 初稿；字段见下文「本篇 article.yaml 字段」** |\n| API Key、微信 AppID/AppSecret | **`aws.env`**（仓库根） | **`env.example.yaml`**（同目录） |\n\n全局校验与首次引导：[first-time-setup.md](first-time-setup.md)；总览流程：[SKILL.md](../SKILL.md)。\n\n**优先级**：用户当次说法 > 本篇 **`article.yaml`**（仅本篇字段）> **`.aws-article/config.yaml`**（`custom_*` 覆盖 `default_*`）> 各 skill 内置默认。\n\n---\n\n## `.aws-article/config.yaml` 字段（按模板分组）\n\n**完整字段与分组**以仓库内 **`config.example.yaml`**（同目录）为准（含逐行注释）。本文不重复粘贴整段 YAML，避免与模板更新分叉。可按项目在该示例基础上增删键；未出现的键由各子 skill 使用内置默认。\n\n**说明**：**`publish_completed`** 请放在本篇 **`article.yaml`**（见下节），勿写在全局 **`config.yaml`**；若旧稿或历史模板仍把「是否发完」放在 config 里，以 **`article.yaml`** 为准并逐步从 config 中清理。\n\n**配图风格**：**封面**预设目录为 **`cover-styles/`**（内置随 `aws-wechat-article-images` + **`.aws-article/presets/cover-styles/`**）；**正文配图**为 **`presets/image-styles/`** 下同名 `.md`。配置键：**`default_cover_image_style`** / **`default_article_image_style`**（账号默认候选）与 **`custom_cover_image_style`** / **`custom_article_image_style`**（覆盖层）；**`custom_*` 非空时优先于同名 `default_*`**。\n\n**预设候选列表**：**`default_structure`**、**`default_closing_block`**、**`default_title_style`**、**`default_format_preset`**、**`default_cover_image_style`**、**`default_article_image_style`**（及 **`default_sticker_style`**）**须为 YAML 字符串列表**：`[]`、单元素 `[名]`，或多项候选；**多项时**智能体须在本篇 **`article.yaml`** 同键改为**单元素列表**后，再运行 **`write.py`**（结构/文末）与 **`format.py`**（排版主题）。**勿使用字符串标量。** 配图风格字段（`custom_cover_image_style`、`custom_article_image_style` 及对应的 `default_*`）同理。\n\n**`custom_*` 覆盖层**：`default_structure`、`default_closing_block` 等字段均有对应的 `custom_*`（如 `custom_structure`、`custom_format_preset` 等），格式相同。当 `custom_*` 非空时，优先于同名 `default_*`。合并优先级：**`article.yaml` > `custom_*` > `default_*`**；配图风格在解析完上述合并后的列表后，再按 skill 规则从内置与用户 **`cover-styles` / `image-styles`** 目录加载预设文件。\n\n---\n\n## 本篇 `article.yaml` 字段\n\n路径：`{drafts_root}/YYYYMMDD-标题slug/article.yaml`。初始化可用 **`skills/aws-wechat-article-publish/scripts/article_init.py`**。\n\n| 键 | 说明 |\n|----|------|\n| `title` | 文章标题 |\n| `author` | 作者；可空时部分流程会回退 **`config.yaml`** 的 **`default_author`** |\n| `digest` | 摘要（微信 digest 上限 128 字） |\n| `cover_image` | 封面路径或 URL（强烈建议） |\n| `content_source` | 正文 HTML 来源，默认 **`article.html`** |\n| `need_open_comment` | 是否开启留言（与微信能力一致） |\n| `only_fans_can_comment` | 是否仅粉丝可留言 |\n| **`publish_completed`** | **`false`** / **`true`**。新建本篇为 **`false`**；**发布闭环结束后**由智能体改为 **`true`**。**`publish.py` 不读写此键**；用于对话分流与运营备忘。 |\n| **`default_structure`** / **`custom_structure`** 等全局同名预设键 | 可选。与 **`config.yaml`** 合并时**本篇覆盖**（`custom_*` 优先于 `default_*`）；若全局某键为**多元素候选列表**，须在本篇写入**单元素列表** `[名]`，再运行 **`write.py`** / **`format.py`**。 |\n\n---\n\n## `aws.env`（仓库根）\n\n与 **`validate_env.py`**、**`publish.py`** 共用。键名见 **`env.example.yaml`**（同目录）。\n\n| 用途 | 典型键 |\n|------|--------|\n| 写作模型 | `WRITING_MODEL_API_KEY` |\n| 图片模型 | `IMAGE_MODEL_API_KEY` |\n| 微信 | `NUMBER_ACCOUNTS`（与 `publish.py` 一致）、`WECHAT_{i}_NAME`、`WECHAT_{i}_APPID`、`WECHAT_{i}_APPSECRET`、可选 `WECHAT_{i}_API_BASE` |\n\n**`validate_env.py`**（环境检测）：写作、图片、微信**三组**未配齐任一组即 **`failed`**、退出码 1；**`publish_method: none`** 时跳过微信组。详见脚本 docstring。\n\n---\n\n## 发布相关（`publish_method`、`publish_completed`、槽位）\n\n| 键 | 所在文件 | 说明 |\n|----|-----------|------|\n| **`publish_method`** | **`config.yaml`** | **`draft`**（默认）：**`full`** 仅写入**公众号草稿箱**。**`published`**：草稿后再**提交发布**。**`none`**：用户明确不填微信时写入；**`full`** 不调接口、直接跳过。 **`full --publish`** 在 `draft` 下可单次强制发布；**`none`** 下仍会跳过。 |\n| **`publish_completed`** | **`article.yaml`** | 新建 **`false`**；发布真正结束后由智能体写 **`true`**。 |\n| **`wechat_publish_slot`** | **`config.yaml`**（可选） | 多账号时指定本篇默认槽位 **1..N**；与 **`publish.py --account`** 二选一，**命令行优先**。 |\n| 微信凭证 | **`aws.env`** | **`WECHAT_{i}_APPID`** / **`WECHAT_{i}_APPSECRET`** 等；**`validate_env.py`** 默认要求配齐，除非 **`publish_method: none`**。 |\n\nFile v1.0.25:references/config.example.yaml\n\n# Account & workflow config (template)\n# Copy to .aws-article/config.yaml; secrets go in aws.env at repo root (see env.example.yaml in this directory)\n# Per-article metadata & publish_completed go in each article.yaml; field docs: skills/aws-wechat-article-main/references/articlescreening-schema.md\n\n# ── Account & positioning ──\narticle_category:        # Account niche / positioning (e.g. tech / education / lifestyle); affects overall style & topic selection\ntarget_reader: \"\"            # Target reader persona (e.g. college students / beginners / dev managers); determines vocabulary depth & examples\ntone:                    # Tone (casual / professional / formal / sharp / humorous); affects voice & sentence style\nupdate_frequency:        # Publishing frequency (e.g. daily / weekly / biweekly); used for scheduling hints\ndefault_author: \"\"           # Default author name; falls back to this when a single article has no author set\n\n# ── Topics & titles ──\ntopic_direction: \"不写XX\"          # Topic direction or exclusions (e.g. \"avoid XX\" / \"more case studies\"); guides topic generation boundaries\ntitle_style: 干货型          # Title style preset (e.g. practical / story / listicle); preference for title generation\ntitle_max_length: 25         # Max title length (in Chinese characters)\nsummary_length: \"80-128\"     # Target summary word count range (for model prompts & self-check; WeChat digest max 128 chars)\nforbidden_title_phrases: []  # Banned title words / phrases (list); prevents clickbait or sensitive terms\n\n# ── Writing ──\nwriting_style: 口语化        # Writing style (conversational / formal / methodology / case-study / narrative); affects structure & expression\nparagraph_preference: 短段为主 # Paragraph preference (short / long / mixed); affects layout & line breaks\nheading_density: 每节必有小标题 # Subheading density (required per section / moderate / minimal); used for structure validation\ntarget_word_count: \"\"        # Target word count (e.g. \"1800-2500\" or \"2000\"); used for writing & validation\nclosing_block: \"\"            # Global closing block (Markdown string); leave empty if using a preset\nforbidden_words: []          # Banned words list for body text; used in review & self-check\noriginal_attribution: \"\"     # Attribution style (e.g. \"original / authorized reprint / references\")\n\n# ── Preset defaults ──\n# Presets live in .aws-article/presets/{type}/; see each directory's README.md\n# Format: must be YAML string lists. [] = no default; single item = use directly; multiple items = candidate pool —\n#   the agent must narrow to a single-item list in this article's article.yaml before running write.py / format.py\n#   (write validates structure/closing; format validates format_preset). Do not use scalar strings.\n# Priority: article.yaml > custom_* > default_*\ndefault_structure:                # e.g. single or multiple candidates\n  - AI Skill 爆款教程结构\n  - AI Skills 实操爆文结构\ndefault_closing_block: []         # e.g. - brand\ndefault_title_style:\n  - 技术实操指南型\ndefault_format_preset:\n  - 金融蓝\ndefault_cover_image_style: []   # Cover preset names → cover-styles/ (built-in + .aws-article/presets/cover-styles/)\ndefault_article_image_style: [] # Body image preset names → presets/image-styles/\ndefault_sticker_style: []         # e.g. - storyboard; sticker workflow — agent picks one from the list\n\n# ── Custom presets (override defaults) ──\n# Same format as default_*: YAML string lists. When set, takes priority over default_*.\n# article.yaml still takes highest priority over both.\ncustom_structure: []\ncustom_closing_block: []\ncustom_title_style: []\ncustom_format_preset: []\ncustom_cover_image_style: []      # Overrides default_cover_image_style; same paths as default_cover_image_style\ncustom_article_image_style: []    # Overrides default_article_image_style; loads from presets/image-styles/\ncustom_sticker_style: []\n\n# ── Images ──\n# Cover presets: cover-styles/ (separate from body presets/image-styles/). Lists: default_* then custom_* then article.yaml.\nimage_source: generated       # generated | user; user = use uploaded images directly (skip image_create.py)\ncover_aspect: \"2.35:1\"       # Cover image aspect ratio (e.g. 2.35:1 / 1.91:1 / 16:9); used for generation & crop reference\ncover_style: 简约             # Broad preference alongside cover presets; minimal / illustration / photo / brand-color\nimage_density: 每节一图       # In-article image density (one per section / moderate / few / optional)\ncaption_style: 有图注         # Caption style (with captions / no captions / key images only)\nmulti_image_count: 6          # Default image count for multi-image scenarios (for generation or layout reference)\n# Business assets (product intros, screenshots, brand images) go in .aws-article/products/{product-name}/\n\n# ── Review ──\nreview_required:              # Required review checks (checked items appear in self-check / review report)\n  - 敏感词                    # Example: check for sensitive words\n  - 错别字                    # Example: typos / common misspellings\n  - 链接                      # Example: external link format / availability\n  - 原创标注                  # Example: whether original / reprint attribution is present\ncustom_sensitive_words: []    # Custom sensitive words list (overrides the general list)\nreview_output_format: 分块详细 # Review output format (brief / detailed-by-section); affects report presentation\n\n\n# ── Embeds ──\n# Articles can reference {embed:profile:name}, {embed:miniprogram:name}, {embed:miniprogram_card:name}, {embed:link:name}\n# Per-article article.yaml should only set embeds.related_articles (e.g. manual); deep-merged with global related_articles.\n# Do not duplicate profile / miniprogram config in article.yaml.\nembeds:\n  profiles:                   # WeChat official account cards (for {embed:profile:name})\n    - nickname: \"\"            # Matches the placeholder; also used as data-nickname\n      alias: \"\"               # Only for gh_ legacy format; new format uses id/headimg instead\n      id: \"\"                  # data-id (when both id & headimg are set, outputs mp-common-profile)\n      profile_id: \"\"          # Same as id; use either one\n      headimg: \"\"             # data-headimg (official account avatar URL)\n      signature: \"\"           # data-signature\n      service_type: \"2\"       # data-service_type\n  miniprograms:               # {embed:miniprogram:…} text links\n    - title: \"\"               # Matches the placeholder; also used as link text when applink is set\n      appid: \"\"               # Mini Program AppID\n      path: \"pages/index/index\" # Launch path\n      applink: \"\"             # When set, generates a weapp text link\n      image: \"\"               # Thumbnail for legacy mp-miniprogram card (when no applink)\n  miniprogram_cards:          # {embed:miniprogram_card:…} mp-common-miniprogram cards (separate from the above)\n    - title: \"\"               # Matches the placeholder\n      appid: \"\"\n      path: \"pages/index/index\"\n      applink: \"\"\n      card_title: \"\"          # Card title (defaults to title)\n      avatar: \"\"              # Mini Program avatar URL\n      imageurl: \"\"            # Card cover image URL\n      imageurlback: \"\"        # Optional: back-side image URL\n  related_articles:           # Past / related article links (for {embed:link:name}; actual list usually merged from article.yaml's manual)\n    manual:\n       - name: \"第一篇的占位名\"\n         url: \"https://...\"\n       - name: \"第二篇的占位名\"\n         url: \"https://...\"              # Manually pinned article list [{name, url}]; used by {embed:link:name}\n\n# ── Paths ──\ndrafts_root: drafts/          # Local drafts root directory (one subdirectory per article)\npublished_root: posts/published/ # Local published archive directory (for backup / sync; does not affect live content)\nseries_root: series/          # Series / topic root directory (holds series config & assets)\n\n\n# ── Publishing & comments (WeChat credentials in aws.env under WECHAT_N_*; this section only selects method & slot) ──\nENABLE_WECHAT:                # Whether WeChat account is configured; true / false\npublish_method: draft         # draft | published | none; none = no WeChat config, publish.py full skips API calls\nwechat_publish_slot: 1        # Multi-account: which WeChat slot to use (1..wechat_accounts); single account can omit or set 1\nneed_open_comment: 1          # 1 = enable comments on publish; 0 = disable (subject to WeChat backend / API capability)\nonly_fans_can_comment: 0      # 1 = only followers can comment; 0 = everyone can comment (requires comments enabled)\n\n# Whether publishing is complete\npublish_completed: false      # true / false; whether publishing is done\n# Assets and presets are stored under .aws-article/; see .aws-article/README.md\n\n# ── Writing model (third-party LLM) ──\n# Supports any OpenAI-compatible endpoint (official, proxy, or self-hosted)\n# Writing spec: see .aws-article/writing-spec.md (copy from writing-spec.example.md in this directory)\nwriting_model:\n  provider: \"\"                    # Optional; auto-detected from base_url / model if empty (openai | volcengine | qwen | gemini)\n  base_url: \"\"\n  model: \"\"                  # e.g. qwen-plus / qwen-turbo / qwen-max\n  temperature: 0.7\n  max_tokens: 4000\n\n# ── Image generation model ──\n# base_url must be the FULL endpoint path (script detects mode from path suffix):\n#   - https://xxx.com/v1/images/generations   (DALL-E / gpt-image)\n#   - https://xxx.com/v1/chat/completions     (Gemini etc. via proxy)\n#   - Gemini native / Qwen native / Volcengine: use their full endpoint URL\nimage_model:\n  provider: \"\"                    # Optional; auto-detected from base_url path if empty (openai | volcengine | qwen | gemini)\n  base_url: \"\"                    # Full endpoint URL (see examples above)\n  model: \"\"\n  default_size: \"1024x1024\"\n  default_quality: \"standard\"\n\n# ── WeChat accounts ──\nwechat_accounts: 1                       # Number of WeChat accounts; default 1\nwechat_api_base: \"\"                        # WeChat API base URL\nwechat_1_name: \"\"                                                # WeChat account 1 display name\nwechat_2_name: \"\"                                                   # WeChat account 2 display name\n\nFile v1.0.25:references/env.example.yaml\n\n# Key names for aws.env at repo root (this file is valid YAML, for reference only; actual secrets go in aws.env, one KEY=value per line)\n---\n# Writing model (pairs with writing_model in config.yaml)\nWRITING_MODEL_API_KEY: \"\"\n\n# Image model (pairs with image_model in config.yaml)\nIMAGE_MODEL_API_KEY: \"\"\n\n# WeChat official account (slot count determined by wechat_accounts in config.yaml; set to 2 requires filling WECHAT_2_*)\nWECHAT_1_APPID: \"\"\nWECHAT_1_APPSECRET: \"\"\nWECHAT_2_APPID: \"\"\nWECHAT_2_APPSECRET: \"\"\n\nFile v1.0.25:references/first-time-setup.md\n\n# 首次引导 ⛔ BLOCKING\n\n任何操作执行前，必须执行以下 **「检测顺序」** 中的检查步骤。\n\n---\n\n一条龙 / 总览流水线：**先具备仓库根 `aws.env`、`.aws-article/config.yaml`，并通过 `validate_env.py`**，再按总览 [SKILL.md](../SKILL.md) 交互顺序完成 **「2) 全局账号约束」**：**`article_category` / `target_reader` / `default_author` 须由用户确认后再写入** `config.yaml`（**禁止**从某篇 `article.yaml` 擅自抄录），再进入 **「3) 本篇准备」**。\n\n总览规则见 [SKILL.md](../SKILL.md)「配置检查」。\n\n---\n\n## 检测顺序（智能体先判断 OS）\n\n- **Linux / macOS**：下文用 Bash。\n- **Windows**：下文用 PowerShell。\n\n### 1）`.aws-article/config.yaml` 与 `aws.env` 是否存在（仓库根）\n\n```bash\ntest -f .aws-article/config.yaml && test -f aws.env && echo ok || echo missing\n```\n\n```powershell\nif ((Test-Path -LiteralPath \".aws-article\\config.yaml\") -and (Test-Path -LiteralPath \"aws.env\")) { \"ok\" } else { \"missing\" }\n```\n\n⛔ 若为 `missing`，按示例各建一份即可：\n\n1. **`.aws-article/config.yaml`**：复制 **`skills/aws-wechat-article-main/references/config.example.yaml`** 为 **`.aws-article/config.yaml`**。\n2. **`aws.env`**：复制 **`skills/aws-wechat-article-main/references/env.example.yaml`** 为仓库根 **`aws.env`**（内容格式为 `KEY=value`）。\n\n**初始化约束**：新建 **`.aws-article/config.yaml`** 时，**`publish_method` 必须初始化为 `draft`**；除非用户明确指定「不接微信/不走上传」，否则禁止初始化为 `none`。\n\n上述两个文件都创建并保存后，在仓库根运行 **`validate_env.py`**（见下节）。\n\n### 2）`validate_env.py`\n\n在**仓库根**执行：\n\n```bash\npython skills/aws-wechat-article-main/scripts/validate_env.py\n# 仅当用户明确同意按“Agent 代生图”方式继续时，才可加 --agent-image-capable：\npython skills/aws-wechat-article-main/scripts/validate_env.py --agent-image-capable\n# 仅当用户明确同意按“Agent 代写”方式继续时，才可加 --agent-writing-approved：\npython skills/aws-wechat-article-main/scripts/validate_env.py --agent-writing-approved\n```\n\n（默认读取 **`.aws-article/config.yaml`** 与 **`aws.env`**；可用 `--config`、`--env` 指定路径。）\n\n**禁止擅自加参**：运行 `validate_env.py` 默认不加 `--agent-image-capable`。仅当用户明确同意按 Agent 代生图模式继续时，才可加该参数。\n\n**脚本运行结果**\n\n- **成功（退出码 0）**：输出 **`True`**、**`配置校验通过`**。仅当写作/图片模型均已配置，或已获用户明确同意并分别传入 `--agent-writing-approved` / `--agent-image-capable` 时，模型缺失才会以警告形式通过。若 **`publish_method: none`**，会多一行说明已跳过微信公众号校验。\n- **失败（退出码 1）**：先输出 **`failed`**，再按脚本实际结果逐项输出 **`XXX配置不完整`**（如 **`微信公众号配置不完整`**、**`图片模型配置不完整`**、**`写作模型配置不完整`**）。后续引导文案必须与已输出项一致，禁止固定复读微信话术。\n\n#### 校验失败时的配置引导（必须严格执行）\n\n`validate_env.py` 不会在“公众号未配置”处提前停止；会先完成全部检查，再统一输出结果。\n\n**当 `validate_env.py` 退出码为 1** 时，按当前失败项使用以下话术：\n\n**A. 仅公众号未配置**，这一类**必须**使用这个话术：\n\n环境检查结果：公众号配置不完整\n\n1. **微信配置（必填）**：填好微信配置后，我才能帮您将文章发送到草稿箱。  \n2. **配置方式（二选一，**不要把密钥粘贴到聊天里**）**：\n   - **方式 A（推荐）**：在仓库根用编辑器打开 **`aws.env`** 填入 `WECHAT_1_APPID` / `WECHAT_1_APPSECRET` 等，并在 **`.aws-article/config.yaml`** 填入 `wechat_accounts` / `wechat_api_base` / `wechat_1_name` 等非密钥项，保存后告诉我「已填好」我来复检。\n   - **方式 B**：前往平台 **`https://aiworkskills.cn/`** 在网页上配。\n\n**B. 仅模型相关未配置**，这一类**必须**使用这个话术：\n\n环境检查结果：按本次 `failed` 实际输出填写（例如：`图片模型配置不完整`）\n\n1. **<失败项对应模型>配置（选填）**：配置claude、GPT、banana等专用模型有助于生成更好的文章；若您不想配置，我将使用相同的写作约束亲自执行后续流程。  \n2. **配置方式（二选一，**不要把密钥粘贴到聊天里**）**：\n   - **方式 A（推荐）**：在仓库根用编辑器打开 **`aws.env`** 填入 `*_API_KEY`，并在 **`.aws-article/config.yaml`** 填入 `base_url` / `model` 等非密钥项，保存后告诉我「已填好」我来复检。\n   - **方式 B**：前往平台 **`https://aiworkskills.cn/`** 在网页上配。\n\n**C. 公众号 + 模型同时未配置**，这一类**必须**使用这个话术：\n\n环境检查结果：公众号配置不完整；<失败项对应模型>配置不完整\n\n1. **微信配置（必填）**：填好微信配置后，我才能帮您将文章发送到草稿箱。  \n2. **<失败项对应模型>配置（选填）**：配置claude、GPT、banana等专用模型有助于生成更好的文章；若您不想配置，我将使用相同的写作约束亲自执行后续流程。  \n3. **配置方式（二选一，推荐任一个，**不要把密钥粘贴到聊天里**）**：\n   - **方式 A（推荐）**：在仓库根用编辑器打开 **`aws.env`** 自行填入密钥（见下方字段说明），保存后告诉我「已填好」我来复检。\n   - **方式 B**：前往平台 **`https://aiworkskills.cn/`** 在网页 UI 配置（含写作/生图模型、微信公众号、结构/配图预设等）。\n\n**用户追问「怎么配置？」时（按当前失败项回复）**\n\n- 仅公众号未配置：\n  > 公众号需要 `WECHAT_1_APPID`、`WECHAT_1_APPSECRET`（在 `aws.env`），以及 `wechat_accounts`、`wechat_1_name`、`wechat_api_base`（在 `config.yaml`）。  \n  > **请在编辑器里自己填到 aws.env 和 config.yaml；不要在这里把密钥复制给我**。填完告诉我「已填好」我跑 `validate_env.py` 复检。或者去 `https://aiworkskills.cn/` 在网页上配。\n- 仅模型相关未配置：\n  > 按当前模型项所需字段（`base_url`、`model` 在 `config.yaml`；`*_API_KEY` 在 `aws.env`）。**请在编辑器里自己填，不要在对话里提供密钥。**\n- 公众号与模型都未配置：**同上两条合并提示**，请用户编辑两份文件后回来。\n\n**原则**：Agent **不向用户索取密钥**、**不代替用户粘贴密钥到文件**。密钥只由用户在本地编辑器中写入 `aws.env`；validate_env 只做非空校验，不读值外发。\n\n**额外操作**：若用户明确表示仅仅不配置微信账号，可将 **`config.yaml`** 中 **`publish_method`** 设为 **`none`**，不发布到草稿箱。（改后须在仓库根重跑 **`python skills/aws-wechat-article-main/scripts/validate_env.py`** 方生效。这句话不输出给用户）\n\n**注意**：写作模型未配置默认**阻断流程**。仅当**用户明确同意**后传入 `--agent-writing-approved` 才降为警告（退出码 0）；图片模型同理，仅当**用户明确同意**后传入 `--agent-image-capable` 才降为警告（退出码 0）。未传入对应参数时仍为阻断（退出码 1）。\n\n**⛔ 配置与写稿分两阶段（必须遵守）**\n\n- **`validate_env.py` 退出码 1** 时：**本轮只谈环境配置**——按当前失败分支展示 **环境检查结果 + 三条 + 额外操作** 即可，**结束在该主题**；**禁止**在同一条回复（或同一轮未闭环配置前）里再接：写哪篇文章、是否继续某篇草稿、`drafts/` 路径、选题、定题、`topic-card`、审稿、排版等**任何写稿向流程**。\n- **`validate_env.py` 退出码 0（含模型警告）** 时：流程**不阻断**，可直接进入下一阶段。模型警告仅在用户已明确同意并传入对应参数时出现。\n- **下一阶段**：用户按上文配置引导完成落盘并重跑校验至 **退出码 0**，或明确声明「不配置微信，按本次例外由智能体继续」并按总览 [SKILL.md](../SKILL.md) 完成 **「本次例外」** 书面确认后，**从下一轮对话起**先完成总览 **「2) 全局账号约束」**，再进入 **「3) 本篇准备」**、写稿等。\n  - **在不了解用户是要续写旧稿还是新开一篇时**（含刚闭环配置后接写稿）：须按总览 **「3) 本篇准备」** 开头规则**先问再动**，**禁止**直接假定某一 `drafts/…` 目录并调用写作脚本。\n\n---\n\n## `validate_env.py` 在做什么（摘要）\n\n| 组别 | `config.yaml` | `aws.env` | 缺失时行为 |\n|------|----------------|-----------|------------|\n| 写作模型 | `writing_model.base_url`、`model`（`provider` 可选） | `WRITING_MODEL_API_KEY` | 默认**阻断**；仅在用户明确同意并传入 `--agent-writing-approved` 时为**警告** |\n| 图片模型 | `image_model.base_url`、`model`（`provider` 可选） | `IMAGE_MODEL_API_KEY` | 取决于 `--agent-image-capable`：传入则**警告**，未传则**阻断** |\n| 微信公众号 | `wechat_accounts`（≥1）、`wechat_api_base`、`wechat_{i}_name` | `WECHAT_{i}_APPID`、`WECHAT_{i}_APPSECRET` | **阻断**：`failed` + 退出码 1 |\n\n写作模型未配置默认**阻断**；仅当用户明确同意并传入 `--agent-writing-approved` 时为**警告**。图片模型同理，仅当用户明确同意并传入 `--agent-image-capable` 时为**警告**，否则为**阻断**；微信组缺失则 **`failed`** 且退出码 1。**例外**：**`config.yaml`** 中 **`publish_method: none`** 时**不校验**微信组。\n\n---\n\n## 阻断规则\n\n⛔ **缺少 `.aws-article/config.yaml` 或 `aws.env`**，或 **`validate_env.py` 退出码 1**（微信配置不完整 / 图片模型配置不完整 / 二者同时）：\n\n- 禁止进入一条龙默认流水线（除非用户按总览 SKILL 明确声明「本次例外」，或先设 **`publish_method: none`** 并重跑校验通过）。\n- 禁止宣称环境已就绪或一条龙已完成。\n\n**写作模型未配置默认触发阻断**：仅当用户明确同意并传入 `--agent-writing-approved` 时，`validate_env.py` 才会以警告通过；`write.py prompt` 可在不调用模型的情况下产出提示词 JSON，Agent 据此代写。**图片模型**：仅当用户明确同意并传入 `--agent-image-capable` 时才降为警告，否则仍阻断。\n\n**不接微信**：将 **`publish_method`** 设为 **`none`** 后重跑 **`validate_env.py`**，可跳过微信组校验；**`publish.py full`** 仍按 **`none`** 直接跳过。\n\n---\n\n## 引导流程（简版）\n\n### 第 1 步：说明可选策略\n\n- **环境与密钥**：写作/生图的 **URL 与模型名**在 **`config.yaml`**，**API Key** 在 **`aws.env`**；微信 **AppID/AppSecret** 在 **`aws.env`**，槽位展示名与 **`wechat_api_base`** 等在 **`config.yaml`**。  \n- **`validate_env.py` 退出码 0** 表示环境检测通过：**写作 + 图片 + 微信** 均完整，或已声明 **`publish_method: none`**（跳过微信组）。要走 **`publish.py`**（**非 none**），须微信已在校验中通过；建议 **`check-wechat-env`**。\n\n### 第 2 步：检查通过以后检查并创建预设目录（这个必须执行）\n\n通过环境检查后，必须先判断以下目录是否存在；**不存在就立即创建**：\n\n- `.aws-article/presets/structures`\n- `.aws-article/presets/closing-blocks`\n- `.aws-article/presets/title-styles`\n- `.aws-article/presets/formatting`\n- `.aws-article/presets/cover-styles`\n- `.aws-article/presets/image-styles`\n- `.aws-article/presets/sticker-styles`\n- `.aws-article/tmp`\n\n> **业务资料库 `.aws-article/products/{产品名}/`**：**不在首次引导创建**——产品名由用户在写第一份业务介绍时决定，AI 用 Write 工具落库时同时 `mkdir -p` 包括 `images/`，详见 [assets skill 一、业务介绍 .md 入库](../../aws-wechat-article-assets/SKILL.md#一业务介绍-md-入库product-intro)。\n\n可按操作系统执行：\n\n```bash\n# Linux / macOS\nmkdir -p .aws-article/presets/structures .aws-article/presets/closing-blocks \\\n  .aws-article/presets/title-styles .aws-article/presets/formatting \\\n  .aws-article/presets/cover-styles .aws-article/presets/image-styles \\\n  .aws-article/presets/sticker-styles \\\n  .aws-article/tmp\n```\n\n```powershell\n# Windows PowerShell\n$dirs = @(\n  \".aws-article/presets/structures\",\n  \".aws-article/presets/closing-blocks\",\n  \".aws-article/presets/title-styles\",\n  \".aws-article/presets/formatting\",\n  \".aws-article/presets/cover-styles\",\n  \".aws-article/presets/image-styles\",\n  \".aws-article/presets/sticker-styles\",\n  \".aws-article/tmp\"\n)\nforeach ($d in $dirs) {\n  if (-not (Test-Path -LiteralPath $d)) {\n    New-Item -ItemType Directory -Path $d -Force | Out-Null\n  }\n}\n```\n\n### 第 3 步：全局 vs 本篇文件\n\n| 文件 | 时机 | 说明 |\n|------|------|------|\n| **`aws.env`** | 首次 / 改密钥时 | 仓库根；写作/图片 API Key、微信 AppID/AppSecret 等|\n| **`.aws-article/config.yaml`** | 首次 / 改账号策略时 | 文风、模型 endpoint、微信槽位元数据、**`publish_method`** 等 |\n| **`article.yaml`** | 每篇、临近发布 | 本篇标题/作者/摘要/封面等；内含 **`publish_completed`**（新建为 **`false`**，发布闭环结束后再改为 **`true`**，便于发布流程分流）；可用 `skills/aws-wechat-article-publish/scripts/article_init.py` |\n\n首次引导**不**创建某篇目录，只保证 **`config.yaml` + `aws.env` 存在**，且 **`validate_env.py` 退出码 0**（三组完整，或 **`publish_method: none`**）。用户明确不填微信 → 先设 **`none`** 再过校验。\n\n### 第 4 步：确认并继续\n\n摘要提示用户（勿打印完整密钥）：\n\n- **`validate_env.py` 退出码 0**：环境检测通过，可按总览进入流水线。**要走 `publish.py`（非 none）** 前建议 **`check-wechat-env`**。  \n\n可提示：写作规范可复制 **`skills/aws-wechat-article-main/references/writing-spec.example.md`** → **`.aws-article/writing-spec.md`**；预设见 **`.aws-article/presets/`**。\n\n---\n\n## 非首次运行\n\n**每次**进入一条龙、或**仅**触发写作 / 配图 / 发布检查前，都须在仓库根执行：\n\n```bash\npython skills/aws-wechat-article-main/scripts/validate_env.py\n```\n\n**智能体**：若退出码非 0，根据终端 **`failed`** 下列出的汇总句，按上文 **「校验失败时的配置引导」** 文案**原样输出**（含三条配置引导 + **额外操作**）；用户补全并落盘后重跑 **`validate_env.py`**。若用户**明确声明本次例外**，按总览 [SKILL.md](../SKILL.md)「智能体行为约束」处理。**禁止**未获补全或明确例外确认就宣称已通过环境校验或一条龙已完成。**禁止**因「上次已通过」而跳过本节命令。\n\n---\n\n## 每次发文目录与顺序（摘要）\n\n- 目录：`drafts/YYYYMMDD-标题slug/`（`drafts_root` 以 **`config.yaml`** 为准时从其读取，否则默认 `drafts/`）。  \n- 建议内含：`draft.md`、`article.md`、`article.html`、`article.yaml`、`imgs/`、`out/` 等（按需生成）。  \n- 流程：定题 → 选题 → 写稿 → 审 → 排版 → 配图 → 终审 → **按需发布**：**`draft`** / **`published`** / **`none`** 见 schema；**`none`** 时 **`full`** 直接跳过；**`draft`/`published`** 须微信就绪（**`check-wechat-env`**）。  \n\n本篇 **`article.yaml`** 必填项：`title`、`author`、`digest`、`content_source`（默认 `article.html`）、**`publish_completed`**（新建 **`false`**，发布成功后再改为 **`true`**）；**`cover_image`** 强烈建议填写。\n\nArchive v1.0.24: 23 files, 38675 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10465b), references/env.example.yaml (511b), references/first-time-setup.md (16454b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill.json (693b), SKILL.md (30201b), _meta.json (143b)\n\nFile v1.0.24:SKILL.md\n\n---\nname: aws-wechat-article-main\ndescription: 公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继续上次的」「接着之前的进度」；**显式模型新写**「用 GPT 写一篇」「用 DeepSeek 写一篇」「把提纲写成文章」。子 skill（topics/writing/review/formatting/images/publish/sticker/assets）单独触发仅限对**已有产物**的修改场景（如\"改标题\"\"润色这段\"\"排版\"\"审稿\"\"加封面\"\"发布\"）；新做/策划/多环节串联一律走本入口。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WRITING_MODEL_API_KEY\n        - IMAGE_MODEL_API_KEY\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 公众号运营总览\n\n**一键式公众号 AI 内容流水线** —— 从选题到上架 8 个子 skill 串联，公众号小编 / 自媒体 / 品牌内容团队一键产出整篇图文。\n\n> **套件说明** · `aws-wechat-article-*` 是公众号一条龙套件，共 9 个 slug：`aws-wechat-article-main / topics / writing / review / formatting / images / publish / assets`，外加 `aws-wechat-sticker`。跨 skill 的相对引用依赖同一 `skills/` 根目录；推荐 `clawhub sync` 或逐个 `clawhub install` 一次性全装。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 作为一条龙套件**编排入口**；真正调用外部 API 的是子 skill（writing / images / publish / sticker / review）。**本入口自身的 `validate_env.py` 脚本**行为：\n\n- **凭证读取**：读取仓库根 `aws.env` 的 `WRITING_MODEL_API_KEY` / `IMAGE_MODEL_API_KEY` / `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`，**仅用于校验键是否存在且非空**，值不用于任何网络请求\n- **网络**：本入口脚本无外发请求；**子 skill 有外发**（详见各子 skill 的能力披露）\n- **文件读**：仓库内 `aws.env`、`.aws-article/config.yaml`、本篇 `article.yaml`\n- **文件写**：仓库内 —— `.aws-article/`（首次引导创建目录结构）、本篇 `article.yaml` 状态字段\n- **shell**：仅 `python3 {baseDir}/scripts/validate_env.py`\n\n> **注意**：整体套件（含子 skill）会调用外部 LLM、图像 API 与微信 API，并在调用时外发 API key 与本篇内容。完整行为见各子 skill 的「能力披露」。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的入口，编排 8 个子 skill：`topics / writing / review / formatting / images / publish / assets` 以及 `aws-wechat-sticker`。\n\n- **装齐全部 9 个 slug** 到同一 `skills/` 根目录，才能走完整一条龙流程（选题→写稿→审稿→排版→配图→发布）。\n- 只装 main 一个时，仍可用于环境校验（`validate_env.py`）；进入内容流水线会因对应子 skill 缺失而无法执行相关步骤（工作流里的跨 skill 脚本调用 / 文档读取会遇到 `file not found`）。\n\n完整 9 slug 清单与安装指引见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。\n\n## 配置检查 ⛔ BLOCKING\n\n**进入交互顺序「2) 全局账号约束」「3) 本篇准备」及内容流水线前**须完成 **第 0～2.5 步**配置检测（任一步失败则 **不得** 继续）。**第 3 步**是**调用 `publish.py` 前**的核对（非流水线起点）：**`.aws-article/config.yaml`** 中 **`publish_method`** 默认为 **`draft`**（**`publish.py full`** 只把图文写入**公众号草稿箱**）；仅当用户明确要求「发出去 / 对外发布」时，再将该键改为 **`published`**（或使用 **`full --publish`** 临时强制发布）。**微信**：**`validate_env.py`** 默认要求公众号账号配齐（见第 2 步）；用户**明确不接微信**时，先将 **`publish_method`** 设为 **`none`** 再过校验（脚本会跳过微信组），之后 **`publish.py full`** 仍直接跳过。要走草稿/发布，须补全 **`aws.env`** 与 **`config.yaml`** 微信槽位，并建议 **`check-wechat-env`**。文风与账号约束以 **`config.yaml`** 为准，发文元数据以本篇 **`article.yaml`** 为准。\n\n### 第 0 步：判断操作系统\n\n智能体在执行下列检测命令前，**先判断当前环境**：\n\n- **Linux / macOS**：使用 Bash 命令（`test`、`echo` 等）。\n- **Windows**：使用 **PowerShell** 命令（`Test-Path` 等）。\n\n### 第 1 步：`.aws-article/config.yaml` 与 `aws.env` 是否存在\n\n在**仓库根目录**（当前工作目录为项目根）执行：\n\n**Linux / macOS：**\n\n```bash\ntest -f .aws-article/config.yaml && test -f aws.env && echo \"ok\" || echo \"missing\"\n```\n\n**Windows（PowerShell）：**\n\n```powers\n\nArchive v1.0.23: 23 files, 38454 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10465b), references/env.example.yaml (511b), references/first-time-setup.md (15954b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill.json (693b), SKILL.md (30201b), _meta.json (143b)\n\nArchive v1.0.22: 23 files, 37943 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10438b), references/env.example.yaml (511b), references/first-time-setup.md (16013b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill.json (693b), SKILL.md (29286b), _meta.json (143b)\n\nArchive v1.0.21: 23 files, 37862 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10438b), references/env.example.yaml (511b), references/first-time-setup.md (16013b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill.json (693b), SKILL.md (29018b), _meta.json (143b)\n\nArchive v1.0.20: 23 files, 37390 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10438b), references/env.example.yaml (511b), references/first-time-setup.md (14683b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill.json (693b), SKILL.md (28761b), _meta.json (143b)\n\nArchive v1.0.19: 23 files, 37318 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10438b), references/env.example.yaml (511b), references/first-time-setup.md (14683b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill.json (693b), SKILL.md (28536b), _meta.json (143b)\n\nArchive v1.0.18: 23 files, 37282 bytes\n\nFiles: references/articlescreening-schema.md (5989b), references/config.example.yaml (10438b), references/env.example.yaml (511b), references/first-time-setup.md (14683b), references/presets/closing-blocks/README.md (1011b), references/presets/closing-blocks/simple.example.md (66b), references/presets/cover-styles/README.md (1111b), references/presets/cover-styles/简约.example.md (656b), references/presets/image-styles/flat-vector.example.md (345b), references/presets/image-styles/README.md (881b), references/presets/review-rules.example.yaml (489b), references/presets/sticker-styles/default.example.md (244b), references/presets/sticker-styles/README.md (476b), references/presets/structures/listing.example.md (604b), references/presets/structures/README.md (976b), references/presets/title-styles/emotion.example.md (665b), references/presets/title-styles/README.md (898b), references/presets/title-styles/suspense.example.md (334b), references/writing-spec.example.md (1191b), scripts/validate_env.py (7498b), skill.json (693b), SKILL.md (28609b), _meta.json (143b)","readmeExcerpt":"Skill: aws-wechat-article-main Owner: aiworkskills Summary: 公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"python3 --version"},{"language":"powershell","snippet":"py -3 --version"},{"language":"bash","snippet":"test -f .aws-article/config.yaml && test -f aws.env && echo \"ok\" || echo \"missing\""},{"language":"powershell","snippet":"if ((Test-Path -LiteralPath \".aws-article\\config.yaml\") -and (Test-Path -LiteralPath \"aws.env\")) { \"ok\" } else { \"missing\" }"},{"language":"bash","snippet":"{python} {baseDir}/scripts/validate_env.py"},{"language":"text","snippet":"选题 → 写稿 → 审稿(内容审) → 排版 → 配图 → 审稿(终审)"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: aws-wechat-article-main\ndescription: 公众号运营｜微信公众号｜公众号一条龙｜公众号全流程｜自媒体运营｜wechat automation｜content pipeline｜AIGC workflow — 公众号一条龙运营总控入口，选题→写稿→审稿→排版→配图→发布串联 8 个子 skill，单条指令完成整篇图文从 0 到上架。面向公众号小编、自媒体、品牌内容。触发词分层：**一条龙流程**「一条龙」「完整流程」「从头做」「从 0 到发布」；**新做新发**「帮我写篇公众号文章」「做一篇公众号文章」「我想发一篇」「帮我发一篇」「再来一篇」；**选题起点**「今天写什么好」「有什么好写的」「找个话题」「爆款选题」「热点选题」「起个爆款标题」；**策划起点**「内容日历」「系列策划」「专栏规划」「连载」；**流程恢复**「接着上次那篇」「继续昨天的」「继续上次的」「接着之前的进度」；**显式模型新写**「用 GPT 写一篇」「用 DeepSeek 写一篇」「把提纲写成文章」。子 skill（topics/writing/review/formatting/images/publish/sticker/assets）单独触发仅限对**已有产物**的修改场景（如\"改标题\"\"润色这段\"\"排版\"\"审稿\"\"加封面\"\"发布\"）；新做/策划/多环节串联一律走本入口。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env:\n        - WRITING_MODEL_API_KEY\n        - IMAGE_MODEL_API_KEY\n        - WECHAT_1_APPID\n        - WECHAT_1_APPSECRET\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 公众号运营总览\n\n**一键式公众号 AI 内容流水线** —— 从选题到上架 8 个子 skill 串联，公众号小编 / 自媒体 / 品牌内容团队一键产出整篇图文。\n\n> **套件说明** · `aws-wechat-article-*` 是公众号一条龙套件，共 9 个 slug：`aws-wechat-article-main / topics / writing / review / formatting / images / publish / assets`，外加 `aws-wechat-sticker`。跨 skill 的相对引用依赖同一 `skills/` 根目录；推荐 `clawhub sync` 或逐个 `clawhub install` 一次性全装。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 作为一条龙套件**编排入口**；真正调用外部 API 的是子 skill（writing / images / publish / sticker / review）。**本入口自身的 `validate_env.py` 脚本**行为：\n\n- **凭证读取**：读取仓库根 `aws.env` 的 `WRITING_MODEL_API_KEY` / `IMAGE_MODEL_API_KEY` / `WECHAT_{N}_APPID` / `WECHAT_{N}_APPSECRET`，**仅用于校验键是否存在且非空**，值不用于任何网络请求\n- **网络**：本入口脚本无外发请求；**子 skill 有外发**（详见各子 skill 的能力披露）\n- **文件读**：仓库内 `aws.env`、`.aws-article/config.yaml`、本篇 `article.yaml`\n- **文件写**：仓库内 —— `.aws-article/`（首次引导创建目录结构）、本篇 `article.yaml` 状态字段\n- **shell**：仅 `{python} {baseDir}/scripts/validate_env.py`（`{python}` = 本机 Python 3 解释器，由下文**第 0 步**探测得出：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n> **注意**：整体套件（含子 skill）会调用外部 LLM、图像 API 与微信 API，并在调用时外发 API key 与本篇内容。完整行为见各子 skill 的「能力披露」。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的入口，编排 8 个子 skill：`topics / writing / review / formatting / images / publish / assets` 以及 `aws-wechat-sticker`。\n\n- **装齐全部 9 个 slug** 到同一 `skills/` 根目录，才能走完整一条龙流程（选题→写稿→审稿→排版→配图→发布）。\n- 只装 main 一个时，仍可用于环境校验（`validate_env.py`）；进入内容流水线会因对应子 skill 缺失而无法执行相关步骤（工作流里的跨 skill 脚本调用 / 文档读取会遇到 `file not found`）。\n\n完整 9 slug 清单与安装指引见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。\n\n## 配置检查 ⛔ BLOCKING\n\n**进入交互顺序「2) 全局账号约束」「3) 本篇准备」及内容流水线前**须完成 **第 0～2.5 步**配置检测（任一步失败则 **不得** 继续）。**第 3 步**是**调用 `publish.py` 前**的核对（非流水线起点）：**`.aws-article/config.yaml`** 中 **`publish_method`** 默认为 **`draft`**（**`publish.py full`** 只把图文写入**公众号草稿箱**）；仅当用户明确要求「发出去 / 对外发布」时，再将该键改为 **`published`**（或使用 **`full --publish`** 临时强制发布）。**微信**：**`validate_env.py`** 默认要求公众号账号配齐（见第 2 步）；用户**明确不接微信**时，先将 **`publish_method`** 设为 **`none`"},{"path":"references/presets/closing-blocks/README.md","content":"# 文末区块预设\n\n本目录下的 `.md` 文件为**文末固定引导区块**。写作时按 config 的 `custom_closing_block` > `default_closing_block` 或 config 中的 `closing_block` 字符串加载。\n\n## Schema\n\n- 每个文件为一段 Markdown，用于文章末尾：关注引导、公众号名片、往期推荐、行动号召等。\n- 可使用嵌入标记：`{embed:profile:名称}`、`{embed:miniprogram:名称}`、`{embed:miniprogram_card:名称}`、`{embed:link:名称}`。名片与小程序以 **`.aws-article/config.yaml`** 的 `embeds` 为准；**仅往期链接**可在本篇 `article.yaml` 写 `embeds.related_articles` 与全局合并（详见 [formatting SKILL](../../../../aws-wechat-article-formatting/SKILL.md)）。\n- 文件名即预设名（不含后缀），如 `brand.md` → 预设名 `brand`。在 config 中设置 `default_closing_block` 或 `custom_closing_block`（`custom_*` 优先）即可使用。\n\n## 示例\n\n见 `simple.example.md`。复制后重命名并按需修改。"},{"path":"references/presets/cover-styles/README.md","content":"# 封面配图风格预设（仓库侧说明）\n\n内置封面预设随 **`aws-wechat-article-images`** 提供，路径为 **`references/cover-styles/`**。本目录说明如何在仓库里**扩展或覆盖**封面风格。\n\n## 放置位置\n\n- **日常自定义**：`.aws-article/presets/cover-styles/<名>.md`\n- **`.aws` 预设包**：包内包含 **`cover-styles/`** 目录，由 `import_presets_aws.py` 合并到上述路径。\n\n## 配置键\n\n- **`default_cover_image_style`**：账号级默认候选（YAML 字符串列表）\n- **`custom_cover_image_style`**：非空时覆盖同名 **`default_*`**\n- **本篇 `article.yaml`**：同名键再覆盖全局\n\n合并后须收窄为**单元素列表**再跑配图流程。完整规则见 [articlescreening-schema.md](../../articlescreening-schema.md) 与 **`config.example.yaml`**。\n\n## Schema 与示例\n\n字段结构与内置一致，见 [cover-styles/README.md](../../../../aws-wechat-article-images/references/cover-styles/README.md)。可将本目录下的 `*.example.md` 复制到 `.aws-article/presets/cover-styles/` 后去掉 `.example` 再按需修改。"},{"path":"references/presets/image-styles/README.md","content":"# 正文配图风格预设\n\n本目录下的 `.md` 文件为**正文配图风格预设**。生成正文配图时按 **`custom_article_image_style`**（本篇 **`article.yaml`** > **`config.yaml`**；**须为 YAML 字符串列表**；多候选须在本篇改为**单元素列表**）加载对应 `.md`；未配置时按用户指定或自动推荐。\n\n> **封面风格预设**在 `skills/aws-wechat-article-images/references/cover-styles/`，与正文配图预设分开管理。\n\n## Schema\n\n- 每个文件描述一种视觉风格：风格名、描述、适用场景、**prompt 要点或关键词**（供 Agent/脚本生成图片时使用）。\n- 正文配图风格库见 [styles.md](../../../../aws-wechat-article-images/references/image-styles/styles.md)。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `flat-vector.example.md`。复制后重命名并按需修改。"},{"path":"references/presets/sticker-styles/README.md","content":"# 贴图风格预设\n\n本目录下的 `.md` 文件为**贴图/多图推送风格预设**。创作贴图时按 config 的 `custom_sticker_style` > `default_sticker_style`（`custom_*` 优先）或用户指定加载。\n\n## Schema\n\n- 每个文件描述多图推送的视觉风格与排版偏好：风格名、画面调性、张数建议、配文风格等。\n- 文件名即预设名（不含后缀）。\n\n## 示例\n\n见 `default.example.md`。复制后重命名并按需修改。"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":826,"uniquenessScore":43,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T07:43:04.445Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T07:43:04.445Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T10:43:55.081Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}