@lark-apaas/openclaw-scripts-diagnose-cli 0.1.18-alpha.0 → 0.1.18-alpha.2

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 (2) hide show
  1. package/dist/index.cjs +172 -170
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -52,7 +52,7 @@ node_assert = __toESM(node_assert);
52
52
  * it terse and parseable.
53
53
  */
54
54
  function getVersion() {
55
- return "0.1.18-alpha.0";
55
+ return "0.1.18-alpha.2";
56
56
  }
57
57
  //#endregion
58
58
  //#region src/rule-engine/base.ts
@@ -3791,6 +3791,16 @@ function effectiveCompatible(pluginVersion, openclawVersion) {
3791
3791
  const max = coerceCalVer(maxInfo.max);
3792
3792
  return maxInfo.exclusive ? semver.default.lt(oc, max) : !semver.default.gt(oc, max);
3793
3793
  }
3794
+ const FORK_LARK_PLUGIN_PINNED_VERSION = "2026.4.1";
3795
+ /**
3796
+ * Resolve the version to evaluate against VERSION_COMPAT_MAP for a given plugin.
3797
+ * The fork is pinned to FORK_LARK_PLUGIN_PINNED_VERSION regardless of its own
3798
+ * version; everything else uses its real version.
3799
+ */
3800
+ function resolveCompatVersion(packageName, version) {
3801
+ if (packageName === "@lark-apaas/openclaw-lark") return FORK_LARK_PLUGIN_PINNED_VERSION;
3802
+ return version;
3803
+ }
3794
3804
  /**
3795
3805
  * Floor match: find the entry with the largest openclawLarkVersion that is
3796
3806
  * ≤ pluginVersion ("closest lower-or-equal version").
@@ -3807,19 +3817,12 @@ function findClosestEntry(pluginVersion) {
3807
3817
  const PLUGIN_NAME$1 = "openclaw-lark";
3808
3818
  const LEGACY_SHORT_NAMES = ["feishu-openclaw-plugin"];
3809
3819
  const FORK_SCOPES = ["@lark-apaas"];
3810
- /** 特化 fork 版全名:复用官方 effectiveCompatible,按对标版本取完整兼容区间 */
3811
- const FORK_LARK_PLUGIN_FULL_NAME = "@lark-apaas/openclaw-lark";
3812
- /**
3813
- * fork 版对标的官方 openclaw-lark 版本。fork 自身版本不在 VERSION_COMPAT_MAP 内,
3814
- * 兼容性按此对标版本经 effectiveCompatible 取完整区间(含推断上界)判定。
3815
- */
3816
- const FORK_LARK_PLUGIN_PINNED_VERSION = "2026.4.1";
3817
3820
  /**
3818
3821
  * fork 版兼容区间的下界,取自 VERSION_COMPAT_MAP 中 openclawLarkVersion=2026.4.1
3819
3822
  * 的 minOpenclawVersion,避免与映射表脱钩写死。仅用于区分升级方向
3820
3823
  * (oc 低于下界 → 升 openclaw;高于上界 → 升 lark);该条目被移除时回退到已知值。
3821
3824
  */
3822
- const FORK_LARK_PLUGIN_MIN_OC_VERSION = findEntry(FORK_LARK_PLUGIN_PINNED_VERSION)?.minOpenclawVersion ?? "2026.3.28";
3825
+ const FORK_LARK_PLUGIN_MIN_OC_VERSION = findEntry("2026.4.1")?.minOpenclawVersion ?? "2026.3.28";
3823
3826
  let _ocVersion = void 0;
3824
3827
  function getOcVersion() {
3825
3828
  if (_ocVersion === void 0) _ocVersion = readOpenclawRuntimeVersion();
@@ -3896,7 +3899,7 @@ let FeishuPluginLarkUpgradeRule = class FeishuPluginLarkUpgradeRule extends Diag
3896
3899
  if (!cc) return { pass: true };
3897
3900
  const { ocCur, recommendedOc, installed, isLegacy } = cc;
3898
3901
  if (isForkPlugin(installed)) {
3899
- if (installed.fullName !== FORK_LARK_PLUGIN_FULL_NAME) return { pass: true };
3902
+ if (installed.fullName !== "@lark-apaas/openclaw-lark") return { pass: true };
3900
3903
  if (resolveForkUpgradeDirection(ocCur) !== "lark") return { pass: true };
3901
3904
  return {
3902
3905
  pass: false,
@@ -3983,7 +3986,7 @@ function describeCompatConstraint(entry, pluginVersion) {
3983
3986
  * 'lark' → oc 高于区间上界(插件相对当前 openclaw 过旧),需升级飞书插件
3984
3987
  */
3985
3988
  function resolveForkUpgradeDirection(ocCur) {
3986
- if (effectiveCompatible(FORK_LARK_PLUGIN_PINNED_VERSION, ocCur)) return null;
3989
+ if (effectiveCompatible("2026.4.1", ocCur)) return null;
3987
3990
  return compareCalVer(ocCur, FORK_LARK_PLUGIN_MIN_OC_VERSION) < 0 ? "openclaw" : "lark";
3988
3991
  }
3989
3992
  /**
@@ -3993,7 +3996,7 @@ function resolveForkUpgradeDirection(ocCur) {
3993
3996
  * recommendedOc 可为 undefined(doctor 模式),此时不指定目标升级版本。
3994
3997
  */
3995
3998
  function validateForkPlugin(installed, ocCur, recommendedOc) {
3996
- if (installed.fullName !== FORK_LARK_PLUGIN_FULL_NAME) return { pass: true };
3999
+ if (installed.fullName !== "@lark-apaas/openclaw-lark") return { pass: true };
3997
4000
  if (resolveForkUpgradeDirection(ocCur) !== "openclaw") return { pass: true };
3998
4001
  const recommendation = recommendedOc ? `;将 openclaw 升级到 ${recommendedOc} 即可满足` : `;请升级 openclaw 至 ${FORK_LARK_PLUGIN_MIN_OC_VERSION} 或更高版本`;
3999
4002
  return {
@@ -4061,7 +4064,7 @@ function needsLarkUpgrade(ctx) {
4061
4064
  if (!cc) return false;
4062
4065
  const { ocCur, installed } = cc;
4063
4066
  if (isForkPlugin(installed)) {
4064
- if (installed.fullName === FORK_LARK_PLUGIN_FULL_NAME) return !effectiveCompatible(FORK_LARK_PLUGIN_PINNED_VERSION, ocCur);
4067
+ if (installed.fullName === "@lark-apaas/openclaw-lark") return !effectiveCompatible(FORK_LARK_PLUGIN_PINNED_VERSION, ocCur);
4065
4068
  return false;
4066
4069
  }
4067
4070
  return isLarkUpgradeNeededFromCC(cc);
@@ -5206,6 +5209,139 @@ async function installOpenclaw(openclawTag, ossFileMap, opts = {}) {
5206
5209
  }
5207
5210
  console.error(`[install-openclaw] done in ${Date.now() - t0}ms`);
5208
5211
  }
5212
+ //#endregion
5213
+ //#region src/lark-tools-update.ts
5214
+ /**
5215
+ * 共享的飞书插件备份 / 恢复 / `openclaw-lark-tools update` 调用。
5216
+ *
5217
+ * upgrade-lark(场景修复流)与 install-extension(升级触发的兼容性预判路径)都需要
5218
+ * 「备份 → npx 适配升级 → 失败回滚」的同一套处理,此处统一封装,避免两份实现漂移。
5219
+ *
5220
+ * 日志通过可选 `log` 注入:upgrade-lark 传写日志文件的 Logger,install-extension 传
5221
+ * `console.error`,独立调用方不传则静默。
5222
+ */
5223
+ const NOOP_LOG = () => {};
5224
+ /** 升级前需备份的 extensions/ 下的插件目录(含 legacy) */
5225
+ const FEISHU_PLUGIN_DIRS = ["openclaw-lark", "feishu-openclaw-plugin"];
5226
+ /** 读取 package.json 的 version 字段,失败返回 null(仅用于日志) */
5227
+ function readPkgVersion(pkgPath) {
5228
+ try {
5229
+ const pkg = JSON.parse(node_fs.default.readFileSync(pkgPath, "utf-8"));
5230
+ return typeof pkg.version === "string" ? pkg.version : null;
5231
+ } catch {
5232
+ return null;
5233
+ }
5234
+ }
5235
+ /**
5236
+ * 备份 openclaw.json + FEISHU_PLUGIN_DIRS 下存在的插件目录到 backupDir。
5237
+ * 只备份当前存在的文件;不存在的记日志后跳过(恢复时据此判断「升级前是否存在」)。
5238
+ */
5239
+ function backupFeishuPlugins(opts) {
5240
+ const { workspaceDir, configPath, backupDir } = opts;
5241
+ const log = opts.log ?? NOOP_LOG;
5242
+ try {
5243
+ node_fs.default.mkdirSync(backupDir, { recursive: true });
5244
+ log(`backup dir: ${backupDir}`);
5245
+ if (node_fs.default.existsSync(configPath)) {
5246
+ const stat = node_fs.default.statSync(configPath);
5247
+ node_fs.default.copyFileSync(configPath, node_path.default.join(backupDir, "openclaw.json"));
5248
+ log(` backed up: openclaw.json (${stat.size} bytes)`);
5249
+ } else log(` skipped: openclaw.json (not found)`);
5250
+ node_fs.default.mkdirSync(node_path.default.join(backupDir, "extensions"), { recursive: true });
5251
+ const extSrc = node_path.default.join(workspaceDir, "extensions");
5252
+ for (const pluginDir of FEISHU_PLUGIN_DIRS) {
5253
+ const src = node_path.default.join(extSrc, pluginDir);
5254
+ if (node_fs.default.existsSync(src)) {
5255
+ const dst = node_path.default.join(backupDir, "extensions", pluginDir);
5256
+ node_fs.default.cpSync(src, dst, { recursive: true });
5257
+ const version = readPkgVersion(node_path.default.join(src, "package.json"));
5258
+ log(` backed up: extensions/${pluginDir}${version ? ` (version: ${version})` : ""}`);
5259
+ } else log(` skipped: extensions/${pluginDir} (not found)`);
5260
+ }
5261
+ return { ok: true };
5262
+ } catch (e) {
5263
+ const msg = `backup failed: ${e.message}`;
5264
+ log(`ERROR: ${msg}`);
5265
+ return {
5266
+ ok: false,
5267
+ error: msg
5268
+ };
5269
+ }
5270
+ }
5271
+ /**
5272
+ * 回滚到备份快照:先删除当前 openclaw.json + 插件目录,再从备份恢复(仅恢复备份中存在的,
5273
+ * 即升级前确实存在的文件)。这样升级过程中新建的文件会被清理,真正回到 pre-state。
5274
+ */
5275
+ function restoreFeishuPlugins(opts) {
5276
+ const { workspaceDir, configPath, backupDir } = opts;
5277
+ const log = opts.log ?? NOOP_LOG;
5278
+ try {
5279
+ if (node_fs.default.existsSync(configPath)) {
5280
+ node_fs.default.rmSync(configPath, { force: true });
5281
+ log(` deleted: openclaw.json`);
5282
+ }
5283
+ const extDst = node_path.default.join(workspaceDir, "extensions");
5284
+ for (const pluginDir of FEISHU_PLUGIN_DIRS) {
5285
+ const dst = node_path.default.join(extDst, pluginDir);
5286
+ if (node_fs.default.existsSync(dst)) {
5287
+ node_fs.default.rmSync(dst, {
5288
+ recursive: true,
5289
+ force: true
5290
+ });
5291
+ log(` deleted: extensions/${pluginDir}`);
5292
+ }
5293
+ }
5294
+ const configBackup = node_path.default.join(backupDir, "openclaw.json");
5295
+ if (node_fs.default.existsSync(configBackup)) {
5296
+ node_fs.default.copyFileSync(configBackup, configPath);
5297
+ log(` restored: openclaw.json`);
5298
+ } else log(` skipped restore: openclaw.json (not in backup — was not present before upgrade)`);
5299
+ for (const pluginDir of FEISHU_PLUGIN_DIRS) {
5300
+ const backupSrc = node_path.default.join(backupDir, "extensions", pluginDir);
5301
+ if (node_fs.default.existsSync(backupSrc)) {
5302
+ node_fs.default.cpSync(backupSrc, node_path.default.join(extDst, pluginDir), { recursive: true });
5303
+ log(` restored: extensions/${pluginDir}`);
5304
+ } else log(` skipped restore: extensions/${pluginDir} (not in backup — was not present before upgrade)`);
5305
+ }
5306
+ return true;
5307
+ } catch (e) {
5308
+ log(` restore error: ${e.message}`);
5309
+ return false;
5310
+ }
5311
+ }
5312
+ /**
5313
+ * 执行 `npx -y @larksuite/openclaw-lark-tools update`,自动按当前 openclaw 内核选择
5314
+ * 适配的 openclaw-lark 版本。stdout/stderr 已 trim;exitCode 缺失时归一为 1。
5315
+ */
5316
+ function runLarkToolsUpdate(opts) {
5317
+ const log = opts.log ?? NOOP_LOG;
5318
+ const r = (0, node_child_process.spawnSync)("npx", [
5319
+ "-y",
5320
+ "@larksuite/openclaw-lark-tools",
5321
+ "update"
5322
+ ], {
5323
+ cwd: opts.cwd,
5324
+ encoding: "utf-8",
5325
+ stdio: [
5326
+ "ignore",
5327
+ "pipe",
5328
+ "pipe"
5329
+ ],
5330
+ timeout: opts.timeoutMs ?? 6e5
5331
+ });
5332
+ const stdout = r.stdout?.trim() ?? "";
5333
+ const stderr = r.stderr?.trim() ?? "";
5334
+ const exitCode = r.status ?? 1;
5335
+ if (stdout) log(`npx stdout:\n${stdout}`);
5336
+ if (stderr) log(`npx stderr:\n${stderr}`);
5337
+ log(`npx exit: ${exitCode}${r.error ? ` error: ${r.error.message}` : ""}`);
5338
+ return {
5339
+ exitCode,
5340
+ stdout,
5341
+ stderr,
5342
+ spawnError: r.error?.message
5343
+ };
5344
+ }
5209
5345
  async function installExtension(tag, ossFileMap, opts = {}) {
5210
5346
  const homeBase = resolveHomeBase(opts.homeBase);
5211
5347
  const hasAll = !!opts.all;
@@ -5370,44 +5506,34 @@ async function installLarkPluginWithCompatCheck(opts) {
5370
5506
  console.error("[install-extension] WARN: cannot read openclaw version — falling back to direct tarball install for openclaw-lark");
5371
5507
  return false;
5372
5508
  }
5373
- const compatible = pkg.version ? effectiveCompatible(pkg.version, ocCur) : true;
5374
- console.error(`[install-extension] openclaw-lark@${pkg.version ?? "unknown"} compat with openclaw@${ocCur}: ${compatible}`);
5509
+ const compatVersion = resolveCompatVersion(pkg.packageName, pkg.version);
5510
+ const compatible = compatVersion ? effectiveCompatible(compatVersion, ocCur) : true;
5511
+ console.error(`[install-extension] ${pkg.packageName ?? pkg.name}@${pkg.version ?? "unknown"} (compat-as ${compatVersion ?? "unknown"}) vs openclaw@${ocCur}: ${compatible}`);
5375
5512
  if (compatible) return false;
5376
5513
  console.error(`[install-extension] openclaw-lark@${pkg.version} incompatible with openclaw@${ocCur} — using openclaw-lark-tools update`);
5514
+ const log = (msg) => console.error(`[install-extension] ${msg}`);
5377
5515
  const backupDir = node_path.default.join(homeBase, `.openclaw-lark-backup-${tag}`);
5378
- const backupOk = backupLarkPlugin({
5516
+ const backupOk = backupFeishuPlugins({
5379
5517
  workspaceDir,
5380
5518
  configPath,
5381
- backupDir
5382
- });
5519
+ backupDir,
5520
+ log
5521
+ }).ok;
5383
5522
  if (!backupOk) console.error("[install-extension] WARN: backup failed — proceeding without backup for openclaw-lark-tools path");
5384
5523
  try {
5385
- const npxResult = (0, node_child_process.spawnSync)("npx", [
5386
- "-y",
5387
- "@larksuite/openclaw-lark-tools",
5388
- "update"
5389
- ], {
5524
+ const { exitCode } = runLarkToolsUpdate({
5390
5525
  cwd: workspaceDir,
5391
- encoding: "utf-8",
5392
- stdio: [
5393
- "ignore",
5394
- "pipe",
5395
- "pipe"
5396
- ],
5397
- timeout: 6e5
5526
+ log
5398
5527
  });
5399
- const npxExit = npxResult.status ?? 1;
5400
- if (npxResult.stdout?.trim()) console.error(`[install-extension] openclaw-lark-tools stdout:\n${npxResult.stdout.trim()}`);
5401
- if (npxResult.stderr?.trim()) console.error(`[install-extension] openclaw-lark-tools stderr:\n${npxResult.stderr.trim()}`);
5402
- console.error(`[install-extension] openclaw-lark-tools exit: ${npxExit}`);
5403
- if (npxExit !== 0) {
5528
+ if (exitCode !== 0) {
5404
5529
  console.error("[install-extension] openclaw-lark-tools failed — attempting rollback");
5405
- if (backupOk) restoreLarkPlugin({
5530
+ if (backupOk) restoreFeishuPlugins({
5406
5531
  workspaceDir,
5407
5532
  configPath,
5408
- backupDir
5533
+ backupDir,
5534
+ log
5409
5535
  });
5410
- throw new Error(`openclaw-lark-tools update exited with code ${npxExit}`);
5536
+ throw new Error(`openclaw-lark-tools update exited with code ${exitCode}`);
5411
5537
  }
5412
5538
  const validation = validateLarkPluginInstall({
5413
5539
  homeBase,
@@ -5415,10 +5541,11 @@ async function installLarkPluginWithCompatCheck(opts) {
5415
5541
  });
5416
5542
  if (!validation.ok) {
5417
5543
  console.error(`[install-extension] post-install validation failed: ${validation.error} — rolling back`);
5418
- if (backupOk) restoreLarkPlugin({
5544
+ if (backupOk) restoreFeishuPlugins({
5419
5545
  workspaceDir,
5420
5546
  configPath,
5421
- backupDir
5547
+ backupDir,
5548
+ log
5422
5549
  });
5423
5550
  throw new Error(`openclaw-lark post-install validation failed: ${validation.error}`);
5424
5551
  }
@@ -5433,38 +5560,6 @@ async function installLarkPluginWithCompatCheck(opts) {
5433
5560
  } catch {}
5434
5561
  }
5435
5562
  }
5436
- function backupLarkPlugin(opts) {
5437
- const { workspaceDir, configPath, backupDir } = opts;
5438
- try {
5439
- node_fs.default.mkdirSync(backupDir, { recursive: true });
5440
- if (node_fs.default.existsSync(configPath)) node_fs.default.copyFileSync(configPath, node_path.default.join(backupDir, "openclaw.json"));
5441
- const pluginSrc = node_path.default.join(workspaceDir, "extensions", LARK_PLUGIN_NAME$1);
5442
- if (node_fs.default.existsSync(pluginSrc)) node_fs.default.cpSync(pluginSrc, node_path.default.join(backupDir, LARK_PLUGIN_NAME$1), { recursive: true });
5443
- return true;
5444
- } catch (e) {
5445
- console.error(`[install-extension] backup error: ${e.message}`);
5446
- return false;
5447
- }
5448
- }
5449
- function restoreLarkPlugin(opts) {
5450
- const { workspaceDir, configPath, backupDir } = opts;
5451
- try {
5452
- const configBak = node_path.default.join(backupDir, "openclaw.json");
5453
- if (node_fs.default.existsSync(configBak)) node_fs.default.copyFileSync(configBak, configPath);
5454
- const pluginBak = node_path.default.join(backupDir, LARK_PLUGIN_NAME$1);
5455
- const pluginDst = node_path.default.join(workspaceDir, "extensions", LARK_PLUGIN_NAME$1);
5456
- if (node_fs.default.existsSync(pluginBak)) {
5457
- if (node_fs.default.existsSync(pluginDst)) node_fs.default.rmSync(pluginDst, {
5458
- recursive: true,
5459
- force: true
5460
- });
5461
- node_fs.default.cpSync(pluginBak, pluginDst, { recursive: true });
5462
- }
5463
- console.error("[install-extension] rollback complete");
5464
- } catch (e) {
5465
- console.error(`[install-extension] rollback error: ${e.message}`);
5466
- }
5467
- }
5468
5563
  /**
5469
5564
  * Post-install validation for the tools-based upgrade path.
5470
5565
  * Checks: plugin directory exists + plugin is enabled in openclaw.json.
@@ -11011,7 +11106,7 @@ async function reportCliRun(opts) {
11011
11106
  //#region src/help.ts
11012
11107
  const BIN = "mclaw-diagnose";
11013
11108
  function versionBanner() {
11014
- return `v0.1.18-alpha.0`;
11109
+ return `v0.1.18-alpha.2`;
11015
11110
  }
11016
11111
  const COMMANDS = [
11017
11112
  {
@@ -11697,83 +11792,6 @@ function buildUpgradeLarkResultSummary(result, checkOnly) {
11697
11792
  }
11698
11793
  //#endregion
11699
11794
  //#region src/upgrade-lark.ts
11700
- /** 升级前需备份的 extensions/ 下的插件目录 */
11701
- const FEISHU_PLUGIN_DIRS = ["openclaw-lark", "feishu-openclaw-plugin"];
11702
- function backupFiles(opts) {
11703
- const { workspaceDir, configPath, backupDir, log } = opts;
11704
- try {
11705
- node_fs.default.mkdirSync(backupDir, { recursive: true });
11706
- log(`backup dir: ${backupDir}`);
11707
- if (node_fs.default.existsSync(configPath)) {
11708
- const stat = node_fs.default.statSync(configPath);
11709
- node_fs.default.copyFileSync(configPath, node_path.default.join(backupDir, "openclaw.json"));
11710
- log(` backed up: openclaw.json (${stat.size} bytes)`);
11711
- } else log(` skipped: openclaw.json (not found)`);
11712
- node_fs.default.mkdirSync(node_path.default.join(backupDir, "extensions"), { recursive: true });
11713
- const extSrc = node_path.default.join(workspaceDir, "extensions");
11714
- for (const pluginDir of FEISHU_PLUGIN_DIRS) {
11715
- const src = node_path.default.join(extSrc, pluginDir);
11716
- if (node_fs.default.existsSync(src)) {
11717
- const dst = node_path.default.join(backupDir, "extensions", pluginDir);
11718
- node_fs.default.cpSync(src, dst, { recursive: true });
11719
- const version = readPkgVersion(node_path.default.join(src, "package.json"));
11720
- log(` backed up: extensions/${pluginDir}${version ? ` (version: ${version})` : ""}`);
11721
- } else log(` skipped: extensions/${pluginDir} (not found)`);
11722
- }
11723
- return { ok: true };
11724
- } catch (e) {
11725
- const msg = `backup failed: ${e.message}`;
11726
- log(`ERROR: ${msg}`);
11727
- return {
11728
- ok: false,
11729
- error: msg
11730
- };
11731
- }
11732
- }
11733
- function restoreFiles(opts) {
11734
- const { workspaceDir, configPath, backupDir, log } = opts;
11735
- try {
11736
- if (node_fs.default.existsSync(configPath)) {
11737
- node_fs.default.rmSync(configPath, { force: true });
11738
- log(` deleted: openclaw.json`);
11739
- }
11740
- const extDst = node_path.default.join(workspaceDir, "extensions");
11741
- for (const pluginDir of FEISHU_PLUGIN_DIRS) {
11742
- const dst = node_path.default.join(extDst, pluginDir);
11743
- if (node_fs.default.existsSync(dst)) {
11744
- node_fs.default.rmSync(dst, {
11745
- recursive: true,
11746
- force: true
11747
- });
11748
- log(` deleted: extensions/${pluginDir}`);
11749
- }
11750
- }
11751
- const configBackup = node_path.default.join(backupDir, "openclaw.json");
11752
- if (node_fs.default.existsSync(configBackup)) {
11753
- node_fs.default.copyFileSync(configBackup, configPath);
11754
- log(` restored: openclaw.json`);
11755
- } else log(` skipped restore: openclaw.json (not in backup — was not present before upgrade)`);
11756
- for (const pluginDir of FEISHU_PLUGIN_DIRS) {
11757
- const backupSrc = node_path.default.join(backupDir, "extensions", pluginDir);
11758
- if (node_fs.default.existsSync(backupSrc)) {
11759
- node_fs.default.cpSync(backupSrc, node_path.default.join(extDst, pluginDir), { recursive: true });
11760
- log(` restored: extensions/${pluginDir}`);
11761
- } else log(` skipped restore: extensions/${pluginDir} (not in backup — was not present before upgrade)`);
11762
- }
11763
- return true;
11764
- } catch (e) {
11765
- log(` restore error: ${e.message}`);
11766
- return false;
11767
- }
11768
- }
11769
- function readPkgVersion(pkgPath) {
11770
- try {
11771
- const pkg = JSON.parse(node_fs.default.readFileSync(pkgPath, "utf-8"));
11772
- return typeof pkg.version === "string" ? pkg.version : null;
11773
- } catch {
11774
- return null;
11775
- }
11776
- }
11777
11795
  function snapshotVersions(cwd, log) {
11778
11796
  const ocResult = (0, node_child_process.spawnSync)("openclaw", ["--version"], {
11779
11797
  cwd,
@@ -12029,7 +12047,7 @@ function runUpgradeLark(opts) {
12029
12047
  log("── [1/6] 文件备份 ────────────────────────────────────────");
12030
12048
  log(`before-state: botCount=${countFeishuBots(configPath)}`);
12031
12049
  const t_backupStart = Date.now();
12032
- const backup = backupFiles(fsOpts);
12050
+ const backup = backupFeishuPlugins(fsOpts);
12033
12051
  timing.backupMs = Date.now() - t_backupStart;
12034
12052
  if (!backup.ok) {
12035
12053
  log(`ERROR: ${backup.error}`);
@@ -12056,27 +12074,11 @@ function runUpgradeLark(opts) {
12056
12074
  log("");
12057
12075
  log("── [3/6] npx install (@larksuite/openclaw-lark-tools update) ──");
12058
12076
  const t_npxStart = Date.now();
12059
- const npxResult = (0, node_child_process.spawnSync)("npx", [
12060
- "-y",
12061
- "@larksuite/openclaw-lark-tools",
12062
- "update"
12063
- ], {
12077
+ const { exitCode: npxExitCode, stdout: npxStdout, stderr: npxStderr } = runLarkToolsUpdate({
12064
12078
  cwd,
12065
- encoding: "utf-8",
12066
- stdio: [
12067
- "ignore",
12068
- "pipe",
12069
- "pipe"
12070
- ],
12071
- timeout: 6e5
12079
+ log
12072
12080
  });
12073
12081
  timing.npxInstallMs = Date.now() - t_npxStart;
12074
- const npxStdout = npxResult.stdout?.trim() ?? "";
12075
- const npxStderr = npxResult.stderr?.trim() ?? "";
12076
- const npxExitCode = npxResult.status ?? 1;
12077
- if (npxStdout) log(`npx stdout:\n${npxStdout}`);
12078
- if (npxStderr) log(`npx stderr:\n${npxStderr}`);
12079
- log(`npx exit: ${npxExitCode}${npxResult.error ? ` error: ${npxResult.error.message}` : ""}`);
12080
12082
  if (statusCheckDelayMs > 0) {
12081
12083
  log("");
12082
12084
  log(`── 等待 ${statusCheckDelayMs / 1e3}s(让 openclaw 服务完成重启) ─────────────`);
@@ -12085,7 +12087,7 @@ function runUpgradeLark(opts) {
12085
12087
  }
12086
12088
  const doRollback = (reason) => {
12087
12089
  log(`ERROR: ${reason}`);
12088
- const rollbackOk = restoreFiles(fsOpts);
12090
+ const rollbackOk = restoreFeishuPlugins(fsOpts);
12089
12091
  log(`rollback: ${rollbackOk ? "ok" : "FAILED"}`);
12090
12092
  return finalReturn({
12091
12093
  status: "failed",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/openclaw-scripts-diagnose-cli",
3
- "version": "0.1.18-alpha.0",
3
+ "version": "0.1.18-alpha.2",
4
4
  "description": "CLI for OpenClaw config diagnose and repair with JSON5 support",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {