mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-19 23:42:03 +08:00
134 lines
3.8 KiB
JavaScript
134 lines
3.8 KiB
JavaScript
#!/usr/bin/env node
|
|
import { spawn } from 'node:child_process';
|
|
import fs from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const rootDir = path.resolve(__dirname, '..');
|
|
const platform = process.env.CLOUDCLI_SEMANTICS_PLATFORM || process.platform;
|
|
const arch = process.env.CLOUDCLI_SEMANTICS_ARCH || process.arch;
|
|
const platformArch = `${platform}-${arch}`;
|
|
const semanticsRoot = path.join(rootDir, 'server', 'modules', 'computer-use', 'semantics');
|
|
const outDir = path.join(semanticsRoot, 'bin', platformArch);
|
|
const requireBuild = process.env.CLOUDCLI_SEMANTICS_BUILD_REQUIRED === '1';
|
|
|
|
function run(command, args, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const child = spawn(command, args, {
|
|
stdio: 'inherit',
|
|
shell: process.platform === 'win32',
|
|
...options,
|
|
});
|
|
child.once('error', reject);
|
|
child.once('exit', (code) => {
|
|
if (code === 0) resolve();
|
|
else reject(new Error(`${command} ${args.join(' ')} exited with code ${code}`));
|
|
});
|
|
});
|
|
}
|
|
|
|
function commandExists(command) {
|
|
return new Promise((resolve) => {
|
|
const child = spawn(command, ['--version'], {
|
|
stdio: 'ignore',
|
|
shell: process.platform === 'win32',
|
|
});
|
|
child.once('error', () => resolve(false));
|
|
child.once('exit', (code) => resolve(code === 0));
|
|
});
|
|
}
|
|
|
|
async function pathExists(filePath) {
|
|
try {
|
|
await fs.access(filePath);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function isUpToDate(output, inputs) {
|
|
if (!(await pathExists(output))) {
|
|
return false;
|
|
}
|
|
|
|
const outputStat = await fs.stat(output);
|
|
for (const input of inputs) {
|
|
const inputStat = await fs.stat(input);
|
|
if (inputStat.mtimeMs > outputStat.mtimeMs) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
async function ensureCommand(command, helpText) {
|
|
if (await commandExists(command)) {
|
|
return true;
|
|
}
|
|
|
|
const message = `${command} was not found. ${helpText}`;
|
|
if (requireBuild) {
|
|
throw new Error(message);
|
|
}
|
|
console.log(`Skipping semantic helper build: ${message}`);
|
|
return false;
|
|
}
|
|
|
|
if (platform === 'darwin') {
|
|
const source = path.join(semanticsRoot, 'helpers', 'macos', 'CloudCLISemantics.swift');
|
|
const output = path.join(outDir, 'CloudCLISemantics');
|
|
|
|
if (!(await ensureCommand('swiftc', 'Install Xcode Command Line Tools to compile the macOS helper.'))) {
|
|
process.exit(0);
|
|
}
|
|
if (await isUpToDate(output, [source])) {
|
|
console.log(`Semantic helper is up to date: ${path.relative(rootDir, output)}`);
|
|
process.exit(0);
|
|
}
|
|
|
|
await fs.mkdir(outDir, { recursive: true });
|
|
await run('swiftc', [
|
|
source,
|
|
'-o',
|
|
output,
|
|
'-framework',
|
|
'AppKit',
|
|
'-framework',
|
|
'ApplicationServices',
|
|
]);
|
|
await fs.chmod(output, 0o755);
|
|
console.log(`Built ${path.relative(rootDir, output)}`);
|
|
} else if (platform === 'win32') {
|
|
const project = path.join(semanticsRoot, 'helpers', 'windows', 'CloudCLISemantics.csproj');
|
|
const source = path.join(semanticsRoot, 'helpers', 'windows', 'Program.cs');
|
|
const output = path.join(outDir, 'CloudCLISemantics.exe');
|
|
|
|
if (!(await ensureCommand('dotnet', '.NET SDK is required to compile the Windows helper.'))) {
|
|
process.exit(0);
|
|
}
|
|
if (await isUpToDate(output, [project, source])) {
|
|
console.log(`Semantic helper is up to date: ${path.relative(rootDir, output)}`);
|
|
process.exit(0);
|
|
}
|
|
|
|
await fs.mkdir(outDir, { recursive: true });
|
|
await run('dotnet', [
|
|
'publish',
|
|
project,
|
|
'-c',
|
|
'Release',
|
|
'-r',
|
|
arch === 'arm64' ? 'win-arm64' : 'win-x64',
|
|
'--self-contained',
|
|
'false',
|
|
'-p:PublishSingleFile=true',
|
|
'-o',
|
|
outDir,
|
|
]);
|
|
console.log(`Built ${path.relative(rootDir, output)}`);
|
|
} else {
|
|
console.log(`Semantic helper build is not supported for ${platform}-${arch}.`);
|
|
}
|