docs: clarify shared Python, CLI vs Action, and Task Center rules
All checks were successful
技能自动化发布 / release (push) Successful in 11s
All checks were successful
技能自动化发布 / release (push) Successful in 11s
This commit is contained in:
86
SKILL.md
86
SKILL.md
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: 技能开发模板(通用业务版)
|
name: 技能开发模板(通用业务版)
|
||||||
description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。"
|
description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。"
|
||||||
version: 1.0.42
|
version: 1.0.43
|
||||||
author: 深圳匠厂科技有限公司
|
author: 深圳匠厂科技有限公司
|
||||||
metadata:
|
metadata:
|
||||||
openclaw:
|
openclaw:
|
||||||
@@ -25,20 +25,51 @@ allowed-tools:
|
|||||||
### 架构铁律(先读)
|
### 架构铁律(先读)
|
||||||
|
|
||||||
- **单业务内核、多入口**:数据管理 / 定时任务 / Agent / 技能详情 / 直接 CLI 必须复用同一 domain service;禁止按入口复制业务逻辑,禁止按 `source` 分叉业务行为。
|
- **单业务内核、多入口**:数据管理 / 定时任务 / Agent / 技能详情 / 直接 CLI 必须复用同一 domain service;禁止按入口复制业务逻辑,禁止按 `source` 分叉业务行为。
|
||||||
- **`placements`**:只决定 Action 出现在哪里。
|
- **`placements`**:只决定 Action **出现在哪里**(toolbar / cron / agent / skill-detail)。
|
||||||
- **`bind.tables`**:只决定数据管理出现在哪些表;含 `toolbar` 时**必须**显式非空绑定。
|
- **`bind.tables`**:只决定数据管理出现在哪些表;含 `toolbar` 时**必须**显式非空绑定。
|
||||||
- **`executionProfile`**:只决定 sync 等待还是 async Job;**必须**显式声明 `sync` 或 `async`;与 placements **正交**(任意合法组合均可)。
|
- **`executionProfile`**:只决定执行方式——`sync` 当场返回结果,`async` 进**任务中心**。与 placements / 入口**无关**;每个 Action **必须**显式写 `sync` 或 `async`。
|
||||||
- **`async`**:宿主建 Job,立即返回 `jobId`,进度见**任务中心** / Skill Run Card。
|
|
||||||
- **同步数据**写技能本地库、不生成导出文件;**导出当前表**由宿主数据管理负责;特殊业务报告才另做 `export-*`。
|
- **同步数据**写技能本地库、不生成导出文件;**导出当前表**由宿主数据管理负责;特殊业务报告才另做 `export-*`。
|
||||||
|
|
||||||
### 编排要点
|
### 如何触发(决策树)
|
||||||
|
|
||||||
- **长耗时 / RPA / 浏览器任务**:必须通过宿主 **Skill Action**(`run_skill_action`)调用 `assets/actions.json` 中的 action;建议 `executionProfile: "async"`。
|
| 你要做什么 | Agent 怎么做 | 进任务中心? |
|
||||||
- **禁止**对长任务使用 `exec python …/scripts/main.py run` 或 `process poll` 干等 CLI 返回。
|
|------------|--------------|--------------|
|
||||||
- 只读查询(`health` / `stats` 等)可用 `"sync"`,立即返回结果。
|
| 短查询 / 只读 / 秒级(`health` / `version` / `stats` / `list` / `get` / `logs` 等) | OpenClaw bash/exec + **共享 Python** 跑 CLI(见下方「共享 Python」) | 否(CLI 当场结束) |
|
||||||
- 批量处理用参数化 `pickCount` / `--pick N` 顺序消费队列,**不要并发**同一 Profile。
|
| 已在 `actions.json` 声明且 `executionProfile: "sync"` 的能力 | 可用 `run_skill_action`,或同等效果的短 CLI(同一内核) | 否 |
|
||||||
- 详细契约:`development/SKILL_ACTION_RUNTIME.md`、`references/ACTIONS.md`、`references/SCHEMA.md`。
|
| 长耗时 / RPA / 浏览器 / 需要进度或取消;或 `executionProfile: "async"` | **必须** `run_skill_action`(先 `list_skill_actions` / `get_skill_action`) | **是**(仅因为该 Action 是 async) |
|
||||||
- 模板源仓库本身仅示范 `health` / `version` / `config-path` / `init-db`(运维/诊断 CLI);定制后按业务增加 Action,**一个能力一个 Action + 多 placements**。
|
| 用户只问用法 / 能做什么 | 读根目录 `README.md`;技术细节读 `references/` | — |
|
||||||
|
|
||||||
|
**硬规则:**
|
||||||
|
|
||||||
|
1. **禁止**对长任务使用 `exec`/`bash` 跑 `…/scripts/main.py run`(或等价业务命令)再 `process poll` 干等。
|
||||||
|
2. **禁止**用 `uv run python …` 跑技能脚本(会建临时环境,缺 `jiangchang_skill_core`)。
|
||||||
|
3. **禁止** Agent 自行 `pip install`。
|
||||||
|
4. Action **可选**:无数据管理 / 定时 / Agent 结构化调用需求时可不提供 `actions.json`;有长任务 / RPA 时**必须**提供至少一条 `executionProfile: "async"` 且 `placements` 含 `agent` 的 Action。
|
||||||
|
5. **一个业务能力一个 Action**,用多个 `placements` 挂入口;底层仍是同一 `scripts/main.py` CLI。
|
||||||
|
|
||||||
|
Agent 执行契约细节:`references/CLI.md`、`references/ACTIONS.md`、`references/SCHEMA.md`(不要把 `development/` 当 Agent 主读路径)。
|
||||||
|
|
||||||
|
## 共享 Python(必读)
|
||||||
|
|
||||||
|
宿主把共享 runtime 注入进程环境:`JIANGCHANG_PYTHON_EXE`、`VIRTUAL_ENV`,并把 venv 的 `bin`/`Scripts` 前置到 `PATH`。
|
||||||
|
|
||||||
|
**推荐调用式(Agent):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health
|
||||||
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py version
|
||||||
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py config-path
|
||||||
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py init-db
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows cmd 可用 `"%JIANGCHANG_PYTHON_EXE%"`。若环境已注入共享 venv,也可写 `python {baseDir}/scripts/main.py …`(须确认不是系统/临时解释器)。
|
||||||
|
|
||||||
|
- 公共库来自共享 venv 的 `jiangchang-platform-kit>=1.2.0`(包名路径 `jiangchang_skill_core`);**不要 vendor** `scripts/jiangchang_skill_core/`。
|
||||||
|
- 根目录 `requirements.txt` **只声明技能特有**依赖;不要写 `jiangchang-platform-kit` / `playwright`。
|
||||||
|
- `metadata.openclaw.platform_kit_min_version` 是宿主兼容声明,**不是** pip 依赖。
|
||||||
|
- `health` 用 `collect_runtime_diagnostics` 做只读诊断。
|
||||||
|
|
||||||
|
配置:仓库 `.env.example` 为模板;用户 `.env` 在 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/{slug}/.env`。优先级:进程环境变量 > 用户 `.env` > `.env.example`。
|
||||||
|
|
||||||
## 面向用户问答(LLM 规则)
|
## 面向用户问答(LLM 规则)
|
||||||
|
|
||||||
@@ -55,8 +86,8 @@ allowed-tools:
|
|||||||
- 能不能帮我完成某个业务任务
|
- 能不能帮我完成某个业务任务
|
||||||
|
|
||||||
- **不要**把 `SKILL.md`、`references/`、`development/` 中的技术细节直接作为用户回答。
|
- **不要**把 `SKILL.md`、`references/`、`development/` 中的技术细节直接作为用户回答。
|
||||||
- **只有当**用户明确询问命令、参数、输出结构、开发、调试、集成或排错时,才读取 `references/` 或 `development/`。
|
- **只有当**用户明确询问命令、参数、输出结构、开发、调试、集成或排错时,才读取 `references/`;`development/` 主要给开发者 / 编码助手,对话 Agent **不必**默认打开。
|
||||||
- 若 `README.md` 与 `SKILL.md` / `references` 表述冲突:对用户展示与市场说明以 `README.md` 为准;对执行契约、CLI、schema、运行约束以 `SKILL.md` / `references` 为准。
|
- 若 `README.md` 与 `SKILL.md` / `references` 表述冲突:对用户展示与市场说明以 `README.md` 为准;对执行契约以 `SKILL.md` / `references` 为准。
|
||||||
- 回答用户时**不要**暴露 Playwright、DOM、Python、RPA 等实现细节,除非用户明确询问技术实现。
|
- 回答用户时**不要**暴露 Playwright、DOM、Python、RPA 等实现细节,除非用户明确询问技术实现。
|
||||||
- 用户未问技术实现时,**不要**讨论 slug 命名规则;开发者问命名或 slug 时,读取 `development/NAMING.md`。
|
- 用户未问技术实现时,**不要**讨论 slug 命名规则;开发者问命名或 slug 时,读取 `development/NAMING.md`。
|
||||||
|
|
||||||
@@ -66,8 +97,8 @@ allowed-tools:
|
|||||||
|------|------|------|
|
|------|------|------|
|
||||||
| 根目录 `README.md` | 普通用户 | 技能市场详情页说明(`metadata.readme_md` 主来源) |
|
| 根目录 `README.md` | 普通用户 | 技能市场详情页说明(`metadata.readme_md` 主来源) |
|
||||||
| `SKILL.md`(本文) | LLM / OpenClaw 平台 | 技能入口、触发与运行契约摘要 |
|
| `SKILL.md`(本文) | LLM / OpenClaw 平台 | 技能入口、触发与运行契约摘要 |
|
||||||
| `references/` | Agent 编排/调用 | 渐进式加载:CLI 契约、字段 schema 等 |
|
| `references/` | Agent 编排 / 调用 | CLI、Action、schema 契约(Agent 主读) |
|
||||||
| `development/` | 开发者 / AI 编程代理 | 需求、开发教程、测试、技术规范 |
|
| `development/` | 开发者 / AI 编程代理 | 需求、开发教程、测试、深度技术规范 |
|
||||||
|
|
||||||
## 目录约定
|
## 目录约定
|
||||||
|
|
||||||
@@ -77,36 +108,15 @@ allowed-tools:
|
|||||||
- CLI 入口固定为 `scripts/main.py`
|
- CLI 入口固定为 `scripts/main.py`
|
||||||
- 业务逻辑按 `cli / db / service / util` 分层
|
- 业务逻辑按 `cli / db / service / util` 分层
|
||||||
|
|
||||||
## 最小命令
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python {baseDir}/scripts/main.py health
|
|
||||||
python {baseDir}/scripts/main.py config-path
|
|
||||||
python {baseDir}/scripts/main.py version
|
|
||||||
python {baseDir}/scripts/main.py init-db
|
|
||||||
```
|
|
||||||
|
|
||||||
配置:仓库 `.env.example` 为模板;用户 `.env` 在 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/{slug}/.env`,启动时自动 bootstrap。优先级:进程环境变量 > 用户 `.env` > `.env.example`。
|
|
||||||
|
|
||||||
## 运行依赖
|
|
||||||
|
|
||||||
- Python 运行环境由匠厂宿主注入**共享 runtime**:`{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。
|
|
||||||
- 公共能力来自共享 runtime 安装的 `jiangchang-platform-kit>=1.2.0`(`jiangchang_skill_core` 包);**不要 vendor** `scripts/jiangchang_skill_core/`,新技能不得在仓库内保留该目录副本。
|
|
||||||
- config、logging、runtime_env、rpa、media-assets、video_session、runtime_diagnostics 等均从共享 venv 的 `jiangchang_skill_core` import,而非技能目录副本。
|
|
||||||
- 根目录 `requirements.txt` **只声明技能特有** Python 三方依赖;`jiangchang-platform-kit`、`playwright` 等公共能力由宿主共享 runtime 提供,**不要**写入技能 requirements。
|
|
||||||
- `metadata.openclaw.platform_kit_min_version`(当前 `1.2.0`)是运行契约/兼容性声明,供宿主安装与启用时校验,**不是**技能 pip 依赖声明。
|
|
||||||
- Skill 代码**不要**自行 `pip install`;系统级依赖(如 VC++ Runtime)仅在 `health` / preflight 中提示用户安装。
|
|
||||||
- `health` 使用 `collect_runtime_diagnostics` 输出统一 runtime 诊断(只读,不下载/修复 media-assets)。
|
|
||||||
|
|
||||||
## 定制入口
|
## 定制入口
|
||||||
|
|
||||||
1. 从本模板创建新业务技能时,**不得保留模板 `.git`**;优先使用 [`tools/scaffold_skill.ps1`](tools/scaffold_skill.ps1)(见 [`tools/README.md`](tools/README.md))。
|
1. 从本模板创建新业务技能时,**不得保留模板 `.git`**;优先使用 [`tools/scaffold_skill.ps1`](tools/scaffold_skill.ps1)(见 [`tools/README.md`](tools/README.md))。
|
||||||
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`;长任务 / 任务中心见 `development/SKILL_ACTION_RUNTIME.md`。
|
5. 用户市场说明写入根 `README.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`(元数据表 `_jiangchang_*` + `CREATE TABLE` 物理顺序)。
|
7. 本地 SQLite 的中文表名/字段名、标准时间字段与字段顺序规范见 `references/SCHEMA.md`。
|
||||||
|
|
||||||
## 技能命名与 slug
|
## 技能命名与 slug
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
- `examples/`:CLI 成功输出形状示例(虚构路径与数据)。
|
- `examples/`:CLI 成功输出形状示例(虚构路径与数据)。
|
||||||
- `schemas/`:轻量 JSON Schema(`skill-actions.schema.json` 为**新技能严格规范**;`task-log-record.schema.json` 等)。
|
- `schemas/`:轻量 JSON Schema(`skill-actions.schema.json` 为**新技能严格规范**;`task-log-record.schema.json` 等)。
|
||||||
|
|
||||||
`skill-actions.schema.json` 使用 `additionalProperties: false`。正式支持 `bind.tables`(toolbar Action 必填);`row`/`batch` placements 与 `concurrency`/`locks` 仍为预留。`placements` 与 `executionProfile` 正交。表级 Action 示例见 [`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)
|
- 用户市场说明见根目录 [`README.md`](../README.md)
|
||||||
- Agent 调用/编排参考见 [`references/`](../references/)(含 [`ACTIONS.md`](../references/ACTIONS.md))
|
- Agent 调用/编排参考见 [`references/`](../references/)(含 [`ACTIONS.md`](../references/ACTIONS.md))
|
||||||
|
|||||||
@@ -628,9 +628,18 @@ cmd_stats() # 只读 sync:JSON,无 job_context
|
|||||||
|
|
||||||
### 1. 验证入口
|
### 1. 验证入口
|
||||||
|
|
||||||
|
本地验证请优先使用宿主共享 Python(与 Agent CLI 相同契约),例如:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/main.py health
|
"$JIANGCHANG_PYTHON_EXE" scripts/main.py health
|
||||||
python scripts/main.py version
|
"$JIANGCHANG_PYTHON_EXE" scripts/main.py version
|
||||||
|
```
|
||||||
|
|
||||||
|
若环境已将共享 venv 置于 PATH,也可用 `python scripts/main.py …`。**禁止**对技能脚本使用 `uv run python`。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/main.py -h
|
||||||
|
python scripts/main.py <your-command> -h
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 验证 CLI 路由
|
### 2. 验证 CLI 路由
|
||||||
@@ -702,6 +711,8 @@ uses: client-jiangchang/jiangchang-platform-kit/.github/workflows/reusable-relea
|
|||||||
|
|
||||||
在执行 `release.ps1` 之前,必须先在本地确认 `python tests/run_tests.py -v` 通过。测试不通过不得发起正式发布。
|
在执行 `release.ps1` 之前,必须先在本地确认 `python tests/run_tests.py -v` 通过。测试不通过不得发起正式发布。
|
||||||
|
|
||||||
|
**发布前必须**将 `SKILL.md` 的 `version:` 与 `scripts/util/constants.py` 的 `SKILL_VERSION` 调整为将打出的版本(例如下一 patch),再执行 `release.ps1`。`release.ps1` **不会**自动改这两个字段;漏改会造成 git tag 与技能版本号不一致。
|
||||||
|
|
||||||
`release.ps1` 会在 **auto commit 之前**、推送 tag 之前,对**当前工作区**自动执行默认测试(`python tests/run_tests.py -v`);失败则中止 release,不会留下失败状态的自动提交。仅紧急排障可使用 `-SkipTests` 跳过(会打印黄色警告)。`-DryRun` 预览发布时**仍会实际运行**默认测试,便于在不打 tag 的情况下验证门禁。
|
`release.ps1` 会在 **auto commit 之前**、推送 tag 之前,对**当前工作区**自动执行默认测试(`python tests/run_tests.py -v`);失败则中止 release,不会留下失败状态的自动提交。仅紧急排障可使用 `-SkipTests` 跳过(会打印黄色警告)。`-DryRun` 预览发布时**仍会实际运行**默认测试,便于在不打 tag 的情况下验证门禁。
|
||||||
|
|
||||||
新增或调整开发规范时,须同步 [`development/POLICY_MATRIX.md`](POLICY_MATRIX.md) 与 [`tests/test_development_policy_guard.py`](../tests/test_development_policy_guard.py)(或注明由既有测试覆盖)。
|
新增或调整开发规范时,须同步 [`development/POLICY_MATRIX.md`](POLICY_MATRIX.md) 与 [`tests/test_development_policy_guard.py`](../tests/test_development_policy_guard.py)(或注明由既有测试覆盖)。
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
| POLICY-STRUCTURE-001 | 标准 `scripts/` 分层:`main.py`、`cli/`、`service/`、`db/`、`util/` 必须存在 | development/DEVELOPMENT.md §2 新 skill 的标准目录结构;development/RUNTIME.md §目录结构 | hard | 目录存在性检查 | `tests/test_development_policy_guard.py::TestPolicyStructure001` |
|
| POLICY-STRUCTURE-001 | 标准 `scripts/` 分层:`main.py`、`cli/`、`service/`、`db/`、`util/` 必须存在 | development/DEVELOPMENT.md §2 新 skill 的标准目录结构;development/RUNTIME.md §目录结构 | hard | 目录存在性检查 | `tests/test_development_policy_guard.py::TestPolicyStructure001` |
|
||||||
| 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(`JIANGCHANG_PYTHON_EXE` / python-runtime);须明确**禁止**对技能脚本使用 `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-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` |
|
||||||
|
|||||||
@@ -8,21 +8,24 @@
|
|||||||
|
|
||||||
| 场景 | 推荐做法 |
|
| 场景 | 推荐做法 |
|
||||||
|------|----------|
|
|------|----------|
|
||||||
| 日常运行 | 由宿主匠厂触发技能 |
|
| 日常运行(宿主 / Agent) | 使用 `JIANGCHANG_PYTHON_EXE` 或 PATH 已指向的共享 venv `python` |
|
||||||
| 手工排查 / 测试机 | 使用共享 runtime 的 `python.exe` 执行 `scripts/main.py` |
|
| 手工排查 / 测试机(环境未注入时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/.../python` 执行 `scripts/main.py` |
|
||||||
| **不推荐** | 在技能目录内 `uv run python …` — 可能创建临时 venv,加载不到宿主共享 runtime |
|
| **禁止** | 在技能目录内 `uv run python …` — 会创建临时 venv,加载不到宿主共享 runtime |
|
||||||
|
|
||||||
占位命令(路径因环境而异,勿写死本机目录):
|
占位命令(路径因环境而异,勿写死本机目录):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Windows:
|
推荐(已注入环境时):
|
||||||
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health
|
||||||
|
|
||||||
|
Windows(未注入时):
|
||||||
{JIANGCHANG_DATA_ROOT}\python-runtime\.venv\Scripts\python.exe {baseDir}\scripts\main.py health
|
{JIANGCHANG_DATA_ROOT}\python-runtime\.venv\Scripts\python.exe {baseDir}\scripts\main.py health
|
||||||
|
|
||||||
通用:
|
Unix(未注入时):
|
||||||
<shared-python> {baseDir}/scripts/main.py health
|
{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/bin/python3 {baseDir}/scripts/main.py health
|
||||||
```
|
```
|
||||||
|
|
||||||
`<shared-python>` 通常位于 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。数据根由宿主注入;开发模式下也可能通过 `JIANGCHANG_DATA_ROOT` 解析(见 `jiangchang_skill_core.runtime_env`)。
|
`<shared-python>` / `JIANGCHANG_PYTHON_EXE` 通常指向 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。数据根由宿主注入(见 `jiangchang_skill_core.runtime_env`)。
|
||||||
|
|
||||||
## Runtime 诊断(platform-kit 1.2.0+)
|
## Runtime 诊断(platform-kit 1.2.0+)
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
1. **宿主管调度,技能管业务** — 不自行实现任务中心 / Job 轮询 / 后台守护进程。
|
1. **宿主管调度,技能管业务** — 不自行实现任务中心 / Job 轮询 / 后台守护进程。
|
||||||
2. **单业务内核、多入口** — 数据管理、定时任务、Agent、技能详情与直接 CLI 复用同一 domain service;禁止按入口复制业务逻辑。
|
2. **单业务内核、多入口** — 数据管理、定时任务、Agent、技能详情与直接 CLI 复用同一 domain service;禁止按入口复制业务逻辑。
|
||||||
3. **五职责正交** — `placements` / `bind.tables` / `executionProfile` / `entrypoint` / domain service 各管一事(见 ACTIONS.md)。
|
3. **五职责正交** — `placements` / `bind.tables` / `executionProfile` / `entrypoint` / domain service 各管一事(见 ACTIONS.md)。
|
||||||
4. **长耗时建议 async** — 开浏览器、RPA、HTTP 大文件下载等建议 `executionProfile: "async"`,进**任务中心**;这是选择建议,**不**限制可以出现在哪些 placement。
|
4. **长耗时建议 async** — 开浏览器、RPA、HTTP 大文件下载等建议 `executionProfile: "async"`,进**任务中心**;这是对**方法**的选择,**不**限制可以出现在哪些 placement / 入口。
|
||||||
5. **Agent 禁止 `exec` 直跑长任务 CLI** — 必须 `run_skill_action`;禁止 `exec python main.py run` + `process poll` 干等。
|
5. **Agent:短 CLI / 长 Action** — 短查询可用共享 Python bash CLI;长任务 / RPA **禁止** `exec` + `process poll`,必须 `run_skill_action`。
|
||||||
6. **进度走 Journal** — `emit` / `video.add_step` → Run Journal;UI / Skill Run Card / 任务中心展示;**不靠 stdout 流**。
|
6. **进度走 Journal** — `emit` / `video.add_step` → Run Journal;UI / Skill Run Card / 任务中心展示;**不靠 stdout 流**。
|
||||||
7. **显式声明 `executionProfile`** — 每个 action **必须**写明 `sync` 或 `async`;禁止依赖宿主缺省;禁止第三种模糊模式(`auto` / `background` / `deferred` 等)。
|
7. **显式声明 `executionProfile`** — 每个 action **必须**写明 `sync` 或 `async`;禁止依赖宿主缺省;禁止第三种模糊模式(`auto` / `background` / `deferred` 等)。
|
||||||
|
|
||||||
@@ -160,15 +160,15 @@ cmd_stats() # 只读 sync:JSON stdout,无 job_context
|
|||||||
|
|
||||||
## 8. Agent / SKILL.md 契约(复制后必改)
|
## 8. Agent / SKILL.md 契约(复制后必改)
|
||||||
|
|
||||||
业务技能 `SKILL.md` 应明确:
|
业务技能 `SKILL.md` / `references/` 应明确(Agent 主读,勿只写在本文):
|
||||||
|
|
||||||
1. 副作用任务必须通过宿主 **Skill Action**(`run_skill_action`)调用。
|
1. 短查询:共享 Python(`JIANGCHANG_PYTHON_EXE`)跑 CLI;**禁止** `uv run`。
|
||||||
2. **禁止**对长任务使用 `exec` + `process poll`。
|
2. 长任务 / RPA / async Action:必须通过宿主 **Skill Action**(`run_skill_action`);**禁止** `exec` + `process poll`。
|
||||||
3. 单条 vs 批量 action id 与参数(如 `url` / `pickCount`)。
|
3. 单条 vs 批量 action id 与参数(如 `url` / `pickCount`)。
|
||||||
4. 长任务进度看**任务中心** / Skill Run Card,不等 CLI stdout。
|
4. `executionProfile: async` → 进度看**任务中心** / Skill Run Card;`sync` → 当场结果。与入口无关。
|
||||||
5. 多入口复用同一业务内核;异步 Action 进入任务中心。
|
5. 多入口复用同一业务内核。
|
||||||
|
|
||||||
模板源仓库的 `SKILL.md` 含占位段落;scaffold 后按业务改写。
|
模板源仓库的 `SKILL.md` / `references/ACTIONS.md` 含占位段落;scaffold 后按业务改写。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
# Skill Action Manifest(匠厂宿主)
|
# Skill Action Manifest(匠厂宿主)
|
||||||
|
|
||||||
本文件说明 `assets/actions.json` 与 `scripts/main.py` CLI 的对应关系,供 Agent 编排与宿主 **Skill Action Runtime** 使用。
|
本文件说明 `assets/actions.json` 与 `scripts/main.py` CLI 的对应关系,供 **Agent 编排**与宿主 **Skill Action Runtime** 使用。这是 Agent 侧关于 Action / 任务中心的**主契约**;实现细节与开发规范见 [`../development/SKILL_ACTION_RUNTIME.md`](../development/SKILL_ACTION_RUNTIME.md)。
|
||||||
|
|
||||||
**权威运行时契约(sync/async、任务中心、单内核编排)见 [`../development/SKILL_ACTION_RUNTIME.md`](../development/SKILL_ACTION_RUNTIME.md)。**
|
**边界:** 用户市场说明见根目录 [`README.md`](../README.md);CLI 参数见 [`CLI.md`](CLI.md)。
|
||||||
|
|
||||||
**边界:** 用户市场说明见根目录 [`README.md`](../README.md);CLI 参数与错误码细节见 [`CLI.md`](CLI.md)。
|
## Agent 何时用 Action(与 CLI 的分工)
|
||||||
|
|
||||||
|
| 场景 | 做法 |
|
||||||
|
|------|------|
|
||||||
|
| 短查询 / 只读 / 秒级 | bash + 共享 Python CLI(见 [`CLI.md`](CLI.md));**不必**强行走 Action |
|
||||||
|
| 数据管理按钮 / 定时任务 / 技能详情按钮 | **必须**在 `actions.json` 声明对应 Action |
|
||||||
|
| 长耗时 / RPA / 需要进度与取消 | **必须** `run_skill_action`;对应 Action 一般为 `executionProfile: "async"` |
|
||||||
|
| 已声明的 `sync` Action | `run_skill_action` 当场返回结果,**不进**任务中心 |
|
||||||
|
| 已声明的 `async` Action | `run_skill_action` 立即返回 `jobId`,**进入**任务中心 |
|
||||||
|
|
||||||
|
**进不进任务中心只取决于该 Action 的 `executionProfile`,与从数据管理、定时任务还是 Agent 触发无关。**
|
||||||
|
|
||||||
|
禁止对长任务 `exec`/`bash` + `process poll` 干等 CLI。禁止 `uv run python` 跑技能脚本。
|
||||||
|
|
||||||
## 模板严格规范 vs 宿主向后兼容
|
## 模板严格规范 vs 宿主向后兼容
|
||||||
|
|
||||||
@@ -117,10 +129,10 @@ Action 是**可选能力**:
|
|||||||
|
|
||||||
## 执行模型
|
## 执行模型
|
||||||
|
|
||||||
宿主将 action 转为 argv,再执行:
|
宿主将 action 转为 argv,再用**共享 Python** 执行(与 Agent CLI 同一解释器契约):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
python {skill_root}/scripts/main.py <command> <args...>
|
{JIANGCHANG_PYTHON_EXE} {skill_root}/scripts/main.py <command> <args...>
|
||||||
```
|
```
|
||||||
|
|
||||||
- `entrypoint.type` 当前只支持 `cli`
|
- `entrypoint.type` 当前只支持 `cli`
|
||||||
@@ -132,7 +144,7 @@ python {skill_root}/scripts/main.py <command> <args...>
|
|||||||
|
|
||||||
### `executionProfile`(仅 sync / async)
|
### `executionProfile`(仅 sync / async)
|
||||||
|
|
||||||
模板与新技能**只允许**这两种值;禁止发明 `auto` / `background` / `deferred` 等第三种模式。
|
模板与新技能**只允许**这两种值;每个 Action **必须**显式写出;禁止发明 `auto` / `background` / `deferred`;**禁止**依赖宿主「省略字段时的兼容默认」。
|
||||||
|
|
||||||
| 值 | 宿主行为 | 任务中心 |
|
| 值 | 宿主行为 | 任务中心 |
|
||||||
|----|----------|----------|
|
|----|----------|----------|
|
||||||
@@ -141,9 +153,9 @@ python {skill_root}/scripts/main.py <command> <args...>
|
|||||||
|
|
||||||
合法组合(全部允许):`sync|async` × `toolbar|cron|agent|skill-detail`。
|
合法组合(全部允许):`sync|async` × `toolbar|cron|agent|skill-detail`。
|
||||||
|
|
||||||
经验建议(**不是** placement 硬限制):耗时不可预测、需要暂停/停止/进度展示的任务,建议用 `async`。
|
经验建议(**不是** placement 硬限制):耗时不可预测、需要暂停/停止/进度展示的任务,用 `async`。
|
||||||
|
|
||||||
直接执行 CLI 时,终端自然等待进程结束;宿主通过 Action 调用同一 CLI 时,再按 `executionProfile` 决定同步等待还是建 Job。技能**不得**自行实现第二套任务中心或后台队列。
|
直接执行短 CLI 时,终端自然等待进程结束。宿主通过 Action 调用同一 CLI 时,再按 `executionProfile` 决定同步等待还是建 Job。技能**不得**自行实现第二套任务中心或后台队列。
|
||||||
|
|
||||||
### CLI 输出契约
|
### CLI 输出契约
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,30 @@
|
|||||||
# 通用业务技能模板 CLI 标准
|
# 通用业务技能模板 CLI 标准
|
||||||
|
|
||||||
将 `{baseDir}` 替换为技能根目录(含 `SKILL.md`、`scripts/` 的目录)。所有命令通过 `python {baseDir}/scripts/main.py` 调用。
|
将 `{baseDir}` 替换为技能根目录(含 `SKILL.md`、`scripts/` 的目录)。
|
||||||
|
|
||||||
|
## 解释器(必读)
|
||||||
|
|
||||||
|
必须使用宿主**共享 Python runtime**,不要用系统 Python / 临时 venv。
|
||||||
|
|
||||||
|
| 优先级 | 写法 |
|
||||||
|
|--------|------|
|
||||||
|
| **推荐(Agent)** | `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py <command> …` |
|
||||||
|
| Windows cmd | `"%JIANGCHANG_PYTHON_EXE%" {baseDir}/scripts/main.py <command> …` |
|
||||||
|
| 等价(PATH 已指向共享 venv) | `python {baseDir}/scripts/main.py <command> …` |
|
||||||
|
| 手工排查(未注入环境时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/Scripts/python.exe`(Windows)或 `…/.venv/bin/python3`(Unix) |
|
||||||
|
|
||||||
|
**禁止**对技能脚本使用 `uv run python …`(会创建临时环境,加载不到 `jiangchang-platform-kit` / `jiangchang_skill_core`)。
|
||||||
|
**禁止** Agent 自行 `pip install` / `uv pip install` 往临时环境塞依赖。
|
||||||
|
|
||||||
|
下文示例里的 `python` **均指**上述共享解释器(优先写成 `$JIANGCHANG_PYTHON_EXE`)。
|
||||||
|
|
||||||
## 最小命令
|
## 最小命令
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python {baseDir}/scripts/main.py health
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health
|
||||||
python {baseDir}/scripts/main.py config-path
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py config-path
|
||||||
python {baseDir}/scripts/main.py version
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py version
|
||||||
python {baseDir}/scripts/main.py init-db
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py init-db
|
||||||
```
|
```
|
||||||
|
|
||||||
## 标准行为
|
## 标准行为
|
||||||
@@ -18,13 +34,13 @@ python {baseDir}/scripts/main.py init-db
|
|||||||
- **`config-path`**:输出 JSON,包含 `skill`、`env_path`、`example_path`。
|
- **`config-path`**:输出 JSON,包含 `skill`、`env_path`、`example_path`。
|
||||||
- **`version`**:输出 JSON(`version`、`skill`)。
|
- **`version`**:输出 JSON(`version`、`skill`)。
|
||||||
- **`init-db`**:幂等创建/迁移本地 SQLite(含 `_jiangchang_*` 展示元数据)。成功输出一行 JSON(`ok` / `skill` / `db_path`),退出码 `0`。宿主可在技能安装或更新成功后静默调用;不要并入 `health`。
|
- **`init-db`**:幂等创建/迁移本地 SQLite(含 `_jiangchang_*` 展示元数据)。成功输出一行 JSON(`ok` / `skill` / `db_path`),退出码 `0`。宿主可在技能安装或更新成功后静默调用;不要并入 `health`。
|
||||||
- **`run`**:长时间无 stdout **不代表卡死**;RPA / 外部调用期间应通过 Activity 或 Run Journal 看进度。
|
- **`run` / RPA / 长任务**:CLI 仍是同一内核;**Agent 禁止**用 bash 干等长任务结束。须走宿主 Skill Action(`run_skill_action`),且该 Action 一般为 `executionProfile: "async"` → **任务中心**。长时间无 stdout **不代表卡死**;进度看任务中心 / Run Journal。
|
||||||
- **排查顺序**(由快到慢):
|
- **排查顺序**(由快到慢):
|
||||||
1. `python {baseDir}/scripts/main.py logs`
|
1. `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs`
|
||||||
2. `python {baseDir}/scripts/main.py log-get <log_id>`
|
2. `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py log-get <log_id>`
|
||||||
3. 统一日志文件 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/logs/jiangchang.log`(含 `trace_id`、`task_failed` 等)
|
3. 统一日志文件 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/logs/jiangchang.log`(含 `trace_id`、`task_failed` 等)
|
||||||
4. Run Journal `{JIANGCHANG_DATA_ROOT}/.jiangchang/runs/{job_id}.jsonl`
|
4. Run Journal `{JIANGCHANG_DATA_ROOT}/.jiangchang/runs/{job_id}.jsonl`
|
||||||
5. RPA artifacts / `video_log` / 失败截图(见 `development/RPA.md`);未开启录屏时可能只有截图或日志
|
5. RPA artifacts / `video_log` / 失败截图(开发规范见 `development/RPA.md`);未开启录屏时可能只有截图或日志
|
||||||
- **录屏默认关闭**:模板 `.env.example` 为 `OPENCLAW_RECORD_VIDEO=0`;若未开启录屏,任务**可能不会**打印录屏路径。
|
- **录屏默认关闭**:模板 `.env.example` 为 `OPENCLAW_RECORD_VIDEO=0`;若未开启录屏,任务**可能不会**打印录屏路径。
|
||||||
- 需要录屏时在用户 `.env` 或进程环境变量中设置 **`OPENCLAW_RECORD_VIDEO=1`**;开启后任务完成时 CLI 应打印录屏路径、录屏日志、视频/音频诊断(见 `task_run_support._print_video_summary`),且 `result_summary` 含 video 字段。
|
- 需要录屏时在用户 `.env` 或进程环境变量中设置 **`OPENCLAW_RECORD_VIDEO=1`**;开启后任务完成时 CLI 应打印录屏路径、录屏日志、视频/音频诊断(见 `task_run_support._print_video_summary`),且 `result_summary` 含 video 字段。
|
||||||
|
|
||||||
@@ -42,7 +58,7 @@ python {baseDir}/scripts/main.py init-db
|
|||||||
|
|
||||||
`health` 委托 `jiangchang_skill_core.collect_runtime_diagnostics`,典型字段:
|
`health` 委托 `jiangchang_skill_core.collect_runtime_diagnostics`,典型字段:
|
||||||
|
|
||||||
- `python_executable` — 当前 Python 解释器路径
|
- `python_executable` — 当前 Python 解释器路径(应落在共享 python-runtime)
|
||||||
- `platform_kit_version` / `platform_kit_min_version` / `platform_kit_version_ok`
|
- `platform_kit_version` / `platform_kit_min_version` / `platform_kit_version_ok`
|
||||||
- `jiangchang_skill_core_file` — 公共库加载来源(若来自技能目录副本会报 warning)
|
- `jiangchang_skill_core_file` — 公共库加载来源(若来自技能目录副本会报 warning)
|
||||||
- `media_assets_root`、`ffmpeg_path`、`ffmpeg_available`、`background_music_mp3_count`
|
- `media_assets_root`、`ffmpeg_path`、`ffmpeg_available`、`background_music_mp3_count`
|
||||||
@@ -52,45 +68,30 @@ python {baseDir}/scripts/main.py init-db
|
|||||||
## 通用业务命令骨架
|
## 通用业务命令骨架
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python {baseDir}/scripts/main.py run
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py run
|
||||||
python {baseDir}/scripts/main.py run -t <target> -i <input_id>
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py run -t <target> -i <input_id>
|
||||||
python {baseDir}/scripts/main.py logs
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs
|
||||||
python {baseDir}/scripts/main.py logs --task-type demo --status failed
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs --task-type demo --status failed
|
||||||
python {baseDir}/scripts/main.py log-get <log_id>
|
"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py log-get <log_id>
|
||||||
```
|
```
|
||||||
|
|
||||||
| 命令 | 用途 |
|
| 命令 | 用途 | Agent 注意 |
|
||||||
|------|------|
|
|------|------|------------|
|
||||||
| `run` | 执行一次任务 |
|
| `run` | 执行一次任务(常为长任务 / RPA) | **走 `run_skill_action`**,不要 bash poll |
|
||||||
| `logs` | 列出最近 N 条任务日志 |
|
| `logs` | 列出最近 N 条任务日志 | 可用短 CLI |
|
||||||
| `log-get` | 按 log_id 查看单条任务日志(JSON) |
|
| `log-get` | 按 log_id 查看单条任务日志(JSON) | 可用短 CLI |
|
||||||
|
|
||||||
## 查询/导出类(可选)
|
## 查询/导出类(可选)
|
||||||
|
|
||||||
复制后按需增加,例如:`contacts`、`contact-get`、`export` 或业务等价命令。
|
复制后按需增加,例如:`contacts`、`contact-get`、`export` 或业务等价命令。短查询用共享 Python CLI;需挂数据管理/定时/Agent 结构化入口时再写进 `assets/actions.json`。
|
||||||
|
|
||||||
## 若你的技能依赖兄弟技能
|
## 若你的技能依赖兄弟技能
|
||||||
|
|
||||||
使用 `service.sibling_bridge.call_sibling_json(skill_slug, args)`,不要硬编码兄弟技能名到 `sibling_bridge.py` 自身;并在 `SKILL.md` 声明 `dependencies.required`。
|
使用 `service.sibling_bridge.call_sibling_json(skill_slug, args)`,不要硬编码兄弟技能名到 `sibling_bridge.py` 自身;并在 `SKILL.md` 声明 `dependencies.required`。兄弟进程继承当前解释器(须已是共享 runtime)。
|
||||||
|
|
||||||
## 手工排查命令(推荐)
|
|
||||||
|
|
||||||
**建议使用宿主共享 python-runtime**,避免技能目录内临时 venv 加载不到公共库:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Windows:
|
|
||||||
{JIANGCHANG_DATA_ROOT}\python-runtime\.venv\Scripts\python.exe {baseDir}\scripts\main.py health
|
|
||||||
|
|
||||||
通用:
|
|
||||||
<shared-python> {baseDir}/scripts/main.py health
|
|
||||||
```
|
|
||||||
|
|
||||||
`<shared-python>` 通常位于 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。
|
|
||||||
|
|
||||||
**不建议**在生产/测试机使用技能目录内 `uv run python`,以免加载不到共享 runtime 中的 `jiangchang-platform-kit` / `playwright`。
|
|
||||||
|
|
||||||
## 模板约定
|
## 模板约定
|
||||||
|
|
||||||
- 最小模板至少保留 `health` / `config-path` / `version`
|
- 最小模板至少保留 `health` / `config-path` / `version`
|
||||||
- 通用业务技能建议使用 `run` / `logs` / `log-get`
|
- 通用业务技能建议使用 `run` / `logs` / `log-get`
|
||||||
- 不要再用旧模板的 `publish` / `--account-id` / `--article-id` 命名
|
- 不要再用旧模板的 `publish` / `--account-id` / `--article-id` 命名
|
||||||
|
- Skill Action 与任务中心契约见 [`ACTIONS.md`](ACTIONS.md)
|
||||||
|
|||||||
@@ -6,16 +6,16 @@
|
|||||||
|
|
||||||
- 本文**不得**包含 YAML frontmatter,**不得**包含 `description` 字段。
|
- 本文**不得**包含 YAML frontmatter,**不得**包含 `description` 字段。
|
||||||
- 技能市场详情与普通用户说明**必须**放在根目录 [`README.md`](../README.md)。
|
- 技能市场详情与普通用户说明**必须**放在根目录 [`README.md`](../README.md)。
|
||||||
- 本目录只保留运行时引用资料(如 `CLI.md`、`SCHEMA.md`);开发规范放在 [`../development/`](../development/)。
|
- **Agent 主读本目录**(`CLI.md` / `ACTIONS.md` / `SCHEMA.md`)与根 [`SKILL.md`](../SKILL.md)。
|
||||||
|
- [`../development/`](../development/) 是开发者 / 编码助手深度规范,**不是**对话 Agent 的默认读盘路径。
|
||||||
|
|
||||||
| 文档 | 用途 |
|
| 文档 | 用途 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 根目录 [`README.md`](../README.md) | 用户市场详情页说明 |
|
| 根目录 [`README.md`](../README.md) | 用户市场详情页说明 |
|
||||||
| [`SKILL.md`](../SKILL.md) | LLM / OpenClaw 平台技能入口 |
|
| [`SKILL.md`](../SKILL.md) | LLM / OpenClaw 平台技能入口与触发摘要 |
|
||||||
| [`CLI.md`](CLI.md) | 命令行入口、参数与调用契约 |
|
| [`CLI.md`](CLI.md) | 共享 Python、命令行入口、参数与短操作契约 |
|
||||||
|
| [`ACTIONS.md`](ACTIONS.md) | Skill Action、sync/async、任务中心、多入口(可选能力) |
|
||||||
| [`SCHEMA.md`](SCHEMA.md) | 本地 SQLite 与数据管理展示契约 |
|
| [`SCHEMA.md`](SCHEMA.md) | 本地 SQLite 与数据管理展示契约 |
|
||||||
| [`ACTIONS.md`](ACTIONS.md) | Skill Action manifest(**可选**能力)与宿主入口契约 |
|
| [`../development/`](../development/) | 开发、测试、RPA 深度规范(给人 / 编码助手) |
|
||||||
| [`../development/SKILL_ACTION_RUNTIME.md`](../development/SKILL_ACTION_RUNTIME.md) | sync/async、任务中心、Agent 禁令、编排与队列 pick(长任务必读) |
|
|
||||||
| [`../development/`](../development/) | 开发、测试、技术规范(给开发者 / AI 编程代理) |
|
|
||||||
|
|
||||||
按需阅读:编排任务时优先 `CLI.md`;解析结构化字段时读 `SCHEMA.md`;配置宿主按钮/定时任务/Agent 入口时读 `ACTIONS.md` + `SKILL_ACTION_RUNTIME.md`;运行时环境细节见 `../development/RUNTIME.md`。
|
按需阅读:短操作优先 `CLI.md`;Action / 任务中心读 `ACTIONS.md`;结构化字段读 `SCHEMA.md`。
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
||||||
|
|
||||||
SKILL_SLUG = "your-skill-slug"
|
SKILL_SLUG = "your-skill-slug"
|
||||||
SKILL_VERSION = "1.0.42"
|
SKILL_VERSION = "1.0.43"
|
||||||
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"
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ POLICY_IDS = (
|
|||||||
"POLICY-STRUCTURE-001",
|
"POLICY-STRUCTURE-001",
|
||||||
"POLICY-RUNTIME-001",
|
"POLICY-RUNTIME-001",
|
||||||
"POLICY-RUNTIME-002",
|
"POLICY-RUNTIME-002",
|
||||||
|
"POLICY-RUNTIME-003",
|
||||||
"POLICY-INSTALL-001",
|
"POLICY-INSTALL-001",
|
||||||
"POLICY-CONFIG-001",
|
"POLICY-CONFIG-001",
|
||||||
"POLICY-CONFIG-002",
|
"POLICY-CONFIG-002",
|
||||||
|
|||||||
@@ -302,10 +302,38 @@ class TestDocsStandards(unittest.TestCase):
|
|||||||
self.assertNotIn("ALLOW_" + "REAL_" + "API", text)
|
self.assertNotIn("ALLOW_" + "REAL_" + "API", text)
|
||||||
self.assertNotIn("ALLOW_WRITE_ACTIONS", text)
|
self.assertNotIn("ALLOW_WRITE_ACTIONS", text)
|
||||||
|
|
||||||
def test_cli_md_mentions_shared_python_runtime(self) -> None:
|
def test_cli_md_requires_shared_python_not_uv_run(self) -> None:
|
||||||
text = self._read("references/CLI.md")
|
text = self._read("references/CLI.md")
|
||||||
self.assertIn("python-runtime", text)
|
self.assertIn("python-runtime", text)
|
||||||
|
self.assertIn("JIANGCHANG_PYTHON_EXE", text)
|
||||||
|
self.assertIn("禁止", text)
|
||||||
self.assertIn("uv run python", text)
|
self.assertIn("uv run python", text)
|
||||||
|
self.assertNotRegex(
|
||||||
|
text,
|
||||||
|
r"(?m)^(?!\*\*禁止\*\*).*\*\*建议\*\*.*uv run python",
|
||||||
|
msg="CLI.md must not recommend uv run for skill scripts",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_skill_md_requires_shared_python_not_uv_run(self) -> None:
|
||||||
|
text = self._read("SKILL.md")
|
||||||
|
self.assertIn("JIANGCHANG_PYTHON_EXE", text)
|
||||||
|
self.assertIn("uv run python", text)
|
||||||
|
self.assertIn("禁止", text)
|
||||||
|
self.assertIn("run_skill_action", text)
|
||||||
|
self.assertIn("executionProfile", text)
|
||||||
|
self.assertTrue(
|
||||||
|
"任务中心" in text and "无关" in text,
|
||||||
|
msg="SKILL.md must state Task Center is independent of entry point",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_actions_md_states_profile_not_entry_for_task_center(self) -> None:
|
||||||
|
text = self._read("references/ACTIONS.md")
|
||||||
|
self.assertIn("executionProfile", text)
|
||||||
|
self.assertIn("任务中心", text)
|
||||||
|
self.assertTrue(
|
||||||
|
"无关" in text or "orthogonal" in text.lower() or "正交" in text,
|
||||||
|
msg="ACTIONS.md must keep placements orthogonal to Task Center",
|
||||||
|
)
|
||||||
|
|
||||||
def test_testing_md_mentions_pytest_txt_collection_guard(self) -> None:
|
def test_testing_md_mentions_pytest_txt_collection_guard(self) -> None:
|
||||||
text = self._read("development/TESTING.md")
|
text = self._read("development/TESTING.md")
|
||||||
|
|||||||
Reference in New Issue
Block a user