const express = require('express'); const http = require('http'); const { Server } = require('socket.io'); const cors = require('cors'); const fs = require('fs').promises; const path = require('path'); const { exec } = require('child_process'); const app = express(); app.use(cors()); app.use(express.json()); // Create a workspace directory const WORKSPACE_DIR = path.join(__dirname, 'workspace'); async function ensureWorkspace() { try { await fs.access(WORKSPACE_DIR); } catch { await fs.mkdir(WORKSPACE_DIR, { recursive: true }); // Create demo files await fs.writeFile( path.join(WORKSPACE_DIR, 'index.html'), ` Demo App

Hello AgentIDE!

This is a sample project.

` ); await fs.writeFile( path.join(WORKSPACE_DIR, 'app.js'), `// Main application file console.log('AgentIDE demo app starting...'); function greet(name) { return \`Hello, \${name}!\`; } const result = greet('World'); console.log(result);` ); await fs.writeFile( path.join(WORKSPACE_DIR, 'styles.css'), `/* Demo styles */ body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background: #1e1e1e; color: #d4d4d4; } h1 { color: #4fc1ff; }` ); await fs.writeFile( path.join(WORKSPACE_DIR, 'package.json'), JSON.stringify({ name: 'demo-project', version: '1.0.0', scripts: { test: 'echo "Tests passed!" && exit 0' } }, null, 2) ); await fs.mkdir(path.join(WORKSPACE_DIR, 'src'), { recursive: true }); await fs.writeFile( path.join(WORKSPACE_DIR, 'src', 'utils.js'), `// Utility functions export function add(a, b) { return a + b; } export function multiply(a, b) { return a * b; }` ); } } // File System API app.get('/api/files', async (req, res) => { try { const files = await readDirectory(WORKSPACE_DIR); res.json(files); } catch (error) { res.status(500).json({ error: error.message }); } }); app.get('/api/files/*', async (req, res) => { try { const filePath = path.join(WORKSPACE_DIR, req.params[0]); const content = await fs.readFile(filePath, 'utf-8'); res.json({ content }); } catch (error) { res.status(500).json({ error: error.message }); } }); app.post('/api/files/*', async (req, res) => { try { const filePath = path.join(WORKSPACE_DIR, req.params[0]); const dir = path.dirname(filePath); await fs.mkdir(dir, { recursive: true }); await fs.writeFile(filePath, req.body.content, 'utf-8'); res.json({ success: true }); } catch (error) { res.status(500).json({ error: error.message }); } }); app.delete('/api/files/*', async (req, res) => { try { const filePath = path.join(WORKSPACE_DIR, req.params[0]); await fs.unlink(filePath); res.json({ success: true }); } catch (error) { res.status(500).json({ error: error.message }); } }); app.post('/api/files/create-folder/*', async (req, res) => { try { const folderPath = path.join(WORKSPACE_DIR, req.params[0]); await fs.mkdir(folderPath, { recursive: true }); res.json({ success: true }); } catch (error) { res.status(500).json({ error: error.message }); } }); app.post('/api/files/rename', async (req, res) => { try { const { oldPath, newPath } = req.body; const fullOldPath = path.join(WORKSPACE_DIR, oldPath); const fullNewPath = path.join(WORKSPACE_DIR, newPath); await fs.rename(fullOldPath, fullNewPath); res.json({ success: true }); } catch (error) { res.status(500).json({ error: error.message }); } }); // AI API app.post('/api/ai/chat', async (req, res) => { const { message, context } = req.body; // Simulated AI responses (in production, integrate with OpenAI/Anthropic) const responses = { 'summarize': { type: 'summary', content: `# Project Summary This is a demo project with the following structure: - **index.html**: Main HTML entry point - **app.js**: JavaScript application logic - **styles.css**: Styling definitions - **package.json**: Project configuration - **src/utils.js**: Utility functions The project appears to be a simple web application demonstrating basic functionality.` }, 'explain': { type: 'explanation', content: `The code you've selected is a simple greeting function that takes a name parameter and returns a formatted string. It uses template literals for string interpolation.` }, 'default': { type: 'response', content: `I've analyzed your request. Based on the project structure, I can help you with: 1. Creating new files and folders 2. Refactoring existing code 3. Generating unit tests 4. Explaining code snippets 5. Running commands and tests What would you like me to do?` } }; // Simple keyword matching for demo let response = responses.default; if (message.toLowerCase().includes('summarize') || message.toLowerCase().includes('structure')) { response = responses.summarize; } else if (message.toLowerCase().includes('explain')) { response = responses.explain; } res.json(response); }); // Execute command app.post('/api/execute', (req, res) => { const { command } = req.body; exec(command, { cwd: WORKSPACE_DIR }, (error, stdout, stderr) => { res.json({ success: !error, output: stdout || stderr, error: error ? error.message : null }); }); }); // Helper function to read directory recursively async function readDirectory(dir, basePath = '') { const entries = await fs.readdir(dir, { withFileTypes: true }); const result = []; for (const entry of entries) { const fullPath = path.join(dir, entry.name); const relativePath = path.join(basePath, entry.name); if (entry.isDirectory()) { result.push({ name: entry.name, path: relativePath, type: 'folder', children: await readDirectory(fullPath, relativePath) }); } else { const stats = await fs.stat(fullPath); result.push({ name: entry.name, path: relativePath, type: 'file', size: stats.size, extension: path.extname(entry.name).slice(1) }); } } return result; } // WebSocket Server for terminal and real-time updates const server = http.createServer(app); const io = new Server(server, { cors: { origin: '*', methods: ['GET', 'POST'] } }); io.on('connection', (socket) => { console.log('Client connected'); socket.on('terminal-input', (data) => { // Simulate terminal output exec(data.command, { cwd: WORKSPACE_DIR }, (error, stdout, stderr) => { socket.emit('terminal-output', { output: stdout || stderr || `Command: ${data.command}`, error: !!error }); }); }); socket.on('file-change', (data) => { socket.broadcast.emit('file-updated', data); }); socket.on('disconnect', () => { console.log('Client disconnected'); }); }); // Start server ensureWorkspace().then(() => { const PORT = process.env.PORT || 3001; server.listen(PORT, () => { console.log(`AgentIDE server running on http://localhost:${PORT}`); console.log(`Workspace: ${WORKSPACE_DIR}`); }); }); module.exports = app;