@ryantest/openclaw-qqbot 1.6.7-beta.8 → 1.6.7-beta.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryantest/openclaw-qqbot",
3
- "version": "1.6.7-beta.8",
3
+ "version": "1.6.7-beta.9",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,15 +18,53 @@
18
18
 
19
19
  set -eo pipefail
20
20
 
21
- # 异常退出时清理临时文件(防止泄露或残留)
21
+ # 异常退出时清理临时文件并回滚(防止泄露或残留)
22
+ INSTALL_COMPLETED=false # 标记 install 是否已完成(用于区分正常退出和异常退出)
22
23
  cleanup_on_exit() {
24
+ local exit_code=$?
25
+
26
+ # 异常退出时同步临时配置中的 install 记录回真实配置
23
27
  if [ -n "$TEMP_CONFIG_FILE" ] && [ -f "$TEMP_CONFIG_FILE" ]; then
28
+ # 尝试同步 install 记录(即使异常退出也要保留)
29
+ node -e "
30
+ try {
31
+ const fs = require('fs');
32
+ const tmp = JSON.parse(fs.readFileSync('$TEMP_CONFIG_FILE', 'utf8'));
33
+ const real = JSON.parse(fs.readFileSync('$CONFIG_FILE', 'utf8'));
34
+ if (tmp.plugins && tmp.plugins.installs) {
35
+ if (!real.plugins) real.plugins = {};
36
+ real.plugins.installs = { ...(real.plugins.installs || {}), ...tmp.plugins.installs };
37
+ }
38
+ if (tmp.plugins && tmp.plugins.entries) {
39
+ if (!real.plugins) real.plugins = {};
40
+ real.plugins.entries = { ...(real.plugins.entries || {}), ...tmp.plugins.entries };
41
+ }
42
+ fs.writeFileSync('$CONFIG_FILE', JSON.stringify(real, null, 4) + '\n');
43
+ } catch {}
44
+ " 2>/dev/null || true
24
45
  rm -f "$TEMP_CONFIG_FILE" 2>/dev/null || true
25
46
  fi
26
- # 异常退出时清理本次备份目录(正常流程中备份已被删除或回滚,这里是兜底)
27
- if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
47
+
48
+ # 异常退出且 install 未完成时,回滚备份目录(而非删除)
49
+ if [ "$INSTALL_COMPLETED" != "true" ] && [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
50
+ if [ ! -d "$EXTENSIONS_DIR/$PLUGIN_ID" ] || [ ! -f "$EXTENSIONS_DIR/$PLUGIN_ID/package.json" ]; then
51
+ # 插件目录不存在或不完整,回滚
52
+ rm -rf "$EXTENSIONS_DIR/$PLUGIN_ID" 2>/dev/null || true
53
+ mv "$BACKUP_DIR/$PLUGIN_ID" "$EXTENSIONS_DIR/$PLUGIN_ID" 2>/dev/null || \
54
+ mv "$BACKUP_DIR"/* "$EXTENSIONS_DIR/$PLUGIN_ID" 2>/dev/null || true
55
+ echo " ↩️ [cleanup] 异常退出,已回滚到旧版本"
56
+ else
57
+ # 插件目录完整,清理备份
58
+ rm -rf "$BACKUP_DIR" 2>/dev/null || true
59
+ fi
60
+ elif [ "$INSTALL_COMPLETED" = "true" ] && [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
61
+ # 正常完成,清理备份
28
62
  rm -rf "$BACKUP_DIR" 2>/dev/null || true
29
63
  fi
64
+
65
+ # 清理 openclaw install 可能残留的暂存目录(extensions 和 /tmp 中都可能存在)
66
+ find "${EXTENSIONS_DIR:-/dev/null}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
67
+ find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
30
68
  }
31
69
  trap cleanup_on_exit EXIT
32
70
 
@@ -232,22 +270,32 @@ fi
232
270
  # plugins install/update 可能把 install 记录写入了临时配置,需要同步回真实配置
233
271
  restore_qqbot_channel() {
234
272
  if [ -n "$TEMP_CONFIG_FILE" ] && [ -f "$TEMP_CONFIG_FILE" ]; then
235
- # 将临时配置中 plugins.installs 的变更同步回真实配置
273
+ # 将临时配置中 plugins.installs 和 plugins.entries 的变更同步回真实配置
236
274
  node -e "
237
275
  try {
238
276
  const fs = require('fs');
239
277
  const tmp = JSON.parse(fs.readFileSync('$TEMP_CONFIG_FILE', 'utf8'));
240
278
  const real = JSON.parse(fs.readFileSync('$CONFIG_FILE', 'utf8'));
279
+ let changed = false;
241
280
  if (tmp.plugins && tmp.plugins.installs) {
242
281
  if (!real.plugins) real.plugins = {};
243
282
  real.plugins.installs = { ...(real.plugins.installs || {}), ...tmp.plugins.installs };
283
+ changed = true;
284
+ }
285
+ // 同步 plugins.entries(openclaw plugins install 会写入 entries)
286
+ if (tmp.plugins && tmp.plugins.entries) {
287
+ if (!real.plugins) real.plugins = {};
288
+ real.plugins.entries = { ...(real.plugins.entries || {}), ...tmp.plugins.entries };
289
+ changed = true;
290
+ }
291
+ if (changed) {
244
292
  fs.writeFileSync('$CONFIG_FILE', JSON.stringify(real, null, 4) + '\n');
245
293
  }
246
294
  } catch {}
247
295
  " 2>/dev/null || true
248
296
  rm -f "$TEMP_CONFIG_FILE"
249
297
  unset OPENCLAW_CONFIG_PATH
250
- echo " [兼容] 已同步 install 记录并清理临时配置副本"
298
+ echo " [兼容] 已同步 install/entries 记录并清理临时配置副本"
251
299
  fi
252
300
  }
253
301
 
@@ -336,21 +384,57 @@ if [ "$UPGRADE_OK" != "true" ]; then
336
384
  echo " 执行 install: $INSTALL_SRC"
337
385
 
338
386
  if $CMD plugins install "$INSTALL_SRC" --pin 2>&1; then
339
- UPGRADE_OK=true
340
- echo " install 成功"
341
- # install 成功,清理备份
342
- if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
343
- rm -rf "$BACKUP_DIR"
344
- echo " 已清理旧版备份"
387
+ # install 返回 0,但需要验证插件目录是否真的存在且完整
388
+ if [ -d "$EXTENSIONS_DIR/$PLUGIN_ID" ] && [ -f "$EXTENSIONS_DIR/$PLUGIN_ID/package.json" ]; then
389
+ UPGRADE_OK=true
390
+ INSTALL_COMPLETED=true
391
+ echo " ✅ install 成功"
392
+ # install 成功,清理备份
393
+ if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
394
+ rm -rf "$BACKUP_DIR"
395
+ echo " 已清理旧版备份"
396
+ fi
397
+ # 清理 openclaw CLI install 可能留下的额外 backup 目录(extensions 内遗留 + 新路径)
398
+ find "$EXTENSIONS_DIR" -maxdepth 1 -name ".openclaw-qqbot-backup-*" -exec rm -rf {} + 2>/dev/null || true
399
+ find "${EXTENSIONS_DIR:-/dev/null}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
400
+ find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
401
+ find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".qqbot-upgrade-backup-*" -exec rm -rf {} + 2>/dev/null || true
402
+ else
403
+ echo " ❌ install 命令返回成功但插件目录不完整"
404
+ echo " [诊断] 目录存在: $([ -d "$EXTENSIONS_DIR/$PLUGIN_ID" ] && echo '是' || echo '否')"
405
+ echo " [诊断] package.json 存在: $([ -f "$EXTENSIONS_DIR/$PLUGIN_ID/package.json" ] && echo '是' || echo '否')"
406
+ # 清理可能残留的暂存目录(extensions 和 /tmp 中都可能存在)
407
+ find "${EXTENSIONS_DIR:-/dev/null}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
408
+ find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
409
+ # 回滚
410
+ if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
411
+ rm -rf "$EXTENSIONS_DIR/$PLUGIN_ID" 2>/dev/null || true
412
+ # 备份目录内可能是 PLUGIN_ID 子目录或直接是内容
413
+ if [ -d "$BACKUP_DIR/$PLUGIN_ID" ]; then
414
+ mv "$BACKUP_DIR/$PLUGIN_ID" "$EXTENSIONS_DIR/$PLUGIN_ID"
415
+ else
416
+ mv "$BACKUP_DIR" "$EXTENSIONS_DIR/$PLUGIN_ID"
417
+ fi
418
+ echo " ↩️ 已回滚到旧版本"
419
+ fi
420
+ restore_qqbot_channel
421
+ echo "QQBOT_NEW_VERSION=unknown"
422
+ echo "QQBOT_REPORT=❌ QQBot 安装异常(目录不完整,已回滚),请重试或手动安装"
423
+ exit 1
345
424
  fi
346
- # 清理 openclaw CLI install 可能留下的额外 backup 目录(extensions 内遗留 + 新路径)
347
- find "$EXTENSIONS_DIR" -maxdepth 1 -name ".openclaw-qqbot-backup-*" -exec rm -rf {} + 2>/dev/null || true
348
- find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".qqbot-upgrade-backup-*" -exec rm -rf {} + 2>/dev/null || true
349
425
  else
350
426
  echo " ❌ install 失败"
427
+ # 清理可能残留的暂存目录(extensions 和 /tmp 中都可能存在)
428
+ find "${EXTENSIONS_DIR:-/dev/null}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
429
+ find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
351
430
  # 回滚:恢复旧目录
352
431
  if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
353
- mv "$BACKUP_DIR" "$EXTENSIONS_DIR/$PLUGIN_ID"
432
+ rm -rf "$EXTENSIONS_DIR/$PLUGIN_ID" 2>/dev/null || true
433
+ if [ -d "$BACKUP_DIR/$PLUGIN_ID" ]; then
434
+ mv "$BACKUP_DIR/$PLUGIN_ID" "$EXTENSIONS_DIR/$PLUGIN_ID"
435
+ else
436
+ mv "$BACKUP_DIR" "$EXTENSIONS_DIR/$PLUGIN_ID"
437
+ fi
354
438
  echo " ↩️ 已回滚到旧版本"
355
439
  fi
356
440
  restore_qqbot_channel
@@ -262,8 +262,9 @@ if lsof -i :18789 -sTCP:LISTEN >/dev/null 2>&1; then
262
262
  sleep 1
263
263
  fi
264
264
 
265
- # 清理之前可能残留的 staging 目录
265
+ # 清理之前可能残留的 staging 目录(extensions 和 /tmp 中都可能存在)
266
266
  find "$HOME/.openclaw/extensions/" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
267
+ find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
267
268
 
268
269
  # ── 清空并重新构建 dist/ ──
269
270
  # openclaw plugins install . 只做文件复制,不执行 npm lifecycle scripts。
@@ -398,6 +399,7 @@ else
398
399
  echo ""
399
400
  echo " 尝试自动修复: 清理残留并重试安装..."
400
401
  find "$HOME/.openclaw/extensions/" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
402
+ find "${TMPDIR:-/tmp}" -maxdepth 1 -name ".openclaw-install-stage-*" -exec rm -rf {} + 2>/dev/null || true
401
403
  if openclaw plugins install . 2>&1 | tee -a "$INSTALL_LOG"; then
402
404
  for _candidate_name in openclaw-qqbot qqbot openclaw-qq; do
403
405
  if [ -d "$HOME/.openclaw/extensions/$_candidate_name" ]; then
@@ -893,7 +893,7 @@ function fireHotUpgrade(targetVersion?: string, pkg?: string, useLocal?: boolean
893
893
  }
894
894
 
895
895
  const shContent = `#!/bin/bash
896
- set -e
896
+ # 注意:不使用 set -e,因为 gateway start 失败时仍需恢复 channels.qqbot
897
897
  CLI="${cliInvoke}"
898
898
  CONFIG="${configPath}"
899
899
  BACKUP="${qqbotChannelBackup}"
@@ -903,13 +903,22 @@ $CLI gateway stop 2>/dev/null || true
903
903
  sleep 2
904
904
 
905
905
  if [ -f "$BACKUP" ]; then
906
- echo "[qqbot-upgrade] Temporarily removing channels.qqbot for config validation bypass..."
906
+ echo "[qqbot-upgrade] Temporarily removing channels.qqbot and plugins.entries for config validation bypass..."
907
907
  node -e "
908
908
  const fs = require('fs');
909
909
  const cfg = JSON.parse(fs.readFileSync(process.argv[1], 'utf8'));
910
+ let changed = false;
910
911
  if (cfg.channels && cfg.channels.qqbot) {
911
912
  delete cfg.channels.qqbot;
912
913
  if (Object.keys(cfg.channels).length === 0) delete cfg.channels;
914
+ changed = true;
915
+ }
916
+ if (cfg.plugins && cfg.plugins.entries && cfg.plugins.entries['openclaw-qqbot']) {
917
+ delete cfg.plugins.entries['openclaw-qqbot'];
918
+ if (Object.keys(cfg.plugins.entries).length === 0) delete cfg.plugins.entries;
919
+ changed = true;
920
+ }
921
+ if (changed) {
913
922
  fs.writeFileSync(process.argv[1], JSON.stringify(cfg, null, 4) + '\\n');
914
923
  }
915
924
  " "$CONFIG" 2>/dev/null
@@ -917,25 +926,44 @@ if [ -f "$BACKUP" ]; then
917
926
  fi
918
927
 
919
928
  echo "[qqbot-upgrade] Starting gateway..."
920
- $CLI gateway start
929
+ START_OK=false
930
+ if $CLI gateway start 2>/dev/null; then
931
+ START_OK=true
932
+ echo "[qqbot-upgrade] Gateway started successfully"
933
+ else
934
+ echo "[qqbot-upgrade] WARNING: gateway start failed, will still restore config"
935
+ fi
921
936
 
922
- echo "[qqbot-upgrade] Waiting for plugin to load (5s)..."
923
- sleep 5
937
+ echo "[qqbot-upgrade] Waiting for plugin to load (8s)..."
938
+ sleep 8
924
939
 
925
940
  if [ -f "$BACKUP" ]; then
926
- echo "[qqbot-upgrade] Restoring channels.qqbot..."
941
+ echo "[qqbot-upgrade] Restoring channels.qqbot and plugins.entries..."
927
942
  node -e "
928
943
  const fs = require('fs');
929
944
  const cfg = JSON.parse(fs.readFileSync(process.argv[1], 'utf8'));
930
945
  const qqbot = JSON.parse(fs.readFileSync(process.argv[2], 'utf8'));
931
946
  if (!cfg.channels) cfg.channels = {};
932
947
  cfg.channels.qqbot = qqbot;
948
+ // 恢复 plugins.entries
949
+ if (!cfg.plugins) cfg.plugins = {};
950
+ if (!cfg.plugins.entries) cfg.plugins.entries = {};
951
+ if (!cfg.plugins.entries['openclaw-qqbot']) {
952
+ cfg.plugins.entries['openclaw-qqbot'] = { enabled: true };
953
+ }
933
954
  fs.writeFileSync(process.argv[1], JSON.stringify(cfg, null, 4) + '\\n');
934
955
  " "$CONFIG" "$BACKUP" 2>/dev/null
935
956
  rm -f "$BACKUP"
936
957
  echo "[qqbot-upgrade] channels.qqbot restored"
937
958
  fi
938
959
 
960
+ # 如果 start 失败,尝试再次启动(此时 channels.qqbot 已恢复,插件可能已注册)
961
+ if [ "$START_OK" != "true" ]; then
962
+ echo "[qqbot-upgrade] Retrying gateway start..."
963
+ sleep 2
964
+ $CLI gateway start 2>/dev/null || echo "[qqbot-upgrade] WARNING: retry also failed"
965
+ fi
966
+
939
967
  # 清理自身
940
968
  rm -f "$0"
941
969
  echo "[qqbot-upgrade] Done."