openmagic 0.36.3 → 0.37.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 +453 -185
- package/dist/cli.js.map +1 -1
- package/dist/toolbar/index.global.js +55 -53
- 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/claude-code.ts","../src/llm/codex-cli.ts","../src/llm/gemini-cli.ts","../src/llm/proxy.ts","../src/detect.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { resolve, join } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\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[] = [];\nlet lastDetectedPort: number | null = null; // Port detected from dev server output\nimport { createProxyServer } from \"./proxy.js\";\nimport { generateSessionToken } from \"./security.js\";\nimport {\n detectDevServer,\n findAvailablePort,\n isPortOpen,\n detectDevScripts,\n getProjectName,\n checkDependenciesInstalled,\n verifyPortOwnership,\n checkNodeCompatibility,\n scanParentLockfiles,\n} from \"./detect.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { cleanupBackups } from \"./filesystem.js\";\n\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\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 = 60000,\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 const elapsed = Date.now() - start;\n if (elapsed > timeoutMs) {\n resolve(false);\n return;\n }\n // Aggressive early polling, then back off\n const interval = elapsed < 10000 ? 300 : 1000;\n setTimeout(check, interval);\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\n// Track which framework was detected (for diagnostic hints)\nlet detectedFramework: string | null = null;\n\n/**\n * After the proxy starts, check if the upstream app actually serves content.\n * If it returns 404, warn with framework-specific troubleshooting hints.\n */\nasync function validateAppHealth(targetHost: string, targetPort: number): Promise<void> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n const res = await fetch(`http://${targetHost}:${targetPort}/`, {\n signal: controller.signal,\n redirect: \"manual\",\n headers: { Accept: \"text/html\" },\n });\n clearTimeout(timeout);\n\n const status = res.status;\n\n // 2xx or redirect → app is healthy\n if (status >= 200 && status < 400) return;\n\n if (status === 404) {\n console.log(chalk.yellow(\" ⚠ Your app returned 404 for the root path (\\\"/\\\").\"));\n console.log(chalk.dim(\" The dev server is running, but no page matched.\"));\n console.log(\"\");\n\n if (detectedFramework === \"Next.js\") {\n const strayLockfiles = scanParentLockfiles(process.cwd());\n if (strayLockfiles.length > 0) {\n console.log(chalk.yellow(\" Found lockfiles in parent directories that confuse Turbopack:\"));\n for (const f of strayLockfiles) {\n console.log(chalk.dim(` • ${f}`));\n }\n console.log(\"\");\n console.log(chalk.dim(\" Fix: remove them, or add to your next.config:\"));\n console.log(chalk.cyan(\" turbopack: { root: __dirname }\"));\n } else {\n console.log(chalk.dim(\" Common Next.js causes:\"));\n console.log(chalk.dim(\" • Missing src/app/page.tsx (App Router) or pages/index.tsx\"));\n console.log(chalk.dim(\" • Middleware redirecting all routes to an auth provider\"));\n }\n } else if (detectedFramework === \"Angular\") {\n console.log(chalk.dim(\" Angular hint: ensure the base href matches the proxy path.\"));\n } else if (detectedFramework === \"Vite\") {\n console.log(chalk.dim(\" Vite hint: check that index.html exists in the project root.\"));\n } else {\n console.log(chalk.dim(\" Check your framework's routing configuration.\"));\n }\n\n console.log(\"\");\n console.log(chalk.dim(\" The toolbar is still available — navigate to a working route.\"));\n console.log(\"\");\n } else if (status >= 500) {\n console.log(chalk.yellow(` ⚠ Your app returned HTTP ${status} on the root path.`));\n console.log(chalk.dim(\" There may be a server-side error. Check your dev server output.\"));\n console.log(\"\");\n }\n } catch {\n // Connection failed or timeout — don't warn here, proxy error page handles it\n }\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\", \"localhost\")\n .action(async (opts) => {\n console.log(\"\");\n console.log(\n \" 🪄 \" + chalk.bold.hex(\"#6c5ce7\")(\"OpenMagic\") + chalk.dim(` v${VERSION}`) + \" ✨\"\n );\n console.log(chalk.dim(\" AI coding toolbar for any web app\"));\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 // Use port detected from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\n const recheck = await detectDevServer();\n if (recheck) { targetPort = recheck.port; targetHost = recheck.host; }\n }\n }\n } else {\n // Auto-detect running dev server\n console.log(chalk.dim(\" Scanning for dev server...\"));\n const detected = await detectDevServer();\n\n if (detected && detected.fromScripts) {\n // Trusted detection via package.json scripts\n targetPort = detected.port;\n targetHost = detected.host;\n } else if (detected && !detected.fromScripts) {\n // Found a port via generic scan — confirm with user\n const answer = await ask(\n chalk.yellow(` Found a server on port ${detected.port}. Is this your project's dev server? `) +\n chalk.dim(\"(y/n) \")\n );\n if (answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\" || answer === \"\") {\n targetPort = detected.port;\n targetHost = detected.host;\n } else {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n process.exit(0);\n }\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 // Use port from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\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\n // Detect framework for diagnostic hints (even if server was already running)\n if (!detectedFramework) {\n const scripts = detectDevScripts();\n if (scripts.length > 0) detectedFramework = scripts[0].framework;\n }\n\n console.log(\n chalk.green(` ✓ Dev server running at ${targetHost}:${targetPort}`)\n );\n\n // Proactive warning: detect parent lockfiles that confuse Turbopack\n if (detectedFramework === \"Next.js\") {\n const strayLockfiles = scanParentLockfiles(process.cwd());\n if (strayLockfiles.length > 0) {\n console.log(\"\");\n console.log(chalk.yellow(\" ⚠ Lockfiles found in parent directories:\"));\n for (const f of strayLockfiles) {\n console.log(chalk.dim(` • ${f}`));\n }\n console.log(chalk.dim(\" Next.js Turbopack may use the wrong workspace root, causing 404s.\"));\n console.log(chalk.dim(\" Fix: remove them, or add to next.config:\"));\n console.log(chalk.cyan(\" turbopack: { root: __dirname }\"));\n }\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, \"localhost\", async () => {\n const proxyUrl = `http://localhost:${proxyPort}`;\n console.log(\"\");\n console.log(chalk.bold.green(\" Ready!\"));\n console.log(\"\");\n console.log(\n chalk.bold(\" → \") + chalk.bold.underline.cyan(proxyUrl)\n );\n console.log(\"\");\n\n await healthCheck(proxyPort, targetPort!);\n\n // Validate the upstream app actually serves content\n await validateAppHealth(targetHost, targetPort!);\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 — kill child processes before exiting\n let shuttingDown = false;\n const shutdown = () => {\n if (shuttingDown) return;\n shuttingDown = true;\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n cleanupBackups();\n proxyServer.close();\n\n // Kill all child processes (dev server, static server, etc.)\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGTERM\"); } catch {}\n }\n\n // Force-kill after 2s, then exit\n const forceExit = setTimeout(() => {\n for (const cp of childProcesses) {\n try { cp.kill(\"SIGKILL\"); } catch {}\n }\n process.exit(0);\n }, 2000);\n forceExit.unref();\n\n // If all children are already dead, exit immediately\n const allDead = childProcesses.every((cp) => cp.killed || cp.exitCode !== null);\n if (allDead) {\n clearTimeout(forceExit);\n process.exit(0);\n }\n\n // Wait for children to exit\n let remaining = childProcesses.filter((cp) => !cp.killed && cp.exitCode === null).length;\n if (remaining === 0) { clearTimeout(forceExit); process.exit(0); }\n for (const cp of childProcesses) {\n cp.once(\"exit\", () => {\n remaining--;\n if (remaining <= 0) { clearTimeout(forceExit); process.exit(0); }\n });\n }\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 // Check for plain HTML project (index.html without package.json scripts)\n const htmlPath = join(process.cwd(), \"index.html\");\n if (existsSync(htmlPath)) {\n console.log(\n chalk.dim(\" No dev scripts found, but index.html detected.\")\n );\n console.log(\"\");\n const answer = await ask(\n chalk.white(\" Serve this directory as a static site? \") + chalk.dim(\"(Y/n) \")\n );\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n return false;\n }\n\n // Start a built-in static file server using Node's http module\n const staticPort = expectedPort || 8080;\n console.log(chalk.dim(` Starting static server on port ${staticPort}...`));\n\n const staticChild = spawn(\"node\", [\"-e\", `\n const http = require(\"http\");\n const fs = require(\"fs\");\n const path = require(\"path\");\n const mimes = {\".html\":\"text/html\",\".css\":\"text/css\",\".js\":\"application/javascript\",\".json\":\"application/json\",\".png\":\"image/png\",\".jpg\":\"image/jpeg\",\".svg\":\"image/svg+xml\",\".ico\":\"image/x-icon\",\".gif\":\"image/gif\",\".woff2\":\"font/woff2\",\".woff\":\"font/woff\"};\n http.createServer((req, res) => {\n let p = path.join(${JSON.stringify(process.cwd())}, req.url === \"/\" ? \"/index.html\" : req.url);\n try { p = decodeURIComponent(p); } catch {}\n fs.readFile(p, (err, data) => {\n if (err) { res.writeHead(404); res.end(\"Not found\"); return; }\n const ext = path.extname(p).toLowerCase();\n res.writeHead(200, {\"Content-Type\": mimes[ext] || \"application/octet-stream\"});\n res.end(data);\n });\n }).listen(${staticPort}, \"localhost\", () => console.log(\"Static server ready on port ${staticPort}\"));\n `], {\n cwd: process.cwd(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: false,\n });\n\n childProcesses.push(staticChild);\n staticChild.stdout?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().trim().split(\"\\n\")) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n // Wait for it to start\n const up = await waitForPort(staticPort, 5000);\n if (up) {\n lastDetectedPort = staticPort;\n console.log(chalk.green(` ✓ Static server running on port ${staticPort}`));\n return true;\n }\n console.log(chalk.red(\" ✗ Failed to start static server.\"));\n return false;\n }\n\n console.log(\n chalk.yellow(\" ⚠ No dev server detected and no dev scripts found.\")\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 // Track framework for diagnostic hints later\n detectedFramework = chosen.framework;\n\n // Pre-flight: check Node.js version compatibility\n const compat = checkNodeCompatibility(chosen.framework);\n if (!compat.ok) {\n console.log(chalk.red(`\\n ✗ ${compat.message}`));\n console.log(\"\");\n console.log(chalk.white(\" Switch Node.js version before running:\"));\n console.log(chalk.cyan(\" nvm use 20\"));\n console.log(chalk.dim(\" # then re-run: npx openmagic\"));\n console.log(\"\");\n return false;\n }\n\n // Start the dev server\n let port = expectedPort || chosen.defaultPort;\n\n // Check if the expected port is already occupied by another process\n let portChanged = false;\n if (await isPortOpen(port)) {\n const owned = verifyPortOwnership(port, process.cwd());\n if (owned === true) {\n // Port is occupied by this project — already running\n console.log(chalk.green(` ✓ Dev server already running on port ${port}`));\n lastDetectedPort = port;\n return true;\n }\n // Port is taken by something else — find a free one\n const altPort = await findAvailablePort(port + 1);\n console.log(\"\");\n console.log(\n chalk.yellow(` ⚠ Port ${port} is already in use by another process.`)\n );\n console.log(\n chalk.dim(` Starting on port ${altPort} instead.`)\n );\n port = altPort;\n portChanged = true;\n }\n\n console.log(\"\");\n console.log(\n chalk.dim(` Starting `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n (portChanged ? chalk.dim(` (port ${port})`) : \"\") +\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 // If port was changed due to conflict, pass --port to frameworks that accept it\n const PORT_FLAG_FRAMEWORKS = new Set([\"Next.js\", \"Vite\", \"Angular\", \"Vue CLI\", \"Astro\", \"Remix\", \"SvelteKit\", \"Nuxt\", \"Create React App\", \"Gatsby\", \"Parcel\", \"Webpack\"]);\n if (portChanged && PORT_FLAG_FRAMEWORKS.has(chosen.framework)) {\n if (runCmd === \"npm\") {\n runArgs.push(\"--\", \"--port\", String(port));\n } else {\n runArgs.push(\"--port\", String(port));\n }\n }\n\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(runCmd, runArgs, {\n cwd: process.cwd(),\n stdio: \"inherit\",\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.on(\"error\", (err) => {\n childExited = true;\n console.log(chalk.red(`\\n ✗ 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(`\\n ✗ 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.once(\"exit\", cleanup);\n process.once(\"SIGINT\", cleanup);\n process.once(\"SIGTERM\", cleanup);\n\n // Wait for the port to open via TCP polling\n console.log(\n chalk.dim(` Waiting for dev server on port ${port}...`)\n );\n\n const isUp = await waitForPort(port, 60000, () => childExited);\n\n if (isUp) {\n lastDetectedPort = port;\n console.log(\"\");\n return true;\n }\n\n // Port didn't open but process is still running — scan nearby ports\n if (!childExited) {\n const scanPorts = [port, 3000, 3001, 3002, 5173, 5174, 4200, 8080, 8000, 4000, 1234, 4321, 3333, 8081]\n .filter((p, i, a) => a.indexOf(p) === i); // dedupe\n for (const scanPort of scanPorts) {\n if (await isPortOpen(scanPort)) {\n const owned = verifyPortOwnership(scanPort, process.cwd());\n if (owned === false) continue;\n console.log(\n chalk.green(`\\n ✓ Dev server found on port ${scanPort}.`)\n );\n lastDetectedPort = scanPort;\n return true;\n }\n }\n }\n\n if (childExited) {\n console.log(\n chalk.red(` ✗ Dev server failed to start.`)\n );\n console.log(\"\");\n\n // Check for Node.js version mismatch\n try {\n const pkgPath = join(process.cwd(), \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n if (pkg.engines?.node) {\n console.log(chalk.yellow(` This project requires Node.js ${pkg.engines.node}`));\n console.log(chalk.dim(` You are running Node.js ${process.version}`));\n console.log(\"\");\n }\n }\n } catch {}\n\n // Also check framework-specific requirements\n if (chosen?.framework) {\n const compat = checkNodeCompatibility(chosen.framework);\n if (!compat.ok) {\n console.log(chalk.yellow(` ${compat.message}`));\n console.log(chalk.dim(\" Switch with: nvm use 20\"));\n console.log(\"\");\n }\n }\n\n console.log(chalk.white(\" Options:\"));\n console.log(chalk.dim(\" 1. Fix the error above and try again\"));\n console.log(chalk.dim(\" 2. Start the server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // All detection methods exhausted\n console.log(\n chalk.yellow(`\\n ⚠ Could not find the dev server after 60s.`)\n );\n console.log(chalk.dim(` Check the output above for errors.`));\n console.log(chalk.dim(` Or start the server manually, then run:`));\n console.log(chalk.cyan(` npx openmagic --port <your-port>`));\n console.log(\"\");\n return false;\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 changeOrigin: true, // Rewrite Host header to match upstream — required by Vite 5.4+ and some Next.js setups\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.on(\"error\", () => { try { res.end(); } catch {} });\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.on(\"error\", () => { try { res.end(buildInjectionScript(token)); } catch {} });\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 let totalSize = 0;\n proxyRes.on(\"data\", (c: Buffer) => { if (totalSize < 16384) { chunks.push(c); totalSize += c.length; } });\n proxyRes.on(\"error\", () => { try { res.end(); } catch {} });\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 } else if (res && typeof (res as any).destroy === \"function\") {\n // WebSocket socket error — destroy cleanly\n try { (res as any).destroy(); } catch {}\n }\n });\n\n // Shared references — set after server creation\n let omHandle: ((req: http.IncomingMessage, res: http.ServerResponse) => boolean) | null = null;\n let omUpgrade: ((req: http.IncomingMessage, socket: any, head: Buffer) => 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 endpoints to THIS server (same port, noServer WSS)\n const om = attachOpenMagic(server, roots);\n omHandle = om.handleRequest;\n omUpgrade = om.handleUpgrade;\n\n // Single upgrade handler — OpenMagic WS first, everything else to dev server\n server.on(\"upgrade\", (req, socket, head) => {\n // Try OpenMagic WebSocket first\n if (omUpgrade && omUpgrade(req, socket, head)) return;\n // Everything else (HMR, hot reload, etc.) forwarded 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, grepFiles, getBackupForFile, cleanupBackups } 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\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ── Server-side log buffer ──\nconst MAX_SERVER_LOGS = 200;\nconst serverLogs: { level: string; msg: string; ts: number }[] = [];\n\nfunction captureServerLog(level: string, ...args: any[]) {\n const msg = args.map(a => {\n try { return typeof a === \"object\" ? JSON.stringify(a).slice(0, 500) : String(a); }\n catch { return String(a); }\n }).join(\" \");\n serverLogs.push({ level, msg, ts: Date.now() });\n if (serverLogs.length > MAX_SERVER_LOGS) serverLogs.shift();\n}\n\n// Intercept console to buffer server logs\nconst _origLog = console.log, _origWarn = console.warn, _origErr = console.error, _origInfo = console.info;\nconsole.log = (...a: any[]) => { captureServerLog(\"log\", ...a); _origLog(...a); };\nconsole.warn = (...a: any[]) => { captureServerLog(\"warn\", ...a); _origWarn(...a); };\nconsole.error = (...a: any[]) => { captureServerLog(\"error\", ...a); _origErr(...a); };\nconsole.info = (...a: any[]) => { captureServerLog(\"info\", ...a); _origInfo(...a); };\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): {\n wss: WebSocketServer;\n handleRequest: (req: http.IncomingMessage, res: http.ServerResponse) => boolean;\n handleUpgrade: (req: http.IncomingMessage, socket: any, head: Buffer) => boolean;\n} {\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 — noServer mode so it doesn't intercept non-OpenMagic upgrades\n const wss = new WebSocketServer({ noServer: true });\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 // Handle WebSocket upgrades for OpenMagic path only\n function handleUpgrade(req: http.IncomingMessage, socket: any, head: Buffer): boolean {\n const urlPath = (req.url || \"\").split(\"?\")[0];\n if (urlPath === \"/__openmagic__/ws\") {\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit(\"connection\", ws, req);\n });\n return true;\n }\n return false;\n }\n\n return { wss, handleRequest, handleUpgrade };\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.undo\": {\n const payload = msg.payload as { path: string };\n if (!payload?.path) { sendError(ws, \"invalid_payload\", \"Missing path\", msg.id); break; }\n const backupPath = getBackupForFile(payload.path);\n if (!backupPath) { sendError(ws, \"fs_error\", \"No backup found\", msg.id); break; }\n try {\n const backupContent = readFileSync(backupPath, \"utf-8\");\n const writeResult = writeFileSafe(payload.path, backupContent, roots);\n if (!writeResult.ok) { sendError(ws, \"fs_error\", writeResult.error || \"Undo failed\", msg.id); break; }\n send(ws, { id: msg.id, type: \"fs.undone\", payload: { path: payload.path, ok: true } });\n } catch (e: unknown) {\n sendError(ws, \"fs_error\", `Backup read failed: ${(e as Error).message}`, msg.id);\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 case \"fs.grep\": {\n const payload = msg.payload as { pattern: string; path?: string };\n if (!payload?.pattern) {\n sendError(ws, \"invalid_payload\", \"Missing pattern\", msg.id);\n break;\n }\n const searchRoot = payload.path ? join(roots[0] || process.cwd(), payload.path) : (roots[0] || process.cwd());\n const results = grepFiles(payload.pattern, searchRoot, roots);\n send(ws, { id: msg.id, type: \"fs.grep.result\", payload: { results } });\n break;\n }\n\n case \"debug.logs\": {\n send(ws, {\n id: msg.id,\n type: \"debug.logs\",\n payload: {\n logs: serverLogs.slice(-100),\n nodeVersion: process.version,\n platform: process.platform,\n arch: process.arch,\n uptime: Math.round(process.uptime()),\n memoryMB: Math.round(process.memoryUsage().rss / 1024 / 1024),\n pid: process.pid,\n cwd: process.cwd(),\n },\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 unlinkSync,\n rmSync,\n} from \"node:fs\";\nimport { join, resolve, relative, dirname, extname } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { createHash } from \"node:crypto\";\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\n// ── Backup Management (temp directory) ──\nconst BACKUP_DIR = join(tmpdir(), \"openmagic-backups\");\nconst backupMap = new Map<string, string>(); // originalPath -> backupTempPath\n\nfunction getBackupPath(filePath: string): string {\n const hash = createHash(\"md5\").update(resolve(filePath)).digest(\"hex\").slice(0, 12);\n const name = filePath.split(/[/\\\\]/).pop() || \"file\";\n return join(BACKUP_DIR, `${hash}_${name}`);\n}\n\nexport function getBackupForFile(filePath: string): string | undefined {\n return backupMap.get(resolve(filePath));\n}\n\nexport function cleanupBackups(): void {\n try {\n if (existsSync(BACKUP_DIR)) {\n rmSync(BACKUP_DIR, { recursive: true, force: true });\n }\n } catch {}\n backupMap.clear();\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 in temp directory\n let backupPath: string | undefined;\n if (existsSync(filePath)) {\n if (!existsSync(BACKUP_DIR)) mkdirSync(BACKUP_DIR, { recursive: true });\n backupPath = getBackupPath(filePath);\n copyFileSync(filePath, backupPath);\n backupMap.set(resolve(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\nconst MAX_LIST_ENTRIES = 2000;\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 || entries.length >= MAX_LIST_ENTRIES) 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 (entries.length >= MAX_LIST_ENTRIES) return;\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\nconst GREP_EXTENSIONS = new Set([\n \".js\", \".jsx\", \".ts\", \".tsx\", \".mjs\", \".cjs\",\n \".vue\", \".svelte\", \".astro\",\n \".html\", \".htm\", \".css\", \".scss\", \".less\",\n \".json\", \".md\", \".yaml\", \".yml\",\n \".php\", \".py\", \".rb\",\n]);\n\nconst MAX_GREP_FILE_SIZE = 256 * 1024; // 256KB — skip large generated/bundled files\nconst MAX_GREP_FILES_SCANNED = 500; // stop walking after scanning this many files\n\nexport function grepFiles(\n pattern: string,\n searchRoot: string,\n roots: string[],\n maxResults: number = 30\n): { file: string; lineNum: number; line: string }[] {\n if (!isPathSafe(searchRoot, roots)) return [];\n\n const results: { file: string; lineNum: number; line: string }[] = [];\n const lowerPattern = pattern.toLowerCase();\n let filesScanned = 0;\n\n function walk(dir: string, depth: number): void {\n if (depth > 6 || results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n let items: string[];\n try { items = readdirSync(dir); } catch { return; }\n\n for (const item of items) {\n if (results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n if (IGNORED_DIRS.has(item) || (item.startsWith(\".\") && item !== \".env.example\")) continue;\n\n const fullPath = join(dir, item);\n let stat;\n try { stat = lstatSync(fullPath); } catch { continue; }\n if (stat.isSymbolicLink()) continue;\n\n if (stat.isDirectory()) {\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!GREP_EXTENSIONS.has(ext)) continue;\n if (stat.size > MAX_GREP_FILE_SIZE) continue; // skip large files\n filesScanned++;\n\n try {\n const content = readFileSync(fullPath, \"utf-8\");\n const lines = content.split(\"\\n\");\n let fileMatches = 0;\n for (let i = 0; i < lines.length && fileMatches < 5; i++) {\n if (lines[i].toLowerCase().includes(lowerPattern)) {\n results.push({\n file: relative(searchRoot, fullPath),\n lineNum: i + 1,\n line: lines[i].trim().slice(0, 200),\n });\n fileMatches++;\n }\n }\n } catch {}\n }\n }\n }\n\n walk(searchRoot, 0);\n return results;\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 // ─── Claude Code (CLI) ────────────────────────────────────────\n \"claude-code\": {\n name: \"Claude Code (CLI)\",\n models: [\n {\n id: \"claude-code\",\n name: \"Claude Code\",\n vision: false,\n context: 200000,\n maxOutput: 64000,\n },\n ],\n apiBase: \"\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── Codex CLI ────────────────────────────────────────────────\n \"codex-cli\": {\n name: \"Codex CLI\",\n models: [\n {\n id: \"codex-cli\",\n name: \"Codex CLI\",\n vision: false,\n context: 192000,\n maxOutput: 100000,\n },\n ],\n apiBase: \"\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── Gemini CLI ───────────────────────────────────────────────\n \"gemini-cli\": {\n name: \"Gemini CLI\",\n models: [\n {\n id: \"gemini-cli\",\n name: \"Gemini CLI\",\n vision: false,\n context: 1048576,\n maxOutput: 65536,\n },\n ],\n apiBase: \"\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\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. If the user is asking a QUESTION (not requesting a change), respond with {\"modifications\":[],\"explanation\":\"your answer here\"}. Only propose modifications when the user explicitly wants something changed.\n2. NEVER use delete+create to modify an existing file. Always use edit with search/replace. Only use create for genuinely new files that don't exist yet.\n3. Copy the search string EXACTLY from the grounded source files — do not retype, reformat, or change whitespace/indentation\n4. Include 3-5 lines of surrounding context in the search field to ensure uniqueness\n5. Keep modifications minimal — change only what's needed. Do NOT rewrite entire files.\n6. If the grounded files don't contain the code you need to modify, return: {\"modifications\":[],\"explanation\":\"NEED_FILE: exact/relative/path/to/file.ext\"}\n7. To search for a pattern across the codebase, return: {\"modifications\":[],\"explanation\":\"SEARCH_FILES: \\\\\"pattern\\\\\" in optional/path/\"}\n7. For style changes: check the dependencies (package.json) to know if the project uses Tailwind, MUI, etc. Use the project's styling approach, not raw CSS\n8. Use the selected element's cssSelector, className, parentContainerStyles, and siblings to understand the full layout context\n9. Use the page URL route and componentHint to identify the correct source file to modify\n10. Always preserve existing code style, conventions, and indentation\n11. ALWAYS respond with valid JSON only — no text before or after the JSON object`;\n\nexport function buildContextParts(context: LlmContext): Parameters<typeof buildUserMessage>[1] {\n const parts: Parameters<typeof buildUserMessage>[1] = {};\n\n // Send FULL element context with all available signals\n if (context.selectedElement) {\n const el = context.selectedElement as any;\n const elementData: Record<string, unknown> = {\n cssSelector: el.cssSelector,\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n outerHTML: el.outerHTML,\n computedStyles: el.computedStyles,\n ancestry: el.ancestry,\n componentHint: el.componentHint,\n };\n // Parent container styles (layout context)\n if (el.parentStyles && Object.keys(el.parentStyles).length) {\n elementData.parentContainerStyles = el.parentStyles;\n }\n // Sibling elements (what else is in the same container)\n if (el.siblings?.length) {\n elementData.siblings = el.siblings;\n }\n // Matched CSS rules from stylesheets\n if (el.matchedCssRules?.length) {\n elementData.matchedCssRules = el.matchedCssRules;\n }\n // Viewport dimensions\n if (el.viewport) {\n elementData.viewport = el.viewport;\n }\n // Accessibility attributes\n if (el.ariaAttributes && Object.keys(el.ariaAttributes).length) {\n elementData.ariaAttributes = el.ariaAttributes;\n }\n // Event handlers\n if (el.eventHandlers?.length) {\n elementData.eventHandlers = el.eventHandlers;\n }\n // React props\n if (el.reactProps) {\n elementData.reactProps = el.reactProps;\n }\n // Children layout measurements (pixel-level spacing between children)\n if (el.childrenLayout?.length) {\n elementData.childrenLayout = el.childrenLayout;\n }\n // Resolved Tailwind/utility classes to actual CSS values\n if (el.resolvedClasses?.length) {\n elementData.resolvedClasses = el.resolvedClasses;\n }\n parts.selectedElement = JSON.stringify(elementData, null, 2);\n }\n\n if (context.files?.length) {\n parts.files = context.files;\n }\n if (context.projectTree) parts.projectTree = context.projectTree;\n if ((context as any).pageUrl) parts.pageUrl = (context as any).pageUrl;\n if ((context as any).pageTitle) parts.pageTitle = (context as any).pageTitle;\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 if ((context as any).searchResults?.length) {\n parts.searchResults = (context as any).searchResults.map(\n (s: any) => `Search: \"${s.query}\"\\n${s.matches.map((m: any) => ` ${m.file}:${m.lineNum}: ${m.line}`).join(\"\\n\")}`\n ).join(\"\\n\\n\");\n }\n return parts;\n}\n\nexport function buildUserMessage(\n userPrompt: string,\n context: {\n selectedElement?: string;\n screenshot?: string;\n files?: Array<{ path: string; content: string }>;\n fileContent?: string;\n filePath?: string;\n networkLogs?: string;\n consoleLogs?: string;\n projectTree?: string;\n pageUrl?: string;\n pageTitle?: string;\n searchResults?: string;\n }\n): string {\n const parts: string[] = [];\n\n // Page context — helps LLM find the right route/page component\n if (context.pageUrl || context.pageTitle) {\n parts.push(`## Page Context\\nURL: ${context.pageUrl || \"unknown\"}\\nTitle: ${context.pageTitle || \"unknown\"}`);\n }\n\n if (context.projectTree) {\n parts.push(`## Project Structure\\n\\`\\`\\`\\n${context.projectTree}\\n\\`\\`\\``);\n }\n\n // Grounded source files\n if (context.files?.length) {\n parts.push(`## Grounded Source Files\\n${context.files.map(f => `### ${f.path}\\n\\`\\`\\`\\n${f.content}\\n\\`\\`\\``).join(\"\\n\\n\")}`);\n } else if (context.filePath && context.fileContent) {\n parts.push(`## Source File: ${context.filePath}\\n\\`\\`\\`\\n${context.fileContent}\\n\\`\\`\\``);\n }\n\n // Selected element — full context including selector, styles, ancestry\n if (context.selectedElement) {\n parts.push(`## Selected Element\\n\\`\\`\\`json\\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 if (context.searchResults) {\n parts.push(`## Search Results\\n\\`\\`\\`\\n${context.searchResults}\\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 { spawn } from \"node:child_process\";\nimport type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\n/**\n * Claude Code CLI adapter.\n * Spawns `claude -p` with the prompt and streams the response.\n * No API key needed — uses the user's existing Claude Code authentication.\n *\n * Docs: https://docs.anthropic.com/en/docs/claude-code\n * Flags verified from official CLI reference.\n */\n\n/**\n * Check if the `claude` CLI is available in PATH.\n */\nexport function isClaudeCliAvailable(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn(\"claude\", [\"--version\"], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n proc.on(\"error\", () => resolve(false));\n proc.on(\"close\", (code) => resolve(code === 0));\n });\n}\n\nexport async function chatClaudeCode(\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 // Build the prompt the same way as other providers\n const lastUserMsg = [...messages].reverse().find((m) => m.role === \"user\");\n const userPrompt =\n typeof lastUserMsg?.content === \"string\"\n ? lastUserMsg.content\n : \"Help me with this element.\";\n\n const contextParts = buildContextParts(context);\n const fullPrompt = buildUserMessage(userPrompt, contextParts);\n\n // Spawn claude -p with stream-json for real-time streaming\n // --verbose + --include-partial-messages: token-level streaming deltas\n // --max-turns 5: allows Claude to read files and produce a complete response\n const proc = spawn(\n \"claude\",\n [\n \"-p\",\n \"--output-format\", \"stream-json\",\n \"--verbose\",\n \"--include-partial-messages\",\n \"--max-turns\", \"5\",\n ],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: process.cwd(),\n env: {\n ...process.env,\n // Generous timeouts — Claude may read files and think between turns\n CLAUDE_STREAM_IDLE_TIMEOUT_MS: \"300000\", // 5 min idle timeout between chunks\n API_TIMEOUT_MS: \"600000\", // 10 min overall API timeout\n },\n }\n );\n\n // Send system prompt + user prompt via stdin\n proc.stdin.write(`${SYSTEM_PROMPT}\\n\\n${fullPrompt}`);\n proc.stdin.end();\n\n let fullContent = \"\";\n let resultContent = \"\"; // From the final result event\n let buffer = \"\";\n let errOutput = \"\";\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n buffer += data.toString();\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line);\n\n // Final result event — this is the authoritative response\n if (event.type === \"result\") {\n if (typeof event.result === \"string\") {\n resultContent = event.result;\n }\n continue;\n }\n\n const text = extractText(event);\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Not valid JSON — skip\n }\n }\n });\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n errOutput += data.toString();\n });\n\n proc.on(\"error\", (err) => {\n if (err.message.includes(\"ENOENT\")) {\n onError(\n \"Claude CLI not found. Install it with: npm install -g @anthropic-ai/claude-code\"\n );\n } else {\n onError(`Claude CLI error: ${err.message}`);\n }\n });\n\n proc.on(\"close\", (code) => {\n // Process remaining buffer\n if (buffer.trim()) {\n try {\n const event = JSON.parse(buffer);\n if (event.type === \"result\" && typeof event.result === \"string\") {\n resultContent = event.result;\n } else {\n const text = extractText(event);\n if (text) fullContent += text;\n }\n } catch {\n // ignore\n }\n }\n\n // Prefer the result event content (complete final answer) over streamed chunks\n const finalContent = resultContent || fullContent;\n\n if (code === 0 || finalContent) {\n onDone({ content: finalContent });\n } else {\n // Parse common errors\n const err = errOutput.trim();\n if (err.includes(\"not authenticated\") || err.includes(\"login\")) {\n onError(\"Claude CLI is not authenticated. Run `claude` in your terminal to log in.\");\n } else if (err.includes(\"ENOENT\") || err.includes(\"not found\")) {\n onError(\"Claude CLI not found. Install it with: npm install -g @anthropic-ai/claude-code\");\n } else {\n onError(err.slice(0, 500) || `Claude CLI exited with code ${code}`);\n }\n }\n });\n}\n\n/**\n * Extract text content from a stream-json event.\n * Handles multiple possible event formats from Claude Code CLI.\n */\nfunction extractText(event: Record<string, unknown>): string | undefined {\n // Format: {\"type\":\"assistant\",\"message\":{\"content\":[{\"type\":\"text\",\"text\":\"...\"}]}}\n if (event.type === \"assistant\") {\n const msg = event.message as Record<string, unknown> | undefined;\n if (msg?.content) {\n if (Array.isArray(msg.content)) {\n return msg.content\n .filter((b: any) => b.type === \"text\" && b.text)\n .map((b: any) => b.text)\n .join(\"\");\n }\n if (typeof msg.content === \"string\") return msg.content;\n }\n // Format: {\"type\":\"assistant\",\"text\":\"...\"}\n if (typeof event.text === \"string\") return event.text;\n }\n\n // Format: {\"type\":\"content_block_delta\",\"delta\":{\"text\":\"...\"}}\n if (event.type === \"content_block_delta\") {\n const delta = event.delta as Record<string, unknown> | undefined;\n if (typeof delta?.text === \"string\") return delta.text;\n }\n\n return undefined;\n}\n","import { spawn } from \"node:child_process\";\nimport type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\n/**\n * OpenAI Codex CLI adapter.\n * Uses `codex exec` — the non-interactive subcommand (no TTY required).\n * Streams JSONL events via --json flag.\n * Auth: uses OPENAI_API_KEY from env or codex's own auth.\n *\n * Docs: https://github.com/openai/codex\n * Event types verified from codex-rs/exec/src/exec_events.rs\n */\n\nexport async function chatCodexCli(\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 lastUserMsg = [...messages].reverse().find((m) => m.role === \"user\");\n const userPrompt =\n typeof lastUserMsg?.content === \"string\"\n ? lastUserMsg.content\n : \"Help me with this element.\";\n\n const contextParts = buildContextParts(context);\n const fullPrompt = `${SYSTEM_PROMPT}\\n\\n${buildUserMessage(userPrompt, contextParts)}`;\n\n // `codex exec` is the non-interactive subcommand (no TTY required)\n // --full-auto: auto-approve actions (alias for --sandbox workspace-write)\n // --json: structured JSONL output to stdout\n // --skip-git-repo-check: allow running outside git repos\n // - : read prompt from stdin\n const proc = spawn(\n \"codex\",\n [\"exec\", \"--full-auto\", \"--json\", \"--skip-git-repo-check\", \"-\"],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: process.cwd(),\n }\n );\n\n proc.stdin.write(fullPrompt);\n proc.stdin.end();\n\n let fullContent = \"\";\n let buffer = \"\";\n let errOutput = \"\";\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n buffer += data.toString();\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line);\n const text = extractCodexText(event);\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Not valid JSON — skip\n }\n }\n });\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n errOutput += data.toString();\n });\n\n proc.on(\"error\", (err) => {\n if (err.message.includes(\"ENOENT\")) {\n onError(\"Codex CLI not found. Install it with: npm install -g @openai/codex\");\n } else {\n onError(`Codex CLI error: ${err.message}`);\n }\n });\n\n proc.on(\"close\", (code) => {\n // Process remaining buffer\n if (buffer.trim()) {\n try {\n const event = JSON.parse(buffer);\n const text = extractCodexText(event);\n if (text) fullContent += text;\n } catch {\n // ignore\n }\n }\n\n if (code === 0 || fullContent.trim()) {\n onDone({ content: fullContent });\n } else {\n const err = errOutput.trim();\n if (err.includes(\"OPENAI_API_KEY\") || err.includes(\"api key\") || err.includes(\"unauthorized\")) {\n onError(\"Codex CLI requires OPENAI_API_KEY in your environment. Set it with: export OPENAI_API_KEY=sk-...\");\n } else {\n onError(err.slice(0, 500) || `Codex CLI exited with code ${code}`);\n }\n }\n });\n}\n\n/**\n * Extract text from a Codex JSONL event.\n *\n * Codex exec --json emits these event types:\n * - item.started / item.updated / item.completed with item payload\n * - Item types: agent_message (text), reasoning (text), command_execution, file_change, etc.\n * - turn.started / turn.completed / turn.failed\n * - thread.started\n * - error\n *\n * We extract text from agent_message items.\n */\nfunction extractCodexText(event: Record<string, unknown>): string | undefined {\n // item.completed or item.updated with agent_message\n if (\n event.type === \"item.completed\" ||\n event.type === \"item.updated\" ||\n event.type === \"item.started\"\n ) {\n const item = event.item as Record<string, unknown> | undefined;\n if (item?.type === \"agent_message\" && typeof item.text === \"string\") {\n return item.text;\n }\n }\n\n // Error event\n if (event.type === \"error\" && typeof (event as any).message === \"string\") {\n return undefined; // Don't stream errors as content\n }\n\n return undefined;\n}\n","import { spawn } from \"node:child_process\";\nimport type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\n/**\n * Google Gemini CLI adapter.\n * Uses `gemini -p` (non-interactive/headless mode) with stream-json output.\n * Auth: uses GEMINI_API_KEY from env or Google OAuth (if logged in interactively).\n *\n * Docs: https://github.com/google-gemini/gemini-cli\n * Flags verified from packages/cli/src/config/config.ts\n */\n\nexport async function chatGeminiCli(\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 lastUserMsg = [...messages].reverse().find((m) => m.role === \"user\");\n const userPrompt =\n typeof lastUserMsg?.content === \"string\"\n ? lastUserMsg.content\n : \"Help me with this element.\";\n\n const contextParts = buildContextParts(context);\n const fullPrompt = `${SYSTEM_PROMPT}\\n\\n${buildUserMessage(userPrompt, contextParts)}`;\n\n // gemini -p: non-interactive/headless mode (no TTY required)\n // --output-format stream-json: structured streaming output\n // --yolo: auto-accept all actions\n // Prompt is piped via stdin (auto-detected when stdin is not a TTY,\n // prepended to -p prompt)\n const proc = spawn(\n \"gemini\",\n [\n \"-p\", userPrompt,\n \"--output-format\", \"stream-json\",\n \"--yolo\",\n ],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: process.cwd(),\n }\n );\n\n // Send full context (system prompt + grounded files) via stdin\n // Gemini CLI prepends stdin content to the -p prompt\n proc.stdin.write(`${SYSTEM_PROMPT}\\n\\n${buildUserMessage(\"\", contextParts)}`);\n proc.stdin.end();\n\n let fullContent = \"\";\n let resultContent = \"\";\n let buffer = \"\";\n let errOutput = \"\";\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n buffer += data.toString();\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line);\n\n // Final result event\n if (event.type === \"result\") {\n if (typeof event.result === \"string\") {\n resultContent = event.result;\n }\n continue;\n }\n\n const text = extractGeminiText(event);\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Not JSON — treat as raw text\n const trimmed = line.trim();\n if (trimmed) {\n fullContent += trimmed + \"\\n\";\n onChunk(trimmed + \"\\n\");\n }\n }\n }\n });\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n errOutput += data.toString();\n });\n\n proc.on(\"error\", (err) => {\n if (err.message.includes(\"ENOENT\")) {\n onError(\"Gemini CLI not found. Install it with: npm install -g @google/gemini-cli\");\n } else {\n onError(`Gemini CLI error: ${err.message}`);\n }\n });\n\n proc.on(\"close\", (code) => {\n // Process remaining buffer\n if (buffer.trim()) {\n try {\n const event = JSON.parse(buffer);\n if (event.type === \"result\" && typeof event.result === \"string\") {\n resultContent = event.result;\n } else {\n const text = extractGeminiText(event);\n if (text) fullContent += text;\n }\n } catch {\n const trimmed = buffer.trim();\n if (trimmed) fullContent += trimmed;\n }\n }\n\n const finalContent = resultContent || fullContent;\n\n if (code === 0 || finalContent.trim()) {\n onDone({ content: finalContent });\n } else {\n const err = errOutput.trim();\n if (err.includes(\"auth\") || err.includes(\"GEMINI_API_KEY\") || err.includes(\"credentials\") || err.includes(\"login\")) {\n onError(\"Gemini CLI requires authentication. Set GEMINI_API_KEY in your environment, or run `gemini` interactively to log in with Google.\");\n } else {\n onError(err.slice(0, 500) || `Gemini CLI exited with code ${code}`);\n }\n }\n });\n}\n\n/**\n * Extract text from a Gemini CLI stream-json event.\n * Gemini CLI uses similar event formats to other AI CLIs.\n */\nfunction extractGeminiText(event: Record<string, unknown>): string | undefined {\n // Assistant message with content blocks\n if (event.type === \"assistant\" || event.type === \"message\") {\n const content = (event as any).content ?? (event as any).message?.content;\n if (Array.isArray(content)) {\n return content\n .filter((b: any) => b.type === \"text\" && b.text)\n .map((b: any) => b.text)\n .join(\"\");\n }\n if (typeof content === \"string\") return content;\n if (typeof (event as any).text === \"string\") return (event as any).text;\n }\n\n // Content block delta (streaming chunks)\n if (event.type === \"content_block_delta\") {\n const delta = event.delta as Record<string, unknown> | undefined;\n if (typeof delta?.text === \"string\") return delta.text;\n }\n\n return undefined;\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\";\nimport { chatClaudeCode } from \"./claude-code.js\";\nimport { chatCodexCli } from \"./codex-cli.js\";\nimport { chatGeminiCli } from \"./gemini-cli.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\nfunction extractJsonFromResponse(content: string): string | null {\n // Try markdown-wrapped JSON first (most common)\n const mdMatch = content.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n if (mdMatch?.[1]) {\n const candidate = mdMatch[1].trim();\n try { JSON.parse(candidate); return candidate; } catch {}\n }\n\n // Brace-counting extraction (handles raw JSON in response)\n const start = content.indexOf('{');\n if (start === -1) return null;\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (let i = start; i < content.length; i++) {\n const ch = content[i];\n if (escape) { escape = false; continue; }\n if (ch === '\\\\' && inString) { escape = true; continue; }\n if (ch === '\"') { inString = !inString; continue; }\n if (inString) continue;\n if (ch === '{') depth++;\n if (ch === '}') {\n depth--;\n if (depth === 0) {\n const candidate = content.substring(start, i + 1);\n try { JSON.parse(candidate); return candidate; } catch { return null; }\n }\n }\n }\n return null;\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 let modifications: LlmResponse[\"modifications\"] | undefined;\n try {\n const json = extractJsonFromResponse(result.content);\n if (json) {\n const parsed = JSON.parse(json) as LlmResponse;\n modifications = parsed.modifications;\n }\n } catch {\n // JSON parse failed — return raw content\n }\n onDone({ content: result.content, modifications });\n };\n\n try {\n if (provider === \"claude-code\") {\n await chatClaudeCode(messages, context, onChunk, wrappedOnDone, onError);\n } else if (provider === \"codex-cli\") {\n await chatCodexCli(messages, context, onChunk, wrappedOnDone, onError);\n } else if (provider === \"gemini-cli\") {\n await chatGeminiCli(messages, context, onChunk, wrappedOnDone, onError);\n } else 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, resolve } from \"node:path\";\nimport { execSync } from \"node:child_process\";\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 checkPortSingle(port: number, host: string): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host, timeout: 1000 });\n socket.unref();\n socket.on(\"connect\", () => { socket.destroy(); resolve(true); });\n socket.on(\"error\", () => { socket.destroy(); resolve(false); });\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n}\n\n// Check both IPv4 and IPv6 — many dev servers (Vite, Node) listen on ::1 only\nasync function checkPort(port: number, host: string = \"127.0.0.1\"): Promise<boolean> {\n const results = await Promise.all([\n checkPortSingle(port, host),\n checkPortSingle(port, \"::1\"),\n checkPortSingle(port, \"localhost\"),\n ]);\n return results.some(Boolean);\n}\n\nexport interface DetectedServer {\n port: number;\n host: string;\n fromScripts?: boolean; // true if detected via package.json scripts\n}\n\n/**\n * Check if the process listening on a port is running from (or near) the expected directory.\n * Uses lsof on macOS/Linux to get the PID, then checks its working directory.\n * Returns true if verified, false if wrong project, null if can't determine.\n */\nexport function verifyPortOwnership(port: number, expectedDir: string): boolean | null {\n try {\n // Get PIDs listening on this port\n const pidOutput = execSync(`lsof -i :${port} -sTCP:LISTEN -t 2>/dev/null`, {\n encoding: \"utf-8\",\n timeout: 3000,\n }).trim();\n\n if (!pidOutput) return null;\n\n const pids = pidOutput.split(\"\\n\").map((p) => p.trim()).filter(Boolean);\n const expected = resolve(expectedDir);\n\n for (const pid of pids) {\n try {\n // Get working directory of this process\n const cwdOutput = execSync(\n `lsof -a -p ${pid} -d cwd -Fn 2>/dev/null | grep ^n | head -1`,\n { encoding: \"utf-8\", timeout: 3000 }\n ).trim();\n\n if (!cwdOutput) continue;\n const processCwd = resolve(cwdOutput.slice(1)); // strip leading 'n'\n\n // Match if the process cwd is the project dir, a parent, or a child\n if (processCwd === expected || expected.startsWith(processCwd) || processCwd.startsWith(expected)) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n // We got PIDs but none matched the project directory\n return false;\n } catch {\n // lsof not available or failed — can't verify\n return null;\n }\n}\n\nexport async function detectDevServer(cwd: string = process.cwd()): Promise<DetectedServer | null> {\n // First: check ports hinted by the project's dev scripts + .env (most reliable)\n const scripts = detectDevScripts(cwd);\n const envPort = checkEnvPort(cwd);\n const scriptPorts = [\n ...(envPort ? [envPort] : []),\n ...scripts.map((s) => s.defaultPort),\n ].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 // Verify this port actually belongs to this project\n const owned = verifyPortOwnership(port, cwd);\n if (owned === false) {\n // Wrong project on this port — skip it\n continue;\n }\n return { port, host: \"localhost\", fromScripts: true };\n }\n }\n // Scripts exist but none running (or all belong to other projects)\n return null;\n }\n\n // No recognized scripts — scan common ports (but flag as unverified)\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\n for (const foundPort of results) {\n if (foundPort === null) continue;\n // For generic scan, also check ownership\n const owned = verifyPortOwnership(foundPort, cwd);\n if (owned === false) continue; // skip — belongs to another project\n return { port: foundPort, host: \"localhost\", fromScripts: false };\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\", \"server\", \"dev:server\", \"web\", \"frontend\"];\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\n// --- Node.js Version Compatibility ---\n\n// Minimum Node.js versions for modern frameworks (conservative — covers latest majors)\nconst FRAMEWORK_NODE_REQUIREMENTS: Record<string, { minNode: string; label: string }> = {\n \"Next.js\": { minNode: \"18.17.0\", label: \"Next.js 14+\" },\n \"Vite\": { minNode: \"18.0.0\", label: \"Vite 5+\" },\n \"Angular\": { minNode: \"18.13.0\", label: \"Angular 17+\" },\n \"SvelteKit\": { minNode: \"18.13.0\", label: \"SvelteKit 2+\" },\n \"Nuxt\": { minNode: \"18.0.0\", label: \"Nuxt 3+\" },\n \"Astro\": { minNode: \"18.14.1\", label: \"Astro 4+\" },\n \"Remix\": { minNode: \"18.0.0\", label: \"Remix 2+\" },\n \"Create React App\": { minNode: \"14.0.0\", label: \"Create React App\" },\n \"Gatsby\": { minNode: \"18.0.0\", label: \"Gatsby 5+\" },\n \"Vue CLI\": { minNode: \"14.0.0\", label: \"Vue CLI\" },\n \"Webpack\": { minNode: \"14.0.0\", label: \"Webpack 5+\" },\n \"Parcel\": { minNode: \"16.0.0\", label: \"Parcel 2+\" },\n};\n\nfunction semverGte(a: string, b: string): boolean {\n const pa = a.split(\".\").map(Number);\n const pb = b.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((pa[i] || 0) > (pb[i] || 0)) return true;\n if ((pa[i] || 0) < (pb[i] || 0)) return false;\n }\n return true; // equal\n}\n\nexport function checkNodeCompatibility(framework: string): { ok: boolean; message?: string } {\n const req = FRAMEWORK_NODE_REQUIREMENTS[framework];\n if (!req) return { ok: true };\n\n const current = process.versions.node;\n if (!semverGte(current, req.minNode)) {\n return {\n ok: false,\n message: `${req.label} requires Node.js >= ${req.minNode}, but you are running v${current}`,\n };\n }\n return { ok: true };\n}\n\n// --- .env PORT detection ---\n\n/**\n * Check .env files for a PORT variable. Helps detect when the dev server\n * is configured to run on a non-default port via environment.\n */\nexport function checkEnvPort(cwd: string = process.cwd()): number | null {\n const envFiles = [\".env.local\", \".env.development.local\", \".env.development\", \".env\"];\n for (const envFile of envFiles) {\n const envPath = join(cwd, envFile);\n if (!existsSync(envPath)) continue;\n try {\n const content = readFileSync(envPath, \"utf-8\");\n const match = content.match(/^PORT\\s*=\\s*(\\d+)/m);\n if (match) return parseInt(match[1], 10);\n } catch {\n continue;\n }\n }\n return null;\n}\n\n// --- Parent lockfile scanning (Turbopack workspace root detection) ---\n\nconst LOCKFILE_NAMES = [\"package-lock.json\", \"bun.lock\", \"bun.lockb\", \"yarn.lock\", \"pnpm-lock.yaml\"];\n\n/**\n * Scan parent directories for lockfiles that could confuse Turbopack's\n * workspace root detection. Returns paths of lockfiles found above the\n * project directory (up to and including the home directory).\n */\nexport function scanParentLockfiles(projectDir: string): string[] {\n const home = process.env.HOME || process.env.USERPROFILE || \"\";\n const project = resolve(projectDir);\n const found: string[] = [];\n\n let dir = resolve(project, \"..\");\n while (dir.length > 1 && dir.length >= home.length) {\n for (const lockfile of LOCKFILE_NAMES) {\n const p = join(dir, lockfile);\n if (existsSync(p)) found.push(p);\n }\n const parent = resolve(dir, \"..\");\n if (parent === dir) break;\n dir = parent;\n }\n\n return found;\n}\n\n// --- Project name ---\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","join","existsSync","readFileSync","spawn","readFileSync","existsSync","join","dirname","readFileSync","writeFileSync","existsSync","mkdirSync","join","modelInfo","spawn","spawn","spawn","spawn","dirname","readFileSync","join","existsSync","readFileSync","existsSync","join","resolve","createRequire","_require","VERSION","resolve","spawn","VERSION","resolve","join","existsSync","spawn","readFileSync","compat"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/proxy.ts","../src/security.ts","../src/server.ts","../src/config.ts","../src/llm/cli-detect.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/claude-code.ts","../src/llm/codex-cli.ts","../src/llm/gemini-cli.ts","../src/llm/proxy.ts","../src/detect.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { resolve, join } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { spawn, execSync, type ChildProcess } from \"node:child_process\";\nimport http from \"node:http\";\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[] = [];\nlet lastDetectedPort: number | null = null; // Port detected from dev server output\nimport { createProxyServer } from \"./proxy.js\";\nimport { generateSessionToken } from \"./security.js\";\nimport {\n detectDevServer,\n findAvailablePort,\n isPortOpen,\n detectDevScripts,\n getProjectName,\n checkDependenciesInstalled,\n verifyPortOwnership,\n checkNodeCompatibility,\n scanParentLockfiles,\n} from \"./detect.js\";\nimport { loadConfig, saveConfig } from \"./config.js\";\nimport { cleanupBackups } from \"./filesystem.js\";\n\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\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\n/** Wait for a port to CLOSE (become free). Used after killing orphan processes. */\nfunction waitForPortClose(port: number, timeoutMs: number = 10000): Promise<boolean> {\n const start = Date.now();\n return new Promise((resolve) => {\n const check = async () => {\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, 300);\n };\n check();\n });\n}\n\n/**\n * Kill a process listening on a given port.\n * Returns true if the process was killed and the port freed.\n */\nfunction killPortProcess(port: number): boolean {\n try {\n const pidOutput = execSync(`lsof -i :${port} -sTCP:LISTEN -t 2>/dev/null`, {\n encoding: \"utf-8\",\n timeout: 3000,\n }).trim();\n if (!pidOutput) return false;\n const pids = pidOutput.split(\"\\n\").map((p) => p.trim()).filter(Boolean);\n for (const pid of pids) {\n try { process.kill(parseInt(pid, 10), \"SIGTERM\"); } catch {}\n }\n return pids.length > 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a server on the given port is healthy (responds with non-error status).\n * Returns true if healthy, false if not responding or returning errors.\n */\n/**\n * Check if a server on the given port is healthy (responds with non-error status).\n * Returns true if healthy, false if not responding or returning errors.\n */\nfunction isPortHealthy(host: string, port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const req = http.get(\n `http://${host}:${port}/`,\n { timeout: 3000 },\n (res) => {\n // 2xx/3xx = healthy, 4xx/5xx = unhealthy\n resolve(res.statusCode !== undefined && res.statusCode < 400);\n res.resume(); // drain\n }\n );\n req.on(\"error\", () => resolve(false));\n req.on(\"timeout\", () => { req.destroy(); resolve(false); });\n });\n}\n\nfunction waitForPort(\n port: number,\n timeoutMs: number = 60000,\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 const elapsed = Date.now() - start;\n if (elapsed > timeoutMs) {\n resolve(false);\n return;\n }\n // Aggressive early polling, then back off\n const interval = elapsed < 10000 ? 300 : 1000;\n setTimeout(check, interval);\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\n// Track which framework was detected (for diagnostic hints)\nlet detectedFramework: string | null = null;\n\n/**\n * After the proxy starts, check if the upstream app actually serves content.\n * If it returns 404, warn with framework-specific troubleshooting hints.\n */\nasync function validateAppHealth(targetHost: string, targetPort: number): Promise<void> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 8000);\n\n const res = await fetch(`http://${targetHost}:${targetPort}/`, {\n signal: controller.signal,\n redirect: \"manual\",\n headers: { Accept: \"text/html\" },\n });\n clearTimeout(timeout);\n\n const status = res.status;\n\n // 2xx or redirect → app is healthy\n if (status >= 200 && status < 400) return;\n\n if (status === 404) {\n console.log(chalk.yellow(\" ⚠ Your app returned 404 for the root path (\\\"/\\\").\"));\n console.log(chalk.dim(\" The dev server is running, but no page matched.\"));\n console.log(\"\");\n\n if (detectedFramework === \"Next.js\") {\n const strayLockfiles = scanParentLockfiles(process.cwd());\n if (strayLockfiles.length > 0) {\n console.log(chalk.yellow(\" Found lockfiles in parent directories that confuse Turbopack:\"));\n for (const f of strayLockfiles) {\n console.log(chalk.dim(` • ${f}`));\n }\n console.log(\"\");\n console.log(chalk.dim(\" Fix: remove them, or add to your next.config:\"));\n console.log(chalk.cyan(\" turbopack: { root: __dirname }\"));\n } else {\n console.log(chalk.dim(\" Common Next.js causes:\"));\n console.log(chalk.dim(\" • Missing src/app/page.tsx (App Router) or pages/index.tsx\"));\n console.log(chalk.dim(\" • Middleware redirecting all routes to an auth provider\"));\n }\n } else if (detectedFramework === \"Angular\") {\n console.log(chalk.dim(\" Angular hint: ensure the base href matches the proxy path.\"));\n } else if (detectedFramework === \"Vite\") {\n console.log(chalk.dim(\" Vite hint: check that index.html exists in the project root.\"));\n } else {\n console.log(chalk.dim(\" Check your framework's routing configuration.\"));\n }\n\n console.log(\"\");\n console.log(chalk.dim(\" The toolbar is still available — navigate to a working route.\"));\n console.log(\"\");\n } else if (status >= 500) {\n console.log(chalk.yellow(` ⚠ Your app returned HTTP ${status} on the root path.`));\n console.log(chalk.dim(\" There may be a server-side error. Check your dev server output.\"));\n console.log(\"\");\n }\n } catch {\n // Connection failed or timeout — don't warn here, proxy error page handles it\n }\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\", \"localhost\")\n .action(async (opts) => {\n console.log(\"\");\n console.log(\n \" 🪄 \" + chalk.bold.hex(\"#6c5ce7\")(\"OpenMagic\") + chalk.dim(` v${VERSION}`) + \" ✨\"\n );\n console.log(chalk.dim(\" AI coding toolbar for any web app\"));\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 // Use port detected from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\n const recheck = await detectDevServer();\n if (recheck) { targetPort = recheck.port; targetHost = recheck.host; }\n }\n }\n } else {\n // Auto-detect running dev server\n console.log(chalk.dim(\" Scanning for dev server...\"));\n const detected = await detectDevServer();\n\n if (detected && detected.fromScripts) {\n // Trusted detection via package.json scripts — but verify it's healthy.\n // An orphaned dev server from a previous OpenMagic session may still be\n // on the port but serving errors (zombie/dying process).\n const healthy = await isPortHealthy(detected.host, detected.port);\n if (healthy) {\n targetPort = detected.port;\n targetHost = detected.host;\n } else {\n console.log(chalk.yellow(` ⚠ Dev server on port ${detected.port} is not responding properly.`));\n console.log(chalk.dim(\" Cleaning up orphaned process...\"));\n killPortProcess(detected.port);\n // Wait for the port to be freed\n const freed = await waitForPortClose(detected.port, 5000);\n if (!freed) {\n // Force kill\n try {\n const pidOutput = execSync(`lsof -i :${detected.port} -sTCP:LISTEN -t 2>/dev/null`, {\n encoding: \"utf-8\", timeout: 3000,\n }).trim();\n for (const pid of pidOutput.split(\"\\n\").filter(Boolean)) {\n try { process.kill(parseInt(pid, 10), \"SIGKILL\"); } catch {}\n }\n await waitForPortClose(detected.port, 3000);\n } catch {}\n }\n // Start a fresh dev server\n const started = await offerToStartDevServer();\n if (!started) { process.exit(1); }\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\n const redetected = await detectDevServer();\n if (redetected) {\n targetPort = redetected.port;\n targetHost = redetected.host;\n } else {\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 process.exit(1);\n }\n }\n }\n } else if (detected && !detected.fromScripts) {\n // Found a port via generic scan — confirm with user\n const answer = await ask(\n chalk.yellow(` Found a server on port ${detected.port}. Is this your project's dev server? `) +\n chalk.dim(\"(y/n) \")\n );\n if (answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\" || answer === \"\") {\n targetPort = detected.port;\n targetHost = detected.host;\n } else {\n console.log(\"\");\n console.log(chalk.dim(\" Start your dev server, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n process.exit(0);\n }\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 // Use port from dev server output, or re-detect\n if (lastDetectedPort) {\n targetPort = lastDetectedPort;\n } else {\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\n // Detect framework for diagnostic hints (even if server was already running)\n if (!detectedFramework) {\n const scripts = detectDevScripts();\n if (scripts.length > 0) detectedFramework = scripts[0].framework;\n }\n\n console.log(\n chalk.green(` ✓ Dev server running at ${targetHost}:${targetPort}`)\n );\n\n // Proactive warning: detect parent lockfiles that confuse Turbopack\n if (detectedFramework === \"Next.js\") {\n const strayLockfiles = scanParentLockfiles(process.cwd());\n if (strayLockfiles.length > 0) {\n console.log(\"\");\n console.log(chalk.yellow(\" ⚠ Lockfiles found in parent directories:\"));\n for (const f of strayLockfiles) {\n console.log(chalk.dim(` • ${f}`));\n }\n console.log(chalk.dim(\" Next.js Turbopack may use the wrong workspace root, causing 404s.\"));\n console.log(chalk.dim(\" Fix: remove them, or add to next.config:\"));\n console.log(chalk.cyan(\" turbopack: { root: __dirname }\"));\n }\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, \"localhost\", async () => {\n const proxyUrl = `http://localhost:${proxyPort}`;\n console.log(\"\");\n console.log(chalk.bold.green(\" Ready!\"));\n console.log(\"\");\n console.log(\n chalk.bold(\" → \") + chalk.bold.underline.cyan(proxyUrl)\n );\n console.log(\"\");\n\n await healthCheck(proxyPort, targetPort!);\n\n // Validate the upstream app actually serves content\n await validateAppHealth(targetHost, targetPort!);\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 — ensure child processes AND the dev server port are\n // fully released before exiting. This prevents the \"404 on restart\" bug\n // where an orphaned dev server zombie holds the port.\n //\n // Strategy:\n // 1. SIGTERM direct children (they also got SIGINT from the terminal)\n // 2. Kill any process still listening on the dev server port (catches grandchildren)\n // 3. Wait for the port to actually close (TCP poll)\n // 4. SIGKILL anything remaining after 3s\n // 5. Only then call process.exit(0)\n let shuttingDown = false;\n const shutdown = async () => {\n if (shuttingDown) return;\n shuttingDown = true;\n console.log(\"\");\n console.log(chalk.dim(\" Shutting down OpenMagic...\"));\n cleanupBackups();\n proxyServer.close();\n\n // Step 1: SIGTERM direct children\n const alive = childProcesses.filter((cp) => cp.exitCode === null);\n for (const cp of alive) {\n try { cp.kill(\"SIGTERM\"); } catch {}\n }\n\n // Step 2: Also kill anything on the dev server port (catches grandchildren\n // like Next.js workers that our direct child.kill() won't reach)\n if (targetPort) {\n killPortProcess(targetPort);\n }\n\n // Step 3: Wait for the port to actually close (poll every 200ms, up to 4s)\n if (targetPort && (await isPortOpen(targetPort))) {\n const freed = await waitForPortClose(targetPort, 4000);\n if (!freed) {\n // Step 4: Force-kill everything on the port\n console.log(chalk.dim(\" Force-killing remaining processes...\"));\n if (targetPort) {\n try {\n const pids = execSync(`lsof -i :${targetPort} -sTCP:LISTEN -t 2>/dev/null`, {\n encoding: \"utf-8\", timeout: 2000,\n }).trim().split(\"\\n\").filter(Boolean);\n for (const pid of pids) {\n try { process.kill(parseInt(pid, 10), \"SIGKILL\"); } catch {}\n }\n } catch {}\n }\n for (const cp of childProcesses) {\n if (cp.exitCode === null) {\n try { cp.kill(\"SIGKILL\"); } catch {}\n }\n }\n // Brief wait for SIGKILL to take effect\n await new Promise((r) => setTimeout(r, 300));\n }\n } else {\n // No port to wait on — just wait for children\n if (alive.length > 0) {\n await Promise.race([\n Promise.all(alive.map((cp) => new Promise<void>((r) => {\n if (cp.exitCode !== null) { r(); return; }\n cp.once(\"exit\", () => r());\n }))),\n new Promise<void>((r) => setTimeout(() => {\n for (const cp of childProcesses) {\n if (cp.exitCode === null) try { cp.kill(\"SIGKILL\"); } catch {}\n }\n setTimeout(r, 200);\n }, 3000)),\n ]);\n }\n }\n\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 // Check for plain HTML project (index.html without package.json scripts)\n const htmlPath = join(process.cwd(), \"index.html\");\n if (existsSync(htmlPath)) {\n console.log(\n chalk.dim(\" No dev scripts found, but index.html detected.\")\n );\n console.log(\"\");\n const answer = await ask(\n chalk.white(\" Serve this directory as a static site? \") + chalk.dim(\"(Y/n) \")\n );\n if (answer.toLowerCase() === \"n\" || answer.toLowerCase() === \"no\") {\n return false;\n }\n\n // Start a built-in static file server using Node's http module\n const staticPort = expectedPort || 8080;\n console.log(chalk.dim(` Starting static server on port ${staticPort}...`));\n\n const staticChild = spawn(\"node\", [\"-e\", `\n const http = require(\"http\");\n const fs = require(\"fs\");\n const path = require(\"path\");\n const mimes = {\".html\":\"text/html\",\".css\":\"text/css\",\".js\":\"application/javascript\",\".json\":\"application/json\",\".png\":\"image/png\",\".jpg\":\"image/jpeg\",\".svg\":\"image/svg+xml\",\".ico\":\"image/x-icon\",\".gif\":\"image/gif\",\".woff2\":\"font/woff2\",\".woff\":\"font/woff\"};\n http.createServer((req, res) => {\n let p = path.join(${JSON.stringify(process.cwd())}, req.url === \"/\" ? \"/index.html\" : req.url);\n try { p = decodeURIComponent(p); } catch {}\n fs.readFile(p, (err, data) => {\n if (err) { res.writeHead(404); res.end(\"Not found\"); return; }\n const ext = path.extname(p).toLowerCase();\n res.writeHead(200, {\"Content-Type\": mimes[ext] || \"application/octet-stream\"});\n res.end(data);\n });\n }).listen(${staticPort}, \"localhost\", () => console.log(\"Static server ready on port ${staticPort}\"));\n `], {\n cwd: process.cwd(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: false,\n });\n\n childProcesses.push(staticChild);\n staticChild.stdout?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().trim().split(\"\\n\")) {\n if (line.trim()) process.stdout.write(chalk.dim(` │ ${line}\\n`));\n }\n });\n\n // Wait for it to start\n const up = await waitForPort(staticPort, 5000);\n if (up) {\n lastDetectedPort = staticPort;\n console.log(chalk.green(` ✓ Static server running on port ${staticPort}`));\n return true;\n }\n console.log(chalk.red(\" ✗ Failed to start static server.\"));\n return false;\n }\n\n console.log(\n chalk.yellow(\" ⚠ No dev server detected and no dev scripts found.\")\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 // Track framework for diagnostic hints later\n detectedFramework = chosen.framework;\n\n // Pre-flight: check Node.js version compatibility\n const compat = checkNodeCompatibility(chosen.framework);\n if (!compat.ok) {\n console.log(chalk.red(`\\n ✗ ${compat.message}`));\n console.log(\"\");\n console.log(chalk.white(\" Switch Node.js version before running:\"));\n console.log(chalk.cyan(\" nvm use 20\"));\n console.log(chalk.dim(\" # then re-run: npx openmagic\"));\n console.log(\"\");\n return false;\n }\n\n // Start the dev server\n let port = expectedPort || chosen.defaultPort;\n\n // Check if the expected port is already occupied by another process\n let portChanged = false;\n if (await isPortOpen(port)) {\n const owned = verifyPortOwnership(port, process.cwd());\n if (owned === true) {\n // Port is occupied by this project — already running\n console.log(chalk.green(` ✓ Dev server already running on port ${port}`));\n lastDetectedPort = port;\n return true;\n }\n // Port is taken by something else — find a free one\n const altPort = await findAvailablePort(port + 1);\n console.log(\"\");\n console.log(\n chalk.yellow(` ⚠ Port ${port} is already in use by another process.`)\n );\n console.log(\n chalk.dim(` Starting on port ${altPort} instead.`)\n );\n port = altPort;\n portChanged = true;\n }\n\n console.log(\"\");\n console.log(\n chalk.dim(` Starting `) +\n chalk.cyan(`npm run ${chosen.name}`) +\n (portChanged ? chalk.dim(` (port ${port})`) : \"\") +\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 // If port was changed due to conflict, pass --port to frameworks that accept it\n const PORT_FLAG_FRAMEWORKS = new Set([\"Next.js\", \"Vite\", \"Angular\", \"Vue CLI\", \"Astro\", \"Remix\", \"SvelteKit\", \"Nuxt\", \"Create React App\", \"Gatsby\", \"Parcel\", \"Webpack\"]);\n if (portChanged && PORT_FLAG_FRAMEWORKS.has(chosen.framework)) {\n if (runCmd === \"npm\") {\n runArgs.push(\"--\", \"--port\", String(port));\n } else {\n runArgs.push(\"--port\", String(port));\n }\n }\n\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(runCmd, runArgs, {\n cwd: process.cwd(),\n stdio: \"inherit\",\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.on(\"error\", (err) => {\n childExited = true;\n console.log(chalk.red(`\\n ✗ 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(`\\n ✗ Dev server exited with code ${code}`));\n }\n });\n\n // Safety-net cleanup on exit (main shutdown handler does the real work)\n process.once(\"exit\", () => {\n for (const cp of childProcesses) {\n if (cp.exitCode === null) {\n try { cp.kill(\"SIGKILL\"); } catch {}\n }\n }\n });\n\n // Wait for the port to open via TCP polling\n console.log(\n chalk.dim(` Waiting for dev server on port ${port}...`)\n );\n\n const isUp = await waitForPort(port, 60000, () => childExited);\n\n if (isUp) {\n lastDetectedPort = port;\n console.log(\"\");\n return true;\n }\n\n // Port didn't open but process is still running — scan nearby ports\n if (!childExited) {\n const scanPorts = [port, 3000, 3001, 3002, 5173, 5174, 4200, 8080, 8000, 4000, 1234, 4321, 3333, 8081]\n .filter((p, i, a) => a.indexOf(p) === i); // dedupe\n for (const scanPort of scanPorts) {\n if (await isPortOpen(scanPort)) {\n const owned = verifyPortOwnership(scanPort, process.cwd());\n if (owned === false) continue;\n console.log(\n chalk.green(`\\n ✓ Dev server found on port ${scanPort}.`)\n );\n lastDetectedPort = scanPort;\n return true;\n }\n }\n }\n\n if (childExited) {\n console.log(\n chalk.red(` ✗ Dev server failed to start.`)\n );\n console.log(\"\");\n\n // Check for Node.js version mismatch\n try {\n const pkgPath = join(process.cwd(), \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n if (pkg.engines?.node) {\n console.log(chalk.yellow(` This project requires Node.js ${pkg.engines.node}`));\n console.log(chalk.dim(` You are running Node.js ${process.version}`));\n console.log(\"\");\n }\n }\n } catch {}\n\n // Also check framework-specific requirements\n if (chosen?.framework) {\n const compat = checkNodeCompatibility(chosen.framework);\n if (!compat.ok) {\n console.log(chalk.yellow(` ${compat.message}`));\n console.log(chalk.dim(\" Switch with: nvm use 20\"));\n console.log(\"\");\n }\n }\n\n console.log(chalk.white(\" Options:\"));\n console.log(chalk.dim(\" 1. Fix the error above and try again\"));\n console.log(chalk.dim(\" 2. Start the server manually, then run:\"));\n console.log(chalk.cyan(\" npx openmagic --port <your-port>\"));\n console.log(\"\");\n return false;\n }\n\n // All detection methods exhausted\n console.log(\n chalk.yellow(`\\n ⚠ Could not find the dev server after 60s.`)\n );\n console.log(chalk.dim(` Check the output above for errors.`));\n console.log(chalk.dim(` Or start the server manually, then run:`));\n console.log(chalk.cyan(` npx openmagic --port <your-port>`));\n console.log(\"\");\n return false;\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 changeOrigin: true, // Rewrite Host header to match upstream — required by Vite 5.4+ and some Next.js setups\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.on(\"error\", () => { try { res.end(); } catch {} });\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.on(\"error\", () => { try { res.end(buildInjectionScript(token)); } catch {} });\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 let totalSize = 0;\n proxyRes.on(\"data\", (c: Buffer) => { if (totalSize < 16384) { chunks.push(c); totalSize += c.length; } });\n proxyRes.on(\"error\", () => { try { res.end(); } catch {} });\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 } else if (res && typeof (res as any).destroy === \"function\") {\n // WebSocket socket error — destroy cleanly\n try { (res as any).destroy(); } catch {}\n }\n });\n\n // Shared references — set after server creation\n let omHandle: ((req: http.IncomingMessage, res: http.ServerResponse) => boolean) | null = null;\n let omUpgrade: ((req: http.IncomingMessage, socket: any, head: Buffer) => 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 endpoints to THIS server (same port, noServer WSS)\n const om = attachOpenMagic(server, roots);\n omHandle = om.handleRequest;\n omUpgrade = om.handleUpgrade;\n\n // Single upgrade handler — OpenMagic WS first, everything else to dev server\n server.on(\"upgrade\", (req, socket, head) => {\n // Try OpenMagic WebSocket first\n if (omUpgrade && omUpgrade(req, socket, head)) return;\n // Everything else (HMR, hot reload, etc.) forwarded 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 { detectAvailableClis, invalidateCliCache } from \"./llm/cli-detect.js\";\nimport { readFileSafe, writeFileSafe, listFiles, getProjectTree, grepFiles, getBackupForFile, cleanupBackups } 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\nimport { createRequire } from \"node:module\";\nconst _require = createRequire(import.meta.url);\nconst VERSION: string = _require(\"../package.json\").version;\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ── Server-side log buffer ──\nconst MAX_SERVER_LOGS = 200;\nconst serverLogs: { level: string; msg: string; ts: number }[] = [];\n\nfunction captureServerLog(level: string, ...args: any[]) {\n const msg = args.map(a => {\n try { return typeof a === \"object\" ? JSON.stringify(a).slice(0, 500) : String(a); }\n catch { return String(a); }\n }).join(\" \");\n serverLogs.push({ level, msg, ts: Date.now() });\n if (serverLogs.length > MAX_SERVER_LOGS) serverLogs.shift();\n}\n\n// Intercept console to buffer server logs\nconst _origLog = console.log, _origWarn = console.warn, _origErr = console.error, _origInfo = console.info;\nconsole.log = (...a: any[]) => { captureServerLog(\"log\", ...a); _origLog(...a); };\nconsole.warn = (...a: any[]) => { captureServerLog(\"warn\", ...a); _origWarn(...a); };\nconsole.error = (...a: any[]) => { captureServerLog(\"error\", ...a); _origErr(...a); };\nconsole.info = (...a: any[]) => { captureServerLog(\"info\", ...a); _origInfo(...a); };\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): {\n wss: WebSocketServer;\n handleRequest: (req: http.IncomingMessage, res: http.ServerResponse) => boolean;\n handleUpgrade: (req: http.IncomingMessage, socket: any, head: Buffer) => boolean;\n} {\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 — noServer mode so it doesn't intercept non-OpenMagic upgrades\n const wss = new WebSocketServer({ noServer: true });\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 // Handle WebSocket upgrades for OpenMagic path only\n function handleUpgrade(req: http.IncomingMessage, socket: any, head: Buffer): boolean {\n const urlPath = (req.url || \"\").split(\"?\")[0];\n if (urlPath === \"/__openmagic__/ws\") {\n wss.handleUpgrade(req, socket, head, (ws) => {\n wss.emit(\"connection\", ws, req);\n });\n return true;\n }\n return false;\n }\n\n return { wss, handleRequest, handleUpgrade };\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.undo\": {\n const payload = msg.payload as { path: string };\n if (!payload?.path) { sendError(ws, \"invalid_payload\", \"Missing path\", msg.id); break; }\n const backupPath = getBackupForFile(payload.path);\n if (!backupPath) { sendError(ws, \"fs_error\", \"No backup found\", msg.id); break; }\n try {\n const backupContent = readFileSync(backupPath, \"utf-8\");\n const writeResult = writeFileSafe(payload.path, backupContent, roots);\n if (!writeResult.ok) { sendError(ws, \"fs_error\", writeResult.error || \"Undo failed\", msg.id); break; }\n send(ws, { id: msg.id, type: \"fs.undone\", payload: { path: payload.path, ok: true } });\n } catch (e: unknown) {\n sendError(ws, \"fs_error\", `Backup read failed: ${(e as Error).message}`, msg.id);\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\n // Auto-detect available CLI agents\n const detectedClis = await detectAvailableClis();\n const cliStatuses = detectedClis.map((c) => ({\n id: c.id,\n name: c.name,\n installed: c.installed,\n authenticated: c.authenticated,\n version: c.version,\n }));\n\n // Auto-select: if no provider is saved, pick the best available CLI\n let provider = config.provider || \"\";\n let model = config.model || \"\";\n if (!provider) {\n const bestCli = detectedClis.find((c) => c.installed && c.authenticated);\n if (bestCli) {\n provider = bestCli.id;\n model = bestCli.id; // CLI providers use same ID for model\n }\n }\n\n send(ws, {\n id: msg.id,\n type: \"config.value\",\n payload: {\n provider,\n model,\n hasApiKey: !!(config.apiKeys?.[provider] || config.apiKey),\n roots: config.roots || roots,\n apiKeys: Object.fromEntries(\n Object.entries(config.apiKeys || {}).map(([k]) => [k, true])\n ),\n detectedClis: cliStatuses,\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 case \"fs.grep\": {\n const payload = msg.payload as { pattern: string; path?: string };\n if (!payload?.pattern) {\n sendError(ws, \"invalid_payload\", \"Missing pattern\", msg.id);\n break;\n }\n const searchRoot = payload.path ? join(roots[0] || process.cwd(), payload.path) : (roots[0] || process.cwd());\n const results = grepFiles(payload.pattern, searchRoot, roots);\n send(ws, { id: msg.id, type: \"fs.grep.result\", payload: { results } });\n break;\n }\n\n case \"debug.logs\": {\n send(ws, {\n id: msg.id,\n type: \"debug.logs\",\n payload: {\n logs: serverLogs.slice(-100),\n nodeVersion: process.version,\n platform: process.platform,\n arch: process.arch,\n uptime: Math.round(process.uptime()),\n memoryMB: Math.round(process.memoryUsage().rss / 1024 / 1024),\n pid: process.pid,\n cwd: process.cwd(),\n },\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 { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n/**\n * Auto-detection for CLI coding agents (Claude Code, Codex, Gemini).\n *\n * Detection is two-phase:\n * 1. Install check: spawn(\"cmd\", [\"--version\"]) — fast, cross-platform\n * 2. Auth check: file/env var inspection — no process spawn needed\n *\n * Priority order (based on benchmark performance):\n * 1. Claude Code — 80.9% SWE-bench, best multi-file coherence\n * 2. Codex CLI — 77.3% Terminal-Bench, strong autonomous execution\n * 3. Gemini CLI — 1M token context, free tier\n */\n\nexport interface CliStatus {\n id: string; // Provider ID matching registry (e.g., \"claude-code\")\n name: string; // Display name\n command: string; // CLI command name\n installed: boolean;\n authenticated: boolean;\n version?: string;\n}\n\n/** All detectable CLI agents in priority order */\nconst CLI_AGENTS = [\n { id: \"claude-code\", name: \"Claude Code\", command: \"claude\" },\n { id: \"codex-cli\", name: \"Codex CLI\", command: \"codex\" },\n { id: \"gemini-cli\", name: \"Gemini CLI\", command: \"gemini\" },\n] as const;\n\n// ── In-memory cache (60s TTL) ─────────────────────────────────────\n\nlet cachedResults: CliStatus[] | null = null;\nlet cacheTimestamp = 0;\nconst CACHE_TTL = 60_000; // 60 seconds\n\n/** Invalidate cache (call after a CLI error to re-detect) */\nexport function invalidateCliCache(): void {\n cachedResults = null;\n cacheTimestamp = 0;\n}\n\n// ── Main detection ────────────────────────────────────────────────\n\n/**\n * Detect all available CLI coding agents.\n * Returns a list sorted by priority, with install/auth status.\n * Results are cached for 60 seconds.\n */\nexport async function detectAvailableClis(): Promise<CliStatus[]> {\n if (cachedResults && Date.now() - cacheTimestamp < CACHE_TTL) {\n return cachedResults;\n }\n\n const results = await Promise.all(\n CLI_AGENTS.map(async (agent) => {\n const { installed, version } = await checkInstalled(agent.command);\n const authenticated = installed\n ? checkAuthenticated(agent.id)\n : false;\n\n return {\n id: agent.id,\n name: agent.name,\n command: agent.command,\n installed,\n authenticated,\n version,\n };\n })\n );\n\n cachedResults = results;\n cacheTimestamp = Date.now();\n return results;\n}\n\n/**\n * Get the best available CLI agent (first that's installed + authenticated).\n * Returns null if no CLI agent is available.\n */\nexport async function getBestAvailableCli(): Promise<CliStatus | null> {\n const clis = await detectAvailableClis();\n return clis.find((c) => c.installed && c.authenticated) || null;\n}\n\n// ── Install detection ─────────────────────────────────────────────\n\nfunction checkInstalled(command: string): Promise<{ installed: boolean; version?: string }> {\n return new Promise((resolve) => {\n try {\n const proc = spawn(command, [\"--version\"], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 5000,\n });\n\n let stdout = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => { stdout += d.toString(); });\n\n proc.on(\"error\", () => resolve({ installed: false }));\n proc.on(\"close\", (code) => {\n if (code === 0) {\n // Extract version from output (common formats: \"v1.2.3\", \"1.2.3\", \"tool 1.2.3\")\n const match = stdout.match(/(\\d+\\.\\d+\\.\\d+)/);\n resolve({ installed: true, version: match?.[1] });\n } else {\n resolve({ installed: false });\n }\n });\n } catch {\n resolve({ installed: false });\n }\n });\n}\n\n// ── Auth detection (file/env checks — no process spawn) ──────────\n\nfunction checkAuthenticated(cliId: string): boolean {\n switch (cliId) {\n case \"claude-code\":\n return isClaudeAuthenticated();\n case \"codex-cli\":\n return isCodexAuthenticated();\n case \"gemini-cli\":\n return isGeminiAuthenticated();\n default:\n return false;\n }\n}\n\n/**\n * Claude Code auth check:\n * 1. ANTHROPIC_API_KEY env var\n * 2. ~/.claude/.claude.json with oauthAccount key\n */\nfunction isClaudeAuthenticated(): boolean {\n if (process.env.ANTHROPIC_API_KEY) return true;\n if (process.env.CLAUDE_CODE_OAUTH_TOKEN) return true;\n\n try {\n const configPath = join(\n process.env.CLAUDE_CONFIG_DIR || join(homedir(), \".claude\"),\n \".claude.json\"\n );\n if (existsSync(configPath)) {\n const config = JSON.parse(readFileSync(configPath, \"utf-8\"));\n if (config.oauthAccount) return true;\n }\n } catch {}\n\n return false;\n}\n\n/**\n * Codex CLI auth check:\n * 1. OPENAI_API_KEY env var\n * 2. ~/.codex/auth.json exists with valid content\n */\nfunction isCodexAuthenticated(): boolean {\n if (process.env.OPENAI_API_KEY) return true;\n\n try {\n const authPath = join(\n process.env.CODEX_HOME || join(homedir(), \".codex\"),\n \"auth.json\"\n );\n if (existsSync(authPath)) {\n const auth = JSON.parse(readFileSync(authPath, \"utf-8\"));\n if (auth.auth_mode && (auth.OPENAI_API_KEY || auth.tokens)) return true;\n }\n } catch {}\n\n return false;\n}\n\n/**\n * Gemini CLI auth check:\n * 1. GEMINI_API_KEY or GOOGLE_API_KEY env var\n * 2. ~/.gemini/oauth_creds.json with refresh_token\n */\nfunction isGeminiAuthenticated(): boolean {\n if (process.env.GEMINI_API_KEY) return true;\n if (process.env.GOOGLE_API_KEY) return true;\n\n try {\n const credsPath = join(homedir(), \".gemini\", \"oauth_creds.json\");\n if (existsSync(credsPath)) {\n const creds = JSON.parse(readFileSync(credsPath, \"utf-8\"));\n if (creds.refresh_token) return true;\n }\n } catch {}\n\n return false;\n}\n","import {\n readFileSync,\n writeFileSync,\n existsSync,\n statSync,\n lstatSync,\n readdirSync,\n copyFileSync,\n mkdirSync,\n realpathSync,\n unlinkSync,\n rmSync,\n openSync,\n fsyncSync,\n closeSync,\n renameSync,\n} from \"node:fs\";\nimport { join, resolve, relative, dirname, extname } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { createHash } from \"node:crypto\";\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\n// Track line endings and BOM per file so writeFileSafe can restore them\nconst fileMetadata = new Map<string, { hasBOM: boolean; lineEnding: string }>();\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 raw = readFileSync(filePath);\n // Detect BOM (UTF-8: EF BB BF)\n const hasBOM = raw[0] === 0xEF && raw[1] === 0xBB && raw[2] === 0xBF;\n let content = hasBOM ? raw.subarray(3).toString(\"utf-8\") : raw.toString(\"utf-8\");\n // Detect and normalize line endings\n const lineEnding = content.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n if (lineEnding === \"\\r\\n\") content = content.replace(/\\r\\n/g, \"\\n\");\n // Store metadata for write restoration\n fileMetadata.set(resolve(filePath), { hasBOM, lineEnding });\n return { content };\n } catch (e: unknown) {\n return { error: `Failed to read file: ${(e as Error).message}` };\n }\n}\n\n// ── Backup Management (temp directory) ──\nconst BACKUP_DIR = join(tmpdir(), \"openmagic-backups\");\nconst backupMap = new Map<string, string>(); // originalPath -> backupTempPath\n\nfunction getBackupPath(filePath: string): string {\n const hash = createHash(\"md5\").update(resolve(filePath)).digest(\"hex\").slice(0, 12);\n const name = filePath.split(/[/\\\\]/).pop() || \"file\";\n return join(BACKUP_DIR, `${hash}_${name}`);\n}\n\nexport function getBackupForFile(filePath: string): string | undefined {\n return backupMap.get(resolve(filePath));\n}\n\nexport function cleanupBackups(): void {\n try {\n if (existsSync(BACKUP_DIR)) {\n rmSync(BACKUP_DIR, { recursive: true, force: true });\n }\n } catch {}\n backupMap.clear();\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 in temp directory\n let backupPath: string | undefined;\n if (existsSync(filePath)) {\n if (!existsSync(BACKUP_DIR)) mkdirSync(BACKUP_DIR, { recursive: true });\n backupPath = getBackupPath(filePath);\n copyFileSync(filePath, backupPath);\n backupMap.set(resolve(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 // Restore original line endings and BOM\n let output = content;\n const meta = fileMetadata.get(resolve(filePath));\n if (meta) {\n if (meta.lineEnding === \"\\r\\n\") output = output.replace(/\\n/g, \"\\r\\n\");\n if (meta.hasBOM) output = \"\\uFEFF\" + output;\n }\n\n // Atomic write: write to temp, then rename\n const tmpPath = filePath + \".openmagic-tmp-\" + Date.now();\n writeFileSync(tmpPath, output, \"utf-8\");\n try {\n const fd = openSync(tmpPath, \"r\");\n fsyncSync(fd);\n closeSync(fd);\n } catch {} // fsync best-effort\n try {\n renameSync(tmpPath, filePath);\n } catch {\n // rename failed (cross-device?) — fall back to direct write\n writeFileSync(filePath, output, \"utf-8\");\n try { unlinkSync(tmpPath); } catch {}\n }\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\nconst MAX_LIST_ENTRIES = 2000;\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 || entries.length >= MAX_LIST_ENTRIES) 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 (entries.length >= MAX_LIST_ENTRIES) return;\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\nconst GREP_EXTENSIONS = new Set([\n \".js\", \".jsx\", \".ts\", \".tsx\", \".mjs\", \".cjs\",\n \".vue\", \".svelte\", \".astro\",\n \".html\", \".htm\", \".css\", \".scss\", \".less\",\n \".json\", \".md\", \".yaml\", \".yml\",\n \".php\", \".py\", \".rb\",\n]);\n\nconst MAX_GREP_FILE_SIZE = 256 * 1024; // 256KB — skip large generated/bundled files\nconst MAX_GREP_FILES_SCANNED = 500; // stop walking after scanning this many files\n\nexport function grepFiles(\n pattern: string,\n searchRoot: string,\n roots: string[],\n maxResults: number = 30\n): { file: string; lineNum: number; line: string }[] {\n if (!isPathSafe(searchRoot, roots)) return [];\n\n const results: { file: string; lineNum: number; line: string }[] = [];\n const lowerPattern = pattern.toLowerCase();\n let filesScanned = 0;\n\n function walk(dir: string, depth: number): void {\n if (depth > 6 || results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n let items: string[];\n try { items = readdirSync(dir); } catch { return; }\n\n for (const item of items) {\n if (results.length >= maxResults || filesScanned >= MAX_GREP_FILES_SCANNED) return;\n if (IGNORED_DIRS.has(item) || (item.startsWith(\".\") && item !== \".env.example\")) continue;\n\n const fullPath = join(dir, item);\n let stat;\n try { stat = lstatSync(fullPath); } catch { continue; }\n if (stat.isSymbolicLink()) continue;\n\n if (stat.isDirectory()) {\n walk(fullPath, depth + 1);\n } else if (stat.isFile()) {\n const ext = extname(item).toLowerCase();\n if (!GREP_EXTENSIONS.has(ext)) continue;\n if (stat.size > MAX_GREP_FILE_SIZE) continue; // skip large files\n filesScanned++;\n\n try {\n const content = readFileSync(fullPath, \"utf-8\");\n const lines = content.split(\"\\n\");\n let fileMatches = 0;\n for (let i = 0; i < lines.length && fileMatches < 5; i++) {\n if (lines[i].toLowerCase().includes(lowerPattern)) {\n results.push({\n file: relative(searchRoot, fullPath),\n lineNum: i + 1,\n line: lines[i].trim().slice(0, 200),\n });\n fileMatches++;\n }\n }\n } catch {}\n }\n }\n }\n\n walk(searchRoot, 0);\n return results;\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 // ─── Claude Code (CLI) ────────────────────────────────────────\n \"claude-code\": {\n name: \"Claude Code (CLI)\",\n models: [\n {\n id: \"claude-code\",\n name: \"Claude Code\",\n vision: false,\n context: 200000,\n maxOutput: 64000,\n },\n ],\n apiBase: \"\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── Codex CLI ────────────────────────────────────────────────\n \"codex-cli\": {\n name: \"Codex CLI\",\n models: [\n {\n id: \"codex-cli\",\n name: \"Codex CLI\",\n vision: false,\n context: 192000,\n maxOutput: 100000,\n },\n ],\n apiBase: \"\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\n // ─── Gemini CLI ───────────────────────────────────────────────\n \"gemini-cli\": {\n name: \"Gemini CLI\",\n models: [\n {\n id: \"gemini-cli\",\n name: \"Gemini CLI\",\n vision: false,\n context: 1048576,\n maxOutput: 65536,\n },\n ],\n apiBase: \"\",\n keyPrefix: \"\",\n keyPlaceholder: \"not required\",\n local: true,\n },\n\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. If the user is asking a QUESTION (not requesting a change), respond with {\"modifications\":[],\"explanation\":\"your answer here\"}. Only propose modifications when the user explicitly wants something changed.\n2. NEVER use delete+create to modify an existing file. Always use edit with search/replace. Only use create for genuinely new files that don't exist yet.\n3. Copy the search string EXACTLY from the grounded source files — do not retype, reformat, or change whitespace/indentation\n4. Include 3-5 lines of surrounding context in the search field to ensure uniqueness\n5. Keep modifications minimal — change only what's needed. Do NOT rewrite entire files.\n6. If the grounded files don't contain the code you need to modify, return: {\"modifications\":[],\"explanation\":\"NEED_FILE: exact/relative/path/to/file.ext\"}\n7. To search for a pattern across the codebase, return: {\"modifications\":[],\"explanation\":\"SEARCH_FILES: \\\\\"pattern\\\\\" in optional/path/\"}\n8. For style changes: check the dependencies (package.json) to know if the project uses Tailwind, MUI, etc. Use the project's styling approach, not raw CSS\n9. Use the selected element's cssSelector, className, parentContainerStyles, and siblings to understand the full layout context\n10. Use the page URL route and componentHint to identify the correct source file to modify\n11. Use childrenLayout pixel measurements for spacing. gapToNext.vertical=0 means elements are touching.\n12. Use resolvedClasses to see actual CSS values behind utility classes (space-y-6 = margin-top: 1.5rem).\n13. Check themeState.darkMode — if true, use dark-mode-aware colors and respect the project's dark mode classes.\n14. Use cssVariables to leverage existing design tokens (var(--color-primary)) instead of hardcoding hex values.\n15. Check activeBreakpoints to know which responsive breakpoint is active. Suggest responsive-aware changes.\n16. Check visibilityState — the element may be scrolled out of view, hidden, or inside a scrollable container.\n17. Always preserve existing code style, conventions, and indentation\n18. ALWAYS respond with valid JSON only — no text before or after the JSON object`;\n\nexport function buildContextParts(context: LlmContext): Parameters<typeof buildUserMessage>[1] {\n const parts: Parameters<typeof buildUserMessage>[1] = {};\n\n // Send FULL element context with all available signals\n if (context.selectedElement) {\n const el = context.selectedElement as any;\n const elementData: Record<string, unknown> = {\n cssSelector: el.cssSelector,\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n outerHTML: el.outerHTML,\n computedStyles: el.computedStyles,\n ancestry: el.ancestry,\n componentHint: el.componentHint,\n };\n // Parent container styles (layout context)\n if (el.parentStyles && Object.keys(el.parentStyles).length) {\n elementData.parentContainerStyles = el.parentStyles;\n }\n // Sibling elements (what else is in the same container)\n if (el.siblings?.length) {\n elementData.siblings = el.siblings;\n }\n // Matched CSS rules from stylesheets\n if (el.matchedCssRules?.length) {\n elementData.matchedCssRules = el.matchedCssRules;\n }\n // Viewport dimensions\n if (el.viewport) {\n elementData.viewport = el.viewport;\n }\n // Accessibility attributes\n if (el.ariaAttributes && Object.keys(el.ariaAttributes).length) {\n elementData.ariaAttributes = el.ariaAttributes;\n }\n // Event handlers\n if (el.eventHandlers?.length) {\n elementData.eventHandlers = el.eventHandlers;\n }\n // React props\n if (el.reactProps) {\n elementData.reactProps = el.reactProps;\n }\n // Children layout measurements (pixel-level spacing between children)\n if (el.childrenLayout?.length) {\n elementData.childrenLayout = el.childrenLayout;\n }\n // Resolved Tailwind/utility classes to actual CSS values\n if (el.resolvedClasses?.length) {\n elementData.resolvedClasses = el.resolvedClasses;\n }\n // Deep element intelligence\n if (el.themeState) elementData.themeState = el.themeState;\n if (el.cssVariables && Object.keys(el.cssVariables).length) elementData.cssVariables = el.cssVariables;\n if (el.stackingContext) elementData.stackingContext = el.stackingContext;\n if (el.visibilityState) elementData.visibilityState = el.visibilityState;\n if (el.activeBreakpoints?.length) elementData.activeBreakpoints = el.activeBreakpoints;\n if (el.pseudoElements && (el.pseudoElements.before !== \"none\" || el.pseudoElements.after !== \"none\")) {\n elementData.pseudoElements = el.pseudoElements;\n }\n if (el.formState) elementData.formState = el.formState;\n parts.selectedElement = JSON.stringify(elementData, null, 2);\n }\n\n if (context.files?.length) {\n parts.files = context.files;\n }\n if (context.projectTree) parts.projectTree = context.projectTree;\n if ((context as any).pageUrl) parts.pageUrl = (context as any).pageUrl;\n if ((context as any).pageTitle) parts.pageTitle = (context as any).pageTitle;\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 if ((context as any).searchResults?.length) {\n parts.searchResults = (context as any).searchResults.map(\n (s: any) => `Search: \"${s.query}\"\\n${s.matches.map((m: any) => ` ${m.file}:${m.lineNum}: ${m.line}`).join(\"\\n\")}`\n ).join(\"\\n\\n\");\n }\n return parts;\n}\n\nexport function buildUserMessage(\n userPrompt: string,\n context: {\n selectedElement?: string;\n screenshot?: string;\n files?: Array<{ path: string; content: string }>;\n fileContent?: string;\n filePath?: string;\n networkLogs?: string;\n consoleLogs?: string;\n projectTree?: string;\n pageUrl?: string;\n pageTitle?: string;\n searchResults?: string;\n }\n): string {\n const parts: string[] = [];\n\n // Page context — helps LLM find the right route/page component\n if (context.pageUrl || context.pageTitle) {\n parts.push(`## Page Context\\nURL: ${context.pageUrl || \"unknown\"}\\nTitle: ${context.pageTitle || \"unknown\"}`);\n }\n\n if (context.projectTree) {\n parts.push(`## Project Structure\\n\\`\\`\\`\\n${context.projectTree}\\n\\`\\`\\``);\n }\n\n // Grounded source files\n if (context.files?.length) {\n parts.push(`## Grounded Source Files\\n${context.files.map(f => `### ${f.path}\\n\\`\\`\\`\\n${f.content}\\n\\`\\`\\``).join(\"\\n\\n\")}`);\n } else if (context.filePath && context.fileContent) {\n parts.push(`## Source File: ${context.filePath}\\n\\`\\`\\`\\n${context.fileContent}\\n\\`\\`\\``);\n }\n\n // Selected element — full context including selector, styles, ancestry\n if (context.selectedElement) {\n parts.push(`## Selected Element\\n\\`\\`\\`json\\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 if (context.searchResults) {\n parts.push(`## Search Results\\n\\`\\`\\`\\n${context.searchResults}\\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 { spawn } from \"node:child_process\";\nimport type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\n/**\n * Claude Code CLI adapter.\n * Spawns `claude -p` with the prompt and streams the response.\n * No API key needed — uses the user's existing Claude Code authentication.\n *\n * Docs: https://docs.anthropic.com/en/docs/claude-code\n * Flags verified from official CLI reference.\n */\n\n/**\n * Check if the `claude` CLI is available in PATH.\n */\nexport function isClaudeCliAvailable(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn(\"claude\", [\"--version\"], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n proc.on(\"error\", () => resolve(false));\n proc.on(\"close\", (code) => resolve(code === 0));\n });\n}\n\nexport async function chatClaudeCode(\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 // Build the prompt the same way as other providers\n const lastUserMsg = [...messages].reverse().find((m) => m.role === \"user\");\n const userPrompt =\n typeof lastUserMsg?.content === \"string\"\n ? lastUserMsg.content\n : \"Help me with this element.\";\n\n const contextParts = buildContextParts(context);\n const fullPrompt = buildUserMessage(userPrompt, contextParts);\n\n // Spawn claude -p with stream-json for real-time streaming\n // --verbose + --include-partial-messages: token-level streaming deltas\n // --max-turns 5: allows Claude to read files and produce a complete response\n const proc = spawn(\n \"claude\",\n [\n \"-p\",\n \"--output-format\", \"stream-json\",\n \"--verbose\",\n \"--include-partial-messages\",\n \"--max-turns\", \"5\",\n ],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: process.cwd(),\n env: {\n ...process.env,\n // Generous timeouts — Claude may read files and think between turns\n CLAUDE_STREAM_IDLE_TIMEOUT_MS: \"300000\", // 5 min idle timeout between chunks\n API_TIMEOUT_MS: \"600000\", // 10 min overall API timeout\n },\n }\n );\n\n // Send system prompt + user prompt via stdin\n proc.stdin.write(`${SYSTEM_PROMPT}\\n\\n${fullPrompt}`);\n proc.stdin.end();\n\n let fullContent = \"\";\n let resultContent = \"\"; // From the final result event\n let buffer = \"\";\n let errOutput = \"\";\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n buffer += data.toString();\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line);\n\n // Final result event — this is the authoritative response\n if (event.type === \"result\") {\n if (typeof event.result === \"string\") {\n resultContent = event.result;\n }\n continue;\n }\n\n const text = extractText(event);\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Not valid JSON — skip\n }\n }\n });\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n errOutput += data.toString();\n });\n\n proc.on(\"error\", (err) => {\n if (err.message.includes(\"ENOENT\")) {\n onError(\n \"Claude CLI not found. Install it with: npm install -g @anthropic-ai/claude-code\"\n );\n } else {\n onError(`Claude CLI error: ${err.message}`);\n }\n });\n\n proc.on(\"close\", (code) => {\n // Process remaining buffer\n if (buffer.trim()) {\n try {\n const event = JSON.parse(buffer);\n if (event.type === \"result\" && typeof event.result === \"string\") {\n resultContent = event.result;\n } else {\n const text = extractText(event);\n if (text) fullContent += text;\n }\n } catch {\n // ignore\n }\n }\n\n // Prefer the result event content (complete final answer) over streamed chunks\n const finalContent = resultContent || fullContent;\n\n if (code === 0 || finalContent) {\n onDone({ content: finalContent });\n } else {\n // Parse common errors\n const err = errOutput.trim();\n if (err.includes(\"not authenticated\") || err.includes(\"login\")) {\n onError(\"Claude CLI is not authenticated. Run `claude` in your terminal to log in.\");\n } else if (err.includes(\"ENOENT\") || err.includes(\"not found\")) {\n onError(\"Claude CLI not found. Install it with: npm install -g @anthropic-ai/claude-code\");\n } else {\n onError(err.slice(0, 500) || `Claude CLI exited with code ${code}`);\n }\n }\n });\n}\n\n/**\n * Extract text content from a stream-json event.\n * Handles multiple possible event formats from Claude Code CLI.\n */\nfunction extractText(event: Record<string, unknown>): string | undefined {\n // Format: {\"type\":\"assistant\",\"message\":{\"content\":[{\"type\":\"text\",\"text\":\"...\"}]}}\n if (event.type === \"assistant\") {\n const msg = event.message as Record<string, unknown> | undefined;\n if (msg?.content) {\n if (Array.isArray(msg.content)) {\n return msg.content\n .filter((b: any) => b.type === \"text\" && b.text)\n .map((b: any) => b.text)\n .join(\"\");\n }\n if (typeof msg.content === \"string\") return msg.content;\n }\n // Format: {\"type\":\"assistant\",\"text\":\"...\"}\n if (typeof event.text === \"string\") return event.text;\n }\n\n // Format: {\"type\":\"content_block_delta\",\"delta\":{\"text\":\"...\"}}\n if (event.type === \"content_block_delta\") {\n const delta = event.delta as Record<string, unknown> | undefined;\n if (typeof delta?.text === \"string\") return delta.text;\n }\n\n return undefined;\n}\n","import { spawn } from \"node:child_process\";\nimport type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\n/**\n * OpenAI Codex CLI adapter.\n * Uses `codex exec` — the non-interactive subcommand (no TTY required).\n * Streams JSONL events via --json flag.\n * Auth: uses OPENAI_API_KEY from env or codex's own auth.\n *\n * Docs: https://github.com/openai/codex\n * Event types verified from codex-rs/exec/src/exec_events.rs\n */\n\nexport async function chatCodexCli(\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 lastUserMsg = [...messages].reverse().find((m) => m.role === \"user\");\n const userPrompt =\n typeof lastUserMsg?.content === \"string\"\n ? lastUserMsg.content\n : \"Help me with this element.\";\n\n const contextParts = buildContextParts(context);\n const fullPrompt = `${SYSTEM_PROMPT}\\n\\n${buildUserMessage(userPrompt, contextParts)}`;\n\n // `codex exec` is the non-interactive subcommand (no TTY required)\n // --full-auto: auto-approve actions (alias for --sandbox workspace-write)\n // --json: structured JSONL output to stdout\n // --skip-git-repo-check: allow running outside git repos\n // - : read prompt from stdin\n const proc = spawn(\n \"codex\",\n [\"exec\", \"--full-auto\", \"--json\", \"--skip-git-repo-check\", \"-\"],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: process.cwd(),\n }\n );\n\n proc.stdin.write(fullPrompt);\n proc.stdin.end();\n\n let fullContent = \"\";\n let buffer = \"\";\n let errOutput = \"\";\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n buffer += data.toString();\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const event = JSON.parse(line);\n const text = extractCodexText(event);\n if (text) {\n fullContent += text;\n onChunk(text);\n }\n } catch {\n // Not valid JSON — skip\n }\n }\n });\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n errOutput += data.toString();\n });\n\n proc.on(\"error\", (err) => {\n if (err.message.includes(\"ENOENT\")) {\n onError(\"Codex CLI not found. Install it with: npm install -g @openai/codex\");\n } else {\n onError(`Codex CLI error: ${err.message}`);\n }\n });\n\n proc.on(\"close\", (code) => {\n // Process remaining buffer\n if (buffer.trim()) {\n try {\n const event = JSON.parse(buffer);\n const text = extractCodexText(event);\n if (text) fullContent += text;\n } catch {\n // ignore\n }\n }\n\n if (code === 0 || fullContent.trim()) {\n onDone({ content: fullContent });\n } else {\n const err = errOutput.trim();\n if (err.includes(\"OPENAI_API_KEY\") || err.includes(\"api key\") || err.includes(\"unauthorized\")) {\n onError(\"Codex CLI requires OPENAI_API_KEY in your environment. Set it with: export OPENAI_API_KEY=sk-...\");\n } else {\n onError(err.slice(0, 500) || `Codex CLI exited with code ${code}`);\n }\n }\n });\n}\n\n/**\n * Extract text from a Codex JSONL event.\n *\n * Codex exec --json emits these event types:\n * - item.started / item.updated / item.completed with item payload\n * - Item types: agent_message (text), reasoning (text), command_execution, file_change, etc.\n * - turn.started / turn.completed / turn.failed\n * - thread.started\n * - error\n *\n * We extract text from agent_message items.\n */\n/**\n * Extract text from a Codex JSONL event.\n * item.text is the FULL accumulated text (not a delta), so we only\n * extract from item.completed to avoid duplicates.\n */\nfunction extractCodexText(event: Record<string, unknown>): string | undefined {\n // Only emit on item.completed — text is full content, not a delta\n if (event.type === \"item.completed\") {\n const item = event.item as Record<string, unknown> | undefined;\n if (item?.type === \"agent_message\" && typeof item.text === \"string\") {\n return item.text;\n }\n }\n\n return undefined;\n}\n","import { spawn } from \"node:child_process\";\nimport type { ChatMessage, LlmContext } from \"../shared-types.js\";\nimport { SYSTEM_PROMPT, buildUserMessage, buildContextParts } from \"./prompts.js\";\n\n/**\n * Google Gemini CLI adapter.\n * Uses `gemini` with prompt piped via stdin (auto-detected headless mode).\n * Auth: uses GEMINI_API_KEY from env or Google OAuth (if logged in interactively).\n *\n * Docs: https://github.com/google-gemini/gemini-cli\n * When stdin is piped and no -p flag, Gemini CLI auto-enters non-interactive mode.\n */\n\nexport async function chatGeminiCli(\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 lastUserMsg = [...messages].reverse().find((m) => m.role === \"user\");\n const userPrompt =\n typeof lastUserMsg?.content === \"string\"\n ? lastUserMsg.content\n : \"Help me with this element.\";\n\n const contextParts = buildContextParts(context);\n const fullPrompt = `${SYSTEM_PROMPT}\\n\\n${buildUserMessage(userPrompt, contextParts)}`;\n\n // Pipe full prompt via stdin — Gemini CLI auto-detects piped stdin\n // and enters non-interactive headless mode.\n // --yolo: auto-accept all tool actions without prompting\n const proc = spawn(\n \"gemini\",\n [\n \"--yolo\",\n ],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: process.cwd(),\n }\n );\n\n // Send the complete prompt (system + context + user) via stdin\n proc.stdin.write(fullPrompt);\n proc.stdin.end();\n\n let fullContent = \"\";\n let errOutput = \"\";\n\n proc.stdout.on(\"data\", (data: Buffer) => {\n const text = data.toString();\n fullContent += text;\n onChunk(text);\n });\n\n proc.stderr.on(\"data\", (data: Buffer) => {\n errOutput += data.toString();\n });\n\n proc.on(\"error\", (err) => {\n if (err.message.includes(\"ENOENT\")) {\n onError(\"Gemini CLI not found. Install it with: npm install -g @google/gemini-cli\");\n } else {\n onError(`Gemini CLI error: ${err.message}`);\n }\n });\n\n proc.on(\"close\", (code) => {\n if (code === 0 || fullContent.trim()) {\n onDone({ content: fullContent });\n } else {\n const err = errOutput.trim();\n if (err.includes(\"auth\") || err.includes(\"GEMINI_API_KEY\") || err.includes(\"credentials\") || err.includes(\"login\")) {\n onError(\"Gemini CLI requires authentication. Set GEMINI_API_KEY in your environment, or run `gemini` interactively to log in with Google.\");\n } else {\n onError(err.slice(0, 500) || `Gemini CLI exited with code ${code}`);\n }\n }\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\";\nimport { chatClaudeCode } from \"./claude-code.js\";\nimport { chatCodexCli } from \"./codex-cli.js\";\nimport { chatGeminiCli } from \"./gemini-cli.js\";\nimport { invalidateCliCache } from \"./cli-detect.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\nfunction extractJsonFromResponse(content: string): string | null {\n // 1. Try direct JSON.parse (clean response)\n try { JSON.parse(content); return content; } catch {}\n\n // 2. Try markdown-wrapped JSON\n const mdMatch = content.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n if (mdMatch?.[1]) {\n const candidate = mdMatch[1].trim();\n try { JSON.parse(candidate); return candidate; } catch {}\n }\n\n // 3. Brace-counting extraction (handles raw JSON in text)\n const start = content.indexOf('{');\n if (start === -1) return null;\n\n let depth = 0;\n let inString = false;\n let escape = false;\n\n for (let i = start; i < content.length; i++) {\n const ch = content[i];\n if (escape) { escape = false; continue; }\n if (ch === '\\\\' && inString) { escape = true; continue; }\n if (ch === '\"') { inString = !inString; continue; }\n if (inString) continue;\n if (ch === '{') depth++;\n if (ch === '}') {\n depth--;\n if (depth === 0) {\n const candidate = content.substring(start, i + 1);\n try { JSON.parse(candidate); return candidate; } catch { break; }\n }\n }\n }\n\n // 4. Truncation repair: if braces are imbalanced, try closing them\n if (depth > 0) {\n let repaired = content.substring(start);\n // Close open strings\n if (inString) repaired += '\"';\n // Close open arrays and objects\n while (depth > 0) { repaired += '}'; depth--; }\n try { JSON.parse(repaired); return repaired; } catch {}\n }\n\n // 5. Regex fallback: extract just the explanation field\n const explMatch = content.match(/\"explanation\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/);\n if (explMatch) {\n return JSON.stringify({ modifications: [], explanation: JSON.parse('\"' + explMatch[1] + '\"') });\n }\n\n return null;\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 let modifications: LlmResponse[\"modifications\"] | undefined;\n try {\n const json = extractJsonFromResponse(result.content);\n if (json) {\n const parsed = JSON.parse(json) as LlmResponse;\n modifications = parsed.modifications;\n }\n } catch {\n // JSON parse failed — return raw content\n }\n onDone({ content: result.content, modifications });\n };\n\n // Wrap CLI error handlers to invalidate detection cache on failure\n const cliOnError = (error: string) => {\n if (error.includes(\"not found\") || error.includes(\"ENOENT\") || error.includes(\"not authenticated\") || error.includes(\"not logged in\")) {\n invalidateCliCache();\n }\n onError(error);\n };\n\n try {\n if (provider === \"claude-code\") {\n await chatClaudeCode(messages, context, onChunk, wrappedOnDone, cliOnError);\n } else if (provider === \"codex-cli\") {\n await chatCodexCli(messages, context, onChunk, wrappedOnDone, cliOnError);\n } else if (provider === \"gemini-cli\") {\n await chatGeminiCli(messages, context, onChunk, wrappedOnDone, cliOnError);\n } else 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, resolve } from \"node:path\";\nimport { execSync } from \"node:child_process\";\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 checkPortSingle(port: number, host: string): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = createConnection({ port, host, timeout: 1000 });\n socket.unref();\n socket.on(\"connect\", () => { socket.destroy(); resolve(true); });\n socket.on(\"error\", () => { socket.destroy(); resolve(false); });\n socket.on(\"timeout\", () => { socket.destroy(); resolve(false); });\n });\n}\n\n// Check both IPv4 and IPv6 — many dev servers (Vite, Node) listen on ::1 only\nasync function checkPort(port: number, host: string = \"127.0.0.1\"): Promise<boolean> {\n const results = await Promise.all([\n checkPortSingle(port, host),\n checkPortSingle(port, \"::1\"),\n checkPortSingle(port, \"localhost\"),\n ]);\n return results.some(Boolean);\n}\n\nexport interface DetectedServer {\n port: number;\n host: string;\n fromScripts?: boolean; // true if detected via package.json scripts\n}\n\n/**\n * Check if the process listening on a port is running from (or near) the expected directory.\n * Uses lsof on macOS/Linux to get the PID, then checks its working directory.\n * Returns true if verified, false if wrong project, null if can't determine.\n */\nexport function verifyPortOwnership(port: number, expectedDir: string): boolean | null {\n try {\n // Get PIDs listening on this port\n const pidOutput = execSync(`lsof -i :${port} -sTCP:LISTEN -t 2>/dev/null`, {\n encoding: \"utf-8\",\n timeout: 3000,\n }).trim();\n\n if (!pidOutput) return null;\n\n const pids = pidOutput.split(\"\\n\").map((p) => p.trim()).filter(Boolean);\n const expected = resolve(expectedDir);\n\n for (const pid of pids) {\n try {\n // Get working directory of this process\n const cwdOutput = execSync(\n `lsof -a -p ${pid} -d cwd -Fn 2>/dev/null | grep ^n | head -1`,\n { encoding: \"utf-8\", timeout: 3000 }\n ).trim();\n\n if (!cwdOutput) continue;\n const processCwd = resolve(cwdOutput.slice(1)); // strip leading 'n'\n\n // Match if the process cwd is the project dir, a parent, or a child\n if (processCwd === expected || expected.startsWith(processCwd) || processCwd.startsWith(expected)) {\n return true;\n }\n } catch {\n continue;\n }\n }\n\n // We got PIDs but none matched the project directory\n return false;\n } catch {\n // lsof not available or failed — can't verify\n return null;\n }\n}\n\nexport async function detectDevServer(cwd: string = process.cwd()): Promise<DetectedServer | null> {\n // First: check ports hinted by the project's dev scripts + .env (most reliable)\n const scripts = detectDevScripts(cwd);\n const envPort = checkEnvPort(cwd);\n const scriptPorts = [\n ...(envPort ? [envPort] : []),\n ...scripts.map((s) => s.defaultPort),\n ].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 // Verify this port actually belongs to this project\n const owned = verifyPortOwnership(port, cwd);\n if (owned === false) {\n // Wrong project on this port — skip it\n continue;\n }\n return { port, host: \"localhost\", fromScripts: true };\n }\n }\n // Scripts exist but none running (or all belong to other projects)\n return null;\n }\n\n // No recognized scripts — scan common ports (but flag as unverified)\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\n for (const foundPort of results) {\n if (foundPort === null) continue;\n // For generic scan, also check ownership\n const owned = verifyPortOwnership(foundPort, cwd);\n if (owned === false) continue; // skip — belongs to another project\n return { port: foundPort, host: \"localhost\", fromScripts: false };\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\", \"server\", \"dev:server\", \"web\", \"frontend\"];\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\n// --- Node.js Version Compatibility ---\n\n// Minimum Node.js versions for modern frameworks (conservative — covers latest majors)\nconst FRAMEWORK_NODE_REQUIREMENTS: Record<string, { minNode: string; label: string }> = {\n \"Next.js\": { minNode: \"18.17.0\", label: \"Next.js 14+\" },\n \"Vite\": { minNode: \"18.0.0\", label: \"Vite 5+\" },\n \"Angular\": { minNode: \"18.13.0\", label: \"Angular 17+\" },\n \"SvelteKit\": { minNode: \"18.13.0\", label: \"SvelteKit 2+\" },\n \"Nuxt\": { minNode: \"18.0.0\", label: \"Nuxt 3+\" },\n \"Astro\": { minNode: \"18.14.1\", label: \"Astro 4+\" },\n \"Remix\": { minNode: \"18.0.0\", label: \"Remix 2+\" },\n \"Create React App\": { minNode: \"14.0.0\", label: \"Create React App\" },\n \"Gatsby\": { minNode: \"18.0.0\", label: \"Gatsby 5+\" },\n \"Vue CLI\": { minNode: \"14.0.0\", label: \"Vue CLI\" },\n \"Webpack\": { minNode: \"14.0.0\", label: \"Webpack 5+\" },\n \"Parcel\": { minNode: \"16.0.0\", label: \"Parcel 2+\" },\n};\n\nfunction semverGte(a: string, b: string): boolean {\n const pa = a.split(\".\").map(Number);\n const pb = b.split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n if ((pa[i] || 0) > (pb[i] || 0)) return true;\n if ((pa[i] || 0) < (pb[i] || 0)) return false;\n }\n return true; // equal\n}\n\nexport function checkNodeCompatibility(framework: string): { ok: boolean; message?: string } {\n const req = FRAMEWORK_NODE_REQUIREMENTS[framework];\n if (!req) return { ok: true };\n\n const current = process.versions.node;\n if (!semverGte(current, req.minNode)) {\n return {\n ok: false,\n message: `${req.label} requires Node.js >= ${req.minNode}, but you are running v${current}`,\n };\n }\n return { ok: true };\n}\n\n// --- .env PORT detection ---\n\n/**\n * Check .env files for a PORT variable. Helps detect when the dev server\n * is configured to run on a non-default port via environment.\n */\nexport function checkEnvPort(cwd: string = process.cwd()): number | null {\n const envFiles = [\".env.local\", \".env.development.local\", \".env.development\", \".env\"];\n for (const envFile of envFiles) {\n const envPath = join(cwd, envFile);\n if (!existsSync(envPath)) continue;\n try {\n const content = readFileSync(envPath, \"utf-8\");\n const match = content.match(/^PORT\\s*=\\s*(\\d+)/m);\n if (match) return parseInt(match[1], 10);\n } catch {\n continue;\n }\n }\n return null;\n}\n\n// --- Parent lockfile scanning (Turbopack workspace root detection) ---\n\nconst LOCKFILE_NAMES = [\"package-lock.json\", \"bun.lock\", \"bun.lockb\", \"yarn.lock\", \"pnpm-lock.yaml\"];\n\n/**\n * Scan parent directories for lockfiles that could confuse Turbopack's\n * workspace root detection. Returns paths of lockfiles found above the\n * project directory (up to and including the home directory).\n */\nexport function scanParentLockfiles(projectDir: string): string[] {\n const home = process.env.HOME || process.env.USERPROFILE || \"\";\n const project = resolve(projectDir);\n const found: string[] = [];\n\n let dir = resolve(project, \"..\");\n while (dir.length > 1 && dir.length >= home.length) {\n for (const lockfile of LOCKFILE_NAMES) {\n const p = join(dir, lockfile);\n if (existsSync(p)) found.push(p);\n }\n const parent = resolve(dir, \"..\");\n if (parent === dir) break;\n dir = parent;\n }\n\n return found;\n}\n\n// --- Project name ---\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","join","existsSync","readFileSync","spawn","execSync","http","readFileSync","existsSync","join","dirname","existsSync","readFileSync","join","homedir","resolve","join","homedir","existsSync","readFileSync","readFileSync","writeFileSync","existsSync","mkdirSync","renameSync","join","modelInfo","spawn","spawn","spawn","spawn","spawn","spawn","dirname","readFileSync","join","existsSync","readFileSync","existsSync","join","resolve","createRequire","_require","VERSION","resolve","execSync","http","spawn","VERSION","execSync","resolve","join","existsSync","spawn","readFileSync","compat"]}
|