hubvibes 0.1.9

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.
@@ -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/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/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\";\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name(\"hubvibes\")\n .description(\n \"Convert Lovable/React landing pages to HubSpot CMS — AI-powered CLI tool\"\n )\n .version(\"0.1.9\")\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: \"#00BDA5\",\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.1.9\";\n\nexport function printBanner() {\n const o = theme.accent; // HubSpot orange for \"hub\"\n const v = theme.vibes; // purple for \"Vibes\" + wave\n const m = theme.muted;\n\n // Block-pixel ASCII art: \"hub ≋ Vibes\"\n const lines = [\n `${o(\"██ ██ ██ ██ █████ \")}${v(\" ≋≋≋≋≋≋≋≋ \")}${v(\"██ ██ ██ █████ ▄▄▄▄▄ ▄▄▄▄▄\")}`,\n `${o(\"██ ██ ██ ██ ██ ██\")}${v(\" ≋≋≋≋≋≋ \")}${v(\"██ ██ ██ ██ ██ ██ ██ \")}`,\n `${o(\"██▀▀██ ██ ██ █████ \")}${v(\" ≋≋≋≋ \")}${v(\"██ ██ ██ █████ ████ ▀▀▀▄ \")}`,\n `${o(\"██ ██ ██ ██ ██ ██\")}${v(\" ≋≋≋≋≋≋ \")}${v(\" █▄▄█▀ ██ ██ ██ ██ ██\")}`,\n `${o(\"██ ██ ████ █████ \")}${v(\" ≋≋≋≋≋≋≋≋ \")}${v(\" ▀▀▀ ██ █████ ▀▀▀▀▀ ▀▀▀▀ \")}`,\n ];\n\n console.log();\n for (const line of lines) {\n console.log(` ${line}`);\n }\n console.log();\n console.log(` ${m(\"Lovable / React → HubSpot CMS\")} ${theme.dim(`v${VERSION}`)}`);\n console.log();\n}\n","import { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { run } from \"./shell.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 function detectClaudeCode(): ToolInfo {\n const result = run(\"claude --version\");\n return {\n name: \"Claude Code\",\n found: result.success,\n version: result.stdout,\n path: run(\"which claude\").stdout,\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 function detectHubSpotAuth(): {\n authenticated: boolean;\n portalName: string;\n portalId: string;\n} {\n const result = run(\"hs accounts list\");\n if (!result.success || !result.stdout) {\n return { authenticated: false, portalName: \"\", portalId: \"\" };\n }\n\n // Parse portal info from \"hs accounts list\" output\n // Default account line: \"Account: name [standard] (123456)\"\n const defaultMatch = result.stdout.match(/Account:\\s*(.+?)\\s*\\((\\d+)\\)/);\n if (defaultMatch) {\n return {\n authenticated: true,\n portalName: defaultMatch[1].trim(),\n portalId: defaultMatch[2].trim(),\n };\n }\n\n // Table row: \"name [standard] 123456 personalaccesskey\"\n const lines = result.stdout.split(\"\\n\");\n for (const line of lines) {\n const tableMatch = line.match(/^\\s*(.+?)\\s{2,}(\\d{5,})\\s/);\n if (tableMatch && !/Account ID/i.test(line)) {\n return {\n authenticated: true,\n portalName: tableMatch[1].trim(),\n portalId: tableMatch[2].trim(),\n };\n }\n }\n\n return {\n authenticated: result.stdout.length > 0,\n portalName: \"\",\n portalId: \"\",\n };\n}\n\nexport function detectGeminiCLI(): ToolInfo {\n const result = run(\"gemini --version\");\n return {\n name: \"Gemini CLI\",\n found: result.success,\n version: result.stdout,\n path: run(\"which gemini\").stdout,\n };\n}\n\nexport function detectCodexCLI(): ToolInfo {\n const result = run(\"codex --version\");\n return {\n name: \"OpenAI Codex CLI\",\n found: result.success,\n version: result.stdout,\n path: run(\"which codex\").stdout,\n };\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","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 = \"claude-code\" | \"api\" | \"gemini-cli\" | \"codex-cli\";\n\nexport interface HubVibesConfig {\n aiEngine?: AIEngineType;\n anthropicApiKey?: string;\n lastThemePath?: string;\n lastSourcePath?: string;\n}\n\nconst CONFIG_DIR = join(homedir(), \".hubvibes\");\nconst CONFIG_PATH = join(CONFIG_DIR, \"config.json\");\n\nexport function loadConfig(): HubVibesConfig {\n if (!fileExists(CONFIG_PATH)) return {};\n\n try {\n return JSON.parse(readFile(CONFIG_PATH));\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(config: HubVibesConfig): 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 \"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\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, \"..\", \"hubvibes-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 } 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, \"..\", \"hubvibes-conversion.log\");\n try {\n const timestamp = new Date().toISOString();\n const logContent = [\n `=== hubVibes 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\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 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## 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\", [\"--quiet\", \"--auto-edit\", 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 { readdirSync, rmSync } from \"node:fs\";\nimport { run } from \"../utils/shell.js\";\nimport { readFile, writeFile, fileExists } from \"../utils/fs.js\";\nimport * as ui from \"../prompts/prompter.js\";\nimport { theme } from \"../cli/theme.js\";\n\ninterface UploadError {\n file: string;\n message: string;\n fixable: boolean;\n}\n\n/** Count \"Uploaded file\" lines in hs upload output */\nfunction countUploadedFiles(output: string): number {\n return (output.match(/^Uploaded file /gm) || []).length;\n}\n\nfunction parseUploadErrors(output: string): UploadError[] {\n const errors: UploadError[] = [];\n\n // textarea field type error\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 // name field reserved\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 // now() function\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 // HubDB requires CMS Hub Pro/Enterprise\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 // Link field invalid default value\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 \"${fieldMatch?.[1] || \"unknown\"}\" has invalid default value`,\n fixable: true,\n });\n }\n\n // Deserialization error (catch-all for fields.json issues)\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 return errors;\n}\n\nfunction autoFix(themePath: string, error: UploadError): boolean {\n if (error.message.includes(\"textarea\")) {\n return fixTextareaFields(themePath);\n }\n if (error.message.includes(\"reserved field name\")) {\n return fixReservedNames(themePath);\n }\n if (error.message.includes(\"now()\")) {\n return fixNowFunction(themePath);\n }\n if (error.message.includes(\"HubDB\")) {\n return fixHubDbTemplates(themePath);\n }\n if (error.message.includes(\"invalid default value\") || error.message.includes(\"deserialization\")) {\n return fixLinkFieldDefaults(themePath);\n }\n return false;\n}\n\nfunction fixTextareaFields(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n\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\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\n return fixed;\n}\n\nfunction fixReservedNames(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n\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\n let content = readFile(fieldsPath);\n // Replace \"name\": \"name\" with \"name\": \"item_name\"\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\n return fixed;\n}\n\nfunction fixNowFunction(themePath: string): boolean {\n let fixed = false;\n const modulesDir = join(themePath, \"modules\");\n\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\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\n return fixed;\n}\n\nfunction 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\n return fixed;\n}\n\nfunction 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\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\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\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 upload \"${themePath}\" \"${themeName}\"`, {\n cwd: join(themePath, \"..\"),\n });\n\n // Combine stdout + stderr — hs 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 = autoFix(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 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 upload` manually to see detailed errors.\"\n );\n return false;\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 `hubvibes init` first or use the full wizard with `hubvibes`.\"\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 hasAnthropicKey,\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\n const hs = detectHubSpotCLI();\n if (!hs.found) {\n ui.logError(\"HubSpot CLI — not installed\");\n ui.log(\" Install: npm install -g @hubspot/cli\");\n issues++;\n } else {\n ui.logSuccess(`HubSpot CLI v${hs.version}`);\n }\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 issues++;\n } else {\n ui.logSuccess(\n `HubSpot portal${auth.portalName ? `: ${auth.portalName}` : \"\"} (ID: ${auth.portalId})`\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 key\n if (hasAnthropicKey()) {\n ui.logSuccess(\"Anthropic API key set\");\n } else {\n ui.log(theme.muted(\"Anthropic API key — not set\"));\n }\n\n // Config\n const config = loadConfig();\n const engineLabels: Record<string, string> = {\n \"claude-code\": \"Claude Code\",\n \"api\": \"Anthropic 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 && !hasAnthropicKey()) {\n ui.logWarn(\"No AI engine available\");\n ui.log(\" Option 1: Install Claude Code — https://claude.ai/code\");\n ui.log(\" Option 2: Install Gemini CLI — https://github.com/google-gemini/gemini-cli\");\n ui.log(\" Option 3: Install OpenAI Codex — https://github.com/openai/codex\");\n ui.log(\" Option 4: Set ANTHROPIC_API_KEY environment variable\");\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","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","homedir","intro","outro","note","text","confirm","select","spinner","log","intro","note","confirm","spinner","select","text","outro","join","join","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","readdirSync","rmSync","join","readdirSync","rmSync","intro","spinner","outro","confirm","execSync","rmSync","basename","intro","note","confirm","execSync","log","basename","rmSync","outro","text","confirm","intro","log","outro","program"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "hubvibes",
3
+ "version": "0.1.9",
4
+ "description": "Convert Lovable/React landing pages to HubSpot CMS — AI-powered CLI tool",
5
+ "type": "module",
6
+ "bin": {
7
+ "hubvibes": "bin/hubvibes.mjs"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "bin",
13
+ "assets"
14
+ ],
15
+ "scripts": {
16
+ "dev": "tsx src/index.ts",
17
+ "build": "tsup",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "dependencies": {
21
+ "@anthropic-ai/sdk": "^0.39.0",
22
+ "@clack/prompts": "^0.9.1",
23
+ "chalk": "^5.4.1",
24
+ "commander": "^13.1.0",
25
+ "execa": "^9.5.2"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.0.0",
29
+ "tsup": "^8.4.0",
30
+ "tsx": "^4.19.0",
31
+ "typescript": "^5.7.0"
32
+ },
33
+ "keywords": [
34
+ "hubspot",
35
+ "lovable",
36
+ "react",
37
+ "cms",
38
+ "converter",
39
+ "landing-page",
40
+ "cli"
41
+ ],
42
+ "author": "Boris Michel",
43
+ "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/borismichel/hubvibes.git"
47
+ }
48
+ }