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

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 +309 -18
  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.17";
55
+ return "0.1.18-alpha.0";
56
56
  }
57
57
  //#endregion
58
58
  //#region src/rule-engine/base.ts
@@ -3743,12 +3743,53 @@ function coerceCalVer(v) {
3743
3743
  function compareCalVer(a, b) {
3744
3744
  return semver.default.compare(coerceCalVer(a), coerceCalVer(b));
3745
3745
  }
3746
- /** Whether the given openclaw version falls inside this plugin entry's compat range. */
3747
- function compatible(entry, openclawVersion) {
3746
+ /** Look up an entry by exact plugin version; undefined if not in the table. */
3747
+ function findEntry(pluginVersion) {
3748
+ return VERSION_COMPAT_MAP.find((e) => e.openclawLarkVersion === pluginVersion);
3749
+ }
3750
+ /**
3751
+ * Infer the effective upper bound for a compat entry that has no explicit maxOpenclawVersion.
3752
+ *
3753
+ * Scans toward higher plugin versions (lower indices in the descending table) and returns
3754
+ * the first entry whose minOpenclawVersion differs from the current entry's.
3755
+ * That minOpenclawVersion becomes an EXCLUSIVE upper bound — the openclaw version that
3756
+ * starts a new incompatible range.
3757
+ *
3758
+ * Returns undefined for the topmost entry (no upper bound).
3759
+ */
3760
+ function inferEffectiveMax(index) {
3761
+ const cur = VERSION_COMPAT_MAP[index];
3762
+ if (cur.maxOpenclawVersion != null) return {
3763
+ max: cur.maxOpenclawVersion,
3764
+ exclusive: false
3765
+ };
3766
+ for (let i = index - 1; i >= 0; i--) if (compareCalVer(VERSION_COMPAT_MAP[i].minOpenclawVersion, cur.minOpenclawVersion) > 0) return {
3767
+ max: VERSION_COMPAT_MAP[i].minOpenclawVersion,
3768
+ exclusive: true
3769
+ };
3770
+ }
3771
+ /**
3772
+ * Full version compatibility check that infers the effective maxOpenclawVersion for
3773
+ * entries that only define minOpenclawVersion.
3774
+ *
3775
+ * For entries with an explicit maxOpenclawVersion the upper bound is INCLUSIVE (existing
3776
+ * semantics). For entries without one the upper bound is EXCLUSIVE — it is derived from
3777
+ * the minOpenclawVersion of the next entry group that requires a higher openclaw version.
3778
+ *
3779
+ * Example: openclaw-lark@2026.4.10 (min=2026.4.27, no explicit max) gets an inferred
3780
+ * exclusive max of '2026.5.6', so openclaw@2026.5.7 is correctly detected as incompatible
3781
+ * whereas the old compatible() call would have returned true.
3782
+ */
3783
+ function effectiveCompatible(pluginVersion, openclawVersion) {
3784
+ const index = VERSION_COMPAT_MAP.findIndex((e) => compareCalVer(e.openclawLarkVersion, pluginVersion) <= 0);
3785
+ if (index === -1) return false;
3786
+ const entry = VERSION_COMPAT_MAP[index];
3748
3787
  const oc = coerceCalVer(openclawVersion);
3749
3788
  if (semver.default.lt(oc, coerceCalVer(entry.minOpenclawVersion))) return false;
3750
- if (entry.maxOpenclawVersion != null && semver.default.gt(oc, coerceCalVer(entry.maxOpenclawVersion))) return false;
3751
- return true;
3789
+ const maxInfo = inferEffectiveMax(index);
3790
+ if (!maxInfo) return true;
3791
+ const max = coerceCalVer(maxInfo.max);
3792
+ return maxInfo.exclusive ? semver.default.lt(oc, max) : !semver.default.gt(oc, max);
3752
3793
  }
3753
3794
  /**
3754
3795
  * Floor match: find the entry with the largest openclawLarkVersion that is
@@ -3766,10 +3807,19 @@ function findClosestEntry(pluginVersion) {
3766
3807
  const PLUGIN_NAME$1 = "openclaw-lark";
3767
3808
  const LEGACY_SHORT_NAMES = ["feishu-openclaw-plugin"];
3768
3809
  const FORK_SCOPES = ["@lark-apaas"];
3769
- /** 特化 fork 版全名:虽免于 VERSION_COMPAT_MAP 检查,仍需 openclaw ≥ 此版本 */
3810
+ /** 特化 fork 版全名:复用官方 effectiveCompatible,按对标版本取完整兼容区间 */
3770
3811
  const FORK_LARK_PLUGIN_FULL_NAME = "@lark-apaas/openclaw-lark";
3771
- /** 来自 VERSION_COMPAT_MAP openclawLarkVersion=2026.4.1 对应的 minOpenclawVersion */
3772
- const FORK_LARK_PLUGIN_MIN_OC_VERSION = "2026.3.28";
3812
+ /**
3813
+ * fork 版对标的官方 openclaw-lark 版本。fork 自身版本不在 VERSION_COMPAT_MAP 内,
3814
+ * 兼容性按此对标版本经 effectiveCompatible 取完整区间(含推断上界)判定。
3815
+ */
3816
+ const FORK_LARK_PLUGIN_PINNED_VERSION = "2026.4.1";
3817
+ /**
3818
+ * fork 版兼容区间的下界,取自 VERSION_COMPAT_MAP 中 openclawLarkVersion=2026.4.1
3819
+ * 的 minOpenclawVersion,避免与映射表脱钩写死。仅用于区分升级方向
3820
+ * (oc 低于下界 → 升 openclaw;高于上界 → 升 lark);该条目被移除时回退到已知值。
3821
+ */
3822
+ const FORK_LARK_PLUGIN_MIN_OC_VERSION = findEntry(FORK_LARK_PLUGIN_PINNED_VERSION)?.minOpenclawVersion ?? "2026.3.28";
3773
3823
  let _ocVersion = void 0;
3774
3824
  function getOcVersion() {
3775
3825
  if (_ocVersion === void 0) _ocVersion = readOpenclawRuntimeVersion();
@@ -3845,7 +3895,15 @@ let FeishuPluginLarkUpgradeRule = class FeishuPluginLarkUpgradeRule extends Diag
3845
3895
  const cc = resolveCompatContext(ctx);
3846
3896
  if (!cc) return { pass: true };
3847
3897
  const { ocCur, recommendedOc, installed, isLegacy } = cc;
3848
- if (isForkPlugin(installed)) return { pass: true };
3898
+ if (isForkPlugin(installed)) {
3899
+ if (installed.fullName !== FORK_LARK_PLUGIN_FULL_NAME) return { pass: true };
3900
+ if (resolveForkUpgradeDirection(ocCur) !== "lark") return { pass: true };
3901
+ return {
3902
+ pass: false,
3903
+ action: "upgrade_lark",
3904
+ message: `飞书插件 ${describePlugin(installed)}(fork 版,对标 openclaw-lark@${FORK_LARK_PLUGIN_PINNED_VERSION})与当前 openclaw@${ocCur} 不兼容;建议升级飞书插件至兼容版本`
3905
+ };
3906
+ }
3849
3907
  if (!isLarkUpgradeNeededFromCC(cc)) return { pass: true };
3850
3908
  const prefix = buildCompatPrefix(installed, ocCur, isLegacy);
3851
3909
  if (!recommendedOc) return {
@@ -3890,13 +3948,12 @@ function isLegacyPlugin(p) {
3890
3948
  return LEGACY_SHORT_NAMES.includes(p.allowName);
3891
3949
  }
3892
3950
  /**
3893
- * floor 匹配找到最近的兼容表条目,检查 ocCur 是否在其 [min, max] 范围内。
3894
- * 版本读不到、表中无 当前插件版本的条目、或不在范围内,均视为不兼容。
3951
+ * 检查已装插件版本与当前 openclaw 版本是否兼容。
3952
+ * 使用 effectiveCompatible() 以正确推断无显式 maxOpenclawVersion 条目的上界。
3895
3953
  */
3896
3954
  function isVersionCompatible(p, ocCur) {
3897
3955
  if (!p.version) return false;
3898
- const entry = findClosestEntry(p.version);
3899
- return entry != null && compatible(entry, ocCur);
3956
+ return effectiveCompatible(p.version, ocCur);
3900
3957
  }
3901
3958
  /**
3902
3959
  * 豁免判断:若推荐的 openclaw 版本本身低于最近条目要求的最低版本,
@@ -3919,13 +3976,25 @@ function describeCompatConstraint(entry, pluginVersion) {
3919
3976
  return `该插件版本要求 openclaw ≥ ${entry.minOpenclawVersion}`;
3920
3977
  }
3921
3978
  /**
3922
- * @lark-apaas/openclaw-lark 豁免 VERSION_COMPAT_MAP,但仍要求 openclaw ≥ FORK_LARK_PLUGIN_MIN_OC_VERSION。
3979
+ * fork @lark-apaas/openclaw-lark 的升级方向:复用官方 effectiveCompatible,按对标版本
3980
+ * FORK_LARK_PLUGIN_PINNED_VERSION (2026.4.1) 取完整兼容区间。
3981
+ * null → 兼容
3982
+ * 'openclaw' → oc 低于区间下界,需升级 openclaw
3983
+ * 'lark' → oc 高于区间上界(插件相对当前 openclaw 过旧),需升级飞书插件
3984
+ */
3985
+ function resolveForkUpgradeDirection(ocCur) {
3986
+ if (effectiveCompatible(FORK_LARK_PLUGIN_PINNED_VERSION, ocCur)) return null;
3987
+ return compareCalVer(ocCur, FORK_LARK_PLUGIN_MIN_OC_VERSION) < 0 ? "openclaw" : "lark";
3988
+ }
3989
+ /**
3990
+ * @lark-apaas/openclaw-lark 复用官方 effectiveCompatible(按对标版本 2026.4.1 完整区间)。
3991
+ * 本函数(Rule 1)只负责 openclaw 方向(oc 低于下界);oc 高于上界由 Rule 2 报 upgrade_lark。
3923
3992
  * 其他 @lark-apaas scope 的 fork 插件继续无条件 pass。
3924
- * recommendedOc 可为 undefined(doctor 模式),此时只检测最低版本要求,不指定目标升级版本。
3993
+ * recommendedOc 可为 undefined(doctor 模式),此时不指定目标升级版本。
3925
3994
  */
3926
3995
  function validateForkPlugin(installed, ocCur, recommendedOc) {
3927
3996
  if (installed.fullName !== FORK_LARK_PLUGIN_FULL_NAME) return { pass: true };
3928
- if (compareCalVer(ocCur, FORK_LARK_PLUGIN_MIN_OC_VERSION) >= 0) return { pass: true };
3997
+ if (resolveForkUpgradeDirection(ocCur) !== "openclaw") return { pass: true };
3929
3998
  const recommendation = recommendedOc ? `;将 openclaw 升级到 ${recommendedOc} 即可满足` : `;请升级 openclaw 至 ${FORK_LARK_PLUGIN_MIN_OC_VERSION} 或更高版本`;
3930
3999
  return {
3931
4000
  pass: false,
@@ -3992,7 +4061,7 @@ function needsLarkUpgrade(ctx) {
3992
4061
  if (!cc) return false;
3993
4062
  const { ocCur, installed } = cc;
3994
4063
  if (isForkPlugin(installed)) {
3995
- if (installed.fullName === FORK_LARK_PLUGIN_FULL_NAME) return compareCalVer(ocCur, FORK_LARK_PLUGIN_MIN_OC_VERSION) < 0;
4064
+ if (installed.fullName === FORK_LARK_PLUGIN_FULL_NAME) return !effectiveCompatible(FORK_LARK_PLUGIN_PINNED_VERSION, ocCur);
3996
4065
  return false;
3997
4066
  }
3998
4067
  return isLarkUpgradeNeededFromCC(cc);
@@ -5159,6 +5228,24 @@ async function installExtension(tag, ossFileMap, opts = {}) {
5159
5228
  }
5160
5229
  console.error(`[install-extension] tag=${tag} targets=${targets.length}`);
5161
5230
  const t0 = Date.now();
5231
+ const larkTarget = opts.skipConfigUpdate ? void 0 : targets.find((p) => p.name === LARK_PLUGIN_NAME$1);
5232
+ if (larkTarget) {
5233
+ if (await installLarkPluginWithCompatCheck({
5234
+ tag,
5235
+ pkg: larkTarget,
5236
+ homeBase,
5237
+ configPath: opts.configPath ?? node_path.default.join(homeBase, "workspace/agent/openclaw.json"),
5238
+ workspaceDir: node_path.default.join(homeBase, "workspace", "agent"),
5239
+ ossFileMap,
5240
+ downloadOpts: opts
5241
+ })) {
5242
+ targets = targets.filter((p) => p.name !== LARK_PLUGIN_NAME$1);
5243
+ if (targets.length === 0) {
5244
+ console.error(`[install-extension] done in ${Date.now() - t0}ms`);
5245
+ return;
5246
+ }
5247
+ }
5248
+ }
5162
5249
  const tarballs = await Promise.all(targets.map(async (p) => {
5163
5250
  const tb = await downloadWithCache(p, ossFileMap, opts);
5164
5251
  console.error(`[install-extension] ${p.name}: downloaded`);
@@ -5175,6 +5262,7 @@ async function installExtension(tag, ossFileMap, opts = {}) {
5175
5262
  else console.error(`[install-extension] skipConfigUpdate=true — not touching openclaw.json`);
5176
5263
  console.error(`[install-extension] done ${targets.length}/${targets.length} in ${Date.now() - t0}ms`);
5177
5264
  }
5265
+ const LARK_PLUGIN_NAME$1 = "openclaw-lark";
5178
5266
  const MEM0_PLUGIN_NAME = "openclaw-mem0-plugin";
5179
5267
  const PLUGINS_TO_AUTO_ENABLE = ["openclaw-lark", "openclaw-extension-miaoda"];
5180
5268
  /**
@@ -5264,6 +5352,147 @@ function installOne$1(pkg, tarball, homeBase) {
5264
5352
  force: true
5265
5353
  });
5266
5354
  }
5355
+ /**
5356
+ * Install openclaw-lark with a pre-flight compatibility check.
5357
+ *
5358
+ * When the recommended version in the manifest is incompatible with the currently
5359
+ * running openclaw, falls back to `npx @larksuite/openclaw-lark-tools update` which
5360
+ * selects the correct plugin version automatically.
5361
+ *
5362
+ * Returns true when the lark plugin was handled by this function (either path),
5363
+ * false when it should fall through to the standard tarball install (e.g. when the
5364
+ * current openclaw version cannot be read).
5365
+ */
5366
+ async function installLarkPluginWithCompatCheck(opts) {
5367
+ const { tag, pkg, homeBase, configPath, workspaceDir } = opts;
5368
+ const ocCur = readOpenclawRuntimeVersion();
5369
+ if (!ocCur) {
5370
+ console.error("[install-extension] WARN: cannot read openclaw version — falling back to direct tarball install for openclaw-lark");
5371
+ return false;
5372
+ }
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}`);
5375
+ if (compatible) return false;
5376
+ console.error(`[install-extension] openclaw-lark@${pkg.version} incompatible with openclaw@${ocCur} — using openclaw-lark-tools update`);
5377
+ const backupDir = node_path.default.join(homeBase, `.openclaw-lark-backup-${tag}`);
5378
+ const backupOk = backupLarkPlugin({
5379
+ workspaceDir,
5380
+ configPath,
5381
+ backupDir
5382
+ });
5383
+ if (!backupOk) console.error("[install-extension] WARN: backup failed — proceeding without backup for openclaw-lark-tools path");
5384
+ try {
5385
+ const npxResult = (0, node_child_process.spawnSync)("npx", [
5386
+ "-y",
5387
+ "@larksuite/openclaw-lark-tools",
5388
+ "update"
5389
+ ], {
5390
+ cwd: workspaceDir,
5391
+ encoding: "utf-8",
5392
+ stdio: [
5393
+ "ignore",
5394
+ "pipe",
5395
+ "pipe"
5396
+ ],
5397
+ timeout: 6e5
5398
+ });
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) {
5404
+ console.error("[install-extension] openclaw-lark-tools failed — attempting rollback");
5405
+ if (backupOk) restoreLarkPlugin({
5406
+ workspaceDir,
5407
+ configPath,
5408
+ backupDir
5409
+ });
5410
+ throw new Error(`openclaw-lark-tools update exited with code ${npxExit}`);
5411
+ }
5412
+ const validation = validateLarkPluginInstall({
5413
+ homeBase,
5414
+ configPath
5415
+ });
5416
+ if (!validation.ok) {
5417
+ console.error(`[install-extension] post-install validation failed: ${validation.error} — rolling back`);
5418
+ if (backupOk) restoreLarkPlugin({
5419
+ workspaceDir,
5420
+ configPath,
5421
+ backupDir
5422
+ });
5423
+ throw new Error(`openclaw-lark post-install validation failed: ${validation.error}`);
5424
+ }
5425
+ console.error("[install-extension] openclaw-lark-tools update succeeded");
5426
+ return true;
5427
+ } finally {
5428
+ if (backupOk && node_fs.default.existsSync(backupDir)) try {
5429
+ node_fs.default.rmSync(backupDir, {
5430
+ recursive: true,
5431
+ force: true
5432
+ });
5433
+ } catch {}
5434
+ }
5435
+ }
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
+ /**
5469
+ * Post-install validation for the tools-based upgrade path.
5470
+ * Checks: plugin directory exists + plugin is enabled in openclaw.json.
5471
+ */
5472
+ function validateLarkPluginInstall(opts) {
5473
+ const { homeBase, configPath } = opts;
5474
+ const pkgJson = node_path.default.join(homeBase, "workspace", "agent", "extensions", LARK_PLUGIN_NAME$1, "package.json");
5475
+ if (!node_fs.default.existsSync(pkgJson)) return {
5476
+ ok: false,
5477
+ error: `plugin directory missing: ${pkgJson}`
5478
+ };
5479
+ if (!node_fs.default.existsSync(configPath)) return {
5480
+ ok: false,
5481
+ error: `openclaw.json not found at ${configPath}`
5482
+ };
5483
+ try {
5484
+ if (asRecord(getNestedMap(loadJSON5().parse(node_fs.default.readFileSync(configPath, "utf-8")), "plugins", "entries")?.[LARK_PLUGIN_NAME$1])?.enabled !== true) return {
5485
+ ok: false,
5486
+ error: `plugins.entries["${LARK_PLUGIN_NAME$1}"].enabled is not true`
5487
+ };
5488
+ } catch (e) {
5489
+ return {
5490
+ ok: false,
5491
+ error: `config parse error: ${e.message}`
5492
+ };
5493
+ }
5494
+ return { ok: true };
5495
+ }
5267
5496
  //#endregion
5268
5497
  //#region ../../openclaw-slardar/lib/client.js
5269
5498
  var import_index_cjs = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports) => {
@@ -6547,6 +6776,31 @@ function reportError(params) {
6547
6776
  const LARK_CLI_NAME = "lark-cli";
6548
6777
  const AGENT_SKILLS_NAME = "agent-skills";
6549
6778
  const WORKSPACE_AGENT_REL = "workspace/agent";
6779
+ const LARK_PLUGIN_NAME = "openclaw-lark";
6780
+ /**
6781
+ * openclaw-lark tools that overlap with lark-cli functionality.
6782
+ * Written to channels.feishu.tools.deny after lark-cli is installed so that
6783
+ * openclaw-lark's shouldRegisterTool() skips them, avoiding duplicate tools.
6784
+ * Supports trailing-* wildcards (handled by openclaw-lark's matchesAnyPattern).
6785
+ *
6786
+ * Kept: feishu_chat*, feishu_get_user, feishu_search_user, feishu_im_*,
6787
+ * feishu_oauth*, feishu_auth, feishu_diagnose, feishu_doctor
6788
+ */
6789
+ const LARK_CLI_OVERLAP_TOOL_DENY = Object.freeze([
6790
+ "feishu_create_doc",
6791
+ "feishu_fetch_doc",
6792
+ "feishu_update_doc",
6793
+ "feishu_doc_comments",
6794
+ "feishu_doc_media",
6795
+ "feishu_drive_file",
6796
+ "feishu_wiki_space",
6797
+ "feishu_wiki_space_node",
6798
+ "feishu_search_doc_wiki",
6799
+ "feishu_bitable_*",
6800
+ "feishu_calendar_*",
6801
+ "feishu_task_*",
6802
+ "feishu_sheet"
6803
+ ]);
6550
6804
  async function installClis(tag, ossFileMap, opts) {
6551
6805
  const homeBase = resolveHomeBase(opts.homeBase);
6552
6806
  if (opts.names.length === 0) throw new Error("install-cli: must provide at least one --cli=<name>");
@@ -6611,6 +6865,7 @@ async function installClis(tag, ossFileMap, opts) {
6611
6865
  }
6612
6866
  });
6613
6867
  }
6868
+ disableLarkCliOverlapTools(node_path.default.join(homeBase, WORKSPACE_AGENT_REL, "openclaw.json"), homeBase);
6614
6869
  }
6615
6870
  console.error(`[install-cli] done ${targets.length}/${targets.length} in ${Date.now() - t0}ms`);
6616
6871
  }
@@ -6785,6 +7040,42 @@ function installOne(pkg, tarball, homeBase, tmpRoot) {
6785
7040
  } catch {}
6786
7041
  }
6787
7042
  }
7043
+ /**
7044
+ * Write overlapping tool names to channels.feishu.tools.deny in openclaw.json so that
7045
+ * openclaw-lark's shouldRegisterTool() skips them when lark-cli is present.
7046
+ *
7047
+ * Only runs when openclaw-lark is installed (extensions/openclaw-lark/ exists).
7048
+ * Idempotent: merges with any existing deny entries.
7049
+ * Failures are non-fatal (logged as warnings).
7050
+ */
7051
+ function disableLarkCliOverlapTools(configPath, homeBase) {
7052
+ const larkPluginDir = node_path.default.join(homeBase, WORKSPACE_AGENT_REL, "extensions", LARK_PLUGIN_NAME);
7053
+ if (!node_fs.default.existsSync(larkPluginDir)) {
7054
+ console.error(`[install-cli] disableLarkCliOverlapTools: ${LARK_PLUGIN_NAME} not installed — skipping`);
7055
+ return;
7056
+ }
7057
+ if (!node_fs.default.existsSync(configPath)) {
7058
+ console.error(`[install-cli] disableLarkCliOverlapTools: config not found at ${configPath} — skipping`);
7059
+ return;
7060
+ }
7061
+ try {
7062
+ const config = loadJSON5().parse(node_fs.default.readFileSync(configPath, "utf-8"));
7063
+ if (!config.channels || typeof config.channels !== "object") config.channels = {};
7064
+ const channels = config.channels;
7065
+ if (!channels.feishu || typeof channels.feishu !== "object") channels.feishu = {};
7066
+ const feishu = channels.feishu;
7067
+ if (!feishu.tools || typeof feishu.tools !== "object") feishu.tools = {};
7068
+ const tools = feishu.tools;
7069
+ const existing = Array.isArray(tools.deny) ? tools.deny : [];
7070
+ tools.deny = [...new Set([...existing, ...LARK_CLI_OVERLAP_TOOL_DENY])];
7071
+ const tmp = configPath + ".lark-cli-deny-tmp";
7072
+ node_fs.default.writeFileSync(tmp, JSON.stringify(config, null, 2), "utf-8");
7073
+ moveSafe(tmp, configPath);
7074
+ console.error(`[install-cli] disableLarkCliOverlapTools: channels.feishu.tools.deny updated (${LARK_CLI_OVERLAP_TOOL_DENY.length} patterns)`);
7075
+ } catch (e) {
7076
+ console.error(`[install-cli] WARN: disableLarkCliOverlapTools failed: ${e.message}`);
7077
+ }
7078
+ }
6788
7079
  //#endregion
6789
7080
  //#region src/download-resource.ts
6790
7081
  /**
@@ -10720,7 +11011,7 @@ async function reportCliRun(opts) {
10720
11011
  //#region src/help.ts
10721
11012
  const BIN = "mclaw-diagnose";
10722
11013
  function versionBanner() {
10723
- return `v0.1.17`;
11014
+ return `v0.1.18-alpha.0`;
10724
11015
  }
10725
11016
  const COMMANDS = [
10726
11017
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/openclaw-scripts-diagnose-cli",
3
- "version": "0.1.17",
3
+ "version": "0.1.18-alpha.0",
4
4
  "description": "CLI for OpenClaw config diagnose and repair with JSON5 support",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {