openmagic 0.16.0 → 0.17.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 +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/toolbar/index.global.js +76 -35
- package/dist/toolbar/index.global.js.map +1 -1
- package/package.json +1 -1
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 { 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.16.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 // Check OpenMagic's own health endpoint (not the app — app may require auth)\n const res = await fetch(`http://127.0.0.1:${proxyPort}/__openmagic__/health`, {\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n if (res.ok) {\n console.log(chalk.green(\" ✓ Toolbar ready.\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Proxy started but toolbar health check failed.\"));\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 generateSessionToken();\n\n // Find available port (single port — proxy + toolbar + WS all on same origin)\n let proxyPort = parseInt(opts.listen, 10);\n while (await isPortOpen(proxyPort)) {\n proxyPort++;\n if (proxyPort > parseInt(opts.listen, 10) + 100) {\n console.log(chalk.red(\" Could not find an available port.\"));\n process.exit(1);\n }\n }\n\n // Single server: proxy + toolbar + WebSocket all on one port\n const proxyServer = createProxyServer(targetHost, targetPort!, roots);\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 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 // Graceful shutdown\n const shutdown = () => {\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n proxyServer.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 httpProxy from \"http-proxy\";\nimport { getSessionToken } from \"./security.js\";\nimport { attachOpenMagic } from \"./server.js\";\n\n/**\n * Create a single-port proxy server that:\n * 1. Serves /__openmagic__/* (toolbar bundle, health, WebSocket)\n * 2. Proxies everything else to the dev server\n * 3. Injects the toolbar script into HTML responses\n */\nexport function createProxyServer(\n targetHost: string,\n targetPort: number,\n roots: string[]\n): http.Server {\n const proxy = httpProxy.createProxyServer({\n target: `http://${targetHost}:${targetPort}`,\n selfHandleResponse: true,\n // ws: false — we handle WebSocket upgrades manually in server.on(\"upgrade\")\n });\n\n const token = getSessionToken();\n\n // Strip Accept-Encoding on HTML requests so upstream sends uncompressed (enables streaming injection)\n // Only apply to regular HTTP requests, not WebSocket upgrades\n proxy.on(\"proxyReq\", (proxyReq, req) => {\n const accept = req.headers.accept || \"\";\n // Only strip for requests that might return HTML (not for API calls, assets, WS upgrades)\n if (accept.includes(\"text/html\") || accept.includes(\"*/*\") || !accept) {\n proxyReq.removeHeader(\"Accept-Encoding\");\n }\n });\n\n proxy.on(\"proxyRes\", (proxyRes, req, res) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isHtml = contentType.includes(\"text/html\");\n const status = proxyRes.statusCode || 200;\n\n if (!isHtml && status < 400) {\n // Non-HTML success: pass through unchanged\n res.writeHead(status, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n if (isHtml) {\n // HTML response: stream through and append toolbar script\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 headers[\"cache-control\"] = \"no-store\";\n\n res.writeHead(status, headers);\n proxyRes.pipe(res, { end: false });\n proxyRes.on(\"end\", () => {\n res.end(buildInjectionScript(token));\n });\n return;\n }\n\n // Non-HTML error (4xx/5xx) — wrap in HTML with toolbar so user can still interact\n const chunks: Buffer[] = [];\n proxyRes.on(\"data\", (c: Buffer) => chunks.push(c));\n proxyRes.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString(\"utf-8\").slice(0, 2000);\n const toolbarScript = buildInjectionScript(token);\n res.writeHead(status, { \"Content-Type\": \"text/html\", \"Cache-Control\": \"no-store\" });\n res.end(`<html><head><meta charset=\"utf-8\"><title>Error ${status}</title></head>\n<body style=\"font-family:system-ui;padding:40px;background:#0f0f1e;color:#e0e0e0;\">\n<h2 style=\"color:#e94560;\">Error ${status}</h2>\n<pre style=\"color:#888;white-space:pre-wrap;max-width:800px;overflow:auto;font-size:13px;\">${body.replace(/</g,\"<\")}</pre>\n<p style=\"color:#555;font-size:13px;\">This error is from your dev server, not OpenMagic. The toolbar is available below.</p>\n${toolbarScript}\n</body></html>`);\n });\n });\n\n proxy.on(\"error\", (err, _req, res) => {\n if (res instanceof http.ServerResponse && !res.headersSent) {\n const toolbarScript = buildInjectionScript(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 // Shared reference for the handler — set after server creation\n let omHandle: ((req: http.IncomingMessage, res: http.ServerResponse) => boolean) | null = null;\n\n const server = http.createServer((req, res) => {\n if (omHandle && omHandle(req, res)) return;\n proxy.web(req, res);\n });\n\n // Attach OpenMagic WS + endpoints to THIS server (same port)\n const om = attachOpenMagic(server, roots);\n omHandle = om.handleRequest;\n\n // Handle WebSocket upgrades\n server.on(\"upgrade\", (req, socket, head) => {\n // OpenMagic WS is handled by the WSS attached to this server\n if (req.url?.startsWith(\"/__openmagic__\")) return;\n // Everything else (HMR, etc.) goes to dev server\n proxy.ws(req, socket, head);\n });\n\n return server;\n}\n\n// Same-origin injection — toolbar.js and WS served from THIS server\nfunction buildInjectionScript(token: string): string {\n return `<script src=\"/__openmagic__/toolbar.js?v=${Date.now()}\" data-openmagic=\"true\" data-openmagic-token=\"${token}\" defer></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 VERSION = \"0.16.0\";\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\ninterface ClientState {\n authenticated: boolean;\n}\n\n/**\n * Attach OpenMagic endpoints to an existing HTTP server.\n * Handles: toolbar bundle serving, health check, WebSocket.\n * Returns a request handler and the WSS instance.\n */\nexport function attachOpenMagic(\n httpServer: http.Server,\n roots: string[]\n): { wss: WebSocketServer; handleRequest: (req: http.IncomingMessage, res: http.ServerResponse) => boolean } {\n\n // Request handler for /__openmagic__/ paths — returns true if handled\n function handleRequest(req: http.IncomingMessage, res: http.ServerResponse): boolean {\n if (!req.url?.startsWith(\"/__openmagic__/\")) return false;\n\n // Strip query string for path matching (e.g., toolbar.js?v=123)\n const urlPath = req.url.split(\"?\")[0];\n\n if (urlPath === \"/__openmagic__/toolbar.js\") {\n serveToolbarBundle(res);\n return true;\n }\n\n if (urlPath === \"/__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: VERSION }));\n return true;\n }\n\n return false;\n }\n\n // WebSocket server on the same HTTP server\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 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 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);\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 { wss, handleRequest };\n}\n\nasync function handleMessage(\n ws: WebSocket,\n msg: WsMessage,\n state: ClientState,\n roots: string[]\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: VERSION,\n roots,\n config: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n apiKeys: Object.fromEntries(Object.entries(config.apiKeys || {}).map(([k]) => [k, true])),\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 if (!payload?.path || payload.content === undefined) {\n sendError(ws, \"invalid_payload\", \"Missing path or content\", msg.id);\n break;\n }\n const writeResult = writeFileSafe(payload.path, payload.content, roots);\n if (!writeResult.ok) {\n sendError(ws, \"fs_error\", writeResult.error || \"Write failed\", msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.written\",\n payload: { path: payload.path, ok: true },\n });\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 // Resolve API key: per-provider keys first, then global fallback\n const provider = payload.provider || config.provider || \"openai\";\n const apiKey = config.apiKeys?.[provider] || config.apiKey || \"\";\n const providerMeta = MODEL_REGISTRY?.[provider];\n\n if (!apiKey && !providerMeta?.local) {\n sendError(ws, \"config_error\", \"API key not configured\", msg.id);\n return;\n }\n\n await handleLlmChat(\n {\n provider,\n model: payload.model || config.model || MODEL_REGISTRY[provider]?.models[0]?.id || \"gpt-4o\",\n 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.apiKeys?.[config.provider || \"\"] || config.apiKey),\n roots: config.roots || roots,\n apiKeys: Object.fromEntries(\n Object.entries(config.apiKeys || {}).map(([k]) => [k, true])\n ),\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 // Per-provider key storage\n if (payload.apiKey !== undefined && payload.provider) {\n const existing = loadConfig();\n const apiKeys = { ...(existing.apiKeys || {}) };\n apiKeys[payload.provider] = payload.apiKey;\n updates.apiKeys = apiKeys;\n updates.apiKey = payload.apiKey; // backward compat\n } else if (payload.apiKey !== undefined) {\n updates.apiKey = payload.apiKey;\n }\n const result = saveConfig(updates);\n if (!result.ok) {\n sendError(ws, \"config_error\", result.error || \"Failed to save\", msg.id);\n } else {\n send(ws, { id: msg.id, type: \"config.saved\", 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(ws: WebSocket, code: string, message: string, id?: string): void {\n send(ws, { id: id || \"error\", type: \"error\", payload: { code, message } });\n}\n\nfunction serveToolbarBundle(res: http.ServerResponse): void {\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 continue;\n }\n }\n\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(`(function(){var d=document.createElement(\"div\");d.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);\";d.textContent=\"OpenMagic: Toolbar bundle not found.\";document.body.appendChild(d);})();`);\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>): { ok: boolean; error?: string } {\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 return { ok: true };\n } catch (e: unknown) {\n return { ok: false, error: (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 lstatSync,\n readdirSync,\n copyFileSync,\n mkdirSync,\n realpathSync,\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\n // Also check realpath to prevent symlink escape\n let real: string;\n try {\n real = realpathSync(resolved);\n } catch {\n // File doesn't exist yet (for writes) — use resolved path\n real = resolved;\n }\n\n return roots.some((root) => {\n const resolvedRoot = resolve(root);\n const rel = relative(resolvedRoot, resolved);\n const realRel = relative(resolvedRoot, real);\n return (\n (!rel.startsWith(\"..\") && !rel.startsWith(\"/\") && !rel.startsWith(\"\\\\\")) &&\n (!realRel.startsWith(\"..\") && !realRel.startsWith(\"/\") && !realRel.startsWith(\"\\\\\"))\n );\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 = lstatSync(fullPath);\n } catch {\n continue;\n }\n if (stat.isSymbolicLink()) continue;\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","import type { LlmContext } from \"../shared-types.js\";\n\nexport 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 buildContextParts(context: LlmContext): Parameters<typeof buildUserMessage>[1] {\n const parts: Parameters<typeof buildUserMessage>[1] = {};\n if (context.selectedElement) parts.selectedElement = context.selectedElement.outerHTML;\n if (context.files?.length) { parts.filePath = context.files[0].path; parts.fileContent = context.files[0].content; }\n if (context.projectTree) parts.projectTree = context.projectTree;\n if (context.networkLogs) parts.networkLogs = context.networkLogs.map(l => `${l.method} ${l.url} → ${l.status || \"pending\"}`).join(\"\\n\");\n if (context.consoleLogs) parts.consoleLogs = context.consoleLogs.map(l => `[${l.level}] ${l.args.join(\" \")}`).join(\"\\n\");\n return parts;\n}\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, buildContextParts } 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 enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\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, buildContextParts } 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 enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\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, buildContextParts } 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 enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\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 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 8888, // Jupyter, generic\n 5000, // Flask (last — macOS AirPlay also uses 5000)\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 // First: check ports hinted by the project's dev scripts (most reliable)\n const scripts = detectDevScripts();\n const scriptPorts = scripts.map((s) => s.defaultPort).filter((p, i, a) => a.indexOf(p) === i);\n\n if (scriptPorts.length > 0) {\n for (const port of scriptPorts) {\n if (await checkPort(port)) {\n return { port, host: \"127.0.0.1\" };\n }\n }\n // Project has dev scripts with known ports but none are running.\n // Do NOT fall back to generic port scan — that would find unrelated\n // services (like macOS AirPlay on 5000). Return null so the CLI\n // offers to start the dev server instead.\n return null;\n }\n\n // No scripts found — fall back to scanning common ports\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","readFileSync","existsSync","join","dirname","readFileSync","writeFileSync","existsSync","mkdirSync","join","modelInfo","dirname","join","existsSync","readFileSync","readFileSync","existsSync","join","resolve","join","existsSync","readFileSync","VERSION","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 { 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.17.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 // Check OpenMagic's own health endpoint (not the app — app may require auth)\n const res = await fetch(`http://127.0.0.1:${proxyPort}/__openmagic__/health`, {\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n if (res.ok) {\n console.log(chalk.green(\" ✓ Toolbar ready.\"));\n } else {\n console.log(chalk.yellow(\" ⚠ Proxy started but toolbar health check failed.\"));\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 generateSessionToken();\n\n // Find available port (single port — proxy + toolbar + WS all on same origin)\n let proxyPort = parseInt(opts.listen, 10);\n while (await isPortOpen(proxyPort)) {\n proxyPort++;\n if (proxyPort > parseInt(opts.listen, 10) + 100) {\n console.log(chalk.red(\" Could not find an available port.\"));\n process.exit(1);\n }\n }\n\n // Single server: proxy + toolbar + WebSocket all on one port\n const proxyServer = createProxyServer(targetHost, targetPort!, roots);\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 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 // Graceful shutdown\n const shutdown = () => {\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n proxyServer.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 httpProxy from \"http-proxy\";\nimport { getSessionToken } from \"./security.js\";\nimport { attachOpenMagic } from \"./server.js\";\n\n/**\n * Create a single-port proxy server that:\n * 1. Serves /__openmagic__/* (toolbar bundle, health, WebSocket)\n * 2. Proxies everything else to the dev server\n * 3. Injects the toolbar script into HTML responses\n */\nexport function createProxyServer(\n targetHost: string,\n targetPort: number,\n roots: string[]\n): http.Server {\n const proxy = httpProxy.createProxyServer({\n target: `http://${targetHost}:${targetPort}`,\n selfHandleResponse: true,\n // ws: false — we handle WebSocket upgrades manually in server.on(\"upgrade\")\n });\n\n const token = getSessionToken();\n\n // Strip Accept-Encoding on HTML requests so upstream sends uncompressed (enables streaming injection)\n // Only apply to regular HTTP requests, not WebSocket upgrades\n proxy.on(\"proxyReq\", (proxyReq, req) => {\n const accept = req.headers.accept || \"\";\n // Only strip for requests that might return HTML (not for API calls, assets, WS upgrades)\n if (accept.includes(\"text/html\") || accept.includes(\"*/*\") || !accept) {\n proxyReq.removeHeader(\"Accept-Encoding\");\n }\n });\n\n proxy.on(\"proxyRes\", (proxyRes, req, res) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isHtml = contentType.includes(\"text/html\");\n const status = proxyRes.statusCode || 200;\n\n if (!isHtml && status < 400) {\n // Non-HTML success: pass through unchanged\n res.writeHead(status, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n if (isHtml) {\n // HTML response: stream through and append toolbar script\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 headers[\"cache-control\"] = \"no-store\";\n\n res.writeHead(status, headers);\n proxyRes.pipe(res, { end: false });\n proxyRes.on(\"end\", () => {\n res.end(buildInjectionScript(token));\n });\n return;\n }\n\n // Non-HTML error (4xx/5xx) — wrap in HTML with toolbar so user can still interact\n const chunks: Buffer[] = [];\n proxyRes.on(\"data\", (c: Buffer) => chunks.push(c));\n proxyRes.on(\"end\", () => {\n const body = Buffer.concat(chunks).toString(\"utf-8\").slice(0, 2000);\n const toolbarScript = buildInjectionScript(token);\n res.writeHead(status, { \"Content-Type\": \"text/html\", \"Cache-Control\": \"no-store\" });\n res.end(`<html><head><meta charset=\"utf-8\"><title>Error ${status}</title></head>\n<body style=\"font-family:system-ui;padding:40px;background:#0f0f1e;color:#e0e0e0;\">\n<h2 style=\"color:#e94560;\">Error ${status}</h2>\n<pre style=\"color:#888;white-space:pre-wrap;max-width:800px;overflow:auto;font-size:13px;\">${body.replace(/</g,\"<\")}</pre>\n<p style=\"color:#555;font-size:13px;\">This error is from your dev server, not OpenMagic. The toolbar is available below.</p>\n${toolbarScript}\n</body></html>`);\n });\n });\n\n proxy.on(\"error\", (err, _req, res) => {\n if (res instanceof http.ServerResponse && !res.headersSent) {\n const toolbarScript = buildInjectionScript(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 // Shared reference for the handler — set after server creation\n let omHandle: ((req: http.IncomingMessage, res: http.ServerResponse) => boolean) | null = null;\n\n const server = http.createServer((req, res) => {\n if (omHandle && omHandle(req, res)) return;\n proxy.web(req, res);\n });\n\n // Attach OpenMagic WS + endpoints to THIS server (same port)\n const om = attachOpenMagic(server, roots);\n omHandle = om.handleRequest;\n\n // Handle WebSocket upgrades\n server.on(\"upgrade\", (req, socket, head) => {\n // OpenMagic WS is handled by the WSS attached to this server\n if (req.url?.startsWith(\"/__openmagic__\")) return;\n // Everything else (HMR, etc.) goes to dev server\n proxy.ws(req, socket, head);\n });\n\n return server;\n}\n\n// Same-origin injection — toolbar.js and WS served from THIS server\nfunction buildInjectionScript(token: string): string {\n return `<script src=\"/__openmagic__/toolbar.js?v=${Date.now()}\" data-openmagic=\"true\" data-openmagic-token=\"${token}\" defer></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 VERSION = \"0.17.0\";\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\ninterface ClientState {\n authenticated: boolean;\n}\n\n/**\n * Attach OpenMagic endpoints to an existing HTTP server.\n * Handles: toolbar bundle serving, health check, WebSocket.\n * Returns a request handler and the WSS instance.\n */\nexport function attachOpenMagic(\n httpServer: http.Server,\n roots: string[]\n): { wss: WebSocketServer; handleRequest: (req: http.IncomingMessage, res: http.ServerResponse) => boolean } {\n\n // Request handler for /__openmagic__/ paths — returns true if handled\n function handleRequest(req: http.IncomingMessage, res: http.ServerResponse): boolean {\n if (!req.url?.startsWith(\"/__openmagic__/\")) return false;\n\n // Strip query string for path matching (e.g., toolbar.js?v=123)\n const urlPath = req.url.split(\"?\")[0];\n\n if (urlPath === \"/__openmagic__/toolbar.js\") {\n serveToolbarBundle(res);\n return true;\n }\n\n if (urlPath === \"/__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: VERSION }));\n return true;\n }\n\n return false;\n }\n\n // WebSocket server on the same HTTP server\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 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 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);\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 { wss, handleRequest };\n}\n\nasync function handleMessage(\n ws: WebSocket,\n msg: WsMessage,\n state: ClientState,\n roots: string[]\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: VERSION,\n roots,\n config: {\n provider: config.provider,\n model: config.model,\n hasApiKey: !!config.apiKey,\n apiKeys: Object.fromEntries(Object.entries(config.apiKeys || {}).map(([k]) => [k, true])),\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 if (!payload?.path || payload.content === undefined) {\n sendError(ws, \"invalid_payload\", \"Missing path or content\", msg.id);\n break;\n }\n const writeResult = writeFileSafe(payload.path, payload.content, roots);\n if (!writeResult.ok) {\n sendError(ws, \"fs_error\", writeResult.error || \"Write failed\", msg.id);\n } else {\n send(ws, {\n id: msg.id,\n type: \"fs.written\",\n payload: { path: payload.path, ok: true },\n });\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 // Resolve API key: per-provider keys first, then global fallback\n const provider = payload.provider || config.provider || \"openai\";\n const apiKey = config.apiKeys?.[provider] || config.apiKey || \"\";\n const providerMeta = MODEL_REGISTRY?.[provider];\n\n if (!apiKey && !providerMeta?.local) {\n sendError(ws, \"config_error\", \"API key not configured\", msg.id);\n return;\n }\n\n await handleLlmChat(\n {\n provider,\n model: payload.model || config.model || MODEL_REGISTRY[provider]?.models[0]?.id || \"gpt-4o\",\n 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.apiKeys?.[config.provider || \"\"] || config.apiKey),\n roots: config.roots || roots,\n apiKeys: Object.fromEntries(\n Object.entries(config.apiKeys || {}).map(([k]) => [k, true])\n ),\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 // Per-provider key storage\n if (payload.apiKey !== undefined && payload.provider) {\n const existing = loadConfig();\n const apiKeys = { ...(existing.apiKeys || {}) };\n apiKeys[payload.provider] = payload.apiKey;\n updates.apiKeys = apiKeys;\n updates.apiKey = payload.apiKey; // backward compat\n } else if (payload.apiKey !== undefined) {\n updates.apiKey = payload.apiKey;\n }\n const result = saveConfig(updates);\n if (!result.ok) {\n sendError(ws, \"config_error\", result.error || \"Failed to save\", msg.id);\n } else {\n send(ws, { id: msg.id, type: \"config.saved\", 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(ws: WebSocket, code: string, message: string, id?: string): void {\n send(ws, { id: id || \"error\", type: \"error\", payload: { code, message } });\n}\n\nfunction serveToolbarBundle(res: http.ServerResponse): void {\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 continue;\n }\n }\n\n res.writeHead(200, {\n \"Content-Type\": \"application/javascript\",\n \"Access-Control-Allow-Origin\": \"*\",\n });\n res.end(`(function(){var d=document.createElement(\"div\");d.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);\";d.textContent=\"OpenMagic: Toolbar bundle not found.\";document.body.appendChild(d);})();`);\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>): { ok: boolean; error?: string } {\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 return { ok: true };\n } catch (e: unknown) {\n return { ok: false, error: (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 lstatSync,\n readdirSync,\n copyFileSync,\n mkdirSync,\n realpathSync,\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\n // Also check realpath to prevent symlink escape\n let real: string;\n try {\n real = realpathSync(resolved);\n } catch {\n // File doesn't exist yet (for writes) — use resolved path\n real = resolved;\n }\n\n return roots.some((root) => {\n const resolvedRoot = resolve(root);\n const rel = relative(resolvedRoot, resolved);\n const realRel = relative(resolvedRoot, real);\n return (\n (!rel.startsWith(\"..\") && !rel.startsWith(\"/\") && !rel.startsWith(\"\\\\\")) &&\n (!realRel.startsWith(\"..\") && !realRel.startsWith(\"/\") && !realRel.startsWith(\"\\\\\"))\n );\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 = lstatSync(fullPath);\n } catch {\n continue;\n }\n if (stat.isSymbolicLink()) continue;\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","import type { LlmContext } from \"../shared-types.js\";\n\nexport 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 buildContextParts(context: LlmContext): Parameters<typeof buildUserMessage>[1] {\n const parts: Parameters<typeof buildUserMessage>[1] = {};\n if (context.selectedElement) parts.selectedElement = context.selectedElement.outerHTML;\n if (context.files?.length) { parts.filePath = context.files[0].path; parts.fileContent = context.files[0].content; }\n if (context.projectTree) parts.projectTree = context.projectTree;\n if (context.networkLogs) parts.networkLogs = context.networkLogs.map(l => `${l.method} ${l.url} → ${l.status || \"pending\"}`).join(\"\\n\");\n if (context.consoleLogs) parts.consoleLogs = context.consoleLogs.map(l => `[${l.level}] ${l.args.join(\" \")}`).join(\"\\n\");\n return parts;\n}\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, buildContextParts } 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 enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\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, buildContextParts } 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 enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\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, buildContextParts } 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 enrichedContent = buildUserMessage(msg.content, buildContextParts(context));\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 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 8888, // Jupyter, generic\n 5000, // Flask (last — macOS AirPlay also uses 5000)\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 // First: check ports hinted by the project's dev scripts (most reliable)\n const scripts = detectDevScripts();\n const scriptPorts = scripts.map((s) => s.defaultPort).filter((p, i, a) => a.indexOf(p) === i);\n\n if (scriptPorts.length > 0) {\n for (const port of scriptPorts) {\n if (await checkPort(port)) {\n return { port, host: \"127.0.0.1\" };\n }\n }\n // Project has dev scripts with known ports but none are running.\n // Do NOT fall back to generic port scan — that would find unrelated\n // services (like macOS AirPlay on 5000). Return null so the CLI\n // offers to start the dev server instead.\n return null;\n }\n\n // No scripts found — fall back to scanning common ports\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","readFileSync","existsSync","join","dirname","readFileSync","writeFileSync","existsSync","mkdirSync","join","modelInfo","dirname","join","existsSync","readFileSync","readFileSync","existsSync","join","resolve","join","existsSync","readFileSync","VERSION","resolve"]}
|