mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-09 03:03:24 +08:00
95 lines
3.4 KiB
JavaScript
Executable file
95 lines
3.4 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
||
|
||
import { readFile } from 'node:fs/promises';
|
||
import { homedir, tmpdir } from 'node:os';
|
||
import { isAbsolute, join, resolve } from 'node:path';
|
||
import { spawnSync } from 'node:child_process';
|
||
|
||
const PACKAGE_NAME = '@xmanrui/dsh-im';
|
||
const DEFAULT_SOURCE = 'github:xmanrui/dsh-im';
|
||
const LEGACY_PACKAGES = ['@xmanrui/dsh-feishu', '@xmanrui/dsh-weixin'];
|
||
|
||
function usage() {
|
||
console.log(`Usage:
|
||
dsh-im install [--profile web] [--source <package-spec>]
|
||
dsh-im uninstall [--profile web]
|
||
|
||
Examples:
|
||
npx -y github:xmanrui/dsh-im install
|
||
dsh-im install --source .`);
|
||
}
|
||
|
||
function takeOption(args, name, fallback) {
|
||
const index = args.indexOf(name);
|
||
if (index < 0) return fallback;
|
||
const value = args[index + 1];
|
||
if (!value || value.startsWith('--')) throw new Error(`${name} requires a value`);
|
||
args.splice(index, 2);
|
||
return value;
|
||
}
|
||
|
||
function runDsh(args) {
|
||
const result = spawnSync('dsh', args, {
|
||
cwd: tmpdir(),
|
||
stdio: 'inherit',
|
||
shell: false,
|
||
});
|
||
if (result.error?.code === 'ENOENT') {
|
||
throw new Error('找不到 dsh,请先安装 DeepSeek Harness 并确保 dsh 在 PATH 中。');
|
||
}
|
||
if (result.error) throw result.error;
|
||
if (result.status !== 0) throw new Error(`dsh 退出,状态码 ${result.status ?? 1}`);
|
||
}
|
||
|
||
async function directProfilePackages(profile) {
|
||
const dshHome = process.env.DSH_HOME || join(homedir(), '.dsh');
|
||
const profilePackage = join(dshHome, 'profiles', profile, 'package.json');
|
||
try {
|
||
const manifest = JSON.parse(await readFile(profilePackage, 'utf8'));
|
||
const bundles = new Set(manifest.dsh?.profile?.bundles ?? []);
|
||
const dependencies = manifest.dependencies ?? {};
|
||
return new Set(LEGACY_PACKAGES.filter((name) => dependencies[name] || bundles.has(name)));
|
||
} catch (error) {
|
||
if (error?.code === 'ENOENT') return new Set();
|
||
throw new Error(`无法读取 Harness 配置 ${profilePackage}:${error.message}`);
|
||
}
|
||
}
|
||
|
||
const args = process.argv.slice(2);
|
||
const command = args.shift();
|
||
|
||
if (!command || command === '--help' || command === '-h') {
|
||
usage();
|
||
process.exit(0);
|
||
}
|
||
|
||
try {
|
||
const profile = takeOption(args, '--profile', 'web');
|
||
if (command === 'install') {
|
||
const requested = takeOption(args, '--source', DEFAULT_SOURCE);
|
||
const source = requested === '.' || requested === '..'
|
||
|| requested.startsWith('./') || requested.startsWith('../')
|
||
? resolve(process.cwd(), requested)
|
||
: (isAbsolute(requested) ? requested : requested);
|
||
if (args.length > 0) throw new Error(`无法识别的参数:${args.join(' ')}`);
|
||
|
||
const legacy = await directProfilePackages(profile);
|
||
runDsh(['plugin', '--profile', profile, 'add', '--save-exact', source]);
|
||
for (const packageName of legacy) {
|
||
runDsh(['plugin', '--profile', profile, 'remove', packageName]);
|
||
}
|
||
console.log('\nIM 机器人插件已安装。请重启 dsh web,然后打开「设置 → 插件 → IM机器人」。');
|
||
if (legacy.size > 0) {
|
||
console.log('已用 dsh-im 替换独立飞书/微信插件;原有凭据和扫码绑定保持不变。');
|
||
}
|
||
} else if (command === 'uninstall') {
|
||
if (args.length > 0) throw new Error(`无法识别的参数:${args.join(' ')}`);
|
||
runDsh(['plugin', '--profile', profile, 'remove', PACKAGE_NAME]);
|
||
console.log('\nIM 机器人插件已卸载。请重启 dsh web。');
|
||
} else {
|
||
throw new Error(`无法识别的命令:${command}`);
|
||
}
|
||
} catch (error) {
|
||
console.error(`dsh-im: ${error.message}`);
|
||
process.exit(1);
|
||
}
|