diff --git a/.env.example b/.env.example index 674a57f..6f11229 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ # 运行模式:决定本技能用模拟数据还是真实浏览器/接口去执行 -OPENCLAW_TEST_TARGET=mock # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认 mock,日常正式使用请改为 real_rpa +OPENCLAW_TEST_TARGET=real_rpa # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认真实浏览器;本地单测/CI 请用 mock # 目标网站地址:技能要访问的网站或服务地址 TARGET_BASE_URL=https://sandbox.jc2009.com # 填写完整网址(含 https://);换环境时再改,一般保持默认即可 diff --git a/CHANGELOG.md b/CHANGELOG.md index f5564e1..18b02cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ - 小节正文写用户能看懂的变化(新能力、修复、注意事项),避免堆砌内部实现细节 - 打 tag 前**必须**为即将发布的版本新增一节;找不到匹配小节时,本次发布不会更新 changelog 字段 +## 1.0.55 + +- 模板 `.env.example` 默认 `OPENCLAW_TEST_TARGET=real_rpa`;四档保留;明确 mock 只保单测/CI,mock 通 ≠ 交活 +- 验收要求 release 到匠厂并看用户体验(进度、失败提示、有头 RPA 等) + ## 1.0.54 - 新增 `development/SHARED_REPOS.md`:可扩展的公开公共仓目录(skill-template / account-manager / jiangchang-platform-kit),含类型、Gitea 地址、clone 与红线 diff --git a/SKILL.md b/SKILL.md index e4dead2..ecab0e7 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,7 +1,7 @@ --- name: 技能开发模板(通用业务版) description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。" -version: 1.0.54 +version: 1.0.55 author: 深圳匠厂科技有限公司 metadata: openclaw: diff --git a/development/ADAPTER.md b/development/ADAPTER.md index 79e3a39..90163b8 100644 --- a/development/ADAPTER.md +++ b/development/ADAPTER.md @@ -1,6 +1,6 @@ # 适配器标准:真实/仿真 × API/RPA 四档模式 -> 凡是"连接三方系统"(ERP、CRM、SaaS、银行等)的 skill,都应采用本文的 **adapter 四档模式**。这样同一套业务逻辑可以在不同档位间切换:开发用 mock、半集成用 simulator、上线用真实,互不影响。 +> 凡是"连接三方系统"(ERP、CRM、SaaS、银行等)的 skill,都应采用本文的 **adapter 四档模式**。同一套业务逻辑可在不同档位间切换;**四档都保留**。 ## 为什么要分档 @@ -15,17 +15,17 @@ | 档位 | 含义 | 默认策略 | |------|------|----------| -| **`mock`** | 纯内存或 fixture,**默认单测/CI** | 模板 `.env.example` 默认 `OPENCLAW_TEST_TARGET=mock` | -| **`simulator_rpa`** | 仿真站点或桌面仿真,可半集成 | 开发联调可选 | -| **`real_api`** | 真实 API | 生产 / 集成测试显式设 `OPENCLAW_TEST_TARGET=real_api` | -| **`real_rpa`** | 真实浏览器/真实系统 | 生产 / 集成测试显式设 `OPENCLAW_TEST_TARGET=real_rpa` | +| **`mock`** | 纯内存或 fixture,离线 | **单测 / CI 必过**;mock 不通不要往下走 | +| **`simulator_rpa`** | 仿真站点或桌面仿真,可半集成 | 按业务场景选用 | +| **`real_api`** | 真实 API | 按业务场景选用(有官方接口时) | +| **`real_rpa`** | 真实浏览器/真实系统 | **模板 `.env.example` 默认**;业务自测与交活用此档 | -- **mock**:纯离线、不联网,给单测 / CI / 开发自测,**保证可重复**。 -- **simulator_rpa**:操作仿真平台(如 `sandbox.jc2009.com`),跑端到端流程但不碰生产。 -- **real_api**:有官方接口时**首选**(最稳、最快、最易维护)。 -- **real_rpa**:没有 API 只能操作生产界面,**风险最高、放最后**。 +- **mock**:纯离线、不联网,给单测 / CI,**保证可重复**。**mock 通 ≠ 开发完成**。 +- **simulator_rpa**:操作仿真平台(如 `sandbox.jc2009.com`),按场景选用。 +- **real_api**:有官方接口时按场景选用。 +- **real_rpa**:真实浏览器路径;模板默认,须真实跑通后再交活。 -> 推荐优先级:**real_api > simulator_rpa > real_rpa**,mock 永远保留做 CI。 +> **口径**:业务配置默认 `real_rpa`;单测/CI 用 `mock`。不得只 mock 通就交活;须 release 到匠厂宿主验收(含用户体验)。 配置读取见 `CONFIG.md`:**bootstrap 之后业务代码只通过 `config.get*()` 读 `OPENCLAW_TEST_TARGET` 等项**(进程 env > 用户 `.env` > `.env.example`)。 @@ -72,7 +72,7 @@ scripts/service/ from jiangchang_skill_core import config def get_adapter(): - target = (config.get("OPENCLAW_TEST_TARGET") or "mock").lower() + target = (config.get("OPENCLAW_TEST_TARGET") or "real_rpa").lower() if target in ("unit", "mock"): return MockAdapter() if target == "real_api": diff --git a/development/CONFIG.md b/development/CONFIG.md index 73d839e..3df3dce 100644 --- a/development/CONFIG.md +++ b/development/CONFIG.md @@ -48,7 +48,7 @@ ```ini # 运行模式:决定本技能用模拟数据还是真实浏览器/接口去执行 -OPENCLAW_TEST_TARGET=mock # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认 mock,日常正式使用请改为 real_rpa +OPENCLAW_TEST_TARGET=real_rpa # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认真实浏览器;本地单测/CI 请用 mock # 是否显示浏览器窗口:网页自动化时是否弹出可见浏览器 OPENCLAW_BROWSER_HEADLESS=0 # 0=显示窗口(必须,便于介入与排查);1=后台静默(勿作日常用法) @@ -58,7 +58,7 @@ OPENCLAW_BROWSER_HEADLESS=0 # 0=显示窗口(必须,便于介入与排查 ```ini # ── 运行模式 / adapter 档位(见 development/ADAPTER.md)── -OPENCLAW_TEST_TARGET=real_rpa # 生产默认真实 RPA;单测/CI 可改为 mock +OPENCLAW_TEST_TARGET=mock # 见 development/ADAPTER.md;单测用 mock # ── 好看视频 / 百度账号(须与 account-manager 平台 key 一致)── TARGET_PLATFORM=baidu @@ -73,7 +73,7 @@ HAOKAN_VIDEO_SELECTOR=video.art-video ```ini # 运行模式:决定本技能用模拟数据还是真实浏览器/接口去执行 -OPENCLAW_TEST_TARGET=mock # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认 mock,日常正式使用请改为 real_rpa +OPENCLAW_TEST_TARGET=real_rpa # 可选:mock=本地模拟,simulator_rpa=仿真站点,real_api=真实接口,real_rpa=真实浏览器;模板默认真实浏览器;本地单测/CI 请用 mock # 目标网站地址:技能要访问的网站或服务地址 TARGET_BASE_URL=https://sandbox.jc2009.com # 填写完整网址(含 https://);换环境时再改,一般保持默认即可 diff --git a/development/DEVELOPMENT.md b/development/DEVELOPMENT.md index 2b9db17..9ce341c 100644 --- a/development/DEVELOPMENT.md +++ b/development/DEVELOPMENT.md @@ -153,7 +153,7 @@ scripts/ from jiangchang_skill_core.rpa import launch_persistent_browser, anti_detect, wait_for_captcha_pass ``` 上述 import 来自宿主共享 runtime 安装的 `jiangchang-platform-kit`,不是技能目录副本。 -4. **mock 档必须离线可跑**(`OPENCLAW_TEST_TARGET=mock`);sim_rpa / real_* 按需单独测。 +4. **单测/CI 须 mock 离线可过**;业务 `.env` 默认 `real_rpa`,须真实跑通。**不得只 mock 通就交活**;须 release 到匠厂宿主验收(见 §15,含用户体验)。 5. **桌面/手机**:本期标准见 RPA.md 第 2/3 节,复用 `jiangchang_desktop_sdk` / `screencast`,**不要在新 skill 里重复造包**(尚待实战验证)。 --- @@ -818,9 +818,17 @@ uses: client-jiangchang/jiangchang-platform-kit/.github/workflows/reusable-relea - 安装后状态正常 - 不会出现缺文件、缺入口或安装失败的问题 -### 第七步:按声明做宿主多入口验收(已声明的入口都要测) +### 第七步:按声明做宿主多入口验收(已声明的入口都要测;须看用户体验) -安装完成后,不要只停留在“已安装”状态。宿主侧栏有多条与技能相关的入口;**按本技能 `assets/actions.json` 的 `placements` / `executionProfile` 声明逐项自测**(契约见 [`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md)、[`../references/ACTIONS.md`](../references/ACTIONS.md))。未声明的入口可以跳过;**已声明却测不到,视为验收失败**。不要只测对话、忽略其它入口。 +安装完成后,不要只停留在“已安装”状态,也**不要**只在本地 mock 通就认为完成。宿主侧栏有多条与技能相关的入口;**按本技能 `assets/actions.json` 的 `placements` / `executionProfile` 声明逐项自测**(契约见 [`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md)、[`../references/ACTIONS.md`](../references/ACTIONS.md))。未声明的入口可以跳过;**已声明却测不到,视为验收失败**。不要只测对话、忽略其它入口。 + +**用户体验(与功能入口并列,后台通了不算完):** + +- 失败时用户能否看懂原因(对话 / 任务中心 / 提示),不是只有技术日志 +- 长任务(async)是否有可见进度,能否取消或等待说明 +- 网页 RPA 是否有头运行;需登录/验证码时是否停下等人,而不是静默失败 +- 数据管理:表名/字段中文、按钮文案是否清楚;结果是否写回用户看得见的地方 +- 市场说明 / 教程是否与真实行为一致 | 宿主入口(侧栏 / 界面) | 技能侧如何挂上 | 建议验收什么 | |-------------------------|----------------|--------------| @@ -880,7 +888,8 @@ uses: client-jiangchang/jiangchang-platform-kit/.github/workflows/reusable-relea - [ ] 本仓库**不是** skill-template 的误复制(根目录**无** `.openclaw-skill-template`) - [ ] `git remote -v` 指向**本技能**远端,URL 不含 skill-template 仓库名 - [ ] `git log` 首条提交属于本技能(非模板历史)(来源 A 从 Gitea 克隆的已有业务仓,以该仓历史为准) -- [ ] 发布后计划在宿主按 §15 第七步验收:已声明的 **新建任务 / 数据管理(toolbar|row|batch) / 定时任务 / 任务中心(async) / 技能详情** 均已覆盖 +- [ ] 业务 `.env` / `.env.example` 默认 `OPENCLAW_TEST_TARGET=real_rpa`(单测/CI 仍用 mock);**未只靠 mock 交活** +- [ ] 发布后计划在宿主按 §15 第七步验收:已声明入口 + **用户体验**(进度、失败提示、有头 RPA、文案一致等) - [ ] 网页 RPA:`ensure-web` 取得 `profile_dir` 再开浏览器;`.env` 默认有头;REQUIREMENTS 写明登录策略(required/optional/not_needed,会话依赖型勿抄 optional);用户 README/TUTORIAL 区分「登记账号」与「站点登录」(`RPA.md` §0.2 / `POLICY-RPA-004`);依赖 kit 空值解析等修复时上调 `platform_kit_min_version` ## 17. 常见错误 diff --git a/development/README.md b/development/README.md index ecbaf48..247ad78 100644 --- a/development/README.md +++ b/development/README.md @@ -12,8 +12,8 @@ | 2 | 按 [`NAMING.md`](NAMING.md) 确认 slug;**先填** [`REQUIREMENTS.md`](REQUIREMENTS.md),再写业务代码 | [`REQUIREMENTS.md`](REQUIREMENTS.md)、[`NAMING.md`](NAMING.md) | | 3 | 替换标识与占位,按四象限 / examples 实现 `scripts/service/` | [`DEVELOPMENT.md`](DEVELOPMENT.md) §4~§14 | | 4 | **配置 `developer_ids`(开发自测必做)**:开发期技能在匠厂默认不公开;不加则开发者自己也装测不了。从宿主设置复制用户 ID 写入 `SKILL.md` | [`DEVELOPMENT.md`](DEVELOPMENT.md) §6「关于 developer_ids」 | -| 5 | 本地 `python tests/run_tests.py -v` 通过后执行 `release.ps1`;看 Gitea CI | [`DEVELOPMENT.md`](DEVELOPMENT.md) §15 | -| 6 | 匠厂安装后,按 `actions.json` **已声明的全部入口**自测(新建任务、数据管理含 toolbar/row/batch、定时任务、任务中心、技能详情等) | [`DEVELOPMENT.md`](DEVELOPMENT.md) §15;[`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md) | +| 5 | 本地单测(mock)通过后,按业务默认 **`real_rpa`** 真实跑通;再 `release.ps1`;看 Gitea CI。**mock 通 ≠ 完成** | [`ADAPTER.md`](ADAPTER.md);[`DEVELOPMENT.md`](DEVELOPMENT.md) §15 | +| 6 | 匠厂安装后,按已声明入口自测,并看**用户体验**(进度、失败提示、有头 RPA 等) | [`DEVELOPMENT.md`](DEVELOPMENT.md) §15;[`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md) | 脚手架与 Git 防串库:[`../tools/README.md`](../tools/README.md)(`scaffold_skill.ps1`)。业务仓也可直接从自建 Gitea clone,见 [`DEVELOPMENT.md`](DEVELOPMENT.md) §4 来源 A。 diff --git a/development/REQUIREMENTS.md b/development/REQUIREMENTS.md index e97c2c0..5fcbf60 100644 --- a/development/REQUIREMENTS.md +++ b/development/REQUIREMENTS.md @@ -164,16 +164,16 @@ - 代码结构符合模板规范;`SKILL.md` slug 与 `constants.SKILL_SLUG` 一致 - `health`、`version`、`init-db` 命令执行正常 -- 主命令(如 `run`)在 mock / simulator 档位可重复验证 -- `python tests/run_tests.py -v` 必跑测试全部通过 +- `python tests/run_tests.py -v` 必跑测试全部通过(mock / 离线门禁;**mock 通 ≠ 完成**) +- 主命令在业务默认档(模板为 `real_rpa`)真实跑通;不得只 mock 通就交活 - `task_logs` 写入和查询符合 `references/SCHEMA.md`(含 `created_at` / `updated_at` Unix 秒级规范) - `init_db()` 已写入 `_jiangchang_tables` / `_jiangchang_columns`;用户可见表/字段具备中文 `display_name` - 字段展示顺序与 `PRAGMA table_info(task_logs)` 的 cid 一致;不依赖 `display_order` - `tests/test_display_metadata.py` 通过 -- 真实联调(如有)放在 `tests/integration/`,且默认套件不包含真实外联 +- 真实联调样例仍放 `tests/integration/`,默认套件不包含真实外联(与业务 `.env` 默认 `real_rpa` 不冲突) - `SKILL.md` 的 `developer_ids` 已配置为开发者本人匠厂用户 ID(开发期不公开时,否则本人无法在市场安装自测;取 ID 步骤见 `development/DEVELOPMENT.md` §6) - 发布后 Gitea 工作流成功;匠厂技能市场对开发者账号可见最新版本并可安装 -- 安装后按本技能 `actions.json` 声明完成宿主多入口验收:至少覆盖已声明的「新建任务(Agent)」;若声明了 `toolbar` / `cron` / `async`,还须分别验收数据管理、定时任务、任务中心(见 `development/DEVELOPMENT.md` §15 第七步) +- 安装后按本技能 `actions.json` 声明完成宿主多入口验收(见 `development/DEVELOPMENT.md` §15);**须看用户体验**(进度可见、失败可读、RPA 有头、文案与真实行为一致等),后台通了不算完 ## 10. 开发注意事项 diff --git a/development/TESTING.md b/development/TESTING.md index b8aba94..b66bb2c 100644 --- a/development/TESTING.md +++ b/development/TESTING.md @@ -81,7 +81,7 @@ def test_whatever(): 未设置环境变量 ⇒ 等价 `unit`。 -默认策略摘要:**不要在 unittest 必跑路径误设 `OPENCLAW_TEST_TARGET=real_*`**。 +默认策略摘要:**不要在 unittest 必跑路径误设 `OPENCLAW_TEST_TARGET=real_*`**(CI 仍离线)。业务 `.env` 模板默认是 `real_rpa`,与「单测用 mock」不冲突;**mock 通 ≠ 交活**。 档位读取与业务代码一致:经 `jiangchang_skill_core.config.get("OPENCLAW_TEST_TARGET")`(见 `CONFIG.md`)。 diff --git a/scripts/util/constants.py b/scripts/util/constants.py index f738230..1498593 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.54" +SKILL_VERSION = "1.0.55" LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug" PLATFORM_KIT_MIN_VERSION = "1.2.2" diff --git a/tests/test_config_bootstrap.py b/tests/test_config_bootstrap.py index c377822..abf7139 100644 --- a/tests/test_config_bootstrap.py +++ b/tests/test_config_bootstrap.py @@ -84,8 +84,8 @@ class TestConfigBootstrap(unittest.TestCase): config.reset_cache() with open(example, encoding="utf-8") as f: example_text = f.read() - self.assertIn(_env_line(_TEST_TARGET_KEY, "mock").strip(), example_text) - self.assertEqual(config.get(_TEST_TARGET_KEY), "mock") + self.assertIn(_env_line(_TEST_TARGET_KEY, "real_" + "rpa").strip(), example_text) + self.assertEqual(config.get(_TEST_TARGET_KEY), "real_" + "rpa") def test_config_path_outputs_json(self) -> None: with IsolatedDataRoot(user_id="_cfg_path"): diff --git a/tests/test_video_service.py b/tests/test_video_service.py index faab747..8caae9a 100644 --- a/tests/test_video_service.py +++ b/tests/test_video_service.py @@ -61,7 +61,7 @@ class TestEnvExampleVideoDefaults(unittest.TestCase): with open(path, encoding="utf-8") as f: text = f.read() for key in ( - "OPENCLAW_" + "TEST_TARGET=mock", + "OPENCLAW_" + "TEST_TARGET=real_" + "rpa", "OPENCLAW_RECORD_VIDEO=0", "OPENCLAW_ARTIFACTS_ON_FAILURE=1", "OPENCLAW_BROWSER_HEADLESS=0",