diff --git a/SKILL.md b/SKILL.md index 4e1fd15..9daadbe 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,7 +1,7 @@ --- name: 技能开发模板(通用业务版) description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。" -version: 1.0.43 +version: 1.0.44 author: 深圳匠厂科技有限公司 metadata: openclaw: @@ -51,19 +51,15 @@ Agent 执行契约细节:`references/CLI.md`、`references/ACTIONS.md`、`refe ## 共享 Python(必读) -宿主把共享 runtime 注入进程环境:`JIANGCHANG_PYTHON_EXE`、`VIRTUAL_ENV`,并把 venv 的 `bin`/`Scripts` 前置到 `PATH`。 - -**推荐调用式(Agent):** +宿主共享 runtime 在 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`,并已前置到 PATH(同时设 `VIRTUAL_ENV`)。短 CLI 一条命令直接跑: ```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 +python {baseDir}/scripts/main.py health +python {baseDir}/scripts/main.py version +python {baseDir}/scripts/main.py config-path +python {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 依赖。 diff --git a/development/DEVELOPMENT.md b/development/DEVELOPMENT.md index 88cbbe9..9bb7ba7 100644 --- a/development/DEVELOPMENT.md +++ b/development/DEVELOPMENT.md @@ -631,11 +631,11 @@ cmd_stats() # 只读 sync:JSON,无 job_context 本地验证请优先使用宿主共享 Python(与 Agent CLI 相同契约),例如: ```bash -"$JIANGCHANG_PYTHON_EXE" scripts/main.py health -"$JIANGCHANG_PYTHON_EXE" scripts/main.py version +python scripts/main.py health +python scripts/main.py version ``` -若环境已将共享 venv 置于 PATH,也可用 `python scripts/main.py …`。**禁止**对技能脚本使用 `uv run python`。 +**禁止**对技能脚本使用 `uv run python`。 ```bash python scripts/main.py -h diff --git a/development/POLICY_MATRIX.md b/development/POLICY_MATRIX.md index 99dd22d..9367600 100644 --- a/development/POLICY_MATRIX.md +++ b/development/POLICY_MATRIX.md @@ -7,7 +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-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-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-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-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-002 | `.gitignore` 必须忽略 `.env` 与 `*.env.local` | development/CONFIG.md §红线:敏感信息不进 .env | hard | 解析 `.gitignore` 行 | `tests/test_development_policy_guard.py::TestPolicyConfig002` | diff --git a/development/RUNTIME.md b/development/RUNTIME.md index e227c1a..991d0ba 100644 --- a/development/RUNTIME.md +++ b/development/RUNTIME.md @@ -8,7 +8,7 @@ | 场景 | 推荐做法 | |------|----------| -| 日常运行(宿主 / Agent) | 使用 `JIANGCHANG_PYTHON_EXE` 或 PATH 已指向的共享 venv `python` | +| 日常运行(宿主 / Agent) | 使用 PATH 上的共享 venv `python`(`{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`) | | 手工排查 / 测试机(环境未注入时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/.../python` 执行 `scripts/main.py` | | **禁止** | 在技能目录内 `uv run python …` — 会创建临时 venv,加载不到宿主共享 runtime | @@ -16,7 +16,7 @@ ```text 推荐(已注入环境时): - "$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health + python {baseDir}/scripts/main.py health Windows(未注入时): {JIANGCHANG_DATA_ROOT}\python-runtime\.venv\Scripts\python.exe {baseDir}\scripts\main.py health @@ -25,7 +25,7 @@ Unix(未注入时): {JIANGCHANG_DATA_ROOT}/python-runtime/.venv/bin/python3 {baseDir}/scripts/main.py health ``` -`` / `JIANGCHANG_PYTHON_EXE` 通常指向 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。数据根由宿主注入(见 `jiangchang_skill_core.runtime_env`)。 +共享解释器通常位于 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`。数据根由宿主注入(见 `jiangchang_skill_core.runtime_env`)。 ## Runtime 诊断(platform-kit 1.2.0+) diff --git a/development/SKILL_ACTION_RUNTIME.md b/development/SKILL_ACTION_RUNTIME.md index 2834c41..b99cfc9 100644 --- a/development/SKILL_ACTION_RUNTIME.md +++ b/development/SKILL_ACTION_RUNTIME.md @@ -162,7 +162,7 @@ cmd_stats() # 只读 sync:JSON stdout,无 job_context 业务技能 `SKILL.md` / `references/` 应明确(Agent 主读,勿只写在本文): -1. 短查询:共享 Python(`JIANGCHANG_PYTHON_EXE`)跑 CLI;**禁止** `uv run`。 +1. 短查询:共享 Python(PATH 上的 `python`)跑 CLI;**禁止** `uv run`。 2. 长任务 / RPA / async Action:必须通过宿主 **Skill Action**(`run_skill_action`);**禁止** `exec` + `process poll`。 3. 单条 vs 批量 action id 与参数(如 `url` / `pickCount`)。 4. `executionProfile: async` → 进度看**任务中心** / Skill Run Card;`sync` → 当场结果。与入口无关。 diff --git a/references/ACTIONS.md b/references/ACTIONS.md index 350ed37..92a3a7d 100644 --- a/references/ACTIONS.md +++ b/references/ACTIONS.md @@ -129,10 +129,10 @@ Action 是**可选能力**: ## 执行模型 -宿主将 action 转为 argv,再用**共享 Python** 执行(与 Agent CLI 同一解释器契约): +宿主将 action 转为 argv,再用**共享 Python**(用户数据目录下 `python-runtime/.venv`)执行: ```text -{JIANGCHANG_PYTHON_EXE} {skill_root}/scripts/main.py +python {skill_root}/scripts/main.py ``` - `entrypoint.type` 当前只支持 `cli` diff --git a/references/CLI.md b/references/CLI.md index 0fa41f9..037af2d 100644 --- a/references/CLI.md +++ b/references/CLI.md @@ -4,27 +4,27 @@ ## 解释器(必读) -必须使用宿主**共享 Python runtime**,不要用系统 Python / 临时 venv。 +必须使用宿主**共享 Python runtime**(`{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`,已在 PATH / `VIRTUAL_ENV`)。一条命令直接跑,不要先探系统 Python。 -| 优先级 | 写法 | -|--------|------| -| **推荐(Agent)** | `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py …` | -| Windows cmd | `"%JIANGCHANG_PYTHON_EXE%" {baseDir}/scripts/main.py …` | -| 等价(PATH 已指向共享 venv) | `python {baseDir}/scripts/main.py …` | -| 手工排查(未注入环境时) | `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv/Scripts/python.exe`(Windows)或 `…/.venv/bin/python3`(Unix) | +```bash +python {baseDir}/scripts/main.py … +``` + +| 场景 | 写法 | +|------|------| +| **推荐(Agent)** | `python {baseDir}/scripts/main.py …` | +| 手工排查(环境未注入时) | `{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 -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py health -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py config-path -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py version -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py init-db +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 ``` ## 标准行为 @@ -36,8 +36,8 @@ - **`init-db`**:幂等创建/迁移本地 SQLite(含 `_jiangchang_*` 展示元数据)。成功输出一行 JSON(`ok` / `skill` / `db_path`),退出码 `0`。宿主可在技能安装或更新成功后静默调用;不要并入 `health`。 - **`run` / RPA / 长任务**:CLI 仍是同一内核;**Agent 禁止**用 bash 干等长任务结束。须走宿主 Skill Action(`run_skill_action`),且该 Action 一般为 `executionProfile: "async"` → **任务中心**。长时间无 stdout **不代表卡死**;进度看任务中心 / Run Journal。 - **排查顺序**(由快到慢): - 1. `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs` - 2. `"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py log-get ` + 1. `python {baseDir}/scripts/main.py logs` + 2. `python {baseDir}/scripts/main.py log-get ` 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` 5. RPA artifacts / `video_log` / 失败截图(开发规范见 `development/RPA.md`);未开启录屏时可能只有截图或日志 @@ -68,30 +68,14 @@ ## 通用业务命令骨架 ```bash -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py run -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py run -t -i -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py logs --task-type demo --status failed -"$JIANGCHANG_PYTHON_EXE" {baseDir}/scripts/main.py log-get +python {baseDir}/scripts/main.py run +python {baseDir}/scripts/main.py run -t -i +python {baseDir}/scripts/main.py logs +python {baseDir}/scripts/main.py logs --task-type demo --status failed +python {baseDir}/scripts/main.py log-get ``` | 命令 | 用途 | Agent 注意 | |------|------|------------| | `run` | 执行一次任务(常为长任务 / RPA) | **走 `run_skill_action`**,不要 bash poll | -| `logs` | 列出最近 N 条任务日志 | 可用短 CLI | -| `log-get` | 按 log_id 查看单条任务日志(JSON) | 可用短 CLI | - -## 查询/导出类(可选) - -复制后按需增加,例如:`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`。兄弟进程继承当前解释器(须已是共享 runtime)。 - -## 模板约定 - -- 最小模板至少保留 `health` / `config-path` / `version` -- 通用业务技能建议使用 `run` / `logs` / `log-get` -- 不要再用旧模板的 `publish` / `--account-id` / `--article-id` 命名 -- Skill Action 与任务中心契约见 [`ACTIONS.md`](ACTIONS.md) +| `logs` / `log-get` | 查任务日志 | 可用短 CLI | diff --git a/scripts/util/constants.py b/scripts/util/constants.py index 5cb04a5..4901642 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.43" +SKILL_VERSION = "1.0.44" 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 67b373e..92123db 100644 --- a/tests/test_docs_standards.py +++ b/tests/test_docs_standards.py @@ -305,7 +305,8 @@ class TestDocsStandards(unittest.TestCase): def test_cli_md_requires_shared_python_not_uv_run(self) -> None: text = self._read("references/CLI.md") self.assertIn("python-runtime", text) - self.assertIn("JIANGCHANG_PYTHON_EXE", text) + self.assertIn("python {baseDir}/scripts/main.py", text) + self.assertNotIn("JIANGCHANG_PYTHON_EXE", text) self.assertIn("禁止", text) self.assertIn("uv run python", text) self.assertNotRegex( @@ -316,7 +317,8 @@ class TestDocsStandards(unittest.TestCase): 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("python {baseDir}/scripts/main.py", text) + self.assertNotIn("JIANGCHANG_PYTHON_EXE", text) self.assertIn("uv run python", text) self.assertIn("禁止", text) self.assertIn("run_skill_action", text)