@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.
- package/README.md +110 -139
- package/agents/build-fixer.md +385 -384
- package/agents/code-reviewer.md +240 -240
- package/agents/logic-coder.md +199 -199
- package/agents/logic-context-builder.md +194 -194
- package/agents/review-fixer.md +405 -405
- package/agents/self-test-fixer.md +296 -296
- package/agents/self-tester.md +396 -393
- package/agents/spec-generator.md +540 -540
- package/dist/cli/config-store.js +150 -17
- package/dist/cli/config.js +10 -3
- package/dist/cli/init.js +391 -233
- package/dist/cli/uninstall.js +12 -7
- package/dist/context/index.js +19 -2
- package/env-requirements.json +177 -181
- package/package.json +1 -1
- package/resource/choose_editor.png +0 -0
- package/resource/migration_process.svg +94 -0
- package/resource/migration_process_transparent.svg +93 -0
- package/resource/set_environment.png +0 -0
- package/resource/set_multimodel.png +0 -0
- package/resource/set_sdk.png +0 -0
- package/skills/hmos-batch-ui-align/SKILL.md +108 -108
- package/skills/hmos-convert-pipeline/SKILL.md +429 -429
- package/skills/hmos-fix-build-errors/SKILL.md +273 -272
- package/skills/hmos-incremental-ui-align/{readme.md → README.md} +234 -237
- package/skills/hmos-incremental-ui-align/SKILL.md +218 -218
- package/skills/hmos-incremental-ui-align/scripts/__pycache__/app_feature_verify.cpython-314.pyc +0 -0
- package/skills/hmos-incremental-ui-align/scripts/app_feature_verify.py +128 -29
- package/skills/hmos-incremental-ui-align/scripts/navigation-capure.md +37 -37
- package/skills/hmos-incremental-ui-align/scripts/page_capture.py +7 -2
- package/skills/hmos-integration-test/{readme.md → README.md} +309 -309
- package/skills/hmos-integration-test/SKILL.md +380 -380
- package/skills/hmos-resources-convert/SKILL.md +623 -623
- package/skills/hmos-spec-generate/SKILL.md +324 -331
- package/tools/test-tools/autotest/README.md +10 -11
- package/tools/test-tools/autotest/self_test_runner.py +40 -12
- package/resource/common_config.png +0 -0
- package/resource/integration_test_config.png +0 -0
- package/resource/set_env.png +0 -0
- package/resource/ui_align_config.png +0 -0
package/dist/cli/config-store.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 全局配置存储:~/.hometrans/config.json
|
|
3
3
|
*
|
|
4
|
-
* 当前包含 editors 配置(Claude Code / Cursor / OpenCode / Codex / CodeBuddy),后续可扩展
|
|
4
|
+
* 当前包含 editors 配置(Claude Code / Cursor / OpenCode / DevEco Code / Codex / CodeBuddy),后续可扩展
|
|
5
5
|
* 其它顶层字段。首次 setup 时若文件不存在则写入默认值;之后用户可手动编辑。
|
|
6
6
|
* `ht config` 只读不改。
|
|
7
7
|
*/
|
|
8
8
|
import fs from 'node:fs/promises';
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
9
10
|
import path from 'node:path';
|
|
10
11
|
import os from 'node:os';
|
|
11
12
|
/** 由 DEVECO_SDK_HOME 派生其余三个 SDK 相关路径。输入为空时全部返回空串。 */
|
|
@@ -50,6 +51,42 @@ export function getConfigPath() {
|
|
|
50
51
|
export function getToolsDir() {
|
|
51
52
|
return path.join(getConfigDir(), 'tools');
|
|
52
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* 最佳努力地「同步」读取 ~/.hometrans/config.json 中某个 `env.*` 字段,供运行时按
|
|
56
|
+
* 统一链路「环境变量 → config.json → 询问用户」做中间一层回落。
|
|
57
|
+
* 读不到 / 解析失败 / 字段不是字符串时返回 ''(绝不抛错,调用方继续走下一层)。
|
|
58
|
+
*/
|
|
59
|
+
export function readConfigEnvFieldSync(key) {
|
|
60
|
+
try {
|
|
61
|
+
const raw = readFileSync(getConfigPath(), 'utf-8');
|
|
62
|
+
const parsed = JSON.parse(raw);
|
|
63
|
+
const v = parsed?.env?.[key];
|
|
64
|
+
return typeof v === 'string' ? v : '';
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 最佳努力地「同步」读取统一多模态模型字段(autotest.unified_model.*)。
|
|
72
|
+
* 字段名取 'api_key' | 'name' | 'base_url' | 'provider'。读不到返回 ''。
|
|
73
|
+
*/
|
|
74
|
+
export function readConfigModelFieldSync(field) {
|
|
75
|
+
try {
|
|
76
|
+
const raw = readFileSync(getConfigPath(), 'utf-8');
|
|
77
|
+
const parsed = JSON.parse(raw);
|
|
78
|
+
const v = parsed?.autotest?.unified_model?.[field];
|
|
79
|
+
if (typeof v !== 'string')
|
|
80
|
+
return '';
|
|
81
|
+
// A placeholder api_key counts as "not set" so callers fall through to ask.
|
|
82
|
+
if (field === 'api_key' && isPlaceholderApiKey(v))
|
|
83
|
+
return '';
|
|
84
|
+
return v;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
53
90
|
/** 把 ~/foo 展开为 $HOME/foo;非 ~ 开头原样返回。 */
|
|
54
91
|
export function expandHome(p) {
|
|
55
92
|
if (!p)
|
|
@@ -96,6 +133,20 @@ export function defaultEditors() {
|
|
|
96
133
|
keyPath: ['mcp', 'hometrans'],
|
|
97
134
|
},
|
|
98
135
|
},
|
|
136
|
+
{
|
|
137
|
+
// DevEco Code 基于 OpenCode 构建,沿用同一套部署方式:~/.config/deveco/
|
|
138
|
+
// 下的 skills / agents 目录,MCP 走 OpenCode 风格的 {type, command:[]}
|
|
139
|
+
// 格式,写入已存在的 deveco.jsonc 配置文件。
|
|
140
|
+
name: 'DevEco Code',
|
|
141
|
+
markerDir: '~/.config/deveco',
|
|
142
|
+
skillsDir: '~/.config/deveco/skills',
|
|
143
|
+
agentsDir: '~/.config/deveco/agents',
|
|
144
|
+
mcp: {
|
|
145
|
+
format: 'jsonc-command-array',
|
|
146
|
+
path: '~/.config/deveco/deveco.jsonc',
|
|
147
|
+
keyPath: ['mcp', 'hometrans'],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
99
150
|
{
|
|
100
151
|
name: 'Codex',
|
|
101
152
|
markerDir: '~/.codex',
|
|
@@ -142,11 +193,59 @@ export function defaultEnv() {
|
|
|
142
193
|
DEVECO_HOME: '',
|
|
143
194
|
OHOS_SDK_PATH: '',
|
|
144
195
|
HMS_SDK_PATH: '',
|
|
145
|
-
TEST_API_KEY: '',
|
|
146
|
-
GLM_API_KEY: '',
|
|
147
196
|
HOMETRANS_TOOL_PATH: '',
|
|
197
|
+
HOMETRANS_MODEL_API_KEY: '',
|
|
198
|
+
HOMETRANS_MODEL_NAME: '',
|
|
199
|
+
HOMETRANS_MODEL_BASE_URL: '',
|
|
148
200
|
};
|
|
149
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* 占位/未设置的 api_key 判定:空串或历史占位符 'YOUR_API_KEY_HERE'。
|
|
204
|
+
*/
|
|
205
|
+
export function isPlaceholderApiKey(key) {
|
|
206
|
+
const k = (key ?? '').trim();
|
|
207
|
+
return !k || k === 'YOUR_API_KEY_HERE';
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 统一多模态模型的机器环境变量名。UI 对齐(phone-agent)与自测(self-test)
|
|
211
|
+
* 共用同一套配置:`ht init` 把 `autotest.unified_model` 的核心字段写成这些 OS
|
|
212
|
+
* 环境变量,运行时各脚本直接从环境变量读取。provider 不导出(默认 openai)。
|
|
213
|
+
*/
|
|
214
|
+
export const MODEL_ENV_KEYS = [
|
|
215
|
+
'HOMETRANS_MODEL_API_KEY',
|
|
216
|
+
'HOMETRANS_MODEL_NAME',
|
|
217
|
+
'HOMETRANS_MODEL_BASE_URL',
|
|
218
|
+
];
|
|
219
|
+
/**
|
|
220
|
+
* 由 `autotest.unified_model` 生成 (name, value) 环境变量对(顺序与 MODEL_ENV_KEYS
|
|
221
|
+
* 一致)。api_key 仍是占位符/空时取空串(不写入环境变量)。provider 不导出为环境
|
|
222
|
+
* 变量(默认 openai,仅存于 unified_model)。
|
|
223
|
+
*/
|
|
224
|
+
export function modelEnvPairs(autotest) {
|
|
225
|
+
const um = autotest?.unified_model ?? defaultAutotest().unified_model;
|
|
226
|
+
return [
|
|
227
|
+
['HOMETRANS_MODEL_API_KEY', isPlaceholderApiKey(um.api_key) ? '' : um.api_key.trim()],
|
|
228
|
+
['HOMETRANS_MODEL_NAME', (um.name ?? '').trim()],
|
|
229
|
+
['HOMETRANS_MODEL_BASE_URL', (um.base_url ?? '').trim()],
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* 把 `autotest.unified_model` 镜像进 `config.env` 的 HOMETRANS_MODEL_* 四项,让
|
|
234
|
+
* config.json 的 `env` 块与 `ht init` 实际写入机器环境变量的集合保持一致。
|
|
235
|
+
* `autotest.unified_model` 是唯一事实来源,这里只做单向派生(env 侧的手改会被覆盖)。
|
|
236
|
+
* 返回是否有字段发生变化(供调用方决定是否落盘)。
|
|
237
|
+
*/
|
|
238
|
+
export function syncModelEnvIntoConfig(config) {
|
|
239
|
+
let changed = false;
|
|
240
|
+
const envRec = config.env;
|
|
241
|
+
for (const [key, value] of modelEnvPairs(config.autotest)) {
|
|
242
|
+
if (envRec[key] !== value) {
|
|
243
|
+
envRec[key] = value;
|
|
244
|
+
changed = true;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return changed;
|
|
248
|
+
}
|
|
150
249
|
/** AutoTest 自测默认配置(单层模式)。`ht init` 的「测试配置」环节会填充 api_key。 */
|
|
151
250
|
export function defaultAutotest() {
|
|
152
251
|
return {
|
|
@@ -154,7 +253,8 @@ export function defaultAutotest() {
|
|
|
154
253
|
name: '',
|
|
155
254
|
base_url: '',
|
|
156
255
|
api_key: '',
|
|
157
|
-
provider
|
|
256
|
+
// provider 不在 `ht init` 中询问,默认 openai(OpenAI 兼容协议)。
|
|
257
|
+
provider: 'openai',
|
|
158
258
|
temperature: 0.1,
|
|
159
259
|
top_p: 0.9,
|
|
160
260
|
frequency_penalty: 0.5,
|
|
@@ -200,7 +300,7 @@ export async function loadHomeTransConfig() {
|
|
|
200
300
|
const config = parsed;
|
|
201
301
|
const anyParsed = parsed;
|
|
202
302
|
// Migrate legacy fields into `env`:
|
|
203
|
-
// - `sdkPaths` / `params` held OHOS_SDK_PATH / HMS_SDK_PATH
|
|
303
|
+
// - `sdkPaths` / `params` held OHOS_SDK_PATH / HMS_SDK_PATH (+ now-removed keys).
|
|
204
304
|
// - `tool_path` held the tools dir, now env.HOMETRANS_TOOL_PATH.
|
|
205
305
|
const legacyParams = (anyParsed.params ?? anyParsed.sdkPaths);
|
|
206
306
|
const legacyToolPath = typeof anyParsed.tool_path === 'string' ? anyParsed.tool_path : undefined;
|
|
@@ -229,9 +329,12 @@ export async function loadHomeTransConfig() {
|
|
|
229
329
|
delete envRecord.DEVECO_PATH;
|
|
230
330
|
envDirty = true;
|
|
231
331
|
}
|
|
232
|
-
// 移除已废弃的派生字段:JAVA_HOME / NODE_HOME 不再写入 env(构建时由
|
|
233
|
-
//
|
|
234
|
-
|
|
332
|
+
// 移除已废弃的派生字段:JAVA_HOME / NODE_HOME 不再写入 env(构建时由 build agent
|
|
333
|
+
// 从 DEVECO_HOME 推导);HOMETRANS_MODEL_PROVIDER 不再导出为环境变量(provider 默认
|
|
334
|
+
// openai,仅存于 unified_model)。清理老配置里残留的同名键。
|
|
335
|
+
// 注意:GLM_API_KEY / TEST_API_KEY 不在这里删——它们走下面的「向后兼容迁移」,
|
|
336
|
+
// 先把值迁进 autotest.unified_model.api_key 再清键,避免丢掉老用户已配置的 key。
|
|
337
|
+
for (const legacyKey of ['JAVA_HOME', 'NODE_HOME', 'HOMETRANS_MODEL_PROVIDER']) {
|
|
235
338
|
if (legacyKey in envRecord) {
|
|
236
339
|
delete envRecord[legacyKey];
|
|
237
340
|
envDirty = true;
|
|
@@ -272,17 +375,33 @@ export async function loadHomeTransConfig() {
|
|
|
272
375
|
config.autotest = defaultAutotest();
|
|
273
376
|
await saveHomeTransConfig(config);
|
|
274
377
|
}
|
|
275
|
-
//
|
|
276
|
-
//
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
const
|
|
280
|
-
|
|
378
|
+
// 向后兼容老版本:老配置把 key 存在 env.TEST_API_KEY(自测)/ env.GLM_API_KEY(UI
|
|
379
|
+
// 对齐)。统一模型迁移后这些字段已废弃,但为兼容老配置——当 unified_model.api_key
|
|
380
|
+
// 仍是占位符/空时,用它们兜底填充(优先 TEST_API_KEY,其次 GLM_API_KEY),随后把旧键
|
|
381
|
+
// 从 env 中清掉(值已迁入 unified_model;运行时仍可读 OS 环境变量做兜底,见各脚本)。
|
|
382
|
+
const legacyApiKey = (typeof envRecord.TEST_API_KEY === 'string' ? envRecord.TEST_API_KEY : '').trim() ||
|
|
383
|
+
(typeof envRecord.GLM_API_KEY === 'string' ? envRecord.GLM_API_KEY : '').trim();
|
|
384
|
+
let legacyDirty = false;
|
|
385
|
+
if (legacyApiKey) {
|
|
281
386
|
const um = config.autotest.unified_model;
|
|
282
|
-
if (um && (
|
|
283
|
-
um.api_key =
|
|
387
|
+
if (um && isPlaceholderApiKey(um.api_key)) {
|
|
388
|
+
um.api_key = legacyApiKey;
|
|
389
|
+
legacyDirty = true;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
for (const legacyKey of ['TEST_API_KEY', 'GLM_API_KEY']) {
|
|
393
|
+
if (legacyKey in envRecord) {
|
|
394
|
+
delete envRecord[legacyKey];
|
|
395
|
+
legacyDirty = true;
|
|
284
396
|
}
|
|
285
|
-
|
|
397
|
+
}
|
|
398
|
+
if (legacyDirty) {
|
|
399
|
+
await saveHomeTransConfig(config);
|
|
400
|
+
}
|
|
401
|
+
// Mirror the unified model into config.env.HOMETRANS_MODEL_* so the `env` block
|
|
402
|
+
// in config.json matches exactly the machine env vars `ht init` persists. Runs
|
|
403
|
+
// after the legacy migration so a migrated api_key is reflected too.
|
|
404
|
+
if (syncModelEnvIntoConfig(config)) {
|
|
286
405
|
await saveHomeTransConfig(config);
|
|
287
406
|
}
|
|
288
407
|
// Append any default editors that this (older) config predates, matched by
|
|
@@ -295,6 +414,20 @@ export async function loadHomeTransConfig() {
|
|
|
295
414
|
config.editors.push(...missingEditors);
|
|
296
415
|
await saveHomeTransConfig(config);
|
|
297
416
|
}
|
|
417
|
+
// Drop the obsolete `stripAgentColors` flag from configs written by older
|
|
418
|
+
// versions. Agent colors are now normalized to hex at install time based on
|
|
419
|
+
// the editor's MCP format (see needsHexAgentColor in init.ts), so the flag is
|
|
420
|
+
// no longer read — strip it so config.json stays clean.
|
|
421
|
+
let editorsDirty = false;
|
|
422
|
+
for (const ed of config.editors) {
|
|
423
|
+
if ('stripAgentColors' in ed) {
|
|
424
|
+
delete ed.stripAgentColors;
|
|
425
|
+
editorsDirty = true;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (editorsDirty) {
|
|
429
|
+
await saveHomeTransConfig(config);
|
|
430
|
+
}
|
|
298
431
|
return config;
|
|
299
432
|
}
|
|
300
433
|
export async function saveHomeTransConfig(config) {
|
package/dist/cli/config.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `ht config` — 打印 editors.json 路径与内容。
|
|
3
3
|
*
|
|
4
4
|
* 该命令只读:用户若要修改 editor 配置,直接编辑这个 JSON 文件即可。
|
|
5
|
-
* 文件不存在时自动写入默认
|
|
5
|
+
* 文件不存在时自动写入默认 6 个 editor。
|
|
6
6
|
*/
|
|
7
7
|
import fs from 'node:fs/promises';
|
|
8
8
|
import { getConfigPath, loadHomeTransConfig } from './config-store.js';
|
|
@@ -23,10 +23,17 @@ export async function configCommand() {
|
|
|
23
23
|
console.log(` DEVECO_HOME : ${config.env.DEVECO_HOME || '(not set)'} (derived)`);
|
|
24
24
|
console.log(` OHOS_SDK_PATH : ${config.env.OHOS_SDK_PATH || '(not set)'} (derived)`);
|
|
25
25
|
console.log(` HMS_SDK_PATH : ${config.env.HMS_SDK_PATH || '(not set)'} (derived)`);
|
|
26
|
-
console.log(` autotest api_key: ${mask(config.autotest?.unified_model?.api_key ?? '')} (config.json → autotest)`);
|
|
27
|
-
console.log(` GLM_API_KEY : ${mask(config.env.GLM_API_KEY)}`);
|
|
28
26
|
console.log(` HOMETRANS_TOOL_PATH : ${config.env.HOMETRANS_TOOL_PATH || '(not set)'}`);
|
|
29
27
|
console.log('');
|
|
28
|
+
// Unified multimodal model — shared by UI alignment + self-test. Stored in
|
|
29
|
+
// autotest.unified_model and exported as HOMETRANS_MODEL_* env vars.
|
|
30
|
+
const um = config.autotest?.unified_model;
|
|
31
|
+
console.log(' Model (UI alignment + self-test, env: HOMETRANS_MODEL_*):');
|
|
32
|
+
console.log(` api_key : ${mask(um?.api_key ?? '')}`);
|
|
33
|
+
console.log(` name : ${um?.name || '(not set)'}`);
|
|
34
|
+
console.log(` base_url : ${um?.base_url || '(not set)'}`);
|
|
35
|
+
console.log(` provider : ${um?.provider || '(not set)'}`);
|
|
36
|
+
console.log('');
|
|
30
37
|
// Full config content
|
|
31
38
|
console.log(' Full Content:');
|
|
32
39
|
console.log('');
|