{"id":"007dc288-6df6-41ea-9ca0-fd089e69ec6c","entityType":"agent","slug":"clawhub-aiworkskills-aws-wechat-article-assets","name":"公众号素材库 & 预设包","canonicalUrl":"https://www.xpersona.co/agent/clawhub-aiworkskills-aws-wechat-article-assets","canonicalPath":"/agent/clawhub-aiworkskills-aws-wechat-article-assets","generatedAt":"2026-10-10T17:35:50.069Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T14:51:27.986Z","emptyReason":null},"description":"公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 `product_image_ingest.py --product <产品名> --stem <中文名>`。导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。 Skill: 公众号素材库 & 预设包 Owner: aiworkskills Summary: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 .aws-article/products/{产品名}/（介绍 .md 直挂产品根 + 配图归 images/ 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 product_image_ingest.py --product <产品名> --stem <中文名>。导入 .aws ZIP 预设包（本地文件或 https://aiworkskills.cn/**/*.aws URL）合并主题/配色/字体配置到 .aws-article/presets/；config.yaml 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s170f08a9xbhfkfp1vjv33y1ph842r9a:aws-wechat-article-assets","sourceUrl":"https://clawhub.ai/aiworkskills/aws-wechat-article-assets","homepage":"https://clawhub.ai/aiworkskills/skills/aws-wechat-article-assets","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/aiworkskills/aws-wechat-article-assets","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/aiworkskills/skills/aws-wechat-article-assets","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:51:27.986Z","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-10T14:51:27.986Z","emptyReason":null},"stars":null,"forks":null,"downloads":1375,"packageName":null,"latestVersion":"1.0.25","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T14:51:27.985Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T14:51:27.986Z","lastCrawledAt":"2026-10-10T14:51:27.985Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T14:51:27.985Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.25","createdAt":"2026-09-06T07:25:03.477Z","changelog":"业务图入库改走 .aws-article/products/{产品名}/images/（stock_image_ingest.py → product_image_ingest.py，--product 必填）；修预设包导入不完整的 bug；支持 https://*.aiworkskills.cn 的 .aws URL 导入；统一 {python} 解释器占位符。","fileCount":6,"zipByteSize":18409},{"version":"1.0.24","createdAt":"2026-04-25T14:18:40.783Z","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":6,"zipByteSize":18290},{"version":"1.0.23","createdAt":"2026-04-24T13:04:20.708Z","changelog":"引入 .aws-article/products/{产品名}/ 业务资料库：涉及自家产品的写稿/配图前先查 products/；AI 生成的业务介绍引导保存到 products/{产品名}/*.md。assets 的图片入库脚本重命名 stock_image_ingest.py → product_image_ingest.py（按产品分目录）。","fileCount":5,"zipByteSize":14813},{"version":"1.0.22","createdAt":"2026-04-22T23:24:29.612Z","changelog":"软化版套件完整性提示：说明工作流会读跨 skill 共享文档、单独安装时会 file-not-found；纯信息性语气，无 shell 循环、无 Agent 强指令","fileCount":5,"zipByteSize":12760},{"version":"1.0.21","createdAt":"2026-04-22T22:47:48.492Z","changelog":"修 import_presets_aws.py 的 ZIP slip 漏洞：新增 _safe_extractall 逐项校验成员路径（拒绝绝对路径、.. 段、解析后指向解压目录外）；SKILL.md 披露","fileCount":5,"zipByteSize":12609},{"version":"1.0.20","createdAt":"2026-04-22T22:36:01.594Z","changelog":"修 scanner 精准点名：移除'不外传/不读仓库外'假陈述；补凭证/内容外发披露；sticker+review 补 WECHAT 凭证声明；空 env 的 skill 移除 primaryEnv；3 个脚本不再遍历父目录","fileCount":5,"zipByteSize":12081},{"version":"1.0.19","createdAt":"2026-04-22T16:36:38.657Z","changelog":"能力披露：frontmatter 加 metadata.openclaw.requires；body 加 Capabilities 段；降温前置依赖块（去 shell 循环与强指令语气）；article_init.py 不再读 Path.home()","fileCount":5,"zipByteSize":11747},{"version":"1.0.18","createdAt":"2026-04-22T15:53:39.054Z","changelog":"清理 tags 只留 latest；frontmatter 加 homepage+url；main/publish 加 automation 关键词","fileCount":5,"zipByteSize":11878}]},"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-assets","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"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-assets/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/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-10T17:35:50.067Z"}},"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-assets/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-aiworkskills-aws-wechat-article-assets/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":"high","updatedAt":"2026-10-10T14:51:27.986Z","emptyReason":null},"readme":"Skill: 公众号素材库 & 预设包\n\nOwner: aiworkskills\n\nSummary: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 `product_image_ingest.py --product <产品名> --stem <中文名>`。导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\n\nTags: assets:1.0.17, chinese:1.0.17, claude-code:1.0.17, latest:1.0.25, media-library:1.0.17, presets:1.0.17, wechat:1.0.17\n\nVersion history:\n\nv1.0.25 | 2026-09-06T07:25:03.477Z | user\n\n业务图入库改走 .aws-article/products/{产品名}/images/（stock_image_ingest.py → product_image_ingest.py，--product 必填）；修预设包导入不完整的 bug；支持 https://*.aiworkskills.cn 的 .aws URL 导入；统一 {python} 解释器占位符。\n\nv1.0.24 | 2026-04-25T14:18:40.783Z | 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:04:20.708Z | 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:24:29.612Z | user\n\n软化版套件完整性提示：说明工作流会读跨 skill 共享文档、单独安装时会 file-not-found；纯信息性语气，无 shell 循环、无 Agent 强指令\n\nv1.0.21 | 2026-04-22T22:47:48.492Z | user\n\n修 import_presets_aws.py 的 ZIP slip 漏洞：新增 _safe_extractall 逐项校验成员路径（拒绝绝对路径、.. 段、解析后指向解压目录外）；SKILL.md 披露\n\nv1.0.20 | 2026-04-22T22:36:01.594Z | user\n\n修 scanner 精准点名：移除'不外传/不读仓库外'假陈述；补凭证/内容外发披露；sticker+review 补 WECHAT 凭证声明；空 env 的 skill 移除 primaryEnv；3 个脚本不再遍历父目录\n\nv1.0.19 | 2026-04-22T16:36:38.657Z | user\n\n能力披露：frontmatter 加 metadata.openclaw.requires；body 加 Capabilities 段；降温前置依赖块（去 shell 循环与强指令语气）；article_init.py 不再读 Path.home()\n\nv1.0.18 | 2026-04-22T15:53:39.054Z | user\n\n清理 tags 只留 latest；frontmatter 加 homepage+url；main/publish 加 automation 关键词\n\nv1.0.17 | 2026-04-22T08:45:37.659Z | user\n\n加前置依赖检查：任一 skill 启动前要求 9 个套件全装，否则停止工作流\n\nv1.0.16 | 2026-04-22T05:13:43.735Z | user\n\n压缩 description 做 SEO 密度优化\n\nv1.0.15 | 2026-04-22T04:50:10.169Z | user\n\nSEO 优化：补关键词/友好名/价值主张/GitHub 链接\n\nv1.0.14 | 2026-04-22T04:35:20.972Z | user\n\n对齐 git tag v1.0.14\n\nv1.0.0 | 2026-04-22T04:25:32.810Z | auto\n\naws-wechat-article-assets v1.0.0\n\n- Initial release with image asset library and preset bundle import features for WeChat article workflows.\n- Supports uploading images to `.aws-article/assets/stock/images/` with auto-generated or agent-provided Markdown descriptions.\n- Enables importing `.aws` (ZIP) preset bundles, merging folders into `.aws-article/presets/`, following intelligent directory conflict resolution.\n- Handles `config.yaml` import logic: copies only if missing, otherwise outputs key-by-key diff as JSON without overwriting existing config.\n- Introduces two main scripts: `stock_image_ingest.py` (image ingestion) and `import_presets_aws.py` (preset bundle import).\n\nArchive index:\n\nArchive v1.0.25: 6 files, 18409 bytes\n\nFiles: scripts/import_presets_aws.py (18384b), scripts/product_image_ingest.py (5423b), skill-card.md (2381b), skill.json (745b), SKILL.md (15136b), _meta.json (145b)\n\nFile v1.0.25:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 `product_image_ingest.py --product <产品名> --stem <中文名>`。导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n---\n\n# 用户业务资料库与预设（Assets）\n\n**业务资料按产品名分目录** — `.aws-article/products/{产品名}/` 直挂业务介绍 `.md`、`images/` 存配图（含同名说明 `.md`）。**写涉及用户自身业务的文章/配图前必须先查这里；新生成的业务介绍内容应引导用户保存到这里**。预设包合并到 `.aws-article/presets/`。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地业务资料库与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件（脚本边界）；AI 在引导业务介绍入库时会先 `ls .aws-article/products/` 看已有产品名\n- **文件写**：仓库内 `.aws-article/products/{产品名}/*.md`（业务介绍，AI 用 Write 工具直接落库）、`.aws-article/products/{产品名}/images/*`（图片 + 同名 `.md`，由脚本写）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）；导入 `.aws` 时**仓库根 `aws.env`** 会按映射表增量写入密钥字段（覆盖现有键前自动备份为 `aws.env.bak.{ts}`，stderr 仅打印键名不打印值）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`。**已内置 ZIP slip 防御**：逐项校验 ZIP 成员路径，拒绝含绝对路径、`..` 段或解析后指向解压目录外的路径，任一违反立即退出不写入任何文件\n- **shell**：仅 `{python} {baseDir}/scripts/product_image_ingest.py`、`import_presets_aws.py`（`{python}` = 本机 Python 3 解释器，见 [main SKILL 第 0 步](../aws-wechat-article-main/SKILL.md)：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**业务资料库与预设环节**（入口 `aws-wechat-article-main`）。\n\n- **单独安装可用**：业务图入库 / `.aws` 预设导入两个脚本都不依赖兄弟 skill，只要 `.aws-article/` 目录就能工作。\n- 其他 skill 读取 `.aws-article/products/{产品名}/`（业务介绍 + `images/`）和 `.aws-article/presets/` 里由本 skill 管理的资源，属套件协同；需结合写稿/配图/排版等 skill 使用。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **业务介绍 .md 入库** | AI 与用户对话产出业务介绍内容时，引导/响应保存到 `products/{产品名}/<文件名>.md`（用 Write 工具直接落库，无脚本） |\n| **业务图入库** | 用户业务图 → `products/{产品名}/images/`（脚本 `--product` 必填），供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 〇、设计意图（必读）⛔\n\n`.aws-article/products/{产品名}/` 是**用户自家业务**（卖货 / 卖软件 / 卖服务 / 自媒体 IP 等）的**资料库**——既是 AI 写涉及业务的内容时的**底稿来源**，也是 AI 与用户协作产出新介绍时的**保存目的地**。\n\n### 目录约定\n\n```\n.aws-article/products/{产品名}/\n├─ 项目介绍.md                # 业务介绍 .md 直挂产品根（命名按用户行业，如 服务介绍.md / 品牌介绍.md）\n├─ (其他业务文档.md)\n└─ images/\n   ├─ 配置首页.png\n   └─ 配置首页.md             # 图片说明 .md（同名）\n```\n\n### 双向触发\n\n| 方向 | 触发条件 | 行为 |\n|------|---------|------|\n| **读** | 当前任务涉及用户自家业务（对外介绍 / 教程 / 案例 / 自家业务安利 / 业务相关配图） | 先 `ls .aws-article/products/`，识别本篇相关产品，读该产品根下 `*.md`、查 `images/` 同名 `.md`，把已有素材作为底稿/配图候选 |\n| **写** | AI 在会话中刚生成或改写的内容**语义属于用户业务介绍** | 走 [一、业务介绍 .md 入库](#一业务介绍-md-入库product-intro)；用户主动说\"保存为产品介绍\"等也走此流程 |\n\n### 反例（不要触发）\n\n- 主题是行业资讯 / 通用教程 / 与用户业务无关 → 不读、不写\n- 用户明确表示内容\"还没定型\" → 不主动引导保存\n- AI 不确定是不是用户自家业务时 → 宁可不主动提，也不要乱塞进 `products/`\n\n---\n\n## 一、业务介绍 .md 入库（Product Intro）\n\n无需脚本，AI 用 Write 工具直接落库。\n\n### 触发模式 A：AI 主动识别 + 引导\n\nAI 在任意会话中刚生成或刚改写了一段内容，**其语义明确属于用户自家业务介绍**（产品 / 服务 / 品牌 / 项目 / 团队 / 业务范围介绍）时，主动提示用户：\n\n> \"这段是 [产品名] 的业务介绍，要不要保存到产品资料库？我可以存到 `.aws-article/products/{产品名}/{文件名}.md`，下次写涉及业务的文章时会自动用上。\"\n\n用户确认 → 走「保存流程」。\n\n### 触发模式 B：用户主动指令\n\n用户说类似 \"保存为产品介绍 / 业务介绍 / 服务介绍 / 自家介绍 / 入库到产品 / 存到产品资料库\" 时，AI 把当前会话中的目标内容（用户指定段落或最近相关产出）走「保存流程」。\n\n### 保存流程\n\n1. **确认产品名**：`ls .aws-article/products/`，已有目录则提示复用；新产品则向用户拿名字\n2. **确认文件名**：默认 `项目介绍.md`；可改为 `产品介绍.md` / `服务介绍.md` / `品牌介绍.md` / `业务介绍.md` 等贴用户行业的命名\n3. **创建目录**：`mkdir -p .aws-article/products/{产品名}/images/`（即便暂为空，把骨架建齐）\n4. **写入文件**：用 Write 工具落到 `.aws-article/products/{产品名}/{文件名}.md`\n5. **反馈**：「已存到 `<完整路径>`，下次涉及 [产品名] 业务的文章会自动用上」\n\n---\n\n## 二、业务图入库（Product Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/products/{产品名}/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径，并指明**所属产品**（与 `products/` 下某个目录对应；新产品则脚本会自动创建）。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `配置首页`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\n{python} {baseDir}/scripts/product_image_ingest.py <源图片路径> \\\n  --product \"公众号AI运营助手\" --stem \"配置首页\" \\\n  --content \"客观中文描述，一两句即可\"\n```\n\n`--product` **必填**；产品目录与 `images/` 子目录不存在时**自动创建**。\n\n4. 生成 `配置首页.png` + `配置首页.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`product_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/products/公众号AI运营助手/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `product_image_ingest.py`\n\n- `source`、`--product`（**必填**）、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 三、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **`config.yaml` 中的密钥字段会被增量写入仓库根 `aws.env`**。包内 `config.yaml` 顶层 `wechat_appid` / `wechat_appsecret`、嵌套 `writing_model.api_key` / `image_model.api_key` 在导入时按下表映射写入：\n\n  | `config.yaml` 字段 | `aws.env` 键 |\n  |---|---|\n  | `wechat_appid` | `WECHAT_1_APPID` |\n  | `wechat_appsecret` | `WECHAT_1_APPSECRET` |\n  | `writing_model.api_key` | `WRITING_MODEL_API_KEY` |\n  | `image_model.api_key` | `IMAGE_MODEL_API_KEY` |\n\n- 写入策略：包内字段为空 → 不动 `aws.env` 现有键；`aws.env` 无该键 → 追加；已有相同值 → 跳过；已有不同值 → 写入前备份 `aws.env.bak.{ts}` 后覆盖。stderr 仅输出键名清单，不打印密钥值；保留原文件顺序、空行与注释。当前前端导出仅支持单微信账号（固定槽位 1），`aws.env` 中的 `WECHAT_2_*` 等其他键不受导入影响。\n- `config.yaml`（运营配置）：本地无则首次复制；本地有则差异 JSON 输出到 stdout 不覆盖（与原行为一致），由 Agent 询问用户确认后手改。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\n{python} {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\n{python} {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\n{python} {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\n{python} {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `product_image_ingest.py` | `{baseDir}/scripts/product_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 业务介绍 .md 入库 | `.aws-article/products/{产品名}/{文件名}.md`（AI 用 Write 工具落库；目录不存在时同时 mkdir 包括 `images/`） |\n| 业务图入库 | `.aws-article/products/{产品名}/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；密钥增量写入仓库根 `aws.env`（覆盖前备份 `aws.env.bak.{ts}`）；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.25:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.25\",\n  \"publishedAt\": 1788679503477\n}\n\nFile v1.0.25:skill-card.md\n\n## Description:\n\n公众号素材库 & 预设包 helps agents manage WeChat article business materials, product images, and .aws preset packages under .aws-article/.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[aiworkskills](https://clawhub.ai/user/aiworkskills)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal content operators, brand teams, and design-support users use this skill to store business descriptions and product images by product, then import .aws preset bundles for WeChat article production workflows.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The preset importer can update aws.env with credential-like values from a bundle config.\n\nMitigation: Inspect the .aws bundle and run a dry run first; avoid running the importer in repositories containing real API keys or WeChat credentials until the user has confirmed the expected changes.\n\nRisk: Configuration diffs printed to stdout may expose sensitive values in logs.\n\nMitigation: Run imports only in controlled terminals, redact captured logs, and avoid shared logging environments unless the config-diff output is fixed or redacted.\n\nRisk: The importer can download .aws bundles and includes a debug flag that relaxes host validation.\n\nMitigation: Use only HTTPS aiworkskills.cn bundle URLs for normal use and avoid --allow-any-host outside controlled testing.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/aiworkskills/skills/aws-wechat-article-assets)\n- [Publisher profile](https://clawhub.ai/user/aiworkskills)\n- [aiworkskills homepage](https://aiworkskills.cn)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON configuration diffs]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Can guide agents to write local Markdown/image asset files under .aws-article/ and run bundled Python scripts that may update .aws-article/ and aws.env.]\n\n## Skill Version(s):\n\n1.0.25 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.0.25:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"用户业务资料库（按产品名分目录于 .aws-article/products/{产品名}/，介绍 .md 直挂产品根 + images/ 配图含同名 .md）+ 预设包管理；业务图入库 product_image_ingest.py（--product 必填）；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"products\", \"business-assets\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.24: 6 files, 18290 bytes\n\nFiles: scripts/import_presets_aws.py (18384b), scripts/product_image_ingest.py (5423b), skill-card.md (2637b), skill.json (745b), SKILL.md (14955b), _meta.json (145b)\n\nFile v1.0.24:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 `product_image_ingest.py --product <产品名> --stem <中文名>`。导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n---\n\n# 用户业务资料库与预设（Assets）\n\n**业务资料按产品名分目录** — `.aws-article/products/{产品名}/` 直挂业务介绍 `.md`、`images/` 存配图（含同名说明 `.md`）。**写涉及用户自身业务的文章/配图前必须先查这里；新生成的业务介绍内容应引导用户保存到这里**。预设包合并到 `.aws-article/presets/`。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地业务资料库与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件（脚本边界）；AI 在引导业务介绍入库时会先 `ls .aws-article/products/` 看已有产品名\n- **文件写**：仓库内 `.aws-article/products/{产品名}/*.md`（业务介绍，AI 用 Write 工具直接落库）、`.aws-article/products/{产品名}/images/*`（图片 + 同名 `.md`，由脚本写）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）；导入 `.aws` 时**仓库根 `aws.env`** 会按映射表增量写入密钥字段（覆盖现有键前自动备份为 `aws.env.bak.{ts}`，stderr 仅打印键名不打印值）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`。**已内置 ZIP slip 防御**：逐项校验 ZIP 成员路径，拒绝含绝对路径、`..` 段或解析后指向解压目录外的路径，任一违反立即退出不写入任何文件\n- **shell**：仅 `python3 {baseDir}/scripts/product_image_ingest.py`、`import_presets_aws.py`\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**业务资料库与预设环节**（入口 `aws-wechat-article-main`）。\n\n- **单独安装可用**：业务图入库 / `.aws` 预设导入两个脚本都不依赖兄弟 skill，只要 `.aws-article/` 目录就能工作。\n- 其他 skill 读取 `.aws-article/products/{产品名}/`（业务介绍 + `images/`）和 `.aws-article/presets/` 里由本 skill 管理的资源，属套件协同；需结合写稿/配图/排版等 skill 使用。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **业务介绍 .md 入库** | AI 与用户对话产出业务介绍内容时，引导/响应保存到 `products/{产品名}/<文件名>.md`（用 Write 工具直接落库，无脚本） |\n| **业务图入库** | 用户业务图 → `products/{产品名}/images/`（脚本 `--product` 必填），供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 〇、设计意图（必读）⛔\n\n`.aws-article/products/{产品名}/` 是**用户自家业务**（卖货 / 卖软件 / 卖服务 / 自媒体 IP 等）的**资料库**——既是 AI 写涉及业务的内容时的**底稿来源**，也是 AI 与用户协作产出新介绍时的**保存目的地**。\n\n### 目录约定\n\n```\n.aws-article/products/{产品名}/\n├─ 项目介绍.md                # 业务介绍 .md 直挂产品根（命名按用户行业，如 服务介绍.md / 品牌介绍.md）\n├─ (其他业务文档.md)\n└─ images/\n   ├─ 配置首页.png\n   └─ 配置首页.md             # 图片说明 .md（同名）\n```\n\n### 双向触发\n\n| 方向 | 触发条件 | 行为 |\n|------|---------|------|\n| **读** | 当前任务涉及用户自家业务（对外介绍 / 教程 / 案例 / 自家业务安利 / 业务相关配图） | 先 `ls .aws-article/products/`，识别本篇相关产品，读该产品根下 `*.md`、查 `images/` 同名 `.md`，把已有素材作为底稿/配图候选 |\n| **写** | AI 在会话中刚生成或改写的内容**语义属于用户业务介绍** | 走 [一、业务介绍 .md 入库](#一业务介绍-md-入库product-intro)；用户主动说\"保存为产品介绍\"等也走此流程 |\n\n### 反例（不要触发）\n\n- 主题是行业资讯 / 通用教程 / 与用户业务无关 → 不读、不写\n- 用户明确表示内容\"还没定型\" → 不主动引导保存\n- AI 不确定是不是用户自家业务时 → 宁可不主动提，也不要乱塞进 `products/`\n\n---\n\n## 一、业务介绍 .md 入库（Product Intro）\n\n无需脚本，AI 用 Write 工具直接落库。\n\n### 触发模式 A：AI 主动识别 + 引导\n\nAI 在任意会话中刚生成或刚改写了一段内容，**其语义明确属于用户自家业务介绍**（产品 / 服务 / 品牌 / 项目 / 团队 / 业务范围介绍）时，主动提示用户：\n\n> \"这段是 [产品名] 的业务介绍，要不要保存到产品资料库？我可以存到 `.aws-article/products/{产品名}/{文件名}.md`，下次写涉及业务的文章时会自动用上。\"\n\n用户确认 → 走「保存流程」。\n\n### 触发模式 B：用户主动指令\n\n用户说类似 \"保存为产品介绍 / 业务介绍 / 服务介绍 / 自家介绍 / 入库到产品 / 存到产品资料库\" 时，AI 把当前会话中的目标内容（用户指定段落或最近相关产出）走「保存流程」。\n\n### 保存流程\n\n1. **确认产品名**：`ls .aws-article/products/`，已有目录则提示复用；新产品则向用户拿名字\n2. **确认文件名**：默认 `项目介绍.md`；可改为 `产品介绍.md` / `服务介绍.md` / `品牌介绍.md` / `业务介绍.md` 等贴用户行业的命名\n3. **创建目录**：`mkdir -p .aws-article/products/{产品名}/images/`（即便暂为空，把骨架建齐）\n4. **写入文件**：用 Write 工具落到 `.aws-article/products/{产品名}/{文件名}.md`\n5. **反馈**：「已存到 `<完整路径>`，下次涉及 [产品名] 业务的文章会自动用上」\n\n---\n\n## 二、业务图入库（Product Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/products/{产品名}/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径，并指明**所属产品**（与 `products/` 下某个目录对应；新产品则脚本会自动创建）。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `配置首页`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/product_image_ingest.py <源图片路径> \\\n  --product \"公众号AI运营助手\" --stem \"配置首页\" \\\n  --content \"客观中文描述，一两句即可\"\n```\n\n`--product` **必填**；产品目录与 `images/` 子目录不存在时**自动创建**。\n\n4. 生成 `配置首页.png` + `配置首页.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`product_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/products/公众号AI运营助手/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `product_image_ingest.py`\n\n- `source`、`--product`（**必填**）、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 三、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **`config.yaml` 中的密钥字段会被增量写入仓库根 `aws.env`**。包内 `config.yaml` 顶层 `wechat_appid` / `wechat_appsecret`、嵌套 `writing_model.api_key` / `image_model.api_key` 在导入时按下表映射写入：\n\n  | `config.yaml` 字段 | `aws.env` 键 |\n  |---|---|\n  | `wechat_appid` | `WECHAT_1_APPID` |\n  | `wechat_appsecret` | `WECHAT_1_APPSECRET` |\n  | `writing_model.api_key` | `WRITING_MODEL_API_KEY` |\n  | `image_model.api_key` | `IMAGE_MODEL_API_KEY` |\n\n- 写入策略：包内字段为空 → 不动 `aws.env` 现有键；`aws.env` 无该键 → 追加；已有相同值 → 跳过；已有不同值 → 写入前备份 `aws.env.bak.{ts}` 后覆盖。stderr 仅输出键名清单，不打印密钥值；保留原文件顺序、空行与注释。当前前端导出仅支持单微信账号（固定槽位 1），`aws.env` 中的 `WECHAT_2_*` 等其他键不受导入影响。\n- `config.yaml`（运营配置）：本地无则首次复制；本地有则差异 JSON 输出到 stdout 不覆盖（与原行为一致），由 Agent 询问用户确认后手改。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `product_image_ingest.py` | `{baseDir}/scripts/product_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 业务介绍 .md 入库 | `.aws-article/products/{产品名}/{文件名}.md`（AI 用 Write 工具落库；目录不存在时同时 mkdir 包括 `images/`） |\n| 业务图入库 | `.aws-article/products/{产品名}/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；密钥增量写入仓库根 `aws.env`（覆盖前备份 `aws.env.bak.{ts}`）；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.24:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.24\",\n  \"publishedAt\": 1777126720783\n}\n\nFile v1.0.24:skill-card.md\n\n## Description: <br>\nHelps agents maintain a local WeChat article asset library for product descriptions, product images, and .aws preset bundles, including controlled import of presets and related configuration. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[aiworkskills](https://clawhub.ai/user/aiworkskills) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nContent operators, brand teams, and design support roles use this skill to store product-specific business copy and images, then import .aws theme and preset bundles for WeChat article production. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Importing a .aws preset bundle can add or overwrite repository-level credentials in aws.env. <br>\nMitigation: Review bundles before import, run --dry-run first, keep aws.env backups, and verify the intended keys and values before relying on imported credentials. <br>\nRisk: Using --allow-any-host weakens the default host restriction for remote .aws bundles. <br>\nMitigation: Use the default aiworkskills.cn HTTPS allowlist for normal use and reserve --allow-any-host for fully trusted sources. <br>\nRisk: Imported preset bundles can replace local preset directories and affect local article production settings. <br>\nMitigation: Inspect the bundle source and review diff output before accepting changes; use retained downloads, extraction output, and backups for audit or rollback. <br>\n\n\n## Reference(s): <br>\n- [ClawHub release page](https://clawhub.ai/aiworkskills/aws-wechat-article-assets) <br>\n- [Publisher profile](https://clawhub.ai/user/aiworkskills) <br>\n- [Artifact-declared homepage](https://aiworkskills.cn) <br>\n- [Artifact-declared project URL](https://github.com/aiworkskills/wechat-article-skills) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, files, guidance] <br>\n**Output Format:** [Markdown guidance with shell commands and generated local files] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Writes product material, image descriptions, presets, downloads, and temporary extraction files under .aws-article/; .aws imports may update the root aws.env.] <br>\n\n## Skill Version(s): <br>\n1.0.24 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.0.24:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"用户业务资料库（按产品名分目录于 .aws-article/products/{产品名}/，介绍 .md 直挂产品根 + images/ 配图含同名 .md）+ 预设包管理；业务图入库 product_image_ingest.py（--product 必填）；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"products\", \"business-assets\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.23: 5 files, 14813 bytes\n\nFiles: scripts/import_presets_aws.py (13051b), scripts/product_image_ingest.py (5423b), skill.json (745b), SKILL.md (13910b), _meta.json (145b)\n\nFile v1.0.23:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 `product_image_ingest.py --product <产品名> --stem <中文名>`。导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n---\n\n# 用户业务资料库与预设（Assets）\n\n**业务资料按产品名分目录** — `.aws-article/products/{产品名}/` 直挂业务介绍 `.md`、`images/` 存配图（含同名说明 `.md`）。**写涉及用户自身业务的文章/配图前必须先查这里；新生成的业务介绍内容应引导用户保存到这里**。预设包合并到 `.aws-article/presets/`。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地业务资料库与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件（脚本边界）；AI 在引导业务介绍入库时会先 `ls .aws-article/products/` 看已有产品名\n- **文件写**：仓库内 `.aws-article/products/{产品名}/*.md`（业务介绍，AI 用 Write 工具直接落库）、`.aws-article/products/{产品名}/images/*`（图片 + 同名 `.md`，由脚本写）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`。**已内置 ZIP slip 防御**：逐项校验 ZIP 成员路径，拒绝含绝对路径、`..` 段或解析后指向解压目录外的路径，任一违反立即退出不写入任何文件\n- **shell**：仅 `python3 {baseDir}/scripts/product_image_ingest.py`、`import_presets_aws.py`\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**业务资料库与预设环节**（入口 `aws-wechat-article-main`）。\n\n- **单独安装可用**：业务图入库 / `.aws` 预设导入两个脚本都不依赖兄弟 skill，只要 `.aws-article/` 目录就能工作。\n- 其他 skill 读取 `.aws-article/products/{产品名}/`（业务介绍 + `images/`）和 `.aws-article/presets/` 里由本 skill 管理的资源，属套件协同；需结合写稿/配图/排版等 skill 使用。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **业务介绍 .md 入库** | AI 与用户对话产出业务介绍内容时，引导/响应保存到 `products/{产品名}/<文件名>.md`（用 Write 工具直接落库，无脚本） |\n| **业务图入库** | 用户业务图 → `products/{产品名}/images/`（脚本 `--product` 必填），供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 〇、设计意图（必读）⛔\n\n`.aws-article/products/{产品名}/` 是**用户自家业务**（卖货 / 卖软件 / 卖服务 / 自媒体 IP 等）的**资料库**——既是 AI 写涉及业务的内容时的**底稿来源**，也是 AI 与用户协作产出新介绍时的**保存目的地**。\n\n### 目录约定\n\n```\n.aws-article/products/{产品名}/\n├─ 项目介绍.md                # 业务介绍 .md 直挂产品根（命名按用户行业，如 服务介绍.md / 品牌介绍.md）\n├─ (其他业务文档.md)\n└─ images/\n   ├─ 配置首页.png\n   └─ 配置首页.md             # 图片说明 .md（同名）\n```\n\n### 双向触发\n\n| 方向 | 触发条件 | 行为 |\n|------|---------|------|\n| **读** | 当前任务涉及用户自家业务（对外介绍 / 教程 / 案例 / 自家业务安利 / 业务相关配图） | 先 `ls .aws-article/products/`，识别本篇相关产品，读该产品根下 `*.md`、查 `images/` 同名 `.md`，把已有素材作为底稿/配图候选 |\n| **写** | AI 在会话中刚生成或改写的内容**语义属于用户业务介绍** | 走 [一、业务介绍 .md 入库](#一业务介绍-md-入库product-intro)；用户主动说\"保存为产品介绍\"等也走此流程 |\n\n### 反例（不要触发）\n\n- 主题是行业资讯 / 通用教程 / 与用户业务无关 → 不读、不写\n- 用户明确表示内容\"还没定型\" → 不主动引导保存\n- AI 不确定是不是用户自家业务时 → 宁可不主动提，也不要乱塞进 `products/`\n\n---\n\n## 一、业务介绍 .md 入库（Product Intro）\n\n无需脚本，AI 用 Write 工具直接落库。\n\n### 触发模式 A：AI 主动识别 + 引导\n\nAI 在任意会话中刚生成或刚改写了一段内容，**其语义明确属于用户自家业务介绍**（产品 / 服务 / 品牌 / 项目 / 团队 / 业务范围介绍）时，主动提示用户：\n\n> \"这段是 [产品名] 的业务介绍，要不要保存到产品资料库？我可以存到 `.aws-article/products/{产品名}/{文件名}.md`，下次写涉及业务的文章时会自动用上。\"\n\n用户确认 → 走「保存流程」。\n\n### 触发模式 B：用户主动指令\n\n用户说类似 \"保存为产品介绍 / 业务介绍 / 服务介绍 / 自家介绍 / 入库到产品 / 存到产品资料库\" 时，AI 把当前会话中的目标内容（用户指定段落或最近相关产出）走「保存流程」。\n\n### 保存流程\n\n1. **确认产品名**：`ls .aws-article/products/`，已有目录则提示复用；新产品则向用户拿名字\n2. **确认文件名**：默认 `项目介绍.md`；可改为 `产品介绍.md` / `服务介绍.md` / `品牌介绍.md` / `业务介绍.md` 等贴用户行业的命名\n3. **创建目录**：`mkdir -p .aws-article/products/{产品名}/images/`（即便暂为空，把骨架建齐）\n4. **写入文件**：用 Write 工具落到 `.aws-article/products/{产品名}/{文件名}.md`\n5. **反馈**：「已存到 `<完整路径>`，下次涉及 [产品名] 业务的文章会自动用上」\n\n---\n\n## 二、业务图入库（Product Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/products/{产品名}/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径，并指明**所属产品**（与 `products/` 下某个目录对应；新产品则脚本会自动创建）。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `配置首页`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/product_image_ingest.py <源图片路径> \\\n  --product \"公众号AI运营助手\" --stem \"配置首页\" \\\n  --content \"客观中文描述，一两句即可\"\n```\n\n`--product` **必填**；产品目录与 `images/` 子目录不存在时**自动创建**。\n\n4. 生成 `配置首页.png` + `配置首页.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`product_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/products/公众号AI运营助手/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `product_image_ingest.py`\n\n- `source`、`--product`（**必填**）、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 三、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `product_image_ingest.py` | `{baseDir}/scripts/product_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 业务介绍 .md 入库 | `.aws-article/products/{产品名}/{文件名}.md`（AI 用 Write 工具落库；目录不存在时同时 mkdir 包括 `images/`） |\n| 业务图入库 | `.aws-article/products/{产品名}/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.23:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.23\",\n  \"publishedAt\": 1777035860708\n}\n\nFile v1.0.23:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"用户业务资料库（按产品名分目录于 .aws-article/products/{产品名}/，介绍 .md 直挂产品根 + images/ 配图含同名 .md）+ 预设包管理；业务图入库 product_image_ingest.py（--product 必填）；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"products\", \"business-assets\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.22: 5 files, 12760 bytes\n\nFiles: scripts/import_presets_aws.py (13051b), scripts/stock_image_ingest.py (4646b), skill.json (541b), SKILL.md (9432b), _meta.json (145b)\n\nFile v1.0.22:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜素材库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 公众号素材库与预设包管理：图片入库到 stock 目录（中文名 + 同名 .md），导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n---\n\n# 公众号素材与预设（Assets）\n\n**素材与预设统一管理** —— 图片入库 + .aws 预设包导入，多 skill 复用同一套内容资产。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地素材与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件\n- **文件写**：仓库内 `.aws-article/assets/stock/images/*`（图片 + 同名 `.md`）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`。**已内置 ZIP slip 防御**：逐项校验 ZIP 成员路径，拒绝含绝对路径、`..` 段或解析后指向解压目录外的路径，任一违反立即退出不写入任何文件\n- **shell**：仅 `python3 {baseDir}/scripts/stock_image_ingest.py`、`import_presets_aws.py`\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**素材与预设环节**（入口 `aws-wechat-article-main`）。\n\n- **单独安装可用**：素材入库 / `.aws` 预设导入两个脚本都不依赖兄弟 skill，只要 `.aws-article/` 目录就能工作。\n- 其他 skill 读取 `.aws-article/assets/stock/images/` 和 `.aws-article/presets/` 里由本 skill 管理的资源，属套件协同；需结合写稿/配图/排版等 skill 使用。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **图片入库** | 用户图 → `assets/stock/images/`，供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 一、图片入库（Stock Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/assets/stock/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `淘米`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/stock_image_ingest.py <源图片路径> --stem \"中文名\" --content \"客观中文描述，一两句即可\"\n```\n\n若暂未写描述，也可只传 `--stem`（见下「图片描述与占位」）。\n\n4. 生成 `淘米.png` + `淘米.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`stock_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/assets/stock/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `stock_image_ingest.py`\n\n- `source`、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 二、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `stock_image_ingest.py` | `{baseDir}/scripts/stock_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 图片入库 | `assets/stock/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.22:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.22\",\n  \"publishedAt\": 1776900269612\n}\n\nFile v1.0.22:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"图片入库 stock/images + 同名 md；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"stock-images\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.21: 5 files, 12609 bytes\n\nFiles: scripts/import_presets_aws.py (13051b), scripts/stock_image_ingest.py (4646b), skill.json (541b), SKILL.md (9085b), _meta.json (145b)\n\nFile v1.0.21:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜素材库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 公众号素材库与预设包管理：图片入库到 stock 目录（中文名 + 同名 .md），导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n---\n\n# 公众号素材与预设（Assets）\n\n**素材与预设统一管理** —— 图片入库 + .aws 预设包导入，多 skill 复用同一套内容资产。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地素材与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件\n- **文件写**：仓库内 `.aws-article/assets/stock/images/*`（图片 + 同名 `.md`）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`。**已内置 ZIP slip 防御**：逐项校验 ZIP 成员路径，拒绝含绝对路径、`..` 段或解析后指向解压目录外的路径，任一违反立即退出不写入任何文件\n- **shell**：仅 `python3 {baseDir}/scripts/stock_image_ingest.py`、`import_presets_aws.py`\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的素材与预设环节（入口 `aws-wechat-article-main`）。完整说明见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **图片入库** | 用户图 → `assets/stock/images/`，供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 一、图片入库（Stock Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/assets/stock/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `淘米`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/stock_image_ingest.py <源图片路径> --stem \"中文名\" --content \"客观中文描述，一两句即可\"\n```\n\n若暂未写描述，也可只传 `--stem`（见下「图片描述与占位」）。\n\n4. 生成 `淘米.png` + `淘米.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`stock_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/assets/stock/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `stock_image_ingest.py`\n\n- `source`、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 二、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `stock_image_ingest.py` | `{baseDir}/scripts/stock_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 图片入库 | `assets/stock/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.21:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.21\",\n  \"publishedAt\": 1776898068492\n}\n\nFile v1.0.21:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"图片入库 stock/images + 同名 md；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"stock-images\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.20: 5 files, 12081 bytes\n\nFiles: scripts/import_presets_aws.py (11898b), scripts/stock_image_ingest.py (4646b), skill.json (541b), SKILL.md (8896b), _meta.json (145b)\n\nFile v1.0.20:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜素材库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 公众号素材库与预设包管理：图片入库到 stock 目录（中文名 + 同名 .md），导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n---\n\n# 公众号素材与预设（Assets）\n\n**素材与预设统一管理** —— 图片入库 + .aws 预设包导入，多 skill 复用同一套内容资产。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地素材与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件\n- **文件写**：仓库内 `.aws-article/assets/stock/images/*`（图片 + 同名 `.md`）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`\n- **shell**：仅 `python3 {baseDir}/scripts/stock_image_ingest.py`、`import_presets_aws.py`\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的素材与预设环节（入口 `aws-wechat-article-main`）。完整说明见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **图片入库** | 用户图 → `assets/stock/images/`，供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 一、图片入库（Stock Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/assets/stock/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `淘米`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/stock_image_ingest.py <源图片路径> --stem \"中文名\" --content \"客观中文描述，一两句即可\"\n```\n\n若暂未写描述，也可只传 `--stem`（见下「图片描述与占位」）。\n\n4. 生成 `淘米.png` + `淘米.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`stock_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/assets/stock/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `stock_image_ingest.py`\n\n- `source`、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 二、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `stock_image_ingest.py` | `{baseDir}/scripts/stock_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 图片入库 | `assets/stock/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.20:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.20\",\n  \"publishedAt\": 1776897361594\n}\n\nFile v1.0.20:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"图片入库 stock/images + 同名 md；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"stock-images\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.19: 5 files, 11747 bytes\n\nFiles: scripts/import_presets_aws.py (11591b), scripts/stock_image_ingest.py (4339b), skill.json (541b), SKILL.md (8920b), _meta.json (145b)\n\nFile v1.0.19:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜素材库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 公众号素材库与预设包管理：图片入库到 stock 目录（中文名 + 同名 .md），导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n    primaryEnv: aws.env\n---\n\n# 公众号素材与预设（Assets）\n\n**素材与预设统一管理** —— 图片入库 + .aws 预设包导入，多 skill 复用同一套内容资产。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地素材与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件\n- **文件写**：仓库内 `.aws-article/assets/stock/images/*`（图片 + 同名 `.md`）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`\n- **shell**：仅 `python3 {baseDir}/scripts/stock_image_ingest.py`、`import_presets_aws.py`\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的素材与预设环节（入口 `aws-wechat-article-main`）。完整说明见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **图片入库** | 用户图 → `assets/stock/images/`，供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 一、图片入库（Stock Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/assets/stock/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `淘米`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/stock_image_ingest.py <源图片路径> --stem \"中文名\" --content \"客观中文描述，一两句即可\"\n```\n\n若暂未写描述，也可只传 `--stem`（见下「图片描述与占位」）。\n\n4. 生成 `淘米.png` + `淘米.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`stock_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/assets/stock/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `stock_image_ingest.py`\n\n- `source`、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 二、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `stock_image_ingest.py` | `{baseDir}/scripts/stock_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 图片入库 | `assets/stock/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.19:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.19\",\n  \"publishedAt\": 1776875798657\n}\n\nFile v1.0.19:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"图片入库 stock/images + 同名 md；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"stock-images\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.18: 5 files, 11878 bytes\n\nFiles: scripts/import_presets_aws.py (11591b), scripts/stock_image_ingest.py (4339b), skill.json (541b), SKILL.md (9132b), _meta.json (145b)\n\nFile v1.0.18:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜素材库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 公众号素材库与预设包管理：图片入库到 stock 目录（中文名 + 同名 .md），导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\n---\n\n# 公众号素材与预设（Assets）\n\n**素材与预设统一管理** —— 图片入库 + .aws 预设包导入，多 skill 复用同一套内容资产。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 前置依赖 ⛔ 套件必须装齐\n\n`aws-wechat-article-*` 一条龙套件的 9 个 skill 互相引用首次引导、环境校验与规则文档。**单独安装任一 skill 无法正常工作**，必须装齐 9 个：\n\n```\naws-wechat-article-main\naws-wechat-article-topics\naws-wechat-article-writing\naws-wechat-article-review\naws-wechat-article-formatting\naws-wechat-article-images\naws-wechat-article-publish\naws-wechat-article-assets\naws-wechat-sticker\n```\n\n**Agent：进入下方工作流前，先检查当前 `skills/` 目录下上述 9 个子目录是否都存在。**\n\n**若任一缺失** → 停止本 skill 工作流，**不得**尝试代替用户跑脚本或继续；按下述话术回复用户：\n\n> 本套件需 9 个 skill 都装齐才能使用。检测到缺少：`<列出缺失项>`。请执行：\n>\n> ```bash\n> # macOS / Linux / Git Bash\n> for slug in aws-wechat-article-main aws-wechat-article-topics aws-wechat-article-writing aws-wechat-article-review aws-wechat-article-formatting aws-wechat-article-images aws-wechat-article-publish aws-wechat-article-assets aws-wechat-sticker; do\n>   clawhub install \"$slug\"\n> done\n> ```\n>\n> ```powershell\n> # Windows PowerShell\n> 'aws-wechat-article-main','aws-wechat-article-topics','aws-wechat-article-writing','aws-wechat-article-review','aws-wechat-article-formatting','aws-wechat-article-images','aws-wechat-article-publish','aws-wechat-article-assets','aws-wechat-sticker' | ForEach-Object { clawhub install $_ }\n> ```\n>\n> 装完再回本 skill 让我继续。\n\n**9 个全部存在** → 按下方工作流继续。\n\n| 能力 | 说明 |\n|------|------|\n| **图片入库** | 用户图 → `assets/stock/images/`，供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 一、图片入库（Stock Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/assets/stock/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `淘米`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/stock_image_ingest.py <源图片路径> --stem \"中文名\" --content \"客观中文描述，一两句即可\"\n```\n\n若暂未写描述，也可只传 `--stem`（见下「图片描述与占位」）。\n\n4. 生成 `淘米.png` + `淘米.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`stock_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/assets/stock/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `stock_image_ingest.py`\n\n- `source`、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 二、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `stock_image_ingest.py` | `{baseDir}/scripts/stock_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 图片入库 | `assets/stock/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.18:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.18\",\n  \"publishedAt\": 1776873219054\n}\n\nFile v1.0.18:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"图片入库 stock/images + 同名 md；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"stock-images\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.17: 5 files, 11906 bytes\n\nFiles: scripts/import_presets_aws.py (11591b), scripts/stock_image_ingest.py (4339b), skill.json (541b), SKILL.md (9143b), _meta.json (145b)\n\nFile v1.0.17:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜微信公众号素材｜素材库｜stock images｜预设包｜.aws 预设包｜主题包｜品牌包｜配色字体｜content assets｜media library｜design presets｜aiworkskills.cn — 公众号素材库与预设包管理：图片入库到 stock 目录（中文名 + 同名 .md），导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\n---\n\n# 公众号素材与预设（Assets）\n\n**素材与预设统一管理** —— 图片入库 + .aws 预设包导入，多 skill 复用同一套内容资产。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 前置依赖 ⛔ 套件必须装齐\n\n`aws-wechat-article-*` 一条龙套件的 9 个 skill 互相引用首次引导、环境校验与规则文档。**单独安装任一 skill 无法正常工作**，必须装齐 9 个：\n\n```\naws-wechat-article-main\naws-wechat-article-topics\naws-wechat-article-writing\naws-wechat-article-review\naws-wechat-article-formatting\naws-wechat-article-images\naws-wechat-article-publish\naws-wechat-article-assets\naws-wechat-sticker\n```\n\n**Agent：进入下方工作流前，先检查当前 `skills/` 目录下上述 9 个子目录是否都存在。**\n\n**若任一缺失** → 停止本 skill 工作流，**不得**尝试代替用户跑脚本或继续；按下述话术回复用户：\n\n> 本套件需 9 个 skill 都装齐才能使用。检测到缺少：`<列出缺失项>`。请执行：\n>\n> ```bash\n> # macOS / Linux / Git Bash\n> for slug in aws-wechat-article-main aws-wechat-article-topics aws-wechat-article-writing aws-wechat-article-review aws-wechat-article-formatting aws-wechat-article-images aws-wechat-article-publish aws-wechat-article-assets aws-wechat-sticker; do\n>   clawhub install \"$slug\"\n> done\n> ```\n>\n> ```powershell\n> # Windows PowerShell\n> 'aws-wechat-article-main','aws-wechat-article-topics','aws-wechat-article-writing','aws-wechat-article-review','aws-wechat-article-formatting','aws-wechat-article-images','aws-wechat-article-publish','aws-wechat-article-assets','aws-wechat-sticker' | ForEach-Object { clawhub install $_ }\n> ```\n>\n> 装完再回本 skill 让我继续。\n\n**9 个全部存在** → 按下方工作流继续。\n\n| 能力 | 说明 |\n|------|------|\n| **图片入库** | 用户图 → `assets/stock/images/`，供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 一、图片入库（Stock Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/assets/stock/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `淘米`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/stock_image_ingest.py <源图片路径> --stem \"中文名\" --content \"客观中文描述，一两句即可\"\n```\n\n若暂未写描述，也可只传 `--stem`（见下「图片描述与占位」）。\n\n4. 生成 `淘米.png` + `淘米.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`stock_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/assets/stock/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `stock_image_ingest.py`\n\n- `source`、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 二、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录采用**「替换式」语义**（以服务端为准，避免旧文件残留）：\n  - 若**包内存在**该子目录 → **先清空本地 `.aws-article/presets/<同名>/` 再写入包内内容**（旧包里有、新包里删掉的文件不会残留）；\n  - 若**包内不存在**该子目录 → 本地对应子目录**保持不动**（不受本次导入影响）。\n  - 包根优先级：若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**；若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `stock_image_ingest.py` | `{baseDir}/scripts/stock_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 图片入库 | `assets/stock/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.17:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.17\",\n  \"publishedAt\": 1776847537659\n}\n\nFile v1.0.17:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"图片入库 stock/images + 同名 md；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"stock-images\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}\n\nArchive v1.0.16: 5 files, 11067 bytes\n\nFiles: scripts/import_presets_aws.py (11059b), scripts/stock_image_ingest.py (4339b), skill.json (541b), SKILL.md (7361b), _meta.json (145b)\n\nFile v1.0.16:SKILL.md\n\n---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜微信公众号素材｜素材库｜stock images｜预设包｜.aws 预设包｜主题包｜品牌包｜配色字体｜content assets｜media library｜design presets｜aiworkskills.cn — 公众号素材库与预设包管理：图片入库到 stock 目录（中文名 + 同名 .md），导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\n---\n\n# 公众号素材与预设（Assets）\n\n**素材与预设统一管理** —— 图片入库 + .aws 预设包导入，多 skill 复用同一套内容资产。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n| 能力 | 说明 |\n|------|------|\n| **图片入库** | 用户图 → `assets/stock/images/`，供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 一、图片入库（Stock Images）\n\n### 目录\n\n| 路径 | 作用 |\n|------|------|\n| `.aws-article/assets/stock/images/` | 入库图片 + 同名 `.md`（固定：**图片路径** / **图片描述**） |\n\n### 工作流\n\n1. 用户上传或给出本地图片路径。\n2. **Agent 读图**（多模态能力在本对话侧）：确定**中文主文件名**（如 `淘米`），并写出**客观画面描述**（供 `.md` 与后续配图检索使用）。\n3. 在**仓库根**执行（**推荐**带上 `--content`，与第 2 步描述一致）：\n\n```bash\npython {baseDir}/scripts/stock_image_ingest.py <源图片路径> --stem \"中文名\" --content \"客观中文描述，一两句即可\"\n```\n\n若暂未写描述，也可只传 `--stem`（见下「图片描述与占位」）。\n\n4. 生成 `淘米.png` + `淘米.md`（格式见下）。\n\n### 图片描述与占位 ⛔\n\n- **`stock_image_ingest.py` 不会读图**：无视觉/多模态，只负责**复制图片**并**按模板写 `.md`**。\n- **未传 `--content`（或为空）** 时，「**图片描述**」会写入固定占位句：**「请根据图片补全（客观描述画面内容即可）。」**——这是预期行为，不是脚本故障。\n- **要直接得到可用描述**：入库命令必须带 **`--content \"……\"`**（由 Agent 读图后填写），或入库后**手动/由 Agent 编辑**同名 `.md` 替换占位段。\n\n### `.md` 固定格式\n\n```markdown\n**图片路径**：`.aws-article/assets/stock/images/示例.png`\n\n**图片描述**：……\n```\n\n### 脚本 `stock_image_ingest.py`\n\n- `source`、`--stem`（必填）、`--content`（可选，**强烈建议由 Agent 读图后传入**）、`--repo`（可选）\n\n---\n\n## 二、预设包导入（`.aws`）\n\n扩展名 **`.aws`**，实质为 **ZIP**。解压后根目录应包含与仓库一致的预设文件夹（可多出其它文件，脚本只处理下列目录）：\n\n`closing-blocks`、`cover-styles`、`formatting`、`image-styles`、`sticker-styles`、`structures`、`title-styles`\n\n另可有根级 **`config.yaml`**、**`writing-spec.md`**。\n\n### 输入来源（本地 / URL）\n\n`bundle` 参数同时接受两种形态：\n\n- **本地路径**：`./brand-a.aws` 或绝对路径\n- **HTTPS URL**：仅限 `aiworkskills.cn` 及其子域，必须 `https://` 开头、路径以 `.aws` 结尾\n  - 示例：`https://aiworkskills.cn/bundles/brand-a.aws`\n  - 下载缓存：`.aws-article/downloads/<原文件名>`（**不在 `tmp/` 内**，不受清空影响，保留供事后核对）\n  - 不在白名单、非 https、或下载内容非 ZIP → **直接报错退出**\n  - 调试放宽：`--allow-any-host` 可跳过域名白名单（仍强制 https）；不建议生产使用\n\n### 合并规则\n\n- 每个上述目录：**递归合并**到 `.aws-article/presets/<同名>/`（推荐 **`presets/<上述名>/`**；若包根下**同时**存在 **`presets/<名>/`** 与 **`<名>/`**，脚本**优先合并前者**（避免误用包根多一层同名子目录）。若目录内仅有一层多余 **`<名>/<名>/`**，脚本会自动以内层为合并根）；**同名文件覆盖**，新路径则**新增**。\n- **`config.yaml`**：若包内存在且本地**尚无** `.aws-article/config.yaml`，则从包内**复制**；若本地**已有**，则**不覆盖**，按包内字段与本地**同名键**递归比对，将差异以 **JSON 数组** 打印到 **stdout**（`{\"key\":\"点分路径\",\"old\":…,\"new\":…}`），供智能体询问用户后再手改配置；说明日志在 stderr。\n- **`writing-spec.md`**：若包内存在，**始终覆盖**写入 **`.aws-article/writing-spec.md`**（与 `config.yaml` 不同，不做差异比对）。\n- 解压目录：**`.aws-article/tmp/`**（固定路径；运行前若无 `.aws-article` 会创建）。**每次执行前**若 `tmp` 已存在则**整目录删除后重建**，再解压本次 `.aws`；合并到 `presets/` 后**保留**解压结果便于核对，下次导入会再次清空 `tmp` 并覆盖为新包内容。\n\n### 密钥与配置\n\n- **预设包内的 `config.yaml` 不应、也不会包含** `aws.env` 中的密钥；仓库密钥始终在仓库根 **`aws.env`**。\n- 本地已有 `config.yaml` 时导入不会自动改配置；请根据 stdout 差异与用户确认后再更新字段（或对照 `.aws-article/tmp/` 解压结果）。\n\n### 工作流\n\n1. 准备 `*.aws` 来源：**(a)** 本地文件（上传或已有路径），或 **(b)** 符合白名单的 **HTTPS URL**。\n2. 可先 **`--dry-run`** 查看将写入的路径（URL 模式下仍会实际下载到 `downloads/` 以便校验 ZIP 结构，但不写入 `presets/` 与 `config.yaml`）。\n3. 在**仓库根**执行：\n\n```bash\n# 本地路径\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\npython {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\npython {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run\n```\n\n### 脚本 `import_presets_aws.py`\n\n- 参数：`bundle`（`.aws` 路径 或 `https://*.aiworkskills.cn` URL）、`--dry-run`、`--repo`、`--allow-any-host`（调试）\n\n---\n\n## 脚本一览\n\n| 脚本 | 路径 |\n|------|------|\n| `stock_image_ingest.py` | `{baseDir}/scripts/stock_image_ingest.py` |\n| `import_presets_aws.py` | `{baseDir}/scripts/import_presets_aws.py` |\n\n## 过程文件\n\n| 场景 | 产出 |\n|------|------|\n| 图片入库 | `assets/stock/images/*.{png,...}` + 同名 `*.md` |\n| `.aws` 导入 | 更新 `.aws-article/presets/**`；`config.yaml` 首次复制或 stdout 差异 JSON；解压缓存在 `.aws-article/tmp/` |\n| `.aws` URL 导入 | 下载缓存 `.aws-article/downloads/*.aws`；其余同本地导入 |\n\nFile v1.0.16:_meta.json\n\n{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.16\",\n  \"publishedAt\": 1776834823735\n}\n\nFile v1.0.16:skill.json\n\n{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"图片入库 stock/images + 同名 md；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"stock-images\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}","readmeExcerpt":"Skill: 公众号素材库 & 预设包 Owner: aiworkskills Summary: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 .aws-article/products/{产品名}/（介绍 .md 直挂产品根 + 配图归 images/ 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 product_image_ingest.py --product <产品名> --stem <中文名>。导入 .aws ZIP 预设包（本地文件或 https://aiworkskills.cn/**/*.aws URL）合并主题/配色/字体配置到 .aws-article/presets/；config.yaml 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON","codeSnippets":[],"executableExamples":[{"language":"text","snippet":".aws-article/products/{产品名}/\n├─ 项目介绍.md                # 业务介绍 .md 直挂产品根（命名按用户行业，如 服务介绍.md / 品牌介绍.md）\n├─ (其他业务文档.md)\n└─ images/\n   ├─ 配置首页.png\n   └─ 配置首页.md             # 图片说明 .md（同名）"},{"language":"bash","snippet":"{python} {baseDir}/scripts/product_image_ingest.py <源图片路径> \\\n  --product \"公众号AI运营助手\" --stem \"配置首页\" \\\n  --content \"客观中文描述，一两句即可\""},{"language":"markdown","snippet":"**图片路径**：`.aws-article/products/公众号AI运营助手/images/示例.png`\n\n**图片描述**：……"},{"language":"bash","snippet":"# 本地路径\n{python} {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws\n{python} {baseDir}/scripts/import_presets_aws.py path/to/bundle.aws --dry-run\n\n# URL（仅 aiworkskills.cn 及子域）\n{python} {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/bundles/brand-a.aws\n{python} {baseDir}/scripts/import_presets_aws.py https://aiworkskills.cn/x/y.aws --dry-run"},{"language":"text","snippet":".aws-article/products/{产品名}/\n├─ 项目介绍.md                # 业务介绍 .md 直挂产品根（命名按用户行业，如 服务介绍.md / 品牌介绍.md）\n├─ (其他业务文档.md)\n└─ images/\n   ├─ 配置首页.png\n   └─ 配置首页.md             # 图片说明 .md（同名）"},{"language":"bash","snippet":"python {baseDir}/scripts/product_image_ingest.py <源图片路径> \\\n  --product \"公众号AI运营助手\" --stem \"配置首页\" \\\n  --content \"客观中文描述，一两句即可\""}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: aws-wechat-article-assets\ndescription: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 `product_image_ingest.py --product <产品名> --stem <中文名>`。导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。\nhomepage: https://aiworkskills.cn\nurl: https://github.com/aiworkskills/wechat-article-skills\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins:\n        - python3\n---\n\n# 用户业务资料库与预设（Assets）\n\n**业务资料按产品名分目录** — `.aws-article/products/{产品名}/` 直挂业务介绍 `.md`、`images/` 存配图（含同名说明 `.md`）。**写涉及用户自身业务的文章/配图前必须先查这里；新生成的业务介绍内容应引导用户保存到这里**。预设包合并到 `.aws-article/presets/`。\n\n> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>\n\n## 能力披露（Capabilities）\n\n本 skill 管理本地业务资料库与预设包，可选从 `aiworkskills.cn` 域下载 `.aws` 预设包（ZIP 格式）。\n\n- **凭证**：无\n- **网络**：可选 `https://*.aiworkskills.cn/**/*.aws` 下载预设包。**白名单强制**：仅 HTTPS + `aiworkskills.cn` 子域，非白名单会**直接报错退出**。调试参数 `--allow-any-host` 可放宽但不推荐生产使用\n- **文件读**：用户指定的本地图片路径或 `.aws` 文件（脚本边界）；AI 在引导业务介绍入库时会先 `ls .aws-article/products/` 看已有产品名\n- **文件写**：仓库内 `.aws-article/products/{产品名}/*.md`（业务介绍，AI 用 Write 工具直接落库）、`.aws-article/products/{产品名}/images/*`（图片 + 同名 `.md`，由脚本写）、`.aws-article/presets/<子目录>/*`（预设文件）、`.aws-article/downloads/*.aws`（下载缓存）、`.aws-article/tmp/*`（解压临时目录）；导入 `.aws` 时**仓库根 `aws.env`** 会按映射表增量写入密钥字段（覆盖现有键前自动备份为 `aws.env.bak.{ts}`，stderr 仅打印键名不打印值）\n- **归档**：解压 `.aws` 扩展名的 ZIP 到 `.aws-article/tmp/`，按白名单子目录合并到 `.aws-article/presets/`。**已内置 ZIP slip 防御**：逐项校验 ZIP 成员路径，拒绝含绝对路径、`..` 段或解析后指向解压目录外的路径，任一违反立即退出不写入任何文件\n- **shell**：仅 `{python} {baseDir}/scripts/product_image_ingest.py`、`import_presets_aws.py`（`{python}` = 本机 Python 3 解释器，见 [main SKILL 第 0 步](../aws-wechat-article-main/SKILL.md)：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）\n\n所有写入限制在仓库根下的 `.aws-article/` 内。\n\n## 配套 skill（informational）\n\n本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**业务资料库与预设环节**（入口 `aws-wechat-article-main`）。\n\n- **单独安装可用**：业务图入库 / `.aws` 预设导入两个脚本都不依赖兄弟 skill，只要 `.aws-article/` 目录就能工作。\n- 其他 skill 读取 `.aws-article/products/{产品名}/`（业务介绍 + `images/`）和 `.aws-article/presets/` 里由本 skill 管理的资源，属套件协同；需结合写稿/配图/排版等 skill 使用。\n\n完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。\n\n| 能力 | 说明 |\n|------|------|\n| **业务介绍 .md 入库** | AI 与用户对话产出业务介绍内容时，引导/响应保存到 `products/{产品名}/<文件名>.md`（用 Write 工具直接落库，无脚本） |\n| **业务图入库** | 用户业务图 → `products/{产品名}/images/`（脚本 `--product` 必填），供其它 skill 引用 |\n| **预设包 `.aws`** | ZIP 包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）→ 合并 `presets/` 子目录；`config.yaml` 见下 |\n\n---\n\n## 〇、设计意图（必读）⛔\n\n`.aws-article/products/{产品名}/` 是**用户自家业"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7f5hvxj1x2ctd5vqnec5x1zs82ce6h\",\n  \"slug\": \"aws-wechat-article-assets\",\n  \"version\": \"1.0.25\",\n  \"publishedAt\": 1788679503477\n}"},{"path":"skill-card.md","content":"## Description:\n\n公众号素材库 & 预设包 helps agents manage WeChat article business materials, product images, and .aws preset packages under .aws-article/.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[aiworkskills](https://clawhub.ai/user/aiworkskills)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal content operators, brand teams, and design-support users use this skill to store business descriptions and product images by product, then import .aws preset bundles for WeChat article production workflows.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The preset importer can update aws.env with credential-like values from a bundle config.\n\nMitigation: Inspect the .aws bundle and run a dry run first; avoid running the importer in repositories containing real API keys or WeChat credentials until the user has confirmed the expected changes.\n\nRisk: Configuration diffs printed to stdout may expose sensitive values in logs.\n\nMitigation: Run imports only in controlled terminals, redact captured logs, and avoid shared logging environments unless the config-diff output is fixed or redacted.\n\nRisk: The importer can download .aws bundles and includes a debug flag that relaxes host validation.\n\nMitigation: Use only HTTPS aiworkskills.cn bundle URLs for normal use and avoid --allow-any-host outside controlled testing.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/aiworkskills/skills/aws-wechat-article-assets)\n- [Publisher profile](https://clawhub.ai/user/aiworkskills)\n- [aiworkskills homepage](https://aiworkskills.cn)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON configuration diffs]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Can guide agents to write local Markdown/image asset files under .aws-article/ and run bundled Python scripts that may update .aws-article/ and aws.env.]\n\n## Skill Version(s):\n\n1.0.25 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."},{"path":"skill.json","content":"{\n  \"name\": \"aws-wechat-article-assets\",\n  \"version\": \"0.2.0\",\n  \"author\": \"aiworkskills\",\n  \"description\": \"用户业务资料库（按产品名分目录于 .aws-article/products/{产品名}/，介绍 .md 直挂产品根 + images/ 配图含同名 .md）+ 预设包管理；业务图入库 product_image_ingest.py（--product 必填）；导入 .aws 预设包合并 presets，config.yaml 仅首次复制、已有则输出差异。\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/aiworkskills/wechat-article-skills\",\n  \"tags\": [\"wechat\", \"公众号\", \"assets\", \"products\", \"business-assets\", \"presets\"],\n  \"permissions\": [\"filesystem\", \"shell\"],\n  \"entryPoint\": {\n    \"type\": \"natural\",\n    \"path\": \"SKILL.md\"\n  },\n  \"dependencies\": []\n}"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 `.aws-article/products/{产品名}/`（介绍 .md 直挂产品根 + 配图归 `images/` 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 `product_image_ingest.py --product <产品名> --stem <中文名>`。导入 .aws ZIP 预设包（本地文件或 `https://aiworkskills.cn/**/*.aws` URL）合并主题/配色/字体配置到 `.aws-article/presets/`；`config.yaml` 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON 不覆盖。面向内容运营、品牌团队、设计支持岗。触发词：「素材库入库」「stock images」「上传图到素材库」「.aws」「预设包」「导入预设」「主题包」「aiworkskills.cn 链接」「.aws 下载地址」。 Skill: 公众号素材库 & 预设包 Owner: aiworkskills Summary: 公众号素材｜业务资料库｜预设包｜.aws 预设包｜主题包｜品牌包｜aiworkskills.cn — 用户业务资料库与预设包管理：业务资料按产品名组织在 .aws-article/products/{产品名}/（介绍 .md 直挂产品根 + 配图归 images/ 子目录含同名说明 .md），AI 与用户对话产出业务介绍内容时引导用户保存；图片入库走 product_image_ingest.py --product <产品名> --stem <中文名>。导入 .aws ZIP 预设包（本地文件或 https://aiworkskills.cn/**/*.aws URL）合并主题/配色/字体配置到 .aws-article/presets/；config.yaml 仅本地不存在时从包内复制，已存在则 stdout 输出差异 JSON","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1056,"uniquenessScore":46,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T14:51:27.986Z","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-10T14:51:27.986Z","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-10T17:35:50.069Z","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"}]}}}