@buaa_smat/hometrans 0.1.4 → 0.1.5

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.
package/README.md CHANGED
@@ -45,13 +45,15 @@ Requires Node.js **>= 18**.
45
45
  - `OHOS_SDK_PATH` — OpenHarmony SDK ETS path
46
46
  - `HMS_SDK_PATH` — HMS SDK ETS path
47
47
  - `TEST_API_KEY` — API key written into the autotest `config.yaml`
48
- 3. **Seeds/refreshes the autotest config**: if `agents/test-tools/autotest/config.yaml` is missing it is created from `config.yaml.example`, and every `api_key:` line is filled with the supplied `TEST_API_KEY`.
49
- 4. For every selected editor, **copies**:
48
+ These are stored under a single `env` object in `~/.hometrans/config.json` (alongside `TOOL_PATH`, set in the next step).
49
+ 3. **Installs bundled tools** to `~/.hometrans/tools` (the AutoTest toolchain lives at `~/.hometrans/tools/test-tools/autotest`) and records the destination as `env.TOOL_PATH` in `~/.hometrans/config.json`. Agents/skills resolve the AutoTest dir from `env.TOOL_PATH`.
50
+ 4. **Seeds/refreshes the autotest config**: if `<TOOL_PATH>/test-tools/autotest/config.yaml` is missing it is created from `config.yaml.example`, and every `api_key:` line is filled with the supplied `TEST_API_KEY`.
51
+ 5. For every selected editor, **copies**:
50
52
  - every skill folder under `skills/` (those containing a `SKILL.md`) → `<editor>/skills/<skill-name>/` (recursive — preserves subdirectory structure)
51
- - every agent under `agents/` → `<editor>/agents/` (recursive — preserves `<agent>/scripts/` and `test-tools/` subtrees)
52
- 5. **Registers the MCP server** (auto-adapts to editor config format: jsonc-object / jsonc-command-array / codex-cli / toml-section).
53
- 6. Editors whose marker directory is missing are reported as **`skipped`** — nothing is written for them.
54
- 7. The install is **idempotent** — re-running overwrites bundled content only. It never touches files under `<editor>/skills/` or `<editor>/agents/` that don't share a name with a bundled item.
53
+ - every agent under `agents/` → `<editor>/agents/` (recursive — preserves `<agent>/scripts/` subtrees)
54
+ 6. **Registers the MCP server** (auto-adapts to editor config format: jsonc-object / jsonc-command-array / codex-cli / toml-section).
55
+ 7. Editors whose marker directory is missing are reported as **`skipped`** — nothing is written for them.
56
+ 8. The install is **idempotent** — re-running overwrites bundled content only. It never touches files under `<editor>/skills/` or `<editor>/agents/` that don't share a name with a bundled item.
55
57
 
56
58
  ### Target directories
57
59
 
@@ -36,15 +36,16 @@ Read the config file written by `ht init` at `~/.hometrans/config.json` (`$HOME/
36
36
  ```jsonc
37
37
  {
38
38
  "editors": [ /* ... */ ],
39
- "params": {
39
+ "env": {
40
40
  "OHOS_SDK_PATH": "...", // OpenHarmony SDK ETS path, e.g. "D:/DevEco Studio/sdk/default/openharmony/ets"
41
41
  "HMS_SDK_PATH": "...", // HMS SDK ETS path, e.g. "D:/DevEco Studio/sdk/default/hms/ets"
42
- "TEST_API_KEY": "..."
42
+ "TEST_API_KEY": "...",
43
+ "TOOL_PATH": "..." // HomeTrans tools dir, e.g. "C:/Users/<you>/.hometrans/tools"
43
44
  }
44
45
  }
45
46
  ```
46
47
 
47
- Read `params.OHOS_SDK_PATH` from this file.
48
+ Read `env.OHOS_SDK_PATH` from this file.
48
49
 
49
50
  ### 0b. Derive the DevEco Studio root and tool paths
50
51
 
@@ -58,11 +59,11 @@ From `<deveco>`, derive:
58
59
  - **ohpm**: `<deveco>/tools/ohpm/bin/ohpm`
59
60
  - **SDK directory**: `<deveco>/sdk`
60
61
 
61
- Verify these files exist. If they do, use them and skip auto-detection. (Fall back to `params.HMS_SDK_PATH` — stripping `/sdk/default/hms/ets` — if `OHOS_SDK_PATH` is absent but `HMS_SDK_PATH` is present.)
62
+ Verify these files exist. If they do, use them and skip auto-detection. (Fall back to `env.HMS_SDK_PATH` — stripping `/sdk/default/hms/ets` — if `OHOS_SDK_PATH` is absent but `HMS_SDK_PATH` is present.)
62
63
 
63
64
  ### 0c. Auto-detect if config is missing or invalid
64
65
 
65
- If `~/.hometrans/config.json` is missing, has empty `params.OHOS_SDK_PATH`/`HMS_SDK_PATH`, or the derived paths don't point to real files, auto-detect:
66
+ If `~/.hometrans/config.json` is missing, has empty `env.OHOS_SDK_PATH`/`HMS_SDK_PATH`, or the derived paths don't point to real files, auto-detect:
66
67
 
67
68
  1. **Find DevEco Studio installation**:
68
69
  - Search common locations: `D:\DevEco Studio`, `C:\DevEco Studio`, `C:\Program Files\DevEco Studio`
@@ -41,7 +41,7 @@ If `commit-id` is provided and is not `none`:
41
41
  - `projectPath`: `<harmonyos-project-path>`
42
42
  - `commitId`: `<commit-id>`
43
43
  - `mode`: `"default"`
44
- - `ohosSdkPath` / `hmsSdkPath`: omit to let the tool read `params.OHOS_SDK_PATH` / `params.HMS_SDK_PATH` from the `ht init` config (`~/.hometrans/config.json`), falling back to the `OHOS_SDK_PATH` / `HMS_SDK_PATH` env vars
44
+ - `ohosSdkPath` / `hmsSdkPath`: omit to let the tool read `env.OHOS_SDK_PATH` / `env.HMS_SDK_PATH` from the `ht init` config (`~/.hometrans/config.json`), falling back to the `OHOS_SDK_PATH` / `HMS_SDK_PATH` env vars
45
45
 
46
46
  2. **On failure**, fall back to:
47
47
  ```bash
@@ -231,14 +231,14 @@ Classify: **CONFIRMED** (fix) | **FALSE_POSITIVE** (skip, record reason) | **UNC
231
231
 
232
232
  ### Step 3.0: Resolve Build Environment
233
233
 
234
- 1. Read the `ht init` config at `~/.hometrans/config.json` (Windows: `%USERPROFILE%\.hometrans\config.json`). Take `params.OHOS_SDK_PATH` (e.g. `D:/DevEco Studio/sdk/default/openharmony/ets`) and strip the trailing `/sdk/default/openharmony/ets` to get the DevEco Studio root `<deveco>`. Fall back to `params.HMS_SDK_PATH` (strip `/sdk/default/hms/ets`) if needed.
234
+ 1. Read the `ht init` config at `~/.hometrans/config.json` (Windows: `%USERPROFILE%\.hometrans\config.json`). Take `env.OHOS_SDK_PATH` (e.g. `D:/DevEco Studio/sdk/default/openharmony/ets`) and strip the trailing `/sdk/default/openharmony/ets` to get the DevEco Studio root `<deveco>`. Fall back to `env.HMS_SDK_PATH` (strip `/sdk/default/hms/ets`) if needed.
235
235
 
236
236
  2. Derive tool paths:
237
237
  - `NODE_EXE`: `<deveco>/tools/node/node.exe`
238
238
  - `HVIGORW_JS`: `<deveco>/tools/hvigor/bin/hvigorw.js`
239
239
  - `OHPM`: `<deveco>/tools/ohpm/bin/ohpm`
240
240
 
241
- 3. If the config is missing or `params.OHOS_SDK_PATH`/`HMS_SDK_PATH` are empty, auto-detect: search `D:\DevEco Studio`, `C:\DevEco Studio`, `C:\Program Files\DevEco Studio` for `tools/hvigor/bin/hvigorw.js`.
241
+ 3. If the config is missing or `env.OHOS_SDK_PATH`/`HMS_SDK_PATH` are empty, auto-detect: search `D:\DevEco Studio`, `C:\DevEco Studio`, `C:\Program Files\DevEco Studio` for `tools/hvigor/bin/hvigorw.js`.
242
242
 
243
243
  4. If detection fails, stop and report clearly what is missing so the user can run `ht init` to configure it.
244
244
 
@@ -38,25 +38,36 @@ You are a self-tester for HarmonyOS applications. You run a single pipeline: par
38
38
 
39
39
  ### AutoTest Directory Locator
40
40
 
41
- Used independently by S5 and T4. **Anchor the search at `<output-path>` sub-agent cwd is not guaranteed to sit anywhere in particular.** Walk up from `<output-path>` looking for a sibling `agents/test-tools/autotest`:
41
+ Used independently by S5 and T4. The AutoTest tools are installed by `ht init` under the HomeTrans tools dir; resolve their location from config rather than searching the filesystem.
42
+
43
+ **Primary — read `env.TOOL_PATH` from the HomeTrans config** at `~/.hometrans/config.json` (`$HOME/.hometrans/config.json`; on Windows `%USERPROFILE%\.hometrans\config.json`). The autotest dir is `<TOOL_PATH>/test-tools/autotest`:
44
+
45
+ ```bash
46
+ cfg="$HOME/.hometrans/config.json"; [ -n "$USERPROFILE" ] && [ -f "$USERPROFILE/.hometrans/config.json" ] && cfg="$USERPROFILE/.hometrans/config.json"
47
+ tool_path="$(python -c "import json,os;print(json.load(open(os.path.expanduser(r'$cfg'),encoding='utf-8')).get('env',{}).get('TOOL_PATH',''))" 2>/dev/null)"
48
+ if [ -n "$tool_path" ] && [ -d "$tool_path/test-tools/autotest" ]; then echo "$tool_path/test-tools/autotest"; fi
49
+ ```
50
+
51
+ If config is missing or `TOOL_PATH` is empty/invalid, **fall back** to walking up from `<output-path>` for a sibling `test-tools/autotest` (then `agents/test-tools/autotest` for legacy layouts) — **anchor the search at `<output-path>`, the sub-agent cwd is not guaranteed**:
42
52
 
43
53
  ```bash
44
54
  d="<output-path>"; while [ "$d" != "/" ] && [ "$d" != "" ]; do \
55
+ if [ -d "$d/test-tools/autotest" ]; then echo "$d/test-tools/autotest"; break; fi; \
45
56
  if [ -d "$d/agents/test-tools/autotest" ]; then echo "$d/agents/test-tools/autotest"; break; fi; \
46
57
  d="$(dirname "$d")"; \
47
58
  done
48
59
  ```
49
60
 
50
- If the walk-up yields nothing, fall back to a `$(pwd)`-anchored search **only as a last resort**:
61
+ As a last resort, a `$(pwd)`-anchored search:
51
62
 
52
63
  ```bash
53
- find "$(pwd)" -type d -path "*/agents/test-tools/autotest" -print -quit 2>/dev/null
64
+ find "$(pwd)" -type d -path "*/test-tools/autotest" -print -quit 2>/dev/null
54
65
  ```
55
66
 
56
67
  | Caller | Purpose | On failure |
57
68
  |--------|---------|------------|
58
- | S5 | Locate then run testcases_tool.py | Emit `Error: cannot locate agents/test-tools/autotest from <output-path>` and exit |
59
- | T4 | Locate then verify config.yaml | Write `self-test-report.md` with status **FAIL** and reason "AutoTest directory not found from output-path", then exit |
69
+ | S5 | Locate then run testcases_tool.py | Emit `Error: cannot locate test-tools/autotest from config env.TOOL_PATH or <output-path>` and exit |
70
+ | T4 | Locate then verify config.yaml | Write `self-test-report.md` with status **FAIL** and reason "AutoTest directory not found from config TOOL_PATH or output-path", then exit |
60
71
 
61
72
  ### Input Validation Template
62
73
 
@@ -173,7 +184,7 @@ Write to `<output-path>/_extracted.json`:
173
184
 
174
185
  ### S5 — Generate testcases.json via Python script
175
186
 
176
- Find the `agents/test-tools/autotest` directory using the **AutoTest Directory Locator** in Shared Utilities (walk up from `<output-path>`). Set `<autotest_dir>` to the resolved path. If not found, emit the documented error and exit. Run:
187
+ Find the `test-tools/autotest` directory using the **AutoTest Directory Locator** in Shared Utilities (prefer config `env.TOOL_PATH`, fall back to walking up from `<output-path>`). Set `<autotest_dir>` to the resolved path. If not found, emit the documented error and exit. Run:
177
188
 
178
189
  ```bash
179
190
  cd "<autotest_dir>" && uv run python testcases_tool.py generate "<output-path>/_extracted.json" "<output-path>/testcases.json" --validate
@@ -236,7 +247,7 @@ Record the device serial number.
236
247
 
237
248
  ### T4 — Locate AutoTest Directory & Verify config.yaml
238
249
 
239
- Find the `agents/test-tools/autotest` directory using the **AutoTest Directory Locator** in Shared Utilities (walk up from `<output-path>`). If not found, write a `self-test-report.md` with the sentinel format (`status: FAIL` / `reason: AutoTest directory not found from output-path`), then stop.
250
+ Find the `test-tools/autotest` directory using the **AutoTest Directory Locator** in Shared Utilities (prefer config `env.TOOL_PATH`, fall back to walking up from `<output-path>`). If not found, write a `self-test-report.md` with the sentinel format (`status: FAIL` / `reason: AutoTest directory not found from config TOOL_PATH or output-path`), then stop.
240
251
 
241
252
  Set `<autotest_dir>` to the found path. Check config.yaml:
242
253
 
@@ -370,7 +381,7 @@ cd "<autotest_dir>" && uv run python report_tool.py validate "<output-path>/self
370
381
  - **Two-phase architecture**: When the parse phase runs, the LLM writes `_extracted.json` → `testcases_tool.py` writes `testcases.json`. Never write `testcases.json` directly. If `testcases.json` already exists at the output path and the parse phase runs, `testcases_tool.py` overwrites it — never skip the script.
371
382
  - **App name → bundle_name is critical**: `test_steps` must use `bundle_name` (e.g., `com.example.tuku`), NOT the display name. AutoTest uses this to launch the correct app. Using the display name instead may launch the wrong app entirely.
372
383
  - **JSON contract**: `app-metadata.json` and `testcases.json` always live at `<output-path>/app-metadata.json` and `<output-path>/testcases.json`. T2 reads from the file (not from memory).
373
- - **AutoTest directory locator**: Walk up from `<output-path>` (see Shared Utilities). Do not assume `$(pwd)` is anchored anywhere in particular.
384
+ - **AutoTest directory locator**: Resolve `<TOOL_PATH>/test-tools/autotest` from `~/.hometrans/config.json` (`env.TOOL_PATH`); fall back to walking up from `<output-path>` (see Shared Utilities). Do not assume `$(pwd)` is anchored anywhere in particular.
374
385
  - **Sentinel-format early-exit reports**: When T1 / T3 / T4 / T7 write a degraded FAIL report (config error, no device, missing autotest dir, crashed batch, timeout, or `setup=false` precondition failure), the report's first non-frontmatter line MUST be `status: FAIL` and the second MUST be `reason: <one-line reason>`. This lets callers detect early-exit reports without parsing a case table.
375
386
  - **Quote all paths** — paths may contain spaces.
376
387
  - **Capture complete output** — never truncate command output; it is essential for diagnosis.
@@ -91,11 +91,12 @@ async function fileExists(p) {
91
91
  * 加载 editors 配置。文件不存在时写入默认值再返回。
92
92
  * 解析失败时抛错,避免静默覆盖用户手动修改。
93
93
  */
94
- export function defaultUserParams() {
94
+ export function defaultEnv() {
95
95
  return {
96
96
  OHOS_SDK_PATH: '',
97
97
  HMS_SDK_PATH: '',
98
98
  TEST_API_KEY: '',
99
+ TOOL_PATH: '',
99
100
  };
100
101
  }
101
102
  export async function loadHomeTransConfig() {
@@ -103,8 +104,7 @@ export async function loadHomeTransConfig() {
103
104
  if (!(await fileExists(configPath))) {
104
105
  const config = {
105
106
  editors: defaultEditors(),
106
- params: defaultUserParams(),
107
- tool_path: '',
107
+ env: defaultEnv(),
108
108
  };
109
109
  await fs.mkdir(getConfigDir(), { recursive: true });
110
110
  await fs.writeFile(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
@@ -122,18 +122,23 @@ export async function loadHomeTransConfig() {
122
122
  throw new Error(`Invalid config.json shape at ${configPath}: top-level must be { "editors": [...] }.`);
123
123
  }
124
124
  const config = parsed;
125
- // Migrate legacy `sdkPaths` field, fill in any missing params keys.
126
- const legacy = parsed.sdkPaths;
127
- if (!config.params) {
128
- config.params = { ...defaultUserParams(), ...(legacy ?? {}) };
129
- }
130
- else {
131
- config.params = { ...defaultUserParams(), ...config.params };
132
- }
133
- if (typeof config.tool_path !== 'string') {
134
- config.tool_path = '';
125
+ const anyParsed = parsed;
126
+ // Migrate legacy fields into `env`:
127
+ // - `sdkPaths` / `params` held OHOS_SDK_PATH / HMS_SDK_PATH / TEST_API_KEY.
128
+ // - `tool_path` held the tools dir, now env.TOOL_PATH.
129
+ const legacyParams = (anyParsed.params ?? anyParsed.sdkPaths);
130
+ const legacyToolPath = typeof anyParsed.tool_path === 'string' ? anyParsed.tool_path : undefined;
131
+ config.env = {
132
+ ...defaultEnv(),
133
+ ...(legacyParams ?? {}),
134
+ ...(config.env ?? {}),
135
+ };
136
+ if (legacyToolPath && !config.env.TOOL_PATH) {
137
+ config.env.TOOL_PATH = legacyToolPath;
135
138
  }
136
- delete config.sdkPaths;
139
+ delete anyParsed.sdkPaths;
140
+ delete anyParsed.params;
141
+ delete anyParsed.tool_path;
137
142
  return config;
138
143
  }
139
144
  export async function saveHomeTransConfig(config) {
@@ -17,16 +17,16 @@ export async function configCommand() {
17
17
  console.log(` Path: ${configPath}`);
18
18
  console.log('');
19
19
  // User parameters
20
- const maskedKey = config.params.TEST_API_KEY
21
- ? config.params.TEST_API_KEY.slice(0, 4) +
20
+ const maskedKey = config.env.TEST_API_KEY
21
+ ? config.env.TEST_API_KEY.slice(0, 4) +
22
22
  '***' +
23
- config.params.TEST_API_KEY.slice(-4)
23
+ config.env.TEST_API_KEY.slice(-4)
24
24
  : '(not set)';
25
25
  console.log(' Parameters:');
26
- console.log(` OHOS_SDK_PATH : ${config.params.OHOS_SDK_PATH || '(not set)'}`);
27
- console.log(` HMS_SDK_PATH : ${config.params.HMS_SDK_PATH || '(not set)'}`);
26
+ console.log(` OHOS_SDK_PATH : ${config.env.OHOS_SDK_PATH || '(not set)'}`);
27
+ console.log(` HMS_SDK_PATH : ${config.env.HMS_SDK_PATH || '(not set)'}`);
28
28
  console.log(` TEST_API_KEY : ${maskedKey}`);
29
- console.log(` tool_path : ${config.tool_path || '(not set)'}`);
29
+ console.log(` TOOL_PATH : ${config.env.TOOL_PATH || '(not set)'}`);
30
30
  console.log('');
31
31
  // Full config content
32
32
  console.log(' Full Content:');
package/dist/cli/init.js CHANGED
@@ -55,7 +55,7 @@ function resolveToolsRoot() {
55
55
  }
56
56
  /**
57
57
  * Copy the bundled `tools/` folder into ~/.hometrans/tools and record the
58
- * destination in config.tool_path. Returns the destination path, or null if
58
+ * destination in config.env.TOOL_PATH. Returns the destination path, or null if
59
59
  * the package ships no tools/ folder.
60
60
  */
61
61
  async function installTools(toolsRoot, config) {
@@ -63,12 +63,17 @@ async function installTools(toolsRoot, config) {
63
63
  return null;
64
64
  const toolsDest = getToolsDir();
65
65
  await copyDirRecursive(toolsRoot, toolsDest);
66
- config.tool_path = toolsDest;
66
+ config.env.TOOL_PATH = toolsDest;
67
67
  await saveHomeTransConfig(config);
68
68
  return toolsDest;
69
69
  }
70
- function resolveAutotestDir(agentsRoot) {
71
- return path.join(agentsRoot, 'test-tools', 'autotest');
70
+ /**
71
+ * The AutoTest tools live under the installed HomeTrans tools dir
72
+ * (~/.hometrans/tools/test-tools/autotest) once `installTools` has run.
73
+ * This is the same location the self-tester agent resolves via config.env.TOOL_PATH.
74
+ */
75
+ function resolveAutotestDir(toolPath) {
76
+ return path.join(toolPath, 'test-tools', 'autotest');
72
77
  }
73
78
  /**
74
79
  * Initialize / refresh `agents/test-tools/autotest/config.yaml`:
@@ -279,51 +284,58 @@ export async function initCommand(options = {}) {
279
284
  type: 'input',
280
285
  name: 'OHOS_SDK_PATH',
281
286
  message: 'OHOS_SDK_PATH:',
282
- default: config.params.OHOS_SDK_PATH || undefined,
287
+ default: config.env.OHOS_SDK_PATH || undefined,
283
288
  },
284
289
  {
285
290
  type: 'input',
286
291
  name: 'HMS_SDK_PATH',
287
292
  message: 'HMS_SDK_PATH:',
288
- default: config.params.HMS_SDK_PATH || undefined,
293
+ default: config.env.HMS_SDK_PATH || undefined,
289
294
  },
290
295
  {
291
296
  type: 'input',
292
297
  name: 'TEST_API_KEY',
293
298
  message: 'TEST_API_KEY (for autotest config.yaml):',
294
- default: config.params.TEST_API_KEY || undefined,
299
+ default: config.env.TEST_API_KEY || undefined,
295
300
  },
296
301
  ]);
297
- config.params.OHOS_SDK_PATH = answers.OHOS_SDK_PATH.trim();
298
- config.params.HMS_SDK_PATH = answers.HMS_SDK_PATH.trim();
299
- config.params.TEST_API_KEY = answers.TEST_API_KEY.trim();
302
+ config.env.OHOS_SDK_PATH = answers.OHOS_SDK_PATH.trim();
303
+ config.env.HMS_SDK_PATH = answers.HMS_SDK_PATH.trim();
304
+ config.env.TEST_API_KEY = answers.TEST_API_KEY.trim();
300
305
  await saveHomeTransConfig(config);
301
306
  }
302
307
  catch {
303
308
  console.log(chalk.yellow(' Parameter prompts skipped (non-interactive mode).'));
304
309
  }
305
- // Initialize / refresh autotest config.yaml from the example template.
310
+ // Copy bundled tools/ into ~/.hometrans/tools and record env.TOOL_PATH.
311
+ // Must run before the autotest config step below, which seeds config.yaml
312
+ // into the installed tools dir (the location agents read via env.TOOL_PATH).
313
+ let installedToolPath = null;
306
314
  try {
307
- const autotestDir = resolveAutotestDir(agentsRoot);
308
- const status = await refreshAutotestConfig(autotestDir, config.params.TEST_API_KEY);
309
- if (status) {
310
- console.log(chalk.green(` + ${status}`));
311
- console.log(chalk.gray(` ${path.join(autotestDir, 'config.yaml')}`));
315
+ installedToolPath = await installTools(toolsRoot, config);
316
+ if (installedToolPath) {
317
+ console.log(chalk.green(` + tools copied -> ${prettyHome(installedToolPath)}`));
318
+ console.log(chalk.gray(` TOOL_PATH set in ${prettyHome(getConfigPath())}`));
312
319
  }
313
320
  }
314
321
  catch (err) {
315
- console.log(chalk.red(` ! autotest config.yaml: ${err.message}`));
322
+ console.log(chalk.red(` ! tools copy: ${err.message}`));
316
323
  }
317
- // Copy bundled tools/ into ~/.hometrans/tools and record tool_path.
324
+ // Initialize / refresh autotest config.yaml from the example template,
325
+ // inside the installed tools dir (<TOOL_PATH>/test-tools/autotest).
318
326
  try {
319
- const toolsDest = await installTools(toolsRoot, config);
320
- if (toolsDest) {
321
- console.log(chalk.green(` + tools copied -> ${prettyHome(toolsDest)}`));
322
- console.log(chalk.gray(` tool_path set in ${prettyHome(getConfigPath())}`));
327
+ const toolPath = installedToolPath ?? config.env.TOOL_PATH;
328
+ if (toolPath) {
329
+ const autotestDir = resolveAutotestDir(toolPath);
330
+ const status = await refreshAutotestConfig(autotestDir, config.env.TEST_API_KEY);
331
+ if (status) {
332
+ console.log(chalk.green(` + ${status}`));
333
+ console.log(chalk.gray(` ${path.join(autotestDir, 'config.yaml')}`));
334
+ }
323
335
  }
324
336
  }
325
337
  catch (err) {
326
- console.log(chalk.red(` ! tools copy: ${err.message}`));
338
+ console.log(chalk.red(` ! autotest config.yaml: ${err.message}`));
327
339
  }
328
340
  console.log('');
329
341
  const editorsToSetup = editors.filter((e) => selectedEditors.includes(e.name));
@@ -84,11 +84,12 @@ async function fileExists(p) {
84
84
  return false;
85
85
  }
86
86
  }
87
- function defaultUserParams() {
87
+ function defaultEnv() {
88
88
  return {
89
89
  OHOS_SDK_PATH: "",
90
90
  HMS_SDK_PATH: "",
91
- TEST_API_KEY: ""
91
+ TEST_API_KEY: "",
92
+ TOOL_PATH: ""
92
93
  };
93
94
  }
94
95
  async function loadHomeTransConfig() {
@@ -96,8 +97,7 @@ async function loadHomeTransConfig() {
96
97
  if (!await fileExists(configPath)) {
97
98
  const config2 = {
98
99
  editors: defaultEditors(),
99
- params: defaultUserParams(),
100
- tool_path: ""
100
+ env: defaultEnv()
101
101
  };
102
102
  await fs.mkdir(getConfigDir(), { recursive: true });
103
103
  await fs.writeFile(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
@@ -118,16 +118,20 @@ async function loadHomeTransConfig() {
118
118
  );
119
119
  }
120
120
  const config = parsed;
121
- const legacy = parsed.sdkPaths;
122
- if (!config.params) {
123
- config.params = { ...defaultUserParams(), ...legacy ?? {} };
124
- } else {
125
- config.params = { ...defaultUserParams(), ...config.params };
126
- }
127
- if (typeof config.tool_path !== "string") {
128
- config.tool_path = "";
121
+ const anyParsed = parsed;
122
+ const legacyParams = anyParsed.params ?? anyParsed.sdkPaths;
123
+ const legacyToolPath = typeof anyParsed.tool_path === "string" ? anyParsed.tool_path : void 0;
124
+ config.env = {
125
+ ...defaultEnv(),
126
+ ...legacyParams ?? {},
127
+ ...config.env ?? {}
128
+ };
129
+ if (legacyToolPath && !config.env.TOOL_PATH) {
130
+ config.env.TOOL_PATH = legacyToolPath;
129
131
  }
130
- delete config.sdkPaths;
132
+ delete anyParsed.sdkPaths;
133
+ delete anyParsed.params;
134
+ delete anyParsed.tool_path;
131
135
  return config;
132
136
  }
133
137
 
@@ -705,10 +709,10 @@ async function extractCommitContext(input) {
705
709
  const mode = input.mode ?? "default";
706
710
  const config = await loadHomeTransConfig();
707
711
  const ohosSdkPath = expandHome(
708
- input.ohosSdkPath ?? config.params.OHOS_SDK_PATH ?? process.env.OHOS_SDK_PATH ?? ""
712
+ input.ohosSdkPath ?? config.env.OHOS_SDK_PATH ?? process.env.OHOS_SDK_PATH ?? ""
709
713
  );
710
714
  const hmsSdkPath = expandHome(
711
- input.hmsSdkPath ?? config.params.HMS_SDK_PATH ?? process.env.HMS_SDK_PATH ?? ""
715
+ input.hmsSdkPath ?? config.env.HMS_SDK_PATH ?? process.env.HMS_SDK_PATH ?? ""
712
716
  );
713
717
  if (!projectPath) {
714
718
  throw new Error("extractCommitContext: projectPath is required");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buaa_smat/hometrans",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "HomeTrans (Android-to-HarmonyOS) skill + agent installer. Run `ht init` to distribute conversion skills and subagents into AI editors.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -159,7 +159,7 @@
159
159
  | 达到最大轮数 | `max_rounds_reached` | 已完成配置的最大轮数循环(`max-rounds`,默认 3),仍有失败未解决 |
160
160
  | 编译未产出 HAP(异常) | `no_signed_hap` | build-fixer 未产出签名 HAP,无法继续测试 |
161
161
  | 用例列表为空(异常) | `no_testcases` | `testcases.json` 里 0 条用例,没有可跑的内容。常见原因:解析阶段没识别到 `### Scenario:` 区块 |
162
- | 自测 agent 早退(异常) | `agent_early_exit` | `self-tester` 在跑用例之前就退出了(设备没连、`config.yaml` 没填、`agents/test-tools/autotest` 目录找不到、batch 启动失败 / 超时 / 崩溃、`setup=false` 但所需 JSON 缺失等)。报告首行会是 `status: FAIL`,第二行 `reason: <原因>`。**这种情况下不会进入 fix 循环**——这些是环境/前置条件问题,不是应用缺陷 |
162
+ | 自测 agent 早退(异常) | `agent_early_exit` | `self-tester` 在跑用例之前就退出了(设备没连、`config.yaml` 没填、`test-tools/autotest` 目录找不到(`env.TOOL_PATH` 未配置或失效)、batch 启动失败 / 超时 / 崩溃、`setup=false` 但所需 JSON 缺失等)。报告首行会是 `status: FAIL`,第二行 `reason: <原因>`。**这种情况下不会进入 fix 循环**——这些是环境/前置条件问题,不是应用缺陷 |
163
163
 
164
164
  ---
165
165
 
@@ -242,7 +242,7 @@ build-fixer 的输出摘要:编译状态、签名类型、迭代次数、修
242
242
  - 操作系统:**Windows** 是主要测试目标;macOS/Linux 上的核心命令(`hdc`、`uv`、POSIX 工具链)也能跑,Skill 里涉及到的复制操作会按可用 shell 自适应
243
243
  - `hdc` 已安装并在 PATH 中
244
244
  - `uv` 已安装(Python 包管理)
245
- - `agents/test-tools/autotest/config.yaml` 已配置真实 api_key
245
+ - `<TOOL_PATH>/test-tools/autotest/config.yaml` 已配置真实 api_key(`TOOL_PATH` 取自 `~/.hometrans/config.json` 的 `env.TOOL_PATH`,默认即 `~/.hometrans/tools`;`ht init` 填好 `TEST_API_KEY` 后会自动写入)
246
246
  - 鸿蒙真机通过 USB 连接,`hdc list targets` 能看到设备
247
247
  - 签名后的 `.hap` 文件
248
248
 
@@ -262,7 +262,7 @@ A: 检查 USB 连接,跑 `hdc list targets` 看看有没有设备 SN。重新
262
262
 
263
263
  **Q: 报 config.yaml missing 或 api_key 没填?**
264
264
 
265
- A: 复制 `agents/test-tools/autotest/config.yaml.example` 为 `config.yaml`,把 `YOUR_API_KEY_HERE` 替换成真实的 API Key
265
+ A: AutoTest 目录 `<TOOL_PATH>/test-tools/autotest`(`TOOL_PATH` 取自 `~/.hometrans/config.json` 的 `env.TOOL_PATH`,默认 `~/.hometrans/tools`)下,复制 `config.yaml.example` 为 `config.yaml`,把 `YOUR_API_KEY_HERE` 替换成真实的 API Key。或者重新跑 `ht init` 并填入 `TEST_API_KEY`,它会自动生成。
266
266
 
267
267
  **Q: 前置用例失败了要不要修代码?**
268
268