@buaa_smat/hometrans 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +110 -139
  2. package/agents/build-fixer.md +385 -384
  3. package/agents/code-reviewer.md +240 -240
  4. package/agents/logic-coder.md +199 -199
  5. package/agents/logic-context-builder.md +194 -194
  6. package/agents/review-fixer.md +405 -405
  7. package/agents/self-test-fixer.md +296 -296
  8. package/agents/self-tester.md +396 -393
  9. package/agents/spec-generator.md +540 -540
  10. package/dist/cli/config-store.js +150 -17
  11. package/dist/cli/config.js +10 -3
  12. package/dist/cli/init.js +391 -233
  13. package/dist/cli/uninstall.js +12 -7
  14. package/dist/context/index.js +19 -2
  15. package/env-requirements.json +177 -181
  16. package/package.json +1 -1
  17. package/resource/choose_editor.png +0 -0
  18. package/resource/migration_process.svg +94 -0
  19. package/resource/migration_process_transparent.svg +93 -0
  20. package/resource/set_environment.png +0 -0
  21. package/resource/set_multimodel.png +0 -0
  22. package/resource/set_sdk.png +0 -0
  23. package/skills/hmos-batch-ui-align/SKILL.md +108 -108
  24. package/skills/hmos-convert-pipeline/SKILL.md +429 -429
  25. package/skills/hmos-fix-build-errors/SKILL.md +273 -272
  26. package/skills/hmos-incremental-ui-align/{readme.md → README.md} +234 -237
  27. package/skills/hmos-incremental-ui-align/SKILL.md +218 -218
  28. package/skills/hmos-incremental-ui-align/scripts/__pycache__/app_feature_verify.cpython-314.pyc +0 -0
  29. package/skills/hmos-incremental-ui-align/scripts/app_feature_verify.py +128 -29
  30. package/skills/hmos-incremental-ui-align/scripts/navigation-capure.md +37 -37
  31. package/skills/hmos-incremental-ui-align/scripts/page_capture.py +7 -2
  32. package/skills/hmos-integration-test/{readme.md → README.md} +309 -309
  33. package/skills/hmos-integration-test/SKILL.md +380 -380
  34. package/skills/hmos-resources-convert/SKILL.md +623 -623
  35. package/skills/hmos-spec-generate/SKILL.md +324 -331
  36. package/tools/test-tools/autotest/README.md +10 -11
  37. package/tools/test-tools/autotest/self_test_runner.py +40 -12
  38. package/resource/common_config.png +0 -0
  39. package/resource/integration_test_config.png +0 -0
  40. package/resource/set_env.png +0 -0
  41. package/resource/ui_align_config.png +0 -0
@@ -14,11 +14,10 @@ HarmonyOS 应用自测执行器。负责把自然语言写的测试用例(`tes
14
14
 
15
15
  | 工具 | 用途 | 验证命令 |
16
16
  |------|------|----------|
17
- | `uv` | Python 包管理 / 启动 `harmony-autotest` | `uv --version` |
17
+ | `uv` | Python 包管理 / 启动 `harmony-autotest` / 提供 Python 解释器 | `uv --version` |
18
18
  | `hdc` | 设备连接 / 安装 HAP | `hdc version` |
19
- | `python` ≥ 3.10 | 入口脚本 | `python --version` |
20
19
 
21
- > `uv sync`(从本地 `tools/test-tools/` 目录加载 6 个 whl)由 `self_test_runner.py` 自动执行,无需手动 `pip install`。
20
+ > 入口脚本经 `uv run --no-project python self_test_runner.py` 运行 —— uv 自带 Python(≥ 3.10),无需单独安装 Python。`uv sync`(从本地 `tools/test-tools/` 目录加载 6 个 whl)由 `self_test_runner.py` 自动执行,无需手动 `pip install`。
22
21
 
23
22
  ### 2. 配置 `autotest`(在 `~/.hometrans/config.json` 中)
24
23
 
@@ -45,8 +44,8 @@ AutoTest 配置不再使用本目录下的 `config.yaml`,而是集中存放在
45
44
  }
46
45
  ```
47
46
 
48
- - `ht init` 的 **测试配置** 环节会展示该块默认内容并提示填写 `api_key`(及 `name`/`base_url`/`provider`),写入 `~/.hometrans/config.json` 的 `autotest` 块。该 key 不再写入系统环境变量。
49
- - `api_key` 兜底:若该字段仍是占位符/空,`self_test_runner.py` 跑用例前会尝试用 OS 环境变量 `TEST_API_KEY` 补全(一般用不到,仅作手动设置时的安全网);二者都没有才报错退出。
47
+ - `ht init` 的 **模型配置** 环节会展示该块默认内容并提示填写 `api_key`(及 `name`/`base_url`/`provider`),写入 `~/.hometrans/config.json` 的 `autotest.unified_model`,并导出为 `HOMETRANS_MODEL_*` 环境变量(与 UI 对齐共用同一个模型)。
48
+ - 模型字段解析链路「环境变量 → config.json → 报错」:`self_test_runner.py` 跑用例前用 OS 环境变量 `HOMETRANS_MODEL_API_KEY` / `HOMETRANS_MODEL_NAME` / `HOMETRANS_MODEL_BASE_URL` 覆盖 config.json 里 `unified_model` 的对应字段(api_key 兼容老版本 `TEST_API_KEY` 作兜底;`provider` 不导出为环境变量,始终取 config.json,默认 openai);覆盖后 api_key 仍是占位符/空才报错退出。
50
49
  - 运行时 `self_test_runner.py` 读取该块、物化成本次任务专属的临时 YAML(`task_<ts>/autotest_config.yaml`)再交给 `AutoTest.batch`,缺 `agent_mode` 时默认补 `"single"`。
51
50
  - 默认单层模式只需填 `unified_model.api_key`;如需双层模式,可在 `autotest` 块里手动加 `execute_model` / `decision_model`(各自含 `api_key`)并把 `agent_mode` 设为 `"layered"`。
52
51
 
@@ -128,7 +127,7 @@ agent 内部用的就是这个脚本,开发自测时可以直接调:
128
127
  cd agents/test-tools/autotest
129
128
 
130
129
  # 启动一次自测(前台同步做准备 + 后台启动 batch,立即返回 PID)
131
- python self_test_runner.py run \
130
+ uv run --no-project python self_test_runner.py run \
132
131
  --testcases <path-to-testcases.json> \
133
132
  --hap <path-to-app.hap> \
134
133
  --bundle-name com.example.xxx \
@@ -137,14 +136,14 @@ python self_test_runner.py run \
137
136
  --output-dir <out>
138
137
 
139
138
  # 轮询状态(agent 每 60s 查一次)
140
- python self_test_runner.py status --task-dir <out>/task --output-dir <out>
139
+ uv run --no-project python self_test_runner.py status --task-dir <out>/task --output-dir <out>
141
140
 
142
141
  # 强行终止后台 batch
143
- python self_test_runner.py kill --task-dir <out>/task
142
+ uv run --no-project python self_test_runner.py kill --task-dir <out>/task
144
143
 
145
144
  # 重置本地状态(杀残留进程 + 删 .venv + 删本目录残留中间产物)
146
145
  # 用它代替手工 `rm -rf .venv` / `uv cache clean`,不会动全局 uv 缓存
147
- python self_test_runner.py clean
146
+ uv run --no-project python self_test_runner.py clean
148
147
  ```
149
148
 
150
149
  ### `report_tool.py` — 单独重渲染报告
@@ -215,7 +214,7 @@ agents/test-tools/autotest/
215
214
  ## 六、常见问题
216
215
 
217
216
  **Q: `autotest 配置缺失 / api_key 没填`**
218
- A: 跑 `ht init` 重新生成 `~/.hometrans/config.json` 的 `autotest` 块并填好 `TEST_API_KEY`;或手动把 `autotest.unified_model.api_key` 改成真实 key;或设置 OS 环境变量 `TEST_API_KEY` 后重试。
217
+ A: 跑 `ht init` 配置统一模型,它会写入 `~/.hometrans/config.json` 的 `autotest.unified_model` 并导出 `HOMETRANS_MODEL_*` 环境变量;或手动把 `autotest.unified_model.api_key` 改成真实 key;或设置 OS 环境变量 `HOMETRANS_MODEL_API_KEY`(兼容老版本 `TEST_API_KEY`)后重试。
219
218
 
220
219
  **Q: `uv sync` 卡住或失败**
221
220
  A: 6 个 whl 改为从本地 `tools/test-tools/` 目录加载(`pyproject.toml` 的 `[tool.uv.sources]` 用相对路径 `../*.whl`)。失败时确认这 6 个 whl 文件存在于上一级目录;其余依赖仍从清华 PyPI 镜像拉取,需基本网络。也可以 `--force-reinit` 强制重建。
@@ -224,7 +223,7 @@ A: 6 个 whl 改为从本地 `tools/test-tools/` 目录加载(`pyproject.toml`
224
223
  A: 不会。`self_test_runner.py run` 启动时会扫描并 kill 残留的 `AutoTest.batch` / `hypium_mcp` / `harmony_autotest` 进程(不止靠 PID 文件,按命令行名兜底),并自动清掉本目录顶层的 `tmp_hypium/` / `hypium_mcp.log` 等遗留中间产物。`task/` 目录在 agent 流程里也会被清空。
225
224
 
226
225
  **Q: 想彻底重置一遍本地状态再跑?**
227
- A: 跑一次 `python self_test_runner.py clean`:杀残留 → 删 `.venv` → 删 `tmp_hypium/` / `hypium_mcp.log` / `batch.pid` / `batch_stdout.log`。**不要**手工 `uv cache clean`——全局缓存清空后重装 6 个 whl 要从 gitcode 重新拉(1–3 分钟);这 6 个 whl 现在从本地加载、不走网络,但其余依赖仍走缓存,保留缓存的话 `uv sync` 只需几秒。
226
+ A: 跑一次 `uv run --no-project python self_test_runner.py clean`:杀残留 → 删 `.venv` → 删 `tmp_hypium/` / `hypium_mcp.log` / `batch.pid` / `batch_stdout.log`。**不要**手工 `uv cache clean`——全局缓存清空后重装 6 个 whl 要从 gitcode 重新拉(1–3 分钟);这 6 个 whl 现在从本地加载、不走网络,但其余依赖仍走缓存,保留缓存的话 `uv sync` 只需几秒。
228
227
 
229
228
  **Q: 想自己改 `testcases.json` 后再跑?**
230
229
  A: 改完后跑一遍校验,再交给 `self-tester`(`setup=false`):
@@ -333,9 +333,15 @@ def get_uv():
333
333
 
334
334
 
335
335
  def _uv_env():
336
+ # Isolate inner uv calls (`uv sync`, `uv run --project`) from the outer
337
+ # `uv run --no-project` context that launches this script: drop the
338
+ # recursion marker and any inherited VIRTUAL_ENV so the inner uv always
339
+ # targets SCRIPT_DIR/.venv, never the launcher's ephemeral environment.
336
340
  env = os.environ.copy()
337
341
  env["UV_NO_PROGRESS"] = "1"
338
342
  env["RUST_LOG"] = "off"
343
+ env.pop("UV_RUN_RECURSION_DEPTH", None)
344
+ env.pop("VIRTUAL_ENV", None)
339
345
  return env
340
346
 
341
347
 
@@ -433,8 +439,9 @@ def load_autotest_config(explicit: str | None) -> dict:
433
439
  """从 `~/.hometrans/config.json` 读取 `autotest` 配置并校验。
434
440
 
435
441
  - 缺文件 / 缺 `autotest` 字段 → 报错退出,提示运行 `ht init`。
436
- - 任一模型端点的 api_key 仍为占位符/空时,用 OS 环境变量 TEST_API_KEY 兜底填充。
437
- - 兜底后仍有未填的 api_key → 报错退出。
442
+ - 模型字段优先用 OS 环境变量 HOMETRANS_MODEL_* 覆盖 config.json
443
+ (api_key 兼容老版本 TEST_API_KEY 作兜底)。
444
+ - 覆盖后仍有未填的 api_key → 报错退出。
438
445
  - 缺 `agent_mode` 时默认补 "single"。
439
446
  返回可直接物化成 YAML 的 dict。
440
447
  """
@@ -462,16 +469,34 @@ def load_autotest_config(explicit: str | None) -> dict:
462
469
  # 深拷贝,避免改动原始 dict(虽然这里只读不写回)
463
470
  autotest = json.loads(json.dumps(autotest))
464
471
 
465
- # OS 环境变量 TEST_API_KEY 兜底填充占位/空 api_key
466
- env_key = os.environ.get("TEST_API_KEY", "").strip()
472
+ # 统一配置链路「环境变量 config.json 报错」:UI 对齐与自测共用同一个多模态
473
+ # 模型,由 `ht init` 导出为 HOMETRANS_MODEL_*。环境变量优先级最高——存在即覆盖
474
+ # config.json 里 unified_model 的对应字段;缺失时才用 config.json 的值。
475
+ # provider 不导出为环境变量(默认 openai),始终取 config.json 的值。
476
+ env_model = {
477
+ "api_key": (
478
+ os.environ.get("HOMETRANS_MODEL_API_KEY", "").strip()
479
+ or os.environ.get("TEST_API_KEY", "").strip() # 兼容老版本
480
+ ),
481
+ "name": os.environ.get("HOMETRANS_MODEL_NAME", "").strip(),
482
+ "base_url": os.environ.get("HOMETRANS_MODEL_BASE_URL", "").strip(),
483
+ }
484
+ um = autotest.get("unified_model")
485
+ if isinstance(um, dict):
486
+ for field in ("api_key", "name", "base_url"):
487
+ if env_model[field]:
488
+ um[field] = env_model[field]
489
+ # api_key 为各端点共用:环境变量存在时一并覆盖 execute/decision 双层模式的端点。
490
+ if env_model["api_key"]:
491
+ for _name, model in _model_dicts(autotest):
492
+ model["api_key"] = env_model["api_key"]
493
+
494
+ # 覆盖后仍为占位符/空的 api_key → 收集后报错(链路最后一层:提示用户配置)。
467
495
  missing = []
468
496
  for name, model in _model_dicts(autotest):
469
497
  cur = str(model.get("api_key", "")).strip()
470
498
  if not cur or cur == API_KEY_PLACEHOLDER:
471
- if env_key:
472
- model["api_key"] = env_key
473
- else:
474
- missing.append(f"{name}.api_key")
499
+ missing.append(f"{name}.api_key")
475
500
 
476
501
  if not list(_model_dicts(autotest)):
477
502
  logger.error(
@@ -484,7 +509,7 @@ def load_autotest_config(explicit: str | None) -> dict:
484
509
  logger.error(
485
510
  f"autotest 配置中以下 api_key 仍为占位符/空:{', '.join(missing)}。\n"
486
511
  f"请在 {config_path} 的 autotest 配置里填入真实 api_key,"
487
- f"或设置 OS 环境变量 TEST_API_KEY 后重试。"
512
+ f"或设置 OS 环境变量 HOMETRANS_MODEL_API_KEY 后重试(可运行 `ht init` 一并配置)。"
488
513
  )
489
514
  sys.exit(1)
490
515
 
@@ -536,8 +561,9 @@ def cmd_run(args):
536
561
  msg = (
537
562
  f"Refusing to run: this script is executing inside {target_venv}, "
538
563
  f"which it is about to delete and recreate (Windows file locks will leave "
539
- f"the venv in a broken state). Invoke with the system Python instead, e.g. "
540
- f"`python self_test_runner.py run ...` (NOT `uv run python ...`)."
564
+ f"the venv in a broken state). Invoke it so the interpreter stays OUT of "
565
+ f"that venv, e.g. `uv run --no-project python self_test_runner.py run ...` "
566
+ f"(NOT plain `uv run python ...`, which would execute inside the project venv)."
541
567
  )
542
568
  logger.error(msg)
543
569
  print(json.dumps({"status": "ERROR", "reason": msg}))
@@ -622,7 +648,9 @@ def cmd_run(args):
622
648
 
623
649
  # 后台启动 AutoTest.batch
624
650
  logger.info("=== Step 3: 后台启动 AutoTest.batch ===")
625
- batch_env = os.environ.copy()
651
+ # _uv_env() so the detached `uv run --project` also stays isolated from
652
+ # the outer `uv run --no-project` launcher context.
653
+ batch_env = _uv_env()
626
654
  batch_env["PYTHONIOENCODING"] = "utf-8"
627
655
  batch_env["PYTHONUTF8"] = "1"
628
656
  batch_env["PYTHONUNBUFFERED"] = "1"
Binary file
Binary file
Binary file