#!/usr/bin/env node /** * QQBot CLI - 用于升级和管理 QQBot 插件 * * 用法: * npx @sliverp/qqbot upgrade # 升级插件 * npx @sliverp/qqbot install # 安装插件 */ import { execSync } from 'child_process'; import { existsSync, readFileSync, writeFileSync, rmSync } from 'fs'; import { homedir } from 'os'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // 获取包的根目录 const PKG_ROOT = join(__dirname, '..'); const args = process.argv.slice(2); const command = args[0]; // 检测使用的是 clawdbot 还是 openclaw function detectInstallation() { const home = homedir(); if (existsSync(join(home, '.openclaw'))) { return 'openclaw'; } if (existsSync(join(home, '.clawdbot'))) { return 'clawdbot'; } return null; } // 清理旧版本插件,返回旧的 qqbot 配置 function cleanupInstallation(appName) { const home = homedir(); const appDir = join(home, `.${appName}`); const configFile = join(appDir, `${appName}.json`); const extensionDir = join(appDir, 'extensions', 'qqbot'); let oldQqbotConfig = null; console.log(`\n>>> 处理 ${appName} 安装...`); // 1. 先读取旧的 qqbot 配置 if (existsSync(configFile)) { try { const config = JSON.parse(readFileSync(configFile, 'utf8')); if (config.channels?.qqbot) { oldQqbotConfig = { ...config.channels.qqbot }; console.log('已保存旧的 qqbot 配置'); } } catch (err) { console.error('读取配置文件失败:', err.message); } } // 2. 删除旧的扩展目录 if (existsSync(extensionDir)) { console.log(`删除旧版本插件: ${extensionDir}`); rmSync(extensionDir, { recursive: true, force: true }); } else { console.log('未找到旧版本插件目录,跳过删除'); } // 3. 清理配置文件中的 qqbot 相关字段 if (existsSync(configFile)) { console.log('清理配置文件中的 qqbot 字段...'); try { const config = JSON.parse(readFileSync(configFile, 'utf8')); // 删除 channels.qqbot if (config.channels?.qqbot) { delete config.channels.qqbot; console.log(' - 已删除 channels.qqbot'); } // 删除 plugins.entries.qqbot if (config.plugins?.entries?.qqbot) { delete config.plugins.entries.qqbot; console.log(' - 已删除 plugins.entries.qqbot'); } // 删除 plugins.installs.qqbot if (config.plugins?.installs?.qqbot) { delete config.plugins.installs.qqbot; console.log(' - 已删除 plugins.installs.qqbot'); } writeFileSync(configFile, JSON.stringify(config, null, 2)); console.log('配置文件已更新'); } catch (err) { console.error('清理配置文件失败:', err.message); } } else { console.log(`未找到配置文件: ${configFile}`); } return oldQqbotConfig; } // 执行命令并继承 stdio function runCommand(cmd, args = []) { try { execSync([cmd, ...args].join(' '), { stdio: 'inherit' }); return true; } catch (err) { return false; } } // 升级命令 function upgrade() { console.log('=== QQBot 插件升级脚本 ==='); let foundInstallation = null; let savedConfig = null; const home = homedir(); // 检查 openclaw if (existsSync(join(home, '.openclaw'))) { savedConfig = cleanupInstallation('openclaw'); foundInstallation = 'openclaw'; } // 检查 clawdbot if (existsSync(join(home, '.clawdbot'))) { const clawdbotConfig = cleanupInstallation('clawdbot'); if (!savedConfig) savedConfig = clawdbotConfig; foundInstallation = 'clawdbot'; } if (!foundInstallation) { console.log('\n未找到 clawdbot 或 openclaw 安装目录'); console.log('请确认已安装 clawdbot 或 openclaw'); process.exit(1); } console.log('\n=== 清理完成 ==='); // 自动安装插件 console.log('\n[1/2] 安装新版本插件...'); runCommand(foundInstallation, ['plugins', 'install', '@sliverp/qqbot']); // 自动配置通道(使用保存的 appId 和 clientSecret) console.log('\n[2/2] 配置机器人通道...'); if (savedConfig?.appId && savedConfig?.clientSecret) { const token = `${savedConfig.appId}:${savedConfig.clientSecret}`; console.log(`使用已保存的配置: appId=${savedConfig.appId}`); runCommand(foundInstallation, ['channels', 'add', '--channel', 'qqbot', '--token', `"${token}"`]); // 恢复其他配置项(如 markdownSupport) if (savedConfig.markdownSupport !== undefined) { runCommand(foundInstallation, ['config', 'set', 'channels.qqbot.markdownSupport', String(savedConfig.markdownSupport)]); } } else { console.log('未找到已保存的 qqbot 配置,请手动配置:'); console.log(` ${foundInstallation} channels add --channel qqbot --token "AppID:AppSecret"`); return; } console.log('\n=== 升级完成 ==='); console.log(`\n可以运行以下命令前台运行启动机器人:`); console.log(` ${foundInstallation} gateway stop && ${foundInstallation} gateway --port 18789 --verbose`); } // 安装命令 function install() { console.log('=== QQBot 插件安装 ==='); const cmd = detectInstallation(); if (!cmd) { console.log('未找到 clawdbot 或 openclaw 安装'); console.log('请先安装 openclaw 或 clawdbot'); process.exit(1); } console.log(`\n使用 ${cmd} 安装插件...`); runCommand(cmd, ['plugins', 'install', '@sliverp/qqbot']); console.log('\n=== 安装完成 ==='); console.log('\n请配置机器人通道:'); console.log(` ${cmd} channels add --channel qqbot --token "AppID:AppSecret"`); } // 显示帮助 function showHelp() { console.log(` QQBot CLI - QQ机器人插件管理工具 用法: npx @sliverp/qqbot <命令> 命令: upgrade 清理旧版本插件(升级前执行) install 安装插件到 openclaw/clawdbot 示例: npx @sliverp/qqbot upgrade npx @sliverp/qqbot install `); } // 主入口 switch (command) { case 'upgrade': upgrade(); break; case 'install': install(); break; case '-h': case '--help': case 'help': showHelp(); break; default: if (command) { console.log(`未知命令: ${command}`); } showHelp(); process.exit(command ? 1 : 0); }