claude-code-templates
Version:
CLI tool to setup Claude Code configurations with framework-specific commands, automation hooks and MCP Servers for your projects
185 lines (158 loc) ⢠4.54 kB
JavaScript
/**
* Docker Sandbox Launcher
* Orchestrates Docker container execution for Claude Code
*/
import { spawn, execSync } from 'child_process';
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Parse command line arguments
const args = process.argv.slice(2);
const prompt = args[0] || 'Hello, Claude!';
const componentsToInstall = args[1] || '';
const anthropicApiKey = process.env.ANTHROPIC_API_KEY;
// Validate API key
if (!anthropicApiKey) {
console.error('ā Error: ANTHROPIC_API_KEY environment variable is required');
process.exit(1);
}
console.log('š³ Docker Sandbox Launcher');
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
/**
* Check if Docker is installed
*/
function checkDockerInstalled() {
try {
execSync('docker --version', { stdio: 'pipe' });
return true;
} catch (error) {
console.error('ā Error: Docker is not installed');
console.error(' Please install Docker: https://docs.docker.com/get-docker/\n');
return false;
}
}
/**
* Check if Docker daemon is running
*/
function checkDockerRunning() {
try {
execSync('docker ps', { stdio: 'pipe' });
return true;
} catch (error) {
console.error('ā Error: Docker daemon is not running');
console.error(' Please start Docker and try again\n');
return false;
}
}
/**
* Build Docker image if it doesn't exist
*/
async function buildDockerImage() {
console.log('šØ Checking Docker image...');
// Check if image exists
try {
execSync('docker image inspect claude-sandbox', { stdio: 'pipe' });
console.log(' ā
Image already exists\n');
return true;
} catch (error) {
// Image doesn't exist, build it
console.log(' š¦ Building Docker image (this may take a few minutes)...\n');
return new Promise((resolve) => {
const build = spawn('docker', [
'build',
'-t', 'claude-sandbox',
'.'
], {
cwd: __dirname,
stdio: 'inherit'
});
build.on('close', (code) => {
if (code === 0) {
console.log('\nā
Docker image built successfully\n');
resolve(true);
} else {
console.error('\nā Failed to build Docker image');
resolve(false);
}
});
build.on('error', (error) => {
console.error('ā Build error:', error.message);
resolve(false);
});
});
}
}
/**
* Run Docker container
*/
async function runDockerContainer() {
console.log('š Starting Docker container...\n');
// Create output directory
const outputDir = path.join(process.cwd(), 'output');
await fs.mkdir(outputDir, { recursive: true });
return new Promise((resolve) => {
const dockerArgs = [
'run',
'--rm',
'-e', `ANTHROPIC_API_KEY=${anthropicApiKey}`,
'-v', `${outputDir}:/output`,
'claude-sandbox',
'node', '/app/execute.js',
prompt,
componentsToInstall
];
const container = spawn('docker', dockerArgs, {
stdio: 'inherit'
});
container.on('close', (code) => {
if (code === 0) {
console.log('\nā
Docker container completed successfully');
// Show output directory
console.log(`\nš Output files saved to: ${outputDir}`);
resolve(true);
} else {
console.error('\nā Docker container failed with code:', code);
resolve(false);
}
});
container.on('error', (error) => {
console.error('ā Container error:', error.message);
resolve(false);
});
});
}
/**
* Main execution flow
*/
async function main() {
try {
// Step 1: Check Docker installation
if (!checkDockerInstalled()) {
process.exit(1);
}
// Step 2: Check Docker daemon
if (!checkDockerRunning()) {
process.exit(1);
}
// Step 3: Build Docker image
const buildSuccess = await buildDockerImage();
if (!buildSuccess) {
process.exit(1);
}
// Step 4: Run container
const runSuccess = await runDockerContainer();
if (!runSuccess) {
process.exit(1);
}
console.log('\nš Docker sandbox execution completed!');
process.exit(0);
} catch (error) {
console.error('ā Fatal error:', error.message);
process.exit(1);
}
}
// Run main function
main();