140 lines
5.2 KiB
JavaScript
140 lines
5.2 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* 从 node_modules 复制 qiming-mcp-stdio-proxy 到 resources/
|
||
*
|
||
* 前提:
|
||
* 1. pnpm install 已执行(workspace 链接生效)
|
||
* 2. qiming-mcp-stdio-proxy 已构建(npm run build)
|
||
*
|
||
* 产物(3 个文件):
|
||
* resources/qiming-mcp-stdio-proxy/
|
||
* ├── dist/index.js — CLI bundle(esbuild 单文件,含 shebang)
|
||
* ├── dist/lib.bundle.js — 库 bundle(PersistentMcpBridge 等导出)
|
||
* └── package.json — 精简版(name/version/bin/main)
|
||
*
|
||
* 打包时 electron-builder extraResources 会打包到
|
||
* .app/Contents/Resources/qiming-mcp-stdio-proxy/
|
||
*/
|
||
|
||
const path = require('path');
|
||
const fs = require('fs');
|
||
const { getProjectRoot } = require('../utils/project-paths');
|
||
|
||
const projectRoot = getProjectRoot();
|
||
const srcDir = path.join(projectRoot, 'node_modules', 'qiming-mcp-stdio-proxy');
|
||
const destDir = path.join(projectRoot, 'resources', 'qiming-mcp-stdio-proxy');
|
||
|
||
function main() {
|
||
// 1. 验证 node_modules 中存在 qiming-mcp-stdio-proxy
|
||
if (!fs.existsSync(path.join(srcDir, 'package.json'))) {
|
||
console.error(`[prepare-mcp-proxy] node_modules 中未找到 qiming-mcp-stdio-proxy`);
|
||
console.error('[prepare-mcp-proxy] 请先执行 pnpm install');
|
||
process.exit(1);
|
||
}
|
||
|
||
const srcPkg = JSON.parse(fs.readFileSync(path.join(srcDir, 'package.json'), 'utf8'));
|
||
console.log(`[prepare-mcp-proxy] 源码版本: ${srcPkg.name}@${srcPkg.version}`);
|
||
|
||
// 2. 验证必要文件存在
|
||
const srcIndexJs = path.join(srcDir, 'dist', 'index.js');
|
||
const srcLibJs = path.join(srcDir, 'dist', 'lib.js');
|
||
|
||
if (!fs.existsSync(srcIndexJs)) {
|
||
console.error(`[prepare-mcp-proxy] CLI 入口不存在: ${srcIndexJs}`);
|
||
console.error('[prepare-mcp-proxy] 请先在 crates/qiming-mcp-stdio-proxy 中执行 npm run build');
|
||
process.exit(1);
|
||
}
|
||
|
||
if (!fs.existsSync(srcLibJs)) {
|
||
console.error(`[prepare-mcp-proxy] 库入口不存在: ${srcLibJs}`);
|
||
console.error('[prepare-mcp-proxy] 请先在 crates/qiming-mcp-stdio-proxy 中执行 npm run build');
|
||
process.exit(1);
|
||
}
|
||
|
||
// 3. 检查目标是否已是最新版本
|
||
const destPkgPath = path.join(destDir, 'package.json');
|
||
if (fs.existsSync(destPkgPath)) {
|
||
try {
|
||
const destPkg = JSON.parse(fs.readFileSync(destPkgPath, 'utf8'));
|
||
if (destPkg.version === srcPkg.version) {
|
||
const destIndexJs = path.join(destDir, 'dist', 'index.js');
|
||
const destLibJs = path.join(destDir, 'dist', 'lib.bundle.js');
|
||
if (fs.existsSync(destIndexJs) && fs.existsSync(destLibJs)) {
|
||
console.log(`[prepare-mcp-proxy] ${srcPkg.version} 已是最新,跳过`);
|
||
return;
|
||
}
|
||
}
|
||
} catch {
|
||
// 目标损坏,重新复制
|
||
}
|
||
}
|
||
|
||
// 4. 构建 lib bundle(使用 esbuild)
|
||
console.log('[prepare-mcp-proxy] 构建 lib bundle (esbuild)...');
|
||
const esbuildBin = path.join(srcDir, 'node_modules', '.bin', 'esbuild');
|
||
|
||
// 如果 proxy 包中没有 esbuild,使用项目根目录的 esbuild
|
||
const esbuildToUse = fs.existsSync(esbuildBin)
|
||
? esbuildBin
|
||
: path.join(projectRoot, 'node_modules', '.bin', 'esbuild');
|
||
|
||
// Windows 兼容
|
||
const esbuildCmd = process.platform === 'win32' && !esbuildToUse.endsWith('.cmd')
|
||
? esbuildToUse + '.cmd'
|
||
: esbuildToUse;
|
||
|
||
const libEntry = srcLibJs;
|
||
const libBundlePath = path.join(srcDir, 'dist', 'lib.bundle.js');
|
||
|
||
const { execSync } = require('child_process');
|
||
try {
|
||
execSync(
|
||
`"${esbuildCmd}" "${libEntry}" --bundle --platform=node --target=node22 --format=cjs --outfile="${libBundlePath}" --legal-comments=none`,
|
||
{ cwd: srcDir, stdio: 'inherit' },
|
||
);
|
||
} catch (e) {
|
||
console.error('[prepare-mcp-proxy] esbuild 打包失败,尝试直接复制 lib.js');
|
||
// 如果 esbuild 失败,直接使用 lib.js 作为 lib.bundle.js
|
||
if (fs.existsSync(libEntry)) {
|
||
fs.copyFileSync(libEntry, libBundlePath);
|
||
} else {
|
||
console.error('[prepare-mcp-proxy] lib.js 也不存在,无法继续');
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// 5. 复制到 resources/qiming-mcp-stdio-proxy/
|
||
console.log('[prepare-mcp-proxy] 复制到 resources/qiming-mcp-stdio-proxy/...');
|
||
|
||
// 清理目标目录
|
||
if (fs.existsSync(destDir)) {
|
||
fs.rmSync(destDir, { recursive: true });
|
||
}
|
||
fs.mkdirSync(path.join(destDir, 'dist'), { recursive: true });
|
||
|
||
// 复制 dist/index.js (CLI bundle)
|
||
const destIndexJs = path.join(destDir, 'dist', 'index.js');
|
||
fs.copyFileSync(srcIndexJs, destIndexJs);
|
||
fs.chmodSync(destIndexJs, 0o755);
|
||
console.log(` dist/index.js (${(fs.statSync(destIndexJs).size / 1024).toFixed(0)} KB)`);
|
||
|
||
// 复制 dist/lib.bundle.js (library bundle)
|
||
const destLibJs = path.join(destDir, 'dist', 'lib.bundle.js');
|
||
fs.copyFileSync(libBundlePath, destLibJs);
|
||
console.log(` dist/lib.bundle.js (${(fs.statSync(destLibJs).size / 1024).toFixed(0)} KB)`);
|
||
|
||
// 6. 生成精简版 package.json
|
||
const slimPkg = {
|
||
name: srcPkg.name,
|
||
version: srcPkg.version,
|
||
bin: { 'qiming-mcp-stdio-proxy': './dist/index.js' },
|
||
main: './dist/lib.bundle.js',
|
||
};
|
||
fs.writeFileSync(destPkgPath, JSON.stringify(slimPkg, null, 2) + '\n');
|
||
console.log(' package.json (slim)');
|
||
|
||
console.log(`[prepare-mcp-proxy] ✓ resources/qiming-mcp-stdio-proxy/ (${srcPkg.version})`);
|
||
}
|
||
|
||
main();
|