vibespot 0.4.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/LICENSE +33 -0
- package/README.md +118 -0
- package/assets/content-guide.md +445 -0
- package/assets/conversion-guide.md +693 -0
- package/assets/design-guide.md +380 -0
- package/assets/hubspot-rules.md +560 -0
- package/assets/page-types.md +116 -0
- package/bin/vibespot.mjs +11 -0
- package/dist/index.js +6552 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
- package/ui/chat.js +803 -0
- package/ui/dashboard.js +383 -0
- package/ui/dialog.js +117 -0
- package/ui/field-editor.js +292 -0
- package/ui/index.html +393 -0
- package/ui/preview.js +132 -0
- package/ui/settings.js +927 -0
- package/ui/setup.js +830 -0
- package/ui/styles.css +2552 -0
- package/ui/upload-panel.js +554 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/program.ts","../src/cli/theme.ts","../src/cli/banner.ts","../src/utils/detect.ts","../src/utils/shell.ts","../src/utils/config.ts","../src/utils/fs.ts","../src/prompts/prompter.ts","../src/wizard/preflight.ts","../src/wizard/source.ts","../src/wizard/theme-setup.ts","../src/wizard/conversion.ts","../src/ai/claude-code.ts","../src/ai/prompts.ts","../src/ai/claude-api.ts","../src/ai/gemini-cli.ts","../src/ai/codex-cli.ts","../src/wizard/uploader.ts","../src/server/auto-fix.ts","../src/wizard/next-steps.ts","../src/commands/wizard.ts","../src/commands/init.ts","../src/commands/convert.ts","../src/commands/upload.ts","../src/commands/doctor.ts","../src/commands/vibe.ts","../src/server/server.ts","../src/server/session.ts","../src/server/project-git.ts","../src/hubl/renderer.ts","../src/server/preview.ts","../src/server/ai-handler.ts","../src/server/process-manager.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { wizardCommand } from \"../commands/wizard.js\";\nimport { initCommand } from \"../commands/init.js\";\nimport { convertCommand } from \"../commands/convert.js\";\nimport { uploadCommand } from \"../commands/upload.js\";\nimport { doctorCommand } from \"../commands/doctor.js\";\nimport { vibeCommand } from \"../commands/vibe.js\";\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name(\"vibespot\")\n .description(\n \"AI-powered HubSpot CMS landing page builder\"\n )\n .version(\"0.3.0\")\n .action(vibeCommand);\n\n program\n .command(\"wizard\")\n .description(\"Classic CLI wizard — step-by-step conversion flow\")\n .action(wizardCommand);\n\n program\n .command(\"init\")\n .description(\"Check and install required tools\")\n .action(initCommand);\n\n program\n .command(\"convert\")\n .description(\"Convert a React project to HubSpot modules\")\n .action(convertCommand);\n\n program\n .command(\"upload\")\n .description(\"Upload theme to HubSpot\")\n .action(uploadCommand);\n\n program\n .command(\"doctor\")\n .description(\"Diagnose environment issues\")\n .action(doctorCommand);\n\n return program;\n}\n","import chalk from \"chalk\";\n\nexport const palette = {\n accent: \"#FF7A59\",\n accentBright: \"#FF9A7A\",\n success: \"#00BDA5\",\n info: \"#0066FF\",\n warn: \"#FFB020\",\n error: \"#E23D2D\",\n muted: \"#8B8D91\",\n vibes: \"#00BDD6\",\n};\n\nconst noColor = !!process.env.NO_COLOR;\n\nfunction hex(color: string) {\n return noColor ? chalk : chalk.hex(color);\n}\n\nexport const theme = {\n accent: hex(palette.accent),\n accentBright: hex(palette.accentBright),\n success: hex(palette.success),\n info: hex(palette.info),\n warn: hex(palette.warn),\n error: hex(palette.error),\n muted: hex(palette.muted),\n vibes: hex(palette.vibes),\n heading: noColor ? chalk.bold : chalk.bold.hex(palette.accent),\n command: hex(palette.accentBright),\n dim: chalk.dim,\n bold: chalk.bold,\n};\n","import { theme } from \"./theme.js\";\n\nconst VERSION = \"0.3.0\";\n\nexport function printBanner() {\n const v = theme.vibes;\n const o = theme.accent; // HubSpot orange for \"Spot\"\n const m = theme.muted;\n\n // Block-pixel ASCII art: \"vibe ≋ Spot\"\n const lines = [\n `${v(\"██ ██ ██ █████ ▄▄▄▄▄\")}${v(\" ≋≋≋≋≋≋≋≋ \")}${o(\"▄▄▄▄▄ █████ ▄▄▄▄ ▀▀██▀▀\")}`,\n `${v(\"██ ██ ██ ██ ██ ██ \")}${v(\" ≋≋≋≋≋≋ \")}${o(\"██ ██ ██ ██ ██ ██ \")}`,\n `${v(\"██ ██ ██ █████ ████ \")}${v(\" ≋≋≋≋ \")}${o(\"▀▀▀▄ █████ ██ ██ ██ \")}`,\n `${v(\" █▄▄█▀ ██ ██ ██ ██ \")}${v(\" ≋≋≋≋≋≋ \")}${o(\" ██ ██ ██ ██ ██ \")}`,\n `${v(\" ▀▀▀ ██ █████ ▀▀▀▀▀\")}${v(\" ≋≋≋≋≋≋≋≋ \")}${o(\"▀▀▀▀ ██ ▀▀▀▀ ██ \")}`,\n ];\n\n console.log();\n for (const line of lines) {\n console.log(` ${line}`);\n }\n console.log();\n console.log(` ${m(\"AI-powered HubSpot Landing Pages\")} ${theme.dim(`v${VERSION}`)}`);\n console.log();\n}\n","import { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { readFileSync, existsSync, readdirSync } from \"node:fs\";\nimport { run } from \"./shell.js\";\nimport { loadConfig, maskApiKey, type AIEngineType } from \"./config.js\";\n\nexport interface ToolInfo {\n name: string;\n found: boolean;\n version: string;\n path: string;\n}\n\nexport function detectNode(): ToolInfo {\n const result = run(\"node --version\");\n return {\n name: \"Node.js\",\n found: result.success,\n version: result.stdout.replace(/^v/, \"\"),\n path: run(\"which node\").stdout,\n };\n}\n\nexport function detectGit(): ToolInfo {\n const result = run(\"git --version\");\n return {\n name: \"Git\",\n found: result.success,\n version: result.stdout.replace(\"git version \", \"\"),\n path: run(\"which git\").stdout,\n };\n}\n\nexport function detectHubSpotCLI(): ToolInfo {\n const result = run(\"hs --version\");\n return {\n name: \"HubSpot CLI\",\n found: result.success,\n version: result.stdout,\n path: run(\"which hs\").stdout,\n };\n}\n\nexport interface CLIToolInfo extends ToolInfo {\n authenticated: boolean;\n authDetail: string;\n}\n\nexport function detectClaudeCode(): CLIToolInfo {\n const result = run(\"claude --version\");\n if (!result.success) {\n return { name: \"Claude Code\", found: false, version: \"\", path: \"\", authenticated: false, authDetail: \"Not installed\" };\n }\n\n // Check for Claude Code auth by looking for credentials\n // Claude Code stores OAuth tokens in ~/.claude/ — if the dir exists with credentials, it's authenticated\n const claudeDir = join(homedir(), \".claude\");\n let authenticated = false;\n let authDetail = \"Not signed in — run `claude` to authenticate\";\n\n try {\n if (existsSync(claudeDir)) {\n // If .claude dir exists with auth files, consider it authenticated\n const files = readdirSync(claudeDir);\n const hasAuth = files.some(f =>\n f.includes(\"credentials\") || f.includes(\"auth\") || f.includes(\"token\") || f === \".credentials.json\"\n );\n if (hasAuth || files.length > 2) {\n // Has some config — likely authenticated\n authenticated = true;\n authDetail = \"Authenticated\";\n }\n }\n } catch { /* ignore */ }\n\n return {\n name: \"Claude Code\",\n found: true,\n version: result.stdout,\n path: run(\"which claude\").stdout,\n authenticated,\n authDetail,\n };\n}\n\nexport function detectDataCenter(portalId: string): string {\n try {\n const configPath = join(homedir(), \".hscli\", \"config.yml\");\n if (!existsSync(configPath)) return \"na1\";\n\n const config = readFileSync(configPath, \"utf-8\");\n\n // Find the account block matching this portal ID\n const accountIdx = config.indexOf(`accountId: ${portalId}`);\n if (accountIdx === -1) return \"na1\";\n\n // Look for personalAccessKey after this account entry\n const keyIdx = config.indexOf(\"personalAccessKey:\", accountIdx);\n if (keyIdx === -1) return \"na1\";\n\n // Extract the key value (next non-empty trimmed line after the label)\n const keySection = config.slice(keyIdx, keyIdx + 300);\n const keyMatch = keySection.match(/personalAccessKey:[\\s>-]*\\n\\s+(\\S+)/);\n if (!keyMatch) return \"na1\";\n\n // CiRldTE = base64 prefix for \"eu1\" datacenter in HubSpot personal access keys\n if (keyMatch[1].startsWith(\"CiRldTE\")) return \"eu1\";\n } catch {\n // Fall through to default\n }\n return \"na1\";\n}\n\nexport interface HubSpotAccount {\n name: string;\n portalId: string;\n authType: string;\n isDefault: boolean;\n}\n\nexport function detectHubSpotAuth(): {\n authenticated: boolean;\n portalName: string;\n portalId: string;\n accounts: HubSpotAccount[];\n} {\n const result = run(\"hs accounts list\");\n if (!result.success || !result.stdout) {\n return { authenticated: false, portalName: \"\", portalId: \"\", accounts: [] };\n }\n\n // Parse all accounts from the table\n const accounts: HubSpotAccount[] = [];\n let defaultName = \"\";\n let defaultId = \"\";\n\n // Default account line: \"Account: name [standard] (123456)\"\n const defaultMatch = result.stdout.match(/Account:\\s*(.+?)\\s*\\((\\d+)\\)/);\n if (defaultMatch) {\n defaultName = defaultMatch[1].trim();\n defaultId = defaultMatch[2].trim();\n }\n\n // Parse table rows: \"name [standard] 123456 personalaccesskey\"\n const lines = result.stdout.split(\"\\n\");\n for (const line of lines) {\n const tableMatch = line.match(/^\\s*(.+?)\\s+(\\d{5,})\\s+(.*)/);\n if (tableMatch && !/Account ID/i.test(line) && !/^-+$/.test(line.trim()) && !/^Name\\s/i.test(line.trim())) {\n const name = tableMatch[1].trim();\n const portalId = tableMatch[2].trim();\n const authType = tableMatch[3]?.trim() || \"unknown\";\n accounts.push({\n name,\n portalId,\n authType,\n isDefault: portalId === defaultId,\n });\n }\n }\n\n if (defaultMatch) {\n return {\n authenticated: true,\n portalName: defaultName,\n portalId: defaultId,\n accounts,\n };\n }\n\n // Fallback: at least one account in table\n if (accounts.length > 0) {\n return {\n authenticated: true,\n portalName: accounts[0].name,\n portalId: accounts[0].portalId,\n accounts,\n };\n }\n\n return {\n authenticated: result.stdout.length > 0,\n portalName: \"\",\n portalId: \"\",\n accounts: [],\n };\n}\n\nexport function detectGeminiCLI(): CLIToolInfo {\n const result = run(\"gemini --version\");\n if (!result.success) {\n return { name: \"Gemini CLI\", found: false, version: \"\", path: \"\", authenticated: false, authDetail: \"Not installed\" };\n }\n\n // Gemini CLI uses Google Cloud auth — check for application default credentials\n const adcPath = join(homedir(), \".config\", \"gcloud\", \"application_default_credentials.json\");\n const hasAdc = existsSync(adcPath);\n // Also check GOOGLE_API_KEY / GEMINI_API_KEY env vars\n const hasEnvKey = !!(process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_AI_API_KEY);\n const authenticated = hasAdc || hasEnvKey;\n\n return {\n name: \"Gemini CLI\",\n found: true,\n version: result.stdout,\n path: run(\"which gemini\").stdout,\n authenticated,\n authDetail: authenticated ? \"Authenticated\" : \"Run `gemini` to sign in with Google\",\n };\n}\n\nexport function detectCodexCLI(): CLIToolInfo {\n const result = run(\"codex --version\");\n if (!result.success) {\n return { name: \"OpenAI Codex CLI\", found: false, version: \"\", path: \"\", authenticated: false, authDetail: \"Not installed\" };\n }\n\n // Codex CLI supports OAuth (stored in ~/.codex/auth.json) or OPENAI_API_KEY\n const hasKey = !!(process.env.OPENAI_API_KEY);\n let hasOAuth = false;\n try {\n const authFile = join(homedir(), \".codex\", \"auth.json\");\n if (existsSync(authFile)) {\n const content = readFileSync(authFile, \"utf-8\");\n hasOAuth = content.length > 10; // non-empty auth file\n }\n } catch { /* ignore */ }\n\n const authenticated = hasKey || hasOAuth;\n const detail = hasOAuth ? \"Authenticated (OAuth)\" : hasKey ? \"Authenticated (API key)\" : \"Not authenticated\";\n return {\n name: \"OpenAI Codex CLI\",\n found: true,\n version: result.stdout,\n path: run(\"which codex\").stdout,\n authenticated,\n authDetail: detail,\n };\n}\n\nexport function detectGitHubCLI(): ToolInfo {\n const result = run(\"gh --version\");\n return {\n name: \"GitHub CLI\",\n found: result.success,\n version: result.stdout.split(\"\\n\")[0]?.replace(\"gh version \", \"\").split(\" \")[0] || \"\",\n path: run(\"which gh\").stdout,\n };\n}\n\nexport function detectGitHubAuth(): { authenticated: boolean; username: string } {\n const result = run(\"gh auth status 2>&1\");\n if (!result.success && !result.stdout) {\n return { authenticated: false, username: \"\" };\n }\n // gh auth status outputs to stderr, but our run() captures both\n const output = result.stdout || result.stderr || \"\";\n const match = output.match(/Logged in to github\\.com.*account\\s+(\\S+)/);\n if (match) {\n return { authenticated: true, username: match[1] };\n }\n // Alternate pattern: \"account borismichel\"\n const altMatch = output.match(/account\\s+(\\S+)/);\n if (altMatch && output.includes(\"Logged in\")) {\n return { authenticated: true, username: altMatch[1] };\n }\n return { authenticated: output.includes(\"Logged in\"), username: \"\" };\n}\n\nexport function hasAnthropicKey(): boolean {\n return !!process.env.ANTHROPIC_API_KEY;\n}\n\nexport function nodeVersionOk(version: string): boolean {\n const major = parseInt(version.split(\".\")[0], 10);\n return major >= 18;\n}\n\n// ---------------------------------------------------------------------------\n// Comprehensive environment status (used by GET /api/settings/status)\n// ---------------------------------------------------------------------------\n\nexport interface EnvironmentStatus {\n tools: {\n node: ToolInfo;\n git: ToolInfo;\n hubspot: ToolInfo & { authenticated: boolean; portalName: string; portalId: string; accounts: HubSpotAccount[] };\n github: ToolInfo & { authenticated: boolean; username: string };\n claudeCode: CLIToolInfo;\n geminiCli: CLIToolInfo;\n codexCli: CLIToolInfo;\n };\n apiKeys: {\n anthropic: { configured: boolean; masked: string; source: \"config\" | \"env\" | null };\n openai: { configured: boolean; masked: string; source: \"config\" | \"env\" | null };\n gemini: { configured: boolean; masked: string; source: \"config\" | \"env\" | null };\n };\n activeEngine: AIEngineType | null;\n availableEngines: AIEngineType[];\n}\n\nexport function detectEnvironment(): EnvironmentStatus {\n const config = loadConfig();\n\n const node = detectNode();\n const git = detectGit();\n const hs = detectHubSpotCLI();\n const hsAuth = hs.found ? detectHubSpotAuth() : { authenticated: false, portalName: \"\", portalId: \"\", accounts: [] as HubSpotAccount[] };\n const gh = detectGitHubCLI();\n const ghAuth = gh.found ? detectGitHubAuth() : { authenticated: false, username: \"\" };\n const claude = detectClaudeCode();\n const gemini = detectGeminiCLI();\n const codex = detectCodexCLI();\n\n // Determine API key status\n function keyStatus(configKey: string | undefined, ...envVars: string[]): { configured: boolean; masked: string; source: \"config\" | \"env\" | null } {\n if (configKey) return { configured: true, masked: maskApiKey(configKey), source: \"config\" };\n for (const v of envVars) {\n if (process.env[v]) return { configured: true, masked: maskApiKey(process.env[v]!), source: \"env\" };\n }\n return { configured: false, masked: \"\", source: null };\n }\n\n const anthropicKey = keyStatus(config.anthropicApiKey, \"ANTHROPIC_API_KEY\");\n const openaiKey = keyStatus(config.openaiApiKey, \"OPENAI_API_KEY\");\n const geminiKey = keyStatus(config.geminiApiKey, \"GEMINI_API_KEY\", \"GOOGLE_AI_API_KEY\");\n\n // Build available engines — CLI tools must be authenticated to be usable\n const available: AIEngineType[] = [];\n if (claude.found && claude.authenticated) available.push(\"claude-code\");\n if (anthropicKey.configured) available.push(\"anthropic-api\");\n if (openaiKey.configured) available.push(\"openai-api\");\n if (gemini.found && gemini.authenticated) available.push(\"gemini-cli\");\n if (geminiKey.configured) available.push(\"gemini-api\");\n if (codex.found && codex.authenticated) available.push(\"codex-cli\");\n\n return {\n tools: {\n node,\n git,\n hubspot: { ...hs, ...hsAuth },\n github: { ...gh, ...ghAuth },\n claudeCode: claude,\n geminiCli: gemini,\n codexCli: codex,\n },\n apiKeys: {\n anthropic: anthropicKey,\n openai: openaiKey,\n gemini: geminiKey,\n },\n activeEngine: config.aiEngine || null,\n availableEngines: available,\n };\n}\n","import { execSync, type ExecSyncOptions } from \"node:child_process\";\n\nexport interface ShellResult {\n stdout: string;\n stderr: string;\n success: boolean;\n}\n\nexport function run(\n command: string,\n options: ExecSyncOptions = {}\n): ShellResult {\n try {\n const stdout = execSync(command, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n timeout: 120_000,\n ...options,\n }).trim();\n return { stdout, stderr: \"\", success: true };\n } catch (err: unknown) {\n const e = err as { stdout?: Buffer | string; stderr?: Buffer | string };\n const stdout = (e.stdout ?? \"\").toString().trim();\n const stderr = (e.stderr ?? \"\").toString().trim();\n return { stdout, stderr, success: false };\n }\n}\n\nexport function runOrThrow(\n command: string,\n options: ExecSyncOptions = {}\n): string {\n return execSync(command, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n timeout: 120_000,\n ...options,\n }).trim();\n}\n\nexport function runPassthrough(\n command: string,\n options: ExecSyncOptions = {}\n): boolean {\n try {\n execSync(command, {\n stdio: \"inherit\",\n timeout: 300_000,\n ...options,\n });\n return true;\n } catch {\n return false;\n }\n}\n","import { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { readFile, writeFile, fileExists } from \"./fs.js\";\n\nexport type AIEngineType =\n | \"claude-code\"\n | \"anthropic-api\"\n | \"openai-api\"\n | \"gemini-cli\"\n | \"gemini-api\"\n | \"codex-cli\"\n // Legacy value — migrated to \"anthropic-api\" on load\n | \"api\";\n\nexport interface VibeSpotConfig {\n aiEngine?: AIEngineType;\n anthropicApiKey?: string;\n openaiApiKey?: string;\n geminiApiKey?: string;\n claudeCodeModel?: string;\n anthropicApiModel?: string;\n openaiApiModel?: string;\n lastThemePath?: string;\n lastSourcePath?: string;\n}\n\nconst CONFIG_DIR = join(homedir(), \".vibespot\");\nconst CONFIG_PATH = join(CONFIG_DIR, \"config.json\");\n\nexport function loadConfig(): VibeSpotConfig {\n if (!fileExists(CONFIG_PATH)) return {};\n\n try {\n const raw = JSON.parse(readFile(CONFIG_PATH));\n // Migrate legacy \"api\" engine type\n if (raw.aiEngine === \"api\") {\n raw.aiEngine = \"anthropic-api\";\n }\n return raw;\n } catch {\n return {};\n }\n}\n\n/**\n * Get the API key for a given engine, checking config first then env vars.\n */\nexport function getApiKeyForEngine(engine: AIEngineType, config?: VibeSpotConfig): string | undefined {\n const c = config || loadConfig();\n switch (engine) {\n case \"anthropic-api\":\n case \"api\":\n return c.anthropicApiKey || process.env.ANTHROPIC_API_KEY;\n case \"openai-api\":\n return c.openaiApiKey || process.env.OPENAI_API_KEY;\n case \"gemini-api\":\n return c.geminiApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY;\n default:\n return undefined;\n }\n}\n\n/**\n * Mask an API key for display (show first 7 + last 4 chars).\n */\nexport function maskApiKey(key: string): string {\n if (key.length <= 12) return \"***\";\n return key.slice(0, 7) + \"...\" + key.slice(-4);\n}\n\nexport function saveConfig(config: VibeSpotConfig): void {\n const existing = loadConfig();\n const merged = { ...existing, ...config };\n writeFile(CONFIG_PATH, JSON.stringify(merged, null, 2));\n}\n\nexport function getConfigDir(): string {\n return CONFIG_DIR;\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nexport function readFile(path: string): string {\n return readFileSync(path, \"utf-8\");\n}\n\nexport function writeFile(path: string, content: string): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, content, \"utf-8\");\n}\n\nexport function fileExists(path: string): boolean {\n return existsSync(path);\n}\n\nexport function ensureDir(path: string): void {\n mkdirSync(path, { recursive: true });\n}\n\nexport function resolveAsset(name: string): string {\n // In built package, assets/ is at the package root\n // During dev, it's relative to the project root\n const paths = [\n join(import.meta.dirname, \"../../assets\", name),\n join(import.meta.dirname, \"../assets\", name),\n join(process.cwd(), \"assets\", name),\n ];\n\n for (const p of paths) {\n if (existsSync(p)) return p;\n }\n\n throw new Error(`Asset not found: ${name}`);\n}\n","import * as p from \"@clack/prompts\";\nimport { theme } from \"../cli/theme.js\";\n\nexport function isCancel(value: unknown): value is symbol {\n return p.isCancel(value);\n}\n\nexport function handleCancel(value: unknown): void {\n if (p.isCancel(value)) {\n p.cancel(theme.muted(\"Operation cancelled.\"));\n process.exit(0);\n }\n}\n\nexport async function intro(title: string): Promise<void> {\n p.intro(theme.heading(title));\n}\n\nexport async function outro(message: string): Promise<void> {\n p.outro(theme.success(message));\n}\n\nexport async function note(message: string, title?: string): Promise<void> {\n p.note(message, title ? theme.heading(title) : undefined);\n}\n\nexport async function text(opts: {\n message: string;\n placeholder?: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n}): Promise<string> {\n const result = await p.text({\n message: theme.accent(opts.message),\n placeholder: opts.placeholder,\n defaultValue: opts.defaultValue,\n validate: opts.validate,\n });\n handleCancel(result);\n return result as string;\n}\n\nexport async function confirm(opts: {\n message: string;\n initialValue?: boolean;\n}): Promise<boolean> {\n const result = await p.confirm({\n message: theme.accent(opts.message),\n initialValue: opts.initialValue ?? true,\n });\n handleCancel(result);\n return result as boolean;\n}\n\nexport async function select<T extends string>(opts: {\n message: string;\n options: { value: T; label: string; hint?: string }[];\n}): Promise<T> {\n const result = await p.select({\n message: theme.accent(opts.message),\n options: opts.options,\n });\n handleCancel(result);\n return result as T;\n}\n\nexport async function spinner(): Promise<{\n start: (msg: string) => void;\n stop: (msg: string) => void;\n message: (msg: string) => void;\n}> {\n const s = p.spinner();\n return {\n start: (msg: string) => s.start(theme.muted(msg)),\n stop: (msg: string) => s.stop(theme.success(msg)),\n message: (msg: string) => s.message(theme.muted(msg)),\n };\n}\n\nexport function log(message: string): void {\n p.log.info(message);\n}\n\nexport function logSuccess(message: string): void {\n p.log.success(theme.success(message));\n}\n\nexport function logWarn(message: string): void {\n p.log.warn(theme.warn(message));\n}\n\nexport function logError(message: string): void {\n p.log.error(theme.error(message));\n}\n\nexport function logStep(message: string): void {\n p.log.step(theme.accent(message));\n}\n","import {\n detectNode,\n detectGit,\n detectHubSpotCLI,\n detectClaudeCode,\n detectGeminiCLI,\n detectCodexCLI,\n detectHubSpotAuth,\n hasAnthropicKey,\n nodeVersionOk,\n} from \"../utils/detect.js\";\nimport { run, runPassthrough } from \"../utils/shell.js\";\nimport { saveConfig, loadConfig, type AIEngineType } from \"../utils/config.js\";\nimport * as ui from \"../prompts/prompter.js\";\nimport { theme } from \"../cli/theme.js\";\n\nexport interface PreflightResult {\n aiEngine: AIEngineType;\n model?: string;\n portalId: string;\n portalName: string;\n}\n\nexport async function runPreflight(): Promise<PreflightResult> {\n await ui.intro(\"Checking your environment\");\n\n // Node.js\n const node = detectNode();\n if (!node.found) {\n ui.logError(\"Node.js not found. Install it from https://nodejs.org\");\n process.exit(1);\n }\n if (!nodeVersionOk(node.version)) {\n ui.logError(\n `Node.js ${node.version} is too old. Version 18+ required. Update at https://nodejs.org`\n );\n process.exit(1);\n }\n ui.logSuccess(`Node.js v${node.version}`);\n\n // Git\n const git = detectGit();\n if (!git.found) {\n ui.logError(\"Git not found. Install it from https://git-scm.com\");\n process.exit(1);\n }\n ui.logSuccess(`Git ${git.version}`);\n\n // HubSpot CLI\n let hs = detectHubSpotCLI();\n if (!hs.found) {\n ui.logWarn(\"HubSpot CLI not found\");\n await ui.note(\n \"The HubSpot CLI is required to upload your theme.\\nI'll install it for you now.\",\n \"Missing dependency\"\n );\n\n const install = await ui.confirm({\n message: \"Install HubSpot CLI globally?\",\n });\n\n if (!install) {\n ui.logError(\n \"HubSpot CLI is required. Install manually: npm install -g @hubspot/cli\"\n );\n process.exit(1);\n }\n\n const s = await ui.spinner();\n s.start(\"Installing HubSpot CLI...\");\n\n const result = run(\"npm install -g @hubspot/cli\");\n if (!result.success) {\n s.stop(\"Failed to install HubSpot CLI\");\n ui.logError(\"Try running manually: npm install -g @hubspot/cli\");\n process.exit(1);\n }\n\n hs = detectHubSpotCLI();\n s.stop(`HubSpot CLI v${hs.version} installed`);\n } else {\n ui.logSuccess(`HubSpot CLI v${hs.version}`);\n }\n\n // HubSpot authentication\n let auth = detectHubSpotAuth();\n if (!auth.authenticated) {\n ui.logWarn(\"HubSpot not authenticated\");\n await ui.note(\n \"You need to connect the CLI to your HubSpot account.\\nThis will open a browser window — log in and authorize.\",\n \"Authentication required\"\n );\n\n const doAuth = await ui.confirm({ message: \"Run `hs init` now?\" });\n\n if (!doAuth) {\n ui.logError(\"HubSpot authentication is required. Run `hs init` manually.\");\n process.exit(1);\n }\n\n const s = await ui.spinner();\n s.start(\"Waiting for HubSpot authentication...\");\n\n const authOk = runPassthrough(\"hs init\");\n if (!authOk) {\n s.stop(\"Authentication failed\");\n ui.logError(\"HubSpot authentication failed. Try running `hs init` manually.\");\n process.exit(1);\n }\n\n auth = detectHubSpotAuth();\n s.stop(\n `Connected to portal${auth.portalName ? `: ${auth.portalName}` : \"\"} (ID: ${auth.portalId})`\n );\n } else {\n ui.logSuccess(\n `HubSpot portal${auth.portalName ? `: ${auth.portalName}` : \"\"} (ID: ${auth.portalId})`\n );\n }\n\n // AI Engine selection\n const claude = detectClaudeCode();\n const gemini = detectGeminiCLI();\n const codex = detectCodexCLI();\n const hasKey = hasAnthropicKey();\n const config = loadConfig();\n\n const engineLabels: Record<AIEngineType, string> = {\n \"claude-code\": \"Claude Code\",\n \"api\": \"Anthropic API\",\n \"anthropic-api\": \"Anthropic API\",\n \"openai-api\": \"OpenAI API\",\n \"gemini-api\": \"Gemini API\",\n \"gemini-cli\": \"Gemini CLI\",\n \"codex-cli\": \"OpenAI Codex\",\n };\n\n let aiEngine: AIEngineType;\n const lastUsed = config.aiEngine;\n\n // Always build list of available engines\n const available: { value: AIEngineType; label: string; hint: string }[] = [];\n\n if (claude.found) {\n available.push({\n value: \"claude-code\",\n label: \"Claude Code\",\n hint: lastUsed === \"claude-code\"\n ? \"last used — recommended\"\n : \"uses your existing Claude subscription — recommended\",\n });\n }\n if (gemini.found) {\n available.push({\n value: \"gemini-cli\",\n label: \"Gemini CLI\",\n hint: lastUsed === \"gemini-cli\"\n ? \"last used\"\n : \"uses your existing Gemini setup\",\n });\n }\n if (codex.found) {\n available.push({\n value: \"codex-cli\",\n label: \"OpenAI Codex\",\n hint: lastUsed === \"codex-cli\"\n ? \"last used\"\n : \"uses your existing OpenAI setup\",\n });\n }\n if (hasKey) {\n available.push({\n value: \"api\",\n label: \"Anthropic API\",\n hint: lastUsed === \"api\"\n ? \"last used\"\n : \"uses your API key\",\n });\n }\n\n // Sort last-used engine to the top\n if (lastUsed) {\n available.sort((a, b) =>\n a.value === lastUsed ? -1 : b.value === lastUsed ? 1 : 0\n );\n }\n\n if (available.length === 1) {\n // Only one option — use it automatically\n aiEngine = available[0].value;\n ui.logSuccess(`AI engine: ${engineLabels[aiEngine]} (auto-detected)`);\n } else if (available.length > 1) {\n // Multiple available — always ask\n aiEngine = await ui.select({\n message: \"Choose your AI engine:\",\n options: available,\n });\n } else {\n // None available — guide the user\n await ui.note(\n \"You need an AI coding assistant to power the conversion.\\n\\n\" +\n `${theme.bold(\"Option 1:\")} Install Claude Code ${theme.muted(\"(recommended)\")}\\n` +\n \" https://claude.ai/code\\n\\n\" +\n `${theme.bold(\"Option 2:\")} Install Gemini CLI\\n` +\n \" https://github.com/google-gemini/gemini-cli\\n\\n\" +\n `${theme.bold(\"Option 3:\")} Install OpenAI Codex\\n` +\n \" https://github.com/openai/codex\\n\\n\" +\n `${theme.bold(\"Option 4:\")} Set an Anthropic API key\\n` +\n \" export ANTHROPIC_API_KEY=sk-ant-...\\n\" +\n \" (get one at https://console.anthropic.com)\",\n \"AI engine required\"\n );\n\n aiEngine = await ui.select({\n message: \"Which will you set up?\",\n options: [\n {\n value: \"claude-code\" as const,\n label: \"Claude Code\",\n hint: \"I'll install it now\",\n },\n {\n value: \"gemini-cli\" as const,\n label: \"Gemini CLI\",\n hint: \"I'll install it now\",\n },\n {\n value: \"codex-cli\" as const,\n label: \"OpenAI Codex\",\n hint: \"I'll install it now\",\n },\n {\n value: \"api\" as const,\n label: \"Anthropic API\",\n hint: \"I'll enter my key\",\n },\n ],\n });\n\n if (aiEngine === \"api\") {\n const key = await ui.text({\n message: \"Enter your Anthropic API key:\",\n placeholder: \"sk-ant-api03-...\",\n validate: (v) =>\n v.startsWith(\"sk-ant-\") ? undefined : \"Key should start with sk-ant-\",\n });\n process.env.ANTHROPIC_API_KEY = key;\n saveConfig({ anthropicApiKey: key });\n }\n }\n\n // Model selection for Claude Code\n let model: string | undefined;\n if (aiEngine === \"claude-code\") {\n model = await ui.select({\n message: \"Which model?\",\n options: [\n { value: \"sonnet\", label: \"Sonnet\", hint: \"fast, recommended\" },\n { value: \"opus\", label: \"Opus\", hint: \"most capable\" },\n { value: \"haiku\", label: \"Haiku\", hint: \"fastest, cheapest\" },\n ],\n });\n }\n\n saveConfig({ aiEngine });\n\n await ui.outro(\"Environment ready!\");\n\n return {\n aiEngine,\n model,\n portalId: auth.portalId,\n portalName: auth.portalName,\n };\n}\n","import { readdirSync, statSync } from \"node:fs\";\nimport { join, basename, extname } from \"node:path\";\nimport { run } from \"../utils/shell.js\";\nimport { fileExists, readFile } from \"../utils/fs.js\";\nimport * as ui from \"../prompts/prompter.js\";\nimport { theme } from \"../cli/theme.js\";\n\nexport interface ComponentInfo {\n name: string;\n path: string;\n description: string;\n}\n\nexport interface SourceAnalysis {\n sourceDir: string;\n wasCloned: boolean;\n components: ComponentInfo[];\n hasTailwind: boolean;\n cssVarCount: number;\n fonts: string[];\n interactions: string[];\n}\n\nfunction findComponents(dir: string): ComponentInfo[] {\n const components: ComponentInfo[] = [];\n\n // Common locations for landing page components\n const searchDirs = [\n join(dir, \"src/components/landing\"),\n join(dir, \"src/components/sections\"),\n join(dir, \"src/components\"),\n join(dir, \"src/pages\"),\n join(dir, \"app/components\"),\n join(dir, \"components\"),\n ];\n\n for (const searchDir of searchDirs) {\n if (!fileExists(searchDir)) continue;\n\n try {\n const files = readdirSync(searchDir);\n for (const file of files) {\n const filePath = join(searchDir, file);\n const stat = statSync(filePath);\n if (!stat.isFile()) continue;\n\n const ext = extname(file);\n if (![\".tsx\", \".jsx\"].includes(ext)) continue;\n\n // Skip utility/UI components\n const name = basename(file, ext);\n if (name.startsWith(\"ui\") || name === \"index\") continue;\n\n // Read the file to extract a description\n const content = readFile(filePath);\n const desc = describeComponent(name, content);\n\n components.push({ name, path: filePath, description: desc });\n }\n } catch {\n // Directory read failed, skip\n }\n }\n\n return components;\n}\n\nfunction describeComponent(name: string, content: string): string {\n const hints: string[] = [];\n\n if (/carousel|slider|swiper|embla/i.test(content)) hints.push(\"carousel\");\n if (/accordion|collapsible|expand/i.test(content)) hints.push(\"accordion\");\n if (/form|submit|input.*email/i.test(content)) hints.push(\"form\");\n if (/nav|navigation|menu/i.test(content)) hints.push(\"navigation\");\n if (/hero|headline|tagline/i.test(content)) hints.push(\"hero\");\n if (/footer|copyright/i.test(content)) hints.push(\"footer\");\n if (/testimonial|quote|review/i.test(content)) hints.push(\"testimonials\");\n if (/pricing|plan|tier/i.test(content)) hints.push(\"pricing\");\n if (/faq|question.*answer/i.test(content)) hints.push(\"FAQ\");\n if (/feature|benefit|advantage/i.test(content)) hints.push(\"features\");\n if (/contact|get.in.touch/i.test(content)) hints.push(\"contact\");\n if (/cta|call.to.action/i.test(content)) hints.push(\"CTA\");\n if (/team|member|bio/i.test(content)) hints.push(\"team\");\n\n if (hints.length === 0) {\n // Fallback: infer from component name\n const readable = name\n .replace(/Section$/, \"\")\n .replace(/([A-Z])/g, \" $1\")\n .trim();\n return readable;\n }\n\n return hints.join(\", \");\n}\n\nfunction analyzeCSS(dir: string): { varCount: number; fonts: string[] } {\n const cssFiles = [\n join(dir, \"src/index.css\"),\n join(dir, \"src/globals.css\"),\n join(dir, \"src/app/globals.css\"),\n join(dir, \"app/globals.css\"),\n ];\n\n let varCount = 0;\n const fonts: string[] = [];\n\n for (const cssFile of cssFiles) {\n if (!fileExists(cssFile)) continue;\n\n const content = readFile(cssFile);\n const varMatches = content.match(/--[\\w-]+:/g);\n if (varMatches) varCount += varMatches.length;\n\n const fontMatches = content.match(\n /font-family:\\s*['\"]([^'\"]+)['\"]/g\n );\n if (fontMatches) {\n for (const m of fontMatches) {\n const font = m.match(/['\"]([^'\"]+)['\"]/)?.[1];\n if (font && !fonts.includes(font)) fonts.push(font);\n }\n }\n\n const importMatches = content.match(\n /@import\\s+url\\([^)]*fonts\\.googleapis\\.com[^)]*family=([^&)]+)/g\n );\n if (importMatches) {\n for (const m of importMatches) {\n const font = m.match(/family=([^&)]+)/)?.[1]?.replace(/\\+/g, \" \");\n if (font && !fonts.includes(font)) fonts.push(font);\n }\n }\n }\n\n return { varCount, fonts };\n}\n\nfunction detectInteractions(dir: string): string[] {\n const interactions: string[] = [];\n\n const hooksDir = join(dir, \"src/hooks\");\n if (fileExists(hooksDir)) {\n try {\n const hooks = readdirSync(hooksDir);\n for (const hook of hooks) {\n if (/scroll/i.test(hook)) interactions.push(\"Scroll animations\");\n if (/intersection/i.test(hook)) interactions.push(\"Scroll animations\");\n }\n } catch {\n // Ignore\n }\n }\n\n // Check landing components for patterns\n const componentDir = join(dir, \"src/components/landing\");\n if (fileExists(componentDir)) {\n try {\n const files = readdirSync(componentDir);\n for (const file of files) {\n if (!file.endsWith(\".tsx\") && !file.endsWith(\".jsx\")) continue;\n const content = readFile(join(componentDir, file));\n if (/carousel|embla|swiper/i.test(content) && !interactions.includes(\"Carousel\"))\n interactions.push(\"Carousel\");\n if (/accordion|collapsible/i.test(content) && !interactions.includes(\"Accordion\"))\n interactions.push(\"Accordion\");\n if (/typing|typewriter/i.test(content) && !interactions.includes(\"Typing animation\"))\n interactions.push(\"Typing animation\");\n if (/parallax|requestAnimationFrame/i.test(content) && !interactions.includes(\"Parallax\"))\n interactions.push(\"Parallax\");\n }\n } catch {\n // Ignore\n }\n }\n\n if (interactions.length === 0) {\n interactions.push(\"Scroll animations\");\n }\n\n return interactions;\n}\n\n/**\n * Headless source analysis — called from the vibe server (no interactive prompts).\n * Clones the repo if it's a URL, then analyzes components.\n */\nexport function analyzeSource(input: string): SourceAnalysis {\n let sourceDir: string;\n let wasCloned = false;\n\n if (input.startsWith(\"http\") || input.startsWith(\"git@\")) {\n wasCloned = true;\n const repoName =\n basename(input.replace(/\\.git$/, \"\")) || \"react-source\";\n sourceDir = join(process.cwd(), \"workspace\", repoName);\n\n if (!fileExists(sourceDir)) {\n const result = run(`git clone --depth 1 \"${input}\" \"${sourceDir}\"`);\n if (!result.success) {\n throw new Error(`Failed to clone ${input}: ${result.stderr}`);\n }\n }\n } else {\n sourceDir = input;\n if (!fileExists(sourceDir)) {\n throw new Error(`Directory not found: ${sourceDir}`);\n }\n }\n\n const components = findComponents(sourceDir);\n const hasTailwind =\n fileExists(join(sourceDir, \"tailwind.config.ts\")) ||\n fileExists(join(sourceDir, \"tailwind.config.js\"));\n const { varCount, fonts } = analyzeCSS(sourceDir);\n const interactions = detectInteractions(sourceDir);\n\n return {\n sourceDir,\n wasCloned,\n components,\n hasTailwind,\n cssVarCount: varCount,\n fonts,\n interactions,\n };\n}\n\nexport async function setupSource(): Promise<SourceAnalysis> {\n await ui.intro(\"Source Project\");\n\n const input = await ui.text({\n message: \"GitHub URL or local path to your React project:\",\n placeholder: \"https://github.com/user/my-lovable-page\",\n validate: (v) => {\n if (!v.trim()) return \"Please enter a URL or path\";\n return undefined;\n },\n });\n\n let sourceDir: string;\n let wasCloned = false;\n\n if (input.startsWith(\"http\") || input.startsWith(\"git@\")) {\n wasCloned = true;\n // Clone from GitHub\n const repoName =\n basename(input.replace(/\\.git$/, \"\")) || \"react-source\";\n sourceDir = join(process.cwd(), \"workspace\", repoName);\n\n if (fileExists(sourceDir)) {\n // Already cloned from a previous run — reuse it\n ui.logSuccess(`Using existing clone: ${theme.dim(sourceDir)}`);\n } else {\n const s = await ui.spinner();\n s.start(\"Cloning repository...\");\n\n const result = run(`git clone --depth 1 \"${input}\" \"${sourceDir}\"`);\n if (!result.success) {\n s.stop(\"Clone failed\");\n ui.logError(\n `Failed to clone ${input}. Check the URL and your access permissions.`\n );\n process.exit(1);\n }\n\n s.stop(`Cloned to ${theme.dim(sourceDir)}`);\n }\n } else {\n sourceDir = input;\n if (!fileExists(sourceDir)) {\n ui.logError(`Directory not found: ${sourceDir}`);\n process.exit(1);\n }\n ui.logSuccess(`Using local source: ${theme.dim(sourceDir)}`);\n }\n\n // Analyze\n const s = await ui.spinner();\n s.start(\"Analyzing project structure...\");\n\n const components = findComponents(sourceDir);\n const hasTailwind =\n fileExists(join(sourceDir, \"tailwind.config.ts\")) ||\n fileExists(join(sourceDir, \"tailwind.config.js\"));\n const { varCount, fonts } = analyzeCSS(sourceDir);\n const interactions = detectInteractions(sourceDir);\n\n s.stop(`Found ${components.length} landing page components`);\n\n if (components.length === 0) {\n ui.logWarn(\n \"No components found. Make sure the React source has .tsx/.jsx files in src/components/\"\n );\n process.exit(1);\n }\n\n // Show summary\n const componentList = components\n .map((c, i) => ` ${theme.dim(`${i + 1}.`)} ${theme.bold(c.name)} ${theme.muted(`— ${c.description}`)}`)\n .join(\"\\n\");\n\n const cssInfo = hasTailwind\n ? `Tailwind + custom CSS (${varCount} variables)`\n : `Custom CSS (${varCount} variables)`;\n const fontInfo = fonts.length > 0 ? fonts.join(\", \") : \"System fonts\";\n const jsInfo = interactions.join(\", \");\n\n await ui.note(\n `${componentList}\\n\\n CSS: ${cssInfo}\\n JS: ${jsInfo}\\n Font: ${fontInfo}`,\n `${components.length} components detected`\n );\n\n const ok = await ui.confirm({ message: \"Does this look right?\" });\n if (!ok) {\n ui.logError(\"Please adjust your source directory and try again.\");\n process.exit(0);\n }\n\n await ui.outro(\"Source analyzed!\");\n\n return {\n sourceDir,\n wasCloned,\n components,\n hasTailwind,\n cssVarCount: varCount,\n fonts,\n interactions,\n };\n}\n","import { join } from \"node:path\";\nimport { readdirSync, renameSync } from \"node:fs\";\nimport { run, runPassthrough } from \"../utils/shell.js\";\nimport { fileExists, readFile, writeFile, ensureDir } from \"../utils/fs.js\";\nimport * as ui from \"../prompts/prompter.js\";\nimport { theme } from \"../cli/theme.js\";\n\nexport interface ThemeInfo {\n themePath: string;\n themeName: string;\n}\n\nexport async function setupTheme(): Promise<ThemeInfo> {\n await ui.intro(\"HubSpot Theme Setup\");\n\n const choice = await ui.select({\n message: \"Do you have an existing HubSpot theme?\",\n options: [\n {\n value: \"fetch\" as const,\n label: \"Fetch my existing theme from HubSpot\",\n hint: \"downloads your current theme\",\n },\n {\n value: \"create\" as const,\n label: \"Start fresh (HubSpot Boilerplate)\",\n hint: \"creates a new starter theme\",\n },\n ],\n });\n\n let themeName: string;\n let themePath: string;\n\n const workspaceDir = join(process.cwd(), \"workspace\");\n ensureDir(workspaceDir);\n\n if (choice === \"fetch\") {\n themeName = await ui.text({\n message: \"What's your theme name in HubSpot?\",\n placeholder: \"My-Company-Theme\",\n validate: (v) =>\n v.trim() ? undefined : \"Theme name is required\",\n });\n\n themePath = join(workspaceDir, themeName);\n\n const s = await ui.spinner();\n s.start(\"Fetching theme from HubSpot...\");\n\n const result = run(`hs fetch \"${themeName}\" \"${themePath}\"`);\n if (!result.success) {\n s.stop(\"Fetch failed\");\n ui.logError(\n `Could not fetch theme \"${themeName}\". Check the name in HubSpot Design Manager.`\n );\n ui.logError('Run `hs list /` to see available themes.');\n process.exit(1);\n }\n\n s.stop(`Theme fetched: ${theme.dim(themePath)}`);\n } else {\n themeName = await ui.text({\n message: \"Name for your new theme:\",\n placeholder: \"my-theme\",\n defaultValue: \"my-theme\",\n });\n\n themePath = join(workspaceDir, themeName);\n\n const s = await ui.spinner();\n s.start(\"Creating theme from boilerplate...\");\n\n // Snapshot cwd contents before hs create to detect what it creates\n const cwdBefore = new Set(readdirSync(process.cwd()));\n\n // hs create always creates in process.cwd(), ignoring execSync cwd\n const result = run(`hs create website-theme \"${themeName}\"`);\n\n // Find the created directory — hs create may use exact name or a variant\n let createdAt = join(process.cwd(), themeName);\n if (!fileExists(createdAt)) {\n // Fallback: find any new directory that appeared in cwd\n const cwdAfter = readdirSync(process.cwd());\n const newDir = cwdAfter.find((e) => !cwdBefore.has(e) && fileExists(join(process.cwd(), e)));\n if (newDir) {\n createdAt = join(process.cwd(), newDir);\n }\n }\n\n if (!result.success || !fileExists(createdAt)) {\n s.stop(\"Creation failed\");\n const errMsg = result.stderr || result.stdout || \"\";\n ui.logError(\n `Could not create theme \"${themeName}\".` +\n (errMsg ? `\\n${errMsg.slice(0, 300)}` : \"\") +\n \"\\nTry running manually: hs create website-theme my-theme\"\n );\n process.exit(1);\n }\n\n // Move from cwd into workspace/\n if (createdAt !== themePath) {\n renameSync(createdAt, themePath);\n }\n\n s.stop(`Theme created: ${theme.dim(themePath)}`);\n\n // Rename theme label from \"CMS theme boilerplate\" to the user's chosen name\n const themeJsonPath = join(themePath, \"theme.json\");\n if (fileExists(themeJsonPath)) {\n try {\n const themeJson = JSON.parse(readFile(themeJsonPath));\n themeJson.label = themeName;\n writeFile(themeJsonPath, JSON.stringify(themeJson, null, 2) + \"\\n\");\n ui.logSuccess(`Theme label set to \"${themeName}\"`);\n } catch {\n ui.logWarn(\"Could not update theme.json label — you can rename it manually in HubSpot.\");\n }\n }\n }\n\n // Validate and patch\n await ui.intro(\"Checking theme compatibility\");\n\n const baseHtmlPath = join(themePath, \"templates/layouts/base.html\");\n if (!fileExists(baseHtmlPath)) {\n ui.logError(\n `base.html not found at ${baseHtmlPath}. Your theme may have a different structure.`\n );\n process.exit(1);\n }\n ui.logSuccess(\"base.html found\");\n\n // Check for template_css and template_js support\n let baseHtml = readFile(baseHtmlPath);\n let patched = false;\n\n if (!baseHtml.includes(\"template_css\")) {\n ui.logWarn(\"Missing template_css support in base.html\");\n\n // Find the line with require_css for theme-overrides or the last require_css\n const cssInsertPoint =\n baseHtml.indexOf(\"theme-overrides.css\") !== -1\n ? baseHtml.indexOf(\n \"{{\",\n baseHtml.lastIndexOf(\"\\n\", baseHtml.indexOf(\"theme-overrides.css\"))\n )\n : baseHtml.lastIndexOf(\"require_css\");\n\n if (cssInsertPoint > 0) {\n const insertBefore = baseHtml.lastIndexOf(\"\\n\", cssInsertPoint);\n const block = `\\n {% if template_css %}\\n {{ require_css(get_asset_url(template_css)) }}\\n {% endif %}`;\n baseHtml =\n baseHtml.slice(0, insertBefore) + block + baseHtml.slice(insertBefore);\n patched = true;\n }\n } else {\n ui.logSuccess(\"template_css support\");\n }\n\n if (!baseHtml.includes(\"template_js\")) {\n ui.logWarn(\"Missing template_js support in base.html\");\n\n // Find the line with require_js for main.js or the last require_js\n const jsLine = baseHtml.indexOf(\"require_js\");\n if (jsLine > 0) {\n const lineEnd = baseHtml.indexOf(\"\\n\", jsLine);\n // Find the end of the require_js line (including closing tags)\n const nextLine = baseHtml.indexOf(\"\\n\", lineEnd + 1);\n const block = `\\n {% if template_js %}\\n {{ require_js(get_asset_url(template_js)) }}\\n {% endif %}`;\n const insertAt =\n baseHtml.indexOf(\"}}\", jsLine) + 2 + baseHtml.slice(baseHtml.indexOf(\"}}\", jsLine) + 2).indexOf(\"\\n\") + 1;\n baseHtml =\n baseHtml.slice(0, baseHtml.indexOf(\"\\n\", baseHtml.indexOf(\"}}\", jsLine) + 2)) +\n block +\n baseHtml.slice(baseHtml.indexOf(\"\\n\", baseHtml.indexOf(\"}}\", jsLine) + 2));\n patched = true;\n }\n } else {\n ui.logSuccess(\"template_js support\");\n }\n\n if (patched) {\n const s = await ui.spinner();\n s.start(\"Patching base.html...\");\n writeFile(baseHtmlPath, baseHtml);\n s.stop(\"base.html patched with template_css/template_js support\");\n }\n\n // Check .hsignore\n const hsignorePath = join(themePath, \".hsignore\");\n if (fileExists(hsignorePath)) {\n const hsignore = readFile(hsignorePath);\n if (!hsignore.includes(\"docs/\")) {\n writeFile(hsignorePath, hsignore + \"\\ndocs/\\n\");\n ui.logSuccess(\"Added docs/ to .hsignore\");\n }\n } else {\n writeFile(hsignorePath, \"docs/\\n*.md\\nnode_modules/\\n.git\\n\");\n ui.logSuccess(\"Created .hsignore\");\n }\n\n await ui.outro(\"Theme ready!\");\n\n return { themePath, themeName };\n}\n","import { join } from \"node:path\";\nimport { readdirSync, rmSync } from \"node:fs\";\nimport type { AIEngine, GeneratedAssets } from \"../ai/engine.js\";\nimport type { AIEngineType } from \"../utils/config.js\";\nimport { ClaudeCodeEngine } from \"../ai/claude-code.js\";\nimport { ClaudeAPIEngine } from \"../ai/claude-api.js\";\nimport { GeminiCLIEngine } from \"../ai/gemini-cli.js\";\nimport { CodexCLIEngine } from \"../ai/codex-cli.js\";\nimport { getConversionGuide } from \"../ai/prompts.js\";\nimport { readFile, writeFile, fileExists } from \"../utils/fs.js\";\nimport * as ui from \"../prompts/prompter.js\";\n\nfunction createEngine(type: AIEngineType, model?: string): AIEngine {\n switch (type) {\n case \"claude-code\":\n return new ClaudeCodeEngine(model);\n case \"gemini-cli\":\n return new GeminiCLIEngine();\n case \"codex-cli\":\n return new CodexCLIEngine();\n case \"api\":\n return new ClaudeAPIEngine();\n }\n}\n\nexport async function runConversion(opts: {\n aiEngine: AIEngineType;\n model?: string;\n sourceDir: string;\n themePath: string;\n}): Promise<GeneratedAssets> {\n await ui.intro(\"Converting React to HubSpot Modules\");\n\n await ui.note(\n \"AI will now analyze your React code and create\\nHubSpot-native modules. This takes 2-5 minutes.\",\n \"AI Conversion\"\n );\n\n const engine = createEngine(opts.aiEngine, opts.model);\n\n const conversionGuide = getConversionGuide();\n\n const s = await ui.spinner();\n s.start(\"Starting AI conversion...\");\n\n const startTime = Date.now();\n\n const result = await engine.convert({\n sourceDir: opts.sourceDir,\n themePath: opts.themePath,\n conversionGuide,\n onProgress: (step, detail) => {\n if (step === \"created\") {\n ui.logSuccess(detail);\n } else {\n s.message(detail);\n }\n },\n });\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(0);\n s.stop(`AI conversion complete (${elapsed}s)`);\n\n // Validate and auto-fix all known HubSpot issues before upload\n const fixes = validateAndFix(opts.themePath);\n for (const fix of fixes) {\n ui.logSuccess(`Auto-fixed: ${fix}`);\n }\n\n // Show conversion checklist\n const checklist = buildChecklist(opts.themePath, result);\n const lines: string[] = [];\n for (const item of checklist) {\n const icon = item.passed ? \"\\u2705\" : \"\\u274c\";\n const severity = !item.passed ? (item.critical ? \" (CRITICAL)\" : \" (cosmetic)\") : \"\";\n lines.push(`${icon} ${item.label}${severity}`);\n }\n const passed = checklist.filter((c) => c.passed).length;\n lines.push(`\\n${passed}/${checklist.length} checks passed`);\n await ui.note(lines.join(\"\\n\"), \"Conversion Checklist\");\n\n const criticalFailures = checklist.filter((c) => !c.passed && c.critical);\n const cosmeticFailures = checklist.filter((c) => !c.passed && !c.critical);\n\n if (criticalFailures.length > 0) {\n ui.logError(\n `${criticalFailures.length} critical issue(s) — upload will likely fail:\\n` +\n criticalFailures.map((c) => ` - ${c.label}`).join(\"\\n\")\n );\n const proceed = await ui.confirm({\n message: \"Continue with upload anyway?\",\n initialValue: false,\n });\n if (!proceed) {\n throw new Error(\"Conversion aborted due to critical checklist failures.\");\n }\n } else if (cosmeticFailures.length > 0) {\n ui.logWarn(\n `${cosmeticFailures.length} non-critical issue(s) — page will work but may look incomplete:\\n` +\n cosmeticFailures.map((c) => ` - ${c.label}`).join(\"\\n\")\n );\n }\n\n // Offer to clean up log file\n const logPath = join(opts.themePath, \"..\", \"vibespot-conversion.log\");\n if (fileExists(logPath)) {\n const keepLog = await ui.confirm({\n message: \"Keep conversion log file for debugging?\",\n initialValue: false,\n });\n if (!keepLog) {\n rmSync(logPath);\n } else {\n ui.logSuccess(`Log saved: ${logPath}`);\n }\n }\n\n await ui.outro(\"Files ready for upload!\");\n\n return result;\n}\n\n/**\n * Run all validation and auto-fix routines before upload.\n * Returns a list of human-readable fix descriptions.\n */\nexport function validateAndFix(themePath: string): string[] {\n const fixes: string[] = [];\n\n // 1. Template annotations\n validateTemplates(themePath);\n\n // 2. Module meta.json\n validateModuleMeta(themePath);\n\n // 3. Fix fields.json issues in all modules\n const modulesDir = join(themePath, \"modules\");\n if (fileExists(modulesDir)) {\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const fieldsPath = join(modulesDir, entry, \"fields.json\");\n if (!fileExists(fieldsPath)) continue;\n\n const moduleName = entry.replace(\".module\", \"\");\n let content = readFile(fieldsPath);\n let changed = false;\n\n // 3a. \"textarea\" → \"text\"\n if (content.includes('\"textarea\"')) {\n content = content.replace(/\"textarea\"/g, '\"text\"');\n changed = true;\n fixes.push(`${moduleName}: \"textarea\" → \"text\"`);\n }\n\n // 3b. \"name\": \"name\" → \"name\": \"item_name\"\n if (/\"name\":\\s*\"name\"/.test(content)) {\n content = content.replace(/\"name\":\\s*\"name\"/g, '\"name\": \"item_name\"');\n changed = true;\n fixes.push(`${moduleName}: reserved field name \"name\" → \"item_name\"`);\n }\n\n // 3c. Fix \"choice\" fields — choices must be [[\"value\",\"Label\"]] not [\"value\"]\n // 3d. Fix \"link\" fields — default must be { url: { href, type }, open_in_new_tab, no_follow }\n try {\n const fields = JSON.parse(content);\n let jsonFixed = false;\n if (fixChoiceFields(fields)) {\n jsonFixed = true;\n fixes.push(`${moduleName}: fixed choice field format`);\n }\n if (fixLinkFields(fields)) {\n jsonFixed = true;\n fixes.push(`${moduleName}: fixed link field default value`);\n }\n if (jsonFixed) {\n content = JSON.stringify(fields, null, 2) + \"\\n\";\n changed = true;\n }\n } catch {\n fixes.push(`${moduleName}: fields.json has invalid JSON — manual fix needed`);\n }\n\n if (changed) writeFile(fieldsPath, content);\n\n // 3d. Fix now() in module.html\n const htmlPath = join(modulesDir, entry, \"module.html\");\n if (fileExists(htmlPath)) {\n let html = readFile(htmlPath);\n if (html.includes(\"now()\")) {\n html = html.replace(/now\\(\\)/g, \"local_dt\");\n writeFile(htmlPath, html);\n fixes.push(`${moduleName}: now() → local_dt`);\n }\n }\n }\n }\n\n // 4. Remove HubDB templates (requires CMS Hub Pro/Enterprise)\n const templatesDir = join(themePath, \"templates\");\n if (fileExists(templatesDir)) {\n for (const file of readdirSync(templatesDir)) {\n if (!file.endsWith(\".html\")) continue;\n const filePath = join(templatesDir, file);\n const content = readFile(filePath);\n if (content.includes(\"hubdb_table\") || content.includes(\"hubdb_table_rows\")) {\n rmSync(filePath);\n fixes.push(`Removed ${file} (HubDB requires CMS Hub Pro/Enterprise)`);\n }\n }\n }\n\n return fixes;\n}\n\n/** Recursively fix choice fields: convert string[] choices to [value, Label][] */\nfunction fixChoiceFields(fields: unknown[]): boolean {\n let fixed = false;\n for (const field of fields) {\n if (typeof field !== \"object\" || field === null) continue;\n const f = field as Record<string, unknown>;\n\n if (f.type === \"choice\" && Array.isArray(f.choices)) {\n const needsFix = f.choices.some((c: unknown) => typeof c === \"string\");\n if (needsFix) {\n f.choices = (f.choices as unknown[]).map((c: unknown) => {\n if (typeof c === \"string\") {\n const label = c.charAt(0).toUpperCase() + c.slice(1);\n return [c, label];\n }\n return c;\n });\n fixed = true;\n }\n }\n\n // Recurse into group children\n if (Array.isArray(f.children)) {\n if (fixChoiceFields(f.children as unknown[])) fixed = true;\n }\n }\n return fixed;\n}\n\n/** Recursively fix link fields: default must be { url: { href, type }, open_in_new_tab, no_follow } */\nfunction fixLinkFields(fields: unknown[]): boolean {\n let fixed = false;\n for (const field of fields) {\n if (typeof field !== \"object\" || field === null) continue;\n const f = field as Record<string, unknown>;\n\n if (f.type === \"link\") {\n const def = f.default;\n // Fix if default is a string, missing, or doesn't have the required url.href structure\n const needsFix =\n typeof def === \"string\" ||\n def === undefined ||\n def === null ||\n (typeof def === \"object\" && !(def as Record<string, unknown>).url);\n\n if (needsFix) {\n const href = typeof def === \"string\" ? def : \"\";\n f.default = {\n url: { href, type: \"EXTERNAL\" },\n open_in_new_tab: false,\n no_follow: false,\n };\n fixed = true;\n }\n }\n\n // Recurse into group children\n if (Array.isArray(f.children)) {\n if (fixLinkFields(f.children as unknown[])) fixed = true;\n }\n }\n return fixed;\n}\n\ninterface CheckItem {\n label: string;\n passed: boolean;\n /** If true, failure blocks upload. If false, it's cosmetic / nice-to-have. */\n critical: boolean;\n}\n\nfunction buildChecklist(themePath: string, result: GeneratedAssets): CheckItem[] {\n const items: CheckItem[] = [];\n\n // Modules — critical: upload will fail with zero modules\n const moduleCount = result.modules.length;\n items.push({\n label: `Modules created (${moduleCount})`,\n passed: moduleCount > 0,\n critical: true,\n });\n\n // fields.json — critical: invalid fields cause upload deserialization errors\n let fieldsOk = true;\n for (const m of result.modules) {\n if (m.fieldsJson.includes('\"textarea\"') || /\"name\":\\s*\"name\"/.test(m.fieldsJson)) {\n fieldsOk = false;\n break;\n }\n }\n items.push({\n label: \"fields.json valid (no textarea, no reserved names)\",\n passed: moduleCount > 0 && fieldsOk,\n critical: true,\n });\n\n // module.html — critical: modules won't render without it\n const allHaveHtml = result.modules.every((m) => m.moduleHtml.length > 0);\n items.push({\n label: \"module.html created for each module\",\n passed: moduleCount > 0 && allHaveHtml,\n critical: true,\n });\n\n // module.css — not critical (page works but looks unstyled)\n const missingCss = result.modules.filter((m) => !m.moduleCss).map((m) => m.moduleName);\n const allHaveCss = missingCss.length === 0;\n items.push({\n label: allHaveCss\n ? \"module.css created for each module\"\n : `module.css missing for: ${missingCss.join(\", \")}`,\n passed: moduleCount > 0 && allHaveCss,\n critical: false,\n });\n\n // Style tab — not critical (modules work without style tab)\n const hasStyleTab = result.modules.some((m) => m.fieldsJson.includes('\"STYLE\"'));\n items.push({\n label: \"Style tab fields (color pickers)\",\n passed: hasStyleTab,\n critical: false,\n });\n\n // Shared CSS — not critical (modules have their own CSS)\n items.push({\n label: \"Shared CSS with design system variables\",\n passed: result.sharedCss.length > 50,\n critical: false,\n });\n\n // Shared JS — not critical (page works without animations)\n items.push({\n label: \"Shared JS for scroll animations\",\n passed: result.sharedJs.length > 50,\n critical: false,\n });\n\n // Page template — critical: no template means no page in HubSpot\n items.push({\n label: \"Page template with dnd_area\",\n passed: result.template.length > 0 && result.template.includes(\"dnd_area\"),\n critical: true,\n });\n\n // Template annotations — critical: template won't appear in picker\n const templatesDir = join(themePath, \"templates\");\n let templateAnnotated = false;\n if (fileExists(templatesDir)) {\n for (const file of readdirSync(templatesDir)) {\n if (!file.endsWith(\".html\") || file === \"base.html\" || file.startsWith(\"system\")) continue;\n const content = readFile(join(templatesDir, file));\n if (content.includes(\"dnd_area\") && /templateType\\s*:\\s*page/i.test(content)) {\n templateAnnotated = true;\n break;\n }\n }\n }\n items.push({\n label: \"Template annotations (templateType: page)\",\n passed: templateAnnotated,\n critical: true,\n });\n\n return items;\n}\n\n/**\n * Ensure all templates in templates/ have the required HubSpot annotations.\n * Without `templateType: page` and `isAvailableForNewContent: true`,\n * the template won't appear in HubSpot's template picker.\n */\nexport function validateTemplates(themePath: string): void {\n const templatesDir = join(themePath, \"templates\");\n if (!fileExists(templatesDir)) return;\n\n for (const file of readdirSync(templatesDir)) {\n if (!file.endsWith(\".html\") || file === \"base.html\" || file.startsWith(\"system\")) continue;\n\n const filePath = join(templatesDir, file);\n let content = readFile(filePath);\n\n // Skip files that don't look like page templates\n if (!content.includes(\"dnd_area\") && !content.includes(\"extends\")) continue;\n\n const hasTemplateType = /templateType\\s*:\\s*page/i.test(content);\n const hasAvailable = /isAvailableForNewContent\\s*:\\s*true/i.test(content);\n\n if (hasTemplateType && hasAvailable) continue;\n\n // Build the annotation block\n const label = file.replace(\".html\", \"\").replace(/[-_]/g, \" \").replace(/\\b\\w/g, c => c.toUpperCase());\n\n if (content.includes(\"<!--\") && content.indexOf(\"-->\") < 200) {\n // Has an existing comment block at the top — patch it\n const commentEnd = content.indexOf(\"-->\");\n let annotation = content.slice(0, commentEnd);\n\n if (!hasTemplateType) {\n annotation += \"\\n templateType: page\";\n }\n if (!hasAvailable) {\n annotation += \"\\n isAvailableForNewContent: true\";\n }\n if (!/label\\s*:/i.test(annotation)) {\n annotation += `\\n label: ${label}`;\n }\n\n content = annotation + content.slice(commentEnd);\n } else {\n // No annotation block — prepend one\n const block = `<!--\\n templateType: page\\n isAvailableForNewContent: true\\n label: ${label}\\n-->\\n`;\n content = block + content;\n }\n\n writeFile(filePath, content);\n ui.logSuccess(`Template \"${file}\" — annotations verified`);\n }\n\n}\n\n/**\n * Ensure all module meta.json files have the required fields for\n * landing page compatibility.\n */\nexport function validateModuleMeta(themePath: string): void {\n const modulesDir = join(themePath, \"modules\");\n if (!fileExists(modulesDir)) return;\n\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const metaPath = join(modulesDir, entry, \"meta.json\");\n if (!fileExists(metaPath)) continue;\n\n try {\n const meta = JSON.parse(readFile(metaPath));\n let changed = false;\n\n if (!meta.host_template_types || !meta.host_template_types.includes(\"PAGE\")) {\n meta.host_template_types = [\"PAGE\"];\n changed = true;\n }\n if (!meta.is_available_for_new_content) {\n meta.is_available_for_new_content = true;\n changed = true;\n }\n\n if (changed) {\n writeFile(metaPath, JSON.stringify(meta, null, 2) + \"\\n\");\n }\n } catch {\n // Skip malformed meta.json\n }\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { join, basename } from \"node:path\";\nimport { readdirSync, statSync, writeFileSync } from \"node:fs\";\nimport type { AIEngine, GeneratedAssets, ModuleFiles } from \"./engine.js\";\nimport { getConversionGuide, getHubspotRules } from \"./prompts.js\";\nimport { readFile, fileExists } from \"../utils/fs.js\";\n\n/** Boilerplate modules from `hs create website-theme` — used to distinguish AI-generated modules. */\nconst BOILERPLATE_MODULES = new Set([\n \"button.module\",\n \"card.module\",\n \"menu.module\",\n \"pricing-card.module\",\n \"social-follow.module\",\n]);\n\n/** Boilerplate templates from `hs create website-theme`. */\nconst BOILERPLATE_TEMPLATES = new Set([\n \"about.html\",\n \"blog-index.html\",\n \"blog-post.html\",\n \"contact.html\",\n \"home.html\",\n \"hubdb.html\",\n \"landing-page.html\",\n \"pricing.html\",\n \"qa-test.html\",\n \"base.html\",\n]);\n\nexport class ClaudeCodeEngine implements AIEngine {\n private model?: string;\n private reported = new Set<string>();\n private moduleCount = 0;\n private expectedModules = 0;\n\n constructor(model?: string) {\n this.model = model;\n }\n\n async convert(opts: {\n sourceDir: string;\n themePath: string;\n conversionGuide: string;\n onProgress: (step: string, detail: string) => void;\n }): Promise<GeneratedAssets> {\n const { sourceDir, themePath, onProgress } = opts;\n const guide = opts.conversionGuide || getConversionGuide();\n\n // Reset progress tracking\n this.reported.clear();\n this.moduleCount = 0;\n this.expectedModules = 0;\n\n // Count source components to estimate expected modules\n const sourceComponents = this.countSourceComponents(sourceDir);\n\n // Snapshot existing files so we can detect what Claude actually created\n const existingModules = this.listModules(themePath);\n const existingCss = this.listDir(join(themePath, \"css\"));\n const existingJs = this.listDir(join(themePath, \"js\"));\n const existingTemplates = this.listDir(join(themePath, \"templates\"));\n\n // Build the prompt for Claude Code\n const prompt = this.buildFullPrompt(sourceDir, themePath, guide);\n\n onProgress(\"convert\", `Starting Claude Code (${sourceComponents} source components found)...`);\n\n // Run Claude Code with real-time progress tracking\n let stdout = \"\";\n let stderr = \"\";\n\n // Poll the filesystem every 3s to show progress\n const progressInterval = setInterval(() => {\n this.reportProgress(themePath, existingModules, existingCss, existingJs, existingTemplates, onProgress);\n }, 3000);\n\n try {\n await new Promise<void>((resolve, reject) => {\n // Strip CLAUDECODE env var to allow running from inside a Claude Code session\n const env = { ...process.env };\n delete env.CLAUDECODE;\n\n const args = [\n \"--print\",\n \"--max-turns\", \"50\",\n \"--allowedTools\", \"Read,Glob,Grep,Write,Edit,Bash\",\n ];\n if (this.model) args.push(\"--model\", this.model);\n\n const child = spawn(\"claude\", args, {\n cwd: themePath,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n });\n\n child.stdout.on(\"data\", (d: Buffer) => { stdout += d.toString(); });\n child.stderr.on(\"data\", (d: Buffer) => { stderr += d.toString(); });\n\n child.on(\"error\", (err) => reject(new Error(`Claude Code failed to start: ${err.message}`)));\n child.on(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(\n `Claude Code exited with code ${code}.\\n` +\n (stderr ? `Stderr: ${stderr.slice(0, 500)}\\n` : \"\") +\n (stdout ? `Output: ${stdout.slice(0, 500)}` : \"No output\")\n ));\n } else {\n resolve();\n }\n });\n\n // Handle stdin errors (EPIPE if claude exits before prompt is fully written)\n child.stdin.on(\"error\", () => {});\n\n // Send prompt via stdin and close\n child.stdin.write(prompt);\n child.stdin.end();\n\n // 30 min timeout\n setTimeout(() => {\n child.kill();\n reject(new Error(\"Claude Code timed out after 30 minutes\"));\n }, 1_800_000);\n });\n } finally {\n clearInterval(progressInterval);\n }\n\n // Write full log to workspace for debugging\n const logPath = join(themePath, \"..\", \"vibespot-conversion.log\");\n try {\n const timestamp = new Date().toISOString();\n const logContent = [\n `=== vibeSpot Conversion Log ===`,\n `Timestamp: ${timestamp}`,\n `Source: ${sourceDir}`,\n `Theme: ${themePath}`,\n `Model: ${this.model || \"default\"}`,\n ``,\n `=== PROMPT SENT ===`,\n prompt.slice(0, 500) + \"\\n... (truncated, full guide follows)\",\n ``,\n `=== CLAUDE CODE STDOUT ===`,\n stdout || \"(empty)\",\n ``,\n `=== CLAUDE CODE STDERR ===`,\n stderr || \"(empty)\",\n ``,\n ].join(\"\\n\");\n writeFileSync(logPath, logContent, \"utf-8\");\n onProgress(\"status\", `Log written to ${basename(logPath)}`);\n } catch {\n // Non-critical — don't fail if log can't be written\n }\n\n onProgress(\"scan\", \"Scanning generated files...\");\n\n // Scan the theme directory for what Claude Code created\n const result = this.scanGeneratedFiles(themePath);\n\n // Validate that new files were actually created\n const newModules = result.modules.filter(\n (m) => !existingModules.has(m.moduleName + \".module\")\n );\n\n if (newModules.length === 0) {\n const outputPreview = stdout.slice(0, 1500) || \"(no output)\";\n const stderrPreview = stderr.slice(0, 500);\n throw new Error(\n \"Claude Code did not create any new module files.\\n\\n\" +\n \"This usually means the model described the conversion instead of using Write tool to create files.\\n\\n\" +\n \"Possible causes:\\n\" +\n \" - Model didn't use Write tool (just printed text)\\n\" +\n \" - Claude Code hit a rate limit or API error\\n\" +\n \" - The source directory was not accessible\\n\\n\" +\n `Source: ${opts.sourceDir}\\n` +\n `Theme: ${themePath}\\n` +\n (stderrPreview ? `\\nStderr:\\n${stderrPreview}\\n` : \"\") +\n `\\nClaude output:\\n${outputPreview}`\n );\n }\n\n return result;\n }\n\n /** Poll filesystem and emit \"created\" events for newly detected files. */\n private reportProgress(\n themePath: string,\n existingModules: Set<string>,\n existingCss: Set<string>,\n existingJs: Set<string>,\n existingTemplates: Set<string>,\n onProgress: (step: string, detail: string) => void,\n ): void {\n let newItems = 0;\n\n // Check for new CSS files\n const currentCss = this.listDir(join(themePath, \"css\"));\n for (const f of currentCss) {\n if (existingCss.has(f) || !f.endsWith(\".css\")) continue;\n const key = `css:${f}`;\n if (!this.reported.has(key)) {\n this.reported.add(key);\n onProgress(\"created\", `Shared CSS (${f})`);\n newItems++;\n }\n }\n\n // Check for new JS files\n const currentJs = this.listDir(join(themePath, \"js\"));\n for (const f of currentJs) {\n if (existingJs.has(f) || !f.endsWith(\".js\")) continue;\n const key = `js:${f}`;\n if (!this.reported.has(key)) {\n this.reported.add(key);\n onProgress(\"created\", `Shared JS (${f})`);\n newItems++;\n }\n }\n\n // Try to detect expected module count from template file (once it exists)\n if (this.expectedModules === 0) {\n this.expectedModules = this.detectExpectedModules(themePath, existingTemplates);\n }\n\n // Check for new modules\n const currentModules = this.listModules(themePath);\n for (const mod of currentModules) {\n if (existingModules.has(mod)) continue;\n const key = `module:${mod}`;\n if (!this.reported.has(key)) {\n this.reported.add(key);\n this.moduleCount++;\n const counter = this.expectedModules > 0\n ? `[${this.moduleCount}/${this.expectedModules}]`\n : `[${this.moduleCount}]`;\n onProgress(\"created\", `Module ${counter}: ${mod.replace(\".module\", \"\")}`);\n newItems++;\n }\n }\n\n // Check for new templates\n const currentTemplates = this.listDir(join(themePath, \"templates\"));\n for (const f of currentTemplates) {\n if (existingTemplates.has(f) || !f.endsWith(\".html\")) continue;\n const key = `template:${f}`;\n if (!this.reported.has(key)) {\n this.reported.add(key);\n onProgress(\"created\", `Page template (${f})`);\n newItems++;\n }\n }\n\n // Update spinner status text (only if no new items were just logged)\n if (newItems === 0) {\n if (this.moduleCount > 0) {\n const of = this.expectedModules > 0 ? `/${this.expectedModules}` : \"\";\n onProgress(\"status\", `${this.moduleCount}${of} modules created, conversion continuing...`);\n } else if (this.reported.size > 0) {\n onProgress(\"status\", \"Shared assets created, building modules...\");\n } else {\n onProgress(\"status\", \"Claude Code is analyzing source files...\");\n }\n }\n }\n\n private buildFullPrompt(\n sourceDir: string,\n themePath: string,\n guide: string\n ): string {\n return `You are converting a React landing page to native HubSpot CMS modules.\n\nSOURCE DIRECTORY: ${sourceDir}\nTHEME DIRECTORY: ${themePath}\n\nIMPORTANT — YOU MUST CREATE REAL FILES:\nYou have access to Write, Edit, Read, Glob, Grep, and Bash tools. You MUST use the Write tool to create each file. Do NOT just describe or list what files should be created — actually call the Write tool for every single file. If you do not call Write, no files will be created and the conversion will fail.\n\nSTEP-BY-STEP PROCESS:\n1. Use Glob to find all .tsx/.jsx files in ${sourceDir}/src/\n2. Use Read to read each component file and understand the page structure\n3. Use Write to create a shared CSS file at ${themePath}/css/<name>-theme.css\n - Include CSS custom properties, design system variables, utility classes\n - Add theme-override countermeasures (.body-wrapper:has(), scoped !important overrides)\n4. Use Write to create a shared JS file at ${themePath}/js/<name>-animations.js\n - Convert React hooks to vanilla JS (IntersectionObserver for scroll animations)\n - IIFE wrapper, DOMContentLoaded setup\n5. For EACH visual section of the page, use Write to create ALL FOUR files:\n a. ${themePath}/modules/<name>.module/fields.json\n - Editable fields for the section content\n - NEVER use \"textarea\" type (use \"text\" instead)\n - NEVER use \"name\" as a field name (use \"item_name\" instead)\n - Add a \"styles\" group with \"tab\": \"STYLE\" containing color pickers\n b. ${themePath}/modules/<name>.module/meta.json\n - Must include: host_template_types: [\"PAGE\"], is_available_for_new_content: true\n c. ${themePath}/modules/<name>.module/module.html\n - HubL template that renders the section (convert JSX to HubL)\n d. ${themePath}/modules/<name>.module/module.css\n - REQUIRED — complete vanilla CSS for this section\n - Must include: layout, spacing, colors, typography, backgrounds, gradients, shadows, borders, hover effects, responsive breakpoints\n - Convert ALL Tailwind classes to BEM-style CSS. Do NOT skip this file.\n6. Use Write to create a page template at ${themePath}/templates/lp-<name>.html\n - Annotation: templateType: page, isAvailableForNewContent: true\n - Extends \"./layouts/base.html\"\n - Sets template_css and template_js variables\n - Wraps modules in dnd_area with dnd_section containers\n7. Read ${themePath}/templates/layouts/base.html and ensure it supports template_css and template_js variables\n\nCSS QUALITY: The converted page must visually match the original React page. Every module.css must be self-contained with complete styling for that section.\n\nDo NOT run hs upload — I will handle that separately.\n\nHUBSPOT CMS RULES:\n${getHubspotRules()}\n\nCONVERSION GUIDE:\n${guide}`;\n }\n\n private scanGeneratedFiles(themePath: string): GeneratedAssets {\n const result: GeneratedAssets = {\n sharedCss: \"\",\n sharedJs: \"\",\n template: \"\",\n modules: [],\n };\n\n // Find shared CSS (any non-boilerplate CSS in css/)\n const cssDir = join(themePath, \"css\");\n if (fileExists(cssDir)) {\n for (const file of readdirSync(cssDir)) {\n if (\n file.endsWith(\".css\") &&\n file !== \"theme-overrides.css\" &&\n file !== \"main.css\" &&\n file !== \"style.css\"\n ) {\n result.sharedCss = readFile(join(cssDir, file));\n break;\n }\n }\n }\n\n // Find shared JS (any non-boilerplate JS in js/)\n const jsDir = join(themePath, \"js\");\n if (fileExists(jsDir)) {\n for (const file of readdirSync(jsDir)) {\n if (\n file.endsWith(\".js\") &&\n file !== \"main.js\"\n ) {\n result.sharedJs = readFile(join(jsDir, file));\n break;\n }\n }\n }\n\n // Find new template (prefer lp-* or non-boilerplate templates)\n const templatesDir = join(themePath, \"templates\");\n if (fileExists(templatesDir)) {\n // First pass: look for lp-* templates (AI-generated naming convention)\n for (const file of readdirSync(templatesDir)) {\n if (file.startsWith(\"lp-\") && file.endsWith(\".html\")) {\n result.template = readFile(join(templatesDir, file));\n break;\n }\n }\n // Second pass: any non-boilerplate template with dnd_area\n if (!result.template) {\n for (const file of readdirSync(templatesDir)) {\n if (\n file.endsWith(\".html\") &&\n !BOILERPLATE_TEMPLATES.has(file) &&\n !file.startsWith(\"system\")\n ) {\n const content = readFile(join(templatesDir, file));\n if (content.includes(\"dnd_area\")) {\n result.template = content;\n break;\n }\n }\n }\n }\n // Third pass: fall back to any template with dnd_area\n if (!result.template) {\n for (const file of readdirSync(templatesDir)) {\n if (\n file.endsWith(\".html\") &&\n !file.startsWith(\"system\") &&\n file !== \"base.html\"\n ) {\n const content = readFile(join(templatesDir, file));\n if (content.includes(\"dnd_area\")) {\n result.template = content;\n break;\n }\n }\n }\n }\n }\n\n // Scan modules/\n const modulesDir = join(themePath, \"modules\");\n if (fileExists(modulesDir)) {\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const modDir = join(modulesDir, entry);\n if (!statSync(modDir).isDirectory()) continue;\n\n const moduleFiles: ModuleFiles = {\n moduleName: entry.replace(\".module\", \"\"),\n fieldsJson: \"\",\n metaJson: \"\",\n moduleHtml: \"\",\n moduleCss: \"\",\n };\n\n const fj = join(modDir, \"fields.json\");\n if (fileExists(fj)) moduleFiles.fieldsJson = readFile(fj);\n\n const mj = join(modDir, \"meta.json\");\n if (fileExists(mj)) moduleFiles.metaJson = readFile(mj);\n\n const mh = join(modDir, \"module.html\");\n if (fileExists(mh)) moduleFiles.moduleHtml = readFile(mh);\n\n const mc = join(modDir, \"module.css\");\n if (fileExists(mc)) moduleFiles.moduleCss = readFile(mc);\n\n const mjs = join(modDir, \"module.js\");\n if (fileExists(mjs)) moduleFiles.moduleJs = readFile(mjs);\n\n // Only count modules that have at least fields.json and module.html\n if (moduleFiles.fieldsJson && moduleFiles.moduleHtml) {\n result.modules.push(moduleFiles);\n }\n }\n }\n\n return result;\n }\n\n /** List module directories in modules/ */\n private listModules(themePath: string): Set<string> {\n const modulesDir = join(themePath, \"modules\");\n if (!fileExists(modulesDir)) return new Set();\n return new Set(\n readdirSync(modulesDir).filter((e) => e.endsWith(\".module\"))\n );\n }\n\n /** List files in a directory */\n private listDir(dir: string): Set<string> {\n if (!fileExists(dir)) return new Set();\n return new Set(readdirSync(dir));\n }\n\n /** Detect expected module count from template file (counts dnd_module references) */\n private detectExpectedModules(themePath: string, existingTemplates: Set<string>): number {\n const templatesDir = join(themePath, \"templates\");\n if (!fileExists(templatesDir)) return 0;\n\n for (const file of readdirSync(templatesDir)) {\n if (existingTemplates.has(file)) continue;\n if (!file.endsWith(\".html\") || file === \"base.html\" || file.startsWith(\"system\")) continue;\n\n try {\n const content = readFile(join(templatesDir, file));\n if (content.includes(\"dnd_area\")) {\n const matches = content.match(/dnd_module/g);\n return matches ? matches.length : 0;\n }\n } catch {\n // Skip unreadable files\n }\n }\n return 0;\n }\n\n /** Count .tsx/.jsx component files in the source directory */\n private countSourceComponents(sourceDir: string): number {\n const srcDir = join(sourceDir, \"src\");\n if (!fileExists(srcDir)) return 0;\n return this.countComponentsRecursive(srcDir);\n }\n\n private countComponentsRecursive(dir: string): number {\n let count = 0;\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry);\n try {\n const stat = statSync(fullPath);\n if (stat.isDirectory() && entry !== \"node_modules\" && entry !== \".git\") {\n count += this.countComponentsRecursive(fullPath);\n } else if (/\\.(tsx|jsx)$/.test(entry) && !entry.includes(\".test.\") && !entry.includes(\".spec.\")) {\n count++;\n }\n } catch {\n // Skip unreadable entries\n }\n }\n return count;\n }\n}\n","import { readFile, resolveAsset } from \"../utils/fs.js\";\n\nexport function getConversionGuide(): string {\n try {\n return readFile(resolveAsset(\"conversion-guide.md\"));\n } catch {\n return \"Conversion guide not found. Using built-in rules.\";\n }\n}\n\nexport function getDesignGuide(): string {\n try {\n return readFile(resolveAsset(\"design-guide.md\"));\n } catch {\n return \"\";\n }\n}\n\nexport function getContentGuide(): string {\n try {\n return readFile(resolveAsset(\"content-guide.md\"));\n } catch {\n return \"\";\n }\n}\n\nexport function getHubspotRules(): string {\n try {\n return readFile(resolveAsset(\"hubspot-rules.md\"));\n } catch {\n return \"\";\n }\n}\n\n/**\n * Extract page-type-specific section from page-types.md.\n * Returns only the relevant section for the given page type.\n */\nexport function getPageTypeGuide(pageType: string): string {\n try {\n const fullGuide = readFile(resolveAsset(\"page-types.md\"));\n\n // Map page type to section header\n const sectionHeaders: Record<string, string> = {\n landing_page: \"## Landing Page\",\n blog_post: \"## Blog Post\",\n website_page: \"## Website Page\",\n module_only: \"## Module Only\",\n };\n\n const header = sectionHeaders[pageType];\n if (!header) return \"\";\n\n const startIdx = fullGuide.indexOf(header);\n if (startIdx < 0) return \"\";\n\n // Find the next section (## at start of line) after this one\n const afterHeader = fullGuide.indexOf(\"\\n## \", startIdx + header.length);\n const section = afterHeader >= 0\n ? fullGuide.slice(startIdx, afterHeader).trim()\n : fullGuide.slice(startIdx).trim();\n\n return section;\n } catch {\n return \"\";\n }\n}\n\nexport function buildSystemPrompt(conversionGuide: string): string {\n return `You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.\n\n## Rules\nFollow the conversion guide below EXACTLY. Key rules:\n- Use \"type\": \"text\" (NEVER \"textarea\")\n- NEVER use \"name\": \"name\" (it's reserved) — use alternatives like \"item_name\"\n- Wrap style fields in a \"styles\" group with \"tab\": \"STYLE\" on the group\n- All CSS classes must use a unique prefix to avoid theme conflicts\n- Every dnd_section needs padding={\"top\":\"0\",\"bottom\":\"0\",\"left\":\"0\",\"right\":\"0\"}, full_width=true\n- Use template_css and template_js variables (resolved in base.html, not child templates)\n- Add .body-wrapper:has(.my-page) CSS fix + JS fallback for body background\n- Add scoped overrides with !important for headings, paragraphs, links to defeat theme-overrides.css\n- Use IntersectionObserver for scroll animations (add .visible class)\n- Convert Tailwind utilities to vanilla CSS with BEM naming\n- Convert React hooks to vanilla JS (no React, no npm packages)\n\n## HubSpot CMS Rules\n${getHubspotRules()}\n\n## Conversion Guide\n${conversionGuide}`;\n}\n\nexport function buildAnalyzePrompt(componentList: string): string {\n return `Analyze these React components and create a module map.\n\nFor each component, return a JSON object with:\n- name: HubSpot module name (e.g., \"My Hero\")\n- description: Brief description of the section\n- hasRepeaters: true if it contains .map() or array iteration\n- hasInteractivity: true if it has JS-driven behavior (carousel, accordion, etc.)\n\nComponents:\n${componentList}\n\nReturn ONLY valid JSON array, no markdown fences.`;\n}\n\nexport function buildModulePrompt(\n componentSource: string,\n moduleName: string,\n cssVars: string\n): string {\n return `Convert this React component to a HubSpot module named \"${moduleName}\".\n\nReturn a JSON object with these keys:\n- fieldsJson: complete fields.json content (as JSON string)\n- metaJson: complete meta.json content (as JSON string)\n- moduleHtml: complete module.html content (HubL template)\n- moduleCss: complete module.css content (vanilla CSS)\n- moduleJs: module.js content if interactive behavior needed, or null\n\nDesign system CSS variables available:\n${cssVars}\n\nReact component source:\n${componentSource}\n\nReturn ONLY valid JSON, no markdown fences.`;\n}\n\nexport function buildCssPrompt(\n indexCss: string,\n tailwindConfig: string,\n pagePrefix: string\n): string {\n return `Create a shared CSS file for a HubSpot CMS landing page.\n\nExtract the design system from the source CSS and Tailwind config below.\nUse the class prefix \".${pagePrefix}-\" for all custom classes.\n\nRequirements:\n- CSS custom properties for all colors, spacing\n- Page wrapper styles (.${pagePrefix}-page) with !important font/color\n- .body-wrapper:has(.${pagePrefix}-page) background fix\n- .body-wrapper.${pagePrefix}-page-active JS fallback\n- Scoped overrides: .${pagePrefix}-page h1-h6, p, a with !important\n- .dnd-section padding: 0 !important and .row-fluid max-width: 100%\n- Form overrides for dark themes\n- Utility classes (container, section, grid, glass)\n- Scroll animation classes (.${pagePrefix}-scroll-animate / .visible)\n- Mobile breakpoint at 767px\n- Responsive grid fallbacks\n\nSource CSS:\n${indexCss}\n\nTailwind config:\n${tailwindConfig}\n\nReturn ONLY the CSS content, no markdown fences.`;\n}\n\nexport function buildJsPrompt(\n hooksSource: string,\n interactiveComponents: string,\n pagePrefix: string\n): string {\n return `Create a shared vanilla JS file for a HubSpot CMS landing page.\n\nConvert the React hooks and interactive components below to plain JavaScript.\nUse the class prefix \"${pagePrefix}-\" to match the CSS.\n\nRequirements:\n- IIFE wrapper with \"use strict\"\n- initBodyWrapper: add \"${pagePrefix}-page-active\" class to .body-wrapper\n- initScrollAnimations: IntersectionObserver for .${pagePrefix}-scroll-animate → .visible\n- Convert any carousels, accordions, typing animations to vanilla JS\n- DOMContentLoaded / readyState check\n\nReact hooks source:\n${hooksSource}\n\nInteractive component sources:\n${interactiveComponents}\n\nReturn ONLY the JavaScript content, no markdown fences.`;\n}\n\nexport function buildTemplatePrompt(\n moduleNames: string[],\n themeName: string,\n pagePrefix: string\n): string {\n return `Create a HubSpot page template that assembles these modules:\n\n${moduleNames.map((n, i) => `${i + 1}. ${n}.module`).join(\"\\n\")}\n\nTemplate requirements:\n- templateType: page, isAvailableForNewContent: true\n- extends \"./layouts/base.html\"\n- set template_css = \"../../css/${pagePrefix}-theme.css\"\n- set template_js = \"../../js/${pagePrefix}-animations.js\"\n- Empty header and footer blocks (modules handle them)\n- Wrap content in <div class=\"${pagePrefix}-page\">\n- Each module in its own dnd_section with padding zeroed and full_width=true\n- dnd_area label: \"${themeName} Landing Page\"\n\nReturn ONLY the template HTML content, no markdown fences.`;\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport { join } from \"node:path\";\nimport { readdirSync } from \"node:fs\";\nimport type { AIEngine, GeneratedAssets, ModuleFiles } from \"./engine.js\";\nimport {\n buildSystemPrompt,\n buildCssPrompt,\n buildJsPrompt,\n buildModulePrompt,\n buildTemplatePrompt,\n} from \"./prompts.js\";\nimport { readFile, fileExists, writeFile, ensureDir } from \"../utils/fs.js\";\n\nexport class ClaudeAPIEngine implements AIEngine {\n private client: Anthropic;\n private model = \"claude-sonnet-4-20250514\";\n\n constructor(apiKey?: string) {\n this.client = new Anthropic({\n apiKey: apiKey || process.env.ANTHROPIC_API_KEY,\n });\n }\n\n async convert(opts: {\n sourceDir: string;\n themePath: string;\n conversionGuide: string;\n onProgress: (step: string, detail: string) => void;\n }): Promise<GeneratedAssets> {\n const { sourceDir, themePath, conversionGuide, onProgress } = opts;\n const systemPrompt = buildSystemPrompt(conversionGuide);\n\n // Determine a page prefix from the source dir name\n const dirName = sourceDir.split(\"/\").pop() || \"page\";\n const pagePrefix = dirName\n .toLowerCase()\n .replace(/[^a-z0-9]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 15);\n\n // Step 1: Generate shared CSS\n onProgress(\"css\", \"Analyzing design system...\");\n const indexCss = this.findAndReadCSS(sourceDir);\n const tailwindConfig = this.findAndReadTailwind(sourceDir);\n\n const cssContent = await this.complete(\n systemPrompt,\n buildCssPrompt(indexCss, tailwindConfig, pagePrefix)\n );\n const cssPath = join(themePath, \"css\", `${pagePrefix}-theme.css`);\n writeFile(cssPath, cssContent);\n onProgress(\"css-done\", `Created css/${pagePrefix}-theme.css`);\n\n // Step 2: Generate shared JS\n onProgress(\"js\", \"Creating shared JavaScript...\");\n const hooksSource = this.findAndReadHooks(sourceDir);\n const interactiveSource = this.findInteractiveComponents(sourceDir);\n\n const jsContent = await this.complete(\n systemPrompt,\n buildJsPrompt(hooksSource, interactiveSource, pagePrefix)\n );\n const jsPath = join(themePath, \"js\", `${pagePrefix}-animations.js`);\n writeFile(jsPath, jsContent);\n onProgress(\"js-done\", `Created js/${pagePrefix}-animations.js`);\n\n // Step 3: Generate modules\n onProgress(\"modules\", \"Building modules...\");\n const components = this.findComponents(sourceDir);\n const modules: ModuleFiles[] = [];\n\n for (let i = 0; i < components.length; i++) {\n const comp = components[i];\n const moduleName = comp.name\n .replace(/Section$/, \"\")\n .replace(/([A-Z])/g, \" $1\")\n .trim();\n\n onProgress(\n \"module\",\n `Building ${moduleName}.module (${i + 1}/${components.length})...`\n );\n\n const source = readFile(comp.path);\n const response = await this.complete(\n systemPrompt,\n buildModulePrompt(source, moduleName, `See css/${pagePrefix}-theme.css`)\n );\n\n try {\n const parsed = JSON.parse(response);\n const mod: ModuleFiles = {\n moduleName,\n fieldsJson: typeof parsed.fieldsJson === \"string\"\n ? parsed.fieldsJson\n : JSON.stringify(parsed.fieldsJson, null, 2),\n metaJson: typeof parsed.metaJson === \"string\"\n ? parsed.metaJson\n : JSON.stringify(parsed.metaJson, null, 2),\n moduleHtml: parsed.moduleHtml || \"\",\n moduleCss: parsed.moduleCss || \"\",\n moduleJs: parsed.moduleJs || undefined,\n };\n\n // Write module files\n const modDir = join(themePath, \"modules\", `${moduleName}.module`);\n ensureDir(modDir);\n writeFile(join(modDir, \"fields.json\"), mod.fieldsJson);\n writeFile(join(modDir, \"meta.json\"), mod.metaJson);\n writeFile(join(modDir, \"module.html\"), mod.moduleHtml);\n writeFile(join(modDir, \"module.css\"), mod.moduleCss);\n if (mod.moduleJs) writeFile(join(modDir, \"module.js\"), mod.moduleJs);\n\n modules.push(mod);\n onProgress(\"module-done\", `${moduleName}.module (${this.countFiles(mod)} files)`);\n } catch {\n onProgress(\"module-error\", `Failed to parse ${moduleName} — skipping`);\n }\n }\n\n // Step 4: Generate template\n onProgress(\"template\", \"Creating page template...\");\n const moduleNames = modules.map((m) => m.moduleName);\n const templateContent = await this.complete(\n systemPrompt,\n buildTemplatePrompt(moduleNames, dirName, pagePrefix)\n );\n\n const templatePath = join(\n themePath,\n \"templates\",\n `lp-${pagePrefix}.html`\n );\n writeFile(templatePath, templateContent);\n onProgress(\"template-done\", `Created templates/lp-${pagePrefix}.html`);\n\n return {\n sharedCss: cssContent,\n sharedJs: jsContent,\n template: templateContent,\n modules,\n };\n }\n\n private async complete(system: string, user: string): Promise<string> {\n const response = await this.client.messages.create({\n model: this.model,\n max_tokens: 8192,\n system,\n messages: [{ role: \"user\", content: user }],\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n return textBlock?.text || \"\";\n }\n\n private findAndReadCSS(dir: string): string {\n const paths = [\n join(dir, \"src/index.css\"),\n join(dir, \"src/globals.css\"),\n join(dir, \"src/app/globals.css\"),\n join(dir, \"app/globals.css\"),\n ];\n for (const p of paths) {\n if (fileExists(p)) return readFile(p);\n }\n return \"\";\n }\n\n private findAndReadTailwind(dir: string): string {\n const paths = [\n join(dir, \"tailwind.config.ts\"),\n join(dir, \"tailwind.config.js\"),\n join(dir, \"tailwind.config.mjs\"),\n ];\n for (const p of paths) {\n if (fileExists(p)) return readFile(p);\n }\n return \"\";\n }\n\n private findAndReadHooks(dir: string): string {\n const hooksDir = join(dir, \"src/hooks\");\n if (!fileExists(hooksDir)) return \"\";\n try {\n return readdirSync(hooksDir)\n .filter((f) => f.endsWith(\".ts\") || f.endsWith(\".tsx\"))\n .map((f) => `// ${f}\\n${readFile(join(hooksDir, f))}`)\n .join(\"\\n\\n\");\n } catch {\n return \"\";\n }\n }\n\n private findInteractiveComponents(dir: string): string {\n const components = this.findComponents(dir);\n const interactive: string[] = [];\n\n for (const comp of components) {\n const content = readFile(comp.path);\n if (\n /carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(\n content\n )\n ) {\n interactive.push(`// ${comp.name}\\n${content}`);\n }\n }\n\n return interactive.join(\"\\n\\n\");\n }\n\n private findComponents(dir: string): { name: string; path: string }[] {\n const searchDirs = [\n join(dir, \"src/components/landing\"),\n join(dir, \"src/components/sections\"),\n join(dir, \"src/components\"),\n ];\n\n for (const searchDir of searchDirs) {\n if (!fileExists(searchDir)) continue;\n try {\n return readdirSync(searchDir)\n .filter(\n (f) =>\n (f.endsWith(\".tsx\") || f.endsWith(\".jsx\")) &&\n !f.startsWith(\"ui\") &&\n f !== \"index.tsx\" &&\n f !== \"index.jsx\"\n )\n .map((f) => ({\n name: f.replace(/\\.(tsx|jsx)$/, \"\"),\n path: join(searchDir, f),\n }));\n } catch {\n continue;\n }\n }\n\n return [];\n }\n\n private countFiles(mod: ModuleFiles): number {\n let count = 3; // fields.json, meta.json, module.html always present\n if (mod.moduleCss) count++;\n if (mod.moduleJs) count++;\n return count;\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { readdirSync, statSync } from \"node:fs\";\nimport type { AIEngine, GeneratedAssets, ModuleFiles } from \"./engine.js\";\nimport { getConversionGuide } from \"./prompts.js\";\nimport { readFile, fileExists } from \"../utils/fs.js\";\n\nexport class GeminiCLIEngine implements AIEngine {\n async convert(opts: {\n sourceDir: string;\n themePath: string;\n conversionGuide: string;\n onProgress: (step: string, detail: string) => void;\n }): Promise<GeneratedAssets> {\n const { sourceDir, themePath, onProgress } = opts;\n const guide = opts.conversionGuide || getConversionGuide();\n\n const prompt = this.buildFullPrompt(sourceDir, themePath, guide);\n\n onProgress(\"convert\", \"Running Gemini CLI (this may take a few minutes)...\");\n\n // Use async spawn so the event loop stays free for spinner animation\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"gemini\", [\"-p\", prompt], {\n cwd: themePath,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (d: Buffer) => { stdout += d.toString(); });\n child.stderr.on(\"data\", (d: Buffer) => { stderr += d.toString(); });\n\n child.on(\"error\", (err) => reject(new Error(`Gemini CLI failed: ${err.message}`)));\n child.on(\"close\", (code) => {\n if (code !== 0 && stderr && !stdout) {\n reject(new Error(`Gemini CLI failed: ${stderr}`));\n } else {\n resolve();\n }\n });\n\n setTimeout(() => {\n child.kill();\n reject(new Error(\"Gemini CLI timed out after 10 minutes\"));\n }, 600_000);\n });\n\n onProgress(\"scan\", \"Scanning generated files...\");\n\n return this.scanGeneratedFiles(themePath);\n }\n\n private buildFullPrompt(\n sourceDir: string,\n themePath: string,\n guide: string\n ): string {\n return `Read the conversion guide below, then convert the React landing page at ${sourceDir} into native HubSpot CMS modules for the theme at ${themePath}.\n\nINSTRUCTIONS:\n1. Analyze all .tsx/.jsx components in the React source\n2. Create a shared CSS file in css/ with design system variables, utilities, and theme-override countermeasures\n3. Create a shared JS file in js/ for scroll animations and interactive features\n4. For each visual section, create a HubSpot module in modules/ with fields.json, meta.json, module.html, module.css\n5. Add a styles group with \"tab\": \"STYLE\" and color pickers to each module\n6. Create a page template in templates/ that assembles all modules\n7. Make sure base.html supports template_css and template_js variables\n\nCONVERSION GUIDE:\n${guide}\n\nDo NOT run hs upload — I will handle that separately.\nCreate all files directly in the theme directory.`;\n }\n\n private scanGeneratedFiles(themePath: string): GeneratedAssets {\n const result: GeneratedAssets = {\n sharedCss: \"\",\n sharedJs: \"\",\n template: \"\",\n modules: [],\n };\n\n const cssDir = join(themePath, \"css\");\n if (fileExists(cssDir)) {\n for (const file of readdirSync(cssDir)) {\n if (\n (file.includes(\"theme\") || file.includes(\"page\")) &&\n file.endsWith(\".css\") &&\n file !== \"theme-overrides.css\" &&\n file !== \"main.css\" &&\n file !== \"style.css\"\n ) {\n result.sharedCss = readFile(join(cssDir, file));\n break;\n }\n }\n }\n\n const jsDir = join(themePath, \"js\");\n if (fileExists(jsDir)) {\n for (const file of readdirSync(jsDir)) {\n if (\n (file.includes(\"animation\") || file.includes(\"page\")) &&\n file.endsWith(\".js\") &&\n file !== \"main.js\"\n ) {\n result.sharedJs = readFile(join(jsDir, file));\n break;\n }\n }\n }\n\n const templatesDir = join(themePath, \"templates\");\n if (fileExists(templatesDir)) {\n for (const file of readdirSync(templatesDir)) {\n if (\n file.endsWith(\".html\") &&\n !file.startsWith(\"system\") &&\n file !== \"base.html\"\n ) {\n const content = readFile(join(templatesDir, file));\n if (content.includes(\"dnd_area\")) {\n result.template = content;\n break;\n }\n }\n }\n }\n\n const modulesDir = join(themePath, \"modules\");\n if (fileExists(modulesDir)) {\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const modDir = join(modulesDir, entry);\n if (!statSync(modDir).isDirectory()) continue;\n\n const moduleFiles: ModuleFiles = {\n moduleName: entry.replace(\".module\", \"\"),\n fieldsJson: \"\",\n metaJson: \"\",\n moduleHtml: \"\",\n moduleCss: \"\",\n };\n\n const fj = join(modDir, \"fields.json\");\n if (fileExists(fj)) moduleFiles.fieldsJson = readFile(fj);\n\n const mj = join(modDir, \"meta.json\");\n if (fileExists(mj)) moduleFiles.metaJson = readFile(mj);\n\n const mh = join(modDir, \"module.html\");\n if (fileExists(mh)) moduleFiles.moduleHtml = readFile(mh);\n\n const mc = join(modDir, \"module.css\");\n if (fileExists(mc)) moduleFiles.moduleCss = readFile(mc);\n\n const mjs = join(modDir, \"module.js\");\n if (fileExists(mjs)) moduleFiles.moduleJs = readFile(mjs);\n\n if (moduleFiles.fieldsJson && moduleFiles.moduleHtml) {\n result.modules.push(moduleFiles);\n }\n }\n }\n\n return result;\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { readdirSync, statSync } from \"node:fs\";\nimport type { AIEngine, GeneratedAssets, ModuleFiles } from \"./engine.js\";\nimport { getConversionGuide } from \"./prompts.js\";\nimport { readFile, fileExists } from \"../utils/fs.js\";\n\nexport class CodexCLIEngine implements AIEngine {\n async convert(opts: {\n sourceDir: string;\n themePath: string;\n conversionGuide: string;\n onProgress: (step: string, detail: string) => void;\n }): Promise<GeneratedAssets> {\n const { sourceDir, themePath, onProgress } = opts;\n const guide = opts.conversionGuide || getConversionGuide();\n\n const prompt = this.buildFullPrompt(sourceDir, themePath, guide);\n\n onProgress(\"convert\", \"Running OpenAI Codex (this may take a few minutes)...\");\n\n // Use async spawn so the event loop stays free for spinner animation\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"codex\", [\"exec\", \"--full-auto\", prompt], {\n cwd: themePath,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (d: Buffer) => { stdout += d.toString(); });\n child.stderr.on(\"data\", (d: Buffer) => { stderr += d.toString(); });\n\n child.on(\"error\", (err) => reject(new Error(`Codex CLI failed: ${err.message}`)));\n child.on(\"close\", (code) => {\n if (code !== 0 && stderr && !stdout) {\n reject(new Error(`Codex CLI failed: ${stderr}`));\n } else {\n resolve();\n }\n });\n\n setTimeout(() => {\n child.kill();\n reject(new Error(\"Codex CLI timed out after 10 minutes\"));\n }, 600_000);\n });\n\n onProgress(\"scan\", \"Scanning generated files...\");\n\n return this.scanGeneratedFiles(themePath);\n }\n\n private buildFullPrompt(\n sourceDir: string,\n themePath: string,\n guide: string\n ): string {\n return `Read the conversion guide below, then convert the React landing page at ${sourceDir} into native HubSpot CMS modules for the theme at ${themePath}.\n\nINSTRUCTIONS:\n1. Analyze all .tsx/.jsx components in the React source\n2. Create a shared CSS file in css/ with design system variables, utilities, and theme-override countermeasures\n3. Create a shared JS file in js/ for scroll animations and interactive features\n4. For each visual section, create a HubSpot module in modules/ with fields.json, meta.json, module.html, module.css\n5. Add a styles group with \"tab\": \"STYLE\" and color pickers to each module\n6. Create a page template in templates/ that assembles all modules\n7. Make sure base.html supports template_css and template_js variables\n\nCONVERSION GUIDE:\n${guide}\n\nDo NOT run hs upload — I will handle that separately.\nCreate all files directly in the theme directory.`;\n }\n\n private scanGeneratedFiles(themePath: string): GeneratedAssets {\n const result: GeneratedAssets = {\n sharedCss: \"\",\n sharedJs: \"\",\n template: \"\",\n modules: [],\n };\n\n const cssDir = join(themePath, \"css\");\n if (fileExists(cssDir)) {\n for (const file of readdirSync(cssDir)) {\n if (\n (file.includes(\"theme\") || file.includes(\"page\")) &&\n file.endsWith(\".css\") &&\n file !== \"theme-overrides.css\" &&\n file !== \"main.css\" &&\n file !== \"style.css\"\n ) {\n result.sharedCss = readFile(join(cssDir, file));\n break;\n }\n }\n }\n\n const jsDir = join(themePath, \"js\");\n if (fileExists(jsDir)) {\n for (const file of readdirSync(jsDir)) {\n if (\n (file.includes(\"animation\") || file.includes(\"page\")) &&\n file.endsWith(\".js\") &&\n file !== \"main.js\"\n ) {\n result.sharedJs = readFile(join(jsDir, file));\n break;\n }\n }\n }\n\n const templatesDir = join(themePath, \"templates\");\n if (fileExists(templatesDir)) {\n for (const file of readdirSync(templatesDir)) {\n if (\n file.endsWith(\".html\") &&\n !file.startsWith(\"system\") &&\n file !== \"base.html\"\n ) {\n const content = readFile(join(templatesDir, file));\n if (content.includes(\"dnd_area\")) {\n result.template = content;\n break;\n }\n }\n }\n }\n\n const modulesDir = join(themePath, \"modules\");\n if (fileExists(modulesDir)) {\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const modDir = join(modulesDir, entry);\n if (!statSync(modDir).isDirectory()) continue;\n\n const moduleFiles: ModuleFiles = {\n moduleName: entry.replace(\".module\", \"\"),\n fieldsJson: \"\",\n metaJson: \"\",\n moduleHtml: \"\",\n moduleCss: \"\",\n };\n\n const fj = join(modDir, \"fields.json\");\n if (fileExists(fj)) moduleFiles.fieldsJson = readFile(fj);\n\n const mj = join(modDir, \"meta.json\");\n if (fileExists(mj)) moduleFiles.metaJson = readFile(mj);\n\n const mh = join(modDir, \"module.html\");\n if (fileExists(mh)) moduleFiles.moduleHtml = readFile(mh);\n\n const mc = join(modDir, \"module.css\");\n if (fileExists(mc)) moduleFiles.moduleCss = readFile(mc);\n\n const mjs = join(modDir, \"module.js\");\n if (fileExists(mjs)) moduleFiles.moduleJs = readFile(mjs);\n\n if (moduleFiles.fieldsJson && moduleFiles.moduleHtml) {\n result.modules.push(moduleFiles);\n }\n }\n }\n\n return result;\n }\n}\n","import { join } from \"node:path\";\nimport { run } from \"../utils/shell.js\";\nimport * as ui from \"../prompts/prompter.js\";\nimport { theme } from \"../cli/theme.js\";\nimport {\n parseUploadErrors,\n autoFixError,\n type UploadError,\n} from \"../server/auto-fix.js\";\n\n/** Count \"Uploaded file\" lines in hs cms upload output */\nfunction countUploadedFiles(output: string): number {\n return (output.match(/^Uploaded file /gm) || []).length;\n}\n\nexport async function runUpload(themePath: string): Promise<boolean> {\n await ui.intro(\"Uploading to HubSpot\");\n\n const themeName = themePath.split(\"/\").pop() || themePath;\n const s = await ui.spinner();\n\n const MAX_RETRIES = 3;\n\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n s.start(\n attempt === 1\n ? \"Uploading theme...\"\n : `Retrying upload (attempt ${attempt}/${MAX_RETRIES})...`\n );\n\n const result = run(`hs cms upload \"${themePath}\" \"${themeName}\"`, {\n cwd: join(themePath, \"..\"),\n });\n\n // Combine stdout + stderr — hs cms upload logs success lines and errors to both\n const fullOutput = [result.stdout, result.stderr].filter(Boolean).join(\"\\n\");\n const uploadedCount = countUploadedFiles(fullOutput);\n\n if (result.success) {\n s.stop(`All files uploaded! (${uploadedCount} files)`);\n await ui.outro(\"Upload complete!\");\n return true;\n }\n\n // Parse errors from combined output\n const errors = parseUploadErrors(fullOutput);\n\n // If files were uploaded despite errors, tell the user\n if (uploadedCount > 0) {\n s.stop(`${uploadedCount} files uploaded, but some errors occurred`);\n } else {\n s.stop(\"Upload failed\");\n }\n\n if (errors.length === 0) {\n // Unknown error — show raw output\n ui.logError(`Upload error:\\n${fullOutput.slice(0, 500)}`);\n\n if (uploadedCount > 0) {\n ui.logWarn(\n \"Most files uploaded successfully. The theme may already be usable in HubSpot.\\n\" +\n \"You can check your HubSpot Design Manager to verify.\"\n );\n const proceed = await ui.confirm({\n message: \"Continue anyway (theme is likely uploaded)?\",\n initialValue: true,\n });\n if (proceed) return true;\n }\n\n if (attempt < MAX_RETRIES) {\n const retry = await ui.confirm({\n message: \"Try uploading again?\",\n });\n if (!retry) break;\n continue;\n }\n break;\n }\n\n // Try to auto-fix known errors\n let anyFixed = false;\n for (const error of errors) {\n if (error.fixable) {\n const fixed = autoFixError(themePath, error);\n if (fixed) {\n ui.logSuccess(`Auto-fixed: ${error.message}`);\n anyFixed = true;\n } else {\n ui.logWarn(`Could not auto-fix: ${error.message}`);\n }\n } else {\n ui.logError(error.message);\n }\n }\n\n if (anyFixed && attempt < MAX_RETRIES) {\n // Retry after fixes\n continue;\n }\n\n // If files were uploaded, offer to continue despite errors\n if (uploadedCount > 0) {\n ui.logWarn(\n `${uploadedCount} files uploaded successfully despite errors.\\n` +\n \"The theme may work — check HubSpot Design Manager.\"\n );\n const proceed = await ui.confirm({\n message: \"Continue anyway?\",\n initialValue: true,\n });\n if (proceed) return true;\n }\n\n if (!anyFixed) {\n // Try removing stuck modules as last resort\n s.start(\"Cleaning up stuck modules...\");\n run(`hs cms remove \"${themeName}/modules\"`, {\n cwd: join(themePath, \"..\"),\n });\n s.stop(\"Cleaned up modules, retrying...\");\n }\n }\n\n ui.logError(\n \"Upload failed after multiple attempts. Try running `hs cms upload` manually to see detailed errors.\"\n );\n return false;\n}\n","/**\n * Auto-fix utilities for common HubSpot upload errors.\n * Shared between CLI wizard (uploader.ts) and web server (server.ts).\n */\n\nimport { join } from \"node:path\";\nimport { readdirSync, rmSync } from \"node:fs\";\nimport { readFile, writeFile, fileExists } from \"../utils/fs.js\";\n\nexport interface UploadError {\n file: string;\n message: string;\n fixable: boolean;\n}\n\nexport function parseUploadErrors(output: string): UploadError[] {\n const errors: UploadError[] = [];\n\n if (/textarea.*not.*valid|unknown.*field.*type/i.test(output)) {\n const fileMatch = output.match(/(?:in|file:?)\\s+(\\S+fields\\.json)/i);\n errors.push({\n file: fileMatch?.[1] || \"fields.json\",\n message: '\"textarea\" is not a valid field type',\n fixable: true,\n });\n }\n\n if (/missing field name|field null/i.test(output)) {\n const fileMatch = output.match(/(?:in|file:?)\\s+(\\S+fields\\.json)/i);\n errors.push({\n file: fileMatch?.[1] || \"fields.json\",\n message: '\"name\" is a reserved field name',\n fixable: true,\n });\n }\n\n if (/could not resolve.*now/i.test(output)) {\n errors.push({\n file: \"module.html\",\n message: \"now() is not a valid HubL function\",\n fixable: true,\n });\n }\n\n if (/hubdb|do not have access to hubdb/i.test(output)) {\n errors.push({\n file: \"templates\",\n message: \"HubDB requires CMS Hub Pro/Enterprise\",\n fixable: true,\n });\n }\n\n if (/invalid default value|link.*field.*invalid/i.test(output)) {\n const fieldMatch = output.match(/field.*?(\\w+)\\s+has an invalid/i);\n errors.push({\n file: fieldMatch?.[1] || \"fields.json\",\n message: `Link field has invalid default value`,\n fixable: true,\n });\n }\n\n if (/failed to deserialize/i.test(output)) {\n const fileMatch = output.match(/file '([^']+)'/i);\n errors.push({\n file: fileMatch?.[1] || \"fields.json\",\n message: \"fields.json deserialization error\",\n fixable: true,\n });\n }\n\n if (/format for the color value is invalid/i.test(output)) {\n errors.push({\n file: \"fields.json\",\n message: \"Color field has invalid format (rgba/rgb/named — must be hex)\",\n fixable: true,\n });\n }\n\n return errors;\n}\n\nexport function applyAutoFixes(themePath: string): string[] {\n const fixes: string[] = [];\n if (fixTextareaFields(themePath)) fixes.push('textarea → text');\n if (fixReservedNames(themePath)) fixes.push('name → item_name');\n if (fixNowFunction(themePath)) fixes.push('now() → local_dt');\n if (fixHubDbTemplates(themePath)) fixes.push('Removed HubDB templates');\n if (fixLinkFieldDefaults(themePath)) fixes.push('Fixed link field defaults');\n if (fixColorFieldDefaults(themePath)) fixes.push('Fixed rgba/invalid color values → hex');\n if (fixCdnImports(themePath)) fixes.push('Stripped CDN @import statements');\n return fixes;\n}\n\nexport function autoFixError(themePath: string, error: UploadError): boolean {\n if (error.message.includes(\"textarea\")) return fixTextareaFields(themePath);\n if (error.message.includes(\"reserved field name\")) return fixReservedNames(themePath);\n if (error.message.includes(\"now()\")) return fixNowFunction(themePath);\n if (error.message.includes(\"HubDB\")) return fixHubDbTemplates(themePath);\n if (error.message.includes(\"invalid default value\") || error.message.includes(\"deserialization\"))\n return fixLinkFieldDefaults(themePath);\n if (error.message.includes(\"invalid format\") && error.message.includes(\"color\"))\n return fixColorFieldDefaults(themePath);\n return false;\n}\n\nexport function fixTextareaFields(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n if (!fileExists(modulesDir)) return false;\n\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const fieldsPath = join(modulesDir, entry, \"fields.json\");\n if (!fileExists(fieldsPath)) continue;\n let content = readFile(fieldsPath);\n if (content.includes('\"textarea\"')) {\n content = content.replace(/\"textarea\"/g, '\"text\"');\n writeFile(fieldsPath, content);\n fixed = true;\n }\n }\n return fixed;\n}\n\nexport function fixReservedNames(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n if (!fileExists(modulesDir)) return false;\n\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const fieldsPath = join(modulesDir, entry, \"fields.json\");\n if (!fileExists(fieldsPath)) continue;\n let content = readFile(fieldsPath);\n if (/\"name\":\\s*\"name\"/g.test(content)) {\n content = content.replace(/\"name\":\\s*\"name\"/g, '\"name\": \"item_name\"');\n writeFile(fieldsPath, content);\n fixed = true;\n }\n }\n return fixed;\n}\n\nexport function fixNowFunction(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n if (!fileExists(modulesDir)) return false;\n\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const htmlPath = join(modulesDir, entry, \"module.html\");\n if (!fileExists(htmlPath)) continue;\n let content = readFile(htmlPath);\n if (content.includes(\"now()\")) {\n content = content.replace(/now\\(\\)/g, \"local_dt\");\n writeFile(htmlPath, content);\n fixed = true;\n }\n }\n return fixed;\n}\n\nexport function fixHubDbTemplates(themePath: string): boolean {\n let fixed = false;\n const templatesDir = join(themePath, \"templates\");\n if (!fileExists(templatesDir)) return false;\n\n for (const file of readdirSync(templatesDir)) {\n if (!file.endsWith(\".html\")) continue;\n const filePath = join(templatesDir, file);\n const content = readFile(filePath);\n if (content.includes(\"hubdb_table\") || content.includes(\"hubdb_table_rows\")) {\n rmSync(filePath);\n fixed = true;\n }\n }\n return fixed;\n}\n\nexport function fixLinkFieldDefaults(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n if (!fileExists(modulesDir)) return false;\n\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const fieldsPath = join(modulesDir, entry, \"fields.json\");\n if (!fileExists(fieldsPath)) continue;\n try {\n const fields = JSON.parse(readFile(fieldsPath));\n if (fixLinkFieldsRecursive(fields)) {\n writeFile(fieldsPath, JSON.stringify(fields, null, 2) + \"\\n\");\n fixed = true;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n return fixed;\n}\n\n/**\n * Strip external CDN @import statements from all CSS files.\n * Google Fonts and other CDN imports can fail in HubSpot's editor\n * and cause content to appear invisible.\n */\nexport function fixCdnImports(themePath: string): boolean {\n let fixed = false;\n\n // Check shared CSS files\n const cssDir = join(themePath, \"css\");\n if (fileExists(cssDir)) {\n for (const file of readdirSync(cssDir)) {\n if (!file.endsWith(\".css\")) continue;\n const filePath = join(cssDir, file);\n let content = readFile(filePath);\n const cleaned = content.replace(/@import\\s+url\\(['\"]?https?:\\/\\/[^)]+['\"]?\\)\\s*;?/gi, \"\");\n if (cleaned !== content) {\n writeFile(filePath, cleaned);\n fixed = true;\n }\n }\n }\n\n // Check module CSS files\n const modulesDir = join(themePath, \"modules\");\n if (fileExists(modulesDir)) {\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const cssPath = join(modulesDir, entry, \"module.css\");\n if (!fileExists(cssPath)) continue;\n let content = readFile(cssPath);\n const cleaned = content.replace(/@import\\s+url\\(['\"]?https?:\\/\\/[^)]+['\"]?\\)\\s*;?/gi, \"\");\n if (cleaned !== content) {\n writeFile(cssPath, cleaned);\n fixed = true;\n }\n }\n }\n\n // Check module HTML for <link> tags to external CDNs\n if (fileExists(modulesDir)) {\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const htmlPath = join(modulesDir, entry, \"module.html\");\n if (!fileExists(htmlPath)) continue;\n let content = readFile(htmlPath);\n const cleaned = content.replace(/<link[^>]+href=['\"]https?:\\/\\/[^'\"]+['\"][^>]*>/gi, \"\");\n if (cleaned !== content) {\n writeFile(htmlPath, cleaned);\n fixed = true;\n }\n }\n }\n\n return fixed;\n}\n\n/**\n * Fix color fields that use rgba(), rgb(), named colors, or 3-digit hex.\n * HubSpot requires: { \"color\": \"#rrggbb\", \"opacity\": 100 }\n */\nexport function fixColorFieldDefaults(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n if (!fileExists(modulesDir)) return false;\n\n for (const entry of readdirSync(modulesDir)) {\n if (!entry.endsWith(\".module\")) continue;\n const fieldsPath = join(modulesDir, entry, \"fields.json\");\n if (!fileExists(fieldsPath)) continue;\n try {\n const fields = JSON.parse(readFile(fieldsPath));\n if (fixColorFieldsRecursive(fields)) {\n writeFile(fieldsPath, JSON.stringify(fields, null, 2) + \"\\n\");\n fixed = true;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n return fixed;\n}\n\nfunction fixColorFieldsRecursive(fields: unknown[]): boolean {\n let fixed = false;\n for (const field of fields) {\n if (typeof field !== \"object\" || field === null) continue;\n const f = field as Record<string, unknown>;\n\n if (f.type === \"color\" && f.default && typeof f.default === \"object\") {\n const def = f.default as Record<string, unknown>;\n const colorVal = def.color;\n if (typeof colorVal === \"string\" && !isValidHexColor(colorVal)) {\n const converted = convertToHex(colorVal);\n if (converted) {\n def.color = converted.hex;\n // If the rgba had opacity, use that instead of the existing opacity\n if (converted.opacity !== undefined) {\n def.opacity = converted.opacity;\n }\n fixed = true;\n }\n }\n }\n\n if (Array.isArray(f.children)) {\n if (fixColorFieldsRecursive(f.children as unknown[])) fixed = true;\n }\n }\n return fixed;\n}\n\nfunction isValidHexColor(color: string): boolean {\n return /^#[0-9a-fA-F]{6}$/.test(color);\n}\n\nfunction convertToHex(color: string): { hex: string; opacity?: number } | null {\n // 3-digit hex → 6-digit\n const hex3 = color.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);\n if (hex3) {\n return { hex: `#${hex3[1]}${hex3[1]}${hex3[2]}${hex3[2]}${hex3[3]}${hex3[3]}` };\n }\n\n // rgba(r, g, b, a)\n const rgba = color.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+))?\\s*\\)/i);\n if (rgba) {\n const r = Math.min(255, parseInt(rgba[1]));\n const g = Math.min(255, parseInt(rgba[2]));\n const b = Math.min(255, parseInt(rgba[3]));\n const hex = `#${r.toString(16).padStart(2, \"0\")}${g.toString(16).padStart(2, \"0\")}${b.toString(16).padStart(2, \"0\")}`;\n const opacity = rgba[4] !== undefined ? Math.round(parseFloat(rgba[4]) * 100) : undefined;\n return { hex, opacity };\n }\n\n // Named colors (common ones)\n const named: Record<string, string> = {\n white: \"#ffffff\", black: \"#000000\", red: \"#ff0000\", green: \"#008000\",\n blue: \"#0000ff\", yellow: \"#ffff00\", orange: \"#ffa500\", purple: \"#800080\",\n gray: \"#808080\", grey: \"#808080\", transparent: \"#000000\",\n };\n const lower = color.toLowerCase().trim();\n if (named[lower]) {\n return { hex: named[lower], opacity: lower === \"transparent\" ? 0 : undefined };\n }\n\n return null;\n}\n\nfunction fixLinkFieldsRecursive(fields: unknown[]): boolean {\n let fixed = false;\n for (const field of fields) {\n if (typeof field !== \"object\" || field === null) continue;\n const f = field as Record<string, unknown>;\n\n if (f.type === \"link\") {\n const def = f.default;\n const needsFix =\n typeof def === \"string\" ||\n def === undefined ||\n def === null ||\n (typeof def === \"object\" && !(def as Record<string, unknown>).url);\n\n if (needsFix) {\n const href = typeof def === \"string\" ? def : \"\";\n f.default = {\n url: { href, type: \"EXTERNAL\" },\n open_in_new_tab: false,\n no_follow: false,\n };\n fixed = true;\n }\n }\n\n if (Array.isArray(f.children)) {\n if (fixLinkFieldsRecursive(f.children as unknown[])) fixed = true;\n }\n }\n return fixed;\n}\n","import { execSync } from \"node:child_process\";\nimport { rmSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport * as ui from \"../prompts/prompter.js\";\nimport { theme } from \"../cli/theme.js\";\nimport { detectDataCenter } from \"../utils/detect.js\";\nimport { fileExists } from \"../utils/fs.js\";\n\nexport async function showNextSteps(opts: {\n portalId: string;\n sourceDir: string;\n themePath: string;\n wasCloned: boolean;\n}): Promise<void> {\n const { portalId, sourceDir, themePath, wasCloned } = opts;\n await ui.intro(\"You're all set!\");\n\n const dataCenter = detectDataCenter(portalId);\n const host =\n dataCenter === \"eu1\" ? \"app-eu1.hubspot.com\" : \"app.hubspot.com\";\n\n await ui.note(\n `Your React page has been converted and uploaded to HubSpot.\\n` +\n `The theme and modules are now in your account, but you still\\n` +\n `need to ${theme.bold(\"create a new landing page\")} that uses them.\\n\\n` +\n `Next steps:\\n\\n` +\n ` ${theme.bold(\"1.\")} Go to HubSpot ${theme.muted(\"→\")} Content ${theme.muted(\"→\")} Landing Pages ${theme.muted(\"→\")} Create\\n` +\n ` ${theme.bold(\"2.\")} Choose your uploaded theme from the theme picker\\n` +\n ` ${theme.bold(\"3.\")} Select the landing page template that was just created\\n` +\n ` ${theme.bold(\"4.\")} Your converted modules will appear — drag them onto the page\\n` +\n ` ${theme.bold(\"5.\")} Click each section to edit text, images, and colors\\n` +\n ` ${theme.bold(\"6.\")} Upload images via File Manager ${theme.muted(\"(Settings → Files)\")}\\n` +\n ` ${theme.bold(\"7.\")} Preview and publish!`,\n \"What's next\"\n );\n\n const openBrowser = await ui.confirm({\n message: \"Open HubSpot Landing Pages in your browser?\",\n });\n\n if (openBrowser) {\n const url = portalId\n ? `https://${host}/page-ui/${portalId}/management/pages/landing`\n : `https://${host}`;\n\n try {\n // Cross-platform browser open\n const platform = process.platform;\n if (platform === \"darwin\") {\n execSync(`open \"${url}\"`);\n } else if (platform === \"win32\") {\n execSync(`cmd /c start \"${url}\"`);\n } else {\n execSync(`xdg-open \"${url}\"`);\n }\n ui.logSuccess(\"Opening HubSpot Landing Pages...\");\n } catch {\n ui.log(`Open this URL in your browser: ${theme.info(url)}`);\n }\n }\n\n // Offer to clean up local directories\n const dirsToClean: { path: string; label: string }[] = [];\n if (wasCloned && fileExists(sourceDir)) {\n dirsToClean.push({ path: sourceDir, label: `Cloned source (${basename(sourceDir)})` });\n }\n if (fileExists(themePath)) {\n dirsToClean.push({ path: themePath, label: `Theme directory (${basename(themePath)})` });\n }\n\n if (dirsToClean.length > 0) {\n const cleanup = await ui.confirm({\n message: \"Clean up local working directories?\",\n });\n\n if (cleanup) {\n for (const dir of dirsToClean) {\n try {\n rmSync(dir.path, { recursive: true, force: true });\n ui.logSuccess(`Removed ${dir.label}`);\n } catch {\n ui.logWarn(`Could not remove ${dir.label} — delete manually if needed.`);\n }\n }\n }\n }\n\n await ui.outro(`Thanks for using hub${theme.vibes(\"Vibes\")}! ${theme.vibes(\"~\")}`);\n}\n","import { printBanner } from \"../cli/banner.js\";\nimport { runPreflight } from \"../wizard/preflight.js\";\nimport { setupSource } from \"../wizard/source.js\";\nimport { setupTheme } from \"../wizard/theme-setup.js\";\nimport { runConversion } from \"../wizard/conversion.js\";\nimport { runUpload } from \"../wizard/uploader.js\";\nimport { showNextSteps } from \"../wizard/next-steps.js\";\nimport { saveConfig } from \"../utils/config.js\";\n\nexport async function wizardCommand(): Promise<void> {\n printBanner();\n\n // Step 1: Preflight checks\n const preflight = await runPreflight();\n\n // Step 2: Source setup\n const source = await setupSource();\n saveConfig({ lastSourcePath: source.sourceDir });\n\n // Step 3: Theme setup\n const themeInfo = await setupTheme();\n saveConfig({ lastThemePath: themeInfo.themePath });\n\n // Step 4: AI conversion\n await runConversion({\n aiEngine: preflight.aiEngine,\n model: preflight.model,\n sourceDir: source.sourceDir,\n themePath: themeInfo.themePath,\n });\n\n // Step 5: Upload\n await runUpload(themeInfo.themePath);\n\n // Step 6: Next steps + optional cleanup\n await showNextSteps({\n portalId: preflight.portalId,\n sourceDir: source.sourceDir,\n themePath: themeInfo.themePath,\n wasCloned: source.wasCloned,\n });\n}\n","import { printBanner } from \"../cli/banner.js\";\nimport { runPreflight } from \"../wizard/preflight.js\";\n\nexport async function initCommand(): Promise<void> {\n printBanner();\n await runPreflight();\n}\n","import { printBanner } from \"../cli/banner.js\";\nimport { setupSource } from \"../wizard/source.js\";\nimport { setupTheme } from \"../wizard/theme-setup.js\";\nimport { runConversion } from \"../wizard/conversion.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport * as ui from \"../prompts/prompter.js\";\n\nexport async function convertCommand(): Promise<void> {\n printBanner();\n\n const config = loadConfig();\n\n if (!config.aiEngine) {\n ui.logError(\n \"AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`.\"\n );\n process.exit(1);\n }\n\n const source = await setupSource();\n const themeInfo = await setupTheme();\n\n await runConversion({\n aiEngine: config.aiEngine,\n sourceDir: source.sourceDir,\n themePath: themeInfo.themePath,\n });\n}\n","import { printBanner } from \"../cli/banner.js\";\nimport { runUpload } from \"../wizard/uploader.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport * as ui from \"../prompts/prompter.js\";\n\nexport async function uploadCommand(): Promise<void> {\n printBanner();\n\n const config = loadConfig();\n\n if (!config.lastThemePath) {\n const path = await ui.text({\n message: \"Path to your HubSpot theme directory:\",\n placeholder: \"./my-theme\",\n validate: (v) => (v.trim() ? undefined : \"Path is required\"),\n });\n await runUpload(path);\n } else {\n const useLast = await ui.confirm({\n message: `Upload from ${config.lastThemePath}?`,\n });\n\n if (useLast) {\n await runUpload(config.lastThemePath);\n } else {\n const path = await ui.text({\n message: \"Path to your HubSpot theme directory:\",\n placeholder: \"./my-theme\",\n });\n await runUpload(path);\n }\n }\n}\n","import { printBanner } from \"../cli/banner.js\";\nimport {\n detectNode,\n detectGit,\n detectHubSpotCLI,\n detectClaudeCode,\n detectGeminiCLI,\n detectCodexCLI,\n detectHubSpotAuth,\n nodeVersionOk,\n} from \"../utils/detect.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport * as ui from \"../prompts/prompter.js\";\nimport { theme } from \"../cli/theme.js\";\n\nexport async function doctorCommand(): Promise<void> {\n printBanner();\n await ui.intro(\"Environment Diagnostics\");\n\n let issues = 0;\n\n // Node.js\n const node = detectNode();\n if (!node.found) {\n ui.logError(\"Node.js — not installed\");\n ui.log(\" Install from https://nodejs.org\");\n issues++;\n } else if (!nodeVersionOk(node.version)) {\n ui.logWarn(`Node.js v${node.version} — too old (need 18+)`);\n ui.log(\" Update at https://nodejs.org\");\n issues++;\n } else {\n ui.logSuccess(`Node.js v${node.version}`);\n }\n\n // Git\n const git = detectGit();\n if (!git.found) {\n ui.logError(\"Git — not installed\");\n ui.log(\" Install from https://git-scm.com\");\n issues++;\n } else {\n ui.logSuccess(`Git ${git.version}`);\n }\n\n // HubSpot CLI (only needed for deployment)\n const hs = detectHubSpotCLI();\n if (!hs.found) {\n ui.logWarn(\"HubSpot CLI — not installed (only needed for deployment)\");\n ui.log(\" Install: npm install -g @hubspot/cli\");\n } else {\n ui.logSuccess(`HubSpot CLI v${hs.version}`);\n\n // HubSpot auth\n const auth = detectHubSpotAuth();\n if (!auth.authenticated) {\n ui.logWarn(\"HubSpot — not authenticated\");\n ui.log(\" Run: hs init\");\n } else {\n ui.logSuccess(\n `HubSpot portal${auth.portalName ? `: ${auth.portalName}` : \"\"} (ID: ${auth.portalId})`\n );\n }\n }\n\n // AI engines\n const claude = detectClaudeCode();\n if (claude.found) {\n ui.logSuccess(`Claude Code ${claude.version} at ${claude.path}`);\n } else {\n ui.log(theme.muted(\"Claude Code — not installed\"));\n }\n\n const gemini = detectGeminiCLI();\n if (gemini.found) {\n ui.logSuccess(`Gemini CLI ${gemini.version} at ${gemini.path}`);\n } else {\n ui.log(theme.muted(\"Gemini CLI — not installed\"));\n }\n\n const codex = detectCodexCLI();\n if (codex.found) {\n ui.logSuccess(`OpenAI Codex ${codex.version} at ${codex.path}`);\n } else {\n ui.log(theme.muted(\"OpenAI Codex — not installed\"));\n }\n\n // API keys\n const config = loadConfig();\n\n const anthropicKey = !!(config.anthropicApiKey || process.env.ANTHROPIC_API_KEY);\n const openaiKey = !!(config.openaiApiKey || process.env.OPENAI_API_KEY);\n const geminiKey = !!(config.geminiApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY);\n\n if (anthropicKey) ui.logSuccess(\"Anthropic API key configured\");\n else ui.log(theme.muted(\"Anthropic API key — not set\"));\n\n if (openaiKey) ui.logSuccess(\"OpenAI API key configured\");\n else ui.log(theme.muted(\"OpenAI API key — not set\"));\n\n if (geminiKey) ui.logSuccess(\"Google AI API key configured\");\n else ui.log(theme.muted(\"Google AI API key — not set\"));\n const engineLabels: Record<string, string> = {\n \"claude-code\": \"Claude Code\",\n \"api\": \"Anthropic API\",\n \"anthropic-api\": \"Anthropic API\",\n \"openai-api\": \"OpenAI API\",\n \"gemini-api\": \"Gemini API\",\n \"gemini-cli\": \"Gemini CLI\",\n \"codex-cli\": \"OpenAI Codex\",\n };\n if (config.aiEngine) {\n ui.logSuccess(`AI engine: ${engineLabels[config.aiEngine] || config.aiEngine}`);\n }\n if (config.lastThemePath) {\n ui.log(theme.muted(`Last theme: ${config.lastThemePath}`));\n }\n\n // No AI option available\n if (!claude.found && !gemini.found && !codex.found && !anthropicKey && !openaiKey && !geminiKey) {\n ui.logWarn(\"No AI engine available\");\n ui.log(\" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)\");\n ui.log(\" Or install: Claude Code — https://claude.ai/code\");\n ui.log(\" Gemini CLI — https://github.com/google-gemini/gemini-cli\");\n ui.log(\" Codex CLI — https://github.com/openai/codex\");\n issues++;\n }\n\n console.log();\n if (issues === 0) {\n await ui.outro(\"Everything looks good!\");\n } else {\n await ui.outro(\n theme.warn(`${issues} issue${issues > 1 ? \"s\" : \"\"} found — see above`)\n );\n }\n}\n","/**\n * `vibespot vibe` — Vibe coding mode.\n * Immediately starts a local server and opens the browser.\n * All setup happens in the web UI — zero CLI prompts.\n */\n\nimport { join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { startServer } from \"../server/server.js\";\nimport { saveSession } from \"../server/session.js\";\n\nconst DEFAULT_PORT = 4200;\n\nexport async function vibeCommand(): Promise<void> {\n const accent = chalk.hex(\"#e8613a\");\n const dim = chalk.dim;\n\n console.log(\"\");\n console.log(accent(\" v vibeSpot\"));\n console.log(dim(\" Starting...\\n\"));\n\n const uiDir = resolveUiDir();\n if (!uiDir) {\n console.error(chalk.red(\" Could not find UI assets. Is the package installed correctly?\"));\n process.exit(1);\n }\n\n try {\n const { port, close } = await startServer({ port: DEFAULT_PORT, uiDir });\n const url = `http://localhost:${port}`;\n\n console.log(accent(` v ${url}`));\n console.log(dim(\" Press Ctrl+C to stop\\n\"));\n\n // Auto-open browser\n try {\n const openCmd =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"start\"\n : \"xdg-open\";\n execSync(`${openCmd} ${url}`, { stdio: \"ignore\" });\n } catch {\n // Browser open failed — user can open manually\n }\n\n // Keep running until Ctrl+C\n await new Promise<void>((resolve) => {\n process.on(\"SIGINT\", () => {\n console.log(dim(\"\\n Saving session...\"));\n saveSession();\n close();\n console.log(dim(\" Goodbye!\\n\"));\n resolve();\n });\n });\n } catch (err) {\n console.error(chalk.red(` Failed to start: ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n}\n\nfunction resolveUiDir(): string | null {\n const candidates = [\n join(import.meta.dirname, \"../../ui\"),\n join(import.meta.dirname, \"../ui\"),\n join(process.cwd(), \"ui\"),\n ];\n\n for (const dir of candidates) {\n if (existsSync(join(dir, \"index.html\"))) return dir;\n }\n\n return null;\n}\n","/**\n * Local development server for vibeSpot vibe coding mode.\n * Serves the UI, handles WebSocket connections, and manages AI interactions.\n */\n\nimport { createServer, IncomingMessage, ServerResponse } from \"node:http\";\nimport { readFileSync, existsSync, readdirSync, appendFileSync, rmSync, renameSync } from \"node:fs\";\nimport { join, extname, basename } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { execSync } from \"node:child_process\";\nimport { WebSocketServer, WebSocket } from \"ws\";\nimport {\n getSession,\n addMessage,\n updateModules,\n reorderModules,\n removeModule,\n updateFieldValue,\n getOrderedModules,\n writeModulesToDisk,\n saveSession,\n createSession,\n scanThemeFromDisk,\n loadSession,\n listSessions,\n deleteSession,\n reloadModulesFromDisk,\n getActiveTemplate,\n setActiveTemplate,\n addTemplate,\n removeTemplate,\n getModuleLibrary,\n migrateSession,\n type PageType,\n type TemplateEntry,\n} from \"./session.js\";\nimport { commitThemeState, getHistory, rollbackToCommit, isGitAvailable } from \"./project-git.js\";\nimport { buildPreviewHtml, buildModulePreviewHtml } from \"./preview.js\";\nimport { handleGenerate, handleGenerateStream, setParseWarningCallback } from \"./ai-handler.js\";\nimport { analyzeSource, type SourceAnalysis } from \"../wizard/source.js\";\nimport { loadConfig, saveConfig, getApiKeyForEngine, type AIEngineType } from \"../utils/config.js\";\nimport { detectEnvironment, detectHubSpotCLI, detectHubSpotAuth, detectDataCenter, detectGitHubCLI, detectGitHubAuth } from \"../utils/detect.js\";\nimport { applyAutoFixes, parseUploadErrors } from \"../server/auto-fix.js\";\nimport { startJob, getJob, startStreamingJob, addJobListener, removeJobListener } from \"./process-manager.js\";\nimport { ensureDir, writeFile } from \"../utils/fs.js\";\n\n// ---------------------------------------------------------------------------\n// MIME types for static serving\n// ---------------------------------------------------------------------------\n\nconst MIME_TYPES: Record<string, string> = {\n \".html\": \"text/html\",\n \".css\": \"text/css\",\n \".js\": \"application/javascript\",\n \".json\": \"application/json\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".ico\": \"image/x-icon\",\n \".woff2\": \"font/woff2\",\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface ServerOptions {\n port: number;\n uiDir: string;\n}\n\nexport function startServer(opts: ServerOptions): Promise<{ port: number; close: () => void }> {\n const { port, uiDir } = opts;\n\n const server = createServer((req, res) => handleRequest(req, res, uiDir));\n\n // WebSocket server — upgrade on the same HTTP server\n const wss = new WebSocketServer({ server });\n wss.on(\"connection\", (ws) => handleWsConnection(ws));\n\n return new Promise((resolve, reject) => {\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n // Try next port\n server.listen(port + 1, () => {\n resolve({\n port: port + 1,\n close: () => { server.close(); wss.close(); },\n });\n });\n } else {\n reject(err);\n }\n });\n\n server.listen(port, () => {\n resolve({\n port,\n close: () => { server.close(); wss.close(); },\n });\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// HTTP request handler\n// ---------------------------------------------------------------------------\n\nfunction handleRequest(req: IncomingMessage, res: ServerResponse, uiDir: string): void {\n const url = new URL(req.url || \"/\", `http://${req.headers.host}`);\n const method = req.method || \"GET\";\n\n // API routes\n if (url.pathname.startsWith(\"/api/\")) {\n handleApiRoute(method, url.pathname, req, res);\n return;\n }\n\n // Preview route — returns rendered preview HTML\n if (url.pathname === \"/preview\") {\n const html = buildPreviewHtml();\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(html);\n return;\n }\n\n // Single-module preview (for dashboard module library)\n if (url.pathname === \"/module-preview\") {\n const moduleName = url.searchParams.get(\"module\") || \"\";\n const html = buildModulePreviewHtml(moduleName);\n res.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(html || \"<!-- module not found -->\");\n return;\n }\n\n // Static files from ui/ directory\n serveStatic(url.pathname, uiDir, res);\n}\n\n// ---------------------------------------------------------------------------\n// API routes\n// ---------------------------------------------------------------------------\n\nfunction handleApiRoute(\n method: string,\n path: string,\n req: IncomingMessage,\n res: ServerResponse\n): void {\n // CORS headers for local dev\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\n if (method === \"OPTIONS\") {\n res.writeHead(204);\n res.end();\n return;\n }\n\n switch (path) {\n case \"/api/session\":\n handleSessionRoute(method, res);\n break;\n\n case \"/api/modules\":\n handleModulesRoute(method, req, res);\n break;\n\n case \"/api/modules/reorder\":\n handleReorderRoute(req, res);\n break;\n\n case \"/api/upload\":\n handleUploadRoute(res);\n break;\n\n case \"/api/field\":\n handleFieldRoute(req, res);\n break;\n\n case \"/api/import\":\n handleImportRoute(req, res);\n break;\n\n case \"/api/setup\":\n handleSetupInfoRoute(res);\n break;\n\n case \"/api/setup/create\":\n handleSetupCreateRoute(req, res);\n break;\n\n case \"/api/setup/fetch\":\n handleSetupFetchRoute(req, res);\n break;\n\n case \"/api/setup/open\":\n handleSetupOpenRoute(req, res);\n break;\n\n case \"/api/setup/resume\":\n handleSetupResumeRoute(req, res);\n break;\n\n case \"/api/setup/apikey\":\n handleSetupApiKeyRoute(req, res);\n break;\n\n // Settings routes\n case \"/api/settings/status\":\n if (method === \"GET\") handleSettingsStatusRoute(res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/engine\":\n if (method === \"POST\") handleSettingsEngineRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/apikey\":\n if (method === \"POST\") handleSettingsApiKeyRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/install\":\n if (method === \"POST\") handleSettingsInstallRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/hs-auth\":\n if (method === \"POST\") handleSettingsHsAuthRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/gh-auth\":\n if (method === \"POST\") handleSettingsGhAuthRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/hs-switch\":\n if (method === \"POST\") handleSettingsHsSwitchRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/gh-logout\":\n if (method === \"POST\") handleSettingsGhLogoutRoute(res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/settings/cli-auth\":\n if (method === \"POST\") handleSettingsCLIAuthRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/themes\":\n handleThemesRoute(method, req, res);\n break;\n\n case \"/api/themes/switch\":\n if (method === \"POST\") handleThemeSwitchRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/themes/delete-local\":\n if (method === \"POST\") handleDeleteLocalThemeRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/history\":\n if (method === \"GET\") handleHistoryRoute(res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/rollback\":\n if (method === \"POST\") handleRollbackRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n // Dashboard & template routes\n case \"/api/dashboard\":\n if (method === \"GET\") handleDashboardRoute(res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/templates\":\n handleTemplatesRoute(method, req, res);\n break;\n\n case \"/api/templates/activate\":\n if (method === \"POST\") handleTemplateActivateRoute(req, res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/module-library\":\n if (method === \"GET\") handleModuleLibraryRoute(res);\n else jsonResponse(res, 405, { error: \"Method not allowed\" });\n break;\n\n case \"/api/brand-assets\":\n handleBrandAssetsRoute(method, req, res);\n break;\n\n default:\n // Prefix match for job polling: /api/settings/job/:id\n if (path.startsWith(\"/api/settings/job/\") && method === \"GET\") {\n handleSettingsJobRoute(path, res);\n }\n // Prefix match for template add-module: /api/templates/:id/add-module\n else if (path.match(/^\\/api\\/templates\\/[^/]+\\/add-module$/) && method === \"POST\") {\n handleAddModuleToTemplateRoute(path, req, res);\n } else {\n jsonResponse(res, 404, { error: \"Not found\" });\n }\n }\n}\n\nfunction handleSessionRoute(method: string, res: ServerResponse): void {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n jsonResponse(res, 200, {\n id: session.id,\n themeName: session.themeName,\n themePath: session.themePath,\n messageCount: session.messages.length,\n moduleCount: session.modules.length,\n moduleOrder: session.moduleOrder,\n });\n}\n\nfunction handleModulesRoute(\n method: string,\n req: IncomingMessage,\n res: ServerResponse\n): void {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n if (method === \"GET\") {\n const ordered = getOrderedModules();\n jsonResponse(res, 200, {\n modules: ordered.map((m) => ({\n moduleName: m.moduleName,\n fieldsJson: m.fieldsJson,\n moduleHtml: m.moduleHtml,\n moduleCss: m.moduleCss,\n moduleJs: m.moduleJs || null,\n })),\n sharedCss: session.sharedCss,\n sharedJs: session.sharedJs,\n });\n return;\n }\n\n if (method === \"DELETE\") {\n readBody(req, (body) => {\n const { moduleName } = JSON.parse(body);\n removeModule(moduleName);\n saveSession();\n jsonResponse(res, 200, { ok: true });\n });\n return;\n }\n\n jsonResponse(res, 405, { error: \"Method not allowed\" });\n}\n\nfunction handleReorderRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n const { order } = JSON.parse(body);\n if (Array.isArray(order)) {\n reorderModules(order);\n saveSession();\n jsonResponse(res, 200, { ok: true });\n } else {\n jsonResponse(res, 400, { error: \"order must be an array\" });\n }\n });\n}\n\nasync function handleUploadRoute(res: ServerResponse): Promise<void> {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n try {\n // Write all modules to disk first\n writeModulesToDisk();\n\n // Apply auto-fixes before uploading\n const fixes = applyAutoFixes(session.themePath);\n\n // Start a streaming upload job\n const jobId = startStreamingJob(\n `hs cms upload \"${session.themePath}\" \"${session.themeName}\"`,\n \"Uploading to HubSpot\",\n { cwd: join(session.themePath, \"..\"), timeout: 180_000 }\n );\n\n jsonResponse(res, 200, {\n ok: true,\n jobId,\n fixes,\n });\n } catch (err) {\n jsonResponse(res, 500, { error: String(err) });\n }\n}\n\nfunction handleFieldRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { moduleName, fieldPath, value } = JSON.parse(body);\n updateFieldValue(moduleName, fieldPath, value);\n saveSession();\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 400, { error: String(err) });\n }\n });\n}\n\nfunction handleImportRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { url } = JSON.parse(body);\n if (!url || typeof url !== \"string\") {\n jsonResponse(res, 400, { error: \"url is required\" });\n return;\n }\n\n // Analyze the source (clones if GitHub URL)\n const analysis = analyzeSource(url);\n\n // Build a component summary for the AI\n const componentSummary = analysis.components\n .map((c) => `- ${c.name}: ${c.description}`)\n .join(\"\\n\");\n\n const summary = {\n sourceDir: analysis.sourceDir,\n componentCount: analysis.components.length,\n components: analysis.components.map((c) => ({\n name: c.name,\n description: c.description,\n })),\n hasTailwind: analysis.hasTailwind,\n cssVarCount: analysis.cssVarCount,\n fonts: analysis.fonts,\n interactions: analysis.interactions,\n // Pre-built prompt the UI can send directly to the chat\n conversionPrompt: `Import and convert the React landing page from ${url} to native HubSpot modules.\n\nSource analysis found ${analysis.components.length} components:\n${componentSummary}\n\nDesign system: ${analysis.hasTailwind ? \"Tailwind CSS\" : \"Custom CSS\"}, ${analysis.cssVarCount} CSS variables\nFonts: ${analysis.fonts.length > 0 ? analysis.fonts.join(\", \") : \"System fonts\"}\nInteractions: ${analysis.interactions.join(\", \")}\n\nRead the React source files from ${analysis.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`,\n };\n\n jsonResponse(res, 200, summary);\n } catch (err) {\n jsonResponse(res, 500, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Setup routes — onboarding flow in the browser\n// ---------------------------------------------------------------------------\n\nconst WORKSPACE_DIR = join(homedir(), \"vibespot-themes\");\n\nfunction handleSetupInfoRoute(res: ServerResponse): void {\n const session = getSession();\n\n // Full environment detection — checks all 6 AI engines, not just Anthropic + Claude Code\n const env = detectEnvironment();\n\n // Lightweight hs check for \"Fetch from HubSpot\" visibility\n let hsInstalled = false;\n try {\n execSync(\"hs --version\", { encoding: \"utf-8\", stdio: \"pipe\" });\n hsInstalled = true;\n } catch { /* not installed */ }\n\n // List previous sessions\n const sessions = listSessions()\n .sort((a, b) => b.updatedAt - a.updatedAt)\n .slice(0, 10);\n\n // Find local theme folders in workspace/\n const localThemes: string[] = [];\n if (existsSync(WORKSPACE_DIR)) {\n try {\n for (const entry of readdirSync(WORKSPACE_DIR, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n const themeJson = join(WORKSPACE_DIR, entry.name, \"theme.json\");\n if (existsSync(themeJson)) {\n localThemes.push(entry.name);\n }\n }\n }\n } catch { /* ignore */ }\n }\n\n jsonResponse(res, 200, {\n hasActiveSession: !!session,\n activeSession: session ? {\n id: session.id,\n themeName: session.themeName,\n moduleCount: session.modules.length,\n } : null,\n hsInstalled,\n aiAvailable: env.availableEngines.length > 0,\n availableEngines: env.availableEngines,\n activeEngine: env.activeEngine,\n sessions,\n localThemes,\n });\n}\n\nfunction handleSetupCreateRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { name } = JSON.parse(body);\n if (!name || typeof name !== \"string\") {\n jsonResponse(res, 400, { error: \"Theme name is required\" });\n return;\n }\n\n const themeName = name\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n const themePath = join(WORKSPACE_DIR, themeName);\n ensureDir(WORKSPACE_DIR);\n\n // Remove existing directory if it exists (stale from a previous run)\n if (existsSync(themePath)) {\n rmSync(themePath, { recursive: true, force: true });\n }\n\n // hs create ALWAYS creates in process.cwd(), ignoring execSync's cwd option.\n // So we create it wherever it lands, then move it to the workspace.\n const cwdBefore = new Set(readdirSync(process.cwd()));\n execSync(`hs create website-theme \"${themeName}\"`, {\n encoding: \"utf-8\",\n stdio: \"pipe\",\n });\n\n // Find where hs create actually put the theme\n let createdAt = join(process.cwd(), themeName);\n if (!existsSync(createdAt)) {\n const cwdAfter = readdirSync(process.cwd());\n const newDir = cwdAfter.find((e) => !cwdBefore.has(e) && existsSync(join(process.cwd(), e)));\n if (newDir) createdAt = join(process.cwd(), newDir);\n }\n\n // Move to workspace if it was created elsewhere\n if (createdAt !== themePath && existsSync(createdAt)) {\n renameSync(createdAt, themePath);\n }\n\n // Clear boilerplate page templates (keep layouts/ and partials/ for extends)\n const tplDir = join(themePath, \"templates\");\n if (existsSync(tplDir)) {\n for (const f of readdirSync(tplDir)) {\n if (f.endsWith(\".html\")) rmSync(join(tplDir, f));\n }\n }\n\n // Create a fresh session — don't scan boilerplate modules into it\n // (boilerplate modules stay on disk but the preview shows the welcome screen)\n createSession(themePath, themeName);\n saveSession();\n\n jsonResponse(res, 200, {\n ok: true,\n themeName,\n themePath,\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSetupFetchRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { name } = JSON.parse(body);\n if (!name || typeof name !== \"string\") {\n jsonResponse(res, 400, { error: \"Theme name is required\" });\n return;\n }\n\n const themePath = join(WORKSPACE_DIR, name);\n ensureDir(WORKSPACE_DIR);\n\n execSync(`hs fetch \"${name}\" \"${themePath}\"`, {\n encoding: \"utf-8\",\n stdio: \"pipe\",\n });\n\n createSession(themePath, name);\n scanThemeFromDisk(themePath);\n saveSession();\n\n jsonResponse(res, 200, {\n ok: true,\n themeName: name,\n themePath,\n moduleCount: getSession()?.modules.length || 0,\n });\n } catch (err) {\n jsonResponse(res, 500, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n}\n\nfunction handleSetupOpenRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { path: themePath } = JSON.parse(body);\n if (!themePath || typeof themePath !== \"string\") {\n jsonResponse(res, 400, { error: \"Theme path is required\" });\n return;\n }\n\n // Support both absolute paths and workspace-relative names\n let fullPath = themePath;\n if (!existsSync(fullPath)) {\n fullPath = join(WORKSPACE_DIR, themePath);\n }\n if (!existsSync(fullPath)) {\n jsonResponse(res, 400, { error: `Theme folder not found: ${themePath}` });\n return;\n }\n\n const themeName = basename(fullPath);\n createSession(fullPath, themeName);\n scanThemeFromDisk(fullPath);\n saveSession();\n\n jsonResponse(res, 200, {\n ok: true,\n themeName,\n themePath: fullPath,\n moduleCount: getSession()?.modules.length || 0,\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSetupResumeRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { sessionId } = JSON.parse(body);\n if (!sessionId || typeof sessionId !== \"string\") {\n jsonResponse(res, 400, { error: \"Session ID is required\" });\n return;\n }\n\n const session = loadSession(sessionId);\n if (!session) {\n jsonResponse(res, 404, { error: \"Session not found\" });\n return;\n }\n\n jsonResponse(res, 200, {\n ok: true,\n themeName: session.themeName,\n themePath: session.themePath,\n moduleCount: session.modules.length,\n messageCount: session.messages.length,\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSetupApiKeyRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { apiKey } = JSON.parse(body);\n if (!apiKey || typeof apiKey !== \"string\") {\n jsonResponse(res, 400, { error: \"API key is required\" });\n return;\n }\n\n saveConfig({ anthropicApiKey: apiKey });\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 400, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Settings routes — environment management, API keys, tool install, auth\n// ---------------------------------------------------------------------------\n\nfunction handleSettingsStatusRoute(res: ServerResponse): void {\n const env = detectEnvironment();\n const config = loadConfig();\n\n jsonResponse(res, 200, {\n environment: env,\n config: {\n aiEngine: config.aiEngine || null,\n claudeCodeModel: config.claudeCodeModel || null,\n anthropicApiModel: config.anthropicApiModel || null,\n openaiApiModel: config.openaiApiModel || null,\n },\n });\n}\n\nfunction handleSettingsEngineRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { engine, model } = JSON.parse(body);\n\n const validEngines: AIEngineType[] = [\n \"claude-code\", \"anthropic-api\", \"openai-api\", \"gemini-cli\", \"gemini-api\", \"codex-cli\",\n ];\n if (!validEngines.includes(engine)) {\n jsonResponse(res, 400, { error: `Invalid engine: ${engine}` });\n return;\n }\n\n const configUpdate: Record<string, unknown> = { aiEngine: engine };\n if (model) {\n switch (engine) {\n case \"claude-code\":\n configUpdate.claudeCodeModel = model;\n break;\n case \"anthropic-api\":\n configUpdate.anthropicApiModel = model;\n break;\n case \"openai-api\":\n configUpdate.openaiApiModel = model;\n break;\n }\n }\n\n saveConfig(configUpdate as any);\n jsonResponse(res, 200, { ok: true, engine });\n } catch (err) {\n jsonResponse(res, 400, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSettingsApiKeyRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { provider, apiKey } = JSON.parse(body);\n\n if (!provider || typeof provider !== \"string\") {\n jsonResponse(res, 400, { error: \"provider is required\" });\n return;\n }\n\n // Handle deletion (apiKey is null or empty)\n if (!apiKey) {\n const configUpdate: Record<string, unknown> = {};\n switch (provider) {\n case \"anthropic\": configUpdate.anthropicApiKey = \"\"; break;\n case \"openai\": configUpdate.openaiApiKey = \"\"; break;\n case \"gemini\": configUpdate.geminiApiKey = \"\"; break;\n default:\n jsonResponse(res, 400, { error: `Unknown provider: ${provider}` });\n return;\n }\n saveConfig(configUpdate as any);\n jsonResponse(res, 200, { ok: true, provider, deleted: true });\n return;\n }\n\n // Save the key\n const configUpdate: Record<string, unknown> = {};\n switch (provider) {\n case \"anthropic\": configUpdate.anthropicApiKey = apiKey; break;\n case \"openai\": configUpdate.openaiApiKey = apiKey; break;\n case \"gemini\": configUpdate.geminiApiKey = apiKey; break;\n default:\n jsonResponse(res, 400, { error: `Unknown provider: ${provider}` });\n return;\n }\n\n saveConfig(configUpdate as any);\n\n // Auto-select engine if none is currently configured\n let autoSelectedEngine: string | null = null;\n const currentConfig = loadConfig();\n if (!currentConfig.aiEngine) {\n const engineMap: Record<string, string> = {\n anthropic: \"anthropic-api\",\n openai: \"openai-api\",\n gemini: \"gemini-api\",\n };\n const engine = engineMap[provider];\n if (engine) {\n saveConfig({ aiEngine: engine } as any);\n autoSelectedEngine = engine;\n }\n }\n\n jsonResponse(res, 200, { ok: true, provider, autoSelectedEngine });\n } catch (err) {\n jsonResponse(res, 400, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSettingsInstallRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { tool } = JSON.parse(body);\n\n const installCommands: Record<string, { cmd: string; desc: string }> = {\n hubspot: { cmd: \"npm install -g @hubspot/cli\", desc: \"Installing HubSpot CLI\" },\n claude: { cmd: \"npm install -g @anthropic-ai/claude-code\", desc: \"Installing Claude Code\" },\n gemini: { cmd: \"npm install -g @google/gemini-cli\", desc: \"Installing Gemini CLI\" },\n codex: { cmd: process.platform === \"darwin\" ? \"brew install --cask codex\" : \"npm install -g @openai/codex\", desc: \"Installing OpenAI Codex\" },\n gh: { cmd: process.platform === \"darwin\" ? \"brew install gh\" : \"npm install -g @cli/gh\", desc: \"Installing GitHub CLI\" },\n };\n\n const config = installCommands[tool];\n if (!config) {\n jsonResponse(res, 400, { error: `Unknown tool: ${tool}. Valid: ${Object.keys(installCommands).join(\", \")}` });\n return;\n }\n\n const jobId = startJob(config.cmd, config.desc, { timeout: 120_000 });\n jsonResponse(res, 200, { ok: true, jobId });\n } catch (err) {\n jsonResponse(res, 400, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSettingsHsAuthRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const parsed = JSON.parse(body || \"{}\");\n\n const hs = detectHubSpotCLI();\n if (!hs.found) {\n jsonResponse(res, 400, { error: \"HubSpot CLI not installed\", needsInstall: true });\n return;\n }\n\n // Check if already authenticated\n const auth = detectHubSpotAuth();\n if (auth.authenticated && !parsed.force) {\n jsonResponse(res, 200, {\n ok: true,\n alreadyAuthenticated: true,\n portalName: auth.portalName,\n portalId: auth.portalId,\n });\n return;\n }\n\n if (parsed.personalAccessKey) {\n // Non-interactive auth with provided key\n const jobId = startJob(\n `echo \"${parsed.personalAccessKey}\" | hs auth personalaccesskey`,\n \"Authenticating with HubSpot\",\n { timeout: 30_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId });\n return;\n }\n\n // No key provided — return instructions for user to get one\n jsonResponse(res, 200, {\n needsKey: true,\n instructions: \"Create a personal access key in HubSpot\",\n url: \"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key\",\n steps: [\n \"Click the link above to open HubSpot\",\n \"Select your account\",\n \"Create a Personal Access Key with CMS permissions\",\n \"Copy the key and paste it below\",\n ],\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSettingsGhAuthRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const parsed = JSON.parse(body || \"{}\");\n\n const gh = detectGitHubCLI();\n if (!gh.found) {\n jsonResponse(res, 400, { error: \"GitHub CLI not installed\", needsInstall: true });\n return;\n }\n\n // Check if already authenticated\n const auth = detectGitHubAuth();\n if (auth.authenticated && !parsed.force) {\n jsonResponse(res, 200, {\n ok: true,\n alreadyAuthenticated: true,\n username: auth.username,\n });\n return;\n }\n\n if (parsed.token) {\n // Auth with provided token\n const jobId = startJob(\n `echo \"${parsed.token}\" | gh auth login --with-token`,\n \"Authenticating with GitHub\",\n { timeout: 30_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId });\n return;\n }\n\n // Start browser-based auth flow\n const jobId = startJob(\n \"gh auth login --web --git-protocol https\",\n \"GitHub authentication (check your browser)\",\n { timeout: 300_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId, browserAuthRequired: true });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSettingsHsSwitchRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { portalId, action } = JSON.parse(body);\n\n const hs = detectHubSpotCLI();\n if (!hs.found) {\n jsonResponse(res, 400, { error: \"HubSpot CLI not installed\" });\n return;\n }\n\n if (action === \"remove\" && portalId) {\n // Remove account: hs accounts clean --account=<portalId>\n const jobId = startJob(\n `hs accounts remove ${portalId}`,\n `Removing HubSpot account ${portalId}`,\n { timeout: 15_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId });\n return;\n }\n\n if (portalId) {\n // Switch default account: hs accounts use <portalId>\n const jobId = startJob(\n `hs accounts use ${portalId}`,\n `Switching to HubSpot account ${portalId}`,\n { timeout: 15_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId });\n return;\n }\n\n jsonResponse(res, 400, { error: \"portalId required\" });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSettingsGhLogoutRoute(res: ServerResponse): void {\n const jobId = startJob(\n \"gh auth logout --hostname github.com -y\",\n \"Logging out of GitHub\",\n { timeout: 15_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId });\n}\n\nfunction handleSettingsCLIAuthRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { cli, apiKey } = JSON.parse(body || \"{}\");\n\n switch (cli) {\n case \"claude\": {\n // Claude Code auth — launch interactive login\n // We need to run `claude` without CLAUDECODE env to avoid nesting error\n const jobId = startJob(\n \"CLAUDECODE= claude --print -p 'reply OK'\",\n \"Authenticating Claude Code (check your browser if prompted)\",\n { timeout: 120_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId, hint: \"If Claude Code opens a browser window, complete the sign-in there.\" });\n break;\n }\n case \"gemini\": {\n // Gemini CLI auth — launch a simple prompt to trigger login\n const jobId = startJob(\n \"gemini -p 'reply OK'\",\n \"Authenticating Gemini CLI (check your browser if prompted)\",\n { timeout: 120_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId, hint: \"If Gemini opens a browser window, complete the sign-in there.\" });\n break;\n }\n case \"codex\": {\n // Codex CLI — two auth paths: OAuth (codex login) or API key\n if (apiKey && apiKey.trim()) {\n // API key path — save to env, config, and shell profile\n const key = apiKey.trim();\n process.env.OPENAI_API_KEY = key;\n saveConfig({ openaiApiKey: key } as any);\n const profileLine = `export OPENAI_API_KEY=\"${key}\"`;\n const shellProfile = process.env.SHELL?.includes(\"zsh\")\n ? join(homedir(), \".zshrc\")\n : join(homedir(), \".bashrc\");\n try {\n const existing = existsSync(shellProfile)\n ? readFileSync(shellProfile, \"utf-8\")\n : \"\";\n if (!existing.includes(\"OPENAI_API_KEY\")) {\n appendFileSync(shellProfile, `\\n# Added by vibeSpot\\n${profileLine}\\n`);\n }\n } catch { /* ignore profile write errors */ }\n jsonResponse(res, 200, { ok: true, message: \"API key saved\" });\n } else {\n // OAuth path — run `codex login` as background job\n const jobId = startJob(\n \"codex login\",\n \"Authenticating Codex CLI (check your browser if prompted)\",\n { timeout: 120_000 }\n );\n jsonResponse(res, 200, { ok: true, jobId, hint: \"Complete the sign-in in your browser.\" });\n }\n break;\n }\n default:\n jsonResponse(res, 400, { error: `Unknown CLI: ${cli}` });\n }\n } catch (err) {\n jsonResponse(res, 400, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleSettingsJobRoute(path: string, res: ServerResponse): void {\n const jobId = path.replace(\"/api/settings/job/\", \"\");\n if (!jobId) {\n jsonResponse(res, 400, { error: \"Job ID required\" });\n return;\n }\n\n const job = getJob(jobId);\n if (!job) {\n jsonResponse(res, 404, { error: \"Job not found\" });\n return;\n }\n\n jsonResponse(res, 200, {\n id: job.id,\n status: job.status,\n description: job.description,\n output: job.output,\n exitCode: job.exitCode,\n startedAt: job.startedAt,\n completedAt: job.completedAt,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Theme routes\n// ---------------------------------------------------------------------------\n\nfunction handleThemesRoute(method: string, req: IncomingMessage, res: ServerResponse): void {\n if (method === \"GET\") {\n const session = getSession();\n const sessions = listSessions()\n .sort((a, b) => b.updatedAt - a.updatedAt);\n\n jsonResponse(res, 200, {\n activeTheme: session\n ? { id: session.id, themeName: session.themeName }\n : null,\n sessions,\n });\n return;\n }\n\n if (method === \"DELETE\") {\n readBody(req, (body) => {\n try {\n const { sessionId, deleteFiles } = JSON.parse(body);\n deleteSession(sessionId, deleteFiles);\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n return;\n }\n\n jsonResponse(res, 405, { error: \"Method not allowed\" });\n}\n\nfunction handleThemeSwitchRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { sessionId } = JSON.parse(body);\n const session = loadSession(sessionId);\n if (!session) {\n jsonResponse(res, 404, { error: \"Session not found\" });\n return;\n }\n\n jsonResponse(res, 200, {\n ok: true,\n themeName: session.themeName,\n themePath: session.themePath,\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleDeleteLocalThemeRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { themeName } = JSON.parse(body);\n if (!themeName || typeof themeName !== \"string\") {\n jsonResponse(res, 400, { error: \"Theme name is required\" });\n return;\n }\n const themePath = join(WORKSPACE_DIR, themeName);\n if (!existsSync(themePath)) {\n jsonResponse(res, 404, { error: \"Theme not found on disk\" });\n return;\n }\n rmSync(themePath, { recursive: true, force: true });\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Version history routes\n// ---------------------------------------------------------------------------\n\nfunction handleHistoryRoute(res: ServerResponse): void {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n if (!isGitAvailable()) {\n jsonResponse(res, 200, { available: false, commits: [] });\n return;\n }\n const commits = getHistory(session.themePath, 50);\n jsonResponse(res, 200, { available: true, commits });\n}\n\nfunction handleRollbackRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n const { hash } = JSON.parse(body);\n if (!hash || typeof hash !== \"string\") {\n jsonResponse(res, 400, { error: \"Commit hash is required\" });\n return;\n }\n\n // Add a system message to chat (chat is immutable, always grows)\n addMessage(\"assistant\", `Rolled back to version ${hash.slice(0, 7)}.`);\n\n const result = rollbackToCommit(session.themePath, hash);\n if (!result.success) {\n jsonResponse(res, 500, { error: result.error || \"Rollback failed\" });\n return;\n }\n\n // Reload modules from restored files\n reloadModulesFromDisk();\n saveSession();\n\n jsonResponse(res, 200, {\n ok: true,\n modules: getOrderedModules().map((m) => m.moduleName),\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Dashboard & template routes\n// ---------------------------------------------------------------------------\n\nfunction handleDashboardRoute(res: ServerResponse): void {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n const library = getModuleLibrary();\n jsonResponse(res, 200, {\n themeName: session.themeName,\n themePath: session.themePath,\n templates: session.templates.map((t) => ({\n id: t.id,\n label: t.label,\n pageType: t.pageType,\n moduleCount: t.modules.length,\n messageCount: t.messages.length,\n })),\n activeTemplateId: session.activeTemplateId,\n moduleLibrary: library.map((entry) => ({\n moduleName: entry.module.moduleName,\n usedIn: entry.usedIn,\n })),\n brandAssets: {\n hasStyleguide: !!session.brandAssets?.styleguide,\n hasBrandvoice: !!session.brandAssets?.brandvoice,\n },\n });\n}\n\nfunction handleTemplatesRoute(method: string, req: IncomingMessage, res: ServerResponse): void {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n if (method === \"GET\") {\n jsonResponse(res, 200, {\n templates: session.templates.map((t) => ({\n id: t.id,\n label: t.label,\n pageType: t.pageType,\n moduleCount: t.modules.length,\n })),\n activeTemplateId: session.activeTemplateId,\n });\n return;\n }\n\n if (method === \"POST\") {\n readBody(req, (body) => {\n try {\n const { pageType, label } = JSON.parse(body);\n if (!pageType || !label) {\n jsonResponse(res, 400, { error: \"pageType and label are required\" });\n return;\n }\n const validTypes: PageType[] = [\"landing_page\", \"blog_post\", \"website_page\", \"module_only\"];\n if (!validTypes.includes(pageType)) {\n jsonResponse(res, 400, { error: `Invalid pageType: ${pageType}` });\n return;\n }\n\n const entry = addTemplate(pageType, label);\n saveSession();\n\n jsonResponse(res, 200, {\n ok: true,\n template: {\n id: entry.id,\n label: entry.label,\n pageType: entry.pageType,\n },\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n return;\n }\n\n if (method === \"DELETE\") {\n readBody(req, (body) => {\n try {\n const { templateId } = JSON.parse(body);\n if (!templateId) {\n jsonResponse(res, 400, { error: \"templateId is required\" });\n return;\n }\n const removed = removeTemplate(templateId);\n if (!removed) {\n jsonResponse(res, 404, { error: \"Template not found\" });\n return;\n }\n saveSession();\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n return;\n }\n\n jsonResponse(res, 405, { error: \"Method not allowed\" });\n}\n\nfunction handleTemplateActivateRoute(req: IncomingMessage, res: ServerResponse): void {\n readBody(req, (body) => {\n try {\n const { templateId } = JSON.parse(body);\n if (!templateId) {\n jsonResponse(res, 400, { error: \"templateId is required\" });\n return;\n }\n const success = setActiveTemplate(templateId);\n if (!success) {\n jsonResponse(res, 404, { error: \"Template not found\" });\n return;\n }\n saveSession();\n const session = getSession();\n jsonResponse(res, 200, {\n ok: true,\n modules: getOrderedModules().map((m) => m.moduleName),\n messageCount: session?.messages.length || 0,\n });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleModuleLibraryRoute(res: ServerResponse): void {\n const library = getModuleLibrary();\n jsonResponse(res, 200, {\n modules: library.map((entry) => ({\n moduleName: entry.module.moduleName,\n usedIn: entry.usedIn,\n fieldsJson: entry.module.fieldsJson,\n })),\n });\n}\n\nfunction handleAddModuleToTemplateRoute(path: string, req: IncomingMessage, res: ServerResponse): void {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n readBody(req, (body) => {\n try {\n const { moduleName } = JSON.parse(body);\n if (!moduleName) {\n jsonResponse(res, 400, { error: \"moduleName is required\" });\n return;\n }\n\n // Find the module in the library (across all templates)\n const library = getModuleLibrary();\n const entry = library.find((e) => e.module.moduleName === moduleName);\n if (!entry) {\n jsonResponse(res, 404, { error: `Module \"${moduleName}\" not found in library` });\n return;\n }\n\n // Copy the module into the active template / session\n const modCopy = { ...entry.module };\n const existing = session.modules.find((m) => m.moduleName === modCopy.moduleName);\n if (!existing) {\n session.modules.push(modCopy);\n session.moduleOrder.push(modCopy.moduleName);\n session.updatedAt = Date.now();\n }\n\n saveSession();\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n}\n\nfunction handleBrandAssetsRoute(method: string, req: IncomingMessage, res: ServerResponse): void {\n const session = getSession();\n if (!session) {\n jsonResponse(res, 404, { error: \"No active session\" });\n return;\n }\n\n if (method === \"GET\") {\n jsonResponse(res, 200, {\n styleguide: session.brandAssets?.styleguide || null,\n brandvoice: session.brandAssets?.brandvoice || null,\n });\n return;\n }\n\n if (method === \"POST\") {\n readBody(req, (body) => {\n try {\n const { type, content } = JSON.parse(body);\n if (!type || !content) {\n jsonResponse(res, 400, { error: \"type and content are required\" });\n return;\n }\n if (type !== \"styleguide\" && type !== \"brandvoice\") {\n jsonResponse(res, 400, { error: `Invalid type: ${type}. Must be \"styleguide\" or \"brandvoice\"` });\n return;\n }\n\n if (!session.brandAssets) session.brandAssets = {};\n session.brandAssets[type] = content;\n session.updatedAt = Date.now();\n\n // Also persist to theme directory\n const assetDir = join(session.themePath, \".vibespot\");\n ensureDir(assetDir);\n writeFile(join(assetDir, `${type}.md`), content);\n\n saveSession();\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n return;\n }\n\n if (method === \"DELETE\") {\n readBody(req, (body) => {\n try {\n const { type } = JSON.parse(body);\n if (type !== \"styleguide\" && type !== \"brandvoice\") {\n jsonResponse(res, 400, { error: `Invalid type: ${type}` });\n return;\n }\n\n if (session.brandAssets) {\n delete session.brandAssets[type];\n }\n session.updatedAt = Date.now();\n\n // Remove from disk too\n const filePath = join(session.themePath, \".vibespot\", `${type}.md`);\n if (existsSync(filePath)) rmSync(filePath);\n\n saveSession();\n jsonResponse(res, 200, { ok: true });\n } catch (err) {\n jsonResponse(res, 500, { error: err instanceof Error ? err.message : String(err) });\n }\n });\n return;\n }\n\n jsonResponse(res, 405, { error: \"Method not allowed\" });\n}\n\n// ---------------------------------------------------------------------------\n// WebSocket handler\n// ---------------------------------------------------------------------------\n\nfunction handleWsConnection(ws: WebSocket): void {\n ws.on(\"message\", async (data) => {\n let msg: { type: string; [key: string]: unknown };\n try {\n msg = JSON.parse(data.toString());\n } catch {\n ws.send(JSON.stringify({ type: \"error\", message: \"Invalid JSON\" }));\n return;\n }\n\n switch (msg.type) {\n case \"chat\": {\n const userMessage = String(msg.message || \"\");\n if (!userMessage.trim()) return;\n\n addMessage(\"user\", userMessage);\n saveSession();\n\n // Set up parse warning callback for this generation\n setParseWarningCallback((warning) => {\n ws.send(JSON.stringify({ type: \"parse_warning\", message: warning }));\n });\n\n // Stream AI response back via WebSocket\n try {\n await handleGenerateStream(\n userMessage,\n (chunk) => {\n ws.send(JSON.stringify({ type: \"stream\", content: chunk }));\n },\n (status) => {\n ws.send(JSON.stringify({ type: \"stream_status\", content: status }));\n }\n );\n\n // Write modules to disk and commit for version history\n const currentSession = getSession();\n if (currentSession) {\n writeModulesToDisk();\n const commitHash = commitThemeState(currentSession.themePath, userMessage);\n if (commitHash) {\n ws.send(JSON.stringify({ type: \"version_created\", hash: commitHash }));\n }\n }\n\n // After generation, send updated preview\n ws.send(JSON.stringify({ type: \"generation_complete\" }));\n ws.send(JSON.stringify({\n type: \"modules_updated\",\n modules: getOrderedModules().map((m) => m.moduleName),\n }));\n } catch (err) {\n ws.send(JSON.stringify({\n type: \"error\",\n message: err instanceof Error ? err.message : String(err),\n }));\n }\n break;\n }\n\n case \"start_upload\": {\n const session = getSession();\n if (!session) {\n ws.send(JSON.stringify({ type: \"error\", message: \"No active session\" }));\n break;\n }\n\n try {\n writeModulesToDisk();\n\n // Apply auto-fixes before uploading\n const fixes = applyAutoFixes(session.themePath);\n if (fixes.length > 0) {\n ws.send(JSON.stringify({ type: \"upload_status\", phase: \"autofix\", fixes }));\n }\n\n // Start streaming upload job\n const jobId = startStreamingJob(\n `hs cms upload \"${session.themePath}\" \"${session.themeName}\"`,\n \"Uploading to HubSpot\",\n { cwd: join(session.themePath, \"..\"), timeout: 180_000 }\n );\n\n ws.send(JSON.stringify({ type: \"upload_started\", jobId }));\n\n // Stream output chunks to the client\n const chunkListener = (chunk: string) => {\n ws.send(JSON.stringify({ type: \"upload_output\", chunk }));\n };\n addJobListener(jobId, chunkListener);\n\n // Poll for job completion\n const pollInterval = setInterval(() => {\n const job = getJob(jobId);\n if (!job || job.status === \"running\") return;\n\n clearInterval(pollInterval);\n removeJobListener(jobId, chunkListener);\n\n if (job.status === \"completed\") {\n const auth = detectHubSpotAuth();\n const dc = auth.portalId ? detectDataCenter(auth.portalId) : \"na1\";\n ws.send(JSON.stringify({\n type: \"upload_complete\",\n output: job.output,\n portalId: auth.portalId || \"\",\n dataCenter: dc,\n themeName: session.themeName,\n }));\n } else {\n const errors = parseUploadErrors(job.output);\n ws.send(JSON.stringify({\n type: \"upload_failed\",\n output: job.output,\n errors,\n exitCode: job.exitCode,\n }));\n }\n }, 500);\n } catch (err) {\n ws.send(JSON.stringify({\n type: \"error\",\n message: err instanceof Error ? err.message : String(err),\n }));\n }\n break;\n }\n\n case \"upload_fix_with_ai\": {\n const errorContext = String(msg.errorContext || \"\");\n if (!errorContext.trim()) {\n ws.send(JSON.stringify({ type: \"error\", message: \"No error context provided\" }));\n break;\n }\n\n const fixPrompt = `The HubSpot upload (\"hs cms upload\") failed. Below is the upload log output containing the errors.\n\nIMPORTANT: Be verbose in your response. For each error:\n1. State exactly which file has the problem and what the error is\n2. Explain WHY this error occurs (e.g. \"HubSpot doesn't support textarea field type\" or \"field name 'name' is reserved in HubSpot modules\")\n3. Describe the specific fix you're applying (e.g. \"Changing field type from textarea to text\" or \"Renaming field from 'name' to 'item_name'\")\n4. Apply the fix to the module files\n\nCRITICAL: After fixing the reported errors, scan ALL other module files in the theme for the same issues. For example, if you fix \"name\" → \"item_name\" in one module, check every other module's fields.json for the same problem. Fix all occurrences, not just the ones in the error log.\n\nAfter fixing all errors, summarize the changes you made.\n\nUpload log:\n${errorContext}`;\n addMessage(\"user\", fixPrompt);\n saveSession();\n\n ws.send(JSON.stringify({ type: \"upload_fix_started\" }));\n\n try {\n await handleGenerateStream(fixPrompt, (chunk) => {\n // Stream to both the chat panel and the upload panel\n ws.send(JSON.stringify({ type: \"stream\", content: chunk }));\n ws.send(JSON.stringify({ type: \"upload_fix_stream\", content: chunk }));\n });\n\n // Write fixes to disk and commit\n const fixSession = getSession();\n if (fixSession) {\n writeModulesToDisk();\n const fixHash = commitThemeState(fixSession.themePath, \"AI fix: upload errors\");\n if (fixHash) {\n ws.send(JSON.stringify({ type: \"version_created\", hash: fixHash }));\n }\n }\n\n ws.send(JSON.stringify({ type: \"upload_fix_complete\" }));\n ws.send(JSON.stringify({\n type: \"modules_updated\",\n modules: getOrderedModules().map((m) => m.moduleName),\n }));\n } catch (err) {\n ws.send(JSON.stringify({\n type: \"upload_failed\",\n output: err instanceof Error ? err.message : String(err),\n errors: [{ file: \"AI fix\", message: err instanceof Error ? err.message : String(err), fixable: false }],\n }));\n }\n break;\n }\n\n case \"ping\":\n ws.send(JSON.stringify({ type: \"pong\" }));\n break;\n\n default:\n ws.send(JSON.stringify({ type: \"error\", message: `Unknown type: ${msg.type}` }));\n }\n });\n\n // Send initial state\n const session = getSession();\n if (session) {\n const cfg = loadConfig();\n const engineLabels: Record<string, string> = {\n \"claude-code\": \"Claude Code\",\n \"anthropic-api\": \"Anthropic API\",\n \"openai-api\": \"OpenAI API\",\n \"gemini-cli\": \"Gemini CLI\",\n \"gemini-api\": \"Gemini API\",\n \"codex-cli\": \"Codex CLI\",\n \"api\": \"Anthropic API\",\n };\n const activeTpl = getActiveTemplate();\n ws.send(JSON.stringify({\n type: \"init\",\n themeName: session.themeName,\n modules: getOrderedModules().map((m) => m.moduleName),\n messageCount: session.messages.length,\n messages: session.messages,\n gitAvailable: isGitAvailable(),\n engine: cfg.aiEngine ? engineLabels[cfg.aiEngine] || cfg.aiEngine : \"\",\n // Multi-template context\n templateId: activeTpl?.id || null,\n pageType: activeTpl?.pageType || null,\n templates: (session.templates || []).map((t) => ({\n id: t.id,\n label: t.label,\n pageType: t.pageType,\n moduleCount: t.modules.length,\n })),\n }));\n } else {\n ws.send(JSON.stringify({ type: \"needs_setup\" }));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Static file serving\n// ---------------------------------------------------------------------------\n\nfunction serveStatic(pathname: string, uiDir: string, res: ServerResponse): void {\n // Default to index.html\n let filePath = pathname === \"/\" ? \"/index.html\" : pathname;\n const fullPath = join(uiDir, filePath);\n\n if (!existsSync(fullPath)) {\n // SPA fallback — serve index.html for unknown routes\n const indexPath = join(uiDir, \"index.html\");\n if (existsSync(indexPath)) {\n const content = readFileSync(indexPath);\n res.writeHead(200, { \"Content-Type\": \"text/html\", \"Cache-Control\": \"no-store\" });\n res.end(content);\n } else {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not found\");\n }\n return;\n }\n\n const ext = extname(fullPath);\n const contentType = MIME_TYPES[ext] || \"application/octet-stream\";\n\n try {\n const content = readFileSync(fullPath);\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Cache-Control\": \"no-store\",\n });\n res.end(content);\n } catch {\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Internal Server Error\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(res: ServerResponse, status: number, data: unknown): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(data));\n}\n\nfunction readBody(req: IncomingMessage, callback: (body: string) => void): void {\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk) => chunks.push(chunk));\n req.on(\"end\", () => callback(Buffer.concat(chunks).toString(\"utf-8\")));\n}\n","/**\n * Session state for the vibe coding workspace.\n * Tracks conversation history, generated modules, and theme state.\n */\n\nimport { readFileSync, readdirSync, existsSync, writeFileSync, mkdirSync, rmSync } from \"node:fs\";\nimport { join, basename } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { ModuleFiles, GeneratedAssets } from \"../ai/engine.js\";\nimport { ensureGitRepo } from \"./project-git.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ChatMessage {\n role: \"user\" | \"assistant\";\n content: string;\n timestamp: number;\n}\n\nexport type PageType = \"landing_page\" | \"blog_post\" | \"website_page\" | \"module_only\";\n\nexport interface TemplateEntry {\n id: string; // e.g. \"lp-main\", \"blog-post\"\n label: string; // \"Main Landing Page\"\n pageType: PageType;\n templateFile: string; // \"templates/lp-main.html\"\n modules: ModuleFiles[];\n moduleOrder: string[];\n sharedCss: string;\n sharedJs: string;\n template: string; // HubL template content\n messages: ChatMessage[]; // per-template chat history\n}\n\nexport interface VibeSession {\n id: string;\n themePath: string;\n themeName: string;\n\n // Multi-template support\n templates: TemplateEntry[];\n activeTemplateId: string;\n brandAssets?: {\n styleguide?: string;\n brandvoice?: string;\n };\n\n // Legacy flat fields — kept for backward compat, redirected to active template\n messages: ChatMessage[];\n modules: ModuleFiles[];\n sharedCss: string;\n sharedJs: string;\n template: string;\n moduleOrder: string[];\n createdAt: number;\n updatedAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// Session management\n// ---------------------------------------------------------------------------\n\nconst SESSIONS_DIR = join(homedir(), \".vibespot\", \"sessions\");\n\nlet activeSession: VibeSession | null = null;\n\nexport function createSession(themePath: string, themeName: string): VibeSession {\n const session: VibeSession = {\n id: generateId(),\n themePath,\n themeName,\n templates: [],\n activeTemplateId: \"\",\n messages: [],\n modules: [],\n sharedCss: \"\",\n sharedJs: \"\",\n template: \"\",\n moduleOrder: [],\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n activeSession = session;\n ensureGitRepo(themePath);\n return session;\n}\n\n// ---------------------------------------------------------------------------\n// Template management\n// ---------------------------------------------------------------------------\n\n/**\n * Migrate a legacy flat session (v0.3.0) into the templates array.\n * Called when loading a session that has modules but no templates.\n */\nexport function migrateSession(session: VibeSession): void {\n if (session.templates && session.templates.length > 0) return;\n if (!session.modules || session.modules.length === 0) {\n session.templates = [];\n session.activeTemplateId = \"\";\n return;\n }\n\n const templateId = `lp-${session.themeName}`;\n const entry: TemplateEntry = {\n id: templateId,\n label: `${session.themeName} Landing Page`,\n pageType: \"landing_page\",\n templateFile: `templates/lp-${session.themeName}.html`,\n modules: [...session.modules],\n moduleOrder: [...session.moduleOrder],\n sharedCss: session.sharedCss || \"\",\n sharedJs: session.sharedJs || \"\",\n template: session.template || \"\",\n messages: [...session.messages],\n };\n\n session.templates = [entry];\n session.activeTemplateId = templateId;\n}\n\n/**\n * Get the active template entry, or null if none set.\n */\nexport function getActiveTemplate(): TemplateEntry | null {\n if (!activeSession) return null;\n if (!activeSession.activeTemplateId || !activeSession.templates?.length) return null;\n return activeSession.templates.find((t) => t.id === activeSession!.activeTemplateId) || null;\n}\n\n/**\n * Set the active template by ID. Syncs flat fields from the template.\n */\nexport function setActiveTemplate(templateId: string): boolean {\n if (!activeSession) return false;\n const tpl = activeSession.templates.find((t) => t.id === templateId);\n if (!tpl) return false;\n\n activeSession.activeTemplateId = templateId;\n syncFlatFieldsFromTemplate(tpl);\n activeSession.updatedAt = Date.now();\n return true;\n}\n\n/**\n * Create a new template entry and add it to the session.\n */\nexport function addTemplate(pageType: PageType, label: string): TemplateEntry {\n if (!activeSession) throw new Error(\"No active session\");\n\n const slug = label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n const prefix = pageType === \"blog_post\" ? \"bp\" :\n pageType === \"website_page\" ? \"wp\" :\n pageType === \"module_only\" ? \"mo\" : \"lp\";\n const id = `${prefix}-${slug}`;\n\n const entry: TemplateEntry = {\n id,\n label,\n pageType,\n templateFile: pageType === \"module_only\" ? \"\" : `templates/${id}.html`,\n modules: [],\n moduleOrder: [],\n sharedCss: \"\",\n sharedJs: \"\",\n template: \"\",\n messages: [],\n };\n\n activeSession.templates.push(entry);\n activeSession.activeTemplateId = id;\n syncFlatFieldsFromTemplate(entry);\n activeSession.updatedAt = Date.now();\n return entry;\n}\n\n/**\n * Remove a template by ID.\n */\nexport function removeTemplate(templateId: string): boolean {\n if (!activeSession) return false;\n const idx = activeSession.templates.findIndex((t) => t.id === templateId);\n if (idx < 0) return false;\n\n activeSession.templates.splice(idx, 1);\n\n // If we removed the active template, switch to the first remaining one\n if (activeSession.activeTemplateId === templateId) {\n if (activeSession.templates.length > 0) {\n setActiveTemplate(activeSession.templates[0].id);\n } else {\n activeSession.activeTemplateId = \"\";\n activeSession.modules = [];\n activeSession.moduleOrder = [];\n activeSession.sharedCss = \"\";\n activeSession.sharedJs = \"\";\n activeSession.template = \"\";\n activeSession.messages = [];\n }\n }\n\n activeSession.updatedAt = Date.now();\n return true;\n}\n\n/**\n * Get deduplicated modules across all templates (the module library).\n */\nexport function getModuleLibrary(): Array<{ module: ModuleFiles; usedIn: string[] }> {\n if (!activeSession) return [];\n const map = new Map<string, { module: ModuleFiles; usedIn: string[] }>();\n\n for (const tpl of activeSession.templates) {\n for (const mod of tpl.modules) {\n const existing = map.get(mod.moduleName);\n if (existing) {\n existing.usedIn.push(tpl.label);\n } else {\n map.set(mod.moduleName, { module: mod, usedIn: [tpl.label] });\n }\n }\n }\n\n return Array.from(map.values());\n}\n\n/**\n * Sync flat session fields from a template (compatibility layer).\n * Existing code reads session.modules, session.messages, etc.\n * This keeps those in sync with the active template.\n */\nfunction syncFlatFieldsFromTemplate(tpl: TemplateEntry): void {\n if (!activeSession) return;\n activeSession.modules = tpl.modules;\n activeSession.moduleOrder = tpl.moduleOrder;\n activeSession.sharedCss = tpl.sharedCss;\n activeSession.sharedJs = tpl.sharedJs;\n activeSession.template = tpl.template;\n activeSession.messages = tpl.messages;\n}\n\n/**\n * Sync changes from flat session fields back to the active template.\n * Called after any mutation to session.modules/sharedCss/etc.\n */\nfunction syncFlatFieldsToTemplate(): void {\n if (!activeSession) return;\n const tpl = getActiveTemplate();\n if (!tpl) return;\n tpl.modules = activeSession.modules;\n tpl.moduleOrder = activeSession.moduleOrder;\n tpl.sharedCss = activeSession.sharedCss;\n tpl.sharedJs = activeSession.sharedJs;\n tpl.template = activeSession.template;\n tpl.messages = activeSession.messages;\n}\n\nexport function getSession(): VibeSession | null {\n return activeSession;\n}\n\nexport function addMessage(role: \"user\" | \"assistant\", content: string): void {\n if (!activeSession) return;\n activeSession.messages.push({ role, content, timestamp: Date.now() });\n activeSession.updatedAt = Date.now();\n syncFlatFieldsToTemplate();\n saveChatToTheme();\n}\n\n/**\n * Update session with newly generated/modified modules.\n * Merges new modules into existing state (updates existing, adds new).\n */\nexport function updateModules(assets: Partial<GeneratedAssets>): void {\n if (!activeSession) return;\n\n if (assets.sharedCss !== undefined) activeSession.sharedCss = assets.sharedCss;\n if (assets.sharedJs !== undefined) activeSession.sharedJs = assets.sharedJs;\n if (assets.template !== undefined) activeSession.template = assets.template;\n\n if (assets.modules) {\n for (const newMod of assets.modules) {\n const idx = activeSession.modules.findIndex(\n (m) => m.moduleName === newMod.moduleName\n );\n if (idx >= 0) {\n activeSession.modules[idx] = newMod;\n } else {\n activeSession.modules.push(newMod);\n activeSession.moduleOrder.push(newMod.moduleName);\n }\n }\n }\n\n activeSession.updatedAt = Date.now();\n syncFlatFieldsToTemplate();\n}\n\n/**\n * Reorder modules (used by drag-and-drop in the UI).\n */\nexport function reorderModules(newOrder: string[]): void {\n if (!activeSession) return;\n activeSession.moduleOrder = newOrder;\n activeSession.updatedAt = Date.now();\n syncFlatFieldsToTemplate();\n}\n\n/**\n * Remove a module by name.\n */\nexport function removeModule(moduleName: string): void {\n if (!activeSession) return;\n activeSession.modules = activeSession.modules.filter(\n (m) => m.moduleName !== moduleName\n );\n activeSession.moduleOrder = activeSession.moduleOrder.filter(\n (n) => n !== moduleName\n );\n activeSession.updatedAt = Date.now();\n syncFlatFieldsToTemplate();\n}\n\n/**\n * Update a single field value in a module's fields.json.\n * Used by the field editor sidebar.\n */\nexport function updateFieldValue(\n moduleName: string,\n fieldPath: string,\n value: unknown\n): void {\n if (!activeSession) return;\n\n const mod = activeSession.modules.find((m) => m.moduleName === moduleName);\n if (!mod) return;\n\n try {\n const fields = JSON.parse(mod.fieldsJson);\n setFieldDefault(fields, fieldPath, value);\n mod.fieldsJson = JSON.stringify(fields, null, 2);\n activeSession.updatedAt = Date.now();\n syncFlatFieldsToTemplate();\n } catch {\n // Invalid JSON — skip\n }\n}\n\n/**\n * Get modules in display order.\n */\nexport function getOrderedModules(): ModuleFiles[] {\n if (!activeSession) return [];\n\n const ordered: ModuleFiles[] = [];\n for (const name of activeSession.moduleOrder) {\n const mod = activeSession.modules.find((m) => m.moduleName === name);\n if (mod) ordered.push(mod);\n }\n\n // Append any modules not in the order list\n for (const mod of activeSession.modules) {\n if (!activeSession.moduleOrder.includes(mod.moduleName)) {\n ordered.push(mod);\n }\n }\n\n return ordered;\n}\n\n// ---------------------------------------------------------------------------\n// Scan modules from disk (for loading existing themes)\n// ---------------------------------------------------------------------------\n\n/**\n * Scan a theme directory on disk and load existing modules into the session.\n */\nexport function scanThemeFromDisk(themePath: string): void {\n if (!activeSession) return;\n\n // Load persisted chat from theme directory (if session has no messages yet)\n const chatFromDisk = loadChatFromTheme(themePath);\n if (chatFromDisk.length > 0 && activeSession.messages.length === 0) {\n activeSession.messages = chatFromDisk;\n }\n\n // Ensure git repo exists (handles themes created before this feature)\n ensureGitRepo(themePath);\n\n const modulesDir = join(themePath, \"modules\");\n if (!existsSync(modulesDir)) return;\n\n const entries = readdirSync(modulesDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory() || !entry.name.endsWith(\".module\")) continue;\n\n const modDir = join(modulesDir, entry.name);\n const moduleName = entry.name.replace(/\\.module$/, \"\");\n\n const mod: ModuleFiles = {\n moduleName,\n fieldsJson: safeRead(join(modDir, \"fields.json\")),\n metaJson: safeRead(join(modDir, \"meta.json\")),\n moduleHtml: safeRead(join(modDir, \"module.html\")),\n moduleCss: safeRead(join(modDir, \"module.css\")),\n moduleJs: safeRead(join(modDir, \"module.js\")) || undefined,\n };\n\n if (mod.fieldsJson && mod.moduleHtml) {\n activeSession.modules.push(mod);\n activeSession.moduleOrder.push(moduleName);\n }\n }\n\n // Load shared CSS/JS\n const cssDir = join(themePath, \"css\");\n const jsDir = join(themePath, \"js\");\n\n if (existsSync(cssDir)) {\n const cssFiles = readdirSync(cssDir).filter(\n (f) => f.endsWith(\"-theme.css\") || f.endsWith(\"-theme.css\")\n );\n if (cssFiles.length > 0) {\n activeSession.sharedCss = safeRead(join(cssDir, cssFiles[0]));\n }\n }\n\n if (existsSync(jsDir)) {\n const jsFiles = readdirSync(jsDir).filter(\n (f) => f.endsWith(\"-animations.js\")\n );\n if (jsFiles.length > 0) {\n activeSession.sharedJs = safeRead(join(jsDir, jsFiles[0]));\n }\n }\n\n // Load brand assets from .vibespot/ directory\n const sgPath = join(themePath, \".vibespot\", \"styleguide.md\");\n const bvPath = join(themePath, \".vibespot\", \"brandvoice.md\");\n if (existsSync(sgPath) || existsSync(bvPath)) {\n if (!activeSession.brandAssets) activeSession.brandAssets = {};\n if (existsSync(sgPath)) activeSession.brandAssets.styleguide = safeRead(sgPath);\n if (existsSync(bvPath)) activeSession.brandAssets.brandvoice = safeRead(bvPath);\n }\n\n // Migrate flat fields to templates if this is a pre-existing theme\n if (!activeSession.templates) activeSession.templates = [];\n if (!activeSession.activeTemplateId) activeSession.activeTemplateId = \"\";\n migrateSession(activeSession);\n}\n\n// ---------------------------------------------------------------------------\n// Persistence — save/load sessions across restarts\n// ---------------------------------------------------------------------------\n\nexport function saveSession(): void {\n if (!activeSession) return;\n\n mkdirSync(SESSIONS_DIR, { recursive: true });\n const filePath = join(SESSIONS_DIR, `${activeSession.id}.json`);\n writeFileSync(filePath, JSON.stringify(activeSession, null, 2), \"utf-8\");\n}\n\nexport function loadSession(sessionId: string): VibeSession | null {\n const filePath = join(SESSIONS_DIR, sessionId + \".json\");\n if (!existsSync(filePath)) return null;\n\n try {\n const data = JSON.parse(readFileSync(filePath, \"utf-8\"));\n\n // Ensure templates array exists (backward compat with v0.3.0 sessions)\n if (!data.templates) data.templates = [];\n if (!data.activeTemplateId) data.activeTemplateId = \"\";\n\n // Migrate flat fields into templates if needed\n migrateSession(data);\n\n activeSession = data;\n return data;\n } catch {\n return null;\n }\n}\n\nexport function listSessions(): Array<{ id: string; themeName: string; updatedAt: number }> {\n if (!existsSync(SESSIONS_DIR)) return [];\n\n return readdirSync(SESSIONS_DIR)\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => {\n try {\n const data = JSON.parse(readFileSync(join(SESSIONS_DIR, f), \"utf-8\"));\n return { id: data.id, themeName: data.themeName, updatedAt: data.updatedAt };\n } catch {\n return null;\n }\n })\n .filter(Boolean) as Array<{ id: string; themeName: string; updatedAt: number }>;\n}\n\nexport function deleteSession(sessionId: string, deleteFiles = false): void {\n const filePath = join(SESSIONS_DIR, sessionId + \".json\");\n\n // Read the session to get themeName (needed to find sibling sessions)\n let themeName = \"\";\n if (deleteFiles) {\n try {\n const data = JSON.parse(readFileSync(filePath, \"utf-8\"));\n themeName = data.themeName || \"\";\n if (data.themePath && existsSync(data.themePath)) {\n rmSync(data.themePath, { recursive: true, force: true });\n }\n } catch { /* ignore */ }\n } else {\n try {\n const data = JSON.parse(readFileSync(filePath, \"utf-8\"));\n themeName = data.themeName || \"\";\n } catch { /* ignore */ }\n }\n\n try {\n if (existsSync(filePath)) rmSync(filePath);\n } catch { /* ignore */ }\n\n // Also delete all other sessions for the same theme (prevents ghost entries)\n if (themeName && existsSync(SESSIONS_DIR)) {\n for (const f of readdirSync(SESSIONS_DIR).filter((f) => f.endsWith(\".json\"))) {\n try {\n const data = JSON.parse(readFileSync(join(SESSIONS_DIR, f), \"utf-8\"));\n if (data.themeName === themeName) {\n rmSync(join(SESSIONS_DIR, f));\n }\n } catch { /* ignore */ }\n }\n }\n\n if (activeSession?.id === sessionId) {\n activeSession = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Write modules back to disk (for upload)\n// ---------------------------------------------------------------------------\n\nexport function writeModulesToDisk(): void {\n if (!activeSession) return;\n\n const themePath = activeSession.themePath;\n\n // Collect all modules from all templates (deduplicated by name)\n const allModules = new Map<string, ModuleFiles>();\n if (activeSession.templates.length > 0) {\n for (const tpl of activeSession.templates) {\n for (const mod of tpl.modules) {\n allModules.set(mod.moduleName, mod);\n }\n }\n }\n // Also include flat session modules (backward compat / active template)\n for (const mod of activeSession.modules) {\n allModules.set(mod.moduleName, mod);\n }\n\n for (const mod of allModules.values()) {\n const modDir = join(themePath, \"modules\", `${mod.moduleName}.module`);\n mkdirSync(modDir, { recursive: true });\n\n writeFileSync(join(modDir, \"fields.json\"), mod.fieldsJson, \"utf-8\");\n writeFileSync(join(modDir, \"meta.json\"), mod.metaJson, \"utf-8\");\n writeFileSync(join(modDir, \"module.html\"), mod.moduleHtml, \"utf-8\");\n writeFileSync(join(modDir, \"module.css\"), mod.moduleCss, \"utf-8\");\n if (mod.moduleJs) {\n writeFileSync(join(modDir, \"module.js\"), mod.moduleJs, \"utf-8\");\n }\n }\n\n // Write shared CSS/JS\n if (activeSession.sharedCss) {\n const cssDir = join(themePath, \"css\");\n mkdirSync(cssDir, { recursive: true });\n writeFileSync(\n join(cssDir, `${activeSession.themeName}-theme.css`),\n activeSession.sharedCss,\n \"utf-8\"\n );\n }\n\n if (activeSession.sharedJs) {\n const jsDir = join(themePath, \"js\");\n mkdirSync(jsDir, { recursive: true });\n writeFileSync(\n join(jsDir, `${activeSession.themeName}-animations.js`),\n activeSession.sharedJs,\n \"utf-8\"\n );\n }\n\n // Write page templates for all templates in the session\n if (activeSession.templates.length > 0) {\n const templatesDir = join(themePath, \"templates\");\n mkdirSync(templatesDir, { recursive: true });\n\n for (const tpl of activeSession.templates) {\n if (tpl.pageType === \"module_only\") continue; // No template for module-only\n if (tpl.modules.length === 0) continue;\n\n const templateContent = tpl.template || generateTemplateForEntry(tpl);\n const annotated = ensureTemplateAnnotations(templateContent, tpl.label, tpl.pageType);\n writeFileSync(\n join(templatesDir, `${tpl.id}.html`),\n annotated,\n \"utf-8\"\n );\n\n // For blog posts, also generate a listing template\n if (tpl.pageType === \"blog_post\") {\n writeBlogListingTemplate(templatesDir, tpl);\n }\n }\n } else if (activeSession.modules.length > 0) {\n // Legacy fallback: single template from flat fields\n const template = activeSession.template || generateTemplateFromModules();\n const templatesDir = join(themePath, \"templates\");\n mkdirSync(templatesDir, { recursive: true });\n const annotated = ensureTemplateAnnotations(template, `${activeSession.themeName} Landing Page`);\n writeFileSync(\n join(templatesDir, `lp-${activeSession.themeName}.html`),\n annotated,\n \"utf-8\"\n );\n }\n\n // Patch base.html to load template_js (animations won't work without this)\n patchBaseTemplate();\n\n // Populate theme.json with proper metadata\n updateThemeJson();\n}\n\n// ---------------------------------------------------------------------------\n// Chat persistence — store chat in theme directory\n// ---------------------------------------------------------------------------\n\n/**\n * Persist chat to {themePath}/.vibespot/chat.json (gitignored).\n */\nfunction saveChatToTheme(): void {\n if (!activeSession) return;\n try {\n const chatDir = join(activeSession.themePath, \".vibespot\");\n mkdirSync(chatDir, { recursive: true });\n const chatData = {\n sessionId: activeSession.id,\n themeName: activeSession.themeName,\n messages: activeSession.messages,\n updatedAt: Date.now(),\n };\n writeFileSync(join(chatDir, \"chat.json\"), JSON.stringify(chatData, null, 2), \"utf-8\");\n } catch {\n // Non-critical — don't block on chat persistence errors\n }\n}\n\n/**\n * Load chat history from a theme's .vibespot/chat.json.\n */\nfunction loadChatFromTheme(themePath: string): ChatMessage[] {\n const chatPath = join(themePath, \".vibespot\", \"chat.json\");\n if (!existsSync(chatPath)) return [];\n try {\n const data = JSON.parse(readFileSync(chatPath, \"utf-8\"));\n return Array.isArray(data.messages) ? data.messages : [];\n } catch {\n return [];\n }\n}\n\n/**\n * Clear in-memory modules and re-scan from disk.\n * Used after a git rollback to sync session state with restored files.\n */\nexport function reloadModulesFromDisk(): void {\n if (!activeSession) return;\n activeSession.modules = [];\n activeSession.moduleOrder = [];\n activeSession.sharedCss = \"\";\n activeSession.sharedJs = \"\";\n activeSession.template = \"\";\n scanThemeFromDisk(activeSession.themePath);\n activeSession.updatedAt = Date.now();\n syncFlatFieldsToTemplate();\n}\n\n// ---------------------------------------------------------------------------\n// Theme metadata — populate theme.json + validate template annotations\n// ---------------------------------------------------------------------------\n\n/**\n * Patch base.html to load template_js (the boilerplate only loads template_css).\n * Without this, shared animations JS never runs and scroll-animate elements stay invisible.\n */\nfunction patchBaseTemplate(): void {\n if (!activeSession) return;\n const basePath = join(activeSession.themePath, \"templates\", \"layouts\", \"base.html\");\n if (!existsSync(basePath)) return;\n\n try {\n let content = readFileSync(basePath, \"utf-8\");\n // Already patched?\n if (content.includes(\"template_js\")) return;\n\n // Insert {% if template_js %} block right after the main.js require line\n const mainJsLine = '{{ require_js(get_asset_url(\"../../js/main.js\")) }}';\n if (content.includes(mainJsLine)) {\n content = content.replace(\n mainJsLine,\n mainJsLine + '\\n {% if template_js %}\\n {{ require_js(get_asset_url(template_js)) }}\\n {% endif %}'\n );\n } else {\n // Fallback: insert before standard_footer_includes\n content = content.replace(\n \"{{ standard_footer_includes }}\",\n '{% if template_js %}\\n {{ require_js(get_asset_url(template_js)) }}\\n {% endif %}\\n {{ standard_footer_includes }}'\n );\n }\n\n writeFileSync(basePath, content, \"utf-8\");\n } catch {\n // Non-critical — the generated template has its own require_js fallback\n }\n}\n\n/**\n * Update theme.json with proper name/label and ensure template annotations.\n * Called during writeModulesToDisk.\n */\nfunction updateThemeJson(): void {\n if (!activeSession) return;\n const themeJsonPath = join(activeSession.themePath, \"theme.json\");\n if (!existsSync(themeJsonPath)) return;\n\n try {\n const themeData = JSON.parse(readFileSync(themeJsonPath, \"utf-8\"));\n themeData.label = activeSession.themeName;\n themeData.name = activeSession.themeName;\n writeFileSync(themeJsonPath, JSON.stringify(themeData, null, 2), \"utf-8\");\n } catch {\n // Non-critical\n }\n}\n\n/**\n * Ensure the page template has proper HubSpot annotations.\n */\nfunction ensureTemplateAnnotations(templateContent: string, label: string, pageType: PageType = \"landing_page\"): string {\n // Check if annotations already exist\n if (templateContent.includes(\"templateType\")) return templateContent;\n\n const templateType = pageType === \"blog_post\" ? \"blog_post\" : \"page\";\n const annotations = `<!--\n templateType: ${templateType}\n isAvailableForNewContent: true\n label: \"${label}\"\n-->\\n`;\n return annotations + templateContent;\n}\n\n// ---------------------------------------------------------------------------\n// Template generation — build page templates from module data\n// ---------------------------------------------------------------------------\n\n/**\n * Build a HubSpot page template for a specific TemplateEntry.\n */\nfunction generateTemplateForEntry(tpl: TemplateEntry): string {\n if (tpl.modules.length === 0) return \"\";\n\n const name = activeSession!.themeName;\n const ordered = getOrderedModulesFrom(tpl);\n\n const sections = ordered.map((mod) => {\n return ` {% dnd_section padding={\"top\":\"0\",\"bottom\":\"0\",\"left\":\"0\",\"right\":\"0\"}, full_width=true %}\n {% dnd_module path=\"../modules/${mod.moduleName}.module\" %}\n {% end_dnd_module %}\n {% end_dnd_section %}`;\n }).join(\"\\n\\n\");\n\n const templateType = tpl.pageType === \"blog_post\" ? \"blog_post\" : \"page\";\n\n return `<!--\n templateType: ${templateType}\n isAvailableForNewContent: true\n label: \"${tpl.label}\"\n-->\n{% extends \"./layouts/base.html\" %}\n\n{% set template_css = \"../../css/${name}-theme.css\" %}\n{% set template_js = \"../../js/${name}-animations.js\" %}\n\n{% block header %}\n{% endblock header %}\n\n{% block body %}\n<div class=\"${name}-page\">\n {% dnd_area \"main_content\" label=\"${tpl.label}\" %}\n\n${sections}\n\n {% end_dnd_area %}\n</div>\n{{ require_js(get_asset_url(\"../../js/${name}-animations.js\")) }}\n{% endblock body %}\n\n{% block footer %}\n{% endblock footer %}\n`;\n}\n\n/**\n * Write a blog listing template alongside a blog post template.\n */\nfunction writeBlogListingTemplate(templatesDir: string, tpl: TemplateEntry): void {\n const listingContent = `<!--\n templateType: blog_listing\n isAvailableForNewContent: true\n label: \"${tpl.label} - Listing\"\n-->\n{% extends \"./layouts/base.html\" %}\n\n{% block body %}\n<div class=\"blog-listing\">\n <h1>{{ group.public_title }}</h1>\n {% for content in contents %}\n <article class=\"blog-listing__post\">\n <h2><a href=\"{{ content.absolute_url }}\">{{ content.name }}</a></h2>\n {% if content.featured_image %}\n <img src=\"{{ content.featured_image }}\" alt=\"{{ content.featured_image_alt_text }}\">\n {% endif %}\n <p>{{ content.post_summary|truncatewords(30) }}</p>\n <span class=\"blog-listing__date\">{{ content.publish_date|datetimeformat('%B %d, %Y') }}</span>\n </article>\n {% endfor %}\n {% if next_page_num %}\n <a href=\"{{ next_page_url }}\">Next Page</a>\n {% endif %}\n</div>\n{% endblock body %}\n`;\n writeFileSync(\n join(templatesDir, `${tpl.id}-listing.html`),\n listingContent,\n \"utf-8\"\n );\n}\n\n/**\n * Get modules in display order for a specific template entry.\n */\nfunction getOrderedModulesFrom(tpl: TemplateEntry): ModuleFiles[] {\n const ordered: ModuleFiles[] = [];\n for (const name of tpl.moduleOrder) {\n const mod = tpl.modules.find((m) => m.moduleName === name);\n if (mod) ordered.push(mod);\n }\n for (const mod of tpl.modules) {\n if (!tpl.moduleOrder.includes(mod.moduleName)) {\n ordered.push(mod);\n }\n }\n return ordered;\n}\n\n/**\n * Build a HubSpot page template that assembles all modules in display order.\n * Legacy — used when no templates array exists (flat session).\n */\nfunction generateTemplateFromModules(): string {\n if (!activeSession || activeSession.modules.length === 0) return \"\";\n\n const name = activeSession.themeName;\n const ordered = getOrderedModules();\n\n const sections = ordered.map((mod) => {\n return ` {% dnd_section padding={\"top\":\"0\",\"bottom\":\"0\",\"left\":\"0\",\"right\":\"0\"}, full_width=true %}\n {% dnd_module path=\"../modules/${mod.moduleName}.module\" %}\n {% end_dnd_module %}\n {% end_dnd_section %}`;\n }).join(\"\\n\\n\");\n\n return `<!--\n templateType: page\n isAvailableForNewContent: true\n label: \"${name} Landing Page\"\n-->\n{% extends \"./layouts/base.html\" %}\n\n{% set template_css = \"../../css/${name}-theme.css\" %}\n{% set template_js = \"../../js/${name}-animations.js\" %}\n\n{% block header %}\n{% endblock header %}\n\n{% block body %}\n<div class=\"${name}-page\">\n {% dnd_area \"main_content\" label=\"${name} Landing Page\" %}\n\n${sections}\n\n {% end_dnd_area %}\n</div>\n{{ require_js(get_asset_url(\"../../js/${name}-animations.js\")) }}\n{% endblock body %}\n\n{% block footer %}\n{% endblock footer %}\n`;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction generateId(): string {\n return `vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction safeRead(filePath: string): string {\n try {\n return readFileSync(filePath, \"utf-8\");\n } catch {\n return \"\";\n }\n}\n\n/**\n * Set a default value at a dot-separated field path in a fields.json array.\n */\nfunction setFieldDefault(fields: FieldDef[], path: string, value: unknown): void {\n const parts = path.split(\".\");\n const fieldName = parts[0];\n const field = fields.find((f: FieldDef) => f.name === fieldName);\n if (!field) return;\n\n if (parts.length === 1) {\n field.default = value;\n } else if (field.children) {\n setFieldDefault(field.children, parts.slice(1).join(\".\"), value);\n }\n}\n\ninterface FieldDef {\n name: string;\n default?: unknown;\n children?: FieldDef[];\n}\n","/**\n * Per-project local git — auto-commits, version history, rollback.\n * All operations are local-only. Git is optional; if unavailable,\n * every function degrades gracefully (returns null / false / []).\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { run } from \"../utils/shell.js\";\n\nexport interface GitCommitInfo {\n hash: string; // short hash (7 chars)\n fullHash: string; // full SHA\n message: string; // first line of commit message\n timestamp: number; // unix epoch ms\n date: string; // ISO string for display\n}\n\n// ---------------------------------------------------------------------------\n// Git availability (cached)\n// ---------------------------------------------------------------------------\n\nlet gitAvailableCache: boolean | null = null;\n\nexport function isGitAvailable(): boolean {\n if (gitAvailableCache !== null) return gitAvailableCache;\n const result = run(\"git --version\");\n gitAvailableCache = result.success;\n return gitAvailableCache;\n}\n\n// ---------------------------------------------------------------------------\n// Repo initialization\n// ---------------------------------------------------------------------------\n\n/**\n * Ensure a git repo exists in the theme directory.\n * Creates .gitignore, .vibespot/ dir, and initial commit if needed.\n * Safe to call multiple times (idempotent).\n */\nexport function ensureGitRepo(themePath: string): boolean {\n if (!isGitAvailable()) return false;\n\n // Already initialized\n if (existsSync(join(themePath, \".git\"))) {\n ensureVibeSpotDir(themePath);\n return true;\n }\n\n // Init repo\n const init = run(\"git init\", { cwd: themePath });\n if (!init.success) {\n console.warn(`[project-git] git init failed in ${themePath}: ${init.stderr}`);\n return false;\n }\n\n // Create .gitignore\n writeGitIgnore(themePath);\n\n // Create .vibespot/ dir for chat persistence\n ensureVibeSpotDir(themePath);\n\n // Initial commit\n run(\"git add -A\", { cwd: themePath });\n run('git commit -m \"Initial theme\"', { cwd: themePath });\n\n return true;\n}\n\nfunction ensureVibeSpotDir(themePath: string): void {\n const dir = join(themePath, \".vibespot\");\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\nfunction writeGitIgnore(themePath: string): void {\n const gitignorePath = join(themePath, \".gitignore\");\n const lines = [\".vibespot/\", \"node_modules/\", \"\"];\n writeFileSync(gitignorePath, lines.join(\"\\n\"), \"utf-8\");\n}\n\n// ---------------------------------------------------------------------------\n// Committing\n// ---------------------------------------------------------------------------\n\n/**\n * Stage all changes and commit with the given message.\n * Returns the short commit hash, or null if nothing to commit or error.\n */\nexport function commitThemeState(themePath: string, message: string): string | null {\n if (!isGitAvailable()) return null;\n if (!existsSync(join(themePath, \".git\"))) return null;\n\n // Stage everything\n run(\"git add -A\", { cwd: themePath });\n\n // Check if there are staged changes\n const diff = run(\"git diff --cached --quiet\", { cwd: themePath });\n if (diff.success) return null; // exit 0 = nothing staged\n\n // Truncate message to 72 chars\n const truncated = message.length > 72\n ? message.slice(0, 69) + \"...\"\n : message;\n\n // Commit (use -- to prevent message from being interpreted as flags)\n const commitResult = run(`git commit -m \"${truncated.replace(/\"/g, '\\\\\"')}\"`, { cwd: themePath });\n if (!commitResult.success) {\n console.warn(`[project-git] commit failed: ${commitResult.stderr}`);\n return null;\n }\n\n // Get short hash\n const hashResult = run(\"git rev-parse --short HEAD\", { cwd: themePath });\n return hashResult.success ? hashResult.stdout : null;\n}\n\n// ---------------------------------------------------------------------------\n// History\n// ---------------------------------------------------------------------------\n\n/**\n * Get commit history (most recent first).\n */\nexport function getHistory(themePath: string, limit: number = 50): GitCommitInfo[] {\n if (!isGitAvailable()) return [];\n if (!existsSync(join(themePath, \".git\"))) return [];\n\n const result = run(\n `git log --pretty=format:\"%h|%H|%s|%at\" -n ${limit}`,\n { cwd: themePath }\n );\n if (!result.success || !result.stdout.trim()) return [];\n\n const commits: GitCommitInfo[] = [];\n for (const line of result.stdout.split(\"\\n\")) {\n const parts = line.split(\"|\");\n if (parts.length < 4) continue;\n const timestamp = parseInt(parts[3], 10) * 1000;\n commits.push({\n hash: parts[0],\n fullHash: parts[1],\n message: parts[2],\n timestamp,\n date: new Date(timestamp).toISOString(),\n });\n }\n return commits;\n}\n\n// ---------------------------------------------------------------------------\n// Rollback\n// ---------------------------------------------------------------------------\n\n/**\n * Restore theme files to a specific commit's state.\n * Creates a new commit (\"Rollback to: <original message>\") to keep linear history.\n * Does NOT touch .vibespot/ (gitignored) — chat is preserved.\n */\nexport function rollbackToCommit(\n themePath: string,\n commitHash: string\n): { success: boolean; error?: string } {\n if (!isGitAvailable()) return { success: false, error: \"Git not available\" };\n if (!existsSync(join(themePath, \".git\"))) return { success: false, error: \"Not a git repo\" };\n\n // Verify commit exists\n const verify = run(`git cat-file -t ${commitHash}`, { cwd: themePath });\n if (!verify.success || verify.stdout.trim() !== \"commit\") {\n return { success: false, error: `Commit ${commitHash} not found` };\n }\n\n // Get original commit message\n const msgResult = run(`git log --format=\"%s\" -1 ${commitHash}`, { cwd: themePath });\n const origMessage = msgResult.success ? msgResult.stdout : commitHash;\n\n // Restore all files from that commit\n const checkout = run(`git checkout ${commitHash} -- .`, { cwd: themePath });\n if (!checkout.success) {\n return { success: false, error: `Checkout failed: ${checkout.stderr}` };\n }\n\n // Commit the rollback\n const rollbackMsg = `Rollback to: ${origMessage}`.slice(0, 72);\n run(`git commit -m \"${rollbackMsg.replace(/\"/g, '\\\\\"')}\"`, { cwd: themePath });\n\n return { success: true };\n}\n","/**\n * Lightweight HubL subset renderer for local preview.\n *\n * Supports the constructs that AI-generated HubSpot modules actually use:\n * {{ module.field }} — variable access\n * {{ module.group.child }} — nested access\n * {% if module.field %}...{% endif %} — conditionals (+ {% else %})\n * {% for item in module.list %}...{% endfor %} — loops\n * {{ item.field }} — loop variable access\n *\n * Everything else (require_css, get_asset_url, dnd_area, etc.) is stripped.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FieldDef {\n name: string;\n type: string;\n default?: unknown;\n children?: FieldDef[];\n occurrence?: { min: number; max: number };\n tab?: string;\n}\n\nexport interface RenderContext {\n module: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a render context from a fields.json array, using each field's default.\n */\nexport function buildContextFromFields(fields: FieldDef[]): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const field of fields) {\n if (field.type === \"group\" && field.occurrence && Array.isArray(field.default)) {\n // Repeater group — default is an array of objects\n result[field.name] = field.default;\n } else if (field.type === \"group\" && field.children) {\n // Nested group (e.g. styles) — recurse into children\n result[field.name] = buildContextFromFields(field.children);\n } else {\n result[field.name] = field.default ?? \"\";\n }\n }\n\n return result;\n}\n\n/**\n * Render a HubL template string with the given context.\n * Returns plain HTML suitable for browser rendering.\n */\nexport function renderHubL(template: string, context: RenderContext): string {\n let output = template;\n\n // 1. Strip HubSpot-only directives that don't apply in preview\n output = stripDirectives(output);\n\n // 2. Process {% for %} loops (must come before if/expressions)\n output = processForLoops(output, context);\n\n // 3. Process {% if %} / {% else %} / {% endif %} conditionals\n output = processConditionals(output, context);\n\n // 4. Resolve {{ expression }} variable references\n output = resolveExpressions(output, context);\n\n // 5. Clean up any remaining unresolved tags\n output = cleanupRemaining(output);\n\n return output;\n}\n\n/**\n * Assemble a full preview HTML page from rendered modules + CSS/JS.\n */\nexport function assemblePreview(opts: {\n renderedModules: string[];\n sharedCss?: string;\n moduleCssArray: string[];\n sharedJs?: string;\n moduleJsArray: string[];\n}): string {\n const styleBlocks = [\n opts.sharedCss || \"\",\n ...opts.moduleCssArray,\n ]\n .filter(Boolean)\n .map((css) => `<style>${css}</style>`)\n .join(\"\\n\");\n\n const scriptBlocks = [\n opts.sharedJs || \"\",\n ...opts.moduleJsArray,\n ]\n .filter(Boolean)\n .map((js) => `<script>${js}</script>`)\n .join(\"\\n\");\n\n const body = opts.renderedModules.join(\"\\n\");\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n${styleBlocks}\n<style>\nhtml{scroll-behavior:smooth}\n.vsp-img-wrap{position:relative;display:inline-block}\n.vsp-img-badge{position:absolute;top:8px;right:8px;background:rgba(0,0,0,.75);color:#fff;font:500 11px/1 -apple-system,sans-serif;padding:5px 8px;border-radius:4px;pointer-events:none;opacity:.85;white-space:nowrap;z-index:10}\n</style>\n</head>\n<body>\n${body}\n${scriptBlocks}\n<script>\n// Anchor link handler — smooth scroll to module sections\ndocument.addEventListener('click',function(e){\n var a=e.target.closest('a[href^=\"#\"]');\n if(!a)return;\n var id=a.getAttribute('href').slice(1);\n if(!id)return;\n var el=document.getElementById(id);\n if(el){\n e.preventDefault();\n el.scrollIntoView({behavior:'smooth',block:'start'});\n }\n});\n// Placeholder image badges\ndocument.querySelectorAll('img').forEach(function(img){\n var src=img.src||img.getAttribute('src')||'';\n if(src.indexOf('placehold')!==-1){\n var w=document.createElement('span');\n w.className='vsp-img-wrap';\n img.parentNode.insertBefore(w,img);\n w.appendChild(img);\n var b=document.createElement('span');\n b.className='vsp-img-badge';\n b.textContent='Placeholder — replace in HubSpot';\n w.appendChild(b);\n }\n});\n</script>\n</body>\n</html>`;\n}\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\n/**\n * Strip HubSpot-specific directives that have no meaning in local preview.\n */\nfunction stripDirectives(tpl: string): string {\n // Remove {% require_css %}, {% require_js %}, {% end_require_css %}, etc.\n tpl = tpl.replace(/\\{%[-\\s]*require_(css|js)\\b.*?%\\}/gs, \"\");\n tpl = tpl.replace(/\\{%[-\\s]*end_require_(css|js)\\s*%\\}/gs, \"\");\n\n // Remove {{ require_css(...) }}, {{ require_js(...) }}\n tpl = tpl.replace(/\\{\\{[-\\s]*require_(css|js)\\(.*?\\)\\s*\\}\\}/gs, \"\");\n\n // Remove {{ get_asset_url(...) }}\n tpl = tpl.replace(/\\{\\{[-\\s]*get_asset_url\\(.*?\\)\\s*\\}\\}/gs, \"\");\n\n // Remove {% dnd_area %}, {% dnd_section %}, {% dnd_column %}, {% dnd_row %} and their end tags\n tpl = tpl.replace(/\\{%[-\\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\\b.*?%\\}/gs, \"\");\n\n // Remove {% module ... %} tags (standalone module includes)\n tpl = tpl.replace(/\\{%[-\\s]*module\\b.*?%\\}/gs, \"\");\n\n // Remove {% extends %}, {% block %}, {% endblock %}, {% set %} — template-level\n tpl = tpl.replace(/\\{%[-\\s]*(extends|block|endblock|set)\\b.*?%\\}/gs, \"\");\n\n // Remove template annotations {# ... #}\n tpl = tpl.replace(/\\{#.*?#\\}/gs, \"\");\n\n // Remove {{ content.* }} page-level variables\n tpl = tpl.replace(/\\{\\{[-\\s]*content\\.\\w+.*?\\}\\}/gs, \"\");\n\n return tpl;\n}\n\n/**\n * Process {% for VAR in PATH %}...{% endfor %} loops.\n * Uses balanced tag matching to handle nested for-loops correctly.\n */\nfunction processForLoops(tpl: string, context: RenderContext): string {\n let result = tpl;\n let safety = 0;\n\n while (safety < 30) {\n safety++;\n const match = findOutermostFor(result);\n if (!match) break;\n\n const { varName, iterExpr, body, start, end } = match;\n const items = resolveIterable(iterExpr, context);\n\n let rendered = \"\";\n if (Array.isArray(items)) {\n rendered = items\n .map((item, index) => {\n const loopContext: RenderContext = {\n ...context,\n [varName]: item,\n loop: { index: index + 1, index0: index, first: index === 0, last: index === items.length - 1, length: items.length },\n };\n\n let out = processForLoops(body, loopContext);\n out = processConditionals(out, loopContext);\n out = resolveExpressions(out, loopContext);\n return out;\n })\n .join(\"\");\n }\n\n result = result.slice(0, start) + rendered + result.slice(end);\n }\n\n return result;\n}\n\n/**\n * Find the first outermost {% for %}...{% endfor %} block with balanced nesting.\n */\nfunction findOutermostFor(tpl: string): { varName: string; iterExpr: string; body: string; start: number; end: number } | null {\n const openTag = /\\{%[-\\s]*for\\s+(\\w+)\\s+in\\s+([\\w.]+(?:\\([^)]*\\))?(?:\\|[\\w(),\"' ]+)*)\\s*-?%\\}/g;\n const forOrEndfor = /\\{%[-\\s]*(for\\s|endfor)\\s*.*?-?%\\}/g;\n\n const firstOpen = openTag.exec(tpl);\n if (!firstOpen) return null;\n\n const varName = firstOpen[1];\n const iterExpr = firstOpen[2];\n const bodyStart = firstOpen.index + firstOpen[0].length;\n\n // Find matching endfor by counting nesting depth\n forOrEndfor.lastIndex = bodyStart;\n let depth = 1;\n let m: RegExpExecArray | null;\n\n while ((m = forOrEndfor.exec(tpl)) !== null) {\n if (m[1].startsWith(\"for\")) {\n depth++;\n } else {\n depth--;\n if (depth === 0) {\n const body = tpl.slice(bodyStart, m.index);\n return { varName, iterExpr, body, start: firstOpen.index, end: m.index + m[0].length };\n }\n }\n }\n\n return null; // Unmatched for-loop\n}\n\n/**\n * Process {% if EXPR %}...{% else %}...{% endif %} conditionals.\n * Supports {% elif %} as well.\n */\nfunction processConditionals(tpl: string, context: RenderContext): string {\n // Process from innermost out\n const ifPattern = /\\{%[-\\s]*if\\s+(.*?)\\s*-?%\\}([\\s\\S]*?)\\{%[-\\s]*endif\\s*-?%\\}/g;\n\n let result = tpl;\n let safety = 0;\n\n while (ifPattern.test(result) && safety < 50) {\n safety++;\n result = result.replace(ifPattern, (_match, condition: string, body: string) => {\n // Split on {% else %} and {% elif %}\n const elseMatch = body.split(/\\{%[-\\s]*else\\s*-?%\\}/);\n const ifBody = elseMatch[0];\n const elseBody = elseMatch[1] || \"\";\n\n // Check for {% elif %} (treat as nested if-else)\n const elifParts = ifBody.split(/\\{%[-\\s]*elif\\s+(.*?)\\s*-?%\\}/);\n\n if (elifParts.length > 1) {\n // Has elif branches\n if (evaluateCondition(condition, context)) {\n return elifParts[0];\n }\n // Check elif branches\n for (let i = 1; i < elifParts.length; i += 2) {\n const elifCondition = elifParts[i];\n const elifBody = elifParts[i + 1] || \"\";\n if (evaluateCondition(elifCondition, context)) {\n return elifBody;\n }\n }\n return elseBody;\n }\n\n if (evaluateCondition(condition, context)) {\n return ifBody;\n }\n return elseBody;\n });\n\n ifPattern.lastIndex = 0;\n }\n\n return result;\n}\n\n/**\n * Resolve all {{ expression }} references in the template.\n */\nfunction resolveExpressions(tpl: string, context: RenderContext): string {\n return tpl.replace(/\\{\\{[-\\s]*(.*?)[-\\s]*\\}\\}/g, (_match, expr: string) => {\n const trimmed = expr.trim();\n\n // Handle filters: {{ value|filter }}\n const filterParts = trimmed.split(\"|\");\n const path = filterParts[0].trim();\n\n let value = resolvePath(context, path);\n\n // Apply basic filters\n for (let i = 1; i < filterParts.length; i++) {\n value = applyFilter(value, filterParts[i].trim());\n }\n\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n });\n}\n\n/**\n * Clean up any remaining HubL tags that weren't handled.\n */\nfunction cleanupRemaining(tpl: string): string {\n // Remove any remaining {% ... %} tags\n tpl = tpl.replace(/\\{%.*?%\\}/gs, \"\");\n // Remove any remaining {{ ... }} that reference unknown paths\n tpl = tpl.replace(/\\{\\{.*?\\}\\}/gs, \"\");\n return tpl;\n}\n\n/**\n * Resolve an iterable expression for {% for %} loops.\n * Handles dotted paths (module.services) and range(start, end) calls.\n */\nfunction resolveIterable(expr: string, context: RenderContext): unknown {\n // Handle range(start, end) — with possible filter on args\n const rangeMatch = expr.match(/^range\\(\\s*(.+?)\\s*,\\s*(.+?)\\s*\\)$/);\n if (rangeMatch) {\n const start = resolveNumericArg(rangeMatch[1], context);\n const end = resolveNumericArg(rangeMatch[2], context);\n const arr: number[] = [];\n for (let i = start; i < end; i++) arr.push(i);\n return arr;\n }\n\n // Handle split('...') filter: \"value|split('\\n')\"\n const splitMatch = expr.match(/^(.+?)\\|split\\(['\"](.+?)['\"]\\)$/);\n if (splitMatch) {\n const val = resolvePath(context, splitMatch[1].trim());\n if (typeof val === \"string\") return val.split(splitMatch[2]);\n return [];\n }\n\n return resolvePath(context, expr);\n}\n\n/**\n * Resolve a numeric argument that may be a literal, a path, or a path|filter.\n */\nfunction resolveNumericArg(arg: string, context: RenderContext): number {\n const trimmed = arg.trim();\n\n // Apply filters (e.g. \"item.rating|int\")\n const filterParts = trimmed.split(\"|\");\n const path = filterParts[0].trim();\n\n // Literal number\n if (!isNaN(Number(path))) return Number(path);\n\n // Path lookup\n let value = resolvePath(context, path);\n for (let i = 1; i < filterParts.length; i++) {\n value = applyFilter(value, filterParts[i].trim());\n }\n return Number(value) || 0;\n}\n\n/**\n * Resolve a dot-path expression against a context object.\n * E.g. \"module.styles.bg_color.color\" → context.module.styles.bg_color.color\n */\nfunction resolvePath(context: RenderContext, path: string): unknown {\n const parts = path.split(\".\");\n let current: unknown = context;\n\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n if (typeof current !== \"object\") return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n}\n\n/**\n * Evaluate a simple condition expression.\n * Supports: path truthiness, \"not path\", \"path == value\", \"path != value\"\n */\nfunction evaluateCondition(expr: string, context: RenderContext): boolean {\n const trimmed = expr.trim();\n\n // Handle \"not\" prefix\n if (trimmed.startsWith(\"not \")) {\n return !evaluateCondition(trimmed.slice(4), context);\n }\n\n // Handle \"and\" / \"or\"\n if (trimmed.includes(\" and \")) {\n return trimmed.split(\" and \").every((part) => evaluateCondition(part, context));\n }\n if (trimmed.includes(\" or \")) {\n return trimmed.split(\" or \").some((part) => evaluateCondition(part, context));\n }\n\n // Handle comparison operators\n const eqMatch = trimmed.match(/^(.+?)\\s*(==|!=|>=|<=|>|<)\\s*(.+)$/);\n if (eqMatch) {\n const left = resolvePath(context, eqMatch[1].trim());\n const operator = eqMatch[2];\n let right: unknown = eqMatch[3].trim();\n\n // Parse right side: string literal, number, or path\n if (\n (typeof right === \"string\" && right.startsWith('\"') && right.endsWith('\"')) ||\n (typeof right === \"string\" && right.startsWith(\"'\") && right.endsWith(\"'\"))\n ) {\n right = (right as string).slice(1, -1);\n } else if (!isNaN(Number(right))) {\n right = Number(right);\n } else {\n right = resolvePath(context, right as string);\n }\n\n switch (operator) {\n case \"==\": return left == right;\n case \"!=\": return left != right;\n case \">\": return Number(left) > Number(right);\n case \"<\": return Number(left) < Number(right);\n case \">=\": return Number(left) >= Number(right);\n case \"<=\": return Number(left) <= Number(right);\n }\n }\n\n // Simple truthiness\n const value = resolvePath(context, trimmed);\n return isTruthy(value);\n}\n\n/**\n * Check HubL-style truthiness (empty strings and 0 are falsy).\n */\nfunction isTruthy(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (value === \"\") return false;\n if (value === 0) return false;\n if (value === false) return false;\n if (Array.isArray(value) && value.length === 0) return false;\n return true;\n}\n\n/**\n * Apply a basic HubL filter.\n */\nfunction applyFilter(value: unknown, filter: string): unknown {\n const str = value === null || value === undefined ? \"\" : String(value);\n\n // Handle filters with arguments: truncate(100), default(\"fallback\")\n const argMatch = filter.match(/^(\\w+)\\((.*)\\)$/);\n const filterName = argMatch ? argMatch[1] : filter;\n const filterArg = argMatch ? argMatch[2].replace(/^[\"']|[\"']$/g, \"\") : undefined;\n\n switch (filterName) {\n case \"escape\":\n case \"e\":\n return str.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\");\n case \"lower\":\n return str.toLowerCase();\n case \"upper\":\n return str.toUpperCase();\n case \"capitalize\":\n return str.charAt(0).toUpperCase() + str.slice(1);\n case \"trim\":\n return str.trim();\n case \"truncate\":\n if (filterArg) {\n const len = parseInt(filterArg, 10);\n return str.length > len ? str.slice(0, len) + \"...\" : str;\n }\n return str;\n case \"default\":\n return isTruthy(value) ? value : (filterArg ?? \"\");\n case \"length\":\n if (Array.isArray(value)) return value.length;\n return str.length;\n case \"join\":\n if (Array.isArray(value)) return value.join(filterArg ?? \", \");\n return str;\n case \"int\":\n case \"float\":\n return Number(str) || 0;\n case \"abs\":\n return Math.abs(Number(str));\n case \"round\":\n return Math.round(Number(str));\n default:\n // Unknown filter — pass through\n return value;\n }\n}\n","/**\n * Preview builder — assembles rendered HubL modules into a full HTML page.\n */\n\nimport {\n renderHubL,\n buildContextFromFields,\n assemblePreview,\n type FieldDef,\n} from \"../hubl/renderer.js\";\nimport { getSession, getOrderedModules } from \"./session.js\";\n\n/**\n * Build a full preview HTML page from the current session state.\n * Each module's HubL template is rendered with its fields.json defaults,\n * then assembled with shared CSS/JS into a complete page.\n */\nexport function buildPreviewHtml(): string {\n const session = getSession();\n if (!session) {\n return welcomePreview();\n }\n\n const modules = getOrderedModules();\n if (modules.length === 0) {\n return welcomePreview();\n }\n\n const renderedModules: string[] = [];\n const moduleCssArray: string[] = [];\n const moduleJsArray: string[] = [];\n\n for (const mod of modules) {\n // Skip template-like content that was accidentally stored as a module\n if (mod.moduleHtml.includes(\"dnd_area\") || mod.moduleHtml.includes(\"extends \")) {\n continue;\n }\n\n // Build context from fields.json defaults\n let context: { module: Record<string, unknown> };\n try {\n const fields: FieldDef[] = JSON.parse(mod.fieldsJson);\n context = { module: buildContextFromFields(fields) };\n } catch {\n context = { module: {} };\n }\n\n // Render HubL template with context\n const rendered = renderHubL(mod.moduleHtml, context);\n\n // Wrap each module in a container with id + data attribute for anchor links\n const anchorId = mod.moduleName.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-|-$/g, \"\");\n renderedModules.push(\n `<div class=\"vibespot-module\" id=\"${anchorId}\" data-module=\"${mod.moduleName}\">${rendered}</div>`\n );\n\n if (mod.moduleCss) moduleCssArray.push(mod.moduleCss);\n if (mod.moduleJs) moduleJsArray.push(mod.moduleJs);\n }\n\n return assemblePreview({\n renderedModules,\n sharedCss: session.sharedCss,\n moduleCssArray,\n sharedJs: session.sharedJs,\n moduleJsArray,\n });\n}\n\n/**\n * Static welcome screen — shown before first generation.\n */\nfunction welcomePreview(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n background: #0f0f14;\n color: #888;\n }\n .welcome {\n text-align: center;\n padding: 2rem;\n }\n .welcome__wave {\n font-size: 4rem;\n margin-bottom: 1.2rem;\n opacity: 0.4;\n animation: float 3s ease-in-out infinite;\n }\n @keyframes float {\n 0%, 100% { transform: translateY(0); }\n 50% { transform: translateY(-6px); }\n }\n .welcome__title {\n font-size: 1.4rem;\n font-weight: 600;\n color: #bbb;\n letter-spacing: 0.5px;\n margin-bottom: 0.4rem;\n }\n .welcome__sub {\n font-size: 1rem;\n color: #666;\n font-weight: 300;\n }\n</style>\n</head>\n<body>\n<div class=\"welcome\">\n <div class=\"welcome__wave\">\\u224B</div>\n <div class=\"welcome__title\">vibeSpot</div>\n <div class=\"welcome__sub\">Build Something Great</div>\n</div>\n</body>\n</html>`;\n}\n\n/**\n * Build a preview HTML page for a single module (used by the dashboard module library).\n */\nexport function buildModulePreviewHtml(moduleName: string): string {\n const session = getSession();\n if (!session) return \"\";\n\n // Find the module across all templates\n let mod: typeof session.modules[0] | undefined;\n for (const tpl of session.templates) {\n mod = tpl.modules.find((m) => m.moduleName === moduleName);\n if (mod) break;\n }\n // Fallback: check flat modules array\n if (!mod) {\n mod = session.modules.find((m) => m.moduleName === moduleName);\n }\n if (!mod) return \"\";\n\n let context: { module: Record<string, unknown> };\n try {\n const fields: FieldDef[] = JSON.parse(mod.fieldsJson);\n context = { module: buildContextFromFields(fields) };\n } catch {\n context = { module: {} };\n }\n\n const rendered = renderHubL(mod.moduleHtml, context);\n\n return assemblePreview({\n renderedModules: [\n `<div class=\"vibespot-module\" data-module=\"${mod.moduleName}\">${rendered}</div>`,\n ],\n sharedCss: session.sharedCss,\n moduleCssArray: mod.moduleCss ? [mod.moduleCss] : [],\n sharedJs: session.sharedJs,\n moduleJsArray: mod.moduleJs ? [mod.moduleJs] : [],\n });\n}\n\n// Note: The generating screen (spinner + rotating messages) is now\n// rendered client-side in preview.js to avoid an extra server round-trip.\n","/**\n * AI handler for vibe coding mode.\n * Supports multiple AI engines: Anthropic API, OpenAI API, Gemini API,\n * Claude Code, Gemini CLI, and Codex CLI.\n */\n\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport { spawn, execSync } from \"node:child_process\";\nimport { getConversionGuide, getDesignGuide, getContentGuide, getHubspotRules, getPageTypeGuide } from \"../ai/prompts.js\";\nimport { loadConfig, getApiKeyForEngine, type AIEngineType } from \"../utils/config.js\";\nimport {\n getSession,\n addMessage,\n updateModules,\n saveSession,\n getActiveTemplate,\n getModuleLibrary,\n type ChatMessage,\n} from \"./session.js\";\nimport type { ModuleFiles } from \"../ai/engine.js\";\n\n/**\n * Get the active template's page type and brand assets from the session.\n * Used when building the system prompt.\n */\nfunction getPromptContext(): { pageType?: string; brandAssets?: { styleguide?: string; brandvoice?: string } } {\n const session = getSession();\n if (!session) return {};\n const tpl = getActiveTemplate();\n return {\n pageType: tpl?.pageType,\n brandAssets: session.brandAssets,\n };\n}\n\n// ---------------------------------------------------------------------------\n// System prompt for vibe coding mode\n// ---------------------------------------------------------------------------\n\nfunction buildVibeSystemPrompt(\n conversionGuide: string,\n themeName: string,\n editMode: boolean = false,\n pageType?: string,\n brandAssets?: { styleguide?: string; brandvoice?: string }\n): string {\n const core = `You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.\n\n## Your Role\nYou generate native HubSpot CMS modules directly from user descriptions. Every module you create is immediately compatible with HubSpot's drag-and-drop page editor.\n\n## Output Format — CRITICAL\nYou MUST include a \\`\\`\\`vibespot-modules code block with ALL module data as JSON. This is the ONLY way modules get created. A text summary, table, or description of modules does NOT work — you must output the actual JSON.\n\n\\`\\`\\`vibespot-modules\n{\n \"modules\": [\n {\n \"moduleName\": \"Hero\",\n \"fieldsJson\": \"...\",\n \"metaJson\": \"...\",\n \"moduleHtml\": \"...\",\n \"moduleCss\": \"...\",\n \"moduleJs\": null\n }\n ],\n \"sharedCss\": \"...\",\n \"sharedJs\": \"...\"\n}\n\\`\\`\\`\n\nNEVER respond with only a text summary. The vibespot-modules JSON block is mandatory.\n\n## Rules\n- fieldsJson, metaJson must be valid JSON strings\n- moduleHtml uses HubL template syntax ({{ module.field_name }})\n- moduleCss is vanilla CSS (no Tailwind, no Sass)\n- moduleJs is optional vanilla JS (wrapped in IIFE)\n- NEVER use CDN imports (@import url(), <link> to external CDNs like Google Fonts, cdnjs, unpkg, jsdelivr)\n- For fonts, use system font stacks with good fallbacks. Define them as CSS custom properties in sharedCss:\n --font-heading: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --font-mono: 'SF Mono', SFMono-Regular, Consolas, monospace;\n- All assets must be self-contained — no external HTTP requests in CSS or HTML\n- Use \"type\": \"text\" (NEVER \"textarea\" — it's deprecated)\n- NEVER use \"name\": \"name\" (reserved) — use \"item_name\" instead\n- Wrap style fields in a \"styles\" group with \"tab\": \"STYLE\"\n- All CSS classes must use a unique prefix \"${themeName}-\" to avoid theme conflicts\n- Use BEM naming: ${themeName}-module__element--modifier\n- metaJson must include: host_template_types: [\"PAGE\"], is_available_for_new_content: true\n- For repeater groups, use \"occurrence\": { \"min\": 0, \"max\": 100 } and iterate with {% for %}\n- Color fields: type \"color\", default { \"color\": \"#hex\", \"opacity\": 100 }\n- Link fields: type \"link\", default { \"url\": { \"href\": \"#\", \"type\": \"EXTERNAL\" }, \"open_in_new_tab\": false, \"no_follow\": false }\n- Image fields: type \"image\", default { \"src\": \"https://placehold.co/800x600/1a1a2e/ffffff?text=Replace+in+HubSpot\", \"alt\": \"Placeholder image\", \"width\": 800, \"height\": 600 }\n\n## Images & Media\n- All images are managed through HubSpot's file manager — users will replace placeholders after publishing\n- ALWAYS use image fields (type \"image\") so users can swap images in the page editor\n- Use placehold.co URLs as defaults so the preview looks complete (e.g. https://placehold.co/800x600/1a1a2e/ffffff?text=Hero+Image)\n- In module.html, render images with: <img src=\"{{ module.field_name.src }}\" alt=\"{{ module.field_name.alt }}\" width=\"{{ module.field_name.width }}\" height=\"{{ module.field_name.height }}\">\n- For background images in CSS, use inline styles: style=\"background-image: url('{{ module.field_name.src }}')\"\n- Size placeholders appropriately for their context (hero: 1920x800, cards: 600x400, icons: 200x200, avatars: 150x150)\n\n## Navigation & Anchor Links\n- Each module is automatically wrapped with an id derived from its moduleName (lowercase, hyphens for spaces)\n- For navigation/menu modules, use anchor links that match module names: e.g. if a module is named \"Features\", link to href=\"#features\"\n- The id is the moduleName lowercased with non-alphanumeric chars replaced by hyphens (e.g. \"Pricing Cards\" → id=\"pricing-cards\")\n- Always include smooth scrolling behavior in navigation link clicks\n- For nav modules, make menu items editable via a repeater group with \"label\" (text) and \"anchor\" (text) fields\n\n## When modifying existing modules\nWhen the user asks to change something, include ONLY the modules that changed. Keep module names consistent.\nIf the change affects shared CSS or JS, include those too.`;\n\n // Page type context (included in both edit and full mode)\n const pageTypeSection = pageType ? getPageTypeGuide(pageType) : \"\";\n const pageTypePrompt = pageTypeSection ? `\\n\\n## Page Type Context\\n${pageTypeSection}` : \"\";\n\n // Brand assets (only in full mode to keep edits lean)\n let brandPrompt = \"\";\n if (!editMode && brandAssets) {\n if (brandAssets.styleguide) {\n brandPrompt += `\\n\\n## Brand Style Guide\\n${brandAssets.styleguide}`;\n }\n if (brandAssets.brandvoice) {\n brandPrompt += `\\n\\n## Brand Voice\\n${brandAssets.brandvoice}`;\n }\n }\n\n // For follow-up edits (modules already exist), skip the heavy guides\n if (editMode) {\n return core + pageTypePrompt + `\n\n## HubSpot CMS Rules\n${getHubspotRules()}`;\n }\n\n // Full prompt for initial generation\n return core + pageTypePrompt + brandPrompt + `\n\n## Design Quality\n- Use modern, clean design with proper spacing and typography\n- Include responsive CSS (mobile breakpoint at 767px)\n- Add scroll animation classes where appropriate\n- Use CSS custom properties for the design system\n- Make content editable through fields.json (headlines, text, colors, images, links)\n\n## Scroll Animation CSS Fallback (IMPORTANT)\nWhen using scroll-animate classes (opacity: 0 → visible), you MUST include a CSS-only fallback animation in sharedCss that auto-reveals elements after a delay. This ensures content is visible even if the JS file fails to load:\n\\`\\`\\`css\n@keyframes scroll-animate-fallback {\n to { opacity: 1; transform: none; }\n}\n.scroll-animate {\n animation: scroll-animate-fallback 0.1s 3s forwards;\n}\n.scroll-animate.visible {\n animation: none;\n}\n\\`\\`\\`\nThis makes elements appear after 3 seconds if JS never adds the .visible class. Once JS runs normally and adds .visible, the animation is cancelled.\n\n## Design Guide\n${getDesignGuide()}\n\n## Content & Copywriting Guide\n${getContentGuide()}\n\n## HubSpot CMS Rules\n${getHubspotRules()}\n\n## Conversion Guide Reference\n${conversionGuide}`;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Stream an AI response for a chat message.\n * Calls onChunk with text fragments as they arrive.\n * After the full response, parses module JSON blocks and updates the session.\n */\nexport async function handleGenerateStream(\n userMessage: string,\n onChunk: (chunk: string) => void,\n onStatus?: (status: string) => void\n): Promise<void> {\n const session = getSession();\n if (!session) throw new Error(\"No active session\");\n\n const config = loadConfig();\n const engine = config.aiEngine || detectDefaultEngine();\n\n switch (engine) {\n case \"anthropic-api\":\n case \"api\": {\n const apiKey = getApiKeyForEngine(\"anthropic-api\", config);\n if (!apiKey) throw new Error(\"Anthropic API key not configured. Open Settings to add one.\");\n await streamWithAnthropicAPI(userMessage, apiKey, session.themeName,\n config.anthropicApiModel || \"claude-sonnet-4-20250514\", onChunk);\n break;\n }\n case \"openai-api\": {\n const apiKey = getApiKeyForEngine(\"openai-api\", config);\n if (!apiKey) throw new Error(\"OpenAI API key not configured. Open Settings to add one.\");\n await streamWithOpenAIAPI(userMessage, apiKey, session.themeName,\n config.openaiApiModel || \"gpt-4o\", onChunk);\n break;\n }\n case \"gemini-api\": {\n const apiKey = getApiKeyForEngine(\"gemini-api\", config);\n if (!apiKey) throw new Error(\"Gemini API key not configured. Open Settings to add one.\");\n await streamWithGeminiAPI(userMessage, apiKey, session.themeName, onChunk);\n break;\n }\n case \"claude-code\":\n await generateWithClaudeCode(userMessage, session.themeName, onChunk, onStatus);\n break;\n case \"gemini-cli\":\n await generateWithCLI(\"gemini\", userMessage, session.themeName, onChunk, onStatus);\n break;\n case \"codex-cli\":\n await generateWithCLI(\"codex\", userMessage, session.themeName, onChunk, onStatus);\n break;\n default:\n throw new Error(`Unknown AI engine: ${engine}. Open Settings to configure one.`);\n }\n}\n\n/**\n * Detect the best available engine when none is configured.\n */\nfunction detectDefaultEngine(): AIEngineType {\n const config = loadConfig();\n if (config.anthropicApiKey || process.env.ANTHROPIC_API_KEY) return \"anthropic-api\";\n if (config.openaiApiKey || process.env.OPENAI_API_KEY) return \"openai-api\";\n if (config.geminiApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_AI_API_KEY) return \"gemini-api\";\n try { execSync(\"claude --version\", { stdio: \"pipe\" }); return \"claude-code\"; } catch {}\n try { execSync(\"gemini --version\", { stdio: \"pipe\" }); return \"gemini-cli\"; } catch {}\n try { execSync(\"codex --version\", { stdio: \"pipe\" }); return \"codex-cli\"; } catch {}\n throw new Error(\"No AI engine available. Open Settings to configure one.\");\n}\n\n/**\n * Non-streaming generation (used by REST API fallback).\n */\nexport async function handleGenerate(userMessage: string): Promise<string> {\n let fullResponse = \"\";\n await handleGenerateStream(userMessage, (chunk) => {\n fullResponse += chunk;\n });\n return fullResponse;\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\nfunction buildStateContext(): string {\n const session = getSession()!;\n let stateContext = \"\";\n if (session.modules.length > 0) {\n stateContext = \"\\n\\n## Current Module State\\n\";\n for (const mod of session.modules) {\n stateContext += `\\n### ${mod.moduleName}.module\\n`;\n stateContext += `**fields.json:**\\n\\`\\`\\`json\\n${mod.fieldsJson}\\n\\`\\`\\`\\n`;\n stateContext += `**module.html:**\\n\\`\\`\\`html\\n${mod.moduleHtml}\\n\\`\\`\\`\\n`;\n stateContext += `**module.css:**\\n\\`\\`\\`css\\n${mod.moduleCss}\\n\\`\\`\\`\\n`;\n if (mod.moduleJs) {\n stateContext += `**module.js:**\\n\\`\\`\\`js\\n${mod.moduleJs}\\n\\`\\`\\`\\n`;\n }\n }\n if (session.sharedCss) {\n stateContext += `\\n### Shared CSS\\n\\`\\`\\`css\\n${session.sharedCss}\\n\\`\\`\\`\\n`;\n }\n if (session.sharedJs) {\n stateContext += `\\n### Shared JS\\n\\`\\`\\`js\\n${session.sharedJs}\\n\\`\\`\\`\\n`;\n }\n }\n\n // Add module library context (modules from other templates the user can reuse)\n const library = getModuleLibrary();\n const currentModuleNames = new Set(session.modules.map((m) => m.moduleName));\n const otherModules = library.filter((e) => !currentModuleNames.has(e.module.moduleName));\n if (otherModules.length > 0) {\n stateContext += \"\\n\\n## Available modules in this theme (reusable)\\n\";\n for (const entry of otherModules) {\n stateContext += `- ${entry.module.moduleName} (used in: ${entry.usedIn.join(\", \")})\\n`;\n }\n stateContext += \"\\nThe user can ask to reuse any of these modules by name.\\n\";\n }\n\n return stateContext;\n}\n\nfunction buildMessagesWithContext(userMessage: string): Array<{ role: \"user\" | \"assistant\"; content: string }> {\n const session = getSession()!;\n const messages: Array<{ role: \"user\" | \"assistant\"; content: string }> =\n session.messages.slice(-20).map((m) => ({\n role: m.role,\n content: m.content,\n }));\n\n const stateContext = buildStateContext();\n const userContent = stateContext\n ? `${userMessage}\\n\\n---\\n${stateContext}`\n : userMessage;\n\n messages.push({ role: \"user\", content: userContent });\n return messages;\n}\n\n/** Callback for parse warnings — set by the WebSocket handler. */\nlet parseWarningCallback: ((warning: string) => void) | null = null;\n\nexport function setParseWarningCallback(cb: ((warning: string) => void) | null): void {\n parseWarningCallback = cb;\n}\n\nfunction finishResponse(fullResponse: string): void {\n addMessage(\"assistant\", fullResponse);\n parseAndApplyModules(fullResponse);\n saveSession();\n}\n\n// ---------------------------------------------------------------------------\n// Anthropic Streaming API\n// ---------------------------------------------------------------------------\n\nasync function streamWithAnthropicAPI(\n userMessage: string,\n apiKey: string,\n themeName: string,\n model: string,\n onChunk: (chunk: string) => void\n): Promise<void> {\n const client = new Anthropic({ apiKey });\n const conversionGuide = getConversionGuide();\n const session = getSession()!;\n const editMode = session.modules.length > 0;\n const messages = buildMessagesWithContext(userMessage);\n\n let fullResponse = \"\";\n\n const stream = client.messages.stream({\n model,\n max_tokens: 16384,\n system: buildVibeSystemPrompt(conversionGuide, themeName, editMode, getPromptContext().pageType, getPromptContext().brandAssets),\n messages,\n });\n\n for await (const event of stream) {\n if (\n event.type === \"content_block_delta\" &&\n event.delta.type === \"text_delta\"\n ) {\n const text = event.delta.text;\n fullResponse += text;\n onChunk(text);\n }\n }\n\n finishResponse(fullResponse);\n}\n\n// ---------------------------------------------------------------------------\n// OpenAI Streaming API (uses native fetch — no npm dependency)\n// ---------------------------------------------------------------------------\n\nasync function streamWithOpenAIAPI(\n userMessage: string,\n apiKey: string,\n themeName: string,\n model: string,\n onChunk: (chunk: string) => void\n): Promise<void> {\n const conversionGuide = getConversionGuide();\n const editMode = getSession()!.modules.length > 0;\n const messages = buildMessagesWithContext(userMessage);\n\n const response = await fetch(\"https://api.openai.com/v1/chat/completions\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n max_tokens: 16384,\n stream: true,\n messages: [\n { role: \"system\", content: buildVibeSystemPrompt(conversionGuide, themeName, editMode, getPromptContext().pageType, getPromptContext().brandAssets) },\n ...messages,\n ],\n }),\n });\n\n if (!response.ok) {\n const err = await response.text();\n throw new Error(`OpenAI API error (${response.status}): ${err}`);\n }\n\n let fullResponse = \"\";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\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]\") break;\n\n try {\n const parsed = JSON.parse(data);\n const delta = parsed.choices?.[0]?.delta?.content;\n if (delta) {\n fullResponse += delta;\n onChunk(delta);\n }\n } catch { /* skip malformed SSE lines */ }\n }\n }\n\n finishResponse(fullResponse);\n}\n\n// ---------------------------------------------------------------------------\n// Gemini Streaming API (uses native fetch — no npm dependency)\n// ---------------------------------------------------------------------------\n\nasync function streamWithGeminiAPI(\n userMessage: string,\n apiKey: string,\n themeName: string,\n onChunk: (chunk: string) => void\n): Promise<void> {\n const conversionGuide = getConversionGuide();\n const session = getSession()!;\n const editMode = session.modules.length > 0;\n const stateContext = buildStateContext();\n\n // Build conversation for Gemini format\n const contents: Array<{ role: string; parts: Array<{ text: string }> }> = [];\n\n // Add system instruction as first user message (Gemini uses systemInstruction separately)\n for (const m of session.messages.slice(-20)) {\n contents.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts: [{ text: m.content }],\n });\n }\n\n const userContent = stateContext\n ? `${userMessage}\\n\\n---\\n${stateContext}`\n : userMessage;\n contents.push({ role: \"user\", parts: [{ text: userContent }] });\n\n const model = \"gemini-2.0-flash\";\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse&key=${apiKey}`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n systemInstruction: { parts: [{ text: buildVibeSystemPrompt(conversionGuide, themeName, editMode, getPromptContext().pageType, getPromptContext().brandAssets) }] },\n contents,\n generationConfig: { maxOutputTokens: 16384 },\n }),\n });\n\n if (!response.ok) {\n const err = await response.text();\n throw new Error(`Gemini API error (${response.status}): ${err}`);\n }\n\n let fullResponse = \"\";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\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 fullResponse += text;\n onChunk(text);\n }\n } catch { /* skip malformed SSE lines */ }\n }\n }\n\n finishResponse(fullResponse);\n}\n\n// ---------------------------------------------------------------------------\n// CLI subprocess helper — sends prompt via stdin to avoid shell arg limits\n// ---------------------------------------------------------------------------\n\nfunction spawnCLI(\n bin: string,\n args: string[],\n prompt: string,\n onChunk?: (chunk: string) => void\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const env = { ...process.env };\n delete env.CLAUDECODE; // allow nesting when running inside Claude Code\n\n const child = spawn(bin, args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (d: Buffer) => {\n const chunk = d.toString();\n stdout += chunk;\n if (onChunk) onChunk(chunk);\n });\n child.stderr.on(\"data\", (d: Buffer) => { stderr += d.toString(); });\n\n child.on(\"error\", (err) =>\n reject(new Error(`${bin} failed to start: ${err.message}`))\n );\n\n child.on(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(\n `${bin} exited with code ${code}.\\n` +\n (stderr ? `Stderr: ${stderr.slice(0, 500)}\\n` : \"\") +\n (stdout ? `Output: ${stdout.slice(0, 500)}` : \"No output\")\n ));\n } else {\n resolve(stdout);\n }\n });\n\n // Send prompt via stdin to avoid shell argument length limits\n child.stdin.on(\"error\", () => {}); // handle EPIPE if child exits early\n child.stdin.write(prompt);\n child.stdin.end();\n\n // 10 min timeout (complex pages need time)\n setTimeout(() => {\n child.kill();\n reject(new Error(`${bin} timed out after 10 minutes`));\n }, 600_000);\n });\n}\n\n// ---------------------------------------------------------------------------\n// CLI status messages (shown while waiting for buffered CLI output)\n// ---------------------------------------------------------------------------\n\nconst CLI_STATUS_MESSAGES = [\n \"Analyzing your request...\",\n \"Reading the conversion guide...\",\n \"Planning module structure...\",\n \"Generating HTML templates...\",\n \"Writing CSS styles...\",\n \"Creating field definitions...\",\n \"Building module metadata...\",\n \"Assembling theme assets...\",\n \"Polishing the output...\",\n \"Almost there — hang tight...\",\n];\n\n// ---------------------------------------------------------------------------\n// Claude Code subprocess\n// ---------------------------------------------------------------------------\n\nasync function generateWithClaudeCode(\n userMessage: string,\n themeName: string,\n onChunk: (chunk: string) => void,\n onStatus?: (status: string) => void\n): Promise<void> {\n const conversionGuide = getConversionGuide();\n const config = loadConfig();\n const editMode = getSession()!.modules.length > 0;\n\n let prompt = buildVibeSystemPrompt(conversionGuide, themeName, editMode, getPromptContext().pageType, getPromptContext().brandAssets);\n prompt += \"\\n\\n## User Request\\n\" + userMessage;\n prompt += buildStateContext();\n\n const args = [\"--print\"];\n if (config.claudeCodeModel) args.push(\"--model\", config.claudeCodeModel);\n\n // Claude --print buffers output until completion, so send periodic\n // status updates so the user knows what's happening\n let statusIndex = 0;\n const sendStatus = onStatus || (() => {});\n sendStatus(CLI_STATUS_MESSAGES[0]);\n\n const heartbeat = setInterval(() => {\n statusIndex++;\n const msg = CLI_STATUS_MESSAGES[Math.min(statusIndex, CLI_STATUS_MESSAGES.length - 1)];\n sendStatus(msg);\n }, 6000);\n\n try {\n const result = await spawnCLI(\"claude\", args, prompt, (chunk) => {\n onChunk(chunk);\n });\n finishResponse(result);\n } finally {\n clearInterval(heartbeat);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Generic CLI subprocess (Gemini CLI, Codex CLI)\n// ---------------------------------------------------------------------------\n\nasync function generateWithCLI(\n cli: \"gemini\" | \"codex\",\n userMessage: string,\n themeName: string,\n onChunk: (chunk: string) => void,\n onStatus?: (status: string) => void\n): Promise<void> {\n const conversionGuide = getConversionGuide();\n const editMode = getSession()!.modules.length > 0;\n\n let prompt = buildVibeSystemPrompt(conversionGuide, themeName, editMode, getPromptContext().pageType, getPromptContext().brandAssets);\n prompt += \"\\n\\n## User Request\\n\" + userMessage;\n prompt += buildStateContext();\n\n let bin: string;\n let args: string[];\n if (cli === \"gemini\") {\n bin = \"gemini\";\n args = [];\n } else {\n bin = \"codex\";\n args = [\"exec\", \"--full-auto\"];\n }\n\n // CLI may buffer output — send status updates so user knows what's happening\n let statusIndex = 0;\n const sendStatus = onStatus || (() => {});\n sendStatus(CLI_STATUS_MESSAGES[0]);\n\n const heartbeat = setInterval(() => {\n statusIndex++;\n const msg = CLI_STATUS_MESSAGES[Math.min(statusIndex, CLI_STATUS_MESSAGES.length - 1)];\n sendStatus(msg);\n }, 6000);\n\n try {\n const result = await spawnCLI(bin, args, prompt, (chunk) => {\n onChunk(chunk);\n });\n finishResponse(result);\n } finally {\n clearInterval(heartbeat);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Module parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Try JSON.parse, and if it fails, attempt to repair common AI JSON issues\n * (unescaped quotes inside string values) and retry.\n */\nfunction tryParseJSON(raw: string): unknown | null {\n try {\n return JSON.parse(raw);\n } catch {\n // Fall through to repair\n }\n\n // Repair: the AI often forgets to escape literal \" chars inside JSON string values\n // (e.g. \">\"{{ some_var }}\"\" where the inner quotes are decorative HTML).\n // Strategy: iteratively find the parse error position, escape the offending quote, retry.\n let repaired = raw;\n for (let attempt = 0; attempt < 20; attempt++) {\n try {\n return JSON.parse(repaired);\n } catch (err) {\n if (!(err instanceof SyntaxError)) return null;\n // Extract position from error message\n const posMatch = /position (\\d+)/.exec(err.message);\n if (!posMatch) return null;\n const pos = parseInt(posMatch[1], 10);\n // Check if there's an unescaped quote nearby that should be escaped\n // Look backwards from pos for the offending \"\n const searchStart = Math.max(0, pos - 5);\n const nearSlice = repaired.slice(searchStart, pos + 1);\n const lastQuote = nearSlice.lastIndexOf('\"');\n if (lastQuote === -1) return null;\n const absPos = searchStart + lastQuote;\n // Don't escape if preceded by backslash (already escaped)\n if (absPos > 0 && repaired[absPos - 1] === \"\\\\\") return null;\n // Escape this quote\n repaired = repaired.slice(0, absPos) + '\\\\\"' + repaired.slice(absPos + 1);\n // Shift won't cause infinite loop because we move past the fixed position\n }\n }\n return null;\n}\n\n/**\n * Parse vibespot-modules JSON blocks from an AI response and update the session.\n */\nfunction parseAndApplyModules(response: string): void {\n let modulesApplied = false;\n\n // Look for ```vibespot-modules ... ``` blocks\n const blockPattern = /```vibespot-modules\\s*\\n([\\s\\S]*?)```/g;\n let match;\n\n while ((match = blockPattern.exec(response)) !== null) {\n try {\n const data = tryParseJSON(match[1]);\n if (!data || typeof data !== \"object\") throw new Error(\"Invalid JSON after repair\");\n\n const obj = data as Record<string, unknown>;\n if (obj.modules && Array.isArray(obj.modules)) {\n const modules: ModuleFiles[] = obj.modules.map((m: Record<string, unknown>) => ({\n moduleName: String(m.moduleName || \"\"),\n fieldsJson: typeof m.fieldsJson === \"string\"\n ? m.fieldsJson\n : JSON.stringify(m.fieldsJson, null, 2),\n metaJson: typeof m.metaJson === \"string\"\n ? m.metaJson\n : JSON.stringify(m.metaJson, null, 2),\n moduleHtml: String(m.moduleHtml || \"\"),\n moduleCss: String(m.moduleCss || \"\"),\n moduleJs: m.moduleJs ? String(m.moduleJs) : undefined,\n }));\n\n updateModules({\n modules,\n sharedCss: obj.sharedCss !== undefined ? String(obj.sharedCss) : undefined,\n sharedJs: obj.sharedJs !== undefined ? String(obj.sharedJs) : undefined,\n });\n modulesApplied = true;\n }\n } catch (err) {\n console.warn(\"[parse] Failed to parse vibespot-modules block:\", err instanceof Error ? err.message : String(err));\n console.warn(\"[parse] Block content (first 200 chars):\", match[1].slice(0, 200));\n }\n }\n\n // Also try to find standalone JSON that looks like module data\n if (!modulesApplied) {\n const jsonPattern = /```(?:json)?\\s*\\n(\\{[\\s\\S]*?\"modules\"\\s*:\\s*\\[[\\s\\S]*?\\})\\s*```/g;\n while ((match = jsonPattern.exec(response)) !== null) {\n try {\n const data = tryParseJSON(match[1]);\n if (!data || typeof data !== \"object\") throw new Error(\"Invalid JSON after repair\");\n const obj = data as Record<string, unknown>;\n if (obj.modules && Array.isArray(obj.modules)) {\n const modules: ModuleFiles[] = obj.modules.map((m: Record<string, unknown>) => ({\n moduleName: String(m.moduleName || \"\"),\n fieldsJson: typeof m.fieldsJson === \"string\"\n ? m.fieldsJson\n : JSON.stringify(m.fieldsJson, null, 2),\n metaJson: typeof m.metaJson === \"string\"\n ? m.metaJson\n : JSON.stringify(m.metaJson, null, 2),\n moduleHtml: String(m.moduleHtml || \"\"),\n moduleCss: String(m.moduleCss || \"\"),\n moduleJs: m.moduleJs ? String(m.moduleJs) : undefined,\n }));\n\n updateModules({\n modules,\n sharedCss: obj.sharedCss !== undefined ? String(obj.sharedCss) : undefined,\n sharedJs: obj.sharedJs !== undefined ? String(obj.sharedJs) : undefined,\n });\n modulesApplied = true;\n }\n } catch (err) {\n console.warn(\"[parse] Failed to parse JSON module block:\", err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n // Warn user if the response looked like it should contain modules but parsing failed\n if (!modulesApplied) {\n const hasModuleRef = response.includes(\"vibespot-modules\") || response.includes('\"modules\"');\n // Detect when the AI describes modules in prose (e.g. a summary table) without providing JSON\n const describesProse = /\\bmodule|modul/i.test(response) &&\n (/\\bcreated?\\b|\\berstellt\\b|\\bgenerat/i.test(response) || /\\|.*\\|.*\\|/m.test(response));\n\n if (hasModuleRef || describesProse) {\n const msg = hasModuleRef\n ? \"Module changes could not be applied — the AI response contained invalid JSON. Try sending your request again.\"\n : \"The AI described modules but did not include the required structured data. Try sending your request again.\";\n console.warn(\"[parse] \" + msg);\n if (parseWarningCallback) {\n parseWarningCallback(msg);\n }\n }\n }\n}\n","/**\n * Background process manager for long-running CLI operations\n * (tool installation, OAuth flows, etc.)\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\n\nexport interface ProcessJob {\n id: string;\n command: string;\n description: string;\n status: \"running\" | \"completed\" | \"failed\";\n output: string;\n exitCode: number | null;\n startedAt: number;\n completedAt: number | null;\n}\n\nconst jobs = new Map<string, ProcessJob>();\n\nexport function startJob(\n command: string,\n description: string,\n opts?: { cwd?: string; env?: Record<string, string>; timeout?: number }\n): string {\n const id = `job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;\n\n const job: ProcessJob = {\n id,\n command,\n description,\n status: \"running\",\n output: \"\",\n exitCode: null,\n startedAt: Date.now(),\n completedAt: null,\n };\n\n jobs.set(id, job);\n\n const parts = command.split(\" \");\n const child: ChildProcess = spawn(parts[0], parts.slice(1), {\n cwd: opts?.cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...opts?.env },\n shell: true,\n });\n\n child.stdout?.on(\"data\", (d: Buffer) => {\n job.output += d.toString();\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n job.output += d.toString();\n });\n\n child.on(\"close\", (code) => {\n job.status = code === 0 ? \"completed\" : \"failed\";\n job.exitCode = code;\n job.completedAt = Date.now();\n });\n\n child.on(\"error\", (err) => {\n job.status = \"failed\";\n job.output += `\\nProcess error: ${err.message}`;\n job.completedAt = Date.now();\n });\n\n // Timeout safety net\n const timeout = opts?.timeout || 300_000;\n setTimeout(() => {\n if (job.status === \"running\") {\n child.kill();\n job.status = \"failed\";\n job.output += \"\\nProcess timed out\";\n job.completedAt = Date.now();\n }\n }, timeout);\n\n return id;\n}\n\nexport function getJob(id: string): ProcessJob | undefined {\n return jobs.get(id);\n}\n\nexport function cleanupOldJobs(): void {\n const cutoff = Date.now() - 30 * 60 * 1000;\n for (const [id, job] of jobs) {\n if (job.completedAt && job.completedAt < cutoff) {\n jobs.delete(id);\n }\n }\n}\n\n// Clean up periodically\nsetInterval(cleanupOldJobs, 10 * 60 * 1000);\n\n// ---------------------------------------------------------------------------\n// Streaming jobs — same as regular jobs but also emit output chunks to listeners\n// ---------------------------------------------------------------------------\n\nexport interface StreamingJob extends ProcessJob {\n listeners: Set<(chunk: string) => void>;\n}\n\nexport function startStreamingJob(\n command: string,\n description: string,\n opts?: { cwd?: string; env?: Record<string, string>; timeout?: number }\n): string {\n const id = `job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;\n\n const job: StreamingJob = {\n id,\n command,\n description,\n status: \"running\",\n output: \"\",\n exitCode: null,\n startedAt: Date.now(),\n completedAt: null,\n listeners: new Set(),\n };\n\n jobs.set(id, job);\n\n const parts = command.split(\" \");\n const child: ChildProcess = spawn(parts[0], parts.slice(1), {\n cwd: opts?.cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...opts?.env },\n shell: true,\n });\n\n const emitChunk = (chunk: string) => {\n for (const listener of job.listeners) {\n try { listener(chunk); } catch { /* listener error — ignore */ }\n }\n };\n\n child.stdout?.on(\"data\", (d: Buffer) => {\n const chunk = d.toString();\n job.output += chunk;\n emitChunk(chunk);\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n const chunk = d.toString();\n job.output += chunk;\n emitChunk(chunk);\n });\n\n child.on(\"close\", (code) => {\n job.status = code === 0 ? \"completed\" : \"failed\";\n job.exitCode = code;\n job.completedAt = Date.now();\n });\n\n child.on(\"error\", (err) => {\n job.status = \"failed\";\n job.output += `\\nProcess error: ${err.message}`;\n job.completedAt = Date.now();\n });\n\n // Timeout safety net\n const timeout = opts?.timeout || 300_000;\n setTimeout(() => {\n if (job.status === \"running\") {\n child.kill();\n job.status = \"failed\";\n job.output += \"\\nProcess timed out\";\n job.completedAt = Date.now();\n }\n }, timeout);\n\n return id;\n}\n\nexport function addJobListener(jobId: string, listener: (chunk: string) => void): void {\n const job = jobs.get(jobId);\n if (!job || !(\"listeners\" in job)) return;\n\n const streamingJob = job as StreamingJob;\n\n // Send buffered output first\n if (streamingJob.output) {\n try { listener(streamingJob.output); } catch { /* ignore */ }\n }\n\n streamingJob.listeners.add(listener);\n}\n\nexport function removeJobListener(jobId: string, listener: (chunk: string) => void): void {\n const job = jobs.get(jobId);\n if (!job || !(\"listeners\" in job)) return;\n\n (job as StreamingJob).listeners.delete(listener);\n}\n","import { buildProgram } from \"./cli/program.js\";\n\nconst program = buildProgram();\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"],"mappings":"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","names":["join","homedir","readFileSync","existsSync","join","p","join","join","homedir","existsSync","readFileSync","intro","outro","note","text","confirm","select","spinner","log","intro","note","confirm","spinner","select","text","outro","readdirSync","join","join","readdirSync","intro","text","s","spinner","note","confirm","outro","join","readdirSync","intro","select","join","text","spinner","readdirSync","outro","join","readdirSync","join","basename","readdirSync","statSync","writeFileSync","join","writeFileSync","basename","readdirSync","statSync","join","readdirSync","join","p","readdirSync","spawn","join","readdirSync","statSync","spawn","join","readdirSync","statSync","spawn","join","readdirSync","statSync","spawn","join","readdirSync","statSync","intro","note","spinner","confirm","join","outro","readdirSync","join","join","readdirSync","rmSync","join","readdirSync","rmSync","hex","intro","spinner","join","outro","confirm","execSync","rmSync","basename","intro","note","confirm","execSync","log","basename","rmSync","outro","text","confirm","intro","log","outro","join","existsSync","execSync","chalk","readFileSync","existsSync","readdirSync","rmSync","renameSync","join","extname","basename","homedir","execSync","readFileSync","readdirSync","existsSync","writeFileSync","mkdirSync","rmSync","join","homedir","existsSync","writeFileSync","mkdirSync","join","existsSync","join","mkdirSync","writeFileSync","join","homedir","existsSync","readdirSync","mkdirSync","writeFileSync","readFileSync","rmSync","f","Anthropic","spawn","execSync","execSync","Anthropic","text","spawn","spawn","join","homedir","execSync","existsSync","readdirSync","rmSync","renameSync","basename","configUpdate","jobId","readFileSync","session","extname","chalk","execSync","join","existsSync","program"]}
|