@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
@@ -22,9 +22,13 @@ import { removeEnvVars } from './env-vars.js';
22
22
  const execFileAsync = promisify(execFile);
23
23
  const __filename = fileURLToPath(import.meta.url);
24
24
  const __dirname = path.dirname(__filename);
25
- /** Names + readable count of env vars that have a non-empty value in config. */
26
- function plannedEnvVarNames(env) {
27
- return MACHINE_ENV_KEYS.filter((k) => (env[k] ?? '').trim().length > 0);
25
+ /**
26
+ * Machine env var names that `ht init` may have set and that have a non-empty
27
+ * value in config.env: the SDK paths / tool dir plus the mirrored unified model
28
+ * fields (HOMETRANS_MODEL_*, kept in sync with autotest.unified_model on load).
29
+ */
30
+ function plannedEnvVarNames(config) {
31
+ return MACHINE_ENV_KEYS.filter((k) => (config.env[k] ?? '').trim().length > 0);
28
32
  }
29
33
  /* ------------------------------------------------------------------ */
30
34
  /* Bundled content discovery */
@@ -398,7 +402,8 @@ export async function uninstallCommand() {
398
402
  console.log(chalk.gray(' Reinstall hometrans or manually remove skill/agent directories from your editors.\n'));
399
403
  return;
400
404
  }
401
- const { editors, env } = await loadHomeTransConfig();
405
+ const config = await loadHomeTransConfig();
406
+ const { editors } = config;
402
407
  const plan = {
403
408
  deletions: [],
404
409
  modifications: [],
@@ -409,9 +414,9 @@ export async function uninstallCommand() {
409
414
  for (const editor of editors) {
410
415
  await buildPlanForEditor(editor, skillNames, agentEntries, plan);
411
416
  }
412
- // Env vars to remove come from config.json `env`; the ~/.hometrans dir
413
- // (which holds config.json) is deleted last.
414
- plan.envVars = plannedEnvVarNames(env);
417
+ // Env vars to remove come from config.json (`env` + the unified model
418
+ // fields); the ~/.hometrans dir (which holds config.json) is deleted last.
419
+ plan.envVars = plannedEnvVarNames(config);
415
420
  const configDir = getConfigDir();
416
421
  if (await dirExists(configDir)) {
417
422
  plan.configDir = configDir;
@@ -10,8 +10,25 @@ import {
10
10
  } from "arkanalyzer";
11
11
 
12
12
  // src/cli/config-store.ts
13
+ import { readFileSync } from "node:fs";
13
14
  import path from "node:path";
14
15
  import os from "node:os";
16
+ function getConfigDir() {
17
+ return path.join(os.homedir(), ".hometrans");
18
+ }
19
+ function getConfigPath() {
20
+ return path.join(getConfigDir(), "config.json");
21
+ }
22
+ function readConfigEnvFieldSync(key) {
23
+ try {
24
+ const raw = readFileSync(getConfigPath(), "utf-8");
25
+ const parsed = JSON.parse(raw);
26
+ const v = parsed?.env?.[key];
27
+ return typeof v === "string" ? v : "";
28
+ } catch {
29
+ return "";
30
+ }
31
+ }
15
32
  function expandHome(p) {
16
33
  if (!p) return p;
17
34
  if (p === "~") return os.homedir();
@@ -594,10 +611,10 @@ async function extractCommitContext(input) {
594
611
  const { projectPath, commitId } = input;
595
612
  const mode = input.mode ?? "default";
596
613
  const ohosSdkPath = expandHome(
597
- input.ohosSdkPath ?? process.env.OHOS_SDK_PATH ?? ""
614
+ input.ohosSdkPath || process.env.OHOS_SDK_PATH || readConfigEnvFieldSync("OHOS_SDK_PATH")
598
615
  );
599
616
  const hmsSdkPath = expandHome(
600
- input.hmsSdkPath ?? process.env.HMS_SDK_PATH ?? ""
617
+ input.hmsSdkPath || process.env.HMS_SDK_PATH || readConfigEnvFieldSync("HMS_SDK_PATH")
601
618
  );
602
619
  if (!projectPath) {
603
620
  throw new Error("extractCommitContext: projectPath is required");
@@ -1,181 +1,177 @@
1
- {
2
- "$comment": [
3
- "Declarative environment requirements for `ht init`.",
4
- "`ht init` reads this file to (1) detect external tools and (2) report which",
5
- "skills/agents are BLOCKED / LIMITED / OK by anything missing.",
6
- "",
7
- "tools[<id>]:",
8
- " source 'path' -> locate a runnable command (where/which) trying each alias;",
9
- " 'env-dir' -> a directory existence check (envVar resolved from ht config).",
10
- " aliases command names to try in order (e.g. python, python3, py). First hit wins.",
11
- " verify argv passed to the resolved command to print its version (existence proof too).",
12
- " Use a flag that prints-and-exits. NEVER use `python -v` (verbose REPL -> hangs);",
13
- " use `python --version`.",
14
- " versionStream 'stdout' (default) or 'stderr' (java -version prints to stderr).",
15
- " versionRegex capture group(s) for the numeric version in the verify output.",
16
- " version default required range for this tool, {min, max} as [min, max) — min",
17
- " inclusive, max exclusive; either may be null/omitted = unbounded. A",
18
- " requirement dependency may override this.",
19
- " fallback when not on PATH, probe <base>/<segments>/<exe>. base is a config env key",
20
- " (DEVECO_SDK_HOME / DEVECO_HOME). Mirrors how the skills resolve hdc/java.",
21
- " hint shown when the tool is missing.",
22
- "",
23
- "requirements[]: name + kind (skill|agent) + dependencies[] of",
24
- " { tool, level: 'required'|'optional', version?: {min,max} }.",
25
- " A missing 'required' tool -> BLOCKED; only 'optional' missing -> LIMITED; else OK."
26
- ],
27
-
28
- "tools": {
29
- "deveco": {
30
- "source": "env-dir",
31
- "envVar": "DEVECO_SDK_HOME",
32
- "hint": "set DEVECO_SDK_HOME via `ht init` (DevEco Studio install)"
33
- },
34
- "adb": {
35
- "source": "path",
36
- "aliases": ["adb"],
37
- "verify": ["version"],
38
- "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
39
- "hint": "Android SDK platform-tools (needed for Android-device capture)"
40
- },
41
- "hdc": {
42
- "source": "path",
43
- "aliases": ["hdc"],
44
- "verify": ["-v"],
45
- "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
46
- "fallback": { "base": "DEVECO_SDK_HOME", "segments": ["default", "openharmony", "toolchains"], "exe": "hdc" },
47
- "hint": "ships with DevEco: <sdk>/default/openharmony/toolchains"
48
- },
49
- "python": {
50
- "source": "path",
51
- "aliases": ["python", "python3", "py"],
52
- "verify": ["--version"],
53
- "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
54
- "version": { "min": "3.10.0", "max": null },
55
- "hint": "install Python >= 3.10 and add to PATH (UI-align capture/parse scripts)"
56
- },
57
- "uv": {
58
- "source": "path",
59
- "aliases": ["uv"],
60
- "verify": ["--version"],
61
- "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
62
- "hint": "https://docs.astral.sh/uv (AutoTest runs under uv)"
63
- },
64
- "java": {
65
- "source": "path",
66
- "aliases": ["java"],
67
- "verify": ["-version"],
68
- "versionStream": "stderr",
69
- "versionRegex": "(\\d+(?:\\.\\d+){1,2})",
70
- "fallback": { "base": "DEVECO_HOME", "segments": ["jbr", "bin"], "exe": "java" },
71
- "hint": "any JDK 17+, or reuse DevEco jbr: <deveco>/jbr/bin"
72
- },
73
- "gitnexus": {
74
- "source": "path",
75
- "aliases": ["gitnexus"],
76
- "verify": ["--version"],
77
- "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
78
- "hint": "npm i -g gitnexus && gitnexus setup"
79
- }
80
- },
81
-
82
- "requirements": [
83
- {
84
- "name": "hmos-spec-generate",
85
- "kind": "skill",
86
- "dependencies": [{ "tool": "gitnexus", "level": "required" }]
87
- },
88
- {
89
- "name": "hmos-resources-convert",
90
- "kind": "skill",
91
- "dependencies": [{ "tool": "java", "level": "optional" }],
92
- "note": "no java -> falls back to source res/"
93
- },
94
- {
95
- "name": "hmos-batch-ui-align",
96
- "kind": "skill",
97
- "dependencies": [
98
- { "tool": "python", "level": "required", "version": { "min": "3.10.0", "max": null } },
99
- { "tool": "adb", "level": "optional" }
100
- ],
101
- "note": "adb only for page exploration"
102
- },
103
- {
104
- "name": "hmos-incremental-ui-align",
105
- "kind": "skill",
106
- "dependencies": [
107
- { "tool": "deveco", "level": "required" },
108
- { "tool": "python", "level": "required", "version": { "min": "3.10.0", "max": null } },
109
- { "tool": "hdc", "level": "required" },
110
- { "tool": "adb", "level": "required" }
111
- ]
112
- },
113
- {
114
- "name": "hmos-integration-test",
115
- "kind": "skill",
116
- "dependencies": [
117
- { "tool": "deveco", "level": "required" },
118
- { "tool": "uv", "level": "required" },
119
- { "tool": "hdc", "level": "required" }
120
- ]
121
- },
122
- {
123
- "name": "hmos-fix-build-errors",
124
- "kind": "skill",
125
- "dependencies": [{ "tool": "deveco", "level": "required" }]
126
- },
127
- {
128
- "name": "hmos-convert-pipeline",
129
- "kind": "skill",
130
- "dependencies": [
131
- { "tool": "deveco", "level": "required" },
132
- { "tool": "uv", "level": "optional" },
133
- { "tool": "hdc", "level": "optional" }
134
- ],
135
- "note": "test stage skippable via skip_test"
136
- },
137
- {
138
- "name": "logic-context-builder",
139
- "kind": "agent",
140
- "dependencies": [{ "tool": "python", "level": "optional" }]
141
- },
142
- {
143
- "name": "logic-coder",
144
- "kind": "agent",
145
- "dependencies": [{ "tool": "python", "level": "optional" }]
146
- },
147
- {
148
- "name": "spec-generator",
149
- "kind": "agent",
150
- "dependencies": [{ "tool": "gitnexus", "level": "required" }]
151
- },
152
- {
153
- "name": "build-fixer",
154
- "kind": "agent",
155
- "dependencies": [{ "tool": "deveco", "level": "required" }]
156
- },
157
- {
158
- "name": "code-reviewer",
159
- "kind": "agent",
160
- "dependencies": [{ "tool": "deveco", "level": "optional" }]
161
- },
162
- {
163
- "name": "review-fixer",
164
- "kind": "agent",
165
- "dependencies": []
166
- },
167
- {
168
- "name": "self-tester",
169
- "kind": "agent",
170
- "dependencies": [
171
- { "tool": "uv", "level": "required" },
172
- { "tool": "hdc", "level": "required" }
173
- ]
174
- },
175
- {
176
- "name": "self-test-fixer",
177
- "kind": "agent",
178
- "dependencies": []
179
- }
180
- ]
181
- }
1
+ {
2
+ "$comment": [
3
+ "Declarative environment requirements for `ht init`.",
4
+ "`ht init` reads this file to (1) detect external tools and (2) report which",
5
+ "skills/agents are BLOCKED / LIMITED / OK by anything missing.",
6
+ "",
7
+ "tools[<id>]:",
8
+ " source 'path' -> locate a runnable command (where/which) trying each alias;",
9
+ " 'env-dir' -> a directory existence check (envVar resolved from ht config).",
10
+ " aliases command names to try in order (e.g. python, python3, py). First hit wins.",
11
+ " verify argv passed to the resolved command to print its version (existence proof too).",
12
+ " Use a flag that prints-and-exits. NEVER use `python -v` (verbose REPL -> hangs);",
13
+ " use `python --version`.",
14
+ " versionStream 'stdout' (default) or 'stderr' (java -version prints to stderr).",
15
+ " versionRegex capture group(s) for the numeric version in the verify output.",
16
+ " version default required range for this tool, {min, max} as [min, max) — min",
17
+ " inclusive, max exclusive; either may be null/omitted = unbounded. A",
18
+ " requirement dependency may override this.",
19
+ " fallback when not on PATH, probe <base>/<segments>/<exe>. base is a config env key",
20
+ " (DEVECO_SDK_HOME / DEVECO_HOME). Mirrors how the skills resolve hdc/java.",
21
+ " hint shown when the tool is missing.",
22
+ "",
23
+ "requirements[]: name + kind (skill|agent) + dependencies[] of",
24
+ " { tool, level: 'required'|'optional', version?: {min,max} }.",
25
+ " A missing 'required' tool -> BLOCKED; only 'optional' missing -> LIMITED; else OK."
26
+ ],
27
+
28
+ "tools": {
29
+ "deveco": {
30
+ "label": "harmony sdk",
31
+ "source": "env-dir",
32
+ "envVar": "DEVECO_SDK_HOME",
33
+ "hint": "set DEVECO_SDK_HOME via `ht init` (DevEco Studio install)"
34
+ },
35
+ "adb": {
36
+ "source": "path",
37
+ "aliases": ["adb"],
38
+ "verify": ["version"],
39
+ "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
40
+ "hint": "Android SDK platform-tools (needed for Android-device capture)"
41
+ },
42
+ "hdc": {
43
+ "source": "path",
44
+ "aliases": ["hdc"],
45
+ "verify": ["-v"],
46
+ "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
47
+ "fallback": { "base": "DEVECO_SDK_HOME", "segments": ["default", "openharmony", "toolchains"], "exe": "hdc" },
48
+ "hint": "ships with DevEco: <sdk>/default/openharmony/toolchains"
49
+ },
50
+ "uv": {
51
+ "source": "path",
52
+ "aliases": ["uv"],
53
+ "verify": ["--version"],
54
+ "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
55
+ "hint": "https://docs.astral.sh/uv — runs every Python script (AutoTest, UI-align, logic) via `uv run` and provides Python ≥ 3.10 on demand (no standalone Python needed)"
56
+ },
57
+ "java": {
58
+ "source": "path",
59
+ "aliases": ["java"],
60
+ "verify": ["-version"],
61
+ "versionStream": "stderr",
62
+ "versionRegex": "(\\d+(?:\\.\\d+){1,2})",
63
+ "fallback": { "base": "DEVECO_HOME", "segments": ["jbr", "bin"], "exe": "java" },
64
+ "hint": "any JDK 17+, or reuse DevEco jbr: <deveco>/jbr/bin"
65
+ },
66
+ "homegraph": {
67
+ "source": "path",
68
+ "aliases": ["homegraph"],
69
+ "verify": ["--version"],
70
+ "versionRegex": "(\\d+\\.\\d+(?:\\.\\d+)?)",
71
+ "hint": "npm install -g homegraph arkanalyzer (code-graph backend for spec generation)"
72
+ }
73
+ },
74
+
75
+ "requirements": [
76
+ {
77
+ "name": "hmos-spec-generate",
78
+ "kind": "skill",
79
+ "dependencies": [{ "tool": "homegraph", "level": "required" }]
80
+ },
81
+ {
82
+ "name": "hmos-resources-convert",
83
+ "kind": "skill",
84
+ "dependencies": [{ "tool": "java", "level": "optional" }],
85
+ "note": "no java -> falls back to source res/"
86
+ },
87
+ {
88
+ "name": "hmos-batch-ui-align",
89
+ "kind": "skill",
90
+ "dependencies": [
91
+ { "tool": "uv", "level": "required" },
92
+ { "tool": "adb", "level": "optional" }
93
+ ],
94
+ "note": "android_parse_fast.py runs via `uv run` (uv provides Python); adb only for page exploration"
95
+ },
96
+ {
97
+ "name": "hmos-incremental-ui-align",
98
+ "kind": "skill",
99
+ "dependencies": [
100
+ { "tool": "deveco", "level": "required" },
101
+ { "tool": "uv", "level": "required" },
102
+ { "tool": "hdc", "level": "required" },
103
+ { "tool": "adb", "level": "required" }
104
+ ],
105
+ "note": "app_feature_verify.py / page_capture.py run via `uv run` (PEP 723 inline deps; uv provides Python)"
106
+ },
107
+ {
108
+ "name": "hmos-integration-test",
109
+ "kind": "skill",
110
+ "dependencies": [
111
+ { "tool": "deveco", "level": "required" },
112
+ { "tool": "uv", "level": "required" },
113
+ { "tool": "hdc", "level": "required" }
114
+ ],
115
+ "note": "self_test_runner.py runs via `uv run --no-project python` (uv provides Python) and then `uv sync`s the AutoTest venv"
116
+ },
117
+ {
118
+ "name": "hmos-fix-build-errors",
119
+ "kind": "skill",
120
+ "dependencies": [{ "tool": "deveco", "level": "required" }]
121
+ },
122
+ {
123
+ "name": "hmos-convert-pipeline",
124
+ "kind": "skill",
125
+ "dependencies": [
126
+ { "tool": "deveco", "level": "required" },
127
+ { "tool": "uv", "level": "optional" },
128
+ { "tool": "hdc", "level": "optional" }
129
+ ],
130
+ "note": "test stage skippable via skip_test; when run it needs uv + hdc"
131
+ },
132
+ {
133
+ "name": "logic-context-builder",
134
+ "kind": "agent",
135
+ "dependencies": [{ "tool": "uv", "level": "optional" }]
136
+ },
137
+ {
138
+ "name": "logic-coder",
139
+ "kind": "agent",
140
+ "dependencies": [{ "tool": "uv", "level": "optional" }]
141
+ },
142
+ {
143
+ "name": "spec-generator",
144
+ "kind": "agent",
145
+ "dependencies": [{ "tool": "homegraph", "level": "required" }]
146
+ },
147
+ {
148
+ "name": "build-fixer",
149
+ "kind": "agent",
150
+ "dependencies": [{ "tool": "deveco", "level": "required" }]
151
+ },
152
+ {
153
+ "name": "code-reviewer",
154
+ "kind": "agent",
155
+ "dependencies": [{ "tool": "deveco", "level": "optional" }]
156
+ },
157
+ {
158
+ "name": "review-fixer",
159
+ "kind": "agent",
160
+ "dependencies": []
161
+ },
162
+ {
163
+ "name": "self-tester",
164
+ "kind": "agent",
165
+ "dependencies": [
166
+ { "tool": "uv", "level": "required" },
167
+ { "tool": "hdc", "level": "required" }
168
+ ],
169
+ "note": "invokes `uv run --no-project python self_test_runner.py run/status/kill` (uv provides Python; --no-project keeps the interpreter out of the .venv it rebuilds)"
170
+ },
171
+ {
172
+ "name": "self-test-fixer",
173
+ "kind": "agent",
174
+ "dependencies": []
175
+ }
176
+ ]
177
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buaa_smat/hometrans",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
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
  "repository": {
Binary file
@@ -0,0 +1,94 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1120 1080" width="1120" height="1080">
2
+ <style>
3
+ text { font-family: 'Helvetica Neue', Helvetica, Arial, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif; }
4
+ .title { font-size: 20px; font-weight: 600; fill: #111827; }
5
+ .sub { font-size: 12px; fill: #6b7280; }
6
+ .banner{ font-size: 12px; fill: #047857; font-weight: 600; }
7
+ .nt { font-size: 14px; font-weight: 600; fill: #111827; }
8
+ .ns { font-size: 11px; fill: #6b7280; }
9
+ .pin { font-size: 11px; fill: #1d4ed8; }
10
+ .pout { font-size: 11px; fill: #047857; }
11
+ .dlab { font-size: 11px; font-weight: 600; fill: #047857; }
12
+ .lg { font-size: 12px; fill: #374151; }
13
+ </style>
14
+ <defs>
15
+ <marker id="arrow" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
16
+ <polygon points="0 0, 10 3.5, 0 7" fill="#2563eb"/>
17
+ </marker>
18
+ <marker id="arrowg" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
19
+ <polygon points="0 0, 10 3.5, 0 7" fill="#059669"/>
20
+ </marker>
21
+ </defs>
22
+ <rect width="1120" height="1080" fill="#ffffff"/>
23
+ <text x="40" y="40" class="title">Android → HarmonyOS 迁移流程 · 含参数传递</text>
24
+ <text x="40" y="62" class="sub">蓝箭头=执行顺序;绿色=参数/产物传递;橙色框=人工介入</text>
25
+ <rect x="280" y="70" width="560" height="44" rx="8" fill="#ecfdf5" stroke="#10b981" stroke-width="1.4" stroke-dasharray="6,4"/>
26
+ <text x="560" y="90" text-anchor="middle" class="banner">公共入参(所有步骤共享):android_project_dir · harmony_project_dir</text>
27
+ <text x="560" y="106" text-anchor="middle" class="banner">步骤2 产物写入 harmony_project_dir,步骤4 据此构建</text>
28
+ <rect x="340" y="140" width="440" height="50" rx="25.0" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.6"/>
29
+ <text x="560" y="170" text-anchor="middle" class="nt">开始:准备 Android 源项目 + 鸿蒙目标项目</text>
30
+ <rect x="100" y="292" width="440" height="96" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
31
+ <text x="320" y="310" text-anchor="middle" class="nt">步骤1.1 UI 迁移</text>
32
+ <text x="320" y="328" text-anchor="middle" class="ns">skill:hmos-batch-ui-align</text>
33
+ <text x="320" y="348" text-anchor="middle" class="pin">入参: 公共入参 + [ui_info_root, pages]</text>
34
+ <text x="320" y="367" text-anchor="middle" class="pout">出参: ArkTS页面 + 资源(含资源转换) + 批量报告</text>
35
+ <rect x="580" y="292" width="440" height="96" rx="9" fill="#f5f9ff" stroke="#2563eb" stroke-width="1.6" stroke-dasharray="6,4"/>
36
+ <text x="800" y="310" text-anchor="middle" class="nt">步骤1.2 UI 对齐</text>
37
+ <text x="800" y="328" text-anchor="middle" class="ns">skill:hmos-incremental-ui-align</text>
38
+ <text x="800" y="348" text-anchor="middle" class="pin">入参: 公共入参 + [capture_output_dir]</text>
39
+ <text x="800" y="367" text-anchor="middle" class="pout">出参: 修改后ArkTS页面 + 双端截图/视图树 + 对齐报告</text>
40
+ <rect x="330" y="448" width="460" height="64" rx="9" fill="#fff7ed" stroke="#ea580c" stroke-width="1.6"/>
41
+ <circle cx="354.0" cy="473" r="4.5" fill="#ea580c"/>
42
+ <path d="M 347.0,488 Q 354.0,479 361.0,488" fill="none" stroke="#ea580c" stroke-width="2.2" stroke-linecap="round"/>
43
+ <text x="574" y="472" text-anchor="middle" class="nt">编写 REQ.txt(需求描述)</text>
44
+ <text x="574" y="492" text-anchor="middle" class="ns">使用自然语言描述原始需求,用空行分隔多个需求</text>
45
+ <text x="574" y="509" text-anchor="middle" class="pout">产出: REQ.txt</text>
46
+ <rect x="310" y="562" width="500" height="96" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
47
+ <text x="560" y="580" text-anchor="middle" class="nt">步骤2 生成需求规格</text>
48
+ <text x="560" y="598" text-anchor="middle" class="ns">skill:hmos-spec-generate</text>
49
+ <text x="560" y="618" text-anchor="middle" class="pin">入参: 公共入参 + requirement_description_file(=REQ.txt) + spec_output_dir</text>
50
+ <text x="560" y="637" text-anchor="middle" class="pout">出参: 〈feature〉-SPEC.md + .trace/〈feature〉.md</text>
51
+ <rect x="310" y="710" width="500" height="80" rx="9" fill="#fff7ed" stroke="#ea580c" stroke-width="1.6"/>
52
+ <circle cx="334.0" cy="743" r="4.5" fill="#ea580c"/>
53
+ <path d="M 327.0,758 Q 334.0,749 341.0,758" fill="none" stroke="#ea580c" stroke-width="2.2" stroke-linecap="round"/>
54
+ <text x="574" y="734" text-anchor="middle" class="nt">编写测试用例 + 连鸿蒙真机 / 配置签名</text>
55
+ <text x="574" y="754" text-anchor="middle" class="ns">如果不执行步骤4中的集成测试(skip_test=true)可跳过此步骤</text>
56
+ <text x="574" y="771" text-anchor="middle" class="pout">产出: test_case.md / pre_test_case.md</text>
57
+ <rect x="300" y="842" width="520" height="96" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
58
+ <text x="560" y="860" text-anchor="middle" class="nt">步骤3 逻辑代码转换流水线</text>
59
+ <text x="560" y="878" text-anchor="middle" class="ns">skill:hmos-convert-pipeline</text>
60
+ <text x="560" y="898" text-anchor="middle" class="pin">入参: 公共入参 + spec_file_path(=SPEC.md) + [test_case_path, pre_test_case_path, skip_test …]</text>
61
+ <text x="560" y="917" text-anchor="middle" class="pout">出参: 已签名HAP + pipeline-manifest.md + 各阶段报告</text>
62
+ <rect x="400" y="983" width="320" height="54" rx="9" fill="#ede9fe" stroke="#7c3aed" stroke-width="1.6"/>
63
+ <text x="560" y="1015" text-anchor="middle" class="nt">产物:已签名 HAP</text>
64
+ <path d="M560,190 V250 H320 V292" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
65
+ <path d="M560,190 V250 H800 V292" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
66
+ <path d="M320,388 V418 H558 V448" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
67
+ <path d="M800,388 V418 H562 V448" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
68
+ <path d="M560,512 V562" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
69
+ <path d="M560,658 V710" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
70
+ <path d="M560,790 V842" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
71
+ <path d="M560,938 V983" fill="none" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
72
+ <path d="M810,610 H865 V890 H822" fill="none" stroke="#059669" stroke-width="1.6" stroke-dasharray="6,4" marker-end="url(#arrowg)"/>
73
+ <rect x="415" y="528" width="290" height="16" rx="3" fill="#ffffff" opacity="0.92"/>
74
+ <text x="560" y="540" text-anchor="middle" class="dlab">REQ.txt ⇒ requirement_description_file</text>
75
+ <rect x="445" y="797" width="230" height="16" rx="3" fill="#ffffff" opacity="0.92"/>
76
+ <text x="560" y="809" text-anchor="middle" class="dlab">test_case.md ⇒ test_case_path</text>
77
+ <rect x="415" y="815" width="290" height="16" rx="3" fill="#ffffff" opacity="0.92"/>
78
+ <text x="560" y="827" text-anchor="middle" class="dlab">pre_test_case.md ⇒ pre_test_case_path</text>
79
+ <rect x="440" y="949" width="240" height="16" rx="3" fill="#ffffff" opacity="0.92"/>
80
+ <text x="560" y="961" text-anchor="middle" class="dlab">已签名HAP · pipeline-manifest.md</text>
81
+ <text x="872" y="745" class="dlab">〈feature〉-SPEC.md ⇒ spec_file_path</text>
82
+ <g transform="translate(40,920)">
83
+ <line x1="0" y1="6" x2="26" y2="6" stroke="#2563eb" stroke-width="1.6" marker-end="url(#arrow)"/>
84
+ <text x="34" y="10" class="lg">执行顺序</text>
85
+ <line x1="0" y1="26" x2="26" y2="26" stroke="#059669" stroke-width="1.6" stroke-dasharray="6,4" marker-end="url(#arrowg)"/>
86
+ <text x="34" y="30" class="lg">参数 / 产物传递</text>
87
+ <rect x="0" y="42" width="20" height="14" rx="3" fill="#eff6ff" stroke="#2563eb" stroke-width="1.4"/>
88
+ <text x="34" y="53" class="lg">自动化步骤(skill)</text>
89
+ <rect x="0" y="64" width="20" height="14" rx="3" fill="#fff7ed" stroke="#ea580c" stroke-width="1.4"/>
90
+ <text x="34" y="75" class="lg">人工介入</text>
91
+ <rect x="0" y="86" width="20" height="14" rx="3" fill="#f5f9ff" stroke="#2563eb" stroke-width="1.4" stroke-dasharray="6,4"/>
92
+ <text x="34" y="97" class="lg">可选 / 按需</text>
93
+ </g>
94
+ </svg>