228 lines
6.3 KiB
JavaScript
228 lines
6.3 KiB
JavaScript
#!/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);
|
||
}
|