UNPKG

bmad-agent-init

Version:

Windsurf integration for BMAD-METHOD - automatic initialization of bmad-agent in projects

140 lines (119 loc) 4.51 kB
import express from 'express'; import { readdir, readFile, stat } from 'fs/promises'; import { join, dirname, relative } from 'path'; // Added 'relative' import { fileURLToPath } from 'url'; import cors from 'cors'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Define the project root as the docs directory at the project root const PROJECT_ROOT = join(__dirname, '..', '..', 'docs'); console.log(`Backend Project Root configured to: ${PROJECT_ROOT}`); // Ensure the docs directory exists import { existsSync, mkdirSync } from 'fs'; if (!existsSync(PROJECT_ROOT)) { console.log(`Creating docs directory at: ${PROJECT_ROOT}`); mkdirSync(PROJECT_ROOT, { recursive: true }); } const app = express(); const PORT = 3000; // Configure CORS const allowedOrigins = [ 'http://localhost:8080', 'http://localhost:8081', 'http://127.0.0.1:8080', 'http://localhost:3000', 'http://127.0.0.1:3000' ]; const corsOptions = { origin: function (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) { // Allow requests with no origin (like mobile apps or curl requests) if (!origin) return callback(null, true); if (allowedOrigins.includes(origin)) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } }, optionsSuccessStatus: 200 }; app.use(cors(corsOptions)); app.use(express.json()); // Log all requests app.use((req, res, next) => { console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`); next(); }); interface FileNode { name: string; path: string; type: 'file' | 'directory'; children?: FileNode[]; } app.get('/files', async (req: express.Request, res: express.Response) => { try { const dirPath = typeof req.query.path === 'string' ? req.query.path : '.'; // Default to PROJECT_ROOT const requestedPath = dirPath as string; const fullPath = join(PROJECT_ROOT, requestedPath); // Security check to prevent directory traversal if (!fullPath.startsWith(PROJECT_ROOT)) { res.status(403).json({ error: 'Access denied' }); return; } const stats = await stat(fullPath); if (!stats.isDirectory()) { res.status(400).json({ error: 'Path is not a directory' }); return; } const entries = await readdir(fullPath, { withFileTypes: true }); const children = await Promise.all( entries .filter(entry => !entry.name.startsWith('.') && entry.name !== 'node_modules') .map(async entry => { const entryPath = join(fullPath, entry.name); const entryStats = await stat(entryPath); return { name: entry.name, path: relative(PROJECT_ROOT, entryPath).replace(/\\/g, '/'), // Make path relative to PROJECT_ROOT type: entryStats.isDirectory() ? 'directory' as const : 'file' as const, children: entryStats.isDirectory() ? [] : undefined }; }) ); // Ensure the root path is also consistently relative (e.g., "." for the root itself) const rootNodeName = dirPath === '.' ? PROJECT_ROOT.split(/[\\/]/).pop() || 'root' : dirPath.split(/[\\/]/).pop() || 'root'; res.json({ name: rootNodeName, path: dirPath === '.' ? '.' : (dirPath as string).replace(/\\/g, '/'), // Ensure root path is just '.' or the relative dirPath type: 'directory', children }); } catch (error) { console.error('Error reading directory:', error); res.status(500).json({ error: 'Failed to read directory' }); } }); app.get('/files/content', async (req: express.Request, res: express.Response) => { try { const { path: filePath } = req.query; if (!filePath) { res.status(400).json({ error: 'File path is required' }); return; } const requestedPath = filePath as string; const fullPath = join(PROJECT_ROOT, requestedPath); // Security check to prevent directory traversal if (!fullPath.startsWith(PROJECT_ROOT)) { res.status(403).json({ error: 'Access denied' }); return; } const content = await readFile(fullPath, 'utf-8'); res.send(content); } catch (error) { console.error('Error reading file:', error); res.status(500).json({ error: 'Failed to read file' }); } }); app.listen(PORT, '0.0.0.0', () => { console.log(`Server is running on http://localhost:${PORT}`); console.log(`Serving files from project root: ${PROJECT_ROOT}`); });