@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.
- package/dist/index.cjs +172 -170
- 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.
|
|
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(
|
|
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 !==
|
|
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(
|
|
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 !==
|
|
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 ===
|
|
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
|
|
5374
|
-
|
|
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 =
|
|
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
|
|
5386
|
-
"-y",
|
|
5387
|
-
"@larksuite/openclaw-lark-tools",
|
|
5388
|
-
"update"
|
|
5389
|
-
], {
|
|
5524
|
+
const { exitCode } = runLarkToolsUpdate({
|
|
5390
5525
|
cwd: workspaceDir,
|
|
5391
|
-
|
|
5392
|
-
stdio: [
|
|
5393
|
-
"ignore",
|
|
5394
|
-
"pipe",
|
|
5395
|
-
"pipe"
|
|
5396
|
-
],
|
|
5397
|
-
timeout: 6e5
|
|
5526
|
+
log
|
|
5398
5527
|
});
|
|
5399
|
-
|
|
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)
|
|
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 ${
|
|
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)
|
|
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.
|
|
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 =
|
|
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
|
|
12060
|
-
"-y",
|
|
12061
|
-
"@larksuite/openclaw-lark-tools",
|
|
12062
|
-
"update"
|
|
12063
|
-
], {
|
|
12077
|
+
const { exitCode: npxExitCode, stdout: npxStdout, stderr: npxStderr } = runLarkToolsUpdate({
|
|
12064
12078
|
cwd,
|
|
12065
|
-
|
|
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 =
|
|
12090
|
+
const rollbackOk = restoreFeishuPlugins(fsOpts);
|
|
12089
12091
|
log(`rollback: ${rollbackOk ? "ok" : "FAILED"}`);
|
|
12090
12092
|
return finalReturn({
|
|
12091
12093
|
status: "failed",
|
package/package.json
CHANGED