#!/usr/bin/env node /** * 准备 claude-code-acp-ts 源码并复制到 resources/ * * 逻辑: * 1. 若 sources/claude-code-acp-ts 不存在 → git clone + npm install + npm run build * 2. 若存在但无 node_modules → npm install + npm run build * 3. 否则跳过构建(认为已就绪) * 4. 复制到 resources/claude-code-acp-ts/ * * 产物: * resources/claude-code-acp-ts/ * ├── dist/ * ├── node_modules/ * └── package.json */ const path = require('path'); const fs = require('fs'); const { execSync } = require('child_process'); const { getProjectRoot } = require('../utils/project-paths'); const projectRoot = getProjectRoot(); const electronClientRoot = projectRoot; // 从 package.json 读取源码地址 const pkgJson = JSON.parse(fs.readFileSync(path.join(electronClientRoot, 'package.json'), 'utf8')); const { url: GIT_REPO, branch: GIT_BRANCH } = pkgJson.bundledSources['claude-code-acp-ts']; const SOURCE_DIR = path.join(electronClientRoot, 'sources', 'claude-code-acp-ts'); const destDir = path.join(electronClientRoot, 'resources', 'claude-code-acp-ts'); function exec(cmd, opts = {}) { console.log(` $ ${cmd}`); execSync(cmd, { stdio: 'inherit', ...opts }); } function getLocalSourceDir() { const candidates = [ process.env.CLAUDE_CODE_ACP_TS_SOURCE_DIR, path.resolve(electronClientRoot, '..', '..', '..', 'claude-code-acp-ts'), ].filter(Boolean); for (const candidate of candidates) { if (fs.existsSync(path.join(candidate, 'package.json'))) { return candidate; } } return null; } function main() { const localSourceDir = getLocalSourceDir(); let sourceDir = SOURCE_DIR; // 1. 克隆或更新源码 if (localSourceDir) { sourceDir = localSourceDir; console.log(`[prepare-claude-code-acp-ts] 使用本地源码: ${sourceDir}`); } else if (!fs.existsSync(path.join(SOURCE_DIR, '.git'))) { console.log('[prepare-claude-code-acp-ts] 克隆源码...'); exec(`git clone --branch ${GIT_BRANCH} ${GIT_REPO} "${SOURCE_DIR}"`); } else { console.log('[prepare-claude-code-acp-ts] 更新源码...'); exec(`cd "${SOURCE_DIR}" && git checkout ${GIT_BRANCH} && git pull`); } // 2. 检查构建产物是否存在 const hasBuild = fs.existsSync(path.join(sourceDir, 'dist')); const hasNodeModules = fs.existsSync(path.join(sourceDir, 'node_modules')); if (!hasBuild || !hasNodeModules) { // 清理旧的 node_modules(若有) const nodeModulesDir = path.join(sourceDir, 'node_modules'); if (fs.existsSync(nodeModulesDir)) { console.log('[prepare-claude-code-acp-ts] 清理旧的 node_modules...'); fs.rmSync(nodeModulesDir, { recursive: true, force: true }); } // 3. 安装依赖 console.log('[prepare-claude-code-acp-ts] 安装依赖...'); exec('npm install --ignore-scripts', { cwd: sourceDir }); // 4. 构建 // 注意:不用 npm run build,因为其 build 脚本可能是 ./node_modules/.bin/tsc(Unix 风格),Windows 不认识 //改用 npx tsc 替代,可跨平台 console.log('[prepare-claude-code-acp-ts] 构建项目...'); exec('npx tsc', { cwd: sourceDir }); } else { console.log('[prepare-claude-code-acp-ts] 构建产物已就绪,跳过构建'); } // 5. 读取版本 const srcPkg = JSON.parse(fs.readFileSync(path.join(sourceDir, 'package.json'), 'utf8')); console.log(`[prepare-claude-code-acp-ts] 源码版本: ${srcPkg.name}@${srcPkg.version}`); // 6. 清理并创建目标目录 if (fs.existsSync(destDir)) { fs.rmSync(destDir, { recursive: true }); } fs.mkdirSync(destDir, { recursive: true }); // 7. 复制 dist/ console.log('[prepare-claude-code-acp-ts] 复制 dist/...'); fs.cpSync(path.join(sourceDir, 'dist'), path.join(destDir, 'dist'), { recursive: true }); // 8. 复制 package.json fs.copyFileSync( path.join(sourceDir, 'package.json'), path.join(destDir, 'package.json') ); // 9. 复制 node_modules/ console.log('[prepare-claude-code-acp-ts] 复制 node_modules/...'); fs.cpSync(path.join(sourceDir, 'node_modules'), path.join(destDir, 'node_modules'), { recursive: true }); // 10. 复制 LICENSE const licenseSrc = path.join(sourceDir, 'LICENSE'); if (fs.existsSync(licenseSrc)) { fs.copyFileSync(licenseSrc, path.join(destDir, 'LICENSE')); } console.log(`[prepare-claude-code-acp-ts] ✓ resources/claude-code-acp-ts/ (${srcPkg.version})`); } main();