fire-code-cli
Version:
AI-powered coding assistant for the terminal. A ChatGPT-like CLI tool built with React Ink and Fireworks AI.
157 lines (131 loc) • 3.91 kB
JavaScript
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const os = require('os');
const { execSync } = require('child_process');
function getPlatform() {
const platform = os.platform();
const arch = os.arch();
// Map Node.js platform/arch to our package names
const platformMap = {
darwin: {
arm64: 'darwin-arm64',
x64: 'darwin-x64',
},
linux: {
x64: 'linux-x64',
arm64: 'linux-arm64',
},
win32: {
x64: 'windows-x64',
},
};
if (!platformMap[platform]?.[arch]) {
throw new Error(`Unsupported platform: ${platform}-${arch}`);
}
return platformMap[platform][arch];
}
function getBinaryName(platform) {
return platform.includes('windows') ? 'firecode.exe' : 'firecode';
}
function createBinDirectory() {
const binDir = path.join(__dirname, '..', 'bin');
if (!fs.existsSync(binDir)) {
fs.mkdirSync(binDir, { recursive: true });
}
return binDir;
}
function findPlatformBinary() {
const platform = getPlatform();
const binaryName = getBinaryName(platform);
// Try to find the binary in platform-specific package
const platformPackagePath = path.join(
__dirname,
'..',
'node_modules',
`fire-code-${platform}`,
'bin',
binaryName,
);
if (fs.existsSync(platformPackagePath)) {
return platformPackagePath;
}
// Try to find in parent project's dist folder (development/build scenario)
const distBinaryPath = path.join(
__dirname,
'..',
'dist',
`firecode-${platform}${platform.includes('windows') ? '.exe' : ''}`,
);
if (fs.existsSync(distBinaryPath)) {
return distBinaryPath;
}
return null;
}
function createBinaryWrapper(binaryPath) {
const binDir = createBinDirectory();
const platform = getPlatform();
const binaryName = getBinaryName(platform);
const wrapperPath = path.join(binDir, binaryName);
if (platform.includes('windows')) {
// For Windows, copy the binary directly
fs.copyFileSync(binaryPath, wrapperPath);
} else {
// For Unix systems, create a symlink or copy
try {
if (fs.existsSync(wrapperPath)) {
fs.unlinkSync(wrapperPath);
}
fs.symlinkSync(path.resolve(binaryPath), wrapperPath);
} catch (error) {
// Fallback to copying if symlink fails
fs.copyFileSync(binaryPath, wrapperPath);
fs.chmodSync(wrapperPath, 0o755);
}
}
// Create wrapper scripts for both 'fire' and 'firecode' commands
const wrapperNames = ['fire.cjs', 'firecode.cjs'];
wrapperNames.forEach((name) => {
const wrapperPath = path.join(binDir, name);
const wrapperContent = `#!/usr/bin/env node
const { getBinaryPath } = require('../lib/get-binary-path.cjs');
const { execSync } = require('child_process');
try {
const binaryPath = getBinaryPath();
execSync(\`"\${binaryPath}" \${process.argv.slice(2).join(' ')}\`, { stdio: 'inherit' });
} catch (error) {
if (error.status) {
process.exit(error.status);
} else {
console.error(error.message);
process.exit(1);
}
}
`;
fs.writeFileSync(wrapperPath, wrapperContent);
if (!platform.includes('windows')) {
fs.chmodSync(wrapperPath, 0o755);
}
});
}
function main() {
try {
console.log('Installing fire-code binary...');
const binaryPath = findPlatformBinary();
if (!binaryPath) {
console.warn('No platform-specific binary found. Skipping binary installation.');
console.warn('Binary will be downloaded on first use.');
return;
}
createBinaryWrapper(binaryPath);
console.log('Binary installed successfully!');
} catch (error) {
console.error('Failed to install binary:', error.message);
console.warn('Binary will be downloaded on first use.');
}
}
// Only run if called directly
if (require.main === module) {
main();
}
module.exports = { getPlatform, findPlatformBinary, createBinaryWrapper };