Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ec9648148 | |||
| ec049fdc2a | |||
| 917df04712 |
68
.env.example
68
.env.example
@@ -1,30 +1,50 @@
|
|||||||
# ── 运行模式 / adapter 档位(见 development/ADAPTER.md)──
|
# 运行模式:决定本技能用模拟数据还是真实浏览器/接口去执行
|
||||||
OPENCLAW_TEST_TARGET=mock # mock | simulator_rpa | real_api | real_rpa
|
OPENCLAW_TEST_TARGET=mock # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认 mock,日常正式使用请改为 real_rpa
|
||||||
|
|
||||||
# ── 目标系统 ──
|
# 目标网站地址:技能要访问的网站或服务地址
|
||||||
TARGET_BASE_URL=https://sandbox.jc2009.com # 仿真/生产地址,可被进程环境变量覆盖
|
TARGET_BASE_URL=https://sandbox.jc2009.com # 填写完整网址(含 https://);换环境时再改,一般保持默认即可
|
||||||
|
|
||||||
# ── 默认账号(仅非敏感标识;密码走 account-manager)──
|
# 默认登录账号:仅填写非敏感的账号标识(如工号/登录名)
|
||||||
DEFAULT_LOGIN_ID=04110001
|
DEFAULT_LOGIN_ID=04110001 # 只填账号标识,不要填密码;密码请在「账号管理」中登记
|
||||||
|
|
||||||
# ── 浏览器 / RPA ──
|
# 是否显示浏览器窗口:打开后能否看见自动化操作过程
|
||||||
OPENCLAW_BROWSER_HEADLESS=0 # 0=有头(默认) 1=无头(CI)
|
OPENCLAW_BROWSER_HEADLESS=0 # 0=显示窗口(推荐,便于排查),1=后台静默运行
|
||||||
OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=开启反检测指纹(默认)
|
|
||||||
|
|
||||||
# ── 存证 ──
|
# 浏览器防检测:降低被网站识别为自动化工具的概率
|
||||||
OPENCLAW_RECORD_VIDEO=0 # 0=默认不录屏;1=启用录屏+字幕+旁白+背景音+MP4
|
OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=开启(推荐),0=关闭;一般保持默认
|
||||||
OPENCLAW_ARTIFACTS_ON_FAILURE=1 # 1=失败截图(默认)
|
|
||||||
|
|
||||||
# ── 节流 / 超时 ──
|
# 是否录制操作过程:用于留证、复现问题或向他人演示
|
||||||
STEP_DELAY_MIN=1.0 # 步骤间随机等待下限(秒)
|
OPENCLAW_RECORD_VIDEO=0 # 0=不录屏(默认),1=录屏并生成带说明的视频文件;需要留证时再改为 1
|
||||||
STEP_DELAY_MAX=5.0 # 步骤间随机等待上限(秒)
|
|
||||||
HUMAN_WAIT_TIMEOUT=180 # 滑块/验证码/2FA 等人工超时(秒)
|
|
||||||
|
|
||||||
# ── 数据目录子路径(见 development/DATA_PATHS.md;留空则用 skill 数据目录下默认子文件夹)──
|
# 失败时是否截图:任务出错时自动保存现场截图,便于排查
|
||||||
# 相对路径相对于 {JIANGCHANG_DATA_ROOT}/{USER_ID}/{slug}/,不是 workspace / CWD
|
OPENCLAW_ARTIFACTS_ON_FAILURE=1 # 1=失败时截图(推荐),0=不截图
|
||||||
# SKILL_DOWNLOAD_DIR=downloads
|
|
||||||
# SKILL_IMPORT_DIR=imports
|
# 步骤最短等待:两步操作之间随机停顿的下限,模拟真人节奏
|
||||||
# SKILL_EXPORT_DIR=exports
|
STEP_DELAY_MIN=1.0 # 单位:秒;一般保持默认,页面不稳定时可略调大
|
||||||
# SKILL_UPLOAD_DIR=uploads
|
|
||||||
# SKILL_CACHE_DIR=cache
|
# 步骤最长等待:两步操作之间随机停顿的上限
|
||||||
# SKILL_TEMP_DIR=temp
|
STEP_DELAY_MAX=5.0 # 单位:秒;须大于等于最短等待;一般保持默认
|
||||||
|
|
||||||
|
# 人工处理超时:遇到滑块、验证码、二次验证时,等待人工处理的最长时间
|
||||||
|
HUMAN_WAIT_TIMEOUT=180 # 单位:秒;来不及处理时可调大,如 300
|
||||||
|
|
||||||
|
# 以下为可选目录配置。一般不用改;取消注释并填写后,才覆盖默认子文件夹。
|
||||||
|
# 填写相对路径时,相对于本技能的数据目录(不是当前工作目录)。
|
||||||
|
|
||||||
|
# 下载目录:技能保存下载文件的位置
|
||||||
|
# SKILL_DOWNLOAD_DIR=downloads # 相对本技能数据目录;留空或保持注释则用默认 downloads
|
||||||
|
|
||||||
|
# 导入目录:待导入文件放置的位置
|
||||||
|
# SKILL_IMPORT_DIR=imports # 相对本技能数据目录;留空或保持注释则用默认 imports
|
||||||
|
|
||||||
|
# 导出目录:技能导出文件的保存位置
|
||||||
|
# SKILL_EXPORT_DIR=exports # 相对本技能数据目录;留空或保持注释则用默认 exports
|
||||||
|
|
||||||
|
# 上传目录:待上传文件放置的位置
|
||||||
|
# SKILL_UPLOAD_DIR=uploads # 相对本技能数据目录;留空或保持注释则用默认 uploads
|
||||||
|
|
||||||
|
# 缓存目录:临时缓存文件的位置
|
||||||
|
# SKILL_CACHE_DIR=cache # 相对本技能数据目录;留空或保持注释则用默认 cache
|
||||||
|
|
||||||
|
# 临时目录:运行中临时文件的位置
|
||||||
|
# SKILL_TEMP_DIR=temp # 相对本技能数据目录;留空或保持注释则用默认 temp
|
||||||
|
|||||||
24
CHANGELOG.md
Normal file
24
CHANGELOG.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
本文件对应技能市场 **「更新日志」** Tab。
|
||||||
|
发布 CI 会按当前 tag 版本(如 `v1.0.46` → `1.0.46`)提取匹配的 `##` 小节,写入该版本的 `changelog`。
|
||||||
|
|
||||||
|
约定:
|
||||||
|
|
||||||
|
- 每个正式版本一节,标题形如 `## 1.0.46` 或 `## [1.0.46] - YYYY-MM-DD`
|
||||||
|
- 小节正文写用户能看懂的变化(新能力、修复、注意事项),避免堆砌内部实现细节
|
||||||
|
- 打 tag 前**必须**为即将发布的版本新增一节;找不到匹配小节时,本次发布不会更新 changelog 字段
|
||||||
|
|
||||||
|
## 1.0.47
|
||||||
|
|
||||||
|
- 规范 `.env.example` 注释:面向「数据管理 → 配置管理」用户,行头说明「是什么」、行尾说明「怎么填」
|
||||||
|
- 去掉注释中的开发文档指向与黑话;`CONFIG.md` / 发布检查清单同步约束,避免各技能注释写法不一致
|
||||||
|
|
||||||
|
## 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 文档标准(见仓库提交说明)
|
||||||
24
DEMO.md
Normal file
24
DEMO.md
Normal file
@@ -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` 填上即可,正文可保留为补充说明。
|
||||||
@@ -6,6 +6,7 @@ description: "用用户能理解的方式说明这个技能能做什么、适合
|
|||||||
> 本文是技能市场详情与普通用户说明,**不是** Agent 参考索引、CLI 契约或开发文档。
|
> 本文是技能市场详情与普通用户说明,**不是** Agent 参考索引、CLI 契约或开发文档。
|
||||||
> frontmatter 的 `description` 必须是用户能看懂的一句话能力描述;**不得**写成 CLI、schema、references、development、契约、数据结构、开发规范或 Agent 参考索引。
|
> frontmatter 的 `description` 必须是用户能看懂的一句话能力描述;**不得**写成 CLI、schema、references、development、契约、数据结构、开发规范或 Agent 参考索引。
|
||||||
> 正文只回答用户关心的问题,**不要**把 Playwright、DOM、Python、RPA、references、development、schema 等作为面向用户的主说明内容;若业务上必须出现技术词,须用用户能理解的方式解释,且不能喧宾夺主。
|
> 正文只回答用户关心的问题,**不要**把 Playwright、DOM、Python、RPA、references、development、schema 等作为面向用户的主说明内容;若业务上必须出现技术词,须用用户能理解的方式解释,且不能喧宾夺主。
|
||||||
|
> **复制后验收章节(标题可微调,建议保留):**「能帮你做什么」「适合什么场景」「使用前需要准备什么」「你可以这样告诉 Agent」「执行后你会得到什么」「注意事项」「常见问题」。
|
||||||
|
|
||||||
# 【技能名称】
|
# 【技能名称】
|
||||||
|
|
||||||
|
|||||||
43
SKILL.md
43
SKILL.md
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: 技能开发模板(通用业务版)
|
name: 技能开发模板(通用业务版)
|
||||||
description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。"
|
description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。"
|
||||||
version: 1.0.44
|
version: 1.0.47
|
||||||
author: 深圳匠厂科技有限公司
|
author: 深圳匠厂科技有限公司
|
||||||
metadata:
|
metadata:
|
||||||
openclaw:
|
openclaw:
|
||||||
@@ -29,15 +29,28 @@ allowed-tools:
|
|||||||
- **`bind.tables`**:只决定数据管理出现在哪些表;含 `toolbar` 时**必须**显式非空绑定。
|
- **`bind.tables`**:只决定数据管理出现在哪些表;含 `toolbar` 时**必须**显式非空绑定。
|
||||||
- **`executionProfile`**:只决定执行方式——`sync` 当场返回结果,`async` 进**任务中心**。与 placements / 入口**无关**;每个 Action **必须**显式写 `sync` 或 `async`。
|
- **`executionProfile`**:只决定执行方式——`sync` 当场返回结果,`async` 进**任务中心**。与 placements / 入口**无关**;每个 Action **必须**显式写 `sync` 或 `async`。
|
||||||
- **同步数据**写技能本地库、不生成导出文件;**导出当前表**由宿主数据管理负责;特殊业务报告才另做 `export-*`。
|
- **同步数据**写技能本地库、不生成导出文件;**导出当前表**由宿主数据管理负责;特殊业务报告才另做 `export-*`。
|
||||||
|
- **准备 vs 执行(适用则拆)**:若技能存在「先写入/准备本地数据」与「再对外产生副作用」两段,Agent 必须能分开触发;禁止默认绑成不可拆的一步。一键无准备态的技能可跳过本条。
|
||||||
|
|
||||||
### 如何触发(决策树)
|
### 如何触发(能力类型)
|
||||||
|
|
||||||
| 你要做什么 | Agent 怎么做 | 进任务中心? |
|
| 你要做什么 | Agent 怎么做 | 进任务中心? |
|
||||||
|------------|--------------|--------------|
|
|------------|--------------|--------------|
|
||||||
| 短查询 / 只读 / 秒级(`health` / `version` / `stats` / `list` / `get` / `logs` 等) | OpenClaw bash/exec + **共享 Python** 跑 CLI(见下方「共享 Python」) | 否(CLI 当场结束) |
|
| 短查询 / 只读 / 秒级(`health` / `version` / `stats` / `list` / `get` / `logs` 等) | OpenClaw bash/exec + **共享 Python** 跑 CLI(见下方「共享 Python」) | 否(CLI 当场结束) |
|
||||||
| 已在 `actions.json` 声明且 `executionProfile: "sync"` 的能力 | 可用 `run_skill_action`,或同等效果的短 CLI(同一内核) | 否 |
|
| 已在 `actions.json` 声明且 `executionProfile: "sync"` 的能力 | 可用 `run_skill_action`,或同等效果的短 CLI(同一内核) | 否 |
|
||||||
| 长耗时 / RPA / 浏览器 / 需要进度或取消;或 `executionProfile: "async"` | **必须** `run_skill_action`(先 `list_skill_actions` / `get_skill_action`) | **是**(仅因为该 Action 是 async) |
|
| 长耗时 / RPA / 浏览器 / 需要进度或取消;或 `executionProfile: "async"` | **必须** `run_skill_action`(先 `list_skill_actions` / `get_skill_action`) | **是**(仅因为该 Action 是 async) |
|
||||||
| 用户只问用法 / 能做什么 | 读根目录 `README.md`;技术细节读 `references/` | — |
|
| 用户只问用法 / 能做什么 | 读根目录 `README.md`;逐步操作再读 `TUTORIAL.md`;**不要**为答用法去列目录或默认打开 `references/` | — |
|
||||||
|
|
||||||
|
### 用户意图路由表(业务技能复制后必改)
|
||||||
|
|
||||||
|
复制为业务技能后,**必须**用本技能真实意图改写下表(保留三列结构)。格子写清:短 CLI 子命令,或 `run_skill_action` → **具体 action id**(及主要 `input`)。勿留模板占位语上线。
|
||||||
|
|
||||||
|
| 用户意图(本技能自填) | Agent 怎么做 | 进任务中心? |
|
||||||
|
|------------------------|--------------|--------------|
|
||||||
|
| (例)查询 / 统计 / 列表 | 短 CLI:`<your-read-commands>` | 否 |
|
||||||
|
| (例)写入 / 导入 / 改本地状态 | 短 CLI:`<your-prep-commands>` | 否 |
|
||||||
|
| (例)长副作用 / RPA / 需进度 | `run_skill_action` → `<your-async-action-id>`,`input.…` | 是(因该 Action 为 async) |
|
||||||
|
|
||||||
|
有长任务 / RPA 时:上表至少一行指向真实的 async action id,且该 id 须出现在 `assets/actions.json`;细节分流见 `references/CLI.md`。
|
||||||
|
|
||||||
**硬规则:**
|
**硬规则:**
|
||||||
|
|
||||||
@@ -46,6 +59,7 @@ allowed-tools:
|
|||||||
3. **禁止** Agent 自行 `pip install`。
|
3. **禁止** Agent 自行 `pip install`。
|
||||||
4. Action **可选**:无数据管理 / 定时 / Agent 结构化调用需求时可不提供 `actions.json`;有长任务 / RPA 时**必须**提供至少一条 `executionProfile: "async"` 且 `placements` 含 `agent` 的 Action。
|
4. Action **可选**:无数据管理 / 定时 / Agent 结构化调用需求时可不提供 `actions.json`;有长任务 / RPA 时**必须**提供至少一条 `executionProfile: "async"` 且 `placements` 含 `agent` 的 Action。
|
||||||
5. **一个业务能力一个 Action**,用多个 `placements` 挂入口;底层仍是同一 `scripts/main.py` CLI。
|
5. **一个业务能力一个 Action**,用多个 `placements` 挂入口;底层仍是同一 `scripts/main.py` CLI。
|
||||||
|
6. 是否进任务中心**只**看该 Action 的 `executionProfile`,与数据管理 / 定时 / Agent 入口无关。
|
||||||
|
|
||||||
Agent 执行契约细节:`references/CLI.md`、`references/ACTIONS.md`、`references/SCHEMA.md`(不要把 `development/` 当 Agent 主读路径)。
|
Agent 执行契约细节:`references/CLI.md`、`references/ACTIONS.md`、`references/SCHEMA.md`(不要把 `development/` 当 Agent 主读路径)。
|
||||||
|
|
||||||
@@ -70,9 +84,9 @@ python {baseDir}/scripts/main.py init-db
|
|||||||
## 面向用户问答(LLM 规则)
|
## 面向用户问答(LLM 规则)
|
||||||
|
|
||||||
- 本文(`SKILL.md`)是 LLM / OpenClaw 平台读取的技能入口,**不是**用户市场说明。
|
- 本文(`SKILL.md`)是 LLM / OpenClaw 平台读取的技能入口,**不是**用户市场说明。
|
||||||
- 根目录 `README.md` 是面向普通用户的说明。
|
- 根目录市场材料面向普通用户(见下方「文档分工」),**不是** Agent 调用契约。
|
||||||
|
|
||||||
当用户询问以下问题时,**必须优先读取**根目录 `README.md`,并用用户能理解的业务语言回答:
|
当用户询问以下问题时,**必须优先读取**根目录 `README.md`(能力说明)与 `TUTORIAL.md`(逐步用法),并用用户能理解的业务语言回答:
|
||||||
|
|
||||||
- 这个技能是做什么的
|
- 这个技能是做什么的
|
||||||
- 这个技能怎么用
|
- 这个技能怎么用
|
||||||
@@ -81,17 +95,28 @@ python {baseDir}/scripts/main.py init-db
|
|||||||
- 执行后会得到什么
|
- 执行后会得到什么
|
||||||
- 能不能帮我完成某个业务任务
|
- 能不能帮我完成某个业务任务
|
||||||
|
|
||||||
|
**回答「怎么用 / 能做什么」时的要求:**
|
||||||
|
|
||||||
|
1. 「能做什么 / 场景 / FAQ」以 `README.md` 为主;「第一次怎么用完」以 `TUTORIAL.md` 为主。
|
||||||
|
2. **禁止**在回答中粘贴 `python …/scripts/main.py …` 或其它命令行(除非用户明确索要命令,或自称技术人员/开发者)。
|
||||||
|
3. **禁止**为答用法而去 `dir` / `ls` / 列技能目录,或默认打开 `references/`、`development/`;仅当用户明确问命令、参数、集成或排错时再读 `references/`。
|
||||||
|
4. **不要**向普通用户暴露 Playwright、DOM、Python、RPA、库表名、`error_code` 等实现细节,除非用户明确询问技术实现。
|
||||||
|
|
||||||
|
**文档读取边界:**
|
||||||
|
|
||||||
- **不要**把 `SKILL.md`、`references/`、`development/` 中的技术细节直接作为用户回答。
|
- **不要**把 `SKILL.md`、`references/`、`development/` 中的技术细节直接作为用户回答。
|
||||||
- **只有当**用户明确询问命令、参数、输出结构、开发、调试、集成或排错时,才读取 `references/`;`development/` 主要给开发者 / 编码助手,对话 Agent **不必**默认打开。
|
- **只有当**用户明确询问命令、参数、输出结构、开发、调试、集成或排错时,才读取 `references/`;`development/` 主要给开发者 / 编码助手,对话 Agent **不必**默认打开。
|
||||||
- 若 `README.md` 与 `SKILL.md` / `references` 表述冲突:对用户展示与市场说明以 `README.md` 为准;对执行契约以 `SKILL.md` / `references` 为准。
|
- 若市场材料与 `SKILL.md` / `references` 表述冲突:对用户展示以 `README.md` / `TUTORIAL.md` 为准;对执行契约以 `SKILL.md` / `references` 为准。
|
||||||
- 回答用户时**不要**暴露 Playwright、DOM、Python、RPA 等实现细节,除非用户明确询问技术实现。
|
|
||||||
- 用户未问技术实现时,**不要**讨论 slug 命名规则;开发者问命名或 slug 时,读取 `development/NAMING.md`。
|
- 用户未问技术实现时,**不要**讨论 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 平台 | 技能入口、触发与运行契约摘要 |
|
| `SKILL.md`(本文) | LLM / OpenClaw 平台 | 技能入口、触发与运行契约摘要 |
|
||||||
| `references/` | Agent 编排 / 调用 | CLI、Action、schema 契约(Agent 主读) |
|
| `references/` | Agent 编排 / 调用 | CLI、Action、schema 契约(Agent 主读) |
|
||||||
| `development/` | 开发者 / AI 编程代理 | 需求、开发教程、测试、深度技术规范 |
|
| `development/` | 开发者 / AI 编程代理 | 需求、开发教程、测试、深度技术规范 |
|
||||||
@@ -110,7 +135,7 @@ python {baseDir}/scripts/main.py init-db
|
|||||||
2. 业务技能仓库中**不得**存在 `.openclaw-skill-template`(仅 template 源仓库保留)。
|
2. 业务技能仓库中**不得**存在 `.openclaw-skill-template`(仅 template 源仓库保留)。
|
||||||
3. 复制目录为你的新 skill 仓库,全局替换 `your-skill-slug` 等占位词。
|
3. 复制目录为你的新 skill 仓库,全局替换 `your-skill-slug` 等占位词。
|
||||||
4. 按 `development/DEVELOPMENT.md` 完成开发与文档定制。
|
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`。
|
6. 同步修改 `scripts/util/constants.py` 中的 `SKILL_SLUG` / `SKILL_VERSION`。
|
||||||
7. 本地 SQLite 的中文表名/字段名、标准时间字段与字段顺序规范见 `references/SCHEMA.md`。
|
7. 本地 SQLite 的中文表名/字段名、标准时间字段与字段顺序规范见 `references/SCHEMA.md`。
|
||||||
|
|
||||||
|
|||||||
63
TUTORIAL.md
Normal file
63
TUTORIAL.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
> **模板说明(复制后删除本段)**
|
||||||
|
> 本文对应技能市场 **「使用教程」** Tab(发布时同步为 `tutorial_md`)。
|
||||||
|
> 面向普通用户写**可跟着做的步骤**,不要写 CLI、目录结构、release、开发规范。
|
||||||
|
> 与根 `README.md`(技能说明)分工:README 讲「是什么 / 能做什么」;本文讲「第一次怎么用完」。
|
||||||
|
> **复制后验收章节(标题可微调):**「开始前」「第一步…」「第二步…」「常见卡住怎么办」。
|
||||||
|
|
||||||
|
# 【技能名称】使用教程
|
||||||
|
|
||||||
|
用最短路径带用户完成一次成功使用。步骤要具体,可用「打开匠厂 → …」这类操作语言。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 开始前
|
||||||
|
|
||||||
|
确认:
|
||||||
|
|
||||||
|
1. 已安装并登录匠厂客户端
|
||||||
|
2. 已在技能市场安装本技能(或更新到最新版)
|
||||||
|
3. 【如需】相关账号已登录、权限可用;需要的文件 / 时间范围 / 单号等已准备好
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 第一步:打开技能并说清目标
|
||||||
|
|
||||||
|
在匠厂里新建任务或打开对话,用自然语言说明要做什么,例如:
|
||||||
|
|
||||||
|
> “帮我【完成某件业务事】,范围是【时间 / 对象 / 条件】。”
|
||||||
|
|
||||||
|
建议一次只交代一件事;范围说清楚,减少来回确认。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 第二步:按提示补充信息
|
||||||
|
|
||||||
|
如果 Agent 问你缺什么(账号、文件、筛选条件),按提示补充即可。
|
||||||
|
|
||||||
|
- 有文件时:按界面提示选择或拖入
|
||||||
|
- 有账号时:确认已在对应平台登录,且具备操作权限
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 第三步:等待结果并核对
|
||||||
|
|
||||||
|
任务结束后,请核对:
|
||||||
|
|
||||||
|
- 是否成功完成
|
||||||
|
- 处理了多少条 / 哪些失败
|
||||||
|
- 生成的文件、表格或记录是否在预期位置
|
||||||
|
|
||||||
|
若失败,先看失败原因说明,再按下一节排查。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常见卡住怎么办
|
||||||
|
|
||||||
|
| 现象 | 你可以先试 |
|
||||||
|
|------|------------|
|
||||||
|
| 提示未登录 / 无权限 | 确认匠厂已登录;业务账号是否在线、权限是否足够 |
|
||||||
|
| 提示缺少必要信息 | 把时间范围、单号、文件等说完整后再试一次 |
|
||||||
|
| 一直没有结果 | 到任务中心查看进度或失败原因;必要时重新发起 |
|
||||||
|
| 结果不对 | 用更明确的条件再说一次,或缩小范围重试 |
|
||||||
|
|
||||||
|
仍无法解决时,把「你说了什么 + 界面提示原文」发给支持人员,便于排查。
|
||||||
@@ -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)。
|
`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))
|
- Agent 调用/编排参考见 [`references/`](../references/)(含 [`ACTIONS.md`](../references/ACTIONS.md))
|
||||||
- 开发规范见 [`development/`](../development/)
|
- 开发规范见 [`development/`](../development/)
|
||||||
|
|||||||
@@ -11,44 +11,107 @@
|
|||||||
4. **技能升级合并缺失项**:`merge_missing_env_keys` 会把 `.env.example` 中新增、但用户 `.env` 尚未包含的 key **追加**进去(带注释块)。
|
4. **技能升级合并缺失项**:`merge_missing_env_keys` 会把 `.env.example` 中新增、但用户 `.env` 尚未包含的 key **追加**进去(带注释块)。
|
||||||
5. **敏感信息绝不进 `.env`**:密码/密钥/口令走 account-manager 的 `secret-ref`(见下"红线")。
|
5. **敏感信息绝不进 `.env`**:密码/密钥/口令走 account-manager 的 `secret-ref`(见下"红线")。
|
||||||
|
|
||||||
## 标准配置项(`.env` 分组)
|
## `.env.example` 注释 = 配置管理用户文案(硬规则)
|
||||||
|
|
||||||
每个 skill 的 `.env.example` 至少包含这些通用项(按需增减):
|
匠厂宿主「数据管理 → 配置管理」会把 `.env` / `.env.example` 的注释展示给**最终用户**(英文 key 可保留作标题)。因此注释必须按**产品文案**来写,不能按开发备忘录来写。
|
||||||
|
|
||||||
|
### 行头与行尾分工
|
||||||
|
|
||||||
|
| 位置 | 职责 | 要求 |
|
||||||
|
|------|------|------|
|
||||||
|
| **行头**(`KEY=` 上一行的 `# …`) | **是什么**:中文说明该配置项干什么 | **每个活跃 key 必有**一行完整中文行头 |
|
||||||
|
| **行尾**(`KEY=值` 同一行 ` #` 之后) | **怎么填**:可选值、单位、推荐默认、何时要改 | 有枚举、开关、单位时**必有**;纯自由文本也应尽量写清填法 |
|
||||||
|
|
||||||
|
宿主当前会把「行头 + 行尾」拼成 key 下方的多行说明。按上表书写后,用户看到的自然是「先懂是什么,再知道怎么填」。
|
||||||
|
|
||||||
|
**不要**依赖 `# ── 分组 ──` 装饰线给整组做唯一说明:宿主只会把行头挂到**紧挨着的下一个活跃 key**,后面的 key 不会自动继承。分组可用空行区分;**逐 key 自带行头(+ 行尾)才是硬要求**。
|
||||||
|
|
||||||
|
### 必须做到
|
||||||
|
|
||||||
|
1. 每个会进入配置管理的活跃 `KEY=` 都有完整中文**行头**。
|
||||||
|
2. 枚举 / `0|1` 开关 / 带单位的数值:必须有中文**行尾**,解释每个可选值或单位,并给出推荐。
|
||||||
|
3. 业务专属 key 同样适用本规则,不得只留英文 key、不写中文说明。
|
||||||
|
4. 开发向细节(四档 adapter 实现、录屏管线、路径解析 API)写在 `development/ADAPTER.md`、`RPA.md`、`DATA_PATHS.md` 等文档;**禁止**写进 `.env.example` 注释。
|
||||||
|
|
||||||
|
### 禁止出现在注释中的内容
|
||||||
|
|
||||||
|
- `见 development/...`、`见 ADAPTER.md`、`见 RPA.md`、`见 DATA_PATHS.md` 等仓库文档指向
|
||||||
|
- 默认假设读者是开发者的黑话:如单独甩 `adapter 档位`、`CI`、`account-manager`、`CWD`、`workspace` 而不解释
|
||||||
|
- 只写裸枚举(如 `mock | real_rpa`)却不说明每个值对用户意味着什么
|
||||||
|
- 多个 key 共用一个行头,后面的 key 没有任何自己的说明
|
||||||
|
|
||||||
|
若必须提到账号体系:写成用户能懂的「请在账号管理中登记密码 / 平台标识须一致」,不要只写内部模块名。
|
||||||
|
|
||||||
|
### 正例
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
# ── 运行模式 / adapter 档位(见 ADAPTER.md)──
|
# 运行模式:决定本技能用模拟数据还是真实浏览器/接口去执行
|
||||||
OPENCLAW_TEST_TARGET=mock # mock | simulator_rpa | real_api | real_rpa
|
OPENCLAW_TEST_TARGET=mock # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认 mock,日常正式使用请改为 real_rpa
|
||||||
|
|
||||||
# ── 目标系统(示例占位,复制后改为业务地址)──
|
# 是否显示浏览器窗口:打开后能否看见自动化操作过程
|
||||||
TARGET_BASE_URL=https://sandbox.jc2009.com
|
OPENCLAW_BROWSER_HEADLESS=0 # 0=显示窗口(推荐,便于排查),1=后台静默运行
|
||||||
|
|
||||||
# ── 默认账号(仅非敏感标识;密码走 account-manager)──
|
|
||||||
# 浏览器 RPA simulator_rpa 联调账号来自 account-manager(platform + profile_dir),不是此处的 DEFAULT_LOGIN_ID
|
|
||||||
DEFAULT_LOGIN_ID=04110001
|
|
||||||
|
|
||||||
# ── 浏览器 / RPA ──
|
|
||||||
OPENCLAW_BROWSER_HEADLESS=0 # 0=有头(默认) 1=无头(CI)
|
|
||||||
OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=开启反检测指纹(默认)
|
|
||||||
|
|
||||||
# ── 录屏与失败存证 ──
|
|
||||||
OPENCLAW_RECORD_VIDEO=0 # 0=默认不录屏;1=启用录屏+字幕+旁白+背景音+MP4(见 RPA.md)
|
|
||||||
OPENCLAW_ARTIFACTS_ON_FAILURE=1 # 1=失败截图(默认)
|
|
||||||
|
|
||||||
# ── 节流 / 超时 ──
|
|
||||||
STEP_DELAY_MIN=1.0
|
|
||||||
STEP_DELAY_MAX=5.0
|
|
||||||
HUMAN_WAIT_TIMEOUT=180 # 滑块/验证码/2FA 等人工超时(秒)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 反例(禁止)
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# ── 运行模式 / adapter 档位(见 development/ADAPTER.md)──
|
||||||
|
OPENCLAW_TEST_TARGET=real_rpa # 生产默认真实 RPA;单测/CI 可改为 mock
|
||||||
|
|
||||||
|
# ── 好看视频 / 百度账号(须与 account-manager 平台 key 一致)──
|
||||||
|
TARGET_PLATFORM=baidu
|
||||||
|
HAOKAN_VIDEO_SELECTOR=video.art-video
|
||||||
|
```
|
||||||
|
|
||||||
|
问题:文档路径与开发黑话;行尾半给用户半给 CI;后续 key 无行头/行尾,用户只看到英文名。
|
||||||
|
|
||||||
|
## 标准配置项(`.env` 分组)
|
||||||
|
|
||||||
|
每个 skill 的 `.env.example` 至少包含这些通用项(按需增减)。**注释写法须与仓库根目录 `.env.example` 保持同级清晰度**(行头 = 是什么,行尾 = 怎么填):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# 运行模式:决定本技能用模拟数据还是真实浏览器/接口去执行
|
||||||
|
OPENCLAW_TEST_TARGET=mock # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认 mock,日常正式使用请改为 real_rpa
|
||||||
|
|
||||||
|
# 目标网站地址:技能要访问的网站或服务地址
|
||||||
|
TARGET_BASE_URL=https://sandbox.jc2009.com # 填写完整网址(含 https://);换环境时再改,一般保持默认即可
|
||||||
|
|
||||||
|
# 默认登录账号:仅填写非敏感的账号标识(如工号/登录名)
|
||||||
|
DEFAULT_LOGIN_ID=04110001 # 只填账号标识,不要填密码;密码请在「账号管理」中登记
|
||||||
|
|
||||||
|
# 是否显示浏览器窗口:打开后能否看见自动化操作过程
|
||||||
|
OPENCLAW_BROWSER_HEADLESS=0 # 0=显示窗口(推荐,便于排查),1=后台静默运行
|
||||||
|
|
||||||
|
# 浏览器防检测:降低被网站识别为自动化工具的概率
|
||||||
|
OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=开启(推荐),0=关闭;一般保持默认
|
||||||
|
|
||||||
|
# 是否录制操作过程:用于留证、复现问题或向他人演示
|
||||||
|
OPENCLAW_RECORD_VIDEO=0 # 0=不录屏(默认),1=录屏并生成带说明的视频文件;需要留证时再改为 1
|
||||||
|
|
||||||
|
# 失败时是否截图:任务出错时自动保存现场截图,便于排查
|
||||||
|
OPENCLAW_ARTIFACTS_ON_FAILURE=1 # 1=失败时截图(推荐),0=不截图
|
||||||
|
|
||||||
|
# 步骤最短等待:两步操作之间随机停顿的下限,模拟真人节奏
|
||||||
|
STEP_DELAY_MIN=1.0 # 单位:秒;一般保持默认,页面不稳定时可略调大
|
||||||
|
|
||||||
|
# 步骤最长等待:两步操作之间随机停顿的上限
|
||||||
|
STEP_DELAY_MAX=5.0 # 单位:秒;须大于等于最短等待;一般保持默认
|
||||||
|
|
||||||
|
# 人工处理超时:遇到滑块、验证码、二次验证时,等待人工处理的最长时间
|
||||||
|
HUMAN_WAIT_TIMEOUT=180 # 单位:秒;来不及处理时可调大,如 300
|
||||||
|
```
|
||||||
|
|
||||||
|
四档运行模式的**实现与测试约定**见 [`ADAPTER.md`](ADAPTER.md);录屏管线见 [`RPA.md`](RPA.md)。这些内容**不要**写回 `.env.example` 注释。
|
||||||
|
|
||||||
**业务专属配置必须带技能前缀**(如 `DEMO_XXX`、`MY_SKILL_XXX`、`SKILL_DOWNLOAD_DIR`),**不要污染全局命名空间**(禁止 `SCRAPE_1688_*`、`RECEIVE_ORDER_*` 等跨技能前缀写入模板)。
|
**业务专属配置必须带技能前缀**(如 `DEMO_XXX`、`MY_SKILL_XXX`、`SKILL_DOWNLOAD_DIR`),**不要污染全局命名空间**(禁止 `SCRAPE_1688_*`、`RECEIVE_ORDER_*` 等跨技能前缀写入模板)。
|
||||||
|
|
||||||
### 数据目录子路径(下载 / 导入 / 导出)
|
### 数据目录子路径(下载 / 导入 / 导出)
|
||||||
|
|
||||||
技能**自己写入**的文件默认在 `{JIANGCHANG_DATA_ROOT}/{USER_ID}/{slug}/` 下标准子目录(`downloads/`、`imports/`、`exports/` 等)。须通过 `util.runtime_paths.resolve_data_path()` 或 `get_*_dir()` 解析,**禁止** `os.path.abspath(config.get(...))` 相对 CWD。
|
技能**自己写入**的文件默认在 `{JIANGCHANG_DATA_ROOT}/{USER_ID}/{slug}/` 下标准子目录(`downloads/`、`imports/`、`exports/` 等)。须通过 `util.runtime_paths.resolve_data_path()` 或 `get_*_dir()` 解析,**禁止** `os.path.abspath(config.get(...))` 相对 CWD。
|
||||||
|
|
||||||
- 权威说明:[`DATA_PATHS.md`](DATA_PATHS.md)
|
- 权威说明(开发):[`DATA_PATHS.md`](DATA_PATHS.md)
|
||||||
- `.env.example` 中路径类配置**留空即用默认**;若写相对路径,必须相对 **skill 数据目录**,**禁止** `./outputs/...` 这类相对 workspace 的写法
|
- `.env.example` 中路径类配置**留空或保持注释即用默认**;若写相对路径,必须相对 **skill 数据目录**,**禁止** `./outputs/...` 这类相对 workspace 的写法
|
||||||
- 可选 env:`SKILL_DOWNLOAD_DIR`、`SKILL_IMPORT_DIR`、`SKILL_EXPORT_DIR` 等(见 DATA_PATHS.md)
|
- 可选 env:`SKILL_DOWNLOAD_DIR`、`SKILL_IMPORT_DIR`、`SKILL_EXPORT_DIR` 等;若作为活跃 key 出现在配置管理中,同样须有用户向行头/行尾(见模板根 `.env.example`)
|
||||||
|
|
||||||
### 录屏开关(`OPENCLAW_RECORD_VIDEO`)
|
### 录屏开关(`OPENCLAW_RECORD_VIDEO`)
|
||||||
|
|
||||||
@@ -110,7 +173,7 @@ config.get_float("STEP_DELAY_MIN", 1.0)
|
|||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- `RPA.md` — 三端 RPA 标准与各开关含义
|
- `RPA.md` — 三端 RPA 标准与各开关含义(开发向;勿写入 `.env` 注释)
|
||||||
- `ADAPTER.md` — `OPENCLAW_TEST_TARGET` 四档模式
|
- `ADAPTER.md` — `OPENCLAW_TEST_TARGET` 四档模式(开发向;勿写入 `.env` 注释)
|
||||||
- `RUNTIME.md` — `JIANGCHANG_DATA_ROOT` 与数据根约定
|
- `RUNTIME.md` — `JIANGCHANG_DATA_ROOT` 与数据根约定
|
||||||
- `DATA_PATHS.md` — 下载/导入/导出等子目录与 `resolve_data_path` 规范
|
- `DATA_PATHS.md` — 下载/导入/导出等子目录与 `resolve_data_path` 规范
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ your-skill/
|
|||||||
├─ tests/
|
├─ tests/
|
||||||
├─ .gitignore
|
├─ .gitignore
|
||||||
├─ README.md
|
├─ README.md
|
||||||
|
├─ TUTORIAL.md
|
||||||
|
├─ DEMO.md
|
||||||
|
├─ CHANGELOG.md
|
||||||
├─ requirements.txt
|
├─ requirements.txt
|
||||||
├─ release.ps1
|
├─ release.ps1
|
||||||
└─ SKILL.md
|
└─ SKILL.md
|
||||||
@@ -114,7 +117,10 @@ your-skill/
|
|||||||
各目录职责如下:
|
各目录职责如下:
|
||||||
|
|
||||||
- `assets/`:放示例输出、schema、静态说明资源
|
- `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 / 平台的技能入口
|
- `SKILL.md`:面向 LLM / 平台的技能入口
|
||||||
- `references/`:Agent 运行/编排/调用时渐进加载的补充上下文(如 CLI、SCHEMA)
|
- `references/`:Agent 运行/编排/调用时渐进加载的补充上下文(如 CLI、SCHEMA)
|
||||||
- `development/`:面向开发者与 AI 编程代理的开发资料、需求、测试与技术规范
|
- `development/`:面向开发者与 AI 编程代理的开发资料、需求、测试与技术规范
|
||||||
@@ -305,7 +311,7 @@ git remote -v
|
|||||||
复制后优先改下面这些地方:
|
复制后优先改下面这些地方:
|
||||||
|
|
||||||
1. `SKILL.md`
|
1. `SKILL.md`
|
||||||
2. 根目录 `README.md`(用户市场说明)
|
2. 根目录市场四 Tab:`README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`
|
||||||
3. `scripts/util/constants.py`
|
3. `scripts/util/constants.py`
|
||||||
4. `references/` 与 `development/` 下的文案
|
4. `references/` 与 `development/` 下的文案
|
||||||
5. `scripts/service/` 下的业务占位实现(优先改 `task_service.py`)
|
5. `scripts/service/` 下的业务占位实现(优先改 `task_service.py`)
|
||||||
@@ -339,7 +345,7 @@ git remote -v
|
|||||||
|
|
||||||
如需浏览器自动化,不要在模板里保留空的 `platform_playwright.py`;请按业务新建 `xxx_playwright.py`(命名自定),并在 `task_service.py` 中按需引用。
|
如需浏览器自动化,不要在模板里保留空的 `platform_playwright.py`;请按业务新建 `xxx_playwright.py`(命名自定),并在 `task_service.py` 中按需引用。
|
||||||
|
|
||||||
## 6. `SKILL.md` 与根 `README.md` 应该怎么写
|
## 6. `SKILL.md` 与市场四 Tab 材料应该怎么写
|
||||||
|
|
||||||
### `SKILL.md`(LLM / 平台入口)
|
### `SKILL.md`(LLM / 平台入口)
|
||||||
|
|
||||||
@@ -351,19 +357,26 @@ git remote -v
|
|||||||
- 何时触发本技能、CLI 入口摘要、运行契约要点
|
- 何时触发本技能、CLI 入口摘要、运行契约要点
|
||||||
- 指向 `references/`(Agent 调用)与 `development/`(开发规范)的分工说明
|
- 指向 `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` |
|
||||||
|
|
||||||
- 能做什么、适合什么场景、使用前准备什么
|
**`README.md`**:能力与场景说明。含 frontmatter `description`;写能做什么、场景、准备、如何告诉 Agent、结果、注意事项、FAQ。不要写开发教程、目录规范、release、requirements。
|
||||||
- 如何自然语言告诉 Agent
|
|
||||||
- 执行结果、注意事项、常见问题
|
|
||||||
|
|
||||||
不要在根 `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 的文档按读者拆分:
|
当前规范 skill 的文档按读者拆分:
|
||||||
|
|
||||||
**根 `README.md`**
|
**根市场材料(四 Tab)**
|
||||||
|
|
||||||
- 用户市场详情页说明(含 frontmatter `description`)
|
- `README.md` — 说明(含 frontmatter `description`)
|
||||||
|
- `TUTORIAL.md` — 使用教程
|
||||||
|
- `DEMO.md` — 演示(`demo_video_url` + 正文)
|
||||||
|
- `CHANGELOG.md` — 按版本更新日志
|
||||||
|
|
||||||
**`SKILL.md`**
|
**`SKILL.md`**
|
||||||
|
|
||||||
@@ -442,7 +458,7 @@ metadata:
|
|||||||
比如 `skill-actions.schema.json`、日志记录、机读 JSON 的 schema
|
比如 `skill-actions.schema.json`、日志记录、机读 JSON 的 schema
|
||||||
|
|
||||||
不要把正式研发文档放到 `assets/`。
|
不要把正式研发文档放到 `assets/`。
|
||||||
用户说明进根 `README.md`;Agent 编排资料进 `references/`;开发规范进 `development/`。
|
用户市场四 Tab 进根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`;Agent 编排资料进 `references/`;开发规范进 `development/`。
|
||||||
|
|
||||||
## 9. `cli` 层怎么写
|
## 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/` 是否齐全
|
||||||
- 工作流文件是否存在
|
- 工作流文件是否存在
|
||||||
- 发布包结构是否符合模板规范
|
- 发布包结构是否符合模板规范
|
||||||
|
|
||||||
@@ -837,6 +853,7 @@ uses: client-jiangchang/jiangchang-platform-kit/.github/workflows/reusable-relea
|
|||||||
- [ ] `service` 下的核心业务文件(如 `task_service.py`)已按领域改名并实现
|
- [ ] `service` 下的核心业务文件(如 `task_service.py`)已按领域改名并实现
|
||||||
- [ ] 没有残留旧平台名
|
- [ ] 没有残留旧平台名
|
||||||
- [ ] `health` / `version` 可运行
|
- [ ] `health` / `version` 可运行
|
||||||
|
- [ ] `.env.example` 注释已按 [`CONFIG.md`](CONFIG.md)「行头 = 是什么、行尾 = 怎么填」写全(面向配置管理用户;无 `见 development/...` 等开发文档指向)
|
||||||
- [ ] `.gitignore` 生效,没有把 `__pycache__` 提交进去
|
- [ ] `.gitignore` 生效,没有把 `__pycache__` 提交进去
|
||||||
- [ ] `release.ps1` 存在(发布前会自动跑 `python tests/run_tests.py -v`;失败不得打 tag)
|
- [ ] `release.ps1` 存在(发布前会自动跑 `python tests/run_tests.py -v`;失败不得打 tag)
|
||||||
- [ ] `.github/workflows/release_skill.yaml` 存在
|
- [ ] `.github/workflows/release_skill.yaml` 存在
|
||||||
@@ -903,7 +920,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 入口
|
- 统一走 `scripts/main.py` 作为 CLI 入口
|
||||||
|
|
||||||
### 错误 5:平台放 slug 最前
|
### 错误 5:平台放 slug 最前
|
||||||
@@ -965,7 +982,7 @@ git remote add origin <新技能仓库 URL>
|
|||||||
如果让一个新人照着做,我建议他按这个顺序:
|
如果让一个新人照着做,我建议他按这个顺序:
|
||||||
|
|
||||||
1. 按 [`NAMING.md`](NAMING.md) 确定 slug,复制模板并改目录名
|
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`
|
3. 改 `scripts/util/constants.py`
|
||||||
4. 改 `references/` 与 `development/`
|
4. 改 `references/` 与 `development/`
|
||||||
5. 改 `scripts/cli/app.py`
|
5. 改 `scripts/cli/app.py`
|
||||||
@@ -981,7 +998,7 @@ git remote add origin <新技能仓库 URL>
|
|||||||
|
|
||||||
- 目录结构统一
|
- 目录结构统一
|
||||||
- 入口统一为 `scripts/main.py`
|
- 入口统一为 `scripts/main.py`
|
||||||
- 用户说明在根 `README.md`,Agent 资料在 `references/`,开发规范在 `development/`
|
- 用户市场四 Tab 在根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`,Agent 资料在 `references/`,开发规范在 `development/`
|
||||||
- 业务核心逻辑统一放 `scripts/service/`
|
- 业务核心逻辑统一放 `scripts/service/`
|
||||||
- 不再使用旧模板历史结构
|
- 不再使用旧模板历史结构
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
| POLICY-RUNTIME-001 | 不得 vendored `scripts/jiangchang_skill_core/` | development/RUNTIME.md §共享 Python Runtime、§明确禁止 | hard | 目录不存在检查 | `tests/test_development_policy_guard.py::TestPolicyRuntime001`(另见 `tests/test_platform_import.py`) |
|
| POLICY-RUNTIME-001 | 不得 vendored `scripts/jiangchang_skill_core/` | development/RUNTIME.md §共享 Python Runtime、§明确禁止 | hard | 目录不存在检查 | `tests/test_development_policy_guard.py::TestPolicyRuntime001`(另见 `tests/test_platform_import.py`) |
|
||||||
| POLICY-RUNTIME-002 | `requirements.txt` 非注释依赖行不得声明 `jiangchang-platform-kit` / `playwright` | development/RUNTIME.md §共享 Python Runtime;development/DEVELOPMENT.md §3.1 requirements.txt 依赖规范 | hard | 解析依赖行 | `tests/test_development_policy_guard.py::TestPolicyRuntime002`(另见 `tests/test_platform_import.py`) |
|
| POLICY-RUNTIME-002 | `requirements.txt` 非注释依赖行不得声明 `jiangchang-platform-kit` / `playwright` | development/RUNTIME.md §共享 Python Runtime;development/DEVELOPMENT.md §3.1 requirements.txt 依赖规范 | hard | 解析依赖行 | `tests/test_development_policy_guard.py::TestPolicyRuntime002`(另见 `tests/test_platform_import.py`) |
|
||||||
| POLICY-RUNTIME-003 | Agent/CLI 文档须要求共享 Python(python-runtime / PATH 上的 `python` + `{baseDir}`);须明确**禁止**对技能脚本使用 `uv run python` | development/RUNTIME.md;references/CLI.md;SKILL.md | hard | 文档标记扫描 | `tests/test_docs_standards.py::test_cli_md_requires_shared_python_not_uv_run`;`tests/test_docs_standards.py::test_skill_md_requires_shared_python_not_uv_run` |
|
| POLICY-RUNTIME-003 | Agent/CLI 文档须要求共享 Python(python-runtime / PATH 上的 `python` + `{baseDir}`);须明确**禁止**对技能脚本使用 `uv run python` | development/RUNTIME.md;references/CLI.md;SKILL.md | hard | 文档标记扫描 | `tests/test_docs_standards.py::test_cli_md_requires_shared_python_not_uv_run`;`tests/test_docs_standards.py::test_skill_md_requires_shared_python_not_uv_run` |
|
||||||
|
| POLICY-AGENT-001 | `SKILL.md` 须含「用户意图路由表」结构;`CLI.md` 须含短 CLI 白名单 / Action 强制黑名单表;用法回答须禁止无故粘贴 CLI、禁止为答用法列目录挖 references | SKILL.md;references/CLI.md | hard | 文档标记扫描 | `tests/test_docs_standards.py::test_skill_md_has_intent_routing_table`;`tests/test_docs_standards.py::test_cli_md_has_agent_routing_tables`;`tests/test_docs_standards.py::test_skill_md_how_to_forbids_cli_paste` |
|
||||||
| POLICY-INSTALL-001 | 交付执行文件不得含 `pip install` / `python -m pip install` / `uv pip install` / `playwright install` | development/RUNTIME.md §共享 Python Runtime;development/RPA.md §1.4 Playwright 与安装边界;development/DEVELOPMENT.md §3.1 | hard | 扫描 `scripts/**/*.py`、`*.ps1`、`*.sh`、`requirements.txt`、`.github/workflows/*`(不扫 `development/*.md`) | `tests/test_development_policy_guard.py::TestPolicyInstall001` |
|
| POLICY-INSTALL-001 | 交付执行文件不得含 `pip install` / `python -m pip install` / `uv pip install` / `playwright install` | development/RUNTIME.md §共享 Python Runtime;development/RPA.md §1.4 Playwright 与安装边界;development/DEVELOPMENT.md §3.1 | hard | 扫描 `scripts/**/*.py`、`*.ps1`、`*.sh`、`requirements.txt`、`.github/workflows/*`(不扫 `development/*.md`) | `tests/test_development_policy_guard.py::TestPolicyInstall001` |
|
||||||
| POLICY-CONFIG-001 | 仓库根目录必须存在 `.env.example` | development/CONFIG.md §核心原则、§标准配置项 | hard | 文件存在性 | `tests/test_development_policy_guard.py::TestPolicyConfig001` |
|
| POLICY-CONFIG-001 | 仓库根目录必须存在 `.env.example` | development/CONFIG.md §核心原则、§标准配置项 | hard | 文件存在性 | `tests/test_development_policy_guard.py::TestPolicyConfig001` |
|
||||||
| POLICY-CONFIG-002 | `.gitignore` 必须忽略 `.env` 与 `*.env.local` | development/CONFIG.md §红线:敏感信息不进 .env | hard | 解析 `.gitignore` 行 | `tests/test_development_policy_guard.py::TestPolicyConfig002` |
|
| POLICY-CONFIG-002 | `.gitignore` 必须忽略 `.env` 与 `*.env.local` | development/CONFIG.md §红线:敏感信息不进 .env | hard | 解析 `.gitignore` 行 | `tests/test_development_policy_guard.py::TestPolicyConfig002` |
|
||||||
|
|||||||
@@ -17,4 +17,4 @@
|
|||||||
脚手架与 Git 防串库:[`../tools/README.md`](../tools/README.md)(`scaffold_skill.ps1`)。
|
脚手架与 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)。
|
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),不要写进本目录。
|
||||||
|
|||||||
@@ -98,7 +98,7 @@
|
|||||||
|
|
||||||
- 目录结构必须符合当前 `skill-template` 规范
|
- 目录结构必须符合当前 `skill-template` 规范
|
||||||
- 入口必须统一为 `scripts/main.py`
|
- 入口必须统一为 `scripts/main.py`
|
||||||
- 用户说明写在根 `README.md`;LLM/运行契约写在 `SKILL.md`;开发规范在 `development/`
|
- 用户市场四 Tab 写在根 `README.md` / `TUTORIAL.md` / `DEMO.md` / `CHANGELOG.md`;LLM/运行契约写在 `SKILL.md`;开发规范在 `development/`
|
||||||
- 输出格式应尽量机读友好;错误前缀统一为 `ERROR:`
|
- 输出格式应尽量机读友好;错误前缀统一为 `ERROR:`
|
||||||
- Windows 环境下需保证 UTF-8 输出兼容
|
- Windows 环境下需保证 UTF-8 输出兼容
|
||||||
- 必须具备基本日志能力;敏感字段脱敏
|
- 必须具备基本日志能力;敏感字段脱敏
|
||||||
|
|||||||
@@ -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)。
|
本文件说明 `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 的分工)
|
## Agent 何时用 Action(与 CLI 的分工)
|
||||||
|
|
||||||
@@ -18,6 +18,23 @@
|
|||||||
|
|
||||||
禁止对长任务 `exec`/`bash` + `process poll` 干等 CLI。禁止 `uv run python` 跑技能脚本。
|
禁止对长任务 `exec`/`bash` + `process poll` 干等 CLI。禁止 `uv run python` 跑技能脚本。
|
||||||
|
|
||||||
|
## async 副作用 Action 最小组合(复制验收 checklist)
|
||||||
|
|
||||||
|
对每个「会开浏览器 / 长耗时 / 需进度或取消」的 Action,声明时建议同时满足:
|
||||||
|
|
||||||
|
1. `executionProfile: "async"`(进入任务中心)
|
||||||
|
2. 若要让 Agent 触发:`placements` **含** `agent`
|
||||||
|
3. 有可感知副作用时:提供 `confirmation.message`
|
||||||
|
4. 需要用户/Agent 入参时:简单 `inputSchema` + entrypoint 中的 `{{fieldName}}`
|
||||||
|
5. `SKILL.md`「用户意图路由表」与 `CLI.md`「Action 强制黑名单」**出现同一 action id / 命令**
|
||||||
|
|
||||||
|
默认模板 `assets/actions.json` 仅含诊断类 sync Action,**不要**为通过本 checklist 而塞假业务 Action;业务技能按需添加。完整字段见下文 Phase 1。
|
||||||
|
|
||||||
|
## 可选:域前缀 CLI(嵌套子命令)
|
||||||
|
|
||||||
|
小技能可继续扁平:`entrypoint.command = "run"`。
|
||||||
|
命令变多时,可采用**域前缀**:`command` 为域(如 `<domain>`),业务动词与参数放在 `args` 数组(如 `["<verb>", "--flag", "{{field}}"]`)。与扁平入口等价,须仍指向同一 domain service。
|
||||||
|
|
||||||
## 模板严格规范 vs 宿主向后兼容
|
## 模板严格规范 vs 宿主向后兼容
|
||||||
|
|
||||||
| 角色 | 定位 |
|
| 角色 | 定位 |
|
||||||
|
|||||||
@@ -18,6 +18,17 @@ python {baseDir}/scripts/main.py <command> …
|
|||||||
**禁止**对技能脚本使用 `uv run python …`(会创建临时环境,加载不到 `jiangchang-platform-kit` / `jiangchang_skill_core`)。
|
**禁止**对技能脚本使用 `uv run python …`(会创建临时环境,加载不到 `jiangchang-platform-kit` / `jiangchang_skill_core`)。
|
||||||
**禁止** Agent 自行 `pip install` / `uv pip install` 往临时环境塞依赖。
|
**禁止** Agent 自行 `pip install` / `uv pip install` 往临时环境塞依赖。
|
||||||
|
|
||||||
|
## Agent 分流(业务技能复制后必改)
|
||||||
|
|
||||||
|
用本表列出**本技能**哪些子命令可走短 CLI,哪些必须走 Skill Action。默认:短查询/只读写本地可用短 CLI;长耗时 / RPA / 需进度取消进**黑名单**。有 async/RPA 的技能:**黑名单不得为空**,且黑名单命令须映射到 `actions.json` 中的 async Action。
|
||||||
|
|
||||||
|
| 类型 | 本技能命令(自填) | Agent |
|
||||||
|
|------|--------------------|-------|
|
||||||
|
| **短 CLI 白名单** | (例)`health` / `version` / `logs` / `<your-read-or-prep>` | 可用 bash/exec + 共享 `python` |
|
||||||
|
| **Action 强制黑名单** | (例)`<your-long-or-rpa-command>` | **禁止** bash + `process poll`;必须 `run_skill_action` |
|
||||||
|
|
||||||
|
细节与 Action 清单见 [`ACTIONS.md`](ACTIONS.md)。
|
||||||
|
|
||||||
## 最小命令
|
## 最小命令
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -5,13 +5,16 @@
|
|||||||
**边界规则:**
|
**边界规则:**
|
||||||
|
|
||||||
- 本文**不得**包含 YAML frontmatter,**不得**包含 `description` 字段。
|
- 本文**不得**包含 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)。
|
- **Agent 主读本目录**(`CLI.md` / `ACTIONS.md` / `SCHEMA.md`)与根 [`SKILL.md`](../SKILL.md)。
|
||||||
- [`../development/`](../development/) 是开发者 / 编码助手深度规范,**不是**对话 Agent 的默认读盘路径。
|
- [`../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 平台技能入口与触发摘要 |
|
| [`SKILL.md`](../SKILL.md) | LLM / OpenClaw 平台技能入口与触发摘要 |
|
||||||
| [`CLI.md`](CLI.md) | 共享 Python、命令行入口、参数与短操作契约 |
|
| [`CLI.md`](CLI.md) | 共享 Python、命令行入口、参数与短操作契约 |
|
||||||
| [`ACTIONS.md`](ACTIONS.md) | Skill Action、sync/async、任务中心、多入口(可选能力) |
|
| [`ACTIONS.md`](ACTIONS.md) | Skill Action、sync/async、任务中心、多入口(可选能力) |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
||||||
|
|
||||||
SKILL_SLUG = "your-skill-slug"
|
SKILL_SLUG = "your-skill-slug"
|
||||||
SKILL_VERSION = "1.0.44"
|
SKILL_VERSION = "1.0.47"
|
||||||
LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug"
|
LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug"
|
||||||
PLATFORM_KIT_MIN_VERSION = "1.2.0"
|
PLATFORM_KIT_MIN_VERSION = "1.2.0"
|
||||||
|
|||||||
@@ -141,6 +141,47 @@ class TestDocsStandards(unittest.TestCase):
|
|||||||
msg="SKILL.md must state README.md is user-facing documentation",
|
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:
|
def test_naming_md_exists_and_covers_standards(self) -> None:
|
||||||
text = self._read("development/NAMING.md")
|
text = self._read("development/NAMING.md")
|
||||||
self.assertIn("verb-noun-platform", text)
|
self.assertIn("verb-noun-platform", text)
|
||||||
@@ -315,6 +356,12 @@ class TestDocsStandards(unittest.TestCase):
|
|||||||
msg="CLI.md must not recommend uv run for skill scripts",
|
msg="CLI.md must not recommend uv run for skill scripts",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_cli_md_has_agent_routing_tables(self) -> None:
|
||||||
|
text = self._read("references/CLI.md")
|
||||||
|
self.assertIn("短 CLI 白名单", text)
|
||||||
|
self.assertIn("Action 强制黑名单", text)
|
||||||
|
self.assertIn("run_skill_action", text)
|
||||||
|
|
||||||
def test_skill_md_requires_shared_python_not_uv_run(self) -> None:
|
def test_skill_md_requires_shared_python_not_uv_run(self) -> None:
|
||||||
text = self._read("SKILL.md")
|
text = self._read("SKILL.md")
|
||||||
self.assertIn("python {baseDir}/scripts/main.py", text)
|
self.assertIn("python {baseDir}/scripts/main.py", text)
|
||||||
@@ -328,6 +375,31 @@ class TestDocsStandards(unittest.TestCase):
|
|||||||
msg="SKILL.md must state Task Center is independent of entry point",
|
msg="SKILL.md must state Task Center is independent of entry point",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_skill_md_has_intent_routing_table(self) -> None:
|
||||||
|
text = self._read("SKILL.md")
|
||||||
|
self.assertIn("用户意图路由表", text)
|
||||||
|
self.assertIn("用户意图", text)
|
||||||
|
self.assertIn("准备 vs 执行", text)
|
||||||
|
|
||||||
|
def test_skill_md_how_to_forbids_cli_paste(self) -> None:
|
||||||
|
text = self._read("SKILL.md")
|
||||||
|
self.assertIn("回答「怎么用", text)
|
||||||
|
self.assertIn("禁止", text)
|
||||||
|
self.assertTrue(
|
||||||
|
"粘贴" in text and "python" in text,
|
||||||
|
msg="SKILL.md must forbid pasting python CLI when answering how-to",
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
"dir" in text or "列" in text,
|
||||||
|
msg="SKILL.md must discourage directory probing for how-to answers",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_actions_md_has_async_side_effect_checklist(self) -> None:
|
||||||
|
text = self._read("references/ACTIONS.md")
|
||||||
|
self.assertIn("最小组合", text)
|
||||||
|
self.assertIn("confirmation.message", text)
|
||||||
|
self.assertIn("用户意图路由表", text)
|
||||||
|
|
||||||
def test_actions_md_states_profile_not_entry_for_task_center(self) -> None:
|
def test_actions_md_states_profile_not_entry_for_task_center(self) -> None:
|
||||||
text = self._read("references/ACTIONS.md")
|
text = self._read("references/ACTIONS.md")
|
||||||
self.assertIn("executionProfile", text)
|
self.assertIn("executionProfile", text)
|
||||||
|
|||||||
Reference in New Issue
Block a user