@ryantest/openclaw-qqbot 1.6.7-beta.4 → 1.6.7-beta.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.
@@ -0,0 +1,252 @@
1
+ import { registerCommand, getPluginVersion } from "../slash-commands.js";
2
+ import { getUpdateInfo, checkVersionExists } from "../update-checker.js";
3
+ import { checkUpgradeCompatibility, fireHotUpgrade, isUpgrading, setUpgrading, preUpgradeCredentialBackup, saveUpgradeGreetingTarget, } from "../upgrade-utils.js";
4
+ const DEFAULT_UPGRADE_URL = "https://docs.qq.com/doc/DSGxOZk1oVnVKVkpq";
5
+ registerCommand({
6
+ name: "bot-upgrade",
7
+ description: "检查更新并查看升级指引",
8
+ usage: [
9
+ `/bot-upgrade 检查是否有新版本`,
10
+ `/bot-upgrade --latest 确认升级到最新版本(需 upgradeMode=hot-reload)`,
11
+ `/bot-upgrade --version X 升级到指定版本(需 upgradeMode=hot-reload)`,
12
+ `/bot-upgrade --pkg scope/name 指定 npm 包(如 ryantest/openclaw-qqbot)`,
13
+ `/bot-upgrade --force 强制重新安装当前版本(需 upgradeMode=hot-reload)`,
14
+ `/bot-upgrade --local 使用本地升级脚本(跳过远端下载)`,
15
+ ].join("\n"),
16
+ handler: async (ctx) => {
17
+ const PLUGIN_VERSION = getPluginVersion();
18
+ const url = ctx.accountConfig?.upgradeUrl || DEFAULT_UPGRADE_URL;
19
+ const upgradeMode = ctx.accountConfig?.upgradeMode || "hot-reload";
20
+ const args = ctx.args.trim();
21
+ const info = await getUpdateInfo();
22
+ const GITHUB_URL = "https://github.com/tencent-connect/openclaw-qqbot/";
23
+ // ── doc 模式(默认):只展示升级指引,不执行热更新 ──
24
+ if (upgradeMode !== "hot-reload") {
25
+ if (info.checkedAt === 0) {
26
+ return `⏳ 版本检查中,请稍后再试`;
27
+ }
28
+ if (info.error) {
29
+ return [
30
+ `❌ 主机网络访问异常,无法检查更新`,
31
+ ``,
32
+ `查看升级指引:[点击查看](${url})`,
33
+ ].join("\n");
34
+ }
35
+ if (!info.hasUpdate) {
36
+ return [
37
+ `✅ 当前已是最新版本 v${PLUGIN_VERSION}`,
38
+ ``,
39
+ `项目地址:[GitHub](${GITHUB_URL})`,
40
+ ].join("\n");
41
+ }
42
+ return [
43
+ `🆕 发现新版本`,
44
+ ``,
45
+ `当前版本:**v${PLUGIN_VERSION}**`,
46
+ `最新版本:**v${info.latest}**`,
47
+ ``,
48
+ `📖 升级指引:[点击查看](${url})`,
49
+ `🌟 官方 GitHub 仓库:[点击前往](${GITHUB_URL})`,
50
+ ].join("\n");
51
+ }
52
+ // ── hot-reload 模式:执行热更新 ──
53
+ if (ctx.type !== "c2c") {
54
+ return `💡 请在私聊中使用此指令`;
55
+ }
56
+ if (isUpgrading()) {
57
+ return `⏳ 正在升级中,请稍候...`;
58
+ }
59
+ let isForce = false;
60
+ let isLatest = false;
61
+ let isLocal = false;
62
+ let versionArg;
63
+ let pkgArg;
64
+ const tokens = args ? args.split(/\s+/).filter(Boolean) : [];
65
+ for (let i = 0; i < tokens.length; i += 1) {
66
+ const t = tokens[i];
67
+ if (t === "--force") {
68
+ isForce = true;
69
+ continue;
70
+ }
71
+ if (t === "--latest") {
72
+ isLatest = true;
73
+ continue;
74
+ }
75
+ if (t === "--local") {
76
+ isLocal = true;
77
+ continue;
78
+ }
79
+ if (t === "--pkg") {
80
+ const next = tokens[i + 1];
81
+ if (!next || next.startsWith("--")) {
82
+ return `❌ 参数错误:--pkg 需要包名\n\n示例:/bot-upgrade --pkg ryantest/openclaw-qqbot`;
83
+ }
84
+ pkgArg = next;
85
+ i += 1;
86
+ continue;
87
+ }
88
+ if (t.startsWith("--pkg=")) {
89
+ const v = t.slice("--pkg=".length).trim();
90
+ if (!v) {
91
+ return `❌ 参数错误:--pkg 需要包名\n\n示例:/bot-upgrade --pkg ryantest/openclaw-qqbot`;
92
+ }
93
+ pkgArg = v;
94
+ continue;
95
+ }
96
+ if (t === "--version") {
97
+ const next = tokens[i + 1];
98
+ if (!next || next.startsWith("--")) {
99
+ return `❌ 参数错误:--version 需要版本号\n\n示例:/bot-upgrade --version 1.6.5`;
100
+ }
101
+ versionArg = next.replace(/^v/, "");
102
+ i += 1;
103
+ continue;
104
+ }
105
+ if (t.startsWith("--version=")) {
106
+ const v = t.slice("--version=".length).trim();
107
+ if (!v) {
108
+ return `❌ 参数错误:--version 需要版本号\n\n示例:/bot-upgrade --version 1.6.5`;
109
+ }
110
+ versionArg = v.replace(/^v/, "");
111
+ continue;
112
+ }
113
+ if (!t.startsWith("--") && !versionArg) {
114
+ versionArg = t.replace(/^v/, "");
115
+ continue;
116
+ }
117
+ }
118
+ // ── 无参数:只展示信息+确认按钮 ──
119
+ if (!versionArg && !isLatest && !isForce) {
120
+ if (info.checkedAt === 0) {
121
+ return `⏳ 版本检查中,请稍后再试`;
122
+ }
123
+ if (info.error) {
124
+ return [
125
+ `❌ 主机网络访问异常,无法检查更新`,
126
+ ``,
127
+ `查看手动升级指引:[点击查看](${url})`,
128
+ ].join("\n");
129
+ }
130
+ if (!info.hasUpdate) {
131
+ const lines = [
132
+ `✅ 当前已是最新版本 v${PLUGIN_VERSION}`,
133
+ ``,
134
+ `项目地址:[GitHub](${GITHUB_URL})`,
135
+ ];
136
+ return lines.join("\n");
137
+ }
138
+ return [
139
+ `🆕 发现新版本`,
140
+ ``,
141
+ `当前版本:**v${PLUGIN_VERSION}**`,
142
+ `最新版本:**v${info.latest}**`,
143
+ ``,
144
+ `升级将重启 Gateway 服务,期间短暂不可用。`,
145
+ `请确认主机网络可正常访问 npm 仓库。`,
146
+ ``,
147
+ `**点击确认升级** <qqbot-cmd-enter text="/bot-upgrade --latest" />`,
148
+ ``,
149
+ `手动升级指引:[点击查看](${url})`,
150
+ `🌟官方 GitHub 仓库:[点击前往](${GITHUB_URL})`,
151
+ ].join("\n");
152
+ }
153
+ let upgradePkg = pkgArg || ctx.accountConfig?.upgradePkg;
154
+ if (upgradePkg) {
155
+ upgradePkg = upgradePkg.trim();
156
+ if (!upgradePkg.startsWith("@"))
157
+ upgradePkg = `@${upgradePkg}`;
158
+ }
159
+ // ── --version 指定版本:先校验版本号是否存在 ──
160
+ if (versionArg) {
161
+ const exists = await checkVersionExists(versionArg, upgradePkg);
162
+ if (!exists) {
163
+ return `❌ 版本 ${versionArg} 不存在,请检查版本号`;
164
+ }
165
+ if (versionArg === PLUGIN_VERSION && !isForce) {
166
+ return `✅ 当前已是 v${PLUGIN_VERSION},无需升级`;
167
+ }
168
+ }
169
+ // ── --latest:检查是否需要升级 ──
170
+ if (isLatest && !versionArg) {
171
+ if (info.checkedAt === 0) {
172
+ return `⏳ 版本检查中,请稍后再试`;
173
+ }
174
+ if (info.error) {
175
+ return [
176
+ `❌ 主机网络访问异常,无法检查更新`,
177
+ ``,
178
+ `查看手动升级指引:[点击查看](${url})`,
179
+ ].join("\n");
180
+ }
181
+ if (!info.hasUpdate && !isForce) {
182
+ return `✅ 当前已是 v${PLUGIN_VERSION},无需升级`;
183
+ }
184
+ }
185
+ const targetVersion = versionArg || info.latest || undefined;
186
+ const isReinstall = isForce && targetVersion === PLUGIN_VERSION;
187
+ // ── 环境兼容性检查 ──
188
+ const compat = checkUpgradeCompatibility();
189
+ if (!compat.ok) {
190
+ return [
191
+ `🚫 当前环境不满足热更新要求:`,
192
+ ``,
193
+ ...compat.errors,
194
+ ...(compat.warnings.length ? [``, ...compat.warnings] : []),
195
+ ``,
196
+ `查看手动升级指引:[点击查看](${url})`,
197
+ ].join("\n");
198
+ }
199
+ setUpgrading(true);
200
+ preUpgradeCredentialBackup(ctx.accountId, ctx.appId);
201
+ const startResult = fireHotUpgrade(targetVersion, upgradePkg, isLocal);
202
+ if (!startResult.ok) {
203
+ setUpgrading(false);
204
+ if (startResult.reason === "no-script") {
205
+ return [
206
+ `❌ 未找到升级脚本,无法执行热更新`,
207
+ ``,
208
+ `可能原因:升级后脚本目录被清理,或远端下载失败(查看日志了解详情)`,
209
+ `💡 可尝试不带 \`--local\` 重试,或手动升级`,
210
+ ``,
211
+ `查看手动升级指引:[点击查看](${url})`,
212
+ ].join("\n");
213
+ }
214
+ if (startResult.reason === "no-cli") {
215
+ return [
216
+ `❌ 未找到 CLI 工具,无法执行热更新`,
217
+ ``,
218
+ `查看手动升级指引:[点击查看](${url})`,
219
+ ].join("\n");
220
+ }
221
+ if (startResult.reason === "no-powershell") {
222
+ return [
223
+ `❌ 未找到 PowerShell,无法执行热更新`,
224
+ ``,
225
+ `请确认系统中已安装 PowerShell(Windows 10+ 自带)`,
226
+ `查看手动升级指引:[点击查看](${url})`,
227
+ ].join("\n");
228
+ }
229
+ return [
230
+ `❌ 当前环境不支持热更新(需要 bash)`,
231
+ ``,
232
+ `查看手动升级指引:[点击查看](${url})`,
233
+ ].join("\n");
234
+ }
235
+ saveUpgradeGreetingTarget(ctx.accountId, ctx.appId, ctx.senderId);
236
+ const resultLines = isReinstall
237
+ ? [
238
+ `🔄 正在重新安装 v${PLUGIN_VERSION}...`,
239
+ ``,
240
+ `预计 30~60 秒完成,届时会自动通知您`,
241
+ ]
242
+ : [
243
+ `🔄 正在升级...`,
244
+ ``,
245
+ `当前版本:v${PLUGIN_VERSION}`,
246
+ ...(targetVersion ? [`目标版本:v${targetVersion}`] : []),
247
+ ``,
248
+ `预计 30~60 秒完成,届时会自动通知您`,
249
+ ];
250
+ return resultLines.join("\n");
251
+ },
252
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import { getUpdateInfo } from "../update-checker.js";
2
+ import { getFrameworkVersion } from "../upgrade-utils.js";
3
+ import { registerCommand, getPluginVersion } from "../slash-commands.js";
4
+ registerCommand({
5
+ name: "bot-version",
6
+ description: "查看插件版本号",
7
+ usage: [
8
+ `/bot-version`,
9
+ ``,
10
+ `查看当前 QQBot 插件版本和 OpenClaw 框架版本。`,
11
+ `同时检查是否有新版本可用。`,
12
+ ].join("\n"),
13
+ handler: async () => {
14
+ const PLUGIN_VERSION = getPluginVersion();
15
+ const frameworkVersion = getFrameworkVersion();
16
+ const lines = [
17
+ `🦞框架版本:${frameworkVersion}`,
18
+ `🤖QQBot 插件版本:v${PLUGIN_VERSION}`,
19
+ ];
20
+ const info = await getUpdateInfo();
21
+ if (info.checkedAt === 0) {
22
+ lines.push(`⏳ 版本检查中...`);
23
+ }
24
+ else if (info.error) {
25
+ lines.push(`⚠️ 版本检查失败`);
26
+ }
27
+ else if (info.hasUpdate && info.latest) {
28
+ lines.push(`🆕最新可用版本:v${info.latest},点击 <qqbot-cmd-input text="/bot-upgrade" show="/bot-upgrade"/> 查看升级指引`);
29
+ }
30
+ lines.push(`🌟官方 GitHub 仓库:[点击前往](https://github.com/tencent-connect/openclaw-qqbot/)`);
31
+ return lines.join("\n");
32
+ },
33
+ });
@@ -11,12 +11,7 @@
11
11
  * 从而计算「开平→插件」和「插件处理」两段耗时
12
12
  */
13
13
  import type { QQBotAccountConfig } from "./types.js";
14
- export declare function getFrameworkVersion(): string;
15
- /**
16
- * 解析框架版本字符串中的日期版本号
17
- * 输入示例: "OpenClaw 2026.3.13 (61d171a)" → "2026.3.13"
18
- */
19
- export declare function parseFrameworkDateVersion(versionStr: string): string | null;
14
+ export { getFrameworkVersion, parseFrameworkDateVersion } from "./upgrade-utils.js";
20
15
  /** 斜杠指令上下文(消息元数据 + 运行时状态) */
21
16
  export interface SlashCommandContext {
22
17
  /** 消息类型 */
@@ -67,6 +62,26 @@ export interface SlashCommandFileResult {
67
62
  /** 要发送的本地文件路径 */
68
63
  filePath: string;
69
64
  }
65
+ /** 斜杠指令定义 */
66
+ export interface SlashCommand {
67
+ /** 指令名(不含 /) */
68
+ name: string;
69
+ /** 简要描述 */
70
+ description: string;
71
+ /** 详细用法说明(支持多行),用于 /指令 ? 查询 */
72
+ usage?: string;
73
+ /** 处理函数 */
74
+ handler: (ctx: SlashCommandContext) => SlashCommandResult | Promise<SlashCommandResult>;
75
+ }
76
+ export declare function registerCommand(cmd: SlashCommand): void;
77
+ /** 获取指令注册表(只读访问,供 bot-help 等使用) */
78
+ export declare function getCommands(): ReadonlyMap<string, SlashCommand>;
79
+ import "./commands/bot-ping.js";
80
+ import "./commands/bot-version.js";
81
+ import "./commands/bot-help.js";
82
+ import "./commands/bot-upgrade.js";
83
+ import "./commands/bot-logs.js";
84
+ import "./commands/bot-clear-storage.js";
70
85
  /**
71
86
  * 尝试匹配并执行插件级斜杠指令
72
87
  *