aide-cli
Version:
AIDE - The companion control system for Claude Code with intelligent task management
192 lines (166 loc) • 6.22 kB
JavaScript
/**
* AIDE Post-Install Script
* Sets up necessary files and configurations after npm install
*/
const fs = require('fs');
const path = require('path');
const os = require('os');
const { execSync } = require('child_process');
class AIDEPostInstaller {
constructor() {
this.claudeDir = path.join(os.homedir(), '.claude');
this.scriptsDir = path.join(__dirname);
this.binDir = path.join(__dirname, '..', 'bin');
}
log(message, type = 'info') {
const icons = {
info: '💡',
success: '✅',
error: '❌',
warning: '⚠️'
};
console.log(`${icons[type]} ${message}`);
}
ensureClaudeDir() {
if (!fs.existsSync(this.claudeDir)) {
fs.mkdirSync(this.claudeDir, { recursive: true });
this.log(`Created Claude directory: ${this.claudeDir}`, 'success');
}
}
cleanOldFiles() {
this.log('Cleaning old AIDE files...');
// List of files to clean
const filesToClean = [
'aide-wrapper.sh',
'aide-wrapper.bat',
'aide_init.py',
'aide_status.py',
'aide_track.py',
'aide_adapt.py',
'aide_i18n.py',
'.aide-daemon/daemon.pid',
'.aide-daemon/daemon.log'
];
let cleaned = 0;
filesToClean.forEach(file => {
const filePath = path.join(this.claudeDir, file);
if (fs.existsSync(filePath)) {
try {
fs.unlinkSync(filePath);
cleaned++;
} catch (e) {
// Ignore errors
}
}
});
if (cleaned > 0) {
this.log(`Cleaned ${cleaned} old files`, 'success');
}
}
copyPythonScripts() {
const pythonScripts = [
'aide_init.py',
'aide_status.py',
'aide_track.py',
'aide_adapt.py'
];
pythonScripts.forEach(script => {
const src = path.join(this.scriptsDir, script);
const dest = path.join(this.claudeDir, script);
if (fs.existsSync(src)) {
fs.copyFileSync(src, dest);
fs.chmodSync(dest, '755');
this.log(`Installed ${script}`, 'success');
}
});
}
createWrapperScript() {
// Copy the template wrapper
const templatePath = path.join(__dirname, '..', 'templates', 'aide-wrapper.sh');
const wrapperPath = path.join(this.claudeDir, 'aide-wrapper.sh');
if (fs.existsSync(templatePath)) {
let content = fs.readFileSync(templatePath, 'utf8');
// Replace placeholders
content = content.replace(/{{PYTHON_COMMAND}}/g, 'python3');
content = content.replace(/{{SCRIPTS_DIR}}/g, this.claudeDir);
content = content.replace(/{{ENABLE_FALLBACK}}/g, 'true');
fs.writeFileSync(wrapperPath, content);
fs.chmodSync(wrapperPath, '755');
this.log('Created AIDE wrapper script from template', 'success');
} else {
// Fallback to basic wrapper if template not found
const wrapperContent = `#!/bin/bash
# AIDE Basic Wrapper
AIDE_DIR="$HOME/.claude"
case "$1" in
init|status|track|adapt)
python3 "$AIDE_DIR/aide_$1.py" "\${@:2}"
;;
*)
echo "Unknown command: $1"
exit 1
;;
esac
`;
fs.writeFileSync(wrapperPath, wrapperContent);
fs.chmodSync(wrapperPath, '755');
this.log('Created basic AIDE wrapper script', 'success');
}
}
fixBinaryPaths() {
// Fix any hardcoded paths in binary files
const binaries = ['aide-init', 'aide-track', 'aide-status', 'aide-adapt', 'aide-license'];
binaries.forEach(binary => {
const binPath = path.join(this.binDir, binary);
if (fs.existsSync(binPath)) {
try {
let content = fs.readFileSync(binPath, 'utf8');
// Replace hardcoded paths with dynamic ones
content = content.replace(/\/Users\/[^\/]+\//g, `${os.homedir()}/`);
content = content.replace(/python3\s+~\/\.claude\//g, 'python3 "$HOME/.claude/');
fs.writeFileSync(binPath, content);
fs.chmodSync(binPath, '755');
} catch (e) {
// Binary might be compiled, skip text replacement
}
}
});
this.log('Updated binary paths', 'success');
}
setupDaemonDirs() {
const daemonDir = path.join(this.claudeDir, '.aide-daemon');
if (!fs.existsSync(daemonDir)) {
fs.mkdirSync(daemonDir, { recursive: true });
}
this.log('Created daemon directory', 'success');
}
run() {
this.log('Running AIDE post-install setup...');
try {
this.ensureClaudeDir();
this.cleanOldFiles();
this.copyPythonScripts();
this.createWrapperScript();
this.fixBinaryPaths();
this.setupDaemonDirs();
// Run the Claude installer
try {
execSync('node lib/installer.js', {
cwd: path.join(__dirname, '..'),
stdio: 'inherit'
});
} catch (e) {
this.log('Could not run Claude installer (may already be installed)', 'warning');
}
this.log('AIDE setup completed successfully! 🎉', 'success');
this.log('You can now use aide-init, aide-track, aide-status, and aide-adapt commands', 'info');
} catch (error) {
this.log(`Setup failed: ${error.message}`, 'error');
// Don't fail npm install
}
}
}
// Run the post-installer
const installer = new AIDEPostInstaller();
installer.run();