diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0f94bf2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +# Changelog + +本文件对应技能市场 **「更新日志」** Tab。 +发布 CI 会按当前 tag 版本(如 `v1.0.46` → `1.0.46`)提取匹配的 `##` 小节,写入该版本的 `changelog`。 + +约定: + +- 每个正式版本一节,标题形如 `## 1.0.46` 或 `## [1.0.46] - YYYY-MM-DD` +- 小节正文写用户能看懂的变化(新能力、修复、注意事项),避免堆砌内部实现细节 +- 打 tag 前**必须**为即将发布的版本新增一节;找不到匹配小节时,本次发布不会更新 changelog 字段 + +## 1.0.46 + +- 模板默认增加市场材料:`TUTORIAL.md`(使用教程)、`DEMO.md`(演示)、`CHANGELOG.md`(更新日志),与根 `README.md`(技能说明)组成四 Tab 内容源 +- 发布 CI 同步 `tutorial_md` / `demo_md` / `demo_video_url` / 版本 `changelog` + +## 1.0.45 + +- 沉淀通用 Agent 路由与 how-to 文档标准(见仓库提交说明) diff --git a/DEMO.md b/DEMO.md new file mode 100644 index 0000000..4c88bb6 --- /dev/null +++ b/DEMO.md @@ -0,0 +1,24 @@ +--- +demo_video_url: "" +--- + +> **模板说明(复制后删除本段)** +> 本文对应技能市场 **「演示」** Tab。 +> - frontmatter 的 `demo_video_url`:演示视频地址(发布时同步为 `demo_video_url`);没有视频时保持空字符串 `""`。 +> - 正文(发布时同步为 `demo_md`):可选,写视频看点、时间轴或无视频时的图文演示说明。 +> **不要**把演示链接写进 `SKILL.md`(市场材料 ≠ Agent 契约)。 +> 复制为业务技能后:填入真实可访问的视频 URL,并删掉本提示段。 + +# 演示说明 + +用一两句话说明这段演示帮助用户看懂什么(例如:从发起任务到看到结果的完整过程)。 + +## 建议观看顺序 + +1. 如何发起一次典型任务 +2. 执行过程中会看到什么提示 / 进度 +3. 成功后的结果长什么样 + +## 没有视频时 + +可在此用简短图文描述关键界面与结果样例;有视频后把 `demo_video_url` 填上即可,正文可保留为补充说明。 diff --git a/SKILL.md b/SKILL.md index 6827a8c..b119109 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,7 +1,7 @@ --- name: 技能开发模板(通用业务版) description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。" -version: 1.0.45 +version: 1.0.46 author: 深圳匠厂科技有限公司 metadata: openclaw: @@ -38,7 +38,7 @@ allowed-tools: | 短查询 / 只读 / 秒级(`health` / `version` / `stats` / `list` / `get` / `logs` 等) | OpenClaw bash/exec + **共享 Python** 跑 CLI(见下方「共享 Python」) | 否(CLI 当场结束) | | 已在 `actions.json` 声明且 `executionProfile: "sync"` 的能力 | 可用 `run_skill_action`,或同等效果的短 CLI(同一内核) | 否 | | 长耗时 / RPA / 浏览器 / 需要进度或取消;或 `executionProfile: "async"` | **必须** `run_skill_action`(先 `list_skill_actions` / `get_skill_action`) | **是**(仅因为该 Action 是 async) | -| 用户只问用法 / 能做什么 | 读根目录 `README.md`;**不要**为答用法去列目录或默认打开 `references/` | — | +| 用户只问用法 / 能做什么 | 读根目录 `README.md`;逐步操作再读 `TUTORIAL.md`;**不要**为答用法去列目录或默认打开 `references/` | — | ### 用户意图路由表(业务技能复制后必改) @@ -84,9 +84,9 @@ python {baseDir}/scripts/main.py init-db ## 面向用户问答(LLM 规则) - 本文(`SKILL.md`)是 LLM / OpenClaw 平台读取的技能入口,**不是**用户市场说明。 -- 根目录 `README.md` 是面向普通用户的说明。 +- 根目录市场材料面向普通用户(见下方「文档分工」),**不是** Agent 调用契约。 -当用户询问以下问题时,**必须优先读取**根目录 `README.md`,并用用户能理解的业务语言回答: +当用户询问以下问题时,**必须优先读取**根目录 `README.md`(能力说明)与 `TUTORIAL.md`(逐步用法),并用用户能理解的业务语言回答: - 这个技能是做什么的 - 这个技能怎么用 @@ -97,7 +97,7 @@ python {baseDir}/scripts/main.py init-db **回答「怎么用 / 能做什么」时的要求:** -1. 以 `README.md` 的「能帮你做什么」「你可以这样告诉 Agent」「常见问题」等章节为主组织回答。 +1. 「能做什么 / 场景 / FAQ」以 `README.md` 为主;「第一次怎么用完」以 `TUTORIAL.md` 为主。 2. **禁止**在回答中粘贴 `python …/scripts/main.py …` 或其它命令行(除非用户明确索要命令,或自称技术人员/开发者)。 3. **禁止**为答用法而去 `dir` / `ls` / 列技能目录,或默认打开 `references/`、`development/`;仅当用户明确问命令、参数、集成或排错时再读 `references/`。 4. **不要**向普通用户暴露 Playwright、DOM、Python、RPA、库表名、`error_code` 等实现细节,除非用户明确询问技术实现。 @@ -106,14 +106,17 @@ python {baseDir}/scripts/main.py init-db - **不要**把 `SKILL.md`、`references/`、`development/` 中的技术细节直接作为用户回答。 - **只有当**用户明确询问命令、参数、输出结构、开发、调试、集成或排错时,才读取 `references/`;`development/` 主要给开发者 / 编码助手,对话 Agent **不必**默认打开。 -- 若 `README.md` 与 `SKILL.md` / `references` 表述冲突:对用户展示与市场说明以 `README.md` 为准;对执行契约以 `SKILL.md` / `references` 为准。 +- 若市场材料与 `SKILL.md` / `references` 表述冲突:对用户展示以 `README.md` / `TUTORIAL.md` 为准;对执行契约以 `SKILL.md` / `references` 为准。 - 用户未问技术实现时,**不要**讨论 slug 命名规则;开发者问命名或 slug 时,读取 `development/NAMING.md`。 ## 文档分工 | 文档 | 读者 | 用途 | |------|------|------| -| 根目录 `README.md` | 普通用户 | 技能市场详情页说明(`metadata.readme_md` 主来源) | +| 根目录 `README.md` | 普通用户 | 市场 **说明** Tab(`readme_md`) | +| 根目录 `TUTORIAL.md` | 普通用户 | 市场 **教程** Tab(`tutorial_md`) | +| 根目录 `DEMO.md` | 普通用户 | 市场 **演示** Tab(`demo_video_url` + `demo_md`) | +| 根目录 `CHANGELOG.md` | 普通用户 | 市场 **更新日志** Tab(按版本小节 → `changelog`) | | `SKILL.md`(本文) | LLM / OpenClaw 平台 | 技能入口、触发与运行契约摘要 | | `references/` | Agent 编排 / 调用 | CLI、Action、schema 契约(Agent 主读) | | `development/` | 开发者 / AI 编程代理 | 需求、开发教程、测试、深度技术规范 | @@ -132,7 +135,7 @@ python {baseDir}/scripts/main.py init-db 2. 业务技能仓库中**不得**存在 `.openclaw-skill-template`(仅 template 源仓库保留)。 3. 复制目录为你的新 skill 仓库,全局替换 `your-skill-slug` 等占位词。 4. 按 `development/DEVELOPMENT.md` 完成开发与文档定制。 -5. 用户市场说明写入根 `README.md`;Agent 调用契约见 `references/CLI.md`、`references/SCHEMA.md`、`references/ACTIONS.md`。 +5. 用户市场四 Tab 材料写入根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`;Agent 调用契约见 `references/CLI.md`、`references/SCHEMA.md`、`references/ACTIONS.md`。 6. 同步修改 `scripts/util/constants.py` 中的 `SKILL_SLUG` / `SKILL_VERSION`。 7. 本地 SQLite 的中文表名/字段名、标准时间字段与字段顺序规范见 `references/SCHEMA.md`。 diff --git a/TUTORIAL.md b/TUTORIAL.md new file mode 100644 index 0000000..1771e6d --- /dev/null +++ b/TUTORIAL.md @@ -0,0 +1,63 @@ +> **模板说明(复制后删除本段)** +> 本文对应技能市场 **「使用教程」** Tab(发布时同步为 `tutorial_md`)。 +> 面向普通用户写**可跟着做的步骤**,不要写 CLI、目录结构、release、开发规范。 +> 与根 `README.md`(技能说明)分工:README 讲「是什么 / 能做什么」;本文讲「第一次怎么用完」。 +> **复制后验收章节(标题可微调):**「开始前」「第一步…」「第二步…」「常见卡住怎么办」。 + +# 【技能名称】使用教程 + +用最短路径带用户完成一次成功使用。步骤要具体,可用「打开匠厂 → …」这类操作语言。 + +--- + +## 开始前 + +确认: + +1. 已安装并登录匠厂客户端 +2. 已在技能市场安装本技能(或更新到最新版) +3. 【如需】相关账号已登录、权限可用;需要的文件 / 时间范围 / 单号等已准备好 + +--- + +## 第一步:打开技能并说清目标 + +在匠厂里新建任务或打开对话,用自然语言说明要做什么,例如: + +> “帮我【完成某件业务事】,范围是【时间 / 对象 / 条件】。” + +建议一次只交代一件事;范围说清楚,减少来回确认。 + +--- + +## 第二步:按提示补充信息 + +如果 Agent 问你缺什么(账号、文件、筛选条件),按提示补充即可。 + +- 有文件时:按界面提示选择或拖入 +- 有账号时:确认已在对应平台登录,且具备操作权限 + +--- + +## 第三步:等待结果并核对 + +任务结束后,请核对: + +- 是否成功完成 +- 处理了多少条 / 哪些失败 +- 生成的文件、表格或记录是否在预期位置 + +若失败,先看失败原因说明,再按下一节排查。 + +--- + +## 常见卡住怎么办 + +| 现象 | 你可以先试 | +|------|------------| +| 提示未登录 / 无权限 | 确认匠厂已登录;业务账号是否在线、权限是否足够 | +| 提示缺少必要信息 | 把时间范围、单号、文件等说完整后再试一次 | +| 一直没有结果 | 到任务中心查看进度或失败原因;必要时重新发起 | +| 结果不对 | 用更明确的条件再说一次,或缩小范围重试 | + +仍无法解决时,把「你说了什么 + 界面提示原文」发给支持人员,便于排查。 diff --git a/assets/README.md b/assets/README.md index a45b940..0543ebb 100644 --- a/assets/README.md +++ b/assets/README.md @@ -6,6 +6,6 @@ `skill-actions.schema.json` 使用 `additionalProperties: false`。正式支持 `bind.tables`(toolbar Action 必填);`row`/`batch` placements 与 `concurrency`/`locks` 仍为预留。`placements` 与 `executionProfile` 正交——进任务中心只看 `async`,与入口无关。表级 Action 与 Agent 契约见 [`references/ACTIONS.md`](../references/ACTIONS.md);开发深度规范见 [`development/SKILL_ACTION_RUNTIME.md`](../development/SKILL_ACTION_RUNTIME.md)。 -- 用户市场说明见根目录 [`README.md`](../README.md) +- 用户市场四 Tab 见根目录 [`README.md`](../README.md) / [`TUTORIAL.md`](../TUTORIAL.md) / [`DEMO.md`](../DEMO.md) / [`CHANGELOG.md`](../CHANGELOG.md) - Agent 调用/编排参考见 [`references/`](../references/)(含 [`ACTIONS.md`](../references/ACTIONS.md)) - 开发规范见 [`development/`](../development/) diff --git a/development/DEVELOPMENT.md b/development/DEVELOPMENT.md index 9bb7ba7..e61f17a 100644 --- a/development/DEVELOPMENT.md +++ b/development/DEVELOPMENT.md @@ -106,6 +106,9 @@ your-skill/ ├─ tests/ ├─ .gitignore ├─ README.md +├─ TUTORIAL.md +├─ DEMO.md +├─ CHANGELOG.md ├─ requirements.txt ├─ release.ps1 └─ SKILL.md @@ -114,7 +117,10 @@ your-skill/ 各目录职责如下: - `assets/`:放示例输出、schema、静态说明资源 -- `README.md`:面向用户的市场详情页说明 +- `README.md`:市场 **说明** Tab(`readme_md`) +- `TUTORIAL.md`:市场 **教程** Tab(`tutorial_md`) +- `DEMO.md`:市场 **演示** Tab(`demo_video_url` + `demo_md`) +- `CHANGELOG.md`:市场 **更新日志** Tab(按版本小节同步 `changelog`) - `SKILL.md`:面向 LLM / 平台的技能入口 - `references/`:Agent 运行/编排/调用时渐进加载的补充上下文(如 CLI、SCHEMA) - `development/`:面向开发者与 AI 编程代理的开发资料、需求、测试与技术规范 @@ -305,7 +311,7 @@ git remote -v 复制后优先改下面这些地方: 1. `SKILL.md` -2. 根目录 `README.md`(用户市场说明) +2. 根目录市场四 Tab:`README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md` 3. `scripts/util/constants.py` 4. `references/` 与 `development/` 下的文案 5. `scripts/service/` 下的业务占位实现(优先改 `task_service.py`) @@ -339,7 +345,7 @@ git remote -v 如需浏览器自动化,不要在模板里保留空的 `platform_playwright.py`;请按业务新建 `xxx_playwright.py`(命名自定),并在 `task_service.py` 中按需引用。 -## 6. `SKILL.md` 与根 `README.md` 应该怎么写 +## 6. `SKILL.md` 与市场四 Tab 材料应该怎么写 ### `SKILL.md`(LLM / 平台入口) @@ -351,19 +357,26 @@ git remote -v - 何时触发本技能、CLI 入口摘要、运行契约要点 - 指向 `references/`(Agent 调用)与 `development/`(开发规范)的分工说明 -不要在 `SKILL.md` 里写大量用户市场文案或实现细节。 +不要在 `SKILL.md` 里写大量用户市场文案或实现细节;**不要**把演示视频 URL 写进 `SKILL.md`(放 `DEMO.md` frontmatter)。 -### 根 `README.md`(用户市场说明) +### 市场四 Tab(根目录,面向普通用户) -根 `README.md` 是技能市场详情页主来源(`metadata.readme_md`),面向普通用户。 +发布 CI 会把下列文件同步到技能市场详情 Tabs(有文件才更新对应字段): -应包含 YAML frontmatter 的 `description`(市场列表简介),正文用用户能理解的语言说明: +| 文件 | 市场 Tab | 同步字段 | +|------|----------|----------| +| `README.md` | 说明 | `readme_md`(frontmatter `description` 作列表简介) | +| `TUTORIAL.md` | 教程 | `tutorial_md` | +| `DEMO.md` | 演示 | `demo_md` + frontmatter `demo_video_url` | +| `CHANGELOG.md` | 更新日志 | 匹配当前 tag 版本的 `##` 小节 → `changelog` | -- 能做什么、适合什么场景、使用前准备什么 -- 如何自然语言告诉 Agent -- 执行结果、注意事项、常见问题 +**`README.md`**:能力与场景说明。含 frontmatter `description`;写能做什么、场景、准备、如何告诉 Agent、结果、注意事项、FAQ。不要写开发教程、目录规范、release、requirements。 -不要在根 `README.md` 里写开发教程、目录规范、release、requirements 等技术细节。 +**`TUTORIAL.md`**:第一次怎么用完的逐步操作。写「开始前 → 步骤 → 卡住怎么办」;不要写 CLI / 目录 / 开发规范。 + +**`DEMO.md`**:演示视频与补充说明。frontmatter 必须含 `demo_video_url`(无视频时用 `""`);正文可选。 + +**`CHANGELOG.md`**:每个正式版本一节(如 `## 1.0.46`)。打 tag 前为即将发布的版本新增小节;用户可读的变化,少写内部实现。 实现细节放在: @@ -402,9 +415,12 @@ metadata: 当前规范 skill 的文档按读者拆分: -**根 `README.md`** +**根市场材料(四 Tab)** -- 用户市场详情页说明(含 frontmatter `description`) +- `README.md` — 说明(含 frontmatter `description`) +- `TUTORIAL.md` — 使用教程 +- `DEMO.md` — 演示(`demo_video_url` + 正文) +- `CHANGELOG.md` — 按版本更新日志 **`SKILL.md`** @@ -442,7 +458,7 @@ metadata: 比如 `skill-actions.schema.json`、日志记录、机读 JSON 的 schema 不要把正式研发文档放到 `assets/`。 -用户说明进根 `README.md`;Agent 编排资料进 `references/`;开发规范进 `development/`。 +用户市场四 Tab 进根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`;Agent 编排资料进 `references/`;开发规范进 `development/`。 ## 9. `cli` 层怎么写 @@ -768,7 +784,7 @@ uses: client-jiangchang/jiangchang-platform-kit/.github/workflows/reusable-relea 如果工作流失败,不要继续做平台验证,而应该先回到代码仓库排查,例如: - 发布脚本是否正常推送 -- `SKILL.md`、根 `README.md`、`scripts/`、`references/`、`development/` 是否齐全 +- `SKILL.md`、根市场四 Tab(`README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`)、`scripts/`、`references/`、`development/` 是否齐全 - 工作流文件是否存在 - 发布包结构是否符合模板规范 @@ -903,7 +919,7 @@ uses: client-jiangchang/jiangchang-platform-kit/.github/workflows/reusable-relea 现在的新模板原则是: - 不做旧结构兼容 -- 用户说明在根 `README.md`,Agent 资料在 `references/`,开发规范在 `development/` +- 用户市场四 Tab 在根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`,Agent 资料在 `references/`,开发规范在 `development/` - 统一走 `scripts/main.py` 作为 CLI 入口 ### 错误 5:平台放 slug 最前 @@ -965,7 +981,7 @@ git remote add origin <新技能仓库 URL> 如果让一个新人照着做,我建议他按这个顺序: 1. 按 [`NAMING.md`](NAMING.md) 确定 slug,复制模板并改目录名 -2. 改 `SKILL.md` 与根 `README.md` +2. 改 `SKILL.md` 与根市场四 Tab(`README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`) 3. 改 `scripts/util/constants.py` 4. 改 `references/` 与 `development/` 5. 改 `scripts/cli/app.py` @@ -981,7 +997,7 @@ git remote add origin <新技能仓库 URL> - 目录结构统一 - 入口统一为 `scripts/main.py` -- 用户说明在根 `README.md`,Agent 资料在 `references/`,开发规范在 `development/` +- 用户市场四 Tab 在根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`,Agent 资料在 `references/`,开发规范在 `development/` - 业务核心逻辑统一放 `scripts/service/` - 不再使用旧模板历史结构 diff --git a/development/README.md b/development/README.md index d71f606..4e7fd40 100644 --- a/development/README.md +++ b/development/README.md @@ -17,4 +17,4 @@ 脚手架与 Git 防串库:[`../tools/README.md`](../tools/README.md)(`scaffold_skill.ps1`)。 Agent 调用契约见 [`../references/CLI.md`](../references/CLI.md)、[`../references/SCHEMA.md`](../references/SCHEMA.md)、[`../references/ACTIONS.md`](../references/ACTIONS.md)。 -用户市场说明见根目录 [`README.md`](../README.md),不要写进本目录。 +用户市场四 Tab 见根目录 [`README.md`](../README.md) / [`TUTORIAL.md`](../TUTORIAL.md) / [`DEMO.md`](../DEMO.md) / [`CHANGELOG.md`](../CHANGELOG.md),不要写进本目录。 diff --git a/development/REQUIREMENTS.md b/development/REQUIREMENTS.md index ee1ea13..7b048a7 100644 --- a/development/REQUIREMENTS.md +++ b/development/REQUIREMENTS.md @@ -98,7 +98,7 @@ - 目录结构必须符合当前 `skill-template` 规范 - 入口必须统一为 `scripts/main.py` -- 用户说明写在根 `README.md`;LLM/运行契约写在 `SKILL.md`;开发规范在 `development/` +- 用户市场四 Tab 写在根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`;LLM/运行契约写在 `SKILL.md`;开发规范在 `development/` - 输出格式应尽量机读友好;错误前缀统一为 `ERROR:` - Windows 环境下需保证 UTF-8 输出兼容 - 必须具备基本日志能力;敏感字段脱敏 diff --git a/references/ACTIONS.md b/references/ACTIONS.md index 3240f21..bcf7585 100644 --- a/references/ACTIONS.md +++ b/references/ACTIONS.md @@ -2,7 +2,7 @@ 本文件说明 `assets/actions.json` 与 `scripts/main.py` CLI 的对应关系,供 **Agent 编排**与宿主 **Skill Action Runtime** 使用。这是 Agent 侧关于 Action / 任务中心的**主契约**;实现细节与开发规范见 [`../development/SKILL_ACTION_RUNTIME.md`](../development/SKILL_ACTION_RUNTIME.md)。 -**边界:** 用户市场说明见根目录 [`README.md`](../README.md);CLI 参数见 [`CLI.md`](CLI.md)。 +**边界:** 用户市场四 Tab 见根目录 [`README.md`](../README.md) / [`TUTORIAL.md`](../TUTORIAL.md) / [`DEMO.md`](../DEMO.md) / [`CHANGELOG.md`](../CHANGELOG.md);CLI 参数见 [`CLI.md`](CLI.md)。 ## Agent 何时用 Action(与 CLI 的分工) diff --git a/references/README.md b/references/README.md index f5a3107..c262198 100644 --- a/references/README.md +++ b/references/README.md @@ -5,13 +5,16 @@ **边界规则:** - 本文**不得**包含 YAML frontmatter,**不得**包含 `description` 字段。 -- 技能市场详情与普通用户说明**必须**放在根目录 [`README.md`](../README.md)。 +- 技能市场四 Tab 材料**必须**放在根目录:[`README.md`](../README.md)、[`TUTORIAL.md`](../TUTORIAL.md)、[`DEMO.md`](../DEMO.md)、[`CHANGELOG.md`](../CHANGELOG.md)。 - **Agent 主读本目录**(`CLI.md` / `ACTIONS.md` / `SCHEMA.md`)与根 [`SKILL.md`](../SKILL.md)。 - [`../development/`](../development/) 是开发者 / 编码助手深度规范,**不是**对话 Agent 的默认读盘路径。 | 文档 | 用途 | |------|------| -| 根目录 [`README.md`](../README.md) | 用户市场详情页说明 | +| 根目录 [`README.md`](../README.md) | 市场说明 Tab(`readme_md`) | +| 根目录 [`TUTORIAL.md`](../TUTORIAL.md) | 市场教程 Tab(`tutorial_md`) | +| 根目录 [`DEMO.md`](../DEMO.md) | 市场演示 Tab(`demo_video_url` + `demo_md`) | +| 根目录 [`CHANGELOG.md`](../CHANGELOG.md) | 市场更新日志 Tab(版本小节 → `changelog`) | | [`SKILL.md`](../SKILL.md) | LLM / OpenClaw 平台技能入口与触发摘要 | | [`CLI.md`](CLI.md) | 共享 Python、命令行入口、参数与短操作契约 | | [`ACTIONS.md`](ACTIONS.md) | Skill Action、sync/async、任务中心、多入口(可选能力) | diff --git a/scripts/util/constants.py b/scripts/util/constants.py index 6583902..13caf7f 100644 --- a/scripts/util/constants.py +++ b/scripts/util/constants.py @@ -1,6 +1,6 @@ """技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。""" SKILL_SLUG = "your-skill-slug" -SKILL_VERSION = "1.0.45" +SKILL_VERSION = "1.0.46" LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug" PLATFORM_KIT_MIN_VERSION = "1.2.0" diff --git a/tests/test_docs_standards.py b/tests/test_docs_standards.py index bcc7378..c74bdf6 100644 --- a/tests/test_docs_standards.py +++ b/tests/test_docs_standards.py @@ -141,6 +141,47 @@ class TestDocsStandards(unittest.TestCase): msg="SKILL.md must state README.md is user-facing documentation", ) + def test_market_tab_docs_exist(self) -> None: + root = get_skill_root() + for name in ("README.md", "TUTORIAL.md", "DEMO.md", "CHANGELOG.md"): + path = os.path.join(root, name) + self.assertTrue(os.path.isfile(path), msg=f"{name} must exist at skill root") + + def test_demo_md_frontmatter_has_demo_video_url(self) -> None: + text = self._read("DEMO.md") + self.assertTrue(text.startswith("---"), "DEMO.md must start with YAML frontmatter") + frontmatter = self._parse_frontmatter(text) + self.assertIn( + "demo_video_url:", + frontmatter, + "DEMO.md frontmatter must include demo_video_url", + ) + + def test_changelog_has_section_for_skill_version(self) -> None: + skill_fm = self._parse_frontmatter(self._read("SKILL.md")) + match = re.search(r"(?m)^version:\s*[\"']?([0-9]+\.[0-9]+\.[0-9]+)", skill_fm) + self.assertIsNotNone(match, "SKILL.md must declare semver version") + version = match.group(1) + changelog = self._read("CHANGELOG.md") + self.assertRegex( + changelog, + rf"(?m)^##\s*\[?v?{re.escape(version)}\]?", + msg=f"CHANGELOG.md must include a ## section for version {version}", + ) + + def test_skill_md_documents_market_four_tabs(self) -> None: + text = self._read("SKILL.md") + for name in ("TUTORIAL.md", "DEMO.md", "CHANGELOG.md", "readme_md", "tutorial_md"): + self.assertIn(name, text, msg=f"SKILL.md must document market material {name}") + + def test_development_md_documents_market_four_tabs(self) -> None: + text = self._read("development/DEVELOPMENT.md") + self.assertIn("TUTORIAL.md", text) + self.assertIn("DEMO.md", text) + self.assertIn("CHANGELOG.md", text) + self.assertIn("demo_video_url", text) + self.assertIn("tutorial_md", text) + def test_naming_md_exists_and_covers_standards(self) -> None: text = self._read("development/NAMING.md") self.assertIn("verb-noun-platform", text)