@harmonyos-arkts/d2h 0.1.5 → 0.1.6

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
@@ -44,7 +44,7 @@ npx --yes @harmonyos-arkts/d2h@0.1.5 upgrade --check
44
44
  npx --yes @harmonyos-arkts/d2h@0.1.5 --check-env --output-dir ./environment-report
45
45
  ```
46
46
 
47
- VS Code 目标是 Huawei HarmonyOS Dev Assistant 扩展;安装器复制 Agent/Skill、注册 `d2h` 并设置读写编辑权限,同时将模式名显示为“安卓转鸿蒙”。扩展使用已解包的 OpenCode 缓存运行,安装器会同步更新当前活动缓存并备份改动;请先启动扩展一次以生成缓存,安装后在 VS Code 中执行“Developer: Reload Window”使对话后端重新读取配置。`doctor --agent vscode` 会检查扩展文件和活动缓存。详细用法见 [环境检查说明](docs/environment-check.md)。本地 npm link 开发安装不会被自动替换。
47
+ VS Code 目标是 Huawei HarmonyOS Dev Assistant 扩展;安装器复制 Agent/Skill、注册 `d2h` 并设置读写编辑权限,同时将模式名显示为“安卓转鸿蒙”。扩展使用已解包的 OpenCode 缓存运行,安装器会同步更新当前活动缓存并备份改动;请先启动扩展一次以生成缓存,安装后在 VS Code 中执行“Developer: Reload Window”使对话后端重新读取配置。`doctor --agent vscode` 会检查扩展文件和活动缓存。详细用法见 [环境检查说明](docs/environment-check.md)。受管 CLI 的全局 npm link 默认保留;显式运行 `d2h install --force --agent vscode` 会重新安装清单中的精确版本,替换全局链接,链接指向的源码目录不会被修改。
48
48
 
49
49
  Claude Code:
50
50
 
@@ -27,7 +27,7 @@ Usage: d2h [options]
27
27
  OPENCODE_CONFIG_DIR / DEVECO_CONFIG_DIR, or
28
28
  $XDG_CONFIG_HOME/<agent>, or ~/.config/<agent>
29
29
  --link Create absolute symbolic links (development only)
30
- --force Replace conflicting installed skills and agents
30
+ --force Replace conflicting definitions and managed CLI npm links
31
31
  --dry-run Print operations without writing files
32
32
  --skip-tools Install definitions only (local development)
33
33
  -h, --help Show this help
@@ -137,7 +137,7 @@ try {
137
137
  console.log(`${item.status}: ${item.package} expected ${item.expectedVersion}, installed ${item.installedVersion ?? 'missing'}`);
138
138
  }
139
139
  else if (!skipTools)
140
- installToolchain(packageRoot, { dryRun: options.dryRun });
140
+ installToolchain(packageRoot, { dryRun: options.dryRun, force: options.force });
141
141
  else if (!explicitSource && !options.dryRun)
142
142
  console.log(`Skipped managed CLI installation (${Object.keys(loadToolchain(packageRoot).tools).join(', ')}).`);
143
143
  if (!checkOnly) {
@@ -48,32 +48,36 @@ export function inspectToolchain(root, runner = run) {
48
48
  const manifest = loadToolchain(root);
49
49
  return Object.entries(manifest.tools).map(([name, tool]) => inspectTool(name, tool, runner));
50
50
  }
51
- export function installToolchain(root, { dryRun = false, runner = run, log = console.log } = {}) {
51
+ export function installToolchain(root, { dryRun = false, force = false, runner = run, log = console.log } = {}) {
52
52
  const manifest = loadToolchain(root);
53
53
  const before = Object.entries(manifest.tools).map(([name, tool]) => inspectTool(name, tool, runner));
54
- const missing = before.filter(item => item.status !== 'passed');
54
+ const targets = force ? before : before.filter(item => item.status !== 'passed');
55
55
  const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
56
- const globalRoot = missing.length ? runner(npm, ['root', '--global']) : null;
57
- if (missing.length && globalRoot?.status !== 0)
56
+ const globalRoot = targets.length ? runner(npm, ['root', '--global']) : null;
57
+ if (targets.length && globalRoot?.status !== 0)
58
58
  throw new Error(`cannot inspect global npm installation: ${globalRoot?.stderr ?? 'unknown error'}`);
59
- for (const item of missing) {
59
+ for (const item of targets) {
60
60
  const tool = manifest.tools[item.name];
61
61
  const coordinate = `${tool.package}@${tool.version}`;
62
62
  const linkedPath = path.join(globalRoot.stdout.trim(), ...tool.package.split('/'));
63
- if (fs.existsSync(linkedPath) && fs.lstatSync(linkedPath).isSymbolicLink() && dryRun) {
64
- log(`would preserve npm link ${tool.package} at ${linkedPath}; managed installation requires removing it explicitly`);
65
- continue;
66
- }
67
- if (fs.existsSync(linkedPath) && fs.lstatSync(linkedPath).isSymbolicLink()) {
68
- throw new Error(`${tool.package} is an npm link at ${linkedPath}; preserving local development installation. Remove the link explicitly or use --skip-tools.`);
63
+ const linked = fs.existsSync(linkedPath) && fs.lstatSync(linkedPath).isSymbolicLink();
64
+ if (linked && !force) {
65
+ if (dryRun) {
66
+ log(`would preserve npm link ${tool.package} at ${linkedPath}; rerun with --force to replace it`);
67
+ continue;
68
+ }
69
+ throw new Error(`${tool.package} is an npm link at ${linkedPath}; rerun with --force to replace it or use --skip-tools.`);
69
70
  }
70
71
  if (dryRun) {
71
- log(`would install ${coordinate}`);
72
+ log(`would ${linked ? 'replace npm link with' : 'install'} ${coordinate}`);
72
73
  continue;
73
74
  }
74
75
  const result = runner(npm, ['install', '--global', coordinate]);
75
76
  if (result.status !== 0)
76
77
  throw new Error(`failed to install ${coordinate}: ${result.stderr || result.error?.message}`);
78
+ if (linked && fs.existsSync(linkedPath) && fs.lstatSync(linkedPath).isSymbolicLink()) {
79
+ throw new Error(`${coordinate} installation completed but npm link remains at ${linkedPath}`);
80
+ }
77
81
  const verified = inspectTool(item.name, tool, runner);
78
82
  if (verified.status !== 'passed')
79
83
  throw new Error(`${coordinate} installed but CLI version or capabilities failed verification`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harmonyos-arkts/d2h",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Install Android-to-HarmonyOS migration agents and skills into OpenCode or DevEco Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,7 @@ description: 安装、检查或升级 D2H 所依赖的 AppGraph 与 droid2hmos C
16
16
  ## 检查与执行
17
17
 
18
18
  1. 确定目标 `--agent opencode|deveco|vscode`;VS Code 可通过 `--extension-dir` 指定扩展根目录。先运行 `d2h upgrade --check --agent <agent>` 只读预览,再运行 `d2h doctor --agent <agent>` 检查定义完整性、精确版本、命令能力与主机环境。
19
- 2. 若缺少定义或受管 CLI,运行 `d2h install --agent <agent>`;已安装但需要应用当前锁定组合时运行 `d2h upgrade --agent <agent>`。开发者的 npm link 不被覆盖:遇到 link 冲突,返回具体路径并等待维护者显式处理。
19
+ 2. 若缺少定义或受管 CLI,运行 `d2h install --agent <agent>`;已安装但需要应用当前锁定组合时运行 `d2h upgrade --agent <agent>`。默认保留开发者的 npm link;只有调用方明确指定 `--force` 时,才重新安装清单中的所有精确版本并替换全局 link,链接指向的源码目录保持不变。
20
20
  3. 安装后重新运行 `doctor`,核对 `.d2h-installation.json`、AppGraph/droid2hmos 的版本及能力,再把状态交给 `preparing-migration-workspace`。项目级 `droid2hmos preflight` 仍由准备 Skill 执行。
21
21
  4. 只想检查主机工具时使用 `d2h --check-env --output-dir <目录>`;读取生成的 JSON/Markdown 报告,不把 DevEco 登录、SDK 或设备缺失误判为需要升级 AppGraph/droid2hmos。
22
22