openmagic 0.8.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/proxy.ts","../src/security.ts","../src/server.ts","../src/config.ts","../src/filesystem.ts","../src/llm/registry.ts","../src/llm/prompts.ts","../src/llm/openai.ts","../src/llm/anthropic.ts","../src/llm/google.ts","../src/llm/proxy.ts","../src/detect.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { resolve } from \"node:path\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\n\n// Suppress http-proxy deprecation warning noise\nconst origEmitWarning = process.emitWarning;\nprocess.emitWarning = function (warning: any, ...args: any[]) {\n if (typeof warning === \"string\" && warning.includes(\"util._extend\")) return;\n return origEmitWarning.call(process, warning, ...args);\n} as typeof process.emitWarning;\n\n// Global error handlers — prevent silent crashes\nprocess.on(\"unhandledRejection\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Unhandled error:\"), (err as Error)?.message || err);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Fatal error:\"), err.message);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n process.exit(1);\n});\n\n// Track child processes for cleanup\nconst childProcesses: ChildProcess[] = [];\nimport { createProxyServer } from \"./proxy.js\";\nimport { createOpenMagicServer } from \"./server.js\";\nimport { generateSessionToken } from \"./security.js\";\nimport {\n detectDevServer,\n findAvailablePort,\n isPortOpen,\n detectDevScripts,\n getProjectName,\n checkDependenciesInstalled,\n} from \"./detect.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\n\nconst VERSION = \"0.8.2\";\n\nfunction ask(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nfunction waitForPort(\n port: number,\n timeoutMs: number = 30000,\n shouldAbort?: () => boolean\n): Promise<boolean> {\n const start = Date.now();\n return new Promise((resolve) => {\n const check = async () => {\n if (shouldAbort?.()) {\n resolve(false);\n return;\n }\n if (await isPortOpen(port)) {\n resolve(true);\n return;\n }\n if (Date.now() - start > timeoutMs) {\n resolve(false);\n return;\n }\n setTimeout(check, 500);\n };\n check();\n });\n}\n\nfunction runCommand(cmd: string, args: string[], cwd: string = process.cwd()): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: true,\n });\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.on(\"error\", () => resolve(false));\n child.on(\"close\", (code) => resolve(code === 0));\n } catch {\n resolve(false);\n }\n });\n}\n\nasync function healthCheck(proxyPort: number, targetPort: number): Promise<void> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n\n const res = await fetch(`http://127.0.0.1:${proxyPort}/`, {\n signal: controller.signal,\n headers: { Accept: \"text/html\" },\n });\n clearTimeout(timeout);\n\n if (res.ok) {\n const text = await res.text();\n if (text.includes(\"__OPENMAGIC_LOADED__\")) {\n console.log(chalk.green(\" ✓ Toolbar injection verified.\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Page loaded but toolbar may not have injected (non-HTML response or CSP).\"));\n }\n } else {\n console.log(\n chalk.yellow(` ⚠ Dev server returned ${res.status}. Pages may have errors.`)\n );\n console.log(\n chalk.dim(\" The toolbar will still appear on pages that load successfully.\")\n );\n }\n } catch {\n console.log(\n chalk.yellow(\" ⚠ Could not verify proxy. The dev server may still be starting.\")\n );\n console.log(\n chalk.dim(\" Try refreshing the page in a few seconds.\")\n );\n }\n console.log(\"\");\n}\n\n// Detect common dev server errors and show hints\nfunction formatDevServerLine(line: string): string {\n const trimmed = line.trim();\n if (!trimmed) return \"\";\n\n // Detect error patterns and add context\n if (trimmed.startsWith(\"Error:\") || trimmed.includes(\"ModuleNotFoundError\") || trimmed.includes(\"Can't resolve\")) {\n return chalk.red(` │ ${trimmed}`);\n }\n if (trimmed.includes(\"EADDRINUSE\") || trimmed.includes(\"address already in use\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Port is already in use. Stop the other process or use --port <different-port>\");\n }\n if (trimmed.includes(\"EACCES\") || trimmed.includes(\"permission denied\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Permission denied. Try a different port or check file permissions.\");\n }\n if (trimmed.includes(\"Cannot find module\") || trimmed.includes(\"MODULE_NOT_FOUND\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Missing dependency. Try running npm install.\");\n }\n\n return chalk.dim(` │ ${trimmed}`);\n}\n\nconst program = new Command();\n\nprogram\n .name(\"openmagic\")\n .description(\"AI-powered coding toolbar for any web application\")\n .version(VERSION)\n .option(\"-p, --port <port>\", \"Dev server port to proxy\", \"\")\n .option(\n \"-l, --listen <port>\",\n \"Port for the OpenMagic proxy\",\n \"4567\"\n )\n .option(\n \"-r, --root <paths...>\",\n \"Project root directories (defaults to cwd)\"\n )\n .option(\"--no-open\", \"Don't auto-open browser\")\n .option(\"--host <host>\", \"Dev server host\", \"127.0.0.1\")\n .action(async (opts) => {\n console.log(\"\");\n console.log(\n chalk.bold.magenta(\" ✨ OpenMagic\") + chalk.dim(` v${VERSION}`)\n );\n console.log(\"\");\n\n let targetPort: number;\n let targetHost = opts.host;\n\n if (opts.port) {\n // User specified a port\n targetPort = parseInt(opts.port, 10);\n const isRunning = await isPortOpen(targetPort);\n if (!isRunning) {\n // Port specified but not running — offer to start it\n const started = await offerToStartDevServer(targetPort);\n if (!started) {\n process.exit(1);\n }\n }\n } else {\n // Auto-detect running dev server\n console.log(chalk.dim(\" Scanning for dev server...\"));\n const detected = await detectDevServer();\n\n if (detected) {\n targetPort = detected.port;\n targetHost = detected.host;\n } else {\n // No server running — try to detect and start from package.json\n const started = await offerToStartDevServer();\n if (!started) {\n process.exit(1);\n }\n // Re-detect after starting\n const redetected = await detectDevServer();\n if (!redetected) {\n console.log(chalk.red(\" ✗ Could not detect the dev server after starting.\"));\n console.log(chalk.dim(\" Try specifying the port: npx openmagic --port 3000\"));\n console.log(\"\");\n process.exit(1);\n }\n targetPort = redetected.port;\n targetHost = redetected.host;\n }\n }\n\n console.log(\n chalk.green(` ✓ Dev server running at ${targetHost}:${targetPort}`)\n );\n\n // Set up roots\n const roots = (opts.root || [process.cwd()]).map((r: string) =>\n resolve(r)\n );\n\n // Save roots to config\n const config = loadConfig();\n saveConfig({ ...config, roots, targetPort });\n\n // Generate session token\n const token = generateSessionToken();\n\n // Find available proxy port (need TWO consecutive free ports: proxy + companion)\n let proxyPort = parseInt(opts.listen, 10);\n while (await isPortOpen(proxyPort) || await isPortOpen(proxyPort + 1)) {\n proxyPort++;\n if (proxyPort > parseInt(opts.listen, 10) + 100) {\n console.log(chalk.red(\" Could not find two consecutive free ports.\"));\n process.exit(1);\n }\n }\n\n const companionPort = proxyPort + 1;\n\n // Start the OpenMagic server (serves toolbar + WebSocket)\n const { httpServer: omServer } = createOpenMagicServer(companionPort, roots);\n omServer.listen(companionPort, \"127.0.0.1\", () => {\n // OpenMagic API/WS server running\n });\n\n // Start the proxy server\n const proxyServer = createProxyServer(\n targetHost,\n targetPort!,\n companionPort\n );\n\n proxyServer.listen(proxyPort, \"127.0.0.1\", async () => {\n console.log(\"\");\n console.log(\n chalk.bold.green(` 🚀 Proxy running at → `) +\n chalk.bold.underline.cyan(`http://localhost:${proxyPort}`)\n );\n console.log(\"\");\n\n // Health check — verify the proxy can reach the dev server\n await healthCheck(proxyPort, targetPort!);\n\n console.log(\n chalk.dim(\" Open the URL above in your browser to start.\")\n );\n console.log(chalk.dim(\" Press Ctrl+C to stop.\"));\n console.log(\n chalk.dim(\" Errors below are from your dev server, not OpenMagic.\")\n );\n console.log(\"\");\n\n if (opts.open !== false) {\n open(`http://localhost:${proxyPort}`).catch(() => {});\n }\n });\n\n // Handle WebSocket upgrades for OpenMagic\n proxyServer.on(\"upgrade\", (req, socket, head) => {\n if (req.url?.startsWith(\"/__openmagic__\")) {\n omServer.emit(\"upgrade\", req, socket, head);\n }\n });\n\n // Graceful shutdown\n const shutdown = () => {\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n proxyServer.close();\n omServer.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n });\n\n// --- Smart Dev Server Start ---\n\nasync function offerToStartDevServer(expectedPort?: number): Promise<boolean> {\n const projectName = getProjectName();\n const scripts = detectDevScripts();\n\n if (scripts.length === 0) {\n console.log(\n chalk.yellow(\" ⚠ No dev server detected and no dev scripts found in package.json\")\n );\n console.log(\"\");\n console.log(chalk.white(\" Start your dev server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // Check if dependencies are installed\n const deps = checkDependenciesInstalled();\n if (!deps.installed) {\n console.log(\n chalk.yellow(\" ⚠ node_modules/ not found. Dependencies need to be installed.\")\n );\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Run `) +\n chalk.cyan(deps.installCommand) +\n chalk.white(\"? \") +\n chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(` Run ${deps.installCommand} manually, then try again.`));\n console.log(\"\");\n return false;\n }\n\n console.log(\"\");\n console.log(chalk.dim(` Installing dependencies with ${deps.packageManager}...`));\n\n const [installCmd, ...installArgs] = deps.installCommand.split(\" \");\n const installed = await runCommand(installCmd, installArgs);\n\n if (!installed) {\n console.log(chalk.red(\" ✗ Dependency installation failed.\"));\n console.log(chalk.dim(` Try running ${deps.installCommand} manually.`));\n console.log(\"\");\n return false;\n }\n\n console.log(chalk.green(\" ✓ Dependencies installed.\"));\n console.log(\"\");\n }\n\n // Pick the best script\n let chosen = scripts[0];\n if (scripts.length === 1) {\n // Only one option\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n chalk.white(` in ${projectName}`) +\n chalk.dim(` (${chosen.framework})`)\n );\n console.log(chalk.dim(` → ${chosen.command}`));\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Start it now? `) + chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n } else {\n // Multiple scripts — let user pick\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found ${scripts.length} dev scripts in ${projectName}:`)\n );\n console.log(\"\");\n\n scripts.forEach((s, i) => {\n console.log(\n chalk.cyan(` ${i + 1}) `) +\n chalk.white(`npm run ${s.name}`) +\n chalk.dim(` — ${s.framework} (port ${s.defaultPort})`)\n );\n console.log(chalk.dim(` ${s.command}`));\n });\n\n console.log(\"\");\n const answer = await ask(\n chalk.white(` Which one to start? `) +\n chalk.dim(`(1-${scripts.length}, or n to cancel) `)\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\" || answer === \"\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n\n const idx = parseInt(answer, 10) - 1;\n if (idx < 0 || idx >= scripts.length || isNaN(idx)) {\n // Default to first\n chosen = scripts[0];\n } else {\n chosen = scripts[idx];\n }\n }\n\n // Start the dev server\n const port = expectedPort || chosen.defaultPort;\n\n console.log(\"\");\n console.log(\n chalk.dim(` Starting `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n chalk.dim(\"...\")\n );\n\n // Use the correct package manager run command\n const depsInfo = checkDependenciesInstalled();\n const runCmd = depsInfo.packageManager === \"yarn\" ? \"yarn\" :\n depsInfo.packageManager === \"pnpm\" ? \"pnpm\" :\n depsInfo.packageManager === \"bun\" ? \"bun\" : \"npm\";\n const runArgs = runCmd === \"npm\" ? [\"run\", chosen.name] : [chosen.name];\n\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(runCmd, runArgs, {\n cwd: process.cwd(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: false,\n shell: true,\n env: {\n ...process.env,\n PORT: String(port),\n BROWSER: \"none\",\n BROWSER_NONE: \"true\",\n },\n });\n } catch (e: unknown) {\n console.log(chalk.red(` ✗ Failed to start: ${(e as Error).message}`));\n return false;\n }\n\n childProcesses.push(child);\n let childExited = false;\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n for (const line of data.toString().trim().split(\"\\n\")) {\n const formatted = formatDevServerLine(line);\n if (formatted) process.stdout.write(formatted + \"\\n\");\n }\n });\n\n child.stderr?.on(\"data\", (data: Buffer) => {\n for (const line of data.toString().trim().split(\"\\n\")) {\n const formatted = formatDevServerLine(line);\n if (formatted) process.stdout.write(formatted + \"\\n\");\n }\n });\n\n child.on(\"error\", (err) => {\n childExited = true;\n console.log(chalk.red(` ✗ Failed to start: ${err.message}`));\n });\n\n child.on(\"exit\", (code) => {\n childExited = true;\n if (code !== null && code !== 0) {\n console.log(chalk.red(` ✗ Dev server exited with code ${code}`));\n }\n });\n\n // Clean up all child processes on exit\n const cleanup = () => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGTERM\"); } catch {}\n }\n setTimeout(() => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGKILL\"); } catch {}\n }\n }, 3000);\n };\n process.on(\"exit\", cleanup);\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Wait for the port to open (abort early if child exits)\n console.log(\n chalk.dim(` Waiting for port ${port}...`)\n );\n\n const isUp = await waitForPort(port, 30000, () => childExited);\n\n if (childExited && !isUp) {\n console.log(\n chalk.red(` ✗ Dev server exited before it was ready.`)\n );\n console.log(\n chalk.dim(` Check the error output above and fix the issue.`)\n );\n console.log(\"\");\n return false;\n }\n\n if (!isUp) {\n console.log(\n chalk.yellow(` ⚠ Port ${port} didn't open after 30s.`)\n );\n console.log(\n chalk.dim(` The server might use a different port. Check the output above.`)\n );\n console.log(\"\");\n\n // Try to detect any port that opened\n const detected = await detectDevServer();\n if (detected) {\n console.log(\n chalk.green(` ✓ Found server on port ${detected.port} instead.`)\n );\n return true;\n }\n\n return false;\n }\n\n console.log(\"\");\n return true;\n}\n\nprogram.parse();\n","import http from \"node:http\";\nimport { createGunzip, createInflate, createBrotliDecompress } from \"node:zlib\";\nimport { pipeline } from \"node:stream/promises\";\nimport httpProxy from \"http-proxy\";\nimport { getSessionToken } from \"./security.js\";\n\nexport function createProxyServer(\n targetHost: string,\n targetPort: number,\n serverPort: number\n): http.Server {\n const proxy = httpProxy.createProxyServer({\n target: `http://${targetHost}:${targetPort}`,\n ws: true,\n selfHandleResponse: true,\n });\n\n const token = getSessionToken();\n\n proxy.on(\"proxyRes\", (proxyRes, req, res) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isHtml = contentType.includes(\"text/html\");\n\n if (!isHtml) {\n // Pass through non-HTML responses unchanged\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n // For HTML responses, collect the body, decompress if needed, and inject toolbar\n collectBody(proxyRes)\n .then((body) => {\n // Inject toolbar script before </body> or at end\n const toolbarScript = buildInjectionScript(serverPort, token);\n if (body.includes(\"</body>\")) {\n body = body.replace(\"</body>\", `${toolbarScript}</body>`);\n } else if (body.includes(\"</html>\")) {\n body = body.replace(\"</html>\", `${toolbarScript}</html>`);\n } else {\n body += toolbarScript;\n }\n\n // Send uncompressed response (we decoded it)\n const headers = { ...proxyRes.headers };\n delete headers[\"content-length\"];\n delete headers[\"content-encoding\"];\n delete headers[\"transfer-encoding\"];\n\n res.writeHead(proxyRes.statusCode || 200, headers);\n res.end(body);\n })\n .catch(() => {\n // If decompression/collection fails, proxy the raw response\n // This ensures the app still works even if injection fails\n try {\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end();\n } catch {\n // Response already sent or connection closed\n }\n });\n });\n\n proxy.on(\"error\", (err, _req, res) => {\n if (res instanceof http.ServerResponse && !res.headersSent) {\n const toolbarScript = buildInjectionScript(serverPort, token);\n res.writeHead(502, { \"Content-Type\": \"text/html\" });\n res.end(\n `<html><body style=\"font-family:system-ui;padding:40px;background:#1a1a2e;color:#e0e0e0;\">\n <h2 style=\"color:#e94560;\">OpenMagic — Cannot connect to dev server</h2>\n <p>Could not reach <code>${targetHost}:${targetPort}</code></p>\n <p style=\"color:#888;\">Make sure your dev server is running, then refresh this page.</p>\n <p style=\"color:#666;font-size:13px;\">${err.message}</p>\n ${toolbarScript}\n </body></html>`\n );\n }\n });\n\n const server = http.createServer((req, res) => {\n if (req.url?.startsWith(\"/__openmagic__/\")) {\n handleToolbarAsset(req, res, serverPort);\n return;\n }\n proxy.web(req, res);\n });\n\n server.on(\"upgrade\", (req, socket, head) => {\n if (req.url?.startsWith(\"/__openmagic__\")) {\n return;\n }\n proxy.ws(req, socket, head);\n });\n\n return server;\n}\n\nfunction collectBody(stream: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const encoding = (stream.headers[\"content-encoding\"] || \"\").toLowerCase();\n const chunks: Buffer[] = [];\n\n let source: NodeJS.ReadableStream = stream;\n\n // Decompress if needed\n if (encoding === \"gzip\" || encoding === \"x-gzip\") {\n const gunzip = createGunzip();\n stream.pipe(gunzip);\n source = gunzip;\n gunzip.on(\"error\", () => {\n // Decompression failed — try reading raw\n collectRaw(stream).then(resolve).catch(reject);\n });\n } else if (encoding === \"deflate\") {\n const inflate = createInflate();\n stream.pipe(inflate);\n source = inflate;\n inflate.on(\"error\", () => {\n collectRaw(stream).then(resolve).catch(reject);\n });\n } else if (encoding === \"br\") {\n const brotli = createBrotliDecompress();\n stream.pipe(brotli);\n source = brotli;\n brotli.on(\"error\", () => {\n collectRaw(stream).then(resolve).catch(reject);\n });\n }\n\n source.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n source.on(\"end\", () => {\n try {\n resolve(Buffer.concat(chunks).toString(\"utf-8\"));\n } catch {\n reject(new Error(\"Failed to decode response body\"));\n }\n });\n source.on(\"error\", (err) => reject(err));\n });\n}\n\nfunction collectRaw(stream: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n stream.on(\"end\", () => {\n try {\n resolve(Buffer.concat(chunks).toString(\"utf-8\"));\n } catch {\n reject(new Error(\"Failed to decode raw body\"));\n }\n });\n stream.on(\"error\", reject);\n });\n}\n\nfunction handleToolbarAsset(\n _req: http.IncomingMessage,\n res: http.ServerResponse,\n _serverPort: number\n): void {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not found\");\n}\n\nfunction buildInjectionScript(serverPort: number, token: string): string {\n return `\n<script data-openmagic=\"true\">\n(function() {\n if (window.__OPENMAGIC_LOADED__) return;\n window.__OPENMAGIC_LOADED__ = true;\n window.__OPENMAGIC_CONFIG__ = {\n wsPort: ${serverPort},\n token: \"${token}\"\n };\n var script = document.createElement(\"script\");\n script.src = \"http://127.0.0.1:${serverPort}/__openmagic__/toolbar.js\";\n script.dataset.openmagic = \"true\";\n document.body.appendChild(script);\n})();\n</script>`;\n}\n","import { randomBytes } from \"node:crypto\";\n\nlet sessionToken: string | null = null;\n\nexport function generateSessionToken(): string {\n sessionToken = randomBytes(32).toString(\"hex\");\n return sessionToken;\n}\n\nexport function getSessionToken(): string {\n if (!sessionToken) {\n return generateSessionToken();\n }\n return sessionToken;\n}\n\nexport function validateToken(token: string): boolean {\n return token === sessionToken;\n}\n","import http from \"node:http\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { WebSocketServer, WebSocket } from \"ws\";\nimport { validateToken } from \"./security.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { readFileSafe, writeFileSafe, listFiles, getProjectTree } from \"./filesystem.js\";\nimport type {\n WsMessage,\n HandshakePayload,\n FsReadPayload,\n FsWritePayload,\n FsListPayload,\n LlmChatPayload,\n ConfigSetPayload,\n OpenMagicConfig,\n} from \"./shared-types.js\";\nimport { handleLlmChat } from \"./llm/proxy.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\ninterface ClientState {\n authenticated: boolean;\n}\n\nexport function createOpenMagicServer(\n proxyPort: number,\n roots: string[]\n): { httpServer: http.Server; wss: WebSocketServer } {\n const httpServer = http.createServer((req, res) => {\n // Serve toolbar bundle\n if (req.url === \"/__openmagic__/toolbar.js\") {\n serveToolbarBundle(res);\n return;\n }\n\n // Health check\n if (req.url === \"/__openmagic__/health\") {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(JSON.stringify({ status: \"ok\", version: \"0.8.2\" }));\n return;\n }\n\n res.writeHead(404);\n res.end(\"Not found\");\n });\n\n const wss = new WebSocketServer({\n server: httpServer,\n path: \"/__openmagic__/ws\",\n });\n\n const clientStates = new WeakMap<WebSocket, ClientState>();\n\n wss.on(\"connection\", (ws) => {\n clientStates.set(ws, { authenticated: false });\n\n ws.on(\"message\", async (data) => {\n let msg: WsMessage;\n try {\n msg = JSON.parse(data.toString());\n } catch {\n sendError(ws, \"parse_error\", \"Invalid JSON\");\n return;\n }\n\n const state = clientStates.get(ws)!;\n\n // Require handshake first\n if (!state.authenticated && msg.type !== \"handshake\") {\n sendError(ws, \"auth_required\", \"Handshake required\");\n return;\n }\n\n try {\n await handleMessage(ws, msg, state, roots, proxyPort);\n } catch (e: unknown) {\n sendError(ws, \"internal_error\", (e as Error).message, msg.id);\n }\n });\n\n ws.on(\"close\", () => {\n clientStates.delete(ws);\n });\n });\n\n return { httpServer, wss };\n}\n\nasync function handleMessage(\n ws: WebSocket,\n msg: WsMessage,\n state: ClientState,\n roots: string[],\n _proxyPort: number\n): Promise<void> {\n switch (msg.type) {\n case \"handshake\": {\n const payload = msg.payload as HandshakePayload;\n if (!payload?.token) {\n sendError(ws, \"invalid_payload\", \"Missing token in handshake\", msg.id);\n ws.close();\n return;\n }\n if (!validateToken(payload.token)) {\n sendError(ws, \"auth_failed\", \"Invalid token\", msg.id);\n ws.close();\n return;\n }\n state.authenticated = true;\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"handshake.ok\",\n payload: {\n version: \"0.8.2\",\n roots,\n config: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n },\n },\n });\n break;\n }\n\n case \"fs.read\": {\n const payload = msg.payload as FsReadPayload;\n if (!payload?.path) {\n sendError(ws, \"invalid_payload\", \"Missing path\", msg.id);\n break;\n }\n const result = readFileSafe(payload.path, roots);\n if (\"error\" in result) {\n sendError(ws, \"fs_error\", result.error, msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.content\",\n payload: { path: payload.path, content: result.content },\n });\n }\n break;\n }\n\n case \"fs.write\": {\n const payload = msg.payload as FsWritePayload;\n const result = writeFileSafe(payload.path, payload.content, roots);\n send(ws, {\n id: msg.id,\n type: \"fs.written\",\n payload: { path: payload.path, ok: result.ok, error: result.error },\n });\n break;\n }\n\n case \"fs.list\": {\n const payload = msg.payload as FsListPayload | undefined;\n const root = payload?.root || roots[0];\n const files = listFiles(root, roots);\n send(ws, {\n id: msg.id,\n type: \"fs.tree\",\n payload: { files, projectTree: getProjectTree(roots) },\n });\n break;\n }\n\n case \"llm.chat\": {\n const payload = msg.payload as LlmChatPayload;\n const config = loadConfig();\n\n if (!config.apiKey) {\n sendError(ws, \"config_error\", \"API key not configured\", msg.id);\n return;\n }\n\n await handleLlmChat(\n {\n provider: payload.provider || config.provider || \"openai\",\n model: payload.model || config.model || \"gpt-4o\",\n apiKey: config.apiKey,\n messages: payload.messages,\n context: payload.context,\n },\n (chunk) => {\n send(ws, { id: msg.id, type: \"llm.chunk\", payload: { delta: chunk } });\n },\n (result) => {\n send(ws, { id: msg.id, type: \"llm.done\", payload: result });\n },\n (error) => {\n send(ws, { id: msg.id, type: \"llm.error\", payload: { message: error } });\n }\n );\n break;\n }\n\n case \"config.get\": {\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"config.value\",\n payload: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n roots: config.roots || roots,\n },\n });\n break;\n }\n\n case \"config.set\": {\n const payload = msg.payload as ConfigSetPayload;\n const updates: Partial<OpenMagicConfig> = {};\n if (payload.provider !== undefined) updates.provider = payload.provider;\n if (payload.model !== undefined) updates.model = payload.model;\n if (payload.apiKey !== undefined) updates.apiKey = payload.apiKey;\n if (payload.roots !== undefined) updates.roots = payload.roots;\n saveConfig(updates);\n send(ws, {\n id: msg.id,\n type: \"config.saved\",\n payload: { ok: true },\n });\n break;\n }\n\n default:\n sendError(ws, \"unknown_type\", `Unknown message type: ${msg.type}`, msg.id);\n }\n}\n\nfunction send(ws: WebSocket, msg: WsMessage): void {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nfunction sendError(\n ws: WebSocket,\n code: string,\n message: string,\n id?: string\n): void {\n send(ws, {\n id: id || \"error\",\n type: \"error\",\n payload: { code, message },\n });\n}\n\nfunction serveToolbarBundle(res: http.ServerResponse): void {\n // Try to serve the pre-built toolbar bundle\n const bundlePaths = [\n join(__dirname, \"toolbar\", \"index.global.js\"),\n join(__dirname, \"..\", \"dist\", \"toolbar\", \"index.global.js\"),\n ];\n\n for (const bundlePath of bundlePaths) {\n try {\n if (existsSync(bundlePath)) {\n const content = readFileSync(bundlePath, \"utf-8\");\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n \"Cache-Control\": \"no-cache\",\n });\n res.end(content);\n return;\n }\n } catch {\n // Permission error or read failure — try next path\n continue;\n }\n }\n\n // Fallback: serve a minimal placeholder that shows a \"build required\" message\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(`\n (function() {\n var div = document.createElement(\"div\");\n div.style.cssText = \"position:fixed;bottom:20px;right:20px;background:#1a1a2e;color:#e94560;padding:16px 24px;border-radius:12px;font-family:system-ui;font-size:14px;z-index:2147483647;box-shadow:0 4px 24px rgba(0,0,0,0.3);\";\n div.textContent = \"OpenMagic: Toolbar bundle not found. Run 'npm run build:toolbar' first.\";\n document.body.appendChild(div);\n })();\n `);\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { OpenMagicConfig } from \"./shared-types.js\";\n\nconst CONFIG_DIR = join(homedir(), \".openmagic\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function loadConfig(): Partial<OpenMagicConfig> {\n ensureConfigDir();\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n try {\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(updates: Partial<OpenMagicConfig>): void {\n try {\n ensureConfigDir();\n const existing = loadConfig();\n const merged = { ...existing, ...updates };\n writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), \"utf-8\");\n } catch (e: unknown) {\n console.warn(`[OpenMagic] Warning: Could not save config to ${CONFIG_FILE}: ${(e as Error).message}`);\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","import {\n readFileSync,\n writeFileSync,\n existsSync,\n statSync,\n readdirSync,\n copyFileSync,\n mkdirSync,\n} from \"node:fs\";\nimport { join, resolve, relative, dirname, extname } from \"node:path\";\nimport type { FileEntry } from \"./shared-types.js\";\n\nconst IGNORED_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \".nuxt\",\n \".svelte-kit\",\n \"dist\",\n \"build\",\n \".cache\",\n \".turbo\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \".DS_Store\",\n]);\n\nconst IGNORED_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".ico\",\n \".webp\",\n \".mp4\",\n \".mp3\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".lock\",\n]);\n\nexport function isPathSafe(filePath: string, roots: string[]): boolean {\n const resolved = resolve(filePath);\n return roots.some((root) => {\n const resolvedRoot = resolve(root);\n return resolved.startsWith(resolvedRoot);\n });\n}\n\nexport function readFileSafe(\n filePath: string,\n roots: string[]\n): { content: string } | { error: string } {\n if (!isPathSafe(filePath, roots)) {\n return { error: \"Path is outside allowed roots\" };\n }\n if (!existsSync(filePath)) {\n return { error: \"File not found\" };\n }\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return { content };\n } catch (e: unknown) {\n return { error: `Failed to read file: ${(e as Error).message}` };\n }\n}\n\nexport function writeFileSafe(\n filePath: string,\n content: string,\n roots: string[]\n): { ok: boolean; error?: string; backupPath?: string } {\n if (!isPathSafe(filePath, roots)) {\n return { ok: false, error: \"Path is outside allowed roots\" };\n }\n\n try {\n // Create backup\n let backupPath: string | undefined;\n if (existsSync(filePath)) {\n backupPath = filePath + \".openmagic-backup\";\n copyFileSync(filePath, backupPath);\n }\n\n // Ensure directory exists\n const dir = dirname(filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(filePath, content, \"utf-8\");\n return { ok: true, backupPath };\n } catch (e: unknown) {\n return { ok: false, error: `Failed to write file: ${(e as Error).message}` };\n }\n}\n\nexport function listFiles(\n rootPath: string,\n roots: string[],\n maxDepth: number = 4\n): FileEntry[] {\n if (!isPathSafe(rootPath, roots)) {\n return [];\n }\n\n const entries: FileEntry[] = [];\n\n function walk(dir: string, depth: number): void {\n if (depth > maxDepth) return;\n\n let items: string[];\n try {\n items = readdirSync(dir);\n } catch {\n return;\n }\n\n for (const item of items) {\n if (IGNORED_DIRS.has(item)) continue;\n if (item.startsWith(\".\") && item !== \".env.example\") continue;\n\n const fullPath = join(dir, item);\n let stat;\n try {\n stat = statSync(fullPath);\n } catch {\n continue;\n }\n\n const relPath = relative(rootPath, fullPath);\n\n if (stat.isDirectory()) {\n entries.push({ path: relPath, type: \"dir\", name: item });\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!IGNORED_EXTENSIONS.has(ext)) {\n entries.push({ path: relPath, type: \"file\", name: item });\n }\n }\n }\n }\n\n walk(rootPath, 0);\n return entries;\n}\n\nexport function getProjectTree(roots: string[]): string {\n const lines: string[] = [];\n for (const root of roots) {\n lines.push(`[${root}]`);\n const files = listFiles(root, roots, 3);\n for (const f of files) {\n const indent = f.path.split(\"/\").length - 1;\n const prefix = \" \".repeat(indent);\n const icon = f.type === \"dir\" ? \"/\" : \"\";\n lines.push(`${prefix}${f.name}${icon}`);\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n}\n","import type { ProviderRegistry } from \"../shared-types.js\";\n\nexport const MODEL_REGISTRY: ProviderRegistry = {\n // ─── OpenAI ───────────────────────────────────────────────────\n openai: {\n name: \"OpenAI\",\n models: [\n // GPT-5.4 family (March 2026 — latest flagship)\n {\n id: \"gpt-5.4\",\n name: \"GPT-5.4\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-pro\",\n name: \"GPT-5.4 Pro\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.4-mini\",\n name: \"GPT-5.4 Mini\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-nano\",\n name: \"GPT-5.4 Nano\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n // GPT-5.2 family (reasoning-focused)\n {\n id: \"gpt-5.2\",\n name: \"GPT-5.2 Thinking\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.2-pro\",\n name: \"GPT-5.2 Pro\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n // o-series reasoning models\n {\n id: \"o3\",\n name: \"o3 (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"o4-mini\",\n name: \"o4-mini (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // GPT-4.1 family\n {\n id: \"gpt-4.1\",\n name: \"GPT-4.1\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-mini\",\n name: \"GPT-4.1 Mini\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-nano\",\n name: \"GPT-4.1 Nano\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n // Codex\n {\n id: \"codex-mini-latest\",\n name: \"Codex Mini\",\n vision: false,\n context: 192000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.openai.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Anthropic ────────────────────────────────────────────────\n anthropic: {\n name: \"Anthropic\",\n models: [\n // Claude 4.6 (latest — Feb 2026)\n {\n id: \"claude-opus-4-6\",\n name: \"Claude Opus 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 128000,\n },\n },\n {\n id: \"claude-sonnet-4-6\",\n name: \"Claude Sonnet 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n // Claude 4.5\n {\n id: \"claude-haiku-4-5-20251001\",\n name: \"Claude Haiku 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 5000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Sonnet 4.5\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-5-20251101\",\n name: \"Claude Opus 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 64000,\n },\n },\n // Claude 4.0\n {\n id: \"claude-sonnet-4-20250514\",\n name: \"Claude Sonnet 4\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-20250514\",\n name: \"Claude Opus 4\",\n vision: true,\n context: 200000,\n maxOutput: 32000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 32000,\n },\n },\n ],\n apiBase: \"https://api.anthropic.com/v1\",\n keyPrefix: \"sk-ant-\",\n keyPlaceholder: \"sk-ant-...\",\n },\n\n // ─── Google Gemini ────────────────────────────────────────────\n google: {\n name: \"Google Gemini\",\n models: [\n // Gemini 3.1 (latest — Feb-Mar 2026)\n {\n id: \"gemini-3.1-pro-preview\",\n name: \"Gemini 3.1 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // Gemini 3.0\n {\n id: \"gemini-3-flash-preview\",\n name: \"Gemini 3 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-3.1-flash-lite-preview\",\n name: \"Gemini 3.1 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n // Gemini 2.5\n {\n id: \"gemini-2.5-pro\",\n name: \"Gemini 2.5 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gemini-2.5-flash\",\n name: \"Gemini 2.5 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-2.5-flash-lite\",\n name: \"Gemini 2.5 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n ],\n apiBase: \"https://generativelanguage.googleapis.com/v1beta\",\n keyPrefix: \"AI\",\n keyPlaceholder: \"AIza...\",\n },\n\n // ─── xAI (Grok) ──────────────────────────────────────────────\n xai: {\n name: \"xAI (Grok)\",\n models: [\n {\n id: \"grok-4.20-0309-reasoning\",\n name: \"Grok 4.20 Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"grok-4.20-0309-non-reasoning\",\n name: \"Grok 4.20\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n {\n id: \"grok-4-1-fast-reasoning\",\n name: \"Grok 4.1 Fast Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"grok-4-1-fast-non-reasoning\",\n name: \"Grok 4.1 Fast\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n ],\n apiBase: \"https://api.x.ai/v1\",\n keyPrefix: \"xai-\",\n keyPlaceholder: \"xai-...\",\n },\n\n // ─── DeepSeek ─────────────────────────────────────────────────\n deepseek: {\n name: \"DeepSeek\",\n models: [\n {\n id: \"deepseek-chat\",\n name: \"DeepSeek V3.2\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n },\n {\n id: \"deepseek-reasoner\",\n name: \"DeepSeek R1\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.deepseek.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Mistral ──────────────────────────────────────────────────\n mistral: {\n name: \"Mistral\",\n models: [\n {\n id: \"mistral-large-3-25-12\",\n name: \"Mistral Large 3\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-4-0-26-03\",\n name: \"Mistral Small 4\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-3-2-25-06\",\n name: \"Mistral Small 3.2\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"codestral-2508\",\n name: \"Codestral\",\n vision: false,\n context: 262144,\n maxOutput: 32768,\n },\n {\n id: \"devstral-2-25-12\",\n name: \"Devstral 2\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"magistral-medium-1-2-25-09\",\n name: \"Magistral Medium (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"magistral-small-1-2-25-09\",\n name: \"Magistral Small (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.mistral.ai/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter API key...\",\n },\n\n // ─── Groq ─────────────────────────────────────────────────────\n groq: {\n name: \"Groq\",\n models: [\n {\n id: \"meta-llama/llama-4-scout-17b-16e-instruct\",\n name: \"Llama 4 Scout 17B\",\n vision: true,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"llama-3.3-70b-versatile\",\n name: \"Llama 3.3 70B\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"llama-3.1-8b-instant\",\n name: \"Llama 3.1 8B Instant\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"qwen/qwen3-32b\",\n name: \"Qwen 3 32B\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n ],\n apiBase: \"https://api.groq.com/openai/v1\",\n keyPrefix: \"gsk_\",\n keyPlaceholder: \"gsk_...\",\n },\n\n // ─── MiniMax ───────────────────────────────────────────────────\n minimax: {\n name: \"MiniMax\",\n models: [\n { id: \"MiniMax-M2.7\", name: \"MiniMax M2.7\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.7-highspeed\", name: \"MiniMax M2.7 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5\", name: \"MiniMax M2.5\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5-highspeed\", name: \"MiniMax M2.5 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n ],\n apiBase: \"https://api.minimax.chat/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter MiniMax API key...\",\n },\n\n // ─── Moonshot / Kimi ──────────────────────────────────────────\n moonshot: {\n name: \"Kimi (Moonshot)\",\n models: [\n {\n id: \"kimi-k2.5\",\n name: \"Kimi K2.5\",\n vision: true,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"kimi-k2-thinking\",\n name: \"Kimi K2 Thinking\",\n vision: false,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.moonshot.cn/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Moonshot API key...\",\n },\n\n // ─── Alibaba Qwen (DashScope) ────────────────────────────────\n qwen: {\n name: \"Qwen (Alibaba)\",\n models: [\n { id: \"qwen3.5-plus\", name: \"Qwen 3.5 Plus\", vision: true, context: 1010000, maxOutput: 16384 },\n { id: \"qwen-plus\", name: \"Qwen Plus\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-max\", name: \"Qwen Max\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-turbo\", name: \"Qwen Turbo\", vision: false, context: 131072, maxOutput: 8192 },\n ],\n apiBase: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter DashScope API key...\",\n },\n\n // ─── Zhipu AI (GLM) ──────────────────────────────────────────\n zhipu: {\n name: \"Zhipu AI (GLM)\",\n models: [\n { id: \"glm-5\", name: \"GLM-5\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.7\", name: \"GLM-4.7\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.6\", name: \"GLM-4.6\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.5\", name: \"GLM-4.5\", vision: true, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://open.bigmodel.cn/api/paas/v4\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Zhipu API key...\",\n },\n\n // ─── ByteDance Doubao ─────────────────────────────────────────\n doubao: {\n name: \"Doubao (ByteDance)\",\n models: [\n { id: \"doubao-seed-2-0-pro\", name: \"Doubao Seed 2.0 Pro\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"doubao-seed-2-0-lite\", name: \"Doubao Seed 2.0 Lite\", vision: false, context: 131072, maxOutput: 8192 },\n { id: \"doubao-seed-2-0-code\", name: \"Doubao Seed 2.0 Code\", vision: false, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://ark.cn-beijing.volces.com/api/v3\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Volcano Engine API key...\",\n },\n\n // ─── Ollama (Local) ───────────────────────────────────────────\n ollama: {\n name: \"Ollama (Local)\",\n models: [],\n apiBase: \"http://localhost:11434/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── OpenRouter (200+ models) ─────────────────────────────────\n openrouter: {\n name: \"OpenRouter\",\n models: [],\n apiBase: \"https://openrouter.ai/api/v1\",\n keyPrefix: \"sk-or-\",\n keyPlaceholder: \"sk-or-...\",\n },\n};\n","export const SYSTEM_PROMPT = `You are OpenMagic, an AI coding assistant embedded in a developer's web application. You help modify the codebase based on visual context from the running app.\n\n## Your Role\n- You can see the developer's running web application (DOM elements, screenshots, styles)\n- You propose code modifications to their source files\n- Your changes are applied directly to their codebase and reflected via hot reload\n\n## Response Format\nYou MUST respond with valid JSON in this exact format:\n\n\\`\\`\\`json\n{\n \"modifications\": [\n {\n \"file\": \"relative/path/to/file.tsx\",\n \"type\": \"edit\",\n \"search\": \"exact code to find (multi-line ok)\",\n \"replace\": \"replacement code\"\n }\n ],\n \"explanation\": \"Brief description of what was changed and why\"\n}\n\\`\\`\\`\n\n## Modification Types\n- \\`edit\\`: Replace existing code. \\`search\\` must match exactly in the file. \\`replace\\` is the new code.\n- \\`create\\`: Create a new file. Use \\`content\\` instead of search/replace.\n- \\`delete\\`: Delete a file. No search/replace/content needed.\n\n## Rules\n1. The \\`search\\` field must contain the EXACT text from the source file — copy it precisely, including whitespace and indentation\n2. Keep modifications minimal — change only what's needed\n3. If you need to read a file first, say so in the explanation and the developer can provide it\n4. For style changes, prefer modifying existing CSS/Tailwind classes over adding inline styles\n5. Always preserve the existing code style and conventions\n6. If the change involves multiple files, include all modifications in the array\n7. ALWAYS respond with the JSON format above, even for explanations (put them in the \"explanation\" field)\n8. If you cannot make the requested change, set modifications to an empty array and explain why`;\n\nexport function buildUserMessage(\n userPrompt: string,\n context: {\n selectedElement?: string;\n screenshot?: string;\n fileContent?: string;\n filePath?: string;\n networkLogs?: string;\n consoleLogs?: string;\n projectTree?: string;\n }\n): string {\n const parts: string[] = [];\n\n if (context.projectTree) {\n parts.push(`## Project Structure\\n\\`\\`\\`\\n${context.projectTree}\\n\\`\\`\\``);\n }\n\n if (context.filePath && context.fileContent) {\n parts.push(\n `## Source File: ${context.filePath}\\n\\`\\`\\`\\n${context.fileContent}\\n\\`\\`\\``\n );\n }\n\n if (context.selectedElement) {\n parts.push(`## Selected Element (DOM)\\n\\`\\`\\`html\\n${context.selectedElement}\\n\\`\\`\\``);\n }\n\n if (context.networkLogs) {\n parts.push(`## Recent Network Requests\\n\\`\\`\\`\\n${context.networkLogs}\\n\\`\\`\\``);\n }\n\n if (context.consoleLogs) {\n parts.push(`## Console Output\\n\\`\\`\\`\\n${context.consoleLogs}\\n\\`\\`\\``);\n }\n\n parts.push(`## User Request\\n${userPrompt}`);\n\n return parts.join(\"\\n\\n\");\n}\n","import type { ChatMessage, ContentPart, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage } from \"./prompts.js\";\n\ninterface OpenAICompatibleRequest {\n model: string;\n messages: Array<{\n role: string;\n content: string | Array<{ type: string; text?: string; image_url?: { url: string } }>;\n }>;\n stream: boolean;\n max_tokens?: number;\n reasoning_effort?: string;\n}\n\nexport async function chatOpenAICompatible(\n provider: string,\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const providerConfig = MODEL_REGISTRY[provider];\n if (!providerConfig) {\n onError(`Unknown provider: ${provider}`);\n return;\n }\n\n const apiBase = providerConfig.apiBase;\n const url = `${apiBase}/chat/completions`;\n\n // Build messages with context\n const apiMessages: OpenAICompatibleRequest[\"messages\"] = [\n { role: \"system\", content: SYSTEM_PROMPT },\n ];\n\n // Add context to the first user message\n for (const msg of messages) {\n if (msg.role === \"user\" && typeof msg.content === \"string\") {\n const contextParts: Parameters<typeof buildUserMessage>[1] = {};\n\n if (context.selectedElement) {\n contextParts.selectedElement = context.selectedElement.outerHTML;\n }\n if (context.files && context.files.length > 0) {\n contextParts.filePath = context.files[0].path;\n contextParts.fileContent = context.files[0].content;\n }\n if (context.projectTree) {\n contextParts.projectTree = context.projectTree;\n }\n if (context.networkLogs) {\n contextParts.networkLogs = context.networkLogs\n .map((l) => `${l.method} ${l.url} → ${l.status || \"pending\"}`)\n .join(\"\\n\");\n }\n if (context.consoleLogs) {\n contextParts.consoleLogs = context.consoleLogs\n .map((l) => `[${l.level}] ${l.args.join(\" \")}`)\n .join(\"\\n\");\n }\n\n const enrichedContent = buildUserMessage(msg.content, contextParts);\n\n // If we have a screenshot and the model supports vision, add it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (context.screenshot && modelInfo?.vision) {\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image_url\",\n image_url: { url: context.screenshot },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else {\n apiMessages.push({\n role: msg.role,\n content: msg.content as string,\n });\n }\n }\n\n const body: OpenAICompatibleRequest = {\n model,\n messages: apiMessages,\n stream: true,\n max_tokens: 4096,\n };\n\n // Add thinking/reasoning config if the model supports it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (modelInfo?.thinking?.supported && modelInfo.thinking.paramType === \"level\") {\n body.reasoning_effort = modelInfo.thinking.defaultLevel || \"medium\";\n // Reasoning models typically need higher max_tokens\n body.max_tokens = Math.min(modelInfo.maxOutput, 16384);\n }\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (provider === \"ollama\") {\n // Ollama doesn't need auth\n } else {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(`Invalid API key for ${providerConfig.name}. Check your key in Settings.`);\n } else if (response.status === 429) {\n onError(`Rate limit exceeded for ${providerConfig.name}. Wait a moment and try again.`);\n } else {\n onError(`${providerConfig.name} API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n // Stream SSE response\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n if (data === \"[DONE]\") continue;\n\n try {\n const parsed = JSON.parse(data);\n const delta = parsed.choices?.[0]?.delta?.content;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage } from \"./prompts.js\";\n\ninterface AnthropicMessage {\n role: \"user\" | \"assistant\";\n content: string | Array<{ type: string; text?: string; source?: { type: string; media_type: string; data: string } }>;\n}\n\nexport async function chatAnthropic(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = \"https://api.anthropic.com/v1/messages\";\n\n const apiMessages: AnthropicMessage[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue; // System prompt goes in system field\n\n if (msg.role === \"user\" && typeof msg.content === \"string\") {\n const contextParts: Parameters<typeof buildUserMessage>[1] = {};\n\n if (context.selectedElement) {\n contextParts.selectedElement = context.selectedElement.outerHTML;\n }\n if (context.files && context.files.length > 0) {\n contextParts.filePath = context.files[0].path;\n contextParts.fileContent = context.files[0].content;\n }\n if (context.projectTree) {\n contextParts.projectTree = context.projectTree;\n }\n if (context.networkLogs) {\n contextParts.networkLogs = context.networkLogs\n .map((l) => `${l.method} ${l.url} → ${l.status || \"pending\"}`)\n .join(\"\\n\");\n }\n if (context.consoleLogs) {\n contextParts.consoleLogs = context.consoleLogs\n .map((l) => `[${l.level}] ${l.args.join(\" \")}`)\n .join(\"\\n\");\n }\n\n const enrichedContent = buildUserMessage(msg.content, contextParts);\n\n // If screenshot available, use vision\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: \"image/png\",\n data: base64Data,\n },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else {\n apiMessages.push({\n role: msg.role as \"user\" | \"assistant\",\n content: msg.content as string,\n });\n }\n }\n\n // Build body with optional extended thinking\n const providerConfig = MODEL_REGISTRY.anthropic;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingBudget = modelInfo?.thinking?.defaultBudget || 0;\n\n const body: Record<string, unknown> = {\n model,\n max_tokens: thinkingBudget > 0 ? Math.max(thinkingBudget + 4096, 16384) : 4096,\n system: SYSTEM_PROMPT,\n messages: apiMessages,\n stream: true,\n };\n\n // Add extended thinking if supported\n if (thinkingBudget > 0) {\n body.thinking = {\n type: \"enabled\",\n budget_tokens: thinkingBudget,\n };\n }\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Anthropic API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Anthropic rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Anthropic API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n if (parsed.type === \"content_block_delta\") {\n const delta = parsed.delta?.text;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage } from \"./prompts.js\";\n\nexport async function chatGoogle(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?key=${apiKey}&alt=sse`;\n\n const contents: Array<{\n role: string;\n parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }>;\n }> = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n const role = msg.role === \"assistant\" ? \"model\" : \"user\";\n\n if (msg.role === \"user\" && typeof msg.content === \"string\") {\n const contextParts: Parameters<typeof buildUserMessage>[1] = {};\n\n if (context.selectedElement) {\n contextParts.selectedElement = context.selectedElement.outerHTML;\n }\n if (context.files && context.files.length > 0) {\n contextParts.filePath = context.files[0].path;\n contextParts.fileContent = context.files[0].content;\n }\n if (context.projectTree) {\n contextParts.projectTree = context.projectTree;\n }\n\n const enrichedContent = buildUserMessage(msg.content, contextParts);\n\n const parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }> = [\n { text: enrichedContent },\n ];\n\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n parts.push({\n inline_data: {\n mime_type: \"image/png\",\n data: base64Data,\n },\n });\n }\n\n contents.push({ role, parts });\n } else {\n contents.push({\n role,\n parts: [{ text: msg.content as string }],\n });\n }\n }\n\n // Check for thinking support\n const providerConfig = MODEL_REGISTRY.google;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingLevel = modelInfo?.thinking?.defaultLevel;\n\n const generationConfig: Record<string, unknown> = {\n maxOutputTokens: 8192,\n };\n\n if (thinkingLevel && thinkingLevel !== \"none\") {\n generationConfig.thinking_level = thinkingLevel.toUpperCase();\n }\n\n const body = {\n system_instruction: {\n parts: [{ text: SYSTEM_PROMPT }],\n },\n contents,\n generationConfig,\n };\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Google API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Google API rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Google API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext, LlmResponse } from \"../shared-types.js\";\nimport { chatOpenAICompatible } from \"./openai.js\";\nimport { chatAnthropic } from \"./anthropic.js\";\nimport { chatGoogle } from \"./google.js\";\n\n// Providers that use OpenAI-compatible API format\nconst OPENAI_COMPATIBLE_PROVIDERS = new Set([\n \"openai\",\n \"deepseek\",\n \"groq\",\n \"mistral\",\n \"xai\",\n \"ollama\",\n \"openrouter\",\n \"minimax\",\n \"moonshot\",\n \"qwen\",\n \"zhipu\",\n \"doubao\",\n]);\n\ninterface LlmChatParams {\n provider: string;\n model: string;\n apiKey: string;\n messages: ChatMessage[];\n context: LlmContext;\n}\n\nexport async function handleLlmChat(\n params: LlmChatParams,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string; modifications?: LlmResponse[\"modifications\"] }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const { provider, model, apiKey, messages, context } = params;\n\n const wrappedOnDone = (result: { content: string }) => {\n // Try to parse modifications from the response\n let modifications: LlmResponse[\"modifications\"] | undefined;\n try {\n // Extract JSON from the response (it might be wrapped in markdown code blocks)\n const jsonMatch = result.content.match(/```json\\s*([\\s\\S]*?)```/) ||\n result.content.match(/\\{[\\s\\S]*\"modifications\"[\\s\\S]*\\}/);\n\n if (jsonMatch) {\n const jsonStr = jsonMatch[1] || jsonMatch[0];\n const parsed = JSON.parse(jsonStr) as LlmResponse;\n modifications = parsed.modifications;\n }\n } catch {\n // If parsing fails, just return the raw content\n }\n\n onDone({ content: result.content, modifications });\n };\n\n try {\n if (provider === \"anthropic\") {\n await chatAnthropic(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (provider === \"google\") {\n await chatGoogle(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (OPENAI_COMPATIBLE_PROVIDERS.has(provider)) {\n await chatOpenAICompatible(\n provider,\n model,\n apiKey,\n messages,\n context,\n onChunk,\n wrappedOnDone,\n onError\n );\n } else {\n onError(`Unsupported provider: ${provider}. Check your Settings.`);\n }\n } catch (e: unknown) {\n const msg = (e as Error).message || \"Unknown error\";\n if (msg.includes(\"fetch\") || msg.includes(\"ECONNREFUSED\") || msg.includes(\"network\")) {\n onError(`Network error: Could not reach the ${provider} API. Check your internet connection.`);\n } else {\n onError(`Unexpected error with ${provider}: ${msg}`);\n }\n }\n}\n","import { createConnection } from \"node:net\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst COMMON_DEV_PORTS = [\n 3000, // React (CRA), Next.js, Express\n 5173, // Vite\n 5174, // Vite (alternate)\n 4200, // Angular\n 8080, // Vue CLI, generic\n 8000, // Django, Python\n 8888, // Jupyter, generic\n 3001, // Common alternate\n 4000, // Phoenix, generic\n 1234, // Parcel\n 4321, // Astro\n 3333, // Remix\n 8081, // Metro (React Native)\n 9000, // generic\n];\n\nfunction checkPort(port: number, host: string = \"127.0.0.1\"): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host, timeout: 500 });\n socket.on(\"connect\", () => {\n socket.destroy();\n resolve(true);\n });\n socket.on(\"error\", () => {\n socket.destroy();\n resolve(false);\n });\n socket.on(\"timeout\", () => {\n socket.destroy();\n resolve(false);\n });\n });\n}\n\nexport interface DetectedServer {\n port: number;\n host: string;\n}\n\nexport async function detectDevServer(): Promise<DetectedServer | null> {\n const checks = COMMON_DEV_PORTS.map(async (port) => {\n const isOpen = await checkPort(port);\n return isOpen ? port : null;\n });\n\n const results = await Promise.all(checks);\n const foundPort = results.find((p) => p !== null);\n\n if (foundPort) {\n return { port: foundPort, host: \"127.0.0.1\" };\n }\n\n return null;\n}\n\nexport async function isPortOpen(port: number): Promise<boolean> {\n return checkPort(port);\n}\n\nexport async function findAvailablePort(startPort: number): Promise<number> {\n let port = startPort;\n while (await isPortOpen(port)) {\n port++;\n if (port > startPort + 100) {\n throw new Error(`Could not find an available port near ${startPort}`);\n }\n }\n return port;\n}\n\n// --- Package.json Dev Script Detection ---\n\nexport interface DevScript {\n name: string; // e.g. \"dev\", \"start\", \"serve\"\n command: string; // e.g. \"next dev\", \"vite\", \"ng serve\"\n framework: string; // e.g. \"Next.js\", \"Vite\", \"Angular\"\n defaultPort: number;\n}\n\nconst FRAMEWORK_PATTERNS: Array<{\n match: RegExp;\n framework: string;\n defaultPort: number;\n}> = [\n { match: /\\bnext\\b/, framework: \"Next.js\", defaultPort: 3000 },\n { match: /\\bvite\\b/, framework: \"Vite\", defaultPort: 5173 },\n { match: /\\bnuxt\\b/, framework: \"Nuxt\", defaultPort: 3000 },\n { match: /\\bng\\s+serve\\b/, framework: \"Angular\", defaultPort: 4200 },\n { match: /\\bvue-cli-service\\s+serve\\b/, framework: \"Vue CLI\", defaultPort: 8080 },\n { match: /\\bsvelte-kit\\b/, framework: \"SvelteKit\", defaultPort: 5173 },\n { match: /\\bastro\\b/, framework: \"Astro\", defaultPort: 4321 },\n { match: /\\bremix\\b/, framework: \"Remix\", defaultPort: 3000 },\n { match: /\\breact-scripts\\s+start\\b/, framework: \"Create React App\", defaultPort: 3000 },\n { match: /\\bparcel\\b/, framework: \"Parcel\", defaultPort: 1234 },\n { match: /\\bwebpack\\s+serve\\b|webpack-dev-server/, framework: \"Webpack\", defaultPort: 8080 },\n { match: /\\bgatsby\\b/, framework: \"Gatsby\", defaultPort: 8000 },\n { match: /\\bturborepo\\b|\\bturbo\\b.*dev/, framework: \"Turborepo\", defaultPort: 3000 },\n { match: /\\bexpo\\b/, framework: \"Expo\", defaultPort: 8081 },\n { match: /\\bnodemon\\b|\\bts-node\\b|\\bnode\\b/, framework: \"Node.js\", defaultPort: 3000 },\n { match: /\\bflask\\b/, framework: \"Flask\", defaultPort: 5000 },\n { match: /\\bdjango\\b|manage\\.py\\s+runserver/, framework: \"Django\", defaultPort: 8000 },\n { match: /\\brails\\b/, framework: \"Rails\", defaultPort: 3000 },\n { match: /\\bphp\\s+.*serve\\b|artisan\\s+serve/, framework: \"PHP/Laravel\", defaultPort: 8000 },\n];\n\nconst DEV_SCRIPT_NAMES = [\"dev\", \"start\", \"serve\", \"develop\", \"dev:start\", \"start:dev\"];\n\nexport function detectDevScripts(cwd: string = process.cwd()): DevScript[] {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return [];\n\n let pkg: any;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n } catch {\n return [];\n }\n\n if (!pkg.scripts) return [];\n\n const scripts: DevScript[] = [];\n\n for (const name of DEV_SCRIPT_NAMES) {\n const command = pkg.scripts[name];\n if (!command) continue;\n\n // Detect framework from command\n let framework = \"Unknown\";\n let defaultPort = 3000;\n\n for (const pattern of FRAMEWORK_PATTERNS) {\n if (pattern.match.test(command)) {\n framework = pattern.framework;\n defaultPort = pattern.defaultPort;\n break;\n }\n }\n\n // Try to extract port from command (e.g., --port 4000, -p 8080)\n const portMatch = command.match(/(?:--port|-p)\\s+(\\d+)/);\n if (portMatch) {\n defaultPort = parseInt(portMatch[1], 10);\n }\n\n scripts.push({ name, command, framework, defaultPort });\n }\n\n return scripts;\n}\n\nexport function getProjectName(cwd: string = process.cwd()): string {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return \"this project\";\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n return pkg.name || \"this project\";\n } catch {\n return \"this project\";\n }\n}\n\n// --- Dependency Installation Check ---\n\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\n\nexport interface DependencyStatus {\n installed: boolean;\n packageManager: PackageManager;\n installCommand: string;\n}\n\nconst LOCK_FILES: Array<{ file: string; pm: PackageManager }> = [\n { file: \"pnpm-lock.yaml\", pm: \"pnpm\" },\n { file: \"yarn.lock\", pm: \"yarn\" },\n { file: \"bun.lockb\", pm: \"bun\" },\n { file: \"bun.lock\", pm: \"bun\" },\n { file: \"package-lock.json\", pm: \"npm\" },\n];\n\nconst INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: \"npm install\",\n yarn: \"yarn install\",\n pnpm: \"pnpm install\",\n bun: \"bun install\",\n};\n\nexport function checkDependenciesInstalled(cwd: string = process.cwd()): DependencyStatus {\n const hasNodeModules = existsSync(join(cwd, \"node_modules\"));\n\n // Detect package manager from lock file\n let pm: PackageManager = \"npm\";\n for (const { file, pm: detectedPm } of LOCK_FILES) {\n if (existsSync(join(cwd, file))) {\n pm = detectedPm;\n break;\n }\n }\n\n return {\n installed: hasNodeModules,\n packageManager: pm,\n installCommand: INSTALL_COMMANDS[pm],\n };\n}\n"],"mappings":"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","names":["resolve","resolve","http","readFileSync","existsSync","join","dirname","readFileSync","writeFileSync","existsSync","mkdirSync","join","modelInfo","dirname","http","join","existsSync","readFileSync","readFileSync","existsSync","join","resolve","join","existsSync","readFileSync","resolve"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/proxy.ts","../src/security.ts","../src/server.ts","../src/config.ts","../src/filesystem.ts","../src/llm/registry.ts","../src/llm/prompts.ts","../src/llm/openai.ts","../src/llm/anthropic.ts","../src/llm/google.ts","../src/llm/proxy.ts","../src/detect.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { resolve } from \"node:path\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\n\n// Suppress http-proxy deprecation warning noise\nconst origEmitWarning = process.emitWarning;\nprocess.emitWarning = function (warning: any, ...args: any[]) {\n if (typeof warning === \"string\" && warning.includes(\"util._extend\")) return;\n return origEmitWarning.call(process, warning, ...args);\n} as typeof process.emitWarning;\n\n// Global error handlers — prevent silent crashes\nprocess.on(\"unhandledRejection\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Unhandled error:\"), (err as Error)?.message || err);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n});\n\nprocess.on(\"uncaughtException\", (err) => {\n console.error(chalk.red(\"\\n [OpenMagic] Fatal error:\"), err.message);\n console.error(chalk.dim(\" Please report this at https://github.com/Kalmuraee/OpenMagic/issues\"));\n process.exit(1);\n});\n\n// Track child processes for cleanup\nconst childProcesses: ChildProcess[] = [];\nimport { createProxyServer } from \"./proxy.js\";\nimport { createOpenMagicServer } from \"./server.js\";\nimport { generateSessionToken } from \"./security.js\";\nimport {\n detectDevServer,\n findAvailablePort,\n isPortOpen,\n detectDevScripts,\n getProjectName,\n checkDependenciesInstalled,\n} from \"./detect.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\n\nconst VERSION = \"0.10.0\";\n\nfunction ask(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nfunction waitForPort(\n port: number,\n timeoutMs: number = 30000,\n shouldAbort?: () => boolean\n): Promise<boolean> {\n const start = Date.now();\n return new Promise((resolve) => {\n const check = async () => {\n if (shouldAbort?.()) {\n resolve(false);\n return;\n }\n if (await isPortOpen(port)) {\n resolve(true);\n return;\n }\n if (Date.now() - start > timeoutMs) {\n resolve(false);\n return;\n }\n setTimeout(check, 500);\n };\n check();\n });\n}\n\nfunction runCommand(cmd: string, args: string[], cwd: string = process.cwd()): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: true,\n });\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().trim().split(\"\\n\");\n for (const line of lines) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n child.on(\"error\", () => resolve(false));\n child.on(\"close\", (code) => resolve(code === 0));\n } catch {\n resolve(false);\n }\n });\n}\n\nasync function healthCheck(proxyPort: number, targetPort: number): Promise<void> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n\n const res = await fetch(`http://127.0.0.1:${proxyPort}/`, {\n signal: controller.signal,\n headers: { Accept: \"text/html\" },\n });\n clearTimeout(timeout);\n\n if (res.ok) {\n const text = await res.text();\n if (text.includes(\"__OPENMAGIC_LOADED__\")) {\n console.log(chalk.green(\" ✓ Toolbar injection verified.\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Page loaded but toolbar may not have injected (non-HTML response or CSP).\"));\n }\n } else {\n console.log(\n chalk.yellow(` ⚠ Dev server returned ${res.status}. Pages may have errors.`)\n );\n console.log(\n chalk.dim(\" The toolbar will still appear on pages that load successfully.\")\n );\n }\n } catch {\n console.log(\n chalk.yellow(\" ⚠ Could not verify proxy. The dev server may still be starting.\")\n );\n console.log(\n chalk.dim(\" Try refreshing the page in a few seconds.\")\n );\n }\n console.log(\"\");\n}\n\n// Detect common dev server errors and show hints\nfunction formatDevServerLine(line: string): string {\n const trimmed = line.trim();\n if (!trimmed) return \"\";\n\n // Detect error patterns and add context\n if (trimmed.startsWith(\"Error:\") || trimmed.includes(\"ModuleNotFoundError\") || trimmed.includes(\"Can't resolve\")) {\n return chalk.red(` │ ${trimmed}`);\n }\n if (trimmed.includes(\"EADDRINUSE\") || trimmed.includes(\"address already in use\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Port is already in use. Stop the other process or use --port <different-port>\");\n }\n if (trimmed.includes(\"EACCES\") || trimmed.includes(\"permission denied\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Permission denied. Try a different port or check file permissions.\");\n }\n if (trimmed.includes(\"Cannot find module\") || trimmed.includes(\"MODULE_NOT_FOUND\")) {\n return chalk.red(` │ ${trimmed}`) + \"\\n\" +\n chalk.yellow(\" │ → Missing dependency. Try running npm install.\");\n }\n\n return chalk.dim(` │ ${trimmed}`);\n}\n\nconst program = new Command();\n\nprogram\n .name(\"openmagic\")\n .description(\"AI-powered coding toolbar for any web application\")\n .version(VERSION)\n .option(\"-p, --port <port>\", \"Dev server port to proxy\", \"\")\n .option(\n \"-l, --listen <port>\",\n \"Port for the OpenMagic proxy\",\n \"4567\"\n )\n .option(\n \"-r, --root <paths...>\",\n \"Project root directories (defaults to cwd)\"\n )\n .option(\"--no-open\", \"Don't auto-open browser\")\n .option(\"--host <host>\", \"Dev server host\", \"127.0.0.1\")\n .action(async (opts) => {\n console.log(\"\");\n console.log(\n chalk.bold.magenta(\" ✨ OpenMagic\") + chalk.dim(` v${VERSION}`)\n );\n console.log(\"\");\n\n let targetPort: number;\n let targetHost = opts.host;\n\n if (opts.port) {\n // User specified a port\n targetPort = parseInt(opts.port, 10);\n const isRunning = await isPortOpen(targetPort);\n if (!isRunning) {\n // Port specified but not running — offer to start it\n const started = await offerToStartDevServer(targetPort);\n if (!started) {\n process.exit(1);\n }\n // Re-detect in case server started on a different port\n const recheck = await detectDevServer();\n if (recheck) { targetPort = recheck.port; targetHost = recheck.host; }\n }\n } else {\n // Auto-detect running dev server\n console.log(chalk.dim(\" Scanning for dev server...\"));\n const detected = await detectDevServer();\n\n if (detected) {\n targetPort = detected.port;\n targetHost = detected.host;\n } else {\n // No server running — try to detect and start from package.json\n const started = await offerToStartDevServer();\n if (!started) {\n process.exit(1);\n }\n // Re-detect after starting\n const redetected = await detectDevServer();\n if (!redetected) {\n console.log(chalk.red(\" ✗ Could not detect the dev server after starting.\"));\n console.log(chalk.dim(\" Try specifying the port: npx openmagic --port 3000\"));\n console.log(\"\");\n process.exit(1);\n }\n targetPort = redetected.port;\n targetHost = redetected.host;\n }\n }\n\n console.log(\n chalk.green(` ✓ Dev server running at ${targetHost}:${targetPort}`)\n );\n\n // Set up roots\n const roots = (opts.root || [process.cwd()]).map((r: string) =>\n resolve(r)\n );\n\n // Save roots to config\n const config = loadConfig();\n saveConfig({ ...config, roots, targetPort });\n\n // Generate session token\n const token = generateSessionToken();\n\n // Find available proxy port (need TWO consecutive free ports: proxy + companion)\n let proxyPort = parseInt(opts.listen, 10);\n while (await isPortOpen(proxyPort) || await isPortOpen(proxyPort + 1)) {\n proxyPort++;\n if (proxyPort > parseInt(opts.listen, 10) + 100) {\n console.log(chalk.red(\" Could not find two consecutive free ports.\"));\n process.exit(1);\n }\n }\n\n const companionPort = proxyPort + 1;\n\n // Start the OpenMagic server (serves toolbar + WebSocket)\n const { httpServer: omServer } = createOpenMagicServer(companionPort, roots);\n omServer.listen(companionPort, \"127.0.0.1\", () => {\n // OpenMagic API/WS server running\n });\n\n // Start the proxy server\n const proxyServer = createProxyServer(\n targetHost,\n targetPort!,\n companionPort\n );\n\n proxyServer.listen(proxyPort, \"127.0.0.1\", async () => {\n console.log(\"\");\n console.log(\n chalk.bold.green(` 🚀 Proxy running at → `) +\n chalk.bold.underline.cyan(`http://localhost:${proxyPort}`)\n );\n console.log(\"\");\n\n // Health check — verify the proxy can reach the dev server\n await healthCheck(proxyPort, targetPort!);\n\n console.log(\n chalk.dim(\" Open the URL above in your browser to start.\")\n );\n console.log(chalk.dim(\" Press Ctrl+C to stop.\"));\n console.log(\n chalk.dim(\" Errors below are from your dev server, not OpenMagic.\")\n );\n console.log(\"\");\n\n if (opts.open !== false) {\n open(`http://localhost:${proxyPort}`).catch(() => {});\n }\n });\n\n // Handle WebSocket upgrades for OpenMagic\n proxyServer.on(\"upgrade\", (req, socket, head) => {\n if (req.url?.startsWith(\"/__openmagic__\")) {\n omServer.emit(\"upgrade\", req, socket, head);\n }\n });\n\n // Graceful shutdown\n const shutdown = () => {\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n proxyServer.close();\n omServer.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n });\n\n// --- Smart Dev Server Start ---\n\nasync function offerToStartDevServer(expectedPort?: number): Promise<boolean> {\n const projectName = getProjectName();\n const scripts = detectDevScripts();\n\n if (scripts.length === 0) {\n console.log(\n chalk.yellow(\" ⚠ No dev server detected and no dev scripts found in package.json\")\n );\n console.log(\"\");\n console.log(chalk.white(\" Start your dev server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // Check if dependencies are installed\n const deps = checkDependenciesInstalled();\n if (!deps.installed) {\n console.log(\n chalk.yellow(\" ⚠ node_modules/ not found. Dependencies need to be installed.\")\n );\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Run `) +\n chalk.cyan(deps.installCommand) +\n chalk.white(\"? \") +\n chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(` Run ${deps.installCommand} manually, then try again.`));\n console.log(\"\");\n return false;\n }\n\n console.log(\"\");\n console.log(chalk.dim(` Installing dependencies with ${deps.packageManager}...`));\n\n const [installCmd, ...installArgs] = deps.installCommand.split(\" \");\n const installed = await runCommand(installCmd, installArgs);\n\n if (!installed) {\n console.log(chalk.red(\" ✗ Dependency installation failed.\"));\n console.log(chalk.dim(` Try running ${deps.installCommand} manually.`));\n console.log(\"\");\n return false;\n }\n\n console.log(chalk.green(\" ✓ Dependencies installed.\"));\n console.log(\"\");\n }\n\n // Pick the best script\n let chosen = scripts[0];\n if (scripts.length === 1) {\n // Only one option\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n chalk.white(` in ${projectName}`) +\n chalk.dim(` (${chosen.framework})`)\n );\n console.log(chalk.dim(` → ${chosen.command}`));\n console.log(\"\");\n\n const answer = await ask(\n chalk.white(` Start it now? `) + chalk.dim(\"(Y/n) \")\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n } else {\n // Multiple scripts — let user pick\n console.log(\n chalk.yellow(\" ⚠ No dev server detected.\")\n );\n console.log(\"\");\n console.log(\n chalk.white(` Found ${scripts.length} dev scripts in ${projectName}:`)\n );\n console.log(\"\");\n\n scripts.forEach((s, i) => {\n console.log(\n chalk.cyan(` ${i + 1}) `) +\n chalk.white(`npm run ${s.name}`) +\n chalk.dim(` — ${s.framework} (port ${s.defaultPort})`)\n );\n console.log(chalk.dim(` ${s.command}`));\n });\n\n console.log(\"\");\n const answer = await ask(\n chalk.white(` Which one to start? `) +\n chalk.dim(`(1-${scripts.length}, or n to cancel) `)\n );\n\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\" || answer === \"\") {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server first, then run openmagic again.\"));\n console.log(\"\");\n return false;\n }\n\n const idx = parseInt(answer, 10) - 1;\n if (idx < 0 || idx >= scripts.length || isNaN(idx)) {\n // Default to first\n chosen = scripts[0];\n } else {\n chosen = scripts[idx];\n }\n }\n\n // Start the dev server\n const port = expectedPort || chosen.defaultPort;\n\n console.log(\"\");\n console.log(\n chalk.dim(` Starting `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n chalk.dim(\"...\")\n );\n\n // Use the correct package manager run command\n const depsInfo = checkDependenciesInstalled();\n const runCmd = depsInfo.packageManager === \"yarn\" ? \"yarn\" :\n depsInfo.packageManager === \"pnpm\" ? \"pnpm\" :\n depsInfo.packageManager === \"bun\" ? \"bun\" : \"npm\";\n const runArgs = runCmd === \"npm\" ? [\"run\", chosen.name] : [chosen.name];\n\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(runCmd, runArgs, {\n cwd: process.cwd(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: false,\n shell: true,\n env: {\n ...process.env,\n PORT: String(port),\n BROWSER: \"none\",\n BROWSER_NONE: \"true\",\n },\n });\n } catch (e: unknown) {\n console.log(chalk.red(` ✗ Failed to start: ${(e as Error).message}`));\n return false;\n }\n\n childProcesses.push(child);\n let childExited = false;\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n for (const line of data.toString().trim().split(\"\\n\")) {\n const formatted = formatDevServerLine(line);\n if (formatted) process.stdout.write(formatted + \"\\n\");\n }\n });\n\n child.stderr?.on(\"data\", (data: Buffer) => {\n for (const line of data.toString().trim().split(\"\\n\")) {\n const formatted = formatDevServerLine(line);\n if (formatted) process.stdout.write(formatted + \"\\n\");\n }\n });\n\n child.on(\"error\", (err) => {\n childExited = true;\n console.log(chalk.red(` ✗ Failed to start: ${err.message}`));\n });\n\n child.on(\"exit\", (code) => {\n childExited = true;\n if (code !== null && code !== 0) {\n console.log(chalk.red(` ✗ Dev server exited with code ${code}`));\n }\n });\n\n // Clean up all child processes on exit\n const cleanup = () => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGTERM\"); } catch {}\n }\n setTimeout(() => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGKILL\"); } catch {}\n }\n }, 3000);\n };\n process.on(\"exit\", cleanup);\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Wait for the port to open (abort early if child exits)\n console.log(\n chalk.dim(` Waiting for port ${port}...`)\n );\n\n const isUp = await waitForPort(port, 30000, () => childExited);\n\n if (childExited && !isUp) {\n console.log(\n chalk.red(` ✗ Dev server exited before it was ready.`)\n );\n console.log(\n chalk.dim(` Check the error output above and fix the issue.`)\n );\n console.log(\"\");\n return false;\n }\n\n if (!isUp) {\n console.log(\n chalk.yellow(` ⚠ Port ${port} didn't open after 30s.`)\n );\n console.log(\n chalk.dim(` The server might use a different port. Check the output above.`)\n );\n console.log(\"\");\n\n // Try to detect any port that opened\n const detected = await detectDevServer();\n if (detected) {\n console.log(\n chalk.green(` ✓ Found server on port ${detected.port} instead.`)\n );\n return true;\n }\n\n return false;\n }\n\n console.log(\"\");\n return true;\n}\n\nprogram.parse();\n","import http from \"node:http\";\nimport { gunzip, inflate, brotliDecompress } from \"node:zlib\";\nimport { promisify } from \"node:util\";\nimport httpProxy from \"http-proxy\";\n\nconst gunzipAsync = promisify(gunzip);\nconst inflateAsync = promisify(inflate);\nconst brotliAsync = promisify(brotliDecompress);\nimport { getSessionToken } from \"./security.js\";\n\nexport function createProxyServer(\n targetHost: string,\n targetPort: number,\n serverPort: number\n): http.Server {\n const proxy = httpProxy.createProxyServer({\n target: `http://${targetHost}:${targetPort}`,\n ws: true,\n selfHandleResponse: true,\n });\n\n const token = getSessionToken();\n\n proxy.on(\"proxyRes\", (proxyRes, req, res) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isHtml = contentType.includes(\"text/html\");\n\n if (!isHtml) {\n // Pass through non-HTML responses unchanged\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n // For HTML responses, collect the body, decompress if needed, and inject toolbar\n collectBody(proxyRes)\n .then((body) => {\n // Inject toolbar script before </body> or at end\n const toolbarScript = buildInjectionScript(serverPort, token);\n if (body.includes(\"</body>\")) {\n body = body.replace(\"</body>\", `${toolbarScript}</body>`);\n } else if (body.includes(\"</html>\")) {\n body = body.replace(\"</html>\", `${toolbarScript}</html>`);\n } else {\n body += toolbarScript;\n }\n\n // Send uncompressed response (we decoded it)\n const headers = { ...proxyRes.headers };\n delete headers[\"content-length\"];\n delete headers[\"content-encoding\"];\n delete headers[\"transfer-encoding\"];\n delete headers[\"content-security-policy\"];\n delete headers[\"content-security-policy-report-only\"];\n delete headers[\"x-content-security-policy\"];\n delete headers[\"etag\"];\n delete headers[\"last-modified\"];\n\n res.writeHead(proxyRes.statusCode || 200, headers);\n res.end(body);\n })\n .catch(() => {\n // If decompression/collection fails, proxy the raw response\n // This ensures the app still works even if injection fails\n try {\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end();\n } catch {\n // Response already sent or connection closed\n }\n });\n });\n\n proxy.on(\"error\", (err, _req, res) => {\n if (res instanceof http.ServerResponse && !res.headersSent) {\n const toolbarScript = buildInjectionScript(serverPort, token);\n res.writeHead(502, { \"Content-Type\": \"text/html\" });\n res.end(\n `<html><body style=\"font-family:system-ui;padding:40px;background:#1a1a2e;color:#e0e0e0;\">\n <h2 style=\"color:#e94560;\">OpenMagic — Cannot connect to dev server</h2>\n <p>Could not reach <code>${targetHost}:${targetPort}</code></p>\n <p style=\"color:#888;\">Make sure your dev server is running, then refresh this page.</p>\n <p style=\"color:#666;font-size:13px;\">${err.message}</p>\n ${toolbarScript}\n </body></html>`\n );\n }\n });\n\n const server = http.createServer((req, res) => {\n if (req.url?.startsWith(\"/__openmagic__/\")) {\n handleToolbarAsset(req, res, serverPort);\n return;\n }\n proxy.web(req, res);\n });\n\n server.on(\"upgrade\", (req, socket, head) => {\n if (req.url?.startsWith(\"/__openmagic__\")) {\n return;\n }\n proxy.ws(req, socket, head);\n });\n\n return server;\n}\n\nasync function collectBody(stream: http.IncomingMessage): Promise<string> {\n // Buffer raw data first, then decompress — avoids consumed-stream problem\n const rawBuffer = await new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n stream.on(\"end\", () => resolve(Buffer.concat(chunks)));\n stream.on(\"error\", reject);\n });\n\n const encoding = (stream.headers[\"content-encoding\"] || \"\").toLowerCase();\n\n if (!encoding || encoding === \"identity\") {\n return rawBuffer.toString(\"utf-8\");\n }\n\n // Try decompression — fall back to raw on failure\n try {\n let decompressed: Buffer;\n if (encoding === \"gzip\" || encoding === \"x-gzip\") {\n decompressed = await gunzipAsync(rawBuffer);\n } else if (encoding === \"deflate\") {\n decompressed = await inflateAsync(rawBuffer);\n } else if (encoding === \"br\") {\n decompressed = await brotliAsync(rawBuffer);\n } else {\n return rawBuffer.toString(\"utf-8\");\n }\n return decompressed.toString(\"utf-8\");\n } catch {\n // Decompression failed — try raw (might be uncompressed despite header)\n return rawBuffer.toString(\"utf-8\");\n }\n}\n\nfunction handleToolbarAsset(\n _req: http.IncomingMessage,\n res: http.ServerResponse,\n _serverPort: number\n): void {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not found\");\n}\n\nfunction buildInjectionScript(serverPort: number, token: string): string {\n return `\n<script data-openmagic=\"true\">\n(function() {\n if (window.__OPENMAGIC_LOADED__) return;\n window.__OPENMAGIC_LOADED__ = true;\n window.__OPENMAGIC_CONFIG__ = {\n wsPort: ${serverPort},\n token: \"${token}\"\n };\n var script = document.createElement(\"script\");\n script.src = \"http://127.0.0.1:${serverPort}/__openmagic__/toolbar.js\";\n script.dataset.openmagic = \"true\";\n document.body.appendChild(script);\n})();\n</script>`;\n}\n","import { randomBytes } from \"node:crypto\";\n\nlet sessionToken: string | null = null;\n\nexport function generateSessionToken(): string {\n sessionToken = randomBytes(32).toString(\"hex\");\n return sessionToken;\n}\n\nexport function getSessionToken(): string {\n if (!sessionToken) {\n return generateSessionToken();\n }\n return sessionToken;\n}\n\nexport function validateToken(token: string): boolean {\n return token === sessionToken;\n}\n","import http from \"node:http\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { WebSocketServer, WebSocket } from \"ws\";\nimport { validateToken } from \"./security.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { readFileSafe, writeFileSafe, listFiles, getProjectTree } from \"./filesystem.js\";\nimport type {\n WsMessage,\n HandshakePayload,\n FsReadPayload,\n FsWritePayload,\n FsListPayload,\n LlmChatPayload,\n ConfigSetPayload,\n OpenMagicConfig,\n} from \"./shared-types.js\";\nimport { handleLlmChat } from \"./llm/proxy.js\";\nimport { MODEL_REGISTRY } from \"./llm/registry.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\ninterface ClientState {\n authenticated: boolean;\n}\n\nexport function createOpenMagicServer(\n proxyPort: number,\n roots: string[]\n): { httpServer: http.Server; wss: WebSocketServer } {\n const httpServer = http.createServer((req, res) => {\n // Serve toolbar bundle\n if (req.url === \"/__openmagic__/toolbar.js\") {\n serveToolbarBundle(res);\n return;\n }\n\n // Health check\n if (req.url === \"/__openmagic__/health\") {\n res.writeHead(200, {\n \"Content-Type\": \"application/json\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(JSON.stringify({ status: \"ok\", version: \"0.10.0\" }));\n return;\n }\n\n res.writeHead(404);\n res.end(\"Not found\");\n });\n\n const wss = new WebSocketServer({\n server: httpServer,\n path: \"/__openmagic__/ws\",\n });\n\n const clientStates = new WeakMap<WebSocket, ClientState>();\n\n wss.on(\"connection\", (ws, req) => {\n // Validate Origin — only allow localhost connections\n const origin = req.headers.origin || \"\";\n if (origin && !origin.startsWith(\"http://localhost\") && !origin.startsWith(\"http://127.0.0.1\")) {\n ws.close(4003, \"Forbidden origin\");\n return;\n }\n clientStates.set(ws, { authenticated: false });\n\n ws.on(\"message\", async (data) => {\n let msg: WsMessage;\n try {\n msg = JSON.parse(data.toString());\n } catch {\n sendError(ws, \"parse_error\", \"Invalid JSON\");\n return;\n }\n\n const state = clientStates.get(ws)!;\n\n // Require handshake first\n if (!state.authenticated && msg.type !== \"handshake\") {\n sendError(ws, \"auth_required\", \"Handshake required\");\n return;\n }\n\n try {\n await handleMessage(ws, msg, state, roots, proxyPort);\n } catch (e: unknown) {\n sendError(ws, \"internal_error\", (e as Error).message, msg.id);\n }\n });\n\n ws.on(\"close\", () => {\n clientStates.delete(ws);\n });\n });\n\n return { httpServer, wss };\n}\n\nasync function handleMessage(\n ws: WebSocket,\n msg: WsMessage,\n state: ClientState,\n roots: string[],\n _proxyPort: number\n): Promise<void> {\n switch (msg.type) {\n case \"handshake\": {\n const payload = msg.payload as HandshakePayload;\n if (!payload?.token) {\n sendError(ws, \"invalid_payload\", \"Missing token in handshake\", msg.id);\n ws.close();\n return;\n }\n if (!validateToken(payload.token)) {\n sendError(ws, \"auth_failed\", \"Invalid token\", msg.id);\n ws.close();\n return;\n }\n state.authenticated = true;\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"handshake.ok\",\n payload: {\n version: \"0.10.0\",\n roots,\n config: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n },\n },\n });\n break;\n }\n\n case \"fs.read\": {\n const payload = msg.payload as FsReadPayload;\n if (!payload?.path) {\n sendError(ws, \"invalid_payload\", \"Missing path\", msg.id);\n break;\n }\n const result = readFileSafe(payload.path, roots);\n if (\"error\" in result) {\n sendError(ws, \"fs_error\", result.error, msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.content\",\n payload: { path: payload.path, content: result.content },\n });\n }\n break;\n }\n\n case \"fs.write\": {\n const payload = msg.payload as FsWritePayload;\n const result = writeFileSafe(payload.path, payload.content, roots);\n send(ws, {\n id: msg.id,\n type: \"fs.written\",\n payload: { path: payload.path, ok: result.ok, error: result.error },\n });\n break;\n }\n\n case \"fs.list\": {\n const payload = msg.payload as FsListPayload | undefined;\n const root = payload?.root || roots[0];\n const files = listFiles(root, roots);\n send(ws, {\n id: msg.id,\n type: \"fs.tree\",\n payload: { files, projectTree: getProjectTree(roots) },\n });\n break;\n }\n\n case \"llm.chat\": {\n const payload = msg.payload as LlmChatPayload;\n const config = loadConfig();\n\n const providerMeta = MODEL_REGISTRY?.[payload.provider || config.provider || \"\"];\n if (!config.apiKey && !providerMeta?.local) {\n sendError(ws, \"config_error\", \"API key not configured\", msg.id);\n return;\n }\n\n await handleLlmChat(\n {\n provider: payload.provider || config.provider || \"openai\",\n model: payload.model || config.model || \"gpt-4o\",\n apiKey: config.apiKey,\n messages: payload.messages,\n context: payload.context,\n },\n (chunk) => {\n send(ws, { id: msg.id, type: \"llm.chunk\", payload: { delta: chunk } });\n },\n (result) => {\n send(ws, { id: msg.id, type: \"llm.done\", payload: result });\n },\n (error) => {\n send(ws, { id: msg.id, type: \"llm.error\", payload: { message: error } });\n }\n );\n break;\n }\n\n case \"config.get\": {\n const config = loadConfig();\n send(ws, {\n id: msg.id,\n type: \"config.value\",\n payload: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n roots: config.roots || roots,\n },\n });\n break;\n }\n\n case \"config.set\": {\n const payload = msg.payload as ConfigSetPayload;\n const updates: Partial<OpenMagicConfig> = {};\n if (payload.provider !== undefined) updates.provider = payload.provider;\n if (payload.model !== undefined) updates.model = payload.model;\n if (payload.apiKey !== undefined) updates.apiKey = payload.apiKey;\n // roots are set by CLI only, not browser-configurable\n saveConfig(updates);\n send(ws, {\n id: msg.id,\n type: \"config.saved\",\n payload: { ok: true },\n });\n break;\n }\n\n default:\n sendError(ws, \"unknown_type\", `Unknown message type: ${msg.type}`, msg.id);\n }\n}\n\nfunction send(ws: WebSocket, msg: WsMessage): void {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n}\n\nfunction sendError(\n ws: WebSocket,\n code: string,\n message: string,\n id?: string\n): void {\n send(ws, {\n id: id || \"error\",\n type: \"error\",\n payload: { code, message },\n });\n}\n\nfunction serveToolbarBundle(res: http.ServerResponse): void {\n // Try to serve the pre-built toolbar bundle\n const bundlePaths = [\n join(__dirname, \"toolbar\", \"index.global.js\"),\n join(__dirname, \"..\", \"dist\", \"toolbar\", \"index.global.js\"),\n ];\n\n for (const bundlePath of bundlePaths) {\n try {\n if (existsSync(bundlePath)) {\n const content = readFileSync(bundlePath, \"utf-8\");\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n \"Cache-Control\": \"no-cache\",\n });\n res.end(content);\n return;\n }\n } catch {\n // Permission error or read failure — try next path\n continue;\n }\n }\n\n // Fallback: serve a minimal placeholder that shows a \"build required\" message\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(`\n (function() {\n var div = document.createElement(\"div\");\n div.style.cssText = \"position:fixed;bottom:20px;right:20px;background:#1a1a2e;color:#e94560;padding:16px 24px;border-radius:12px;font-family:system-ui;font-size:14px;z-index:2147483647;box-shadow:0 4px 24px rgba(0,0,0,0.3);\";\n div.textContent = \"OpenMagic: Toolbar bundle not found. Run 'npm run build:toolbar' first.\";\n document.body.appendChild(div);\n })();\n `);\n}\n","import { readFileSync, writeFileSync, renameSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { OpenMagicConfig } from \"./shared-types.js\";\n\nconst CONFIG_DIR = join(homedir(), \".openmagic\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nfunction ensureConfigDir(): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\nexport function loadConfig(): Partial<OpenMagicConfig> {\n ensureConfigDir();\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n try {\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(updates: Partial<OpenMagicConfig>): void {\n try {\n ensureConfigDir();\n const existing = loadConfig();\n const merged = { ...existing, ...updates };\n const tmpFile = CONFIG_FILE + \".tmp\";\n writeFileSync(tmpFile, JSON.stringify(merged, null, 2), { encoding: \"utf-8\", mode: 0o600 });\n renameSync(tmpFile, CONFIG_FILE);\n } catch (e: unknown) {\n console.warn(`[OpenMagic] Warning: Could not save config to ${CONFIG_FILE}: ${(e as Error).message}`);\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","import {\n readFileSync,\n writeFileSync,\n existsSync,\n statSync,\n readdirSync,\n copyFileSync,\n mkdirSync,\n} from \"node:fs\";\nimport { join, resolve, relative, dirname, extname } from \"node:path\";\nimport type { FileEntry } from \"./shared-types.js\";\n\nconst IGNORED_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \".nuxt\",\n \".svelte-kit\",\n \"dist\",\n \"build\",\n \".cache\",\n \".turbo\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \".DS_Store\",\n]);\n\nconst IGNORED_EXTENSIONS = new Set([\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".ico\",\n \".webp\",\n \".mp4\",\n \".mp3\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".lock\",\n]);\n\nexport function isPathSafe(filePath: string, roots: string[]): boolean {\n const resolved = resolve(filePath);\n return roots.some((root) => {\n const resolvedRoot = resolve(root);\n const rel = relative(resolvedRoot, resolved);\n return !rel.startsWith(\"..\") && !rel.startsWith(\"/\") && !rel.startsWith(\"\\\\\");\n });\n}\n\nexport function readFileSafe(\n filePath: string,\n roots: string[]\n): { content: string } | { error: string } {\n if (!isPathSafe(filePath, roots)) {\n return { error: \"Path is outside allowed roots\" };\n }\n if (!existsSync(filePath)) {\n return { error: \"File not found\" };\n }\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return { content };\n } catch (e: unknown) {\n return { error: `Failed to read file: ${(e as Error).message}` };\n }\n}\n\nexport function writeFileSafe(\n filePath: string,\n content: string,\n roots: string[]\n): { ok: boolean; error?: string; backupPath?: string } {\n if (!isPathSafe(filePath, roots)) {\n return { ok: false, error: \"Path is outside allowed roots\" };\n }\n\n try {\n // Create backup\n let backupPath: string | undefined;\n if (existsSync(filePath)) {\n backupPath = filePath + \".openmagic-backup\";\n copyFileSync(filePath, backupPath);\n }\n\n // Ensure directory exists\n const dir = dirname(filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(filePath, content, \"utf-8\");\n return { ok: true, backupPath };\n } catch (e: unknown) {\n return { ok: false, error: `Failed to write file: ${(e as Error).message}` };\n }\n}\n\nexport function listFiles(\n rootPath: string,\n roots: string[],\n maxDepth: number = 4\n): FileEntry[] {\n if (!isPathSafe(rootPath, roots)) {\n return [];\n }\n\n const entries: FileEntry[] = [];\n\n function walk(dir: string, depth: number): void {\n if (depth > maxDepth) return;\n\n let items: string[];\n try {\n items = readdirSync(dir);\n } catch {\n return;\n }\n\n for (const item of items) {\n if (IGNORED_DIRS.has(item)) continue;\n if (item.startsWith(\".\") && item !== \".env.example\") continue;\n\n const fullPath = join(dir, item);\n let stat;\n try {\n stat = statSync(fullPath);\n } catch {\n continue;\n }\n\n const relPath = relative(rootPath, fullPath);\n\n if (stat.isDirectory()) {\n entries.push({ path: relPath, type: \"dir\", name: item });\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!IGNORED_EXTENSIONS.has(ext)) {\n entries.push({ path: relPath, type: \"file\", name: item });\n }\n }\n }\n }\n\n walk(rootPath, 0);\n return entries;\n}\n\nexport function getProjectTree(roots: string[]): string {\n const lines: string[] = [];\n for (const root of roots) {\n lines.push(`[${root}]`);\n const files = listFiles(root, roots, 3);\n for (const f of files) {\n const indent = f.path.split(\"/\").length - 1;\n const prefix = \" \".repeat(indent);\n const icon = f.type === \"dir\" ? \"/\" : \"\";\n lines.push(`${prefix}${f.name}${icon}`);\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n}\n","import type { ProviderRegistry } from \"../shared-types.js\";\n\nexport const MODEL_REGISTRY: ProviderRegistry = {\n // ─── OpenAI ───────────────────────────────────────────────────\n openai: {\n name: \"OpenAI\",\n models: [\n // GPT-5.4 family (March 2026 — latest flagship)\n {\n id: \"gpt-5.4\",\n name: \"GPT-5.4\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-pro\",\n name: \"GPT-5.4 Pro\",\n vision: true,\n context: 1050000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.4-mini\",\n name: \"GPT-5.4 Mini\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-nano\",\n name: \"GPT-5.4 Nano\",\n vision: true,\n context: 400000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n // GPT-5.2 family (reasoning-focused)\n {\n id: \"gpt-5.2\",\n name: \"GPT-5.2 Thinking\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n {\n id: \"gpt-5.2-pro\",\n name: \"GPT-5.2 Pro\",\n vision: true,\n context: 272000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n defaultLevel: \"high\",\n },\n },\n // o-series reasoning models\n {\n id: \"o3\",\n name: \"o3 (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"o4-mini\",\n name: \"o4-mini (Reasoning)\",\n vision: true,\n context: 200000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // GPT-4.1 family\n {\n id: \"gpt-4.1\",\n name: \"GPT-4.1\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-mini\",\n name: \"GPT-4.1 Mini\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n {\n id: \"gpt-4.1-nano\",\n name: \"GPT-4.1 Nano\",\n vision: true,\n context: 1047576,\n maxOutput: 32768,\n },\n // Codex\n {\n id: \"codex-mini-latest\",\n name: \"Codex Mini\",\n vision: false,\n context: 192000,\n maxOutput: 100000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.openai.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Anthropic ────────────────────────────────────────────────\n anthropic: {\n name: \"Anthropic\",\n models: [\n // Claude 4.6 (latest — Feb 2026)\n {\n id: \"claude-opus-4-6\",\n name: \"Claude Opus 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 128000,\n },\n },\n {\n id: \"claude-sonnet-4-6\",\n name: \"Claude Sonnet 4.6\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n // Claude 4.5\n {\n id: \"claude-haiku-4-5-20251001\",\n name: \"Claude Haiku 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 5000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Sonnet 4.5\",\n vision: true,\n context: 1000000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-5-20251101\",\n name: \"Claude Opus 4.5\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 64000,\n },\n },\n // Claude 4.0\n {\n id: \"claude-sonnet-4-20250514\",\n name: \"Claude Sonnet 4\",\n vision: true,\n context: 200000,\n maxOutput: 64000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 8000,\n maxBudget: 64000,\n },\n },\n {\n id: \"claude-opus-4-20250514\",\n name: \"Claude Opus 4\",\n vision: true,\n context: 200000,\n maxOutput: 32000,\n thinking: {\n supported: true,\n paramName: \"budget_tokens\",\n paramType: \"budget\",\n defaultBudget: 10000,\n maxBudget: 32000,\n },\n },\n ],\n apiBase: \"https://api.anthropic.com/v1\",\n keyPrefix: \"sk-ant-\",\n keyPlaceholder: \"sk-ant-...\",\n },\n\n // ─── Google Gemini ────────────────────────────────────────────\n google: {\n name: \"Google Gemini\",\n models: [\n // Gemini 3.1 (latest — Feb-Mar 2026)\n {\n id: \"gemini-3.1-pro-preview\",\n name: \"Gemini 3.1 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n // Gemini 3.0\n {\n id: \"gemini-3-flash-preview\",\n name: \"Gemini 3 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-3.1-flash-lite-preview\",\n name: \"Gemini 3.1 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n // Gemini 2.5\n {\n id: \"gemini-2.5-pro\",\n name: \"Gemini 2.5 Pro\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"gemini-2.5-flash\",\n name: \"Gemini 2.5 Flash\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n thinking: {\n supported: true,\n paramName: \"thinking_level\",\n paramType: \"level\",\n levels: [\"none\", \"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"gemini-2.5-flash-lite\",\n name: \"Gemini 2.5 Flash Lite\",\n vision: true,\n context: 1048576,\n maxOutput: 65536,\n },\n ],\n apiBase: \"https://generativelanguage.googleapis.com/v1beta\",\n keyPrefix: \"AI\",\n keyPlaceholder: \"AIza...\",\n },\n\n // ─── xAI (Grok) ──────────────────────────────────────────────\n xai: {\n name: \"xAI (Grok)\",\n models: [\n {\n id: \"grok-4.20-0309-reasoning\",\n name: \"Grok 4.20 Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"grok-4.20-0309-non-reasoning\",\n name: \"Grok 4.20\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n {\n id: \"grok-4-1-fast-reasoning\",\n name: \"Grok 4.1 Fast Reasoning\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"low\",\n },\n },\n {\n id: \"grok-4-1-fast-non-reasoning\",\n name: \"Grok 4.1 Fast\",\n vision: true,\n context: 2000000,\n maxOutput: 128000,\n },\n ],\n apiBase: \"https://api.x.ai/v1\",\n keyPrefix: \"xai-\",\n keyPlaceholder: \"xai-...\",\n },\n\n // ─── DeepSeek ─────────────────────────────────────────────────\n deepseek: {\n name: \"DeepSeek\",\n models: [\n {\n id: \"deepseek-chat\",\n name: \"DeepSeek V3.2\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n },\n {\n id: \"deepseek-reasoner\",\n name: \"DeepSeek R1\",\n vision: false,\n context: 128000,\n maxOutput: 8192,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.deepseek.com/v1\",\n keyPrefix: \"sk-\",\n keyPlaceholder: \"sk-...\",\n },\n\n // ─── Mistral ──────────────────────────────────────────────────\n mistral: {\n name: \"Mistral\",\n models: [\n {\n id: \"mistral-large-3-25-12\",\n name: \"Mistral Large 3\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-4-0-26-03\",\n name: \"Mistral Small 4\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"mistral-small-3-2-25-06\",\n name: \"Mistral Small 3.2\",\n vision: true,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"codestral-2508\",\n name: \"Codestral\",\n vision: false,\n context: 262144,\n maxOutput: 32768,\n },\n {\n id: \"devstral-2-25-12\",\n name: \"Devstral 2\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"magistral-medium-1-2-25-09\",\n name: \"Magistral Medium (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"magistral-small-1-2-25-09\",\n name: \"Magistral Small (Reasoning)\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n ],\n apiBase: \"https://api.mistral.ai/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter API key...\",\n },\n\n // ─── Groq ─────────────────────────────────────────────────────\n groq: {\n name: \"Groq\",\n models: [\n {\n id: \"meta-llama/llama-4-scout-17b-16e-instruct\",\n name: \"Llama 4 Scout 17B\",\n vision: true,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"llama-3.3-70b-versatile\",\n name: \"Llama 3.3 70B\",\n vision: false,\n context: 131072,\n maxOutput: 32768,\n },\n {\n id: \"llama-3.1-8b-instant\",\n name: \"Llama 3.1 8B Instant\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n {\n id: \"qwen/qwen3-32b\",\n name: \"Qwen 3 32B\",\n vision: false,\n context: 131072,\n maxOutput: 8192,\n },\n ],\n apiBase: \"https://api.groq.com/openai/v1\",\n keyPrefix: \"gsk_\",\n keyPlaceholder: \"gsk_...\",\n },\n\n // ─── MiniMax ───────────────────────────────────────────────────\n minimax: {\n name: \"MiniMax\",\n models: [\n { id: \"MiniMax-M2.7\", name: \"MiniMax M2.7\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.7-highspeed\", name: \"MiniMax M2.7 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5\", name: \"MiniMax M2.5\", vision: true, context: 1048576, maxOutput: 16384 },\n { id: \"MiniMax-M2.5-highspeed\", name: \"MiniMax M2.5 Highspeed\", vision: true, context: 1048576, maxOutput: 16384 },\n ],\n apiBase: \"https://api.minimax.chat/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter MiniMax API key...\",\n },\n\n // ─── Moonshot / Kimi ──────────────────────────────────────────\n moonshot: {\n name: \"Kimi (Moonshot)\",\n models: [\n {\n id: \"kimi-k2.5\",\n name: \"Kimi K2.5\",\n vision: true,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"medium\",\n },\n },\n {\n id: \"kimi-k2-thinking\",\n name: \"Kimi K2 Thinking\",\n vision: false,\n context: 262144,\n maxOutput: 16384,\n thinking: {\n supported: true,\n paramName: \"reasoning_effort\",\n paramType: \"level\",\n levels: [\"low\", \"medium\", \"high\"],\n defaultLevel: \"high\",\n },\n },\n ],\n apiBase: \"https://api.moonshot.cn/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Moonshot API key...\",\n },\n\n // ─── Alibaba Qwen (DashScope) ────────────────────────────────\n qwen: {\n name: \"Qwen (Alibaba)\",\n models: [\n { id: \"qwen3.5-plus\", name: \"Qwen 3.5 Plus\", vision: true, context: 1010000, maxOutput: 16384 },\n { id: \"qwen-plus\", name: \"Qwen Plus\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-max\", name: \"Qwen Max\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"qwen-turbo\", name: \"Qwen Turbo\", vision: false, context: 131072, maxOutput: 8192 },\n ],\n apiBase: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter DashScope API key...\",\n },\n\n // ─── Zhipu AI (GLM) ──────────────────────────────────────────\n zhipu: {\n name: \"Zhipu AI (GLM)\",\n models: [\n { id: \"glm-5\", name: \"GLM-5\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.7\", name: \"GLM-4.7\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.6\", name: \"GLM-4.6\", vision: true, context: 131072, maxOutput: 16384 },\n { id: \"glm-4.5\", name: \"GLM-4.5\", vision: true, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://open.bigmodel.cn/api/paas/v4\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Zhipu API key...\",\n },\n\n // ─── ByteDance Doubao ─────────────────────────────────────────\n doubao: {\n name: \"Doubao (ByteDance)\",\n models: [\n { id: \"doubao-seed-2-0-pro\", name: \"Doubao Seed 2.0 Pro\", vision: false, context: 131072, maxOutput: 16384 },\n { id: \"doubao-seed-2-0-lite\", name: \"Doubao Seed 2.0 Lite\", vision: false, context: 131072, maxOutput: 8192 },\n { id: \"doubao-seed-2-0-code\", name: \"Doubao Seed 2.0 Code\", vision: false, context: 131072, maxOutput: 16384 },\n ],\n apiBase: \"https://ark.cn-beijing.volces.com/api/v3\",\n keyPrefix: \"\",\n keyPlaceholder: \"Enter Volcano Engine API key...\",\n },\n\n // ─── Ollama (Local) ───────────────────────────────────────────\n ollama: {\n name: \"Ollama (Local)\",\n models: [],\n apiBase: \"http://localhost:11434/v1\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── OpenRouter (200+ models) ─────────────────────────────────\n openrouter: {\n name: \"OpenRouter\",\n models: [],\n apiBase: \"https://openrouter.ai/api/v1\",\n keyPrefix: \"sk-or-\",\n keyPlaceholder: \"sk-or-...\",\n },\n};\n","export const SYSTEM_PROMPT = `You are OpenMagic, an AI coding assistant embedded in a developer's web application. You help modify the codebase based on visual context from the running app.\n\n## Your Role\n- You can see the developer's running web application (DOM elements, screenshots, styles)\n- You propose code modifications to their source files\n- Your changes are applied directly to their codebase and reflected via hot reload\n\n## Response Format\nYou MUST respond with valid JSON in this exact format:\n\n\\`\\`\\`json\n{\n \"modifications\": [\n {\n \"file\": \"relative/path/to/file.tsx\",\n \"type\": \"edit\",\n \"search\": \"exact code to find (multi-line ok)\",\n \"replace\": \"replacement code\"\n }\n ],\n \"explanation\": \"Brief description of what was changed and why\"\n}\n\\`\\`\\`\n\n## Modification Types\n- \\`edit\\`: Replace existing code. \\`search\\` must match exactly in the file. \\`replace\\` is the new code.\n- \\`create\\`: Create a new file. Use \\`content\\` instead of search/replace.\n- \\`delete\\`: Delete a file. No search/replace/content needed.\n\n## Rules\n1. The \\`search\\` field must contain the EXACT text from the source file — copy it precisely, including whitespace and indentation\n2. Keep modifications minimal — change only what's needed\n3. If you need to read a file first, say so in the explanation and the developer can provide it\n4. For style changes, prefer modifying existing CSS/Tailwind classes over adding inline styles\n5. Always preserve the existing code style and conventions\n6. If the change involves multiple files, include all modifications in the array\n7. ALWAYS respond with the JSON format above, even for explanations (put them in the \"explanation\" field)\n8. If you cannot make the requested change, set modifications to an empty array and explain why`;\n\nexport function buildUserMessage(\n userPrompt: string,\n context: {\n selectedElement?: string;\n screenshot?: string;\n fileContent?: string;\n filePath?: string;\n networkLogs?: string;\n consoleLogs?: string;\n projectTree?: string;\n }\n): string {\n const parts: string[] = [];\n\n if (context.projectTree) {\n parts.push(`## Project Structure\\n\\`\\`\\`\\n${context.projectTree}\\n\\`\\`\\``);\n }\n\n if (context.filePath && context.fileContent) {\n parts.push(\n `## Source File: ${context.filePath}\\n\\`\\`\\`\\n${context.fileContent}\\n\\`\\`\\``\n );\n }\n\n if (context.selectedElement) {\n parts.push(`## Selected Element (DOM)\\n\\`\\`\\`html\\n${context.selectedElement}\\n\\`\\`\\``);\n }\n\n if (context.networkLogs) {\n parts.push(`## Recent Network Requests\\n\\`\\`\\`\\n${context.networkLogs}\\n\\`\\`\\``);\n }\n\n if (context.consoleLogs) {\n parts.push(`## Console Output\\n\\`\\`\\`\\n${context.consoleLogs}\\n\\`\\`\\``);\n }\n\n parts.push(`## User Request\\n${userPrompt}`);\n\n return parts.join(\"\\n\\n\");\n}\n","import type { ChatMessage, ContentPart, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage } from \"./prompts.js\";\n\ninterface OpenAICompatibleRequest {\n model: string;\n messages: Array<{\n role: string;\n content: string | Array<{ type: string; text?: string; image_url?: { url: string } }>;\n }>;\n stream: boolean;\n max_tokens?: number;\n max_completion_tokens?: number;\n reasoning_effort?: string;\n}\n\nexport async function chatOpenAICompatible(\n provider: string,\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const providerConfig = MODEL_REGISTRY[provider];\n if (!providerConfig) {\n onError(`Unknown provider: ${provider}`);\n return;\n }\n\n const apiBase = providerConfig.apiBase;\n const url = `${apiBase}/chat/completions`;\n\n // Build messages with context\n const apiMessages: OpenAICompatibleRequest[\"messages\"] = [\n { role: \"system\", content: SYSTEM_PROMPT },\n ];\n\n // Only enrich the LAST user message with context (not all historical ones)\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const contextParts: Parameters<typeof buildUserMessage>[1] = {};\n\n if (context.selectedElement) {\n contextParts.selectedElement = context.selectedElement.outerHTML;\n }\n if (context.files && context.files.length > 0) {\n contextParts.filePath = context.files[0].path;\n contextParts.fileContent = context.files[0].content;\n }\n if (context.projectTree) {\n contextParts.projectTree = context.projectTree;\n }\n if (context.networkLogs) {\n contextParts.networkLogs = context.networkLogs\n .map((l) => `${l.method} ${l.url} → ${l.status || \"pending\"}`)\n .join(\"\\n\");\n }\n if (context.consoleLogs) {\n contextParts.consoleLogs = context.consoleLogs\n .map((l) => `[${l.level}] ${l.args.join(\" \")}`)\n .join(\"\\n\");\n }\n\n const enrichedContent = buildUserMessage(msg.content, contextParts);\n\n // If we have a screenshot and the model supports vision, add it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (context.screenshot && modelInfo?.vision) {\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image_url\",\n image_url: { url: context.screenshot },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else if (msg.role === \"system\") {\n continue; // System prompt already added\n } else {\n apiMessages.push({\n role: msg.role,\n content: msg.content as string,\n });\n }\n }\n\n // GPT-5.x, o3, o4 models require max_completion_tokens instead of max_tokens\n const usesCompletionTokens = provider === \"openai\" && (\n model.startsWith(\"gpt-5\") || model.startsWith(\"o3\") || model.startsWith(\"o4\") || model.startsWith(\"codex\")\n );\n\n const body: OpenAICompatibleRequest = {\n model,\n messages: apiMessages,\n stream: true,\n };\n\n if (usesCompletionTokens) {\n body.max_completion_tokens = 4096;\n } else {\n body.max_tokens = 4096;\n }\n\n // Add thinking/reasoning config if the model supports it\n const modelInfo = providerConfig.models.find((m) => m.id === model);\n if (modelInfo?.thinking?.supported && modelInfo.thinking.paramType === \"level\") {\n body.reasoning_effort = modelInfo.thinking.defaultLevel || \"medium\";\n const limit = Math.min(modelInfo.maxOutput, 16384);\n if (usesCompletionTokens) {\n body.max_completion_tokens = limit;\n } else {\n body.max_tokens = limit;\n }\n }\n\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (provider === \"ollama\") {\n // Ollama doesn't need auth\n } else {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(`Invalid API key for ${providerConfig.name}. Check your key in Settings.`);\n } else if (response.status === 429) {\n onError(`Rate limit exceeded for ${providerConfig.name}. Wait a moment and try again.`);\n } else {\n onError(`${providerConfig.name} API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n // Stream SSE response\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n if (data === \"[DONE]\") continue;\n\n try {\n const parsed = JSON.parse(data);\n const delta = parsed.choices?.[0]?.delta?.content;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage } from \"./prompts.js\";\n\ninterface AnthropicMessage {\n role: \"user\" | \"assistant\";\n content: string | Array<{ type: string; text?: string; source?: { type: string; media_type: string; data: string } }>;\n}\n\nexport async function chatAnthropic(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = \"https://api.anthropic.com/v1/messages\";\n\n const apiMessages: AnthropicMessage[] = [];\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const contextParts: Parameters<typeof buildUserMessage>[1] = {};\n\n if (context.selectedElement) {\n contextParts.selectedElement = context.selectedElement.outerHTML;\n }\n if (context.files && context.files.length > 0) {\n contextParts.filePath = context.files[0].path;\n contextParts.fileContent = context.files[0].content;\n }\n if (context.projectTree) {\n contextParts.projectTree = context.projectTree;\n }\n if (context.networkLogs) {\n contextParts.networkLogs = context.networkLogs\n .map((l) => `${l.method} ${l.url} → ${l.status || \"pending\"}`)\n .join(\"\\n\");\n }\n if (context.consoleLogs) {\n contextParts.consoleLogs = context.consoleLogs\n .map((l) => `[${l.level}] ${l.args.join(\" \")}`)\n .join(\"\\n\");\n }\n\n const enrichedContent = buildUserMessage(msg.content, contextParts);\n\n // If screenshot available, use vision\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n apiMessages.push({\n role: \"user\",\n content: [\n { type: \"text\", text: enrichedContent },\n {\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: \"image/png\",\n data: base64Data,\n },\n },\n ],\n });\n } else {\n apiMessages.push({ role: \"user\", content: enrichedContent });\n }\n } else {\n apiMessages.push({\n role: msg.role as \"user\" | \"assistant\",\n content: msg.content as string,\n });\n }\n }\n\n // Build body with optional extended thinking\n const providerConfig = MODEL_REGISTRY.anthropic;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingBudget = modelInfo?.thinking?.defaultBudget || 0;\n\n const body: Record<string, unknown> = {\n model,\n max_tokens: thinkingBudget > 0 ? Math.max(thinkingBudget + 4096, 16384) : 4096,\n system: SYSTEM_PROMPT,\n messages: apiMessages,\n stream: true,\n };\n\n // Add extended thinking if supported\n if (thinkingBudget > 0) {\n body.thinking = {\n type: \"enabled\",\n budget_tokens: thinkingBudget,\n };\n }\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Anthropic API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Anthropic rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Anthropic API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n if (parsed.type === \"content_block_delta\") {\n const delta = parsed.delta?.text;\n if (delta) {\n fullContent += delta;\n onChunk(delta);\n }\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { MODEL_REGISTRY } from \"./registry.js\";\nimport { SYSTEM_PROMPT, buildUserMessage } from \"./prompts.js\";\n\nexport async function chatGoogle(\n model: string,\n apiKey: string,\n messages: ChatMessage[],\n context: LlmContext,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?key=${apiKey}&alt=sse`;\n\n const contents: Array<{\n role: string;\n parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }>;\n }> = [];\n\n const lastUserIdx = messages.reduce((acc, m, i) => m.role === \"user\" ? i : acc, -1);\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role === \"system\") continue;\n\n const role = msg.role === \"assistant\" ? \"model\" : \"user\";\n\n if (msg.role === \"user\" && typeof msg.content === \"string\" && i === lastUserIdx) {\n const contextParts: Parameters<typeof buildUserMessage>[1] = {};\n\n if (context.selectedElement) {\n contextParts.selectedElement = context.selectedElement.outerHTML;\n }\n if (context.files && context.files.length > 0) {\n contextParts.filePath = context.files[0].path;\n contextParts.fileContent = context.files[0].content;\n }\n if (context.projectTree) {\n contextParts.projectTree = context.projectTree;\n }\n\n const enrichedContent = buildUserMessage(msg.content, contextParts);\n\n const parts: Array<{ text?: string; inline_data?: { mime_type: string; data: string } }> = [\n { text: enrichedContent },\n ];\n\n if (context.screenshot) {\n const base64Data = context.screenshot.replace(\n /^data:image\\/\\w+;base64,/,\n \"\"\n );\n parts.push({\n inline_data: {\n mime_type: \"image/png\",\n data: base64Data,\n },\n });\n }\n\n contents.push({ role, parts });\n } else {\n contents.push({\n role,\n parts: [{ text: msg.content as string }],\n });\n }\n }\n\n // Check for thinking support\n const providerConfig = MODEL_REGISTRY.google;\n const modelInfo = providerConfig?.models.find((m) => m.id === model);\n const thinkingLevel = modelInfo?.thinking?.defaultLevel;\n\n const generationConfig: Record<string, unknown> = {\n maxOutputTokens: 8192,\n };\n\n const thinkingConfig = (thinkingLevel && thinkingLevel !== \"none\")\n ? { thinkingLevel: thinkingLevel.toUpperCase() }\n : undefined;\n\n const body: Record<string, unknown> = {\n system_instruction: {\n parts: [{ text: SYSTEM_PROMPT }],\n },\n contents,\n generationConfig,\n };\n if (thinkingConfig) {\n body.thinkingConfig = thinkingConfig;\n }\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n if (response.status === 401 || response.status === 403) {\n onError(\"Invalid Google API key. Check your key in Settings.\");\n } else if (response.status === 429) {\n onError(\"Google API rate limit exceeded. Wait a moment and try again.\");\n } else {\n onError(`Google API error ${response.status}: ${errorText.slice(0, 200)}`);\n }\n return;\n }\n\n if (!response.body) {\n onError(\"No response body\");\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6).trim();\n\n try {\n const parsed = JSON.parse(data);\n const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n\n onDone({ content: fullContent });\n } catch (e: unknown) {\n onError(`Request failed: ${(e as Error).message}`);\n }\n}\n","import type { ChatMessage, LlmContext, LlmResponse } from \"../shared-types.js\";\nimport { chatOpenAICompatible } from \"./openai.js\";\nimport { chatAnthropic } from \"./anthropic.js\";\nimport { chatGoogle } from \"./google.js\";\n\n// Providers that use OpenAI-compatible API format\nconst OPENAI_COMPATIBLE_PROVIDERS = new Set([\n \"openai\",\n \"deepseek\",\n \"groq\",\n \"mistral\",\n \"xai\",\n \"ollama\",\n \"openrouter\",\n \"minimax\",\n \"moonshot\",\n \"qwen\",\n \"zhipu\",\n \"doubao\",\n]);\n\ninterface LlmChatParams {\n provider: string;\n model: string;\n apiKey: string;\n messages: ChatMessage[];\n context: LlmContext;\n}\n\nexport async function handleLlmChat(\n params: LlmChatParams,\n onChunk: (chunk: string) => void,\n onDone: (result: { content: string; modifications?: LlmResponse[\"modifications\"] }) => void,\n onError: (error: string) => void\n): Promise<void> {\n const { provider, model, apiKey, messages, context } = params;\n\n const wrappedOnDone = (result: { content: string }) => {\n // Try to parse modifications from the response\n let modifications: LlmResponse[\"modifications\"] | undefined;\n try {\n // Extract JSON from the response (it might be wrapped in markdown code blocks)\n const jsonMatch = result.content.match(/```json\\s*([\\s\\S]*?)```/) ||\n result.content.match(/\\{[\\s\\S]*\"modifications\"[\\s\\S]*\\}/);\n\n if (jsonMatch) {\n const jsonStr = jsonMatch[1] || jsonMatch[0];\n const parsed = JSON.parse(jsonStr) as LlmResponse;\n modifications = parsed.modifications;\n }\n } catch {\n // If parsing fails, just return the raw content\n }\n\n onDone({ content: result.content, modifications });\n };\n\n try {\n if (provider === \"anthropic\") {\n await chatAnthropic(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (provider === \"google\") {\n await chatGoogle(model, apiKey, messages, context, onChunk, wrappedOnDone, onError);\n } else if (OPENAI_COMPATIBLE_PROVIDERS.has(provider)) {\n await chatOpenAICompatible(\n provider,\n model,\n apiKey,\n messages,\n context,\n onChunk,\n wrappedOnDone,\n onError\n );\n } else {\n onError(`Unsupported provider: ${provider}. Check your Settings.`);\n }\n } catch (e: unknown) {\n const msg = (e as Error).message || \"Unknown error\";\n if (msg.includes(\"fetch\") || msg.includes(\"ECONNREFUSED\") || msg.includes(\"network\")) {\n onError(`Network error: Could not reach the ${provider} API. Check your internet connection.`);\n } else {\n onError(`Unexpected error with ${provider}: ${msg}`);\n }\n }\n}\n","import { createConnection } from \"node:net\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst COMMON_DEV_PORTS = [\n 3000, // React (CRA), Next.js, Express\n 5173, // Vite\n 5174, // Vite (alternate)\n 4200, // Angular\n 8080, // Vue CLI, generic\n 8000, // Django, Python\n 8888, // Jupyter, generic\n 3001, // Common alternate\n 4000, // Phoenix, generic\n 1234, // Parcel\n 4321, // Astro\n 3333, // Remix\n 8081, // Metro (React Native)\n 9000, // generic\n];\n\nfunction checkPort(port: number, host: string = \"127.0.0.1\"): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host, timeout: 500 });\n socket.on(\"connect\", () => {\n socket.destroy();\n resolve(true);\n });\n socket.on(\"error\", () => {\n socket.destroy();\n resolve(false);\n });\n socket.on(\"timeout\", () => {\n socket.destroy();\n resolve(false);\n });\n });\n}\n\nexport interface DetectedServer {\n port: number;\n host: string;\n}\n\nexport async function detectDevServer(): Promise<DetectedServer | null> {\n const checks = COMMON_DEV_PORTS.map(async (port) => {\n const isOpen = await checkPort(port);\n return isOpen ? port : null;\n });\n\n const results = await Promise.all(checks);\n const foundPort = results.find((p) => p !== null);\n\n if (foundPort) {\n return { port: foundPort, host: \"127.0.0.1\" };\n }\n\n return null;\n}\n\nexport async function isPortOpen(port: number): Promise<boolean> {\n return checkPort(port);\n}\n\nexport async function findAvailablePort(startPort: number): Promise<number> {\n let port = startPort;\n while (await isPortOpen(port)) {\n port++;\n if (port > startPort + 100) {\n throw new Error(`Could not find an available port near ${startPort}`);\n }\n }\n return port;\n}\n\n// --- Package.json Dev Script Detection ---\n\nexport interface DevScript {\n name: string; // e.g. \"dev\", \"start\", \"serve\"\n command: string; // e.g. \"next dev\", \"vite\", \"ng serve\"\n framework: string; // e.g. \"Next.js\", \"Vite\", \"Angular\"\n defaultPort: number;\n}\n\nconst FRAMEWORK_PATTERNS: Array<{\n match: RegExp;\n framework: string;\n defaultPort: number;\n}> = [\n { match: /\\bnext\\b/, framework: \"Next.js\", defaultPort: 3000 },\n { match: /\\bvite\\b/, framework: \"Vite\", defaultPort: 5173 },\n { match: /\\bnuxt\\b/, framework: \"Nuxt\", defaultPort: 3000 },\n { match: /\\bng\\s+serve\\b/, framework: \"Angular\", defaultPort: 4200 },\n { match: /\\bvue-cli-service\\s+serve\\b/, framework: \"Vue CLI\", defaultPort: 8080 },\n { match: /\\bsvelte-kit\\b/, framework: \"SvelteKit\", defaultPort: 5173 },\n { match: /\\bastro\\b/, framework: \"Astro\", defaultPort: 4321 },\n { match: /\\bremix\\b/, framework: \"Remix\", defaultPort: 3000 },\n { match: /\\breact-scripts\\s+start\\b/, framework: \"Create React App\", defaultPort: 3000 },\n { match: /\\bparcel\\b/, framework: \"Parcel\", defaultPort: 1234 },\n { match: /\\bwebpack\\s+serve\\b|webpack-dev-server/, framework: \"Webpack\", defaultPort: 8080 },\n { match: /\\bgatsby\\b/, framework: \"Gatsby\", defaultPort: 8000 },\n { match: /\\bturborepo\\b|\\bturbo\\b.*dev/, framework: \"Turborepo\", defaultPort: 3000 },\n { match: /\\bexpo\\b/, framework: \"Expo\", defaultPort: 8081 },\n { match: /\\bnodemon\\b|\\bts-node\\b|\\bnode\\b/, framework: \"Node.js\", defaultPort: 3000 },\n { match: /\\bflask\\b/, framework: \"Flask\", defaultPort: 5000 },\n { match: /\\bdjango\\b|manage\\.py\\s+runserver/, framework: \"Django\", defaultPort: 8000 },\n { match: /\\brails\\b/, framework: \"Rails\", defaultPort: 3000 },\n { match: /\\bphp\\s+.*serve\\b|artisan\\s+serve/, framework: \"PHP/Laravel\", defaultPort: 8000 },\n];\n\nconst DEV_SCRIPT_NAMES = [\"dev\", \"start\", \"serve\", \"develop\", \"dev:start\", \"start:dev\"];\n\nexport function detectDevScripts(cwd: string = process.cwd()): DevScript[] {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return [];\n\n let pkg: any;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n } catch {\n return [];\n }\n\n if (!pkg.scripts) return [];\n\n const scripts: DevScript[] = [];\n\n for (const name of DEV_SCRIPT_NAMES) {\n const command = pkg.scripts[name];\n if (!command) continue;\n\n // Detect framework from command\n let framework = \"Unknown\";\n let defaultPort = 3000;\n\n for (const pattern of FRAMEWORK_PATTERNS) {\n if (pattern.match.test(command)) {\n framework = pattern.framework;\n defaultPort = pattern.defaultPort;\n break;\n }\n }\n\n // Try to extract port from command (e.g., --port 4000, -p 8080)\n const portMatch = command.match(/(?:--port|-p)\\s+(\\d+)/);\n if (portMatch) {\n defaultPort = parseInt(portMatch[1], 10);\n }\n\n scripts.push({ name, command, framework, defaultPort });\n }\n\n return scripts;\n}\n\nexport function getProjectName(cwd: string = process.cwd()): string {\n const pkgPath = join(cwd, \"package.json\");\n if (!existsSync(pkgPath)) return \"this project\";\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n return pkg.name || \"this project\";\n } catch {\n return \"this project\";\n }\n}\n\n// --- Dependency Installation Check ---\n\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\n\nexport interface DependencyStatus {\n installed: boolean;\n packageManager: PackageManager;\n installCommand: string;\n}\n\nconst LOCK_FILES: Array<{ file: string; pm: PackageManager }> = [\n { file: \"pnpm-lock.yaml\", pm: \"pnpm\" },\n { file: \"yarn.lock\", pm: \"yarn\" },\n { file: \"bun.lockb\", pm: \"bun\" },\n { file: \"bun.lock\", pm: \"bun\" },\n { file: \"package-lock.json\", pm: \"npm\" },\n];\n\nconst INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: \"npm install\",\n yarn: \"yarn install\",\n pnpm: \"pnpm install\",\n bun: \"bun install\",\n};\n\nexport function checkDependenciesInstalled(cwd: string = process.cwd()): DependencyStatus {\n const hasNodeModules = existsSync(join(cwd, \"node_modules\"));\n\n // Detect package manager from lock file\n let pm: PackageManager = \"npm\";\n for (const { file, pm: detectedPm } of LOCK_FILES) {\n if (existsSync(join(cwd, file))) {\n pm = detectedPm;\n break;\n }\n }\n\n return {\n installed: hasNodeModules,\n packageManager: pm,\n installCommand: INSTALL_COMMANDS[pm],\n };\n}\n"],"mappings":"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","names":["resolve","resolve","http","readFileSync","existsSync","join","dirname","readFileSync","writeFileSync","existsSync","mkdirSync","join","modelInfo","dirname","http","join","existsSync","readFileSync","readFileSync","existsSync","join","resolve","join","existsSync","readFileSync","resolve"]}