vibespot 1.6.4 → 1.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- var rg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{for(var n in t)rg(e,n,{get:t[n],enumerable:!0})};import xv from"path";import{fileURLToPath as Cv}from"url";var y=N(()=>{"use strict"});import pn from"chalk";function Tt(e){return Ba?pn:pn.hex(e)}var pt,Ba,I,gt=N(()=>{"use strict";y();pt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Ba=!!process.env.NO_COLOR;I={accent:Tt(pt.accent),accentBright:Tt(pt.accentBright),success:Tt(pt.success),info:Tt(pt.info),warn:Tt(pt.warn),error:Tt(pt.error),muted:Tt(pt.muted),vibes:Tt(pt.vibes),heading:Ba?pn.bold:pn.bold.hex(pt.accent),command:Tt(pt.accentBright),dim:pn.dim,bold:pn.bold}});import{readFileSync as Ii,writeFileSync as ag,mkdirSync as Ha,existsSync as Ws}from"fs";import{dirname as Ua,join as At}from"path";import{fileURLToPath as lg}from"url";function P(e){return Ii(e,"utf-8")}function B(e,t){Ha(Ua(e),{recursive:!0}),ag(e,t,"utf-8")}function x(e){return Ws(e)}function Re(e){Ha(e,{recursive:!0})}function hn(e){let t=[At(fn,"../../assets",e),At(fn,"../assets",e),At(process.cwd(),"assets",e)];for(let n of t)if(Ws(n))return n;throw new Error(`Asset not found: ${e}`)}function yn(){if(gn)return gn;let e=[At(fn,"../../package.json"),At(fn,"../package.json"),At(process.cwd(),"package.json")];for(let t of e)if(Ws(t))try{let n=JSON.parse(Ii(t,"utf-8"));if(n.name==="vibespot"&&n.version)return gn=n.version,gn}catch{}return gn="dev",gn}function Ga(){if(Gs)return Gs;let e=[At(fn,"../../CHANGELOG.md"),At(fn,"../CHANGELOG.md"),At(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Ws(t))try{return Gs=Ii(t,"utf-8"),Gs}catch{}return""}var fn,gn,Gs,oe=N(()=>{"use strict";y();fn=Ua(lg(import.meta.url));gn="";Gs=""});import{execSync as Wa,execFileSync as cg}from"child_process";function ie(e,t={}){try{return{stdout:Wa(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Z(e,t={}){try{return{stdout:cg("git",e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Ka(e,t={}){try{return Wa(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var qt=N(()=>{"use strict";y()});var Ya={};Ge(Ya,{addHubSpotAccount:()=>qn,getActiveHubSpotAccount:()=>Lt,getApiKeyForEngine:()=>Fe,getConfigDir:()=>mg,getHubSpotPak:()=>Le,isCliToolEnabled:()=>st,loadConfig:()=>R,maskApiKey:()=>Vs,removeHubSpotAccount:()=>Pi,saveConfig:()=>Y,setActiveHubSpotAccount:()=>Ni,setCliToolEnabled:()=>Ri});import{join as Va}from"path";import{homedir as dg}from"os";import{chmodSync as ug}from"fs";function R(){let e={};if(x(Ks))try{e=JSON.parse(P(Ks)),e.aiEngine==="api"&&(e.aiEngine="anthropic-api")}catch{e={}}return process.env.VIBESPOT_AI_ENGINE&&!e.aiEngine&&(e.aiEngine=process.env.VIBESPOT_AI_ENGINE),process.env.ANTHROPIC_API_KEY&&!e.anthropicApiKey&&(e.anthropicApiKey=process.env.ANTHROPIC_API_KEY),process.env.OPENAI_API_KEY&&!e.openaiApiKey&&(e.openaiApiKey=process.env.OPENAI_API_KEY),(process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)&&!e.geminiApiKey&&(e.geminiApiKey=process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY),process.env.LANGDOCK_API_KEY&&!e.langdockApiKey&&(e.langdockApiKey=process.env.LANGDOCK_API_KEY),process.env.LANGDOCK_BASE_URL&&!e.langdockBaseUrl&&(e.langdockBaseUrl=process.env.LANGDOCK_BASE_URL),process.env.LANGDOCK_PROVIDER&&!e.langdockProvider&&(e.langdockProvider=process.env.LANGDOCK_PROVIDER),process.env.FIGMA_TOKEN&&!e.figmaToken&&(e.figmaToken=process.env.FIGMA_TOKEN),process.env.VIBESPOT_AGENTIC_MODE!==void 0&&e.agenticMode===void 0&&(e.agenticMode=process.env.VIBESPOT_AGENTIC_MODE==="true"),process.env.LANGFUSE_PUBLIC_KEY&&!e.langfusePublicKey&&(e.langfusePublicKey=process.env.LANGFUSE_PUBLIC_KEY),process.env.LANGFUSE_SECRET_KEY&&!e.langfuseSecretKey&&(e.langfuseSecretKey=process.env.LANGFUSE_SECRET_KEY),process.env.LANGFUSE_BASE_URL&&!e.langfuseBaseUrl&&(e.langfuseBaseUrl=process.env.LANGFUSE_BASE_URL),process.env.LANGFUSE_ENABLED!==void 0&&e.langfuseEnabled===void 0&&(e.langfuseEnabled=process.env.LANGFUSE_ENABLED==="true"),e}function Fe(e,t){let n=t||R();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;case"langdock-api":return n.langdockApiKey||process.env.LANGDOCK_API_KEY;default:return}}function Vs(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function Y(e){let n={...R(),...e};if(B(Ks,JSON.stringify(n,null,2)),process.platform!=="win32")try{ug(Ks,384)}catch{}}function mg(){return za}function Lt(){let e=R();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function qn(e,t,n,s){let i=R().hubspotAccounts||[],r=i.findIndex(l=>l.portalId===t),a={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};r>=0?i[r]=a:i.push(a),Y({hubspotAccounts:i,activeHubSpotAccount:t})}function Pi(e){let t=R(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),Y(s)}function Ni(e){Y({activeHubSpotAccount:e})}function Le(){return Lt()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function st(e){return R().enabledCLITools?.includes(e)??!1}function Ri(e,t){let n=R(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),Y({enabledCLITools:[...s]})}var za,Ks,ee=N(()=>{"use strict";y();oe();za=Va(dg(),".vibespot"),Ks=Va(za,"config.json")});var Di={};Ge(Di,{OAUTH_EXTRA_HEADERS:()=>Xn,OAUTH_SYSTEM_PREFIX:()=>Sn,clearOAuthTokens:()=>qs,getOAuthTokenInfo:()=>Xt,getValidAccessToken:()=>Fi,hasValidOAuthToken:()=>Ze,saveInitialToken:()=>Oi});import{join as pg}from"path";import{homedir as gg}from"os";import{chmodSync as fg,unlinkSync as hg}from"fs";function Ys(){if(!x(bn))return null;try{return JSON.parse(P(bn))}catch{return null}}function qa(e){if(B(bn,JSON.stringify(e,null,2)),process.platform!=="win32")try{fg(bn,384)}catch{}}async function vg(e){let t=await fetch(bg,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:yg})});if(!t.ok)throw qs(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();qa({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Oi(e,t=""){qa({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Ze(){let e=Ys();return e?e.expires_at>Date.now():!1}async function Fi(){let e=Ys();if(!e)return null;if(e.expires_at-Date.now()>Sg)return e.access_token;if(e.refresh_token){zs||(zs=vg(e.refresh_token).finally(()=>{zs=null}));try{await zs}catch{return null}return Ys()?.access_token??null}return e.access_token}function Xt(){let e=Ys();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function qs(){if(x(bn))try{hg(bn)}catch{}}var yg,bg,bn,Sg,Xn,Sn,zs,_t=N(()=>{"use strict";y();oe();yg="9d1c250a-e61b-44d9-88ed-5944d1962f5e",bg="https://console.anthropic.com/v1/oauth/token",bn=pg(gg(),".vibespot","claude-oauth.json"),Sg=300*1e3,Xn={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},Sn="You are Claude Code, Anthropic's official CLI for Claude.";zs=null});import{join as Xs}from"path";import{homedir as Zs}from"os";import{readFileSync as Xa,existsSync as Qs,readdirSync as xg}from"fs";function Zn(){let e=ie("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:ie(`${Zt} node`).stdout}}function Qn(){let e=ie("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:ie(`${Zt} git`).stdout}}function ft(){let e=ie("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:ie(`${Zt} hs`).stdout}}function wn(){let e=ie("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Xs(Zs(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Qs(t)){let o=xg(t);(o.some(r=>r.includes("credentials")||r.includes("auth")||r.includes("token")||r===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:ie(`${Zt} claude`).stdout,authenticated:n,authDetail:s}}function es(e){try{let t=Xs(Zs(),".hscli","config.yml");if(!Qs(t))return"na1";let n=Xa(t,"utf-8"),s=n.indexOf(`accountId: ${e}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let r=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!r)return"na1";if(r[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function ht(){let e=ie("hs accounts list",{timeout:Za});if(!e.success||!e.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let t=[],n="",s="",o=e.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=e.stdout.split(`
2
- `);for(let r of i){let a=r.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(a&&!/Account ID/i.test(r)&&!/^-+$/.test(r.trim())&&!/^Name\s/i.test(r.trim())){let l=a[1].trim(),c=a[2].trim(),d=a[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Cn(){let e=ie("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Xs(Zs(),".config","gcloud","application_default_credentials.json"),n=Qs(t),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:e.stdout,path:ie(`${Zt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function kn(){let e=ie("codex --version");if(!e.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=!!process.env.OPENAI_API_KEY,n=!1;try{let i=Xs(Zs(),".codex","auth.json");Qs(i)&&(n=Xa(i,"utf-8").length>10)}catch{}let s=t||n,o=n?"Authenticated (OAuth)":t?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:e.stdout,path:ie(`${Zt} codex`).stdout,authenticated:s,authDetail:o}}function eo(){let e=ie("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
3
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:ie(`${Zt} gh`).stdout}}function to(){let e=ie("gh auth status 2>&1",{timeout:Za});if(!e.success&&!e.stdout)return{authenticated:!1,username:""};let t=e.stdout||e.stderr||"",n=t.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=t.match(/account\s+(\S+)/);return s&&t.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:t.includes("Logged in"),username:""}}function Qa(){return!!process.env.ANTHROPIC_API_KEY}function no(e){return parseInt(e.split(".")[0],10)>=18}function el(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function wg(){let e=R(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Lt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function vn(e,...t){if(e)return{configured:!0,masked:Vs(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:Vs(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function ji(e){return{anthropic:vn(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:vn(e.openaiApiKey,"OPENAI_API_KEY"),gemini:vn(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:vn(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:vn(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:vn(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function Li(e){let t=[];return e.claudeCode&&t.push("claude-code"),e.claudeOAuth&&t.push("claude-oauth"),e.apiKeys.anthropic.configured&&t.push("anthropic-api"),e.apiKeys.openai.configured&&t.push("openai-api"),e.geminiCli&&t.push("gemini-cli"),e.apiKeys.gemini.configured&&t.push("gemini-api"),e.codexCli&&t.push("codex-cli"),e.apiKeys.langdock.configured&&t.push("langdock-api"),t}function Ji(e,t){if(e==="cli"){if(!t)return{name:"HubSpot CLI",found:!1,version:"",path:"",authenticated:!1,portalName:"",portalId:"",dataCenter:"na1",accounts:[],uploadMode:"cli"};let n=ft(),s=n.found?ht():{authenticated:!1,portalName:"",portalId:"",accounts:[]},o=s.portalId?es(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...wg()}}function tl(){let e=R(),t=e.hubspotUploadMode||"api",n=ji(e),s={authenticated:Ze(),expiresAt:Xt()?.expiresAt},o=r=>({name:r,found:!1,version:"",path:"",authenticated:!1,authDetail:"Not scanned"}),i=r=>({name:r,found:!1,version:"",path:""});return{tools:{node:i("Node.js"),git:i("Git"),hubspot:Ji(t,!1),github:{...i("GitHub CLI"),authenticated:!1,username:""},claudeCode:o("Claude Code"),claudeOAuth:s,geminiCli:o("Gemini CLI"),codexCli:o("OpenAI Codex CLI")},apiKeys:n,activeEngine:e.aiEngine||null,availableEngines:Li({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:st("claude-code"),geminiCli:st("gemini-cli"),codexCli:st("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function nl(){let e=R(),t=ji(e),n={authenticated:Ze(),expiresAt:Xt()?.expiresAt},s=st("claude-code")?wn():{...xn,name:"Claude Code"},o=st("gemini-cli")?Cn():{...xn,name:"Gemini CLI"},i=st("codex-cli")?kn():{...xn,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:i,claudeOAuth:n,availableEngines:Li({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:i.found&&i.authenticated})}}function sl(){let t=R().hubspotUploadMode||"api",n=eo(),s=n.found?to():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:Ji(t,!0)}}function so(){let e=R(),t=e.hubspotUploadMode||"api",n=Zn(),s=Qn(),o=Ji(t,!0),i=eo(),r=i.found?to():{authenticated:!1,username:""},a={authenticated:Ze(),expiresAt:Xt()?.expiresAt},l=st("claude-code")?wn():{...xn,name:"Claude Code"},c=st("gemini-cli")?Cn():{...xn,name:"Gemini CLI"},d=st("codex-cli")?kn():{...xn,name:"OpenAI Codex CLI"},u=ji(e);return{tools:{node:n,git:s,hubspot:o,github:{...i,...r},claudeCode:l,claudeOAuth:a,geminiCli:c,codexCli:d},apiKeys:u,activeEngine:e.aiEngine||null,availableEngines:Li({apiKeys:u,claudeOAuth:a.authenticated,claudeCode:l.found&&l.authenticated,geminiCli:c.found&&c.authenticated,codexCli:d.found&&d.authenticated}),enabledCLITools:e.enabledCLITools||[],scanned:!0}}var Zt,Za,xn,Qt=N(()=>{"use strict";y();qt();ee();_t();Zt=process.platform==="win32"?"where":"which",Za=4e3;xn={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as Cg}from"fs";import{basename as kg}from"path";async function il(e){let t=ol.get(e);if(t&&t.expiresAt-Date.now()>_g)return t;let n=await fetch(`${$t}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:e})});if(!n.ok){let i=await n.text().catch(()=>"");throw new Error(n.status===401||n.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${n.status}): ${i.slice(0,200)}`)}let s=await n.json(),o={accessToken:s.oauthAccessToken,expiresAt:s.expiresAtMillis,hubId:s.hubId,hubName:s.hubName||""};return ol.set(e,o),o}async function Tn(e){let{accessToken:t}=await il(e);return{Authorization:`Bearer ${t}`}}function oo(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function $g(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Eg(e){return new Promise(t=>setTimeout(t,e))}async function ts(e,t){let n=`HTTP ${e.status}`,s,o;try{let i=await e.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let r=i.errors[0];o=r.message||JSON.stringify(r)}}catch{try{let i=await e.text();i&&(n=i.slice(0,500))}catch{}}return{status:e.status,message:t?`${n} (${t})`:n,category:s,detail:o}}async function ns(e,t,n=Tg){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=Ag*Math.pow(2,s);await Eg(i);continue}return o}return fetch(e,t)}async function io(e){let t=await il(e),n=`${$t}/account-info/v3/details`,s=await ns(n,{headers:await Tn(e)});if(!s.ok){let a=await ts(s);throw new Error(`Failed to get account info: ${a.message}`)}let o=await s.json(),i=String(o.portalId||t.hubId||""),r=t.hubName||o.uiDomain||i;return{portalId:i,portalName:r,dataCenter:$g(e)}}async function rl(e,t,n){let s=Cg(n),o=kg(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${$t}/cms/v3/source-code/published/content/${oo(t)}`,l=await ns(a,{method:"PUT",headers:await Tn(e),body:i});if(!l.ok){let c=await ts(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function Bi(e,t){let n=`${$t}/cms/v3/source-code/published/content/${oo(t)}`,s=await ns(n,{method:"DELETE",headers:await Tn(e)});if(!s.ok&&s.status!==404){let o=await ts(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function al(e,t){let n=`${$t}/cms/v3/source-code/published/content/${oo(t)}`,s=await ns(n,{method:"GET",headers:await Tn(e)});if(!s.ok){let i=await ts(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function ro(e,t){let n=`${$t}/cms/v3/source-code/published/metadata/${oo(t)}`,s=await ns(n,{method:"GET",headers:await Tn(e)});if(s.status===404)return null;if(!s.ok){let o=await ts(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function ll(e){let t=await Tn(e),n=[`${$t}/cms/v3/source-code/published/metadata`,`${$t}/cms/v3/source-code/published/metadata/`,`${$t}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let i=await o.json(),r=i.children||i.objects||(Array.isArray(i)?i:null);if(r&&r.length>0)return r.filter(a=>a.folder)}}catch{}return[]}var $t,Tg,Ag,_g,ol,en=N(()=>{"use strict";y();$t="https://api.hubapi.com",Tg=3,Ag=1e3,_g=300*1e3,ol=new Map});import*as ae from"@clack/prompts";function Hi(e){ae.isCancel(e)&&(ae.cancel(I.muted("Operation cancelled.")),process.exit(0))}async function ge(e){ae.intro(I.heading(e))}async function fe(e){ae.outro(I.success(e))}async function yt(e,t){ae.note(e,t?I.heading(t):void 0)}async function Se(e){let t=await ae.text({message:I.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return Hi(t),t}async function Me(e){let t=await ae.confirm({message:I.accent(e.message),initialValue:e.initialValue??!0});return Hi(t),t}async function Et(e){let t=await ae.select({message:I.accent(e.message),options:e.options});return Hi(t),t}async function De(){let e=ae.spinner();return{start:t=>e.start(I.muted(t)),stop:t=>e.stop(I.success(t)),message:t=>e.message(I.muted(t))}}function D(e){ae.log.info(e)}function G(e){ae.log.success(I.success(e))}function se(e){ae.log.warn(I.warn(e))}function V(e){ae.log.error(I.error(e))}var Qe=N(()=>{"use strict";y();gt()});import{readdirSync as Ui,statSync as Mg}from"fs";import{join as he,basename as Gi,extname as Ig}from"path";function cl(e){return typeof e!="string"||e.length===0||e.length>2048||/[\s;&|`$()<>\\]/.test(e)?!1:!!(/^https?:\/\/[^\s]+$/.test(e)||/^git@[\w.-]+:[\w./~+-]+$/.test(e))}function dl(e){let t=[],n=[he(e,"src/components/landing"),he(e,"src/components/sections"),he(e,"src/components"),he(e,"src/pages"),he(e,"app/components"),he(e,"components")];for(let s of n)if(x(s))try{let o=Ui(s);for(let i of o){let r=he(s,i);if(!Mg(r).isFile())continue;let l=Ig(i);if(![".tsx",".jsx"].includes(l))continue;let c=Gi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=P(r),u=Pg(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function Pg(e,t){let n=[];return/carousel|slider|swiper|embla/i.test(t)&&n.push("carousel"),/accordion|collapsible|expand/i.test(t)&&n.push("accordion"),/form|submit|input.*email/i.test(t)&&n.push("form"),/nav|navigation|menu/i.test(t)&&n.push("navigation"),/hero|headline|tagline/i.test(t)&&n.push("hero"),/footer|copyright/i.test(t)&&n.push("footer"),/testimonial|quote|review/i.test(t)&&n.push("testimonials"),/pricing|plan|tier/i.test(t)&&n.push("pricing"),/faq|question.*answer/i.test(t)&&n.push("FAQ"),/feature|benefit|advantage/i.test(t)&&n.push("features"),/contact|get.in.touch/i.test(t)&&n.push("contact"),/cta|call.to.action/i.test(t)&&n.push("CTA"),/team|member|bio/i.test(t)&&n.push("team"),n.length===0?e.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function ul(e){let t=[he(e,"src/index.css"),he(e,"src/globals.css"),he(e,"src/app/globals.css"),he(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!x(o))continue;let i=P(o),r=i.match(/--[\w-]+:/g);r&&(n+=r.length);let a=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(a)for(let c of a){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function ml(e){let t=[],n=he(e,"src/hooks");if(x(n))try{let o=Ui(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=he(e,"src/components/landing");if(x(s))try{let o=Ui(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=P(he(s,i));/carousel|embla|swiper/i.test(r)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(r)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(r)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(r)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function pl(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!cl(e))throw new Error(`Refusing to clone unsafe source URL: ${e}. Only http(s):// and git@host:path URLs without shell metacharacters are allowed.`);n=!0;let l=Gi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",l),!x(t)){let c=Z(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!x(t))throw new Error(`Directory not found: ${t}`);let s=dl(t),o=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:i,fonts:r}=ul(t),a=ml(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function lo(){await ge("Source Project");let e=await Se({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){cl(e)||(V("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let h=Gi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",h),x(t))G(`Using existing clone: ${I.dim(t)}`);else{let f=await De();f.start("Cloning repository..."),Z(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${I.dim(t)}`)}}else t=e,x(t)||(V(`Directory not found: ${t}`),process.exit(1)),G(`Using local source: ${I.dim(t)}`);let s=await De();s.start("Analyzing project structure...");let o=dl(t),i=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:r,fonts:a}=ul(t),l=ml(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(se("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${I.dim(`${f+1}.`)} ${I.bold(h.name)} ${I.muted(`\u2014 ${h.description}`)}`).join(`
4
- `),d=i?`Tailwind + custom CSS (${r} variables)`:`Custom CSS (${r} variables)`,u=a.length>0?a.join(", "):"System fonts",m=l.join(", ");return await yt(`${c}
1
+ var ef=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var We=(e,t)=>{for(var n in t)ef(e,n,{get:t[n],enumerable:!0})};import Px from"path";import{fileURLToPath as Mx}from"url";var y=R(()=>{"use strict"});import xn from"chalk";function Et(e){return ml?xn:xn.hex(e)}var yt,ml,E,bt=R(()=>{"use strict";y();yt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ml=!!process.env.NO_COLOR;E={accent:Et(yt.accent),accentBright:Et(yt.accentBright),success:Et(yt.success),info:Et(yt.info),warn:Et(yt.warn),error:Et(yt.error),muted:Et(yt.muted),vibes:Et(yt.vibes),heading:ml?xn.bold:xn.bold.hex(yt.accent),command:Et(yt.accentBright),dim:xn.dim,bold:xn.bold}});import{readFileSync as zi,writeFileSync as tf,mkdirSync as pl,existsSync as so}from"fs";import{dirname as gl,join as Mt}from"path";import{fileURLToPath as nf}from"url";function M(e){return zi(e,"utf-8")}function H(e,t){pl(gl(e),{recursive:!0}),tf(e,t,"utf-8")}function v(e){return so(e)}function Ie(e){pl(e,{recursive:!0})}function Cn(e){let t=[Mt(kn,"../../assets",e),Mt(kn,"../assets",e),Mt(process.cwd(),"assets",e)];for(let n of t)if(so(n))return n;throw new Error(`Asset not found: ${e}`)}function Tn(){if(wn)return wn;let e=[Mt(kn,"../../package.json"),Mt(kn,"../package.json"),Mt(process.cwd(),"package.json")];for(let t of e)if(so(t))try{let n=JSON.parse(zi(t,"utf-8"));if(n.name==="vibespot"&&n.version)return wn=n.version,wn}catch{}return wn="dev",wn}function fl(){if(no)return no;let e=[Mt(kn,"../../CHANGELOG.md"),Mt(kn,"../CHANGELOG.md"),Mt(process.cwd(),"CHANGELOG.md")];for(let t of e)if(so(t))try{return no=zi(t,"utf-8"),no}catch{}return""}var kn,wn,no,ae=R(()=>{"use strict";y();kn=gl(nf(import.meta.url));wn="";no=""});import{execSync as hl,execFileSync as sf}from"child_process";function le(e,t={}){try{return{stdout:hl(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function te(e,t={}){try{return{stdout:sf("git",e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function yl(e,t={}){try{return hl(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var tn=R(()=>{"use strict";y()});var vl={};We(vl,{addHubSpotAccount:()=>ns,getActiveHubSpotAccount:()=>Gt,getApiKeyForEngine:()=>De,getConfigDir:()=>af,getHubSpotPak:()=>Be,isCliToolEnabled:()=>it,loadConfig:()=>N,maskApiKey:()=>io,removeHubSpotAccount:()=>Yi,saveConfig:()=>q,setActiveHubSpotAccount:()=>qi,setCliToolEnabled:()=>Xi});import{join as bl}from"path";import{homedir as of}from"os";import{chmodSync as rf}from"fs";function N(){let e={};if(v(oo))try{e=JSON.parse(M(oo)),e.aiEngine==="api"&&(e.aiEngine="anthropic-api")}catch{e={}}return process.env.VIBESPOT_AI_ENGINE&&!e.aiEngine&&(e.aiEngine=process.env.VIBESPOT_AI_ENGINE),process.env.ANTHROPIC_API_KEY&&!e.anthropicApiKey&&(e.anthropicApiKey=process.env.ANTHROPIC_API_KEY),process.env.OPENAI_API_KEY&&!e.openaiApiKey&&(e.openaiApiKey=process.env.OPENAI_API_KEY),(process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)&&!e.geminiApiKey&&(e.geminiApiKey=process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY),process.env.LANGDOCK_API_KEY&&!e.langdockApiKey&&(e.langdockApiKey=process.env.LANGDOCK_API_KEY),process.env.LANGDOCK_BASE_URL&&!e.langdockBaseUrl&&(e.langdockBaseUrl=process.env.LANGDOCK_BASE_URL),process.env.LANGDOCK_PROVIDER&&!e.langdockProvider&&(e.langdockProvider=process.env.LANGDOCK_PROVIDER),process.env.FIGMA_TOKEN&&!e.figmaToken&&(e.figmaToken=process.env.FIGMA_TOKEN),process.env.VIBESPOT_AGENTIC_MODE!==void 0&&e.agenticMode===void 0&&(e.agenticMode=process.env.VIBESPOT_AGENTIC_MODE==="true"),process.env.LANGFUSE_PUBLIC_KEY&&!e.langfusePublicKey&&(e.langfusePublicKey=process.env.LANGFUSE_PUBLIC_KEY),process.env.LANGFUSE_SECRET_KEY&&!e.langfuseSecretKey&&(e.langfuseSecretKey=process.env.LANGFUSE_SECRET_KEY),process.env.LANGFUSE_BASE_URL&&!e.langfuseBaseUrl&&(e.langfuseBaseUrl=process.env.LANGFUSE_BASE_URL),process.env.LANGFUSE_ENABLED!==void 0&&e.langfuseEnabled===void 0&&(e.langfuseEnabled=process.env.LANGFUSE_ENABLED==="true"),e}function De(e,t){let n=t||N();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;case"langdock-api":return n.langdockApiKey||process.env.LANGDOCK_API_KEY;default:return}}function io(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function q(e){let n={...N(),...e};if(H(oo,JSON.stringify(n,null,2)),process.platform!=="win32")try{rf(oo,384)}catch{}}function af(){return Sl}function Gt(){let e=N();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function ns(e,t,n,s){let i=N().hubspotAccounts||[],r=i.findIndex(l=>l.portalId===t),a={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};r>=0?i[r]=a:i.push(a),q({hubspotAccounts:i,activeHubSpotAccount:t})}function Yi(e){let t=N(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),q(s)}function qi(e){q({activeHubSpotAccount:e})}function Be(){return Gt()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function it(e){return N().enabledCLITools?.includes(e)??!1}function Xi(e,t){let n=N(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),q({enabledCLITools:[...s]})}var Sl,oo,oe=R(()=>{"use strict";y();ae();Sl=bl(of(),".vibespot"),oo=bl(Sl,"config.json")});var er={};We(er,{OAUTH_EXTRA_HEADERS:()=>ss,OAUTH_SYSTEM_PREFIX:()=>_n,clearOAuthTokens:()=>lo,getOAuthTokenInfo:()=>nn,getValidAccessToken:()=>Qi,hasValidOAuthToken:()=>tt,saveInitialToken:()=>Zi});import{join as lf}from"path";import{homedir as cf}from"os";import{chmodSync as df,unlinkSync as uf}from"fs";function ao(){if(!v(An))return null;try{return JSON.parse(M(An))}catch{return null}}function xl(e){if(H(An,JSON.stringify(e,null,2)),process.platform!=="win32")try{df(An,384)}catch{}}async function ff(e){let t=await fetch(pf,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:mf})});if(!t.ok)throw lo(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();xl({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Zi(e,t=""){xl({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function tt(){let e=ao();return e?e.expires_at>Date.now():!1}async function Qi(){let e=ao();if(!e)return null;if(e.expires_at-Date.now()>gf)return e.access_token;if(e.refresh_token){ro||(ro=ff(e.refresh_token).finally(()=>{ro=null}));try{await ro}catch{return null}return ao()?.access_token??null}return e.access_token}function nn(){let e=ao();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function lo(){if(v(An))try{uf(An)}catch{}}var mf,pf,An,gf,ss,_n,ro,It=R(()=>{"use strict";y();ae();mf="9d1c250a-e61b-44d9-88ed-5944d1962f5e",pf="https://console.anthropic.com/v1/oauth/token",An=lf(cf(),".vibespot","claude-oauth.json"),gf=300*1e3,ss={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},_n="You are Claude Code, Anthropic's official CLI for Claude.";ro=null});import{join as co}from"path";import{homedir as uo}from"os";import{readFileSync as wl,existsSync as mo,readdirSync as hf}from"fs";function os(){let e=le("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:le(`${sn} node`).stdout}}function is(){let e=le("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:le(`${sn} git`).stdout}}function St(){let e=le("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:le(`${sn} hs`).stdout}}function En(){let e=le("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=co(uo(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(mo(t)){let o=hf(t);(o.some(r=>r.includes("credentials")||r.includes("auth")||r.includes("token")||r===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:le(`${sn} claude`).stdout,authenticated:n,authDetail:s}}function rs(e){try{let t=co(uo(),".hscli","config.yml");if(!mo(t))return"na1";let n=wl(t,"utf-8"),s=n.indexOf(`accountId: ${e}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let r=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!r)return"na1";if(r[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function vt(){let e=le("hs accounts list",{timeout:kl});if(!e.success||!e.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let t=[],n="",s="",o=e.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=e.stdout.split(`
2
+ `);for(let r of i){let a=r.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(a&&!/Account ID/i.test(r)&&!/^-+$/.test(r.trim())&&!/^Name\s/i.test(r.trim())){let l=a[1].trim(),c=a[2].trim(),d=a[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Mn(){let e=le("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=co(uo(),".config","gcloud","application_default_credentials.json"),n=mo(t),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:e.stdout,path:le(`${sn} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function In(){let e=le("codex --version");if(!e.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=!!process.env.OPENAI_API_KEY,n=!1;try{let i=co(uo(),".codex","auth.json");mo(i)&&(n=wl(i,"utf-8").length>10)}catch{}let s=t||n,o=n?"Authenticated (OAuth)":t?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:e.stdout,path:le(`${sn} codex`).stdout,authenticated:s,authDetail:o}}function po(){let e=le("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
3
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:le(`${sn} gh`).stdout}}function go(){let e=le("gh auth status 2>&1",{timeout:kl});if(!e.success&&!e.stdout)return{authenticated:!1,username:""};let t=e.stdout||e.stderr||"",n=t.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=t.match(/account\s+(\S+)/);return s&&t.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:t.includes("Logged in"),username:""}}function Cl(){return!!process.env.ANTHROPIC_API_KEY}function fo(e){return parseInt(e.split(".")[0],10)>=18}function Tl(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function yf(){let e=N(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Gt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function $n(e,...t){if(e)return{configured:!0,masked:io(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:io(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function tr(e){return{anthropic:$n(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:$n(e.openaiApiKey,"OPENAI_API_KEY"),gemini:$n(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:$n(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:$n(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:$n(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function nr(e){let t=[];return e.claudeCode&&t.push("claude-code"),e.claudeOAuth&&t.push("claude-oauth"),e.apiKeys.anthropic.configured&&t.push("anthropic-api"),e.apiKeys.openai.configured&&t.push("openai-api"),e.geminiCli&&t.push("gemini-cli"),e.apiKeys.gemini.configured&&t.push("gemini-api"),e.codexCli&&t.push("codex-cli"),e.apiKeys.langdock.configured&&t.push("langdock-api"),t}function sr(e,t){if(e==="cli"){if(!t)return{name:"HubSpot CLI",found:!1,version:"",path:"",authenticated:!1,portalName:"",portalId:"",dataCenter:"na1",accounts:[],uploadMode:"cli"};let n=St(),s=n.found?vt():{authenticated:!1,portalName:"",portalId:"",accounts:[]},o=s.portalId?rs(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...yf()}}function Al(){let e=N(),t=e.hubspotUploadMode||"api",n=tr(e),s={authenticated:tt(),expiresAt:nn()?.expiresAt},o=r=>({name:r,found:!1,version:"",path:"",authenticated:!1,authDetail:"Not scanned"}),i=r=>({name:r,found:!1,version:"",path:""});return{tools:{node:i("Node.js"),git:i("Git"),hubspot:sr(t,!1),github:{...i("GitHub CLI"),authenticated:!1,username:""},claudeCode:o("Claude Code"),claudeOAuth:s,geminiCli:o("Gemini CLI"),codexCli:o("OpenAI Codex CLI")},apiKeys:n,activeEngine:e.aiEngine||null,availableEngines:nr({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:it("claude-code"),geminiCli:it("gemini-cli"),codexCli:it("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function _l(){let e=N(),t=tr(e),n={authenticated:tt(),expiresAt:nn()?.expiresAt},s=it("claude-code")?En():{...Pn,name:"Claude Code"},o=it("gemini-cli")?Mn():{...Pn,name:"Gemini CLI"},i=it("codex-cli")?In():{...Pn,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:i,claudeOAuth:n,availableEngines:nr({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:i.found&&i.authenticated})}}function $l(){let t=N().hubspotUploadMode||"api",n=po(),s=n.found?go():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:sr(t,!0)}}function ho(){let e=N(),t=e.hubspotUploadMode||"api",n=os(),s=is(),o=sr(t,!0),i=po(),r=i.found?go():{authenticated:!1,username:""},a={authenticated:tt(),expiresAt:nn()?.expiresAt},l=it("claude-code")?En():{...Pn,name:"Claude Code"},c=it("gemini-cli")?Mn():{...Pn,name:"Gemini CLI"},d=it("codex-cli")?In():{...Pn,name:"OpenAI Codex CLI"},u=tr(e);return{tools:{node:n,git:s,hubspot:o,github:{...i,...r},claudeCode:l,claudeOAuth:a,geminiCli:c,codexCli:d},apiKeys:u,activeEngine:e.aiEngine||null,availableEngines:nr({apiKeys:u,claudeOAuth:a.authenticated,claudeCode:l.found&&l.authenticated,geminiCli:c.found&&c.authenticated,codexCli:d.found&&d.authenticated}),enabledCLITools:e.enabledCLITools||[],scanned:!0}}var sn,kl,Pn,on=R(()=>{"use strict";y();tn();oe();It();sn=process.platform==="win32"?"where":"which",kl=4e3;Pn={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as bf}from"fs";import{basename as Sf}from"path";async function El(e){let t=Pl.get(e);if(t&&t.expiresAt-Date.now()>wf)return t;let n=await fetch(`${Rt}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:e})});if(!n.ok){let i=await n.text().catch(()=>"");throw new Error(n.status===401||n.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${n.status}): ${i.slice(0,200)}`)}let s=await n.json(),o={accessToken:s.oauthAccessToken,expiresAt:s.expiresAtMillis,hubId:s.hubId,hubName:s.hubName||""};return Pl.set(e,o),o}async function Rn(e){let{accessToken:t}=await El(e);return{Authorization:`Bearer ${t}`}}function yo(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function kf(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Cf(e){return new Promise(t=>setTimeout(t,e))}async function as(e,t){let n=`HTTP ${e.status}`,s,o;try{let i=await e.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let r=i.errors[0];o=r.message||JSON.stringify(r)}}catch{try{let i=await e.text();i&&(n=i.slice(0,500))}catch{}}return{status:e.status,message:t?`${n} (${t})`:n,category:s,detail:o}}async function ls(e,t,n=vf){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=xf*Math.pow(2,s);await Cf(i);continue}return o}return fetch(e,t)}async function bo(e){let t=await El(e),n=`${Rt}/account-info/v3/details`,s=await ls(n,{headers:await Rn(e)});if(!s.ok){let a=await as(s);throw new Error(`Failed to get account info: ${a.message}`)}let o=await s.json(),i=String(o.portalId||t.hubId||""),r=t.hubName||o.uiDomain||i;return{portalId:i,portalName:r,dataCenter:kf(e)}}async function Ml(e,t,n){let s=bf(n),o=Sf(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${Rt}/cms/v3/source-code/published/content/${yo(t)}`,l=await ls(a,{method:"PUT",headers:await Rn(e),body:i});if(!l.ok){let c=await as(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function or(e,t){let n=`${Rt}/cms/v3/source-code/published/content/${yo(t)}`,s=await ls(n,{method:"DELETE",headers:await Rn(e)});if(!s.ok&&s.status!==404){let o=await as(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Il(e,t){let n=`${Rt}/cms/v3/source-code/published/content/${yo(t)}`,s=await ls(n,{method:"GET",headers:await Rn(e)});if(!s.ok){let i=await as(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function So(e,t){let n=`${Rt}/cms/v3/source-code/published/metadata/${yo(t)}`,s=await ls(n,{method:"GET",headers:await Rn(e)});if(s.status===404)return null;if(!s.ok){let o=await as(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Rl(e){let t=await Rn(e),n=[`${Rt}/cms/v3/source-code/published/metadata`,`${Rt}/cms/v3/source-code/published/metadata/`,`${Rt}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let i=await o.json(),r=i.children||i.objects||(Array.isArray(i)?i:null);if(r&&r.length>0)return r.filter(a=>a.folder)}}catch{}return[]}var Rt,vf,xf,wf,Pl,rn=R(()=>{"use strict";y();Rt="https://api.hubapi.com",vf=3,xf=1e3,wf=300*1e3,Pl=new Map});import*as ce from"@clack/prompts";function ir(e){ce.isCancel(e)&&(ce.cancel(E.muted("Operation cancelled.")),process.exit(0))}async function fe(e){ce.intro(E.heading(e))}async function he(e){ce.outro(E.success(e))}async function xt(e,t){ce.note(e,t?E.heading(t):void 0)}async function ve(e){let t=e.validate,n=await ce.text({message:E.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:t?s=>t(s??""):void 0});return ir(n),n}async function Pe(e){let t=await ce.confirm({message:E.accent(e.message),initialValue:e.initialValue??!0});return ir(t),t}async function Nt(e){let t=await ce.select({message:E.accent(e.message),options:e.options});return ir(t),t}async function je(){let e=ce.spinner();return{start:t=>e.start(E.muted(t)),stop:t=>e.stop(E.success(t)),message:t=>e.message(E.muted(t))}}function B(e){ce.log.info(e)}function W(e){ce.log.success(E.success(e))}function ie(e){ce.log.warn(E.warn(e))}function Y(e){ce.log.error(E.error(e))}var nt=R(()=>{"use strict";y();bt()});import{readdirSync as rr,statSync as Tf}from"fs";import{join as ye,basename as ar,extname as Af}from"path";function Nl(e){return typeof e!="string"||e.length===0||e.length>2048||/[\s;&|`$()<>\\]/.test(e)?!1:!!(/^https?:\/\/[^\s]+$/.test(e)||/^git@[\w.-]+:[\w./~+-]+$/.test(e))}function Ol(e){let t=[],n=[ye(e,"src/components/landing"),ye(e,"src/components/sections"),ye(e,"src/components"),ye(e,"src/pages"),ye(e,"app/components"),ye(e,"components")];for(let s of n)if(v(s))try{let o=rr(s);for(let i of o){let r=ye(s,i);if(!Tf(r).isFile())continue;let l=Af(i);if(![".tsx",".jsx"].includes(l))continue;let c=ar(i,l);if(c.startsWith("ui")||c==="index")continue;let d=M(r),u=_f(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function _f(e,t){let n=[];return/carousel|slider|swiper|embla/i.test(t)&&n.push("carousel"),/accordion|collapsible|expand/i.test(t)&&n.push("accordion"),/form|submit|input.*email/i.test(t)&&n.push("form"),/nav|navigation|menu/i.test(t)&&n.push("navigation"),/hero|headline|tagline/i.test(t)&&n.push("hero"),/footer|copyright/i.test(t)&&n.push("footer"),/testimonial|quote|review/i.test(t)&&n.push("testimonials"),/pricing|plan|tier/i.test(t)&&n.push("pricing"),/faq|question.*answer/i.test(t)&&n.push("FAQ"),/feature|benefit|advantage/i.test(t)&&n.push("features"),/contact|get.in.touch/i.test(t)&&n.push("contact"),/cta|call.to.action/i.test(t)&&n.push("CTA"),/team|member|bio/i.test(t)&&n.push("team"),n.length===0?e.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function Fl(e){let t=[ye(e,"src/index.css"),ye(e,"src/globals.css"),ye(e,"src/app/globals.css"),ye(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!v(o))continue;let i=M(o),r=i.match(/--[\w-]+:/g);r&&(n+=r.length);let a=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(a)for(let c of a){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function Dl(e){let t=[],n=ye(e,"src/hooks");if(v(n))try{let o=rr(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=ye(e,"src/components/landing");if(v(s))try{let o=rr(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=M(ye(s,i));/carousel|embla|swiper/i.test(r)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(r)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(r)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(r)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function jl(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!Nl(e))throw new Error(`Refusing to clone unsafe source URL: ${e}. Only http(s):// and git@host:path URLs without shell metacharacters are allowed.`);n=!0;let l=ar(e.replace(/\.git$/,""))||"react-source";if(t=ye(process.cwd(),"workspace",l),!v(t)){let c=te(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!v(t))throw new Error(`Directory not found: ${t}`);let s=Ol(t),o=v(ye(t,"tailwind.config.ts"))||v(ye(t,"tailwind.config.js")),{varCount:i,fonts:r}=Fl(t),a=Dl(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function xo(){await fe("Source Project");let e=await ve({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){Nl(e)||(Y("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let h=ar(e.replace(/\.git$/,""))||"react-source";if(t=ye(process.cwd(),"workspace",h),v(t))W(`Using existing clone: ${E.dim(t)}`);else{let f=await je();f.start("Cloning repository..."),te(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),Y(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${E.dim(t)}`)}}else t=e,v(t)||(Y(`Directory not found: ${t}`),process.exit(1)),W(`Using local source: ${E.dim(t)}`);let s=await je();s.start("Analyzing project structure...");let o=Ol(t),i=v(ye(t,"tailwind.config.ts"))||v(ye(t,"tailwind.config.js")),{varCount:r,fonts:a}=Fl(t),l=Dl(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(ie("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${E.dim(`${f+1}.`)} ${E.bold(h.name)} ${E.muted(`\u2014 ${h.description}`)}`).join(`
4
+ `),d=i?`Tailwind + custom CSS (${r} variables)`:`Custom CSS (${r} variables)`,u=a.length>0?a.join(", "):"System fonts",m=l.join(", ");return await xt(`${c}
5
5
 
6
6
  CSS: ${d}
7
7
  JS: ${m}
8
- Font: ${u}`,`${o.length} components detected`),await Me({message:"Does this look right?"})||(V("Please adjust your source directory and try again."),process.exit(0)),await fe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var co=N(()=>{"use strict";y();qt();oe();Qe();gt()});var gl={};Ge(gl,{addEmailTemplateToTheme:()=>An,createThemeScaffold:()=>os});import{mkdirSync as Mt,writeFileSync as ss}from"fs";import{join as We}from"path";function os(e,t){Mt(e,{recursive:!0}),Mt(We(e,"templates"),{recursive:!0}),Mt(We(e,"modules"),{recursive:!0}),Mt(We(e,"css"),{recursive:!0}),Mt(We(e,"js"),{recursive:!0}),Mt(We(e,"images"),{recursive:!0}),Mt(We(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};ss(We(e,"theme.json"),JSON.stringify(n,null,2)+`
9
- `),ss(We(e,"fields.json"),`[]
8
+ Font: ${u}`,`${o.length} components detected`),await Pe({message:"Does this look right?"})||(Y("Please adjust your source directory and try again."),process.exit(0)),await he("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var wo=R(()=>{"use strict";y();tn();ae();nt();bt()});var Ll={};We(Ll,{addEmailTemplateToTheme:()=>Nn,createThemeScaffold:()=>ds});import{mkdirSync as Ot,writeFileSync as cs}from"fs";import{join as Ke}from"path";function ds(e,t){Ot(e,{recursive:!0}),Ot(Ke(e,"templates"),{recursive:!0}),Ot(Ke(e,"modules"),{recursive:!0}),Ot(Ke(e,"css"),{recursive:!0}),Ot(Ke(e,"js"),{recursive:!0}),Ot(Ke(e,"images"),{recursive:!0}),Ot(Ke(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};cs(Ke(e,"theme.json"),JSON.stringify(n,null,2)+`
9
+ `),cs(Ke(e,"fields.json"),`[]
10
10
  `);let s=`<!--
11
11
  templateType: page
12
12
  isAvailableForNewContent: false
@@ -22,7 +22,7 @@ var rg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
22
22
  %}
23
23
  {% end_dnd_area %}
24
24
  {% endblock body %}
25
- `;ss(We(e,"templates","home.html"),s);let o=`<!--
25
+ `;cs(Ke(e,"templates","home.html"),s);let o=`<!--
26
26
  templateType: none
27
27
  isAvailableForNewContent: false
28
28
  label: Base Layout
@@ -45,7 +45,7 @@ var rg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
45
45
  {{ standard_footer_includes }}
46
46
  </body>
47
47
  </html>
48
- `;Mt(We(e,"templates","layouts"),{recursive:!0}),ss(We(e,"templates","layouts","base.html"),o)}function An(e,t){let n=`<!--
48
+ `;Ot(Ke(e,"templates","layouts"),{recursive:!0}),cs(Ke(e,"templates","layouts","base.html"),o)}function Nn(e,t){let n=`<!--
49
49
  templateType: email
50
50
  isAvailableForNewContent: true
51
51
  label: ${t} Email Template
@@ -84,8 +84,8 @@ var rg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
84
84
  {{ standard_footer_includes }}
85
85
  </body>
86
86
  </html>
87
- `;Mt(We(e,"templates"),{recursive:!0}),ss(We(e,"templates","email.html"),n)}var is=N(()=>{"use strict";y()});var hl={};Ge(hl,{fetchTheme:()=>rs});import{mkdirSync as fl,writeFileSync as Ng}from"fs";import{join as Rg,dirname as Og}from"path";async function Wi(e,t){let n=await ro(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let i of o){let r=typeof i=="string"?i:i.name;if(!r)continue;let a=`${t}/${r}`;if(typeof i=="string")s.push(...await Wi(e,a));else{let l=i;l.folder?s.push(...await Wi(e,l.path||a)):s.push(l.path||a)}}return s}async function Fg(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function rs(e,t,n,s={}){let o=s.concurrency??5,i=await Wi(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);fl(n,{recursive:!0}),await Fg(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=Rg(n,a);fl(Og(l),{recursive:!0});let c=await al(e,r);Ng(l,c),s.onFile?.(a)})}var uo=N(()=>{"use strict";y();en()});function Jt(e){let t=yl.get(e);if(t!==void 0)return t;try{t=P(hn(e))}catch{t=""}return yl.set(e,t),t}function ye(){return Jt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function ls(){return Jt("design-guide.md")}function Ki(){return Jt("content-guide.md")}function Je(){return Jt("hubspot-rules.md")}function Vi(){return Jt("humanify-guide.md")}function bl(){return Jt("email-rules.md")}function Sl(){return Jt("blog-rules.md")}function zi(e){let t=Jt("page-types.md");if(!t)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[e];if(!s)return"";let o=t.indexOf(s);if(o<0)return"";let i=t.indexOf(`
88
- ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function vl(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
87
+ `;Ot(Ke(e,"templates"),{recursive:!0}),cs(Ke(e,"templates","email.html"),n)}var us=R(()=>{"use strict";y()});var Jl={};We(Jl,{fetchTheme:()=>ms});import{mkdirSync as Bl,writeFileSync as $f}from"fs";import{join as Pf,dirname as Ef}from"path";async function lr(e,t){let n=await So(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let i of o){let r=typeof i=="string"?i:i.name;if(!r)continue;let a=`${t}/${r}`;if(typeof i=="string")s.push(...await lr(e,a));else{let l=i;l.folder?s.push(...await lr(e,l.path||a)):s.push(l.path||a)}}return s}async function Mf(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function ms(e,t,n,s={}){let o=s.concurrency??5,i=await lr(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);Bl(n,{recursive:!0}),await Mf(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=Pf(n,a);Bl(Ef(l),{recursive:!0});let c=await Il(e,r);$f(l,c),s.onFile?.(a)})}var ko=R(()=>{"use strict";y();rn()});function Wt(e){let t=Hl.get(e);if(t!==void 0)return t;try{t=M(Cn(e))}catch{t=""}return Hl.set(e,t),t}function be(){return Wt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function gs(){return Wt("design-guide.md")}function cr(){return Wt("content-guide.md")}function Je(){return Wt("hubspot-rules.md")}function dr(){return Wt("humanify-guide.md")}function Ul(){return Wt("email-rules.md")}function Gl(){return Wt("blog-rules.md")}function ur(e){let t=Wt("page-types.md");if(!t)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[e];if(!s)return"";let o=t.indexOf(s);if(o<0)return"";let i=t.indexOf(`
88
+ ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function Wl(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
89
89
 
90
90
  ## Rules
91
91
  Follow the conversion guide below EXACTLY. Key rules:
@@ -105,7 +105,7 @@ Follow the conversion guide below EXACTLY. Key rules:
105
105
  ${Je()}
106
106
 
107
107
  ## Conversion Guide
108
- ${e}`}function xl(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
108
+ ${e}`}function Kl(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
109
109
 
110
110
  Return a JSON object with these keys:
111
111
  - fieldsJson: complete fields.json content (as JSON string)
@@ -120,7 +120,7 @@ ${n}
120
120
  React component source:
121
121
  ${e}
122
122
 
123
- Return ONLY valid JSON, no markdown fences.`}function wl(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
123
+ Return ONLY valid JSON, no markdown fences.`}function Vl(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
124
124
 
125
125
  Extract the design system from the source CSS and Tailwind config below.
126
126
  Use the class prefix ".${n}-" for all custom classes.
@@ -144,7 +144,7 @@ ${e}
144
144
  Tailwind config:
145
145
  ${t}
146
146
 
147
- Return ONLY the CSS content, no markdown fences.`}function Cl(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
147
+ Return ONLY the CSS content, no markdown fences.`}function zl(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
148
148
 
149
149
  Convert the React hooks and interactive components below to plain JavaScript.
150
150
  Use the class prefix "${n}-" to match the CSS.
@@ -162,7 +162,7 @@ ${e}
162
162
  Interactive component sources:
163
163
  ${t}
164
164
 
165
- Return ONLY the JavaScript content, no markdown fences.`}function kl(e,t,n){return`Create a HubSpot page template that assembles these modules:
165
+ Return ONLY the JavaScript content, no markdown fences.`}function Yl(e,t,n){return`Create a HubSpot page template that assembles these modules:
166
166
 
167
167
  ${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
168
168
  `)}
@@ -177,29 +177,29 @@ Template requirements:
177
177
  - Each module in its own dnd_section with padding zeroed and full_width=true
178
178
  - dnd_area label: "${t} Landing Page"
179
179
 
180
- Return ONLY the template HTML content, no markdown fences.`}var yl,Ke=N(()=>{"use strict";y();oe();yl=new Map});import{appendFileSync as Bg,mkdirSync as Hg,readdirSync as Ug,unlinkSync as Gg}from"fs";import{join as Zi}from"path";import{homedir as Wg}from"os";function Vg(){if(!qi)try{Hg(go,{recursive:!0}),qi=!0}catch{}}function zg(){if(!Xi){Xi=!0;try{let e=Date.now()-Kg*864e5;for(let t of Ug(go)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{Gg(Zi(go,t))}catch{}}}catch{}}}function Yg(){let t=new Date().toISOString().slice(0,10);return Zi(go,`vibespot-${t}.log`)}function qg(){return new Date().toISOString().slice(11,23)}function Yi(e,t){if(Vg(),!!qi){Xi||zg();try{Bg(Yg(),`${qg()} ${e} ${t}
181
- `)}catch{}}}var go,Kg,qi,Xi,E,le=N(()=>{"use strict";y();go=Zi(Wg(),".vibespot","logs"),Kg=7,qi=!1,Xi=!1;E={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),Yi("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),Yi("WARN",s)},error(e,t,n){let s=n instanceof Error?n.message:n?String(n):"",o=s?`[${e}] ${t}: ${s}`:`[${e}] ${t}`;console.error(o),Yi("ERROR",o)}}});function Zg(e){let t=(e||"").toLowerCase();return Xg.find(n=>t.includes(n.match))}function cs(e,t){let n=Zg(e);if(!n)return;let s=n.cacheReadPerM??n.inputPerM*.1,o=n.cacheWritePerM??n.inputPerM*1.25,i=(t.inputTokens??0)*n.inputPerM,r=(t.outputTokens??0)*n.outputPerM,a=(t.cacheReadTokens??0)*s,l=(t.cacheCreationTokens??0)*o,c={total:(i+r+a+l)/1e6};return t.inputTokens!=null&&(c.input=i/1e6),t.outputTokens!=null&&(c.output=r/1e6),t.cacheReadTokens&&(c.cache_read_input_tokens=a/1e6),t.cacheCreationTokens&&(c.cache_creation_input_tokens=l/1e6),c}function et(e){if(e)return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_input_tokens??void 0,cacheCreationTokens:e.cache_creation_input_tokens??void 0}}function _n(e){if(!e)return;let t=e.prompt_tokens_details?.cached_tokens??0,n=e.prompt_tokens;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.completion_tokens,totalTokens:e.total_tokens,cacheReadTokens:t||void 0}}function $n(e){if(!e)return;let t=e.cachedContentTokenCount??0,n=e.promptTokenCount;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.candidatesTokenCount,totalTokens:e.totalTokenCount,cacheReadTokens:t||void 0}}function Al(e){let t={};return e.inputTokens!=null&&(t.input=e.inputTokens),e.outputTokens!=null&&(t.output=e.outputTokens),e.cacheReadTokens&&(t.cache_read_input_tokens=e.cacheReadTokens),e.cacheCreationTokens&&(t.cache_creation_input_tokens=e.cacheCreationTokens),e.totalTokens!=null&&(t.total=e.totalTokens),t}var Xg,tn=N(()=>{"use strict";y();Xg=[{match:"claude-opus-4",inputPerM:15,outputPerM:75},{match:"claude-sonnet-4",inputPerM:3,outputPerM:15},{match:"claude-haiku-4",inputPerM:1,outputPerM:5},{match:"claude-3-7-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-haiku",inputPerM:.8,outputPerM:4},{match:"claude-3-opus",inputPerM:15,outputPerM:75},{match:"gpt-5.5",inputPerM:5,outputPerM:30},{match:"gpt-5.4",inputPerM:2.5,outputPerM:15},{match:"gpt-5.3",inputPerM:1.75,outputPerM:14},{match:"gpt-4o-mini",inputPerM:.15,outputPerM:.6},{match:"gpt-4o",inputPerM:2.5,outputPerM:10},{match:"gpt-4.1-nano",inputPerM:.1,outputPerM:.4},{match:"gpt-4.1-mini",inputPerM:.4,outputPerM:1.6},{match:"gpt-4.1",inputPerM:2,outputPerM:8},{match:"gemini-2.5-pro",inputPerM:1.25,outputPerM:10},{match:"gemini-2.5-flash",inputPerM:.3,outputPerM:2.5},{match:"gemini-2.0-flash",inputPerM:.1,outputPerM:.4},{match:"gemini-1.5-pro",inputPerM:1.25,outputPerM:5},{match:"gemini-1.5-flash",inputPerM:.075,outputPerM:.3}]});import{AsyncLocalStorage as Qg}from"async_hooks";function ef(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function tf(e){return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,cacheReadTokens:e.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens,totalTokens:e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens,costUsd:e.costUsd,calls:e.calls,costComplete:e.unpricedCalls===0}}async function Qi(e){let t=ef();return{result:await _l.run(t,e),cost:tf(t)}}function $l(e,t){if(!t)return;let n=_l.getStore();if(!n)return;n.inputTokens+=t.inputTokens??0,n.outputTokens+=t.outputTokens??0,n.cacheReadTokens+=t.cacheReadTokens??0,n.cacheCreationTokens+=t.cacheCreationTokens??0,n.calls+=1;let s=cs(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}var _l,er=N(()=>{"use strict";y();tn();_l=new Qg});import{randomUUID as Bt}from"crypto";import{AsyncLocalStorage as nf}from"async_hooks";function Ml(){let e=R(),t=e.langfusePublicKey||process.env.LANGFUSE_PUBLIC_KEY,n=e.langfuseSecretKey||process.env.LANGFUSE_SECRET_KEY;if(!(e.langfuseEnabled===!0||process.env.LANGFUSE_ENABLED==="true")||!t||!n)return null;let o=(e.langfuseBaseUrl||process.env.LANGFUSE_BASE_URL||sf).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function tr(){return Ml()!==null}function ho(e){if(typeof e=="string")return e.length>En?e.slice(0,En)+`\u2026[+${e.length-En} chars]`:e;try{let t=JSON.stringify(e);if(t&&t.length>En)return t.slice(0,En)+`\u2026[+${t.length-En} chars]`}catch{return"[unserializable]"}return e}async function tt(e,t){if(!tr())return t();let n=Bt();nn.push({id:Bt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},...e.userId?{userId:e.userId}:{},...e.input!==void 0?{input:ho(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await fo.run({traceId:n,sessionId:e.sessionId},t)}finally{await Il()}}async function te(e,t,n){let s=fo.getStore();if(!tr()||!s?.traceId)return t();let o=Bt(),i=s.spanId,r=new Date,a,l;try{return await fo.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{nn.push({id:Bt(),type:"span-create",timestamp:new Date().toISOString(),body:{id:o,traceId:s.traceId,name:e,startTime:r.toISOString(),endTime:new Date().toISOString(),...i?{parentObservationId:i}:{},...n?.input!==void 0?{input:ho(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function of(e){if(tr())try{let t=fo.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Bt(),o=!0,nn.push({id:Bt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let i=e.usage?Al(e.usage):void 0,r=e.usage?cs(e.model,e.usage):void 0;nn.push({id:Bt(),type:"generation-create",timestamp:new Date().toISOString(),body:{id:Bt(),traceId:n,...s?{parentObservationId:s}:{},name:e.name,model:e.model,startTime:(e.startTime??new Date).toISOString(),endTime:(e.endTime??new Date).toISOString(),...e.input!==void 0?{input:ho(e.input)}:{},...e.output!==void 0?{output:ho(e.output)}:{},...i?{usageDetails:i}:{},...r?{costDetails:r}:{},...e.level?{level:e.level}:{},...e.statusMessage?{statusMessage:e.statusMessage}:{},metadata:{...e.engine?{engine:e.engine}:{},...e.metadata??{}}}}),o&&await Il()}catch(t){E.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function St(e){let{engine:t,model:n,name:s,usage:o,startTime:i,endTime:r}=e,a=r.getTime()-i.getTime(),l=o?cs(n,o):void 0;if(o&&E.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),El.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:i,endTime:r,durationMs:a};for(let d of El)try{d(c)}catch{}}$l(n,o),of({name:s,model:n,engine:t,input:e.input,output:e.output,usage:o,startTime:i,endTime:r,level:e.level,statusMessage:e.statusMessage,metadata:e.metadata})}async function Il(){let e=Ml();if(!e||nn.length===0)return;let t=nn;nn=[];try{let n=Buffer.from(`${e.publicKey}:${e.secretKey}`).toString("base64"),s=await fetch(`${e.baseUrl}/api/public/ingestion`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Basic ${n}`},body:JSON.stringify({batch:t})});if(!s.ok&&s.status!==207){let o=await s.text().catch(()=>"");E.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else E.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){E.warn("langfuse",`ingestion failed: ${n.message}`)}}var sf,En,fo,nn,El,Be=N(()=>{"use strict";y();ee();le();tn();er();sf="https://cloud.langfuse.com",En=24e3,fo=new nf,nn=[],El=new Set});import{join as me}from"path";import{readdirSync as it,rmSync as yf}from"fs";function Co(e){let t=[];for(let n of e){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),/dnd.area.*only.*have.*name.*main/i.test(s)&&(o=!0),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function ko(e){let t=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(e)&&t.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(e)&&t.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(e)){let n=e.match(/field.*?(\w+)\s+has an invalid/i);t.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(e)){let n=e.match(/file '([^']+)'/i);t.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(e)&&t.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),/dnd.area.*only.*have.*name.*main/i.test(e)&&t.push({file:"templates/email.html",message:'Dnd area can only have name "main"',fixable:!0}),t}function To(e){let t=[];return Dl(e)&&t.push("textarea \u2192 text"),jl(e)&&t.push("name \u2192 item_name"),Ll(e)&&t.push("now() \u2192 local_dt"),Jl(e)&&t.push("Removed HubDB templates"),Bl(e)&&t.push("Fixed link field defaults"),Hl(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),bf(e)&&t.push("Stripped CDN @import statements"),Gl(e)&&t.push('dnd_area \u2192 "main" in email templates'),Wl(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function Fl(e,t){return t.message.includes("textarea")?Dl(e):t.message.includes("reserved field name")?jl(e):t.message.includes("now()")?Ll(e):t.message.includes("HubDB")?Jl(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?Bl(e):t.message.includes("invalid format")&&t.message.includes("color")?Hl(e):t.message.includes("dnd")||t.message.includes("Dnd area")?Gl(e):t.message.includes("dnd_area_stylesheet")?Wl(e):!1}function Dl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),B(o,i),t=!0)}return t}function jl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),B(o,i),t=!0)}return t}function Ll(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"module.html");if(!x(o))continue;let i=P(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),B(o,i),t=!0)}return t}function Jl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(yf(o),t=!0)}return t}function Bl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));Kl(i)&&(B(o,JSON.stringify(i,null,2)+`
182
- `),t=!0)}catch{}}return t}function bf(e){let t=!1,n=me(e,"css");if(x(n))for(let o of it(n)){if(!o.endsWith(".css"))continue;let i=me(n,o),r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(B(i,a),t=!0)}let s=me(e,"modules");if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.css");if(!x(i))continue;let r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(B(i,a),t=!0)}if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.html");if(!x(i))continue;let r=P(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(B(i,a),t=!0)}return t}function Hl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));Ul(i)&&(B(o,JSON.stringify(i,null,2)+`
183
- `),t=!0)}catch{}}return t}function Ul(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="color"&&s.default&&typeof s.default=="object"){let o=s.default,i=o.color;if(typeof i=="string"&&!Sf(i)){let r=vf(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&Ul(s.children)&&(t=!0)}return t}function Sf(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function vf(e){let t=e.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(t)return{hex:`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`};let n=e.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),r=Math.min(255,parseInt(n[2])),a=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=e.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function Gl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i))continue;let r=i.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');r!==i&&(B(o,r),t=!0)}return t}function Wl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i)||i.includes("dnd_area_stylesheet"))continue;let r=i.replace(/(\{\{\s*standard_header_includes\s*\}\})/,`$1
184
- {{ dnd_area_stylesheet }}`);r!==i&&(B(o,r),t=!0)}return t}function Kl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&Kl(s.children)&&(t=!0)}return t}var Ao=N(()=>{"use strict";y();oe()});import{readdirSync as xf}from"fs";import{join as wf,relative as Cf}from"path";function Vl(e){let t=[];for(let n of xf(e,{withFileTypes:!0})){if(kf.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=wf(e,n.name);n.isDirectory()?t.push(...Vl(s)):n.isFile()&&t.push(s)}return t}async function Tf(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function _o(e,t,n,s={}){let o=s.concurrency??5,i=Vl(t),r=i.length,a=0,l=0,c=[];return await Tf(i,o,async d=>{let u=Cf(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await rl(e,m,d);if(g.success)a++,s.onFileComplete?.(u);else{l++;let h={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(h),s.onFileError?.(u,h)}s.onProgress?.(a+l,r)}),{success:l===0,uploaded:a,failed:l,total:r,errors:c}}var kf,nr=N(()=>{"use strict";y();en();en();kf=new Set([".git","node_modules",".vibespot",".DS_Store"])});var nc=N(()=>{"use strict";y()});import{existsSync as It,writeFileSync as Ef,mkdirSync as Mf}from"fs";import{join as vt}from"path";function oc(e){return/^[0-9a-f]{4,40}$/i.test(e)}function ic(e){return Number.isInteger(e)&&e>0&&e<1e3}function rt(){return $o!==null||($o=Z(["--version"]).success),$o}function Eo(e){if(!rt())return!1;if(It(vt(e,".git")))return sc(e),!0;let t=Z(["init"],{cwd:e});return t.success?(If(e),sc(e),Z(["add","-A"],{cwd:e}),Z(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function sc(e){let t=vt(e,".vibespot");It(t)||Mf(t,{recursive:!0})}function If(e){let t=vt(e,".gitignore");Ef(t,[".vibespot/","node_modules/",""].join(`
185
- `),"utf-8")}function sn(e,t){if(!rt()||!It(vt(e,".git"))||(Z(["add","-A"],{cwd:e}),Z(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=Z(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=Z(["rev-parse","--short","HEAD"],{cwd:e});return i.success?i.stdout:null}function or(e,t,n,s){if(!rt()||!It(vt(e,".git")))return null;for(let u of s){let m=vt(e,u);It(m)&&Z(["add","--",u],{cwd:e})}if(Z(["diff","--cached","--quiet"],{cwd:e}).success)return null;let i=`[${t}] `,r=72-i.length,a=n.length>r?n.slice(0,r-3)+"...":n,l=i+a,c=Z(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=Z(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function rc(e){let t=[],n=null;for(let s of e.split(`
186
- `)){let o=s.trimEnd();if(o.startsWith("COMMIT|")){n&&t.push(n);let i=o.slice(7).split("|");if(i.length<4){n=null;continue}let r=parseInt(i[3],10)*1e3;n={hash:i[0],fullHash:i[1],message:i[2],timestamp:r,date:new Date(r).toISOString(),changedFiles:[],changedModules:[]}}else o&&n&&n.changedFiles.push(o)}n&&t.push(n);for(let s of t){if(!s.changedFiles)continue;let o=new Set;for(let i of s.changedFiles){let r=i.match(/^modules\/([^/]+)\.module(?:\/|$)/);r&&o.add(r[1])}s.changedModules=[...o]}return t}function ac(e,t=50){if(!rt())return[];if(!It(vt(e,".git")))return[];if(!ic(t))return[];let n=Z(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:rc(n.stdout)}function lc(e,t,n=50){if(!rt())return[];if(!It(vt(e,".git")))return[];if(!ic(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=Z(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:rc(o.stdout)}function cc(e,t){if(!rt())return{success:!1,error:"Git not available"};if(!It(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!oc(t))return{success:!1,error:"Invalid commit hash"};let n=Z(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=Z(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=Z(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return Z(["commit","-m",r],{cwd:e}),{success:!0}}function dc(e,t,n,s){if(!rt())return{success:!1,error:"Git not available"};if(!It(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!oc(n))return{success:!1,error:"Invalid commit hash"};let o=Z(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=Z(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)Z(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};Z(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return Z(["commit","-m",c],{cwd:e}),{success:!0}}var $o,In=N(()=>{"use strict";y();qt();$o=null});import{readFileSync as Pf,existsSync as mc,writeFileSync as Nf,mkdirSync as Rf,rmSync as Of}from"fs";import{join as Mo}from"path";function on(e){let t=C();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e.plan)}function at(){let e=C();if(!e)return;let t=ke();if(!t){if(e.modules.length===0)return;let n={modules:e.modules,moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,template:e.template,messages:e.messages,plan:e.brandAssets?.plan};t=Pt("landing_page",`${e.themeName} Landing Page`),e.activeTemplateId=t.id,e.modules=n.modules,e.moduleOrder=n.moduleOrder,e.sharedCss=n.sharedCss,e.sharedJs=n.sharedJs,e.template=n.template,e.messages=n.messages,e.brandAssets&&(e.brandAssets.plan=n.plan)}t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.plan=e.brandAssets?.plan}function lt(e,t,n){let s=C();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),at(),Df()}function pc(e){let t=C();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),L())}function gc(e){let t=C();if(!t)return;if(e.calls===0)return t.costTotal;let n=t.costTotal??{costUsd:0,totalTokens:0,generations:0,costComplete:!0},s={costUsd:n.costUsd+e.costUsd,totalTokens:n.totalTokens+e.totalTokens,generations:n.generations+1,costComplete:n.costComplete&&e.costComplete};return t.costTotal=s,t.updatedAt=Date.now(),s}function uc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function Ff(e,t){let n=uc(e),s=uc(t);if(n===s)return!0;if(n.length<4||s.length<4)return!1;let o=n.length<=s.length?n:s,i=n.length<=s.length?s:n;return i.includes(o)?o.length/i.length>=.8:!1}function He(e){let t=C();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let i=t.modules.find(r=>Ff(r.moduleName,n.moduleName));i&&E.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${i.moduleName}" \u2014 adding as a new module. This usually indicates the Module Planner re-named an existing module. Check the prompt's "preserve existing names" rule.`),t.modules.push(n),t.moduleOrder.some(r=>r.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),at()}}function Ht(e){let t=C();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),at())}function fc(e){let t=C();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=Mo(t.themePath,"modules",`${e}.module`);mc(n)&&Of(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),at()}}function hc(e){let t=C();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),at())}function yc(e,t,n){let s=C();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);vc(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),at()}catch{}}function ve(){let e=C();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Df(){let e=C();if(e)try{let t=Mo(e.themePath,".vibespot");Rf(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};Nf(Mo(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function bc(e){let t=Mo(e,".vibespot","chat.json");if(!mc(t))return[];try{let n=JSON.parse(Pf(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Sc(e){let t=C();if(t){for(let n of t.templates)n.sharedCss=e.sharedCss,n.sharedJs=e.sharedJs;t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs;for(let n of e.pages){let s=e.pageLabels.get(n.pageId),o=s?.label||n.pageId,i=s?.pageType||"website_page",r=t.templates.find(a=>a.id===n.templateId);r||(r=Pt(i,o),r.id=n.templateId,r.templateFile=`templates/${n.templateId}.html`),r.modules=n.modules,r.moduleOrder=n.moduleOrder,r.sharedCss=e.sharedCss,r.sharedJs=e.sharedJs}e.pages.length>0&&ms(e.pages[0].templateId),t.updatedAt=Date.now()}}function vc(e,t,n){let s=t.split("."),o=s[0],i=e.find(r=>r.name===o);i&&(s.length===1?i.default=n:i.children&&vc(i.children,s.slice(1).join("."),n))}var us=N(()=>{"use strict";y();ps();Ut();le()});import{existsSync as Io,rmSync as Po}from"fs";import{join as Pn}from"path";function No(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function ke(){let e=C();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function ms(e){let t=C();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,on(n),t.updatedAt=Date.now(),!0):!1}function Pt(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=n==="email",a=`${i?"email":e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:t,pageType:e,contentMode:n,templateFile:i?"templates/email.html":e==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,on(l),s.updatedAt=Date.now(),l}function xc(e,t){let n=C();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:a,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${a}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[],plan:s.plan};return n.templates.push(l),n.activeTemplateId=a,on(l),n.updatedAt=Date.now(),l}function wc(e){let t=C();if(!t||!Array.isArray(e)||e.length===0)return!1;let n=new Map(t.templates.map(i=>[i.id,i])),s=new Set,o=[];for(let i of e){let r=n.get(i);!r||s.has(i)||(o.push(r),s.add(i))}for(let i of t.templates)s.has(i.id)||o.push(i);return o.length!==t.templates.length?!1:(t.templates=o,t.updatedAt=Date.now(),!0)}function Cc(e,t){let n=C();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function kc(e,t=!1){let n=C();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Pn(n.themePath,"templates"),r=`${o.id}.html`,a=Pn(i,r);if(Io(a)&&Po(a,{force:!0}),o.pageType==="blog_post"){let l=Pn(i,`${o.id}-listing.html`);Io(l)&&Po(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let a of n.templates)for(let l of a.modules)i.add(l.moduleName);for(let a of n.modules)i.add(a.moduleName);let r=o.modules.map(a=>a.moduleName).filter(a=>!i.has(a));if(n.themePath&&r.length>0){let a=Pn(n.themePath,"modules");for(let l of r){let c=Pn(a,`${l}.module`);Io(c)&&Po(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?ms(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[],n.brandAssets&&delete n.brandAssets.plan)),o.plan&&n.themePath&&!n.templates.some(r=>!!r.plan)){let r=Pn(n.themePath,".vibespot","plan.md");Io(r)&&Po(r,{force:!0})}return n.updatedAt=Date.now(),!0}function Nt(){let e=C();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of e.modules)t.has(n.moduleName)||t.set(n.moduleName,{module:n,usedIn:[]});return Array.from(t.values())}var Ut=N(()=>{"use strict";y();ps();us()});import{readFileSync as xt,readdirSync as cr,existsSync as Ie,writeFileSync as gs,mkdirSync as Ro,rmSync as ir,renameSync as rr,cpSync as jf}from"fs";import{join as pe,dirname as Tc}from"path";import{homedir as Lf}from"os";function Oo(){if(Nn)return Nn;try{return Ie(ar)?(Nn=JSON.parse(xt(ar,"utf-8")),Nn):lr()}catch{return lr()}}function Fo(e){Nn=e;try{Ro(de,{recursive:!0}),gs(ar,JSON.stringify(e),"utf-8")}catch{}}function lr(){if(!Ie(de))return[];let e=[];for(let t of cr(de).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(xt(pe(de,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length,pageCount:s.filter(o=>o.contentMode!=="email").length,emailCount:s.filter(o=>o.contentMode==="email").length,hasBrandAssets:!!(n.brandAssets&&(n.brandAssets.styleguide||n.brandAssets.brandvoice||n.brandAssets.brandKit)),isImported:!!n.isImported})}catch{}return Nn=e,Fo(e),e}function Ac(e){let t=Oo(),n=e.templates||[],s={id:e.id,themeName:e.themeName,updatedAt:e.updatedAt,moduleCount:n.reduce((i,r)=>i+(r.modules?.length||0),0),templateCount:n.length,pageCount:n.filter(i=>i.contentMode!=="email").length,emailCount:n.filter(i=>i.contentMode==="email").length,hasBrandAssets:!!(e.brandAssets&&(e.brandAssets.styleguide||e.brandAssets.brandvoice||e.brandAssets.brandKit)),isImported:!!e.isImported},o=t.findIndex(i=>i.id===e.id);o>=0?t[o]=s:t.push(s),Fo(t)}function Jf(e){let t=Oo().filter(n=>n.id!==e);Fo(t)}function Bf(e){let t=Oo().filter(n=>n.themeName!==e);Fo(t)}function C(){return Ue}function _c(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Rn(e,t,n={}){let s={id:_c(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Ue=s,Eo(e),s}function L(){if(!Ue)return;Ro(de,{recursive:!0});let e=pe(de,`${Ue.id}.json`);gs(e,JSON.stringify(Ue,null,2),"utf-8"),Ac(Ue)}function Do(e){let t=pe(de,e+".json");if(!Ie(t))return null;try{let n=JSON.parse(xt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),No(n),n.brandAssets?.plan&&n.templates?.length>0){let s=n.templates.find(o=>o.id===n.activeTemplateId)||n.templates[0];s.plan||(s.plan=n.brandAssets.plan)}return Ue=n,n}catch{return null}}function On(){return Ie(de)?Oo():[]}function $c(e,t=!1){let n=pe(de,e+".json"),s="";if(t)try{let o=JSON.parse(xt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ie(o.themePath)&&ir(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(xt(n,"utf-8")).themeName||""}catch{}try{Ie(n)&&ir(n)}catch{}if(s&&Ie(de)){for(let o of cr(de).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(xt(pe(de,o),"utf-8")).themeName===s&&ir(pe(de,o))}catch{}Bf(s)}else Jf(e);Ue?.id===e&&(Ue=null)}function Ec(e,t){let n=pe(de,e+".json");if(!Ie(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(xt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,r=pe(Tc(i),t);if(Ie(i)){if(Ie(r))return{ok:!1,error:"A project with that name already exists"};try{rr(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=pe(r,"css",`${o}-theme.css`),l=pe(r,"css",`${t}-theme.css`);if(Ie(a))try{rr(a,l)}catch{}let c=pe(r,"js",`${o}-animations.js`),d=pe(r,"js",`${t}-animations.js`);if(Ie(c))try{rr(c,d)}catch{}let u=pe(r,"theme.json");if(Ie(u))try{let m=JSON.parse(xt(u,"utf-8"));m.label=t,m.name=t,gs(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ie(de))for(let a of cr(de).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(xt(pe(de,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),gs(pe(de,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Ue&&Ue.themeName===o&&(Ue.themeName=t,Ue.themePath=r,Ue.updatedAt=Date.now()),lr(),{ok:!0}}function Mc(e){let t=pe(de,e+".json");if(!Ie(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(xt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=Tc(n.themePath),i=`${s}-copy`,r=1;for(;Ie(pe(o,i));)r++,i=`${s}-copy-${r}`;let a=pe(o,i);if(Ie(n.themePath))try{jf(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else Ro(a,{recursive:!0});let l=_c(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return Ro(de,{recursive:!0}),gs(pe(de,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Ac(c),{ok:!0,newName:i,newSessionId:l}}var de,ar,Nn,Ue,ps=N(()=>{"use strict";y();In();Ut();de=pe(Lf(),".vibespot","sessions"),ar=pe(de,"_index.json"),Nn=null;Ue=null});import{readFileSync as Hf,readdirSync as Nc,statSync as dr}from"fs";import{createHash as Uf}from"crypto";import{join as be,relative as Gf}from"path";function Jo(e){let t=[];if(!x(e))return fh(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=Fn(e),s=uh(e),o=ph(e),i=gh(e),r=Yf(e);Object.keys(n.cssVariables).length===0&&t.push({severity:"info",rule:"design.cssVariables.empty",message:"No :root CSS custom properties found in theme CSS.",fix:"Run with --apply-tokens to seed a :root block from inferred palette/typography."}),n.palette.length===0&&t.push({severity:"info",rule:"design.palette.empty",message:"Could not infer a colour palette from the theme CSS."}),s.orphanModules.length>0&&t.push({severity:"warning",rule:"modules.orphan",message:`${s.orphanModules.length} module(s) are not referenced by any template: ${s.orphanModules.join(", ")}`,fix:"Either reference these modules from a template or remove them."}),s.templates.length===0&&s.modules.length>0&&t.push({severity:"warning",rule:"templates.missing",message:"Theme has modules but no page templates wiring them together.",fix:"Add a templates/<name>.html that includes the modules via dnd_module."});for(let l of o)t.push({severity:"info",rule:"field.unsupported-pattern",file:`modules/${l.module}.module/fields.json`,message:`${l.module}.${l.field}: ${l.reason}`,fix:"vibeSpot will preserve this field as-is. Edit it in HubSpot if changes are needed."});for(let l of i)t.push({severity:"warning",rule:"roundtrip.preserve-pattern",file:l.file,message:`${l.pattern}: ${l.detail}`,fix:"vibeSpot avoids modifying this. Don't ask the AI to refactor it."});r.hasSnapshot&&r.filesChanged>0&&t.push({severity:"info",rule:"roundtrip.snapshot.diff",message:`${r.filesChanged} file(s) differ from the imported theme snapshot.`,fix:"Review report.roundTripDiff before re-uploading if you need to preserve imported files exactly."});let a=i.filter(l=>l.pattern==="hubl.macro").length;return{themePath:e,designTokens:n,graph:s,fieldFlags:o,roundTripRisks:i,roundTripDiff:r,findings:t,summary:{moduleCount:s.modules.length,templateCount:s.templates.length,orphanCount:s.orphanModules.length,paletteSize:n.palette.length,cssVarCount:Object.keys(n.cssVariables).length,customMacroCount:a,roundTripChangedCount:r.filesChanged}}}function fs(e){let t=[];for(let[n,s]of Object.entries(e.cssVariables))t.push(` ${n}: ${s};`);return Object.keys(e.cssVariables).length===0&&(e.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;t.push(` --color-${o}: ${n.value};`)}),e.fontFamilies[0]&&t.push(` --font-family-base: ${e.fontFamilies[0]};`),e.fontFamilies[1]&&t.push(` --font-family-heading: ${e.fontFamilies[1]};`)),t.length===0?"":`:root {
180
+ Return ONLY the template HTML content, no markdown fences.`}var Hl,Ve=R(()=>{"use strict";y();ae();Hl=new Map});import{appendFileSync as Ff,mkdirSync as Df,readdirSync as jf,unlinkSync as Lf}from"fs";import{join as fr}from"path";import{homedir as Bf}from"os";function Hf(){if(!pr)try{Df(Ao,{recursive:!0}),pr=!0}catch{}}function Uf(){if(!gr){gr=!0;try{let e=Date.now()-Jf*864e5;for(let t of jf(Ao)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{Lf(fr(Ao,t))}catch{}}}catch{}}}function Gf(){let t=new Date().toISOString().slice(0,10);return fr(Ao,`vibespot-${t}.log`)}function Wf(){return new Date().toISOString().slice(11,23)}function mr(e,t){if(Hf(),!!pr){gr||Uf();try{Ff(Gf(),`${Wf()} ${e} ${t}
181
+ `)}catch{}}}var Ao,Jf,pr,gr,T,de=R(()=>{"use strict";y();Ao=fr(Bf(),".vibespot","logs"),Jf=7,pr=!1,gr=!1;T={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),mr("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),mr("WARN",s)},error(e,t,n){let s=n instanceof Error?n.message:n?String(n):"",o=s?`[${e}] ${t}: ${s}`:`[${e}] ${t}`;console.error(o),mr("ERROR",o)}}});function Vf(e){let t=(e||"").toLowerCase();return Kf.find(n=>t.includes(n.match))}function fs(e,t){let n=Vf(e);if(!n)return;let s=n.cacheReadPerM??n.inputPerM*.1,o=n.cacheWritePerM??n.inputPerM*1.25,i=(t.inputTokens??0)*n.inputPerM,r=(t.outputTokens??0)*n.outputPerM,a=(t.cacheReadTokens??0)*s,l=(t.cacheCreationTokens??0)*o,c={total:(i+r+a+l)/1e6};return t.inputTokens!=null&&(c.input=i/1e6),t.outputTokens!=null&&(c.output=r/1e6),t.cacheReadTokens&&(c.cache_read_input_tokens=a/1e6),t.cacheCreationTokens&&(c.cache_creation_input_tokens=l/1e6),c}function st(e){if(e)return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_input_tokens??void 0,cacheCreationTokens:e.cache_creation_input_tokens??void 0}}function On(e){if(!e)return;let t=e.prompt_tokens_details?.cached_tokens??0,n=e.prompt_tokens;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.completion_tokens,totalTokens:e.total_tokens,cacheReadTokens:t||void 0}}function Fn(e){if(!e)return;let t=e.cachedContentTokenCount??0,n=e.promptTokenCount;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.candidatesTokenCount,totalTokens:e.totalTokenCount,cacheReadTokens:t||void 0}}function Xl(e){let t={};return e.inputTokens!=null&&(t.input=e.inputTokens),e.outputTokens!=null&&(t.output=e.outputTokens),e.cacheReadTokens&&(t.cache_read_input_tokens=e.cacheReadTokens),e.cacheCreationTokens&&(t.cache_creation_input_tokens=e.cacheCreationTokens),e.totalTokens!=null&&(t.total=e.totalTokens),t}var Kf,an=R(()=>{"use strict";y();Kf=[{match:"claude-opus-4",inputPerM:15,outputPerM:75},{match:"claude-sonnet-4",inputPerM:3,outputPerM:15},{match:"claude-haiku-4",inputPerM:1,outputPerM:5},{match:"claude-3-7-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-haiku",inputPerM:.8,outputPerM:4},{match:"claude-3-opus",inputPerM:15,outputPerM:75},{match:"gpt-5.5",inputPerM:5,outputPerM:30},{match:"gpt-5.4",inputPerM:2.5,outputPerM:15},{match:"gpt-5.3",inputPerM:1.75,outputPerM:14},{match:"gpt-4o-mini",inputPerM:.15,outputPerM:.6},{match:"gpt-4o",inputPerM:2.5,outputPerM:10},{match:"gpt-4.1-nano",inputPerM:.1,outputPerM:.4},{match:"gpt-4.1-mini",inputPerM:.4,outputPerM:1.6},{match:"gpt-4.1",inputPerM:2,outputPerM:8},{match:"gemini-2.5-pro",inputPerM:1.25,outputPerM:10},{match:"gemini-2.5-flash",inputPerM:.3,outputPerM:2.5},{match:"gemini-2.0-flash",inputPerM:.1,outputPerM:.4},{match:"gemini-1.5-pro",inputPerM:1.25,outputPerM:5},{match:"gemini-1.5-flash",inputPerM:.075,outputPerM:.3}]});import{AsyncLocalStorage as zf}from"async_hooks";function Yf(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function Zl(e){return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,cacheReadTokens:e.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens,totalTokens:e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens,costUsd:e.costUsd,calls:e.calls,costComplete:e.unpricedCalls===0}}async function _o(e){let t=Yf();return{result:await hr.run(t,e),cost:Zl(t)}}function Ql(e,t){if(!t)return;let n=hr.getStore();if(!n)return;n.inputTokens+=t.inputTokens??0,n.outputTokens+=t.outputTokens??0,n.cacheReadTokens+=t.cacheReadTokens??0,n.cacheCreationTokens+=t.cacheCreationTokens??0,n.calls+=1;let s=fs(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}function ec(){let e=hr.getStore();return e?Zl(e):null}var hr,$o=R(()=>{"use strict";y();an();hr=new zf});import{randomUUID as Ft}from"crypto";import{AsyncLocalStorage as qf}from"async_hooks";function sc(){let e=N(),t=e.langfusePublicKey||process.env.LANGFUSE_PUBLIC_KEY,n=e.langfuseSecretKey||process.env.LANGFUSE_SECRET_KEY;if(!(e.langfuseEnabled===!0||process.env.LANGFUSE_ENABLED==="true")||!t||!n)return null;let o=(e.langfuseBaseUrl||process.env.LANGFUSE_BASE_URL||Xf).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function Po(){return sc()!==null}function ys(e,t=Zf){if(typeof e=="string")return e.length>t?e.slice(0,t)+`\u2026[+${e.length-t} chars]`:e;try{let n=JSON.stringify(e);if(n&&n.length>t)return n.slice(0,t)+`\u2026[+${n.length-t} chars]`}catch{return"[unserializable]"}return e}async function ze(e,t){if(!Po())return t();let n=Ft();Kt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},...e.userId?{userId:e.userId}:{},...e.input!==void 0?{input:ys(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await hs.run({traceId:n,sessionId:e.sessionId},t)}finally{await oc()}}function Eo(e){if(!Po())return;let t=hs.getStore();t?.traceId&&Kt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:t.traceId,timestamp:new Date().toISOString(),output:ys(e)}})}async function se(e,t,n){let s=hs.getStore();if(!Po()||!s?.traceId)return t();let o=Ft(),i=s.spanId,r=new Date,a,l;try{return await hs.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{Kt.push({id:Ft(),type:"span-create",timestamp:new Date().toISOString(),body:{id:o,traceId:s.traceId,name:e,startTime:r.toISOString(),endTime:new Date().toISOString(),...i?{parentObservationId:i}:{},...n?.input!==void 0?{input:ys(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function Qf(e){if(Po())try{let t=hs.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Ft(),o=!0,Kt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let i=e.usage?Xl(e.usage):void 0,r=e.usage?fs(e.model,e.usage):void 0;Kt.push({id:Ft(),type:"generation-create",timestamp:new Date().toISOString(),body:{id:Ft(),traceId:n,...s?{parentObservationId:s}:{},name:e.name,model:e.model,startTime:(e.startTime??new Date).toISOString(),endTime:(e.endTime??new Date).toISOString(),...e.input!==void 0?{input:ys(e.input,tc)}:{},...e.output!==void 0?{output:ys(e.output,tc)}:{},...i?{usageDetails:i}:{},...r?{costDetails:r}:{},...e.level?{level:e.level}:{},...e.statusMessage?{statusMessage:e.statusMessage}:{},...e.promptName?{promptName:e.promptName,...e.promptVersion!=null?{promptVersion:e.promptVersion}:{}}:{},metadata:{...e.engine?{engine:e.engine}:{},...e.metadata??{}}}}),o&&await oc()}catch(t){T.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function kt(e){let{engine:t,model:n,name:s,usage:o,startTime:i,endTime:r}=e,a=r.getTime()-i.getTime(),l=o?fs(n,o):void 0;if(o&&T.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),nc.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:i,endTime:r,durationMs:a};for(let d of nc)try{d(c)}catch{}}Ql(n,o),Qf({name:s,model:n,engine:t,input:e.input,output:e.output,usage:o,startTime:i,endTime:r,level:e.level,statusMessage:e.statusMessage,metadata:e.metadata,promptName:e.promptName,promptVersion:e.promptVersion})}async function oc(){let e=sc();if(!e||Kt.length===0)return;let t=Kt;Kt=[];try{let n=Buffer.from(`${e.publicKey}:${e.secretKey}`).toString("base64"),s=await fetch(`${e.baseUrl}/api/public/ingestion`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Basic ${n}`},body:JSON.stringify({batch:t})});if(!s.ok&&s.status!==207){let o=await s.text().catch(()=>"");T.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else T.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){T.warn("langfuse",`ingestion failed: ${n.message}`)}}var Xf,Zf,tc,hs,Kt,nc,He=R(()=>{"use strict";y();oe();de();an();$o();Xf="https://cloud.langfuse.com",Zf=24e3,tc=2e5,hs=new qf,Kt=[],nc=new Set});import{join as pe}from"path";import{readdirSync as at,rmSync as uh}from"fs";function Do(e){let t=[];for(let n of e){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),/dnd.area.*only.*have.*name.*main/i.test(s)&&(o=!0),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function jo(e){let t=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(e)&&t.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(e)&&t.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(e)){let n=e.match(/field.*?(\w+)\s+has an invalid/i);t.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(e)){let n=e.match(/file '([^']+)'/i);t.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(e)&&t.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),/dnd.area.*only.*have.*name.*main/i.test(e)&&t.push({file:"templates/email.html",message:'Dnd area can only have name "main"',fixable:!0}),t}function Lo(e){let t=[];return dc(e)&&t.push("textarea \u2192 text"),uc(e)&&t.push("name \u2192 item_name"),mc(e)&&t.push("now() \u2192 local_dt"),pc(e)&&t.push("Removed HubDB templates"),gc(e)&&t.push("Fixed link field defaults"),fc(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),mh(e)&&t.push("Stripped CDN @import statements"),yc(e)&&t.push('dnd_area \u2192 "main" in email templates'),bc(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function cc(e,t){return t.message.includes("textarea")?dc(e):t.message.includes("reserved field name")?uc(e):t.message.includes("now()")?mc(e):t.message.includes("HubDB")?pc(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?gc(e):t.message.includes("invalid format")&&t.message.includes("color")?fc(e):t.message.includes("dnd")||t.message.includes("Dnd area")?yc(e):t.message.includes("dnd_area_stylesheet")?bc(e):!1}function dc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(!v(o))continue;let i=M(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),H(o,i),t=!0)}return t}function uc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(!v(o))continue;let i=M(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),H(o,i),t=!0)}return t}function mc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"module.html");if(!v(o))continue;let i=M(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),H(o,i),t=!0)}return t}function pc(e){let t=!1,n=pe(e,"templates");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".html"))continue;let o=pe(n,s),i=M(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(uh(o),t=!0)}return t}function gc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(v(o))try{let i=JSON.parse(M(o));Sc(i)&&(H(o,JSON.stringify(i,null,2)+`
182
+ `),t=!0)}catch{}}return t}function mh(e){let t=!1,n=pe(e,"css");if(v(n))for(let o of at(n)){if(!o.endsWith(".css"))continue;let i=pe(n,o),r=M(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(H(i,a),t=!0)}let s=pe(e,"modules");if(v(s))for(let o of at(s)){if(!o.endsWith(".module"))continue;let i=pe(s,o,"module.css");if(!v(i))continue;let r=M(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(H(i,a),t=!0)}if(v(s))for(let o of at(s)){if(!o.endsWith(".module"))continue;let i=pe(s,o,"module.html");if(!v(i))continue;let r=M(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(H(i,a),t=!0)}return t}function fc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(v(o))try{let i=JSON.parse(M(o));hc(i)&&(H(o,JSON.stringify(i,null,2)+`
183
+ `),t=!0)}catch{}}return t}function hc(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="color"&&s.default&&typeof s.default=="object"){let o=s.default,i=o.color;if(typeof i=="string"&&!ph(i)){let r=gh(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&hc(s.children)&&(t=!0)}return t}function ph(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function gh(e){let t=e.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(t)return{hex:`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`};let n=e.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),r=Math.min(255,parseInt(n[2])),a=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=e.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function yc(e){let t=!1,n=pe(e,"templates");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".html"))continue;let o=pe(n,s),i=M(o);if(!/templateType:\s*email/i.test(i))continue;let r=i.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');r!==i&&(H(o,r),t=!0)}return t}function bc(e){let t=!1,n=pe(e,"templates");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".html"))continue;let o=pe(n,s),i=M(o);if(!/templateType:\s*email/i.test(i)||i.includes("dnd_area_stylesheet"))continue;let r=i.replace(/(\{\{\s*standard_header_includes\s*\}\})/,`$1
184
+ {{ dnd_area_stylesheet }}`);r!==i&&(H(o,r),t=!0)}return t}function Sc(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&Sc(s.children)&&(t=!0)}return t}var Bo=R(()=>{"use strict";y();ae()});import{readdirSync as fh}from"fs";import{join as hh,relative as yh}from"path";function vc(e){let t=[];for(let n of fh(e,{withFileTypes:!0})){if(bh.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=hh(e,n.name);n.isDirectory()?t.push(...vc(s)):n.isFile()&&t.push(s)}return t}async function Sh(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function Jo(e,t,n,s={}){let o=s.concurrency??5,i=vc(t),r=i.length,a=0,l=0,c=[];return await Sh(i,o,async d=>{let u=yh(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await Ml(e,m,d);if(g.success)a++,s.onFileComplete?.(u);else{l++;let h={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(h),s.onFileError?.(u,h)}s.onProgress?.(a+l,r)}),{success:l===0,uploaded:a,failed:l,total:r,errors:c}}var bh,yr=R(()=>{"use strict";y();rn();rn();bh=new Set([".git","node_modules",".vibespot",".DS_Store"])});var Pc=R(()=>{"use strict";y()});import{existsSync as Dt,writeFileSync as kh,mkdirSync as Ch}from"fs";import{join as Ct}from"path";function Mc(e){return/^[0-9a-f]{4,40}$/i.test(e)}function Ic(e){return Number.isInteger(e)&&e>0&&e<1e3}function lt(){return Ho!==null||(Ho=te(["--version"]).success),Ho}function Uo(e){if(!lt())return!1;if(Dt(Ct(e,".git")))return Ec(e),!0;let t=te(["init"],{cwd:e});return t.success?(Th(e),Ec(e),te(["add","-A"],{cwd:e}),te(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Ec(e){let t=Ct(e,".vibespot");Dt(t)||Ch(t,{recursive:!0})}function Th(e){let t=Ct(e,".gitignore");kh(t,[".vibespot/","node_modules/",""].join(`
185
+ `),"utf-8")}function ln(e,t){if(!lt()||!Dt(Ct(e,".git"))||(te(["add","-A"],{cwd:e}),te(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=te(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=te(["rev-parse","--short","HEAD"],{cwd:e});return i.success?i.stdout:null}function Sr(e,t,n,s){if(!lt()||!Dt(Ct(e,".git")))return null;for(let u of s){let m=Ct(e,u);Dt(m)&&te(["add","--",u],{cwd:e})}if(te(["diff","--cached","--quiet"],{cwd:e}).success)return null;let i=`[${t}] `,r=72-i.length,a=n.length>r?n.slice(0,r-3)+"...":n,l=i+a,c=te(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=te(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function Rc(e){let t=[],n=null;for(let s of e.split(`
186
+ `)){let o=s.trimEnd();if(o.startsWith("COMMIT|")){n&&t.push(n);let i=o.slice(7).split("|");if(i.length<4){n=null;continue}let r=parseInt(i[3],10)*1e3;n={hash:i[0],fullHash:i[1],message:i[2],timestamp:r,date:new Date(r).toISOString(),changedFiles:[],changedModules:[]}}else o&&n&&n.changedFiles.push(o)}n&&t.push(n);for(let s of t){if(!s.changedFiles)continue;let o=new Set;for(let i of s.changedFiles){let r=i.match(/^modules\/([^/]+)\.module(?:\/|$)/);r&&o.add(r[1])}s.changedModules=[...o]}return t}function Nc(e,t=50){if(!lt())return[];if(!Dt(Ct(e,".git")))return[];if(!Ic(t))return[];let n=te(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:Rc(n.stdout)}function Oc(e,t,n=50){if(!lt())return[];if(!Dt(Ct(e,".git")))return[];if(!Ic(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=te(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:Rc(o.stdout)}function Fc(e,t){if(!lt())return{success:!1,error:"Git not available"};if(!Dt(Ct(e,".git")))return{success:!1,error:"Not a git repo"};if(!Mc(t))return{success:!1,error:"Invalid commit hash"};let n=te(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=te(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=te(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return te(["commit","-m",r],{cwd:e}),{success:!0}}function Dc(e,t,n,s){if(!lt())return{success:!1,error:"Git not available"};if(!Dt(Ct(e,".git")))return{success:!1,error:"Not a git repo"};if(!Mc(n))return{success:!1,error:"Invalid commit hash"};let o=te(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=te(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)te(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};te(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return te(["commit","-m",c],{cwd:e}),{success:!0}}var Ho,jn=R(()=>{"use strict";y();tn();Ho=null});import{readFileSync as Ah,existsSync as Lc,writeFileSync as _h,mkdirSync as $h,rmSync as Ph}from"fs";import{join as Go}from"path";function cn(e){let t=w();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e.plan)}function ct(){let e=w();if(!e)return;let t=Te();if(!t){if(e.modules.length===0)return;let n={modules:e.modules,moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,template:e.template,messages:e.messages,plan:e.brandAssets?.plan};t=jt("landing_page",`${e.themeName} Landing Page`),e.activeTemplateId=t.id,e.modules=n.modules,e.moduleOrder=n.moduleOrder,e.sharedCss=n.sharedCss,e.sharedJs=n.sharedJs,e.template=n.template,e.messages=n.messages,e.brandAssets&&(e.brandAssets.plan=n.plan)}t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.plan=e.brandAssets?.plan}function dt(e,t,n){let s=w();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),ct(),Mh()}function Bc(e){let t=w();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),F())}function Jc(e){let t=w();if(!t)return;if(e.calls===0)return t.costTotal;let n=t.costTotal??{costUsd:0,totalTokens:0,generations:0,costComplete:!0},s={costUsd:n.costUsd+e.costUsd,totalTokens:n.totalTokens+e.totalTokens,generations:n.generations+1,costComplete:n.costComplete&&e.costComplete};return t.costTotal=s,t.updatedAt=Date.now(),s}function jc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function Eh(e,t){let n=jc(e),s=jc(t);if(n===s)return!0;if(n.length<4||s.length<4)return!1;let o=n.length<=s.length?n:s,i=n.length<=s.length?s:n;return i.includes(o)?o.length/i.length>=.8:!1}function Ue(e){let t=w();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let i=t.modules.find(r=>Eh(r.moduleName,n.moduleName));i&&T.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${i.moduleName}" \u2014 adding as a new module. This usually indicates the Module Planner re-named an existing module. Check the prompt's "preserve existing names" rule.`),t.modules.push(n),t.moduleOrder.some(r=>r.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),ct()}}function Vt(e){let t=w();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),ct())}function Hc(e){let t=w();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=Go(t.themePath,"modules",`${e}.module`);Lc(n)&&Ph(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),ct()}}function Uc(e){let t=w();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),ct())}function Gc(e,t,n){let s=w();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);Vc(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),ct()}catch{}}function xe(){let e=w();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Mh(){let e=w();if(e)try{let t=Go(e.themePath,".vibespot");$h(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};_h(Go(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Wc(e){let t=Go(e,".vibespot","chat.json");if(!Lc(t))return[];try{let n=JSON.parse(Ah(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Kc(e){let t=w();if(t){for(let n of t.templates)n.sharedCss=e.sharedCss,n.sharedJs=e.sharedJs;t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs;for(let n of e.pages){let s=e.pageLabels.get(n.pageId),o=s?.label||n.pageId,i=s?.pageType||"website_page",r=t.templates.find(a=>a.id===n.templateId);r||(r=jt(i,o),r.id=n.templateId,r.templateFile=`templates/${n.templateId}.html`),r.modules=n.modules,r.moduleOrder=n.moduleOrder,r.sharedCss=e.sharedCss,r.sharedJs=e.sharedJs}e.pages.length>0&&vs(e.pages[0].templateId),t.updatedAt=Date.now()}}function Vc(e,t,n){let s=t.split("."),o=s[0],i=e.find(r=>r.name===o);i&&(s.length===1?i.default=n:i.children&&Vc(i.children,s.slice(1).join("."),n))}var Ss=R(()=>{"use strict";y();xs();zt();de()});import{existsSync as Wo,rmSync as Ko}from"fs";import{join as Ln}from"path";function Vo(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function Te(){let e=w();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function vs(e){let t=w();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,cn(n),t.updatedAt=Date.now(),!0):!1}function jt(e,t,n){let s=w();if(!s)throw new Error("No active session");let o=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=n==="email",a=`${i?"email":e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:t,pageType:e,contentMode:n,templateFile:i?"templates/email.html":e==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,cn(l),s.updatedAt=Date.now(),l}function zc(e,t){let n=w();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:a,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${a}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[],plan:s.plan};return n.templates.push(l),n.activeTemplateId=a,cn(l),n.updatedAt=Date.now(),l}function Yc(e){let t=w();if(!t||!Array.isArray(e)||e.length===0)return!1;let n=new Map(t.templates.map(i=>[i.id,i])),s=new Set,o=[];for(let i of e){let r=n.get(i);!r||s.has(i)||(o.push(r),s.add(i))}for(let i of t.templates)s.has(i.id)||o.push(i);return o.length!==t.templates.length?!1:(t.templates=o,t.updatedAt=Date.now(),!0)}function qc(e,t){let n=w();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function Xc(e,t=!1){let n=w();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Ln(n.themePath,"templates"),r=`${o.id}.html`,a=Ln(i,r);if(Wo(a)&&Ko(a,{force:!0}),o.pageType==="blog_post"){let l=Ln(i,`${o.id}-listing.html`);Wo(l)&&Ko(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let a of n.templates)for(let l of a.modules)i.add(l.moduleName);for(let a of n.modules)i.add(a.moduleName);let r=o.modules.map(a=>a.moduleName).filter(a=>!i.has(a));if(n.themePath&&r.length>0){let a=Ln(n.themePath,"modules");for(let l of r){let c=Ln(a,`${l}.module`);Wo(c)&&Ko(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?vs(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[],n.brandAssets&&delete n.brandAssets.plan)),o.plan&&n.themePath&&!n.templates.some(r=>!!r.plan)){let r=Ln(n.themePath,".vibespot","plan.md");Wo(r)&&Ko(r,{force:!0})}return n.updatedAt=Date.now(),!0}function Lt(){let e=w();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of e.modules)t.has(n.moduleName)||t.set(n.moduleName,{module:n,usedIn:[]});return Array.from(t.values())}var zt=R(()=>{"use strict";y();xs();Ss()});import{readFileSync as Tt,readdirSync as Cr,existsSync as Ee,writeFileSync as ws,mkdirSync as zo,rmSync as vr,renameSync as xr,cpSync as Ih}from"fs";import{join as ge,dirname as Zc}from"path";import{homedir as Rh}from"os";function Yo(){if(Bn)return Bn;try{return Ee(wr)?(Bn=JSON.parse(Tt(wr,"utf-8")),Bn):kr()}catch{return kr()}}function qo(e){Bn=e;try{zo(me,{recursive:!0}),ws(wr,JSON.stringify(e),"utf-8")}catch{}}function kr(){if(!Ee(me))return[];let e=[];for(let t of Cr(me).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(Tt(ge(me,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length,pageCount:s.filter(o=>o.contentMode!=="email").length,emailCount:s.filter(o=>o.contentMode==="email").length,hasBrandAssets:!!(n.brandAssets&&(n.brandAssets.styleguide||n.brandAssets.brandvoice||n.brandAssets.brandKit)),isImported:!!n.isImported})}catch{}return Bn=e,qo(e),e}function Qc(e){let t=Yo(),n=e.templates||[],s={id:e.id,themeName:e.themeName,updatedAt:e.updatedAt,moduleCount:n.reduce((i,r)=>i+(r.modules?.length||0),0),templateCount:n.length,pageCount:n.filter(i=>i.contentMode!=="email").length,emailCount:n.filter(i=>i.contentMode==="email").length,hasBrandAssets:!!(e.brandAssets&&(e.brandAssets.styleguide||e.brandAssets.brandvoice||e.brandAssets.brandKit)),isImported:!!e.isImported},o=t.findIndex(i=>i.id===e.id);o>=0?t[o]=s:t.push(s),qo(t)}function Nh(e){let t=Yo().filter(n=>n.id!==e);qo(t)}function Oh(e){let t=Yo().filter(n=>n.themeName!==e);qo(t)}function w(){return Ge}function ed(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Jn(e,t,n={}){let s={id:ed(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Ge=s,Uo(e),s}function F(){if(!Ge)return;zo(me,{recursive:!0});let e=ge(me,`${Ge.id}.json`);ws(e,JSON.stringify(Ge,null,2),"utf-8"),Qc(Ge)}function Xo(e){let t=ge(me,e+".json");if(!Ee(t))return null;try{let n=JSON.parse(Tt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Vo(n),n.brandAssets?.plan&&n.templates?.length>0){let s=n.templates.find(o=>o.id===n.activeTemplateId)||n.templates[0];s.plan||(s.plan=n.brandAssets.plan)}return Ge=n,n}catch{return null}}function Hn(){return Ee(me)?Yo():[]}function td(e,t=!1){let n=ge(me,e+".json"),s="";if(t)try{let o=JSON.parse(Tt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ee(o.themePath)&&vr(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(Tt(n,"utf-8")).themeName||""}catch{}try{Ee(n)&&vr(n)}catch{}if(s&&Ee(me)){for(let o of Cr(me).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(Tt(ge(me,o),"utf-8")).themeName===s&&vr(ge(me,o))}catch{}Oh(s)}else Nh(e);Ge?.id===e&&(Ge=null)}function nd(e,t){let n=ge(me,e+".json");if(!Ee(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(Tt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,r=ge(Zc(i),t);if(Ee(i)){if(Ee(r))return{ok:!1,error:"A project with that name already exists"};try{xr(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=ge(r,"css",`${o}-theme.css`),l=ge(r,"css",`${t}-theme.css`);if(Ee(a))try{xr(a,l)}catch{}let c=ge(r,"js",`${o}-animations.js`),d=ge(r,"js",`${t}-animations.js`);if(Ee(c))try{xr(c,d)}catch{}let u=ge(r,"theme.json");if(Ee(u))try{let m=JSON.parse(Tt(u,"utf-8"));m.label=t,m.name=t,ws(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ee(me))for(let a of Cr(me).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(Tt(ge(me,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),ws(ge(me,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Ge&&Ge.themeName===o&&(Ge.themeName=t,Ge.themePath=r,Ge.updatedAt=Date.now()),kr(),{ok:!0}}function sd(e){let t=ge(me,e+".json");if(!Ee(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(Tt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=Zc(n.themePath),i=`${s}-copy`,r=1;for(;Ee(ge(o,i));)r++,i=`${s}-copy-${r}`;let a=ge(o,i);if(Ee(n.themePath))try{Ih(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else zo(a,{recursive:!0});let l=ed(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return zo(me,{recursive:!0}),ws(ge(me,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Qc(c),{ok:!0,newName:i,newSessionId:l}}var me,wr,Bn,Ge,xs=R(()=>{"use strict";y();jn();zt();me=ge(Rh(),".vibespot","sessions"),wr=ge(me,"_index.json"),Bn=null;Ge=null});import{readFileSync as Fh,readdirSync as rd,statSync as Tr}from"fs";import{createHash as Dh}from"crypto";import{join as Se,relative as jh}from"path";function ei(e){let t=[];if(!v(e))return cy(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=qt(e),s=iy(e),o=ay(e),i=ly(e),r=Uh(e);Object.keys(n.cssVariables).length===0&&t.push({severity:"info",rule:"design.cssVariables.empty",message:"No :root CSS custom properties found in theme CSS.",fix:"Run with --apply-tokens to seed a :root block from inferred palette/typography."}),n.palette.length===0&&t.push({severity:"info",rule:"design.palette.empty",message:"Could not infer a colour palette from the theme CSS."}),s.orphanModules.length>0&&t.push({severity:"warning",rule:"modules.orphan",message:`${s.orphanModules.length} module(s) are not referenced by any template: ${s.orphanModules.join(", ")}`,fix:"Either reference these modules from a template or remove them."}),s.templates.length===0&&s.modules.length>0&&t.push({severity:"warning",rule:"templates.missing",message:"Theme has modules but no page templates wiring them together.",fix:"Add a templates/<name>.html that includes the modules via dnd_module."});for(let l of o)t.push({severity:"info",rule:"field.unsupported-pattern",file:`modules/${l.module}.module/fields.json`,message:`${l.module}.${l.field}: ${l.reason}`,fix:"vibeSpot will preserve this field as-is. Edit it in HubSpot if changes are needed."});for(let l of i)t.push({severity:"warning",rule:"roundtrip.preserve-pattern",file:l.file,message:`${l.pattern}: ${l.detail}`,fix:"vibeSpot avoids modifying this. Don't ask the AI to refactor it."});r.hasSnapshot&&r.filesChanged>0&&t.push({severity:"info",rule:"roundtrip.snapshot.diff",message:`${r.filesChanged} file(s) differ from the imported theme snapshot.`,fix:"Review report.roundTripDiff before re-uploading if you need to preserve imported files exactly."});let a=i.filter(l=>l.pattern==="hubl.macro").length;return{themePath:e,designTokens:n,graph:s,fieldFlags:o,roundTripRisks:i,roundTripDiff:r,findings:t,summary:{moduleCount:s.modules.length,templateCount:s.templates.length,orphanCount:s.orphanModules.length,paletteSize:n.palette.length,cssVarCount:Object.keys(n.cssVariables).length,customMacroCount:a,roundTripChangedCount:r.filesChanged}}}function dn(e){let t=[];for(let[n,s]of Object.entries(e.cssVariables))t.push(` ${n}: ${s};`);return Object.keys(e.cssVariables).length===0&&(e.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;t.push(` --color-${o}: ${n.value};`)}),e.fontFamilies[0]&&t.push(` --font-family-base: ${e.fontFamilies[0]};`),e.fontFamilies[1]&&t.push(` --font-family-heading: ${e.fontFamilies[1]};`)),t.length===0?"":`:root {
187
187
  ${t.join(`
188
188
  `)}
189
189
  }
190
- `}function Bo(e,t){let n=be(e,"css");if(x(n))try{for(let r of Nc(n))if(r.endsWith("-theme.css"))return null}catch{}let s=Fn(e),o=fs(s);if(!o)return null;let i=be(n,`${t}-theme.css`);return B(i,o),i}function hs(e){return be(e,Wf)}function Vf(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:Fc(e)}}function ur(e,t){let n=Vf(e,t),s=hs(e);return B(s,JSON.stringify(n,null,2)+`
191
- `),s}function Rc(e){let t=hs(e);return x(t)?null:ur(e)}function zf(e){let t=hs(e);if(!x(t))return null;try{let n=JSON.parse(P(t));return yh(n)?n:null}catch{return null}}function Yf(e){let t=hs(e),n=zf(e);if(!n)return{hasSnapshot:!1,snapshotPath:t,filesChanged:0,added:0,modified:0,deleted:0,files:[]};let s=new Map(n.files.map(d=>[d.path,d])),o=Fc(e),i=new Map(o.map(d=>[d.path,d])),r=[];for(let d of n.files){let u=i.get(d.path);u?u.sha256!==d.sha256&&r.push({file:d.path,status:"modified",beforeSha256:d.sha256,afterSha256:u.sha256,beforeSize:d.size,afterSize:u.size,beforeLines:Lo(d.text),afterLines:Lo(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:Lo(d.text)})}for(let d of o)s.has(d.path)||r.push({file:d.path,status:"added",afterSha256:d.sha256,afterSize:d.size,afterLines:Lo(d.text)});r.sort((d,u)=>d.file.localeCompare(u.file));let a=r.filter(d=>d.status==="added").length,l=r.filter(d=>d.status==="modified").length,c=r.filter(d=>d.status==="deleted").length;return{hasSnapshot:!0,snapshotPath:t,filesChanged:r.length,added:a,modified:l,deleted:c,files:r}}function Fn(e){let t=dh(e),n={},s=new Map,o=new Map,i=new Set,r=new Set,a=new Set,l=new Set,c=new Set;for(let u of t){let m;try{m=P(u)}catch{continue}let g,h=new RegExp(oh.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(ih.source,"g"),S;for(;(S=b.exec(f))!==null;){let v=S[1].trim(),w=S[2].trim();n[v]||(n[v]=w);let M=w.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if(M){let j=Ic(M[0]);o.set(j,v)}}}for(let f of[qf,Xf,Zf]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let v=Ic(S[0]);v&&s.set(v,(s.get(v)??0)+1)}}jo(m,Qf,i,ah),jo(m,eh,r,f=>f.trim()),rh(m,a),jo(m,nh,l,f=>f.trim()),jo(m,sh,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!ch(u)).sort((u,m)=>m[1]-u[1]).slice(0,12).map(([u,m])=>({value:u,count:m,varName:o.get(u)}));return{cssVariables:n,palette:d,fontFamilies:[...i].slice(0,8),fontSizes:[...r].slice(0,16),spacing:[...a].slice(0,16),radii:[...l].slice(0,8),shadows:[...c].slice(0,8)}}function jo(e,t,n,s){let o=new RegExp(t.source,"g"),i;for(;(i=o.exec(e))!==null;){let r=s(i[1]);r&&!r.startsWith("var(")&&n.add(r)}}function rh(e,t){let n=new RegExp(th.source,"g"),s;for(;(s=n.exec(e))!==null;){let o=s[1].trim();if(!o.startsWith("var("))for(let i of o.split(/\s+/))/^-?\d+(\.\d+)?(rem|em|px|%)$/.test(i)&&t.add(i)}}function ah(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function Ic(e){let t=e.trim().toLowerCase();if(t.startsWith("#")){if(/^#[0-9a-f]{3}$/.test(t)){let[,n,s,o]=t.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);return`#${n}${n}${s}${s}${o}${o}`}return t}return t.replace(/\s+/g,"")}function ch(e){return lh.has(e)}function dh(e){let t=[],n=be(e,"css");if(x(n))for(let o of Gt(n))o.endsWith(".css")&&t.push(be(n,o));let s=be(e,"modules");if(x(s))for(let o of Gt(s)){if(!o.endsWith(".module"))continue;let i=be(s,o,"module.css");x(i)&&t.push(i)}return t}function uh(e){let t=be(e,"modules"),n=be(e,"templates"),s=new Set,o=new Map;if(x(t))for(let c of Gt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,x(be(t,c,"module.js")))}let i=[],r=new Map;if(x(n))for(let c of Gt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=be(n,c),u;try{u=dr(d)}catch{continue}if(!u.isFile())continue;let m;try{m=P(d)}catch{continue}let g=mr(m);for(let f of g){let b=r.get(f)??new Set;b.add(c),r.set(f,b)}let h=c.replace(/\.html$/,"");i.push({id:h,file:`templates/${c}`,modules:bh(g)})}let a=[...s].sort().map(c=>({name:c,templates:[...r.get(c)??[]].sort(),hasJs:o.get(c)??!1})),l=a.filter(c=>c.templates.length===0).map(c=>c.name);return{templates:i,modules:a,orphanModules:l}}function mr(e){let t=[],n=/{%\s*dnd_module\b[\s\S]*?%}/g,s;for(;(s=n.exec(e))!==null;){let o=s[0].match(/\bpath\s*=\s*["']([^"']+)["']/);if(!o)continue;let i=o[1].match(/(?:^|\/)modules\/(.+)$/);if(!i)continue;let r=i[1].replace(/\.module$/,"");r&&t.push(r)}return t}function ph(e){let t=[],n=be(e,"modules");if(!x(n))return t;for(let s of Gt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=be(n,s,"fields.json");if(!x(i))continue;let r;try{r=JSON.parse(P(i))}catch{continue}Array.isArray(r)&&Oc(r,o,t,0)}return t}function Oc(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)",a=typeof i.type=="string"?i.type:"";if(a==="group"&&s>=1&&n.push({module:t,field:r,reason:"deeply nested group (>1 level)"}),(a==="group"||a==="module")&&i.occurrence){let l=i.occurrence;l.max!==void 0&&l.max!==1&&n.push({module:t,field:r,reason:"repeater (occurrence) field"})}(a==="hubdb_table"||a==="hubdbtable")&&n.push({module:t,field:r,reason:"HubDB-backed field"}),(a==="crm_object"||a==="crm_object_property")&&n.push({module:t,field:r,reason:"CRM object field"}),a==="embed"&&typeof i.embed=="object"&&n.push({module:t,field:r,reason:"rich embed field"}),a&&!mh.has(a)&&a!=="module"&&n.push({module:t,field:r,reason:`field type "${a}" not in vibeSpot's generation set`}),i.visibility&&typeof i.visibility=="object"&&n.push({module:t,field:r,reason:"conditional visibility rule"}),Array.isArray(i.children)&&Oc(i.children,t,n,s+1)}}function gh(e){let t=[],n=be(e,"modules");if(x(n))for(let i of Gt(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=be(n,i,"module.html");x(a)&&Pc(a,e,r,t);let l=be(n,i,"module.js");if(x(l))try{P(l).trim().length>0&&t.push({file:pr(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=be(e,"templates");if(x(s))for(let i of Gt(s)){if(!i.endsWith(".html"))continue;let r=be(s,i);if(!x(r))continue;let a;try{a=dr(r)}catch{continue}a.isFile()&&Pc(r,e,i,t)}let o=be(e,"import_modules.json");return x(o)&&t.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),t}function Pc(e,t,n,s){let o;try{o=P(e)}catch{return}let i=pr(t,e);/{%\s*macro\s+\w+/.test(o)&&s.push({file:i,pattern:"hubl.macro",detail:`${n}: contains custom HubL {% macro %}`}),/{%\s*raw\s*%}/.test(o)&&s.push({file:i,pattern:"hubl.raw",detail:`${n}: contains {% raw %} block`});let r=/{%\s*include\s+["']([^"']+)["']/g,a;for(;(a=r.exec(o))!==null;){let l=a[1];!l.startsWith("../modules/")&&!l.startsWith("./modules/")&&!l.includes("/layouts/")&&s.push({file:i,pattern:"hubl.include",detail:`${n}: includes partial "${l}" outside modules/`})}}function fh(e,t){let n={hasSnapshot:!1,snapshotPath:hs(e),filesChanged:0,added:0,modified:0,deleted:0,files:[]};return{themePath:e,designTokens:{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]},graph:{templates:[],modules:[],orphanModules:[]},fieldFlags:[],roundTripRisks:[],roundTripDiff:n,findings:t,summary:{moduleCount:0,templateCount:0,orphanCount:0,paletteSize:0,cssVarCount:0,customMacroCount:0,roundTripChangedCount:0}}}function Fc(e){let t=[];function n(s){for(let o of Gt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=be(s,o),r;try{r=dr(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=pr(e,i),l=Hf(i),c={path:a,sha256:Uf("sha256").update(l).digest("hex"),size:l.length};hh(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function hh(e){let t=e.lastIndexOf(".");return t<0?!1:Kf.has(e.slice(t).toLowerCase())}function yh(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version!==1||typeof t.createdAt!="string"||!Array.isArray(t.files)?!1:t.files.every(n=>{if(typeof n!="object"||n===null)return!1;let s=n;return typeof s.path=="string"&&typeof s.sha256=="string"&&typeof s.size=="number"&&(s.text===void 0||typeof s.text=="string")})}function Lo(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Gt(e){try{return Nc(e)}catch{return[]}}function pr(e,t){return Gf(e,t).split("\\").join("/")}function bh(e){return[...new Set(e)]}var Wf,Kf,qf,Xf,Zf,Qf,eh,th,nh,sh,oh,ih,lh,mh,Ho=N(()=>{"use strict";y();oe();Wf=".vibespot/import-snapshot.json",Kf=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);qf=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Xf=/\brgba?\([^)]+\)/g,Zf=/\bhsla?\([^)]+\)/g,Qf=/font-family\s*:\s*([^;}\n]+)/g,eh=/font-size\s*:\s*([^;}\n]+)/g,th=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,nh=/border-radius\s*:\s*([^;}\n]+)/g,sh=/box-shadow\s*:\s*([^;}\n]+)/g,oh=/:root\s*\{([\s\S]*?)\}/g,ih=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;lh=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);mh=new Set(["text","richtext","image","url","boolean","choice","number","color","icon","link","menu","video","form","cta","blog","tag","page","email","logo","embed","alignment","border","spacing","font","background","gradient","textalignment","group"])});import{readFileSync as gr,readdirSync as bs,existsSync as xe,writeFileSync as Ye,mkdirSync as ys,rmSync as Dc}from"fs";import{join as U}from"path";function we(e){try{return gr(e,"utf-8")}catch{return""}}function Lc(e){let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Sh(e,t){let n=we(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o=/templateType:\s*email\b/i.test(n),i="landing_page",r;o?(i="module_only",r="email"):s.startsWith("bp-")?i="blog_post":s.startsWith("wp-")?i="website_page":s.startsWith("mo-")&&(i="module_only");let a=s,l=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);l&&(a=l[1].trim());let c=mr(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function vh(e,t,n,s,o){if(!xe(e))return[];let i=[],r=bs(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=U(e,a),c=Sh(l,a);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let g=t.get(m);g&&(d.push(g),u.push(m))}i.push({id:c.id,label:c.label,pageType:c.pageType,contentMode:c.contentMode,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:c.contentMode==="email"?"":n,sharedJs:c.contentMode==="email"?"":s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function Uo(e){let t=C();if(!t)return;let n=bc(e);n.length>0&&t.messages.length===0&&(t.messages=n),Eo(e),Rc(e);let s=U(e,"modules");if(!xe(s))return;let o=bs(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let v=U(s,S.name),w=S.name.replace(/\.module$/,""),M={moduleName:w,fieldsJson:we(U(v,"fields.json")),metaJson:we(U(v,"meta.json")),moduleHtml:we(U(v,"module.html")),moduleCss:we(U(v,"module.css")),moduleJs:we(U(v,"module.js"))||void 0};M.fieldsJson&&M.moduleHtml&&(t.modules.push(M),t.moduleOrder.push(w))}let i=U(e,"css"),r=U(e,"js"),a="",l="";if(xe(i)){let S=bs(i).filter(v=>v.endsWith("-theme.css"));S.length>0&&(a=we(U(i,S[0])),t.sharedCss=a)}if(xe(r)){let S=bs(r).filter(v=>v.endsWith("-animations.js"));S.length>0&&(l=we(U(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=Fn(e),v=fs(S);v&&(t.sharedCss=v,a=v)}let c=U(e,".vibespot","styleguide.md"),d=U(e,".vibespot","brandvoice.md"),u=U(e,".vibespot","theme-context.md"),m=U(e,".vibespot","plan.md"),g=U(e,".vibespot","brand-kit.json");if((xe(c)||xe(d)||xe(u)||xe(m)||xe(g))&&(t.brandAssets||(t.brandAssets={}),xe(c)&&(t.brandAssets.styleguide=we(c)),xe(d)&&(t.brandAssets.brandvoice=we(d)),xe(u)&&(t.brandAssets.themeContext=we(u)),xe(m)&&(t.brandAssets.plan=we(m)),xe(g)))try{t.brandAssets.brandKit=JSON.parse(we(g))}catch{}let h=U(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=vh(h,f,a,l,t.messages);if(b.length>0){t.templates=b,t.activeTemplateId=b[0].id,t.brandAssets?.plan&&!b[0].plan&&(b[0].plan=t.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let v=new Set(t.moduleOrder),w=S.filter(M=>v.has(M));for(let M of t.moduleOrder)w.includes(M)||w.push(M);t.moduleOrder=w}on(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),No(t)}function Te(){let e=C();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=U(t,"modules");ys(s,{recursive:!0});for(let l of n.values())ys(U(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=U(s,`${l.moduleName}.module`);Ye(U(c,"fields.json"),l.fieldsJson,"utf-8"),Ye(U(c,"meta.json"),l.metaJson,"utf-8"),Ye(U(c,"module.html"),l.moduleHtml,"utf-8"),Ye(U(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ye(U(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=U(t,"css");ys(l,{recursive:!0}),Ye(U(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=U(t,"js");ys(l,{recursive:!0}),Ye(U(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=U(t,"templates");ys(o,{recursive:!0});let i=U(o,"home.html");(e.templates.length>0||e.modules.length>0)&&xe(i)&&Dc(i,{force:!0});let a=new Set;if(e.templates.length>0)for(let l of e.templates){if(l.contentMode==="email"){if(l.modules.length===0)continue;let m=kh(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ye(U(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||Ch(l),d=jc(c,l.label,l.pageType),u=`${l.id}.html`;Ye(U(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(Th(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||Ah(),c=jc(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ye(U(o,d),c,"utf-8"),a.add(d)}try{for(let l of bs(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&Dc(U(o,l),{force:!0})}catch{}xh(),wh()}function Jc(){let e=C();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",Uo(e.themePath),e.updatedAt=Date.now(),at())}function Bc(){let e=C();if(!e)return;let t=ke();if(!t)return;let n=e.themePath,s=U(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=U(s,`${o}.module`);if(!xe(i))continue;let r={moduleName:o,fieldsJson:we(U(i,"fields.json")),metaJson:we(U(i,"meta.json")),moduleHtml:we(U(i,"module.html")),moduleCss:we(U(i,"module.css")),moduleJs:we(U(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=U(n,t.templateFile);xe(o)&&(t.template=we(o))}on(t),e.updatedAt=Date.now()}function xh(){let e=C();if(!e)return;let t=U(e.themePath,"templates","layouts","base.html");if(xe(t))try{let n=gr(t,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
190
+ `}function ti(e,t){let n=Se(e,"css");if(v(n))try{for(let r of rd(n))if(r.endsWith("-theme.css"))return null}catch{}let s=qt(e),o=dn(s);if(!o)return null;let i=Se(n,`${t}-theme.css`);return H(i,o),i}function ks(e){return Se(e,Lh)}function Jh(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:cd(e)}}function Ar(e,t){let n=Jh(e,t),s=ks(e);return H(s,JSON.stringify(n,null,2)+`
191
+ `),s}function ad(e){let t=ks(e);return v(t)?null:Ar(e)}function Hh(e){let t=ks(e);if(!v(t))return null;try{let n=JSON.parse(M(t));return uy(n)?n:null}catch{return null}}function Uh(e){let t=ks(e),n=Hh(e);if(!n)return{hasSnapshot:!1,snapshotPath:t,filesChanged:0,added:0,modified:0,deleted:0,files:[]};let s=new Map(n.files.map(d=>[d.path,d])),o=cd(e),i=new Map(o.map(d=>[d.path,d])),r=[];for(let d of n.files){let u=i.get(d.path);u?u.sha256!==d.sha256&&r.push({file:d.path,status:"modified",beforeSha256:d.sha256,afterSha256:u.sha256,beforeSize:d.size,afterSize:u.size,beforeLines:Qo(d.text),afterLines:Qo(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:Qo(d.text)})}for(let d of o)s.has(d.path)||r.push({file:d.path,status:"added",afterSha256:d.sha256,afterSize:d.size,afterLines:Qo(d.text)});r.sort((d,u)=>d.file.localeCompare(u.file));let a=r.filter(d=>d.status==="added").length,l=r.filter(d=>d.status==="modified").length,c=r.filter(d=>d.status==="deleted").length;return{hasSnapshot:!0,snapshotPath:t,filesChanged:r.length,added:a,modified:l,deleted:c,files:r}}function qt(e){let t=oy(e),n={},s=new Map,o=new Map,i=new Set,r=new Set,a=new Set,l=new Set,c=new Set;for(let u of t){let m;try{m=M(u)}catch{continue}let g,h=new RegExp(Zh.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(Qh.source,"g"),S;for(;(S=b.exec(f))!==null;){let x=S[1].trim(),k=S[2].trim();n[x]||(n[x]=k);let $=k.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if($){let L=od($[0]);o.set(L,x)}}}for(let f of[Gh,Wh,Kh]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let x=od(S[0]);x&&s.set(x,(s.get(x)??0)+1)}}Zo(m,Vh,i,ty),Zo(m,zh,r,f=>f.trim()),ey(m,a),Zo(m,qh,l,f=>f.trim()),Zo(m,Xh,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!sy(u)).sort((u,m)=>m[1]-u[1]).slice(0,12).map(([u,m])=>({value:u,count:m,varName:o.get(u)}));return{cssVariables:n,palette:d,fontFamilies:[...i].slice(0,8),fontSizes:[...r].slice(0,16),spacing:[...a].slice(0,16),radii:[...l].slice(0,8),shadows:[...c].slice(0,8)}}function Zo(e,t,n,s){let o=new RegExp(t.source,"g"),i;for(;(i=o.exec(e))!==null;){let r=s(i[1]);r&&!r.startsWith("var(")&&n.add(r)}}function ey(e,t){let n=new RegExp(Yh.source,"g"),s;for(;(s=n.exec(e))!==null;){let o=s[1].trim();if(!o.startsWith("var("))for(let i of o.split(/\s+/))/^-?\d+(\.\d+)?(rem|em|px|%)$/.test(i)&&t.add(i)}}function ty(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function od(e){let t=e.trim().toLowerCase();if(t.startsWith("#")){if(/^#[0-9a-f]{3}$/.test(t)){let[,n,s,o]=t.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);return`#${n}${n}${s}${s}${o}${o}`}return t}return t.replace(/\s+/g,"")}function sy(e){return ny.has(e)}function oy(e){let t=[],n=Se(e,"css");if(v(n))for(let o of Yt(n))o.endsWith(".css")&&t.push(Se(n,o));let s=Se(e,"modules");if(v(s))for(let o of Yt(s)){if(!o.endsWith(".module"))continue;let i=Se(s,o,"module.css");v(i)&&t.push(i)}return t}function iy(e){let t=Se(e,"modules"),n=Se(e,"templates"),s=new Set,o=new Map;if(v(t))for(let c of Yt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,v(Se(t,c,"module.js")))}let i=[],r=new Map;if(v(n))for(let c of Yt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=Se(n,c),u;try{u=Tr(d)}catch{continue}if(!u.isFile())continue;let m;try{m=M(d)}catch{continue}let g=_r(m);for(let f of g){let b=r.get(f)??new Set;b.add(c),r.set(f,b)}let h=c.replace(/\.html$/,"");i.push({id:h,file:`templates/${c}`,modules:my(g)})}let a=[...s].sort().map(c=>({name:c,templates:[...r.get(c)??[]].sort(),hasJs:o.get(c)??!1})),l=a.filter(c=>c.templates.length===0).map(c=>c.name);return{templates:i,modules:a,orphanModules:l}}function _r(e){let t=[],n=/{%\s*dnd_module\b[\s\S]*?%}/g,s;for(;(s=n.exec(e))!==null;){let o=s[0].match(/\bpath\s*=\s*["']([^"']+)["']/);if(!o)continue;let i=o[1].match(/(?:^|\/)modules\/(.+)$/);if(!i)continue;let r=i[1].replace(/\.module$/,"");r&&t.push(r)}return t}function ay(e){let t=[],n=Se(e,"modules");if(!v(n))return t;for(let s of Yt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=Se(n,s,"fields.json");if(!v(i))continue;let r;try{r=JSON.parse(M(i))}catch{continue}Array.isArray(r)&&ld(r,o,t,0)}return t}function ld(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)",a=typeof i.type=="string"?i.type:"";if(a==="group"&&s>=1&&n.push({module:t,field:r,reason:"deeply nested group (>1 level)"}),(a==="group"||a==="module")&&i.occurrence){let l=i.occurrence;l.max!==void 0&&l.max!==1&&n.push({module:t,field:r,reason:"repeater (occurrence) field"})}(a==="hubdb_table"||a==="hubdbtable")&&n.push({module:t,field:r,reason:"HubDB-backed field"}),(a==="crm_object"||a==="crm_object_property")&&n.push({module:t,field:r,reason:"CRM object field"}),a==="embed"&&typeof i.embed=="object"&&n.push({module:t,field:r,reason:"rich embed field"}),a&&!ry.has(a)&&a!=="module"&&n.push({module:t,field:r,reason:`field type "${a}" not in vibeSpot's generation set`}),i.visibility&&typeof i.visibility=="object"&&n.push({module:t,field:r,reason:"conditional visibility rule"}),Array.isArray(i.children)&&ld(i.children,t,n,s+1)}}function ly(e){let t=[],n=Se(e,"modules");if(v(n))for(let i of Yt(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=Se(n,i,"module.html");v(a)&&id(a,e,r,t);let l=Se(n,i,"module.js");if(v(l))try{M(l).trim().length>0&&t.push({file:$r(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=Se(e,"templates");if(v(s))for(let i of Yt(s)){if(!i.endsWith(".html"))continue;let r=Se(s,i);if(!v(r))continue;let a;try{a=Tr(r)}catch{continue}a.isFile()&&id(r,e,i,t)}let o=Se(e,"import_modules.json");return v(o)&&t.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),t}function id(e,t,n,s){let o;try{o=M(e)}catch{return}let i=$r(t,e);/{%\s*macro\s+\w+/.test(o)&&s.push({file:i,pattern:"hubl.macro",detail:`${n}: contains custom HubL {% macro %}`}),/{%\s*raw\s*%}/.test(o)&&s.push({file:i,pattern:"hubl.raw",detail:`${n}: contains {% raw %} block`});let r=/{%\s*include\s+["']([^"']+)["']/g,a;for(;(a=r.exec(o))!==null;){let l=a[1];!l.startsWith("../modules/")&&!l.startsWith("./modules/")&&!l.includes("/layouts/")&&s.push({file:i,pattern:"hubl.include",detail:`${n}: includes partial "${l}" outside modules/`})}}function cy(e,t){let n={hasSnapshot:!1,snapshotPath:ks(e),filesChanged:0,added:0,modified:0,deleted:0,files:[]};return{themePath:e,designTokens:{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]},graph:{templates:[],modules:[],orphanModules:[]},fieldFlags:[],roundTripRisks:[],roundTripDiff:n,findings:t,summary:{moduleCount:0,templateCount:0,orphanCount:0,paletteSize:0,cssVarCount:0,customMacroCount:0,roundTripChangedCount:0}}}function cd(e){let t=[];function n(s){for(let o of Yt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=Se(s,o),r;try{r=Tr(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=$r(e,i),l=Fh(i),c={path:a,sha256:Dh("sha256").update(l).digest("hex"),size:l.length};dy(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function dy(e){let t=e.lastIndexOf(".");return t<0?!1:Bh.has(e.slice(t).toLowerCase())}function uy(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version!==1||typeof t.createdAt!="string"||!Array.isArray(t.files)?!1:t.files.every(n=>{if(typeof n!="object"||n===null)return!1;let s=n;return typeof s.path=="string"&&typeof s.sha256=="string"&&typeof s.size=="number"&&(s.text===void 0||typeof s.text=="string")})}function Qo(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Yt(e){try{return rd(e)}catch{return[]}}function $r(e,t){return jh(e,t).split("\\").join("/")}function my(e){return[...new Set(e)]}var Lh,Bh,Gh,Wh,Kh,Vh,zh,Yh,qh,Xh,Zh,Qh,ny,ry,Cs=R(()=>{"use strict";y();ae();Lh=".vibespot/import-snapshot.json",Bh=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);Gh=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Wh=/\brgba?\([^)]+\)/g,Kh=/\bhsla?\([^)]+\)/g,Vh=/font-family\s*:\s*([^;}\n]+)/g,zh=/font-size\s*:\s*([^;}\n]+)/g,Yh=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,qh=/border-radius\s*:\s*([^;}\n]+)/g,Xh=/box-shadow\s*:\s*([^;}\n]+)/g,Zh=/:root\s*\{([\s\S]*?)\}/g,Qh=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;ny=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);ry=new Set(["text","richtext","image","url","boolean","choice","number","color","icon","link","menu","video","form","cta","blog","tag","page","email","logo","embed","alignment","border","spacing","font","background","gradient","textalignment","group"])});import{readFileSync as Pr,readdirSync as As,existsSync as we,writeFileSync as Xe,mkdirSync as Ts,rmSync as dd}from"fs";import{join as G}from"path";function ke(e){try{return Pr(e,"utf-8")}catch{return""}}function md(e){let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function py(e,t){let n=ke(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o=/templateType:\s*email\b/i.test(n),i="landing_page",r;o?(i="module_only",r="email"):s.startsWith("bp-")?i="blog_post":s.startsWith("wp-")?i="website_page":s.startsWith("mo-")&&(i="module_only");let a=s,l=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);l&&(a=l[1].trim());let c=_r(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function gy(e,t,n,s,o){if(!we(e))return[];let i=[],r=As(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=G(e,a),c=py(l,a);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let g=t.get(m);g&&(d.push(g),u.push(m))}i.push({id:c.id,label:c.label,pageType:c.pageType,contentMode:c.contentMode,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:c.contentMode==="email"?"":n,sharedJs:c.contentMode==="email"?"":s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function ni(e){let t=w();if(!t)return;let n=Wc(e);n.length>0&&t.messages.length===0&&(t.messages=n),Uo(e),ad(e);let s=G(e,"modules");if(!we(s))return;let o=As(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let x=G(s,S.name),k=S.name.replace(/\.module$/,""),$={moduleName:k,fieldsJson:ke(G(x,"fields.json")),metaJson:ke(G(x,"meta.json")),moduleHtml:ke(G(x,"module.html")),moduleCss:ke(G(x,"module.css")),moduleJs:ke(G(x,"module.js"))||void 0};$.fieldsJson&&$.moduleHtml&&(t.modules.push($),t.moduleOrder.push(k))}let i=G(e,"css"),r=G(e,"js"),a="",l="";if(we(i)){let S=As(i).filter(x=>x.endsWith("-theme.css"));S.length>0&&(a=ke(G(i,S[0])),t.sharedCss=a)}if(we(r)){let S=As(r).filter(x=>x.endsWith("-animations.js"));S.length>0&&(l=ke(G(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=qt(e),x=dn(S);x&&(t.sharedCss=x,a=x)}let c=G(e,".vibespot","styleguide.md"),d=G(e,".vibespot","brandvoice.md"),u=G(e,".vibespot","theme-context.md"),m=G(e,".vibespot","plan.md"),g=G(e,".vibespot","brand-kit.json");if((we(c)||we(d)||we(u)||we(m)||we(g))&&(t.brandAssets||(t.brandAssets={}),we(c)&&(t.brandAssets.styleguide=ke(c)),we(d)&&(t.brandAssets.brandvoice=ke(d)),we(u)&&(t.brandAssets.themeContext=ke(u)),we(m)&&(t.brandAssets.plan=ke(m)),we(g)))try{t.brandAssets.brandKit=JSON.parse(ke(g))}catch{}let h=G(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=gy(h,f,a,l,t.messages);if(b.length>0){t.templates=b,t.activeTemplateId=b[0].id,t.brandAssets?.plan&&!b[0].plan&&(b[0].plan=t.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let x=new Set(t.moduleOrder),k=S.filter($=>x.has($));for(let $ of t.moduleOrder)k.includes($)||k.push($);t.moduleOrder=k}cn(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),Vo(t)}function Ae(){let e=w();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=G(t,"modules");Ts(s,{recursive:!0});for(let l of n.values())Ts(G(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=G(s,`${l.moduleName}.module`);Xe(G(c,"fields.json"),l.fieldsJson,"utf-8"),Xe(G(c,"meta.json"),l.metaJson,"utf-8"),Xe(G(c,"module.html"),l.moduleHtml,"utf-8"),Xe(G(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Xe(G(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=G(t,"css");Ts(l,{recursive:!0}),Xe(G(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=G(t,"js");Ts(l,{recursive:!0}),Xe(G(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=G(t,"templates");Ts(o,{recursive:!0});let i=G(o,"home.html");(e.templates.length>0||e.modules.length>0)&&we(i)&&dd(i,{force:!0});let a=new Set;if(e.templates.length>0)for(let l of e.templates){if(l.contentMode==="email"){if(l.modules.length===0)continue;let m=by(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Xe(G(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||yy(l),d=ud(c,l.label,l.pageType),u=`${l.id}.html`;Xe(G(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(Sy(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||vy(),c=ud(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Xe(G(o,d),c,"utf-8"),a.add(d)}try{for(let l of As(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&dd(G(o,l),{force:!0})}catch{}fy(),hy()}function pd(){let e=w();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",ni(e.themePath),e.updatedAt=Date.now(),ct())}function gd(){let e=w();if(!e)return;let t=Te();if(!t)return;let n=e.themePath,s=G(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=G(s,`${o}.module`);if(!we(i))continue;let r={moduleName:o,fieldsJson:ke(G(i,"fields.json")),metaJson:ke(G(i,"meta.json")),moduleHtml:ke(G(i,"module.html")),moduleCss:ke(G(i,"module.css")),moduleJs:ke(G(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=G(n,t.templateFile);we(o)&&(t.template=ke(o))}cn(t),e.updatedAt=Date.now()}function fy(){let e=w();if(!e)return;let t=G(e.themePath,"templates","layouts","base.html");if(we(t))try{let n=Pr(t,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
192
192
  {% if template_js %}
193
193
  {{ require_js(get_asset_url(template_js)) }}
194
194
  {% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
195
195
  {{ require_js(get_asset_url(template_js)) }}
196
196
  {% endif %}
197
- {{ standard_footer_includes }}`),Ye(t,n,"utf-8")}catch{}}function wh(){let e=C();if(!e)return;let t=U(e.themePath,"theme.json");if(xe(t))try{let n=JSON.parse(gr(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ye(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function jc(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
197
+ {{ standard_footer_includes }}`),Xe(t,n,"utf-8")}catch{}}function hy(){let e=w();if(!e)return;let t=G(e.themePath,"theme.json");if(we(t))try{let n=JSON.parse(Pr(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Xe(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function ud(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
198
198
  templateType: ${n==="blog_post"?"blog_post":"page"}
199
199
  isAvailableForNewContent: true
200
200
  label: "${t}"
201
201
  -->
202
- `+e}function Ch(e){if(e.modules.length===0)return"";let n=C().themeName,o=Lc(e).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
202
+ `+e}function yy(e){if(e.modules.length===0)return"";let n=w().themeName,o=md(e).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
203
203
  {% dnd_module path="../modules/${r.moduleName}.module" %}
204
204
  {% end_dnd_module %}
205
205
  {% end_dnd_section %}`).join(`
@@ -230,7 +230,7 @@ ${o}
230
230
 
231
231
  {% block footer %}
232
232
  {% endblock footer %}
233
- `}function kh(e){let n=Lc(e).map(s=>` {% dnd_section %}
233
+ `}function by(e){let n=md(e).map(s=>` {% dnd_section %}
234
234
  {% dnd_module path="../modules/${s.moduleName}.module" %}
235
235
  {% end_dnd_module %}
236
236
  {% end_dnd_section %}`).join(`
@@ -277,7 +277,7 @@ ${n}
277
277
  {{ standard_footer_includes }}
278
278
  </body>
279
279
  </html>
280
- `}function Th(e,t){let n=`<!--
280
+ `}function Sy(e,t){let n=`<!--
281
281
  templateType: blog_listing
282
282
  isAvailableForNewContent: true
283
283
  label: "${t.label} - Listing"
@@ -302,7 +302,7 @@ ${n}
302
302
  {% endif %}
303
303
  </div>
304
304
  {% endblock body %}
305
- `;Ye(U(e,`${t.id}-listing.html`),n,"utf-8")}function Ah(){let e=C();if(!e||e.modules.length===0)return"";let t=e.themeName,s=ve().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
305
+ `;Xe(G(e,`${t.id}-listing.html`),n,"utf-8")}function vy(){let e=w();if(!e||e.modules.length===0)return"";let t=e.themeName,s=xe().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
306
306
  {% dnd_module path="../modules/${o.moduleName}.module" %}
307
307
  {% end_dnd_module %}
308
308
  {% end_dnd_section %}`).join(`
@@ -333,7 +333,7 @@ ${s}
333
333
 
334
334
  {% block footer %}
335
335
  {% endblock footer %}
336
- `}var fr=N(()=>{"use strict";y();ps();us();Ut();In();Ho()});var Hc=N(()=>{"use strict";y();nc();ps();us();fr();Ut()});var Ce=N(()=>{"use strict";y();Hc()});function rn(e){let t={};for(let n of e)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?t[n.name]=n.default:n.type==="group"&&n.children?t[n.name]=rn(n.children):t[n.name]=n.default??"";return t}function jn(e,t){let n=e;return n=Oh(n),n=Kc(n,t),n=Vc(n,t),n=zc(n,t),n=Dh(n),n}function br(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
336
+ `}var Er=R(()=>{"use strict";y();xs();Ss();zt();jn();Cs()});var fd=R(()=>{"use strict";y();Pc();xs();Ss();Er();zt()});var Ce=R(()=>{"use strict";y();fd()});function un(e){let t={};for(let n of e)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?t[n.name]=n.default:n.type==="group"&&n.children?t[n.name]=un(n.children):t[n.name]=n.default??"";return t}function Gn(e,t){let n=e;return n=Py(n),n=Sd(n,t),n=vd(n,t),n=xd(n,t),n=My(n),n}function Rr(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
337
337
  `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
338
338
  `),s=e.renderedModules.join(`
339
339
  `);return`<!DOCTYPE html>
@@ -380,11 +380,11 @@ document.querySelectorAll('img').forEach(function(img){
380
380
  });
381
381
  </script>
382
382
  </body>
383
- </html>`}function Oh(e){return e=e.replace(_h,""),e=e.replace($h,""),e=e.replace(Eh,""),Uc.lastIndex=0,e=e.replace(Uc,(t,n)=>`/theme-assets/${n}`),Gc.lastIndex=0,e=e.replace(Gc,""),e=e.replace(Mh,""),e=e.replace(Ih,""),e=e.replace(Ph,""),e=e.replace(Nh,""),e=e.replace(Rh,""),e}function Kc(e,t){let n=e,s=0;for(;s<30;){s++;let o=Fh(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=jh(r,t),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let h={...t,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},f=Kc(a,h);return f=Vc(f,h),f=zc(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Fh(e){let t=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=t.exec(e);if(!s)return null;let o=s[1],i=s[2],r=s.index+s[0].length;n.lastIndex=r;let a=1,l;for(;(l=n.exec(e))!==null;)if(l[1].startsWith("for"))a++;else if(a--,a===0){let c=e.slice(r,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function Vc(e,t){let n=e,s=0;for(;hr.test(n)&&s<50;)s++,n=n.replace(hr,(o,i,r)=>{let a=r.split(/\{%[-\s]*else\s*-?%\}/),l=a[0],c=a[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(Dn(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(Dn(m,t))return g}return c}return Dn(i,t)?l:c}),hr.lastIndex=0;return n}function zc(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Lh(t,r);for(let c=1;c<i.length;c++)a=qc(a,i[c].trim());if(a==null)return"";if(typeof a=="object")return JSON.stringify(a);let l=String(a);return l=l.replace(/\\n/g," ").replace(/\n/g," "),l})}function Dh(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function jh(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Wc(n[1],t),i=Wc(n[2],t),r=[];for(let a=o;a<i;a++)r.push(a);return r}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=Wt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Wt(t,e)}function Wc(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Wt(t,o);for(let r=1;r<s.length;r++)i=qc(i,s[r].trim());return Number(i)||0}function Wt(e,t){let n=t.split("."),s=e;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function Lh(e,t){let n=t.match(/^(.+?)\s*([*/])\s*([\d.]+)$/);if(n){let s=Wt(e,n[1].trim());if(s==null||s==="")return"";let o=Number(s);if(Number.isNaN(o))return"";let i=Number(n[3]);return n[2]==="/"?i===0?"":o/i:o*i}return Wt(e,t)}function Dn(e,t){let n=e.trim();if(n.startsWith("not "))return!Dn(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Dn(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Dn(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=Wt(t,s[1].trim()),r=s[2],a=s[3].trim();switch(typeof a=="string"&&a.startsWith('"')&&a.endsWith('"')||typeof a=="string"&&a.startsWith("'")&&a.endsWith("'")?a=a.slice(1,-1):isNaN(Number(a))?a=Wt(t,a):a=Number(a),r){case"==":return i==a;case"!=":return i!=a;case">":return Number(i)>Number(a);case"<":return Number(i)<Number(a);case">=":return Number(i)>=Number(a);case"<=":return Number(i)<=Number(a)}}let o=Wt(t,n);return Yc(o)}function Yc(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function qc(e,t){let n=e==null?"":String(e),s=t.match(/^(\w+)\((.*)\)$/),o=s?s[1]:t,i=s?s[2].replace(/^["']|["']$/g,""):void 0;switch(o){case"escape":case"e":return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");case"lower":return n.toLowerCase();case"upper":return n.toUpperCase();case"capitalize":return n.charAt(0).toUpperCase()+n.slice(1);case"trim":return n.trim();case"truncate":if(i){let r=parseInt(i,10);return n.length>r?n.slice(0,r)+"...":n}return n;case"default":return Yc(e)?e:i??"";case"length":return Array.isArray(e)?e.length:n.length;case"join":return Array.isArray(e)?e.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));case"convert_rgb":{let r=yr(e);return r?Bh(r):""}default:return e}}function yr(e){if(e==null)return null;if(typeof e=="string"){let t=e.match(/#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})(?![0-9a-fA-F])/);return t?Jh(t[1]):null}if(typeof e=="object"){let t=e;if(typeof t.color=="string")return yr(t.color);if(typeof t.hex=="string")return yr(t.hex)}return null}function Jh(e){let t=e.toLowerCase();return t.length===3?t.split("").map(n=>n+n).join(""):t}function Bh(e){let t=parseInt(e.slice(0,2),16),n=parseInt(e.slice(2,4),16),s=parseInt(e.slice(4,6),16);return`${t}, ${n}, ${s}`}var _h,$h,Eh,Uc,Gc,Mh,Ih,Ph,Nh,Rh,hr,Sr=N(()=>{"use strict";y();_h=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,$h=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,Eh=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,Uc=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Gc=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Mh=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Ih=/\{%[-\s]*module\b.*?%\}/gs,Ph=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Nh=/\{#.*?#\}/gs,Rh=/\{\{[-\s]*content\.\w+.*?\}\}/gs,hr=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Go={};Ge(Go,{buildModulePreviewHtml:()=>wr,buildPreviewHtml:()=>xr});function Hh(e){if(Ln()==="email")return!0;for(let t of e)try{let n=JSON.parse(t.metaJson);if(Array.isArray(n.host_template_types)&&n.host_template_types.includes("EMAIL"))return!0}catch{}return!1}function Uh(e){if(!e)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let t=(a,l)=>{for(let c of a){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=e.match(d);if(u)return u[1].trim()}return l},n=t(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=t(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=t(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=t(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),r=t(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:r}}function vr(e,t){if(!Array.isArray(t))return e;let n=new Map;for(let o of t)n.set(o.name,o.type);let s=e;return s=s.replace(/(<([a-zA-Z]\w*)(\s[^>]*)?>)\s*(\{\{\s*module\.(\w+)(?:\.\w+)*(?:\|[^}]*)?\s*\}\})\s*(<\/\2>)/g,(o,i,r,a,l,c,d)=>{if(i.includes("data-vs-field"))return o;let u=n.get(c)||"text";return`${i.replace(/>$/,` data-vs-field="${c}" data-vs-type="${u}">`)}${l}${d}`}),s=s.replace(/(<img\b)([^>]*?)\bsrc\s*=\s*["']\{\{\s*module\.(\w+)\.src\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-field")?o:o.replace("<img",`<img data-vs-field="${a}" data-vs-type="image"`)),s=s.replace(/(<a\b)([^>]*?)\bhref\s*=\s*["']\{\{\s*module\.(\w+)\.url\.href\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-link")?o:o.replace("<a",`<a data-vs-link="${a}"`)),s}function xr(){let e=C();if(!e)return Xc();let t=ve(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return Xc();if(Hh(t))return Gh(t,n);let s=[],o=[],i=[],r=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d,u=[];try{let f=JSON.parse(c.fieldsJson);u=Array.isArray(f)?f:[],d={module:rn(u)}}catch{d={module:{}}}let m=vr(c.moduleHtml,u),g=jn(m,d),h=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${h}" data-module="${c.moduleName}">${g}</div>`),r.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let a=Uh(e.sharedCss);for(let c of n)if(!r.has(c)){let d=c.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module vibespot-module--pending" id="${d}" data-module="${c}">
383
+ </html>`}function Py(e){return e=e.replace(xy,""),e=e.replace(wy,""),e=e.replace(ky,""),hd.lastIndex=0,e=e.replace(hd,(t,n)=>`/theme-assets/${n}`),yd.lastIndex=0,e=e.replace(yd,""),e=e.replace(Cy,""),e=e.replace(Ty,""),e=e.replace(Ay,""),e=e.replace(_y,""),e=e.replace($y,""),e}function Sd(e,t){let n=e,s=0;for(;s<30;){s++;let o=Ey(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Iy(r,t),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let h={...t,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},f=Sd(a,h);return f=vd(f,h),f=xd(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Ey(e){let t=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=t.exec(e);if(!s)return null;let o=s[1],i=s[2],r=s.index+s[0].length;n.lastIndex=r;let a=1,l;for(;(l=n.exec(e))!==null;)if(l[1].startsWith("for"))a++;else if(a--,a===0){let c=e.slice(r,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function vd(e,t){let n=e,s=0;for(;Mr.test(n)&&s<50;)s++,n=n.replace(Mr,(o,i,r)=>{let a=r.split(/\{%[-\s]*else\s*-?%\}/),l=a[0],c=a[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(Un(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(Un(m,t))return g}return c}return Un(i,t)?l:c}),Mr.lastIndex=0;return n}function xd(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Ry(t,r);for(let c=1;c<i.length;c++)a=kd(a,i[c].trim());if(a==null)return"";if(typeof a=="object")return JSON.stringify(a);let l=String(a);return l=l.replace(/\\n/g," ").replace(/\n/g," "),l})}function My(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Iy(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=bd(n[1],t),i=bd(n[2],t),r=[];for(let a=o;a<i;a++)r.push(a);return r}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=Xt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Xt(t,e)}function bd(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Xt(t,o);for(let r=1;r<s.length;r++)i=kd(i,s[r].trim());return Number(i)||0}function Xt(e,t){let n=t.split("."),s=e;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function Ry(e,t){let n=t.match(/^(.+?)\s*([*/])\s*([\d.]+)$/);if(n){let s=Xt(e,n[1].trim());if(s==null||s==="")return"";let o=Number(s);if(Number.isNaN(o))return"";let i=Number(n[3]);return n[2]==="/"?i===0?"":o/i:o*i}return Xt(e,t)}function Un(e,t){let n=e.trim();if(n.startsWith("not "))return!Un(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Un(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Un(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=Xt(t,s[1].trim()),r=s[2],a=s[3].trim();switch(typeof a=="string"&&a.startsWith('"')&&a.endsWith('"')||typeof a=="string"&&a.startsWith("'")&&a.endsWith("'")?a=a.slice(1,-1):isNaN(Number(a))?a=Xt(t,a):a=Number(a),r){case"==":return i==a;case"!=":return i!=a;case">":return Number(i)>Number(a);case"<":return Number(i)<Number(a);case">=":return Number(i)>=Number(a);case"<=":return Number(i)<=Number(a)}}let o=Xt(t,n);return wd(o)}function wd(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function kd(e,t){let n=e==null?"":String(e),s=t.match(/^(\w+)\((.*)\)$/),o=s?s[1]:t,i=s?s[2].replace(/^["']|["']$/g,""):void 0;switch(o){case"escape":case"e":return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");case"lower":return n.toLowerCase();case"upper":return n.toUpperCase();case"capitalize":return n.charAt(0).toUpperCase()+n.slice(1);case"trim":return n.trim();case"truncate":if(i){let r=parseInt(i,10);return n.length>r?n.slice(0,r)+"...":n}return n;case"default":return wd(e)?e:i??"";case"length":return Array.isArray(e)?e.length:n.length;case"join":return Array.isArray(e)?e.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));case"convert_rgb":{let r=Ir(e);return r?Oy(r):""}default:return e}}function Ir(e){if(e==null)return null;if(typeof e=="string"){let t=e.match(/#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})(?![0-9a-fA-F])/);return t?Ny(t[1]):null}if(typeof e=="object"){let t=e;if(typeof t.color=="string")return Ir(t.color);if(typeof t.hex=="string")return Ir(t.hex)}return null}function Ny(e){let t=e.toLowerCase();return t.length===3?t.split("").map(n=>n+n).join(""):t}function Oy(e){let t=parseInt(e.slice(0,2),16),n=parseInt(e.slice(2,4),16),s=parseInt(e.slice(4,6),16);return`${t}, ${n}, ${s}`}var xy,wy,ky,hd,yd,Cy,Ty,Ay,_y,$y,Mr,Nr=R(()=>{"use strict";y();xy=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,wy=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,ky=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,hd=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,yd=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Cy=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Ty=/\{%[-\s]*module\b.*?%\}/gs,Ay=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,_y=/\{#.*?#\}/gs,$y=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Mr=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var si={};We(si,{buildModulePreviewHtml:()=>Dr,buildPreviewHtml:()=>Fr});function Fy(e){if(Wn()==="email")return!0;for(let t of e)try{let n=JSON.parse(t.metaJson);if(Array.isArray(n.host_template_types)&&n.host_template_types.includes("EMAIL"))return!0}catch{}return!1}function Dy(e){if(!e)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let t=(a,l)=>{for(let c of a){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=e.match(d);if(u)return u[1].trim()}return l},n=t(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=t(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=t(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=t(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),r=t(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:r}}function Or(e,t){if(!Array.isArray(t))return e;let n=new Map;for(let o of t)n.set(o.name,o.type);let s=e;return s=s.replace(/(<([a-zA-Z]\w*)(\s[^>]*)?>)\s*(\{\{\s*module\.(\w+)(?:\.\w+)*(?:\|[^}]*)?\s*\}\})\s*(<\/\2>)/g,(o,i,r,a,l,c,d)=>{if(i.includes("data-vs-field"))return o;let u=n.get(c)||"text";return`${i.replace(/>$/,` data-vs-field="${c}" data-vs-type="${u}">`)}${l}${d}`}),s=s.replace(/(<img\b)([^>]*?)\bsrc\s*=\s*["']\{\{\s*module\.(\w+)\.src\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-field")?o:o.replace("<img",`<img data-vs-field="${a}" data-vs-type="image"`)),s=s.replace(/(<a\b)([^>]*?)\bhref\s*=\s*["']\{\{\s*module\.(\w+)\.url\.href\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-link")?o:o.replace("<a",`<a data-vs-link="${a}"`)),s}function Fr(){let e=w();if(!e)return Cd();let t=xe(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return Cd();if(Fy(t))return jy(t,n);let s=[],o=[],i=[],r=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d,u=[];try{let f=JSON.parse(c.fieldsJson);u=Array.isArray(f)?f:[],d={module:un(u)}}catch{d={module:{}}}let m=Or(c.moduleHtml,u),g=Gn(m,d),h=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${h}" data-module="${c.moduleName}">${g}</div>`),r.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let a=Dy(e.sharedCss);for(let c of n)if(!r.has(c)){let d=c.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module vibespot-module--pending" id="${d}" data-module="${c}">
384
384
  <div class="vibespot-placeholder">
385
385
  <div class="vibespot-placeholder__name">${c}</div>
386
386
  </div>
387
- </div>`)}let l=`body{background:${a.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${a.surface};border:1px dashed ${a.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${a.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return br({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function Xc(){return`<!DOCTYPE html>
387
+ </div>`)}let l=`body{background:${a.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${a.surface};border:1px dashed ${a.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${a.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return Rr({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function Cd(){return`<!DOCTYPE html>
388
388
  <html lang="en">
389
389
  <head>
390
390
  <meta charset="utf-8">
@@ -435,7 +435,7 @@ document.querySelectorAll('img').forEach(function(img){
435
435
  <div class="welcome__sub">Build Something Great</div>
436
436
  </div>
437
437
  </body>
438
- </html>`}function wr(e){let t=C();if(!t)return"";let n;for(let a of t.templates)if(n=a.modules.find(l=>l.moduleName===e),n)break;if(n||(n=t.modules.find(a=>a.moduleName===e)),!n)return"";let s,o=[];try{let a=JSON.parse(n.fieldsJson);o=Array.isArray(a)?a:[],s={module:rn(o)}}catch{s={module:{}}}let i=vr(n.moduleHtml,o),r=jn(i,s);return br({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${r}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}function Gh(e,t){let n=[],s=new Set;for(let i of e){let r,a=[];try{let u=JSON.parse(i.fieldsJson);a=Array.isArray(u)?u:[],r={module:rn(a)}}catch{r={module:{}}}let l=vr(i.moduleHtml,a),c=jn(l,r),d=i.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module" id="${d}" data-module="${i.moduleName}">${c}</div>`),s.add(i.moduleName)}for(let i of t)if(!s.has(i)){let r=i.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module vibespot-module--pending" id="${r}" data-module="${i}">
438
+ </html>`}function Dr(e){let t=w();if(!t)return"";let n;for(let a of t.templates)if(n=a.modules.find(l=>l.moduleName===e),n)break;if(n||(n=t.modules.find(a=>a.moduleName===e)),!n)return"";let s,o=[];try{let a=JSON.parse(n.fieldsJson);o=Array.isArray(a)?a:[],s={module:un(o)}}catch{s={module:{}}}let i=Or(n.moduleHtml,o),r=Gn(i,s);return Rr({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${r}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}function jy(e,t){let n=[],s=new Set;for(let i of e){let r,a=[];try{let u=JSON.parse(i.fieldsJson);a=Array.isArray(u)?u:[],r={module:un(a)}}catch{r={module:{}}}let l=Or(i.moduleHtml,a),c=Gn(l,r),d=i.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module" id="${d}" data-module="${i.moduleName}">${c}</div>`),s.add(i.moduleName)}for(let i of t)if(!s.has(i)){let r=i.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module vibespot-module--pending" id="${r}" data-module="${i}">
439
439
  <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="max-width:600px;margin:0 auto;">
440
440
  <tr><td style="padding:40px 30px;text-align:center;background-color:#ffffff;border:1px dashed #ddd;">
441
441
  <p style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#999;">${i}</p>
@@ -485,7 +485,7 @@ document.addEventListener('click', function(e) {
485
485
  });
486
486
  </script>
487
487
  </body>
488
- </html>`}var Ss=N(()=>{"use strict";y();Sr();Ce();vs()});function ct(e){try{return JSON.parse(e)}catch{}let t=e,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(t)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let r=parseInt(i[1],10);if(r<=n)return null;n=r;let a=Math.max(0,r-5),c=t.slice(a,r+1).lastIndexOf('"');if(c===-1)return null;let d=a+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function xs(e){let t=e.indexOf('"modules"');if(t===-1)return null;let n=e.indexOf("[",t);if(n===-1)return null;let s=-1,o=0,i=!1,r=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(r){r=!1;continue}if(u==="\\"){r=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=e.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ct(c)}function Cr(e){return{moduleName:String(e.moduleName||""),fieldsJson:typeof e.fieldsJson=="string"?e.fieldsJson:JSON.stringify(e.fieldsJson,null,2),metaJson:typeof e.metaJson=="string"?e.metaJson:JSON.stringify(e.metaJson,null,2),moduleHtml:String(e.moduleHtml||""),moduleCss:String(e.moduleCss||""),moduleJs:e.moduleJs?String(e.moduleJs):void 0}}function Zc(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{E.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ct(s[1]);if(!i||typeof i!="object")throw E.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let r=i;r.modules&&Array.isArray(r.modules)&&(He({modules:r.modules.map(a=>Cr(a)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(i){E.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let r=ct(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(He({modules:a.modules.map(l=>Cr(l)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(r){E.warn("parse","Failed to parse JSON module block",{error:r instanceof Error?r.message:String(r)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){E.info("parse","Detected truncated response (odd fence count), attempting salvage");let r=e.lastIndexOf("```"),a=e.slice(r+3);a=a.replace(/^[\w-]*\s*\n?/,"");let l=xs(a);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(E.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),He({modules:c.modules.map(d=>Cr(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){E.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),r=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(i||r){let a=i?"Module changes could not be applied \u2014 the AI response contained invalid JSON. Try sending your request again.":"The AI described modules but did not include the required structured data. Try sending your request again.";E.warn("parse",a),t&&t(a)}}}var Wo=N(()=>{"use strict";y();Ce();le()});function Bn(){let e=C();return e?{pageType:ke()?.pageType,brandAssets:e.brandAssets}:{}}function ed(e,t,n=!1,s,o){let r=[{type:"text",text:Kh(t,n)}];if(n){let l=`## HubSpot CMS Rules
488
+ </html>`}var _s=R(()=>{"use strict";y();Nr();Ce();$s()});function ut(e){try{return JSON.parse(e)}catch{}let t=e,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(t)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let r=parseInt(i[1],10);if(r<=n)return null;n=r;let a=Math.max(0,r-5),c=t.slice(a,r+1).lastIndexOf('"');if(c===-1)return null;let d=a+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function Ps(e){let t=e.indexOf('"modules"');if(t===-1)return null;let n=e.indexOf("[",t);if(n===-1)return null;let s=-1,o=0,i=!1,r=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(r){r=!1;continue}if(u==="\\"){r=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=e.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ut(c)}function jr(e){return{moduleName:String(e.moduleName||""),fieldsJson:typeof e.fieldsJson=="string"?e.fieldsJson:JSON.stringify(e.fieldsJson,null,2),metaJson:typeof e.metaJson=="string"?e.metaJson:JSON.stringify(e.metaJson,null,2),moduleHtml:String(e.moduleHtml||""),moduleCss:String(e.moduleCss||""),moduleJs:e.moduleJs?String(e.moduleJs):void 0}}function Td(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{T.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ut(s[1]);if(!i||typeof i!="object")throw T.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let r=i;r.modules&&Array.isArray(r.modules)&&(Ue({modules:r.modules.map(a=>jr(a)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(i){T.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let r=ut(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(Ue({modules:a.modules.map(l=>jr(l)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(r){T.warn("parse","Failed to parse JSON module block",{error:r instanceof Error?r.message:String(r)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){T.info("parse","Detected truncated response (odd fence count), attempting salvage");let r=e.lastIndexOf("```"),a=e.slice(r+3);a=a.replace(/^[\w-]*\s*\n?/,"");let l=Ps(a);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(T.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),Ue({modules:c.modules.map(d=>jr(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){T.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),r=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(i||r){let a=i?"Module changes could not be applied \u2014 the AI response contained invalid JSON. Try sending your request again.":"The AI described modules but did not include the required structured data. Try sending your request again.";T.warn("parse",a),t&&t(a)}}}var oi=R(()=>{"use strict";y();Ce();de()});function Vn(){let e=w();return e?{pageType:Te()?.pageType,brandAssets:e.brandAssets}:{}}function _d(e,t,n=!1,s,o){let r=[{type:"text",text:By(t,n)}];if(n){let l=`## HubSpot CMS Rules
489
489
  ${Je()}
490
490
 
491
491
  ## Conversion Guide Reference
@@ -512,22 +512,22 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
512
512
  This makes elements appear after 3 seconds if JS never adds the .visible class. Once JS runs normally and adds .visible, the animation is cancelled.
513
513
 
514
514
  ## Design Guide
515
- ${ls()}
515
+ ${gs()}
516
516
 
517
517
  ## Content & Copywriting Guide
518
- ${Ki()}
518
+ ${cr()}
519
519
 
520
520
  ## HubSpot CMS Rules
521
521
  ${Je()}
522
522
 
523
523
  ## Conversion Guide Reference
524
- ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=Wh(s,o);return a&&r.push({type:"text",text:a}),r.push({type:"text",text:"## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory."}),r}function Wh(e,t){let n=[];if(e){let s=zi(e);s&&n.push(`## Page Type Context
524
+ ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=Ly(s,o);return a&&r.push({type:"text",text:a}),r.push({type:"text",text:"## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory."}),r}function Ly(e,t){let n=[];if(e){let s=ur(e);s&&n.push(`## Page Type Context
525
525
  ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
526
526
  ${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
527
- ${t.brandvoice}`),t?.humanify!==!1){let s=Vi();s&&n.push(`## Anti-AI Copy Rules (Humanify)
527
+ ${t.brandvoice}`),t?.humanify!==!1){let s=dr();s&&n.push(`## Anti-AI Copy Rules (Humanify)
528
528
  ${s}`)}return n.join(`
529
529
 
530
- `)}function Kh(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
530
+ `)}function By(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
531
531
 
532
532
  ## Your Role
533
533
  You generate native HubSpot CMS modules directly from user descriptions. Every module you create is immediately compatible with HubSpot's drag-and-drop page editor.
@@ -606,7 +606,7 @@ The current template's modules are listed in page order in the user message. Thi
606
606
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
607
607
  - **Remove**: When the user asks to remove a section, omit it from the output.
608
608
  - **Preserve**: Always include ALL modules you want to keep (modified + unchanged) in your output. Modules omitted from the output will be removed from the page.
609
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function ws(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
609
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function Es(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
610
610
 
611
611
  ## Your Role
612
612
  You generate native HubSpot CMS modules directly from user descriptions. Every module you create is immediately compatible with HubSpot's drag-and-drop page editor.
@@ -685,7 +685,7 @@ The current template's modules are listed in page order in the user message. Thi
685
685
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
686
686
  - **Remove**: When the user asks to remove a section, omit it from the output.
687
687
  - **Preserve**: Always include ALL modules you want to keep (modified + unchanged) in your output. Modules omitted from the output will be removed from the page.
688
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,r=s?zi(s):"",a=r?`
688
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,r=s?ur(s):"",a=r?`
689
689
 
690
690
  ## Page Type Context
691
691
  ${r}`:"",l="";if(o?.styleguide&&(l+=`
@@ -694,7 +694,7 @@ ${r}`:"",l="";if(o?.styleguide&&(l+=`
694
694
  ${o.styleguide}`),o?.brandvoice&&(l+=`
695
695
 
696
696
  ## Brand Voice
697
- ${o.brandvoice}`),o?.humanify!==!1){let d=Vi();d&&(l+=`
697
+ ${o.brandvoice}`),o?.humanify!==!1){let d=dr();d&&(l+=`
698
698
 
699
699
  ## Anti-AI Copy Rules (Humanify)
700
700
  ${d}`)}let c="\n\n## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory.";return n?i+a+l+`
@@ -728,17 +728,17 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
728
728
  This makes elements appear after 3 seconds if JS never adds the .visible class. Once JS runs normally and adds .visible, the animation is cancelled.
729
729
 
730
730
  ## Design Guide
731
- ${ls()}
731
+ ${gs()}
732
732
 
733
733
  ## Content & Copywriting Guide
734
- ${Ki()}
734
+ ${cr()}
735
735
 
736
736
  ## HubSpot CMS Rules
737
737
  ${Je()}
738
738
 
739
739
  ## Conversion Guide Reference
740
- ${e}`+c}function Jn(e,t){return e.length<=t?e:e.slice(0,t)+`
741
- /* \u2026truncated ${e.length-t} chars to fit the context budget\u2026 */`}function Cs(){let e=C(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
740
+ ${e}`+c}function Kn(e,t){return e.length<=t?e:e.slice(0,t)+`
741
+ /* \u2026truncated ${e.length-t} chars to fit the context budget\u2026 */`}function Ms(){let e=w(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
742
742
 
743
743
  ## Page Narrative (module sequence)
744
744
  `),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
@@ -747,43 +747,43 @@ ${e}`+c}function Jn(e,t){return e.length<=t?e:e.slice(0,t)+`
747
747
  When the user asks to modify this page, decide whether to MODIFY existing modules, ADD new ones at the right narrative position, REARRANGE the sequence, or REMOVE sections. Always include ALL modules you want to keep in your output.
748
748
  `),t.push(`
749
749
  ## Current Module State
750
- `);let a=0,l=!1,c=Math.max(2e3,Math.floor(Qc/Math.max(s,1)));for(let d=0;d<s;d++){let u=n[d];if(l){t.push(`
750
+ `);let a=0,l=!1,c=Math.max(2e3,Math.floor(Ad/Math.max(s,1)));for(let d=0;d<s;d++){let u=n[d];if(l){t.push(`
751
751
  ### ${d+1}/${s}: ${u.moduleName}.module \u2014 (source omitted to fit context budget; ask to edit it specifically to load its source)
752
752
  `);continue}let m=`
753
753
  ### ${d+1}/${s}: ${u.moduleName}.module
754
754
  **fields.json:**
755
755
  \`\`\`json
756
- ${Jn(u.fieldsJson,c)}
756
+ ${Kn(u.fieldsJson,c)}
757
757
  \`\`\`
758
758
  **module.html:**
759
759
  \`\`\`html
760
- ${Jn(u.moduleHtml,c)}
760
+ ${Kn(u.moduleHtml,c)}
761
761
  \`\`\`
762
762
  **module.css:**
763
763
  \`\`\`css
764
- ${Jn(u.moduleCss,c)}
764
+ ${Kn(u.moduleCss,c)}
765
765
  \`\`\`
766
766
  `+(u.moduleJs?`**module.js:**
767
767
  \`\`\`js
768
- ${Jn(u.moduleJs,c)}
768
+ ${Kn(u.moduleJs,c)}
769
769
  \`\`\`
770
- `:"");a+=m.length,t.push(m),a>Qc&&(l=!0)}e.sharedCss&&t.push(`
770
+ `:"");a+=m.length,t.push(m),a>Ad&&(l=!0)}e.sharedCss&&t.push(`
771
771
  ### Shared CSS
772
772
  \`\`\`css
773
- ${Jn(e.sharedCss,c)}
773
+ ${Kn(e.sharedCss,c)}
774
774
  \`\`\`
775
775
  `),e.sharedJs&&t.push(`
776
776
  ### Shared JS
777
777
  \`\`\`js
778
- ${Jn(e.sharedJs,c)}
778
+ ${Kn(e.sharedJs,c)}
779
779
  \`\`\`
780
- `)}let o=Nt(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
780
+ `)}let o=Lt(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
781
781
 
782
782
  ## Available modules in this theme (reusable)
783
783
  `);for(let a of r)t.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
784
784
  `);t.push(`
785
785
  The user can ask to reuse any of these modules by name.
786
- `)}return t.join("")}function kr(e,t){let n=C(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===e&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=Cs(),r="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(r=`
786
+ `)}return t.join("")}function Lr(e,t){let n=w(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===e&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=Ms(),r="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(r=`
787
787
 
788
788
  ## Available Theme Assets
789
789
  These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
@@ -797,50 +797,50 @@ ${i}`),r&&(a+=r),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON
797
797
  [Attached document: ${d.originalName}]
798
798
  ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(a+=`
799
799
 
800
- [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?t.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:a}),o.push({role:"user",content:d})}else o.push({role:"user",content:a});return o}var Qc,td=N(()=>{"use strict";y();Ke();Ce();Qc=2e5});import{spawn as sd}from"child_process";import{mkdtempSync as Vh}from"fs";import{tmpdir as nd}from"os";import{join as zh}from"path";async function od(){return Tr||(Tr=(await import("@anthropic-ai/sdk")).default),Tr}function id(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
800
+ [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?t.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:a}),o.push({role:"user",content:d})}else o.push({role:"user",content:a});return o}var Ad,$d=R(()=>{"use strict";y();Ve();Ce();Ad=2e5});import{spawn as Ed}from"child_process";import{mkdtempSync as Jy}from"fs";import{tmpdir as Pd}from"os";import{join as Hy}from"path";async function Md(){return Br||(Br=(await import("@anthropic-ai/sdk")).default),Br}function Id(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
801
801
  [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
802
802
 
803
803
  ---
804
804
  [Attached document: ${n.originalName}]
805
- ${n.extractedText}`);return t.join("")}async function rd(e,t,n,s,o,i,r,a="anthropic-api"){for(let l=0;;l++){let c=new Date;try{let d="",u=0,m=i||(()=>{});m(je[0]);let g=setInterval(()=>{u++,m(je[Math.min(u,je.length-1)])},6e3),h=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});try{for await(let b of h)if(b.type==="content_block_delta"&&b.delta.type==="text_delta"){let S=b.delta.text;d+=S,o(S)}}finally{clearInterval(g)}let f;try{f=et((await h.finalMessage()).usage)}catch{}St({engine:a,model:s,name:"vibe-chat",input:{system:t,messages:n},output:d,usage:f,startTime:c,endTime:new Date}),r&&r(d);return}catch(d){let u=d.status,m=d.error?.type;if(!(u===429||m==="rate_limit_error"||d instanceof Error&&d.message.includes("429"))||l>=Ar.length)throw d;let h=Ar[l];E.warn("ai-engine",`Rate limited (429), attempt ${l+1}/${Ar.length} \u2014 waiting ${h}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${h}s...`),await new Promise(f=>setTimeout(f,h*1e3)),i&&i("Retrying...")}}}function ad(e,t,n){let s=ye(),i=C().modules.length>0,r=kr(e,n),a=Bn(),l=ed(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function _r(e,t,n,s,o,i,r,a,l){let c=await od(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:m}=ad(e,n,a);E.info("anthropic","API call",{model:s,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:u.length}),await rd(d,m,u,s,o,i,r)}async function ld(e,t,n,s,o,i,r){let a=await Fi();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await od(),c=new l({authToken:a,defaultHeaders:Xn}),{messages:d,systemBlocks:u}=ad(e,t,r),m=[{type:"text",text:Sn},...u];E.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await rd(c,m,d,n,s,o,i,"claude-oauth")}async function $r(e,t,n,s,o,i,r,a,l){let c=ye(),d=C().modules.length>0,u=kr(e,a),m=Bn(),g=u.map(k=>typeof k.content=="string"?k:{role:k.role,content:k.content.map(T=>T.type==="text"?{type:"text",text:T.text}:{type:"image_url",image_url:{url:`data:${T.source.media_type};base64,${T.source.data}`}})}),h=ws(c,n,d,m.pageType,m.brandAssets),f=l||"https://api.openai.com/v1/chat/completions",b=!/\/mistral(\/|$|\?)/.test(f),S=new Date,v=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,...b?{stream_options:{include_usage:!0}}:{},messages:[{role:"system",content:h},...g]})});if(!v.ok){let k=await v.text();throw new Error(`API error (${v.status}): ${k}`)}let w=0,M=i||(()=>{});M(je[0]);let j=setInterval(()=>{w++,M(je[Math.min(w,je.length-1)])},6e3),J="",H,K=v.body.getReader(),X=new TextDecoder,O="";try{for(;;){let{done:k,value:T}=await K.read();if(k)break;O+=X.decode(T,{stream:!0});let $=O.split(`
806
- `);O=$.pop()||"";for(let F of $){if(!F.startsWith("data: "))continue;let re=F.slice(6).trim();if(re==="[DONE]")break;try{let _e=JSON.parse(re),z=_e.choices?.[0]?.delta?.content;z&&(J+=z,o(z)),_e.usage&&(H=_e.usage)}catch{}}}}finally{clearInterval(j)}St({engine:"openai-api",model:s,name:"vibe-chat",input:{system:h,messages:g},output:J,usage:_n(H),startTime:S,endTime:new Date}),r&&r(J)}async function Er(e,t,n,s,o,i,r,a,l){let c=ye(),d=C(),u=d.modules.length>0,m=Cs(),g=Bn(),h=[];for(let F of d.messages.slice(-20))h.push({role:F.role==="assistant"?"model":"user",parts:[{text:F.content}]});let f=m?`${e}
805
+ ${n.extractedText}`);return t.join("")}async function Rd(e,t,n,s,o,i,r,a="anthropic-api"){for(let l=0;;l++){let c=new Date;try{let d="",u=0,m=i||(()=>{});m(Le[0]);let g=setInterval(()=>{u++,m(Le[Math.min(u,Le.length-1)])},6e3),h=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});try{for await(let b of h)if(b.type==="content_block_delta"&&b.delta.type==="text_delta"){let S=b.delta.text;d+=S,o(S)}}finally{clearInterval(g)}let f;try{f=st((await h.finalMessage()).usage)}catch{}kt({engine:a,model:s,name:"vibe-chat",input:{system:t,messages:n},output:d,usage:f,startTime:c,endTime:new Date}),r&&r(d);return}catch(d){let u=d.status,m=d.error?.type;if(!(u===429||m==="rate_limit_error"||d instanceof Error&&d.message.includes("429"))||l>=Jr.length)throw d;let h=Jr[l];T.warn("ai-engine",`Rate limited (429), attempt ${l+1}/${Jr.length} \u2014 waiting ${h}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${h}s...`),await new Promise(f=>setTimeout(f,h*1e3)),i&&i("Retrying...")}}}function Nd(e,t,n){let s=be(),i=w().modules.length>0,r=Lr(e,n),a=Vn(),l=_d(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function Hr(e,t,n,s,o,i,r,a,l){let c=await Md(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:m}=Nd(e,n,a);T.info("anthropic","API call",{model:s,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:u.length}),await Rd(d,m,u,s,o,i,r)}async function Od(e,t,n,s,o,i,r){let a=await Qi();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await Md(),c=new l({authToken:a,defaultHeaders:ss}),{messages:d,systemBlocks:u}=Nd(e,t,r),m=[{type:"text",text:_n},...u];T.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await Rd(c,m,d,n,s,o,i,"claude-oauth")}async function Ur(e,t,n,s,o,i,r,a,l){let c=be(),d=w().modules.length>0,u=Lr(e,a),m=Vn(),g=u.map(C=>typeof C.content=="string"?C:{role:C.role,content:C.content.map(P=>P.type==="text"?{type:"text",text:P.text}:{type:"image_url",image_url:{url:`data:${P.source.media_type};base64,${P.source.data}`}})}),h=Es(c,n,d,m.pageType,m.brandAssets),f=l||"https://api.openai.com/v1/chat/completions",b=!/\/mistral(\/|$|\?)/.test(f),S=new Date,x=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,...b?{stream_options:{include_usage:!0}}:{},messages:[{role:"system",content:h},...g]})});if(!x.ok){let C=await x.text();throw new Error(`API error (${x.status}): ${C}`)}let k=0,$=i||(()=>{});$(Le[0]);let L=setInterval(()=>{k++,$(Le[Math.min(k,Le.length-1)])},6e3),j="",J,V=x.body.getReader(),D=new TextDecoder,U="";try{for(;;){let{done:C,value:P}=await V.read();if(C)break;U+=D.decode(P,{stream:!0});let O=U.split(`
806
+ `);U=O.pop()||"";for(let I of O){if(!I.startsWith("data: "))continue;let Q=I.slice(6).trim();if(Q==="[DONE]")break;try{let et=JSON.parse(Q),Fe=et.choices?.[0]?.delta?.content;Fe&&(j+=Fe,o(Fe)),et.usage&&(J=et.usage)}catch{}}}}finally{clearInterval(L)}kt({engine:"openai-api",model:s,name:"vibe-chat",input:{system:h,messages:g},output:j,usage:On(J),startTime:S,endTime:new Date}),r&&r(j)}async function Gr(e,t,n,s,o,i,r,a,l){let c=be(),d=w(),u=d.modules.length>0,m=Ms(),g=Vn(),h=[];for(let I of d.messages.slice(-20))h.push({role:I.role==="assistant"?"model":"user",parts:[{text:I.content}]});let f=m?`${e}
807
807
 
808
808
  ---
809
- ${m}`:e;if(r?.length)for(let F of r)F.type==="document"&&F.extractedText&&(f+=`
809
+ ${m}`:e;if(r?.length)for(let I of r)I.type==="document"&&I.extractedText&&(f+=`
810
810
 
811
811
  ---
812
- [Attached document: ${F.originalName}]
813
- ${F.extractedText}`),F.type==="image"&&F.usage==="asset"&&F.assetPath&&(f+=`
812
+ [Attached document: ${I.originalName}]
813
+ ${I.extractedText}`),I.type==="image"&&I.usage==="asset"&&I.assetPath&&(f+=`
814
814
 
815
- [Uploaded image: ${F.originalName} \u2192 available as get_asset_url("${F.assetPath}")]`);let b=[];if(r?.length)for(let F of r)F.type==="image"&&F.base64&&b.push({inlineData:{mimeType:F.mimeType,data:F.base64}});b.push({text:f}),h.push({role:"user",parts:b});let S=l||"gemini-2.5-flash",v=a||`https://generativelanguage.googleapis.com/v1beta/models/${S}:streamGenerateContent?alt=sse&key=${t}`,w=ws(c,n,u,g.pageType,g.brandAssets),M=new Date,j=await fetch(v,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:w}]},contents:h,generationConfig:{maxOutputTokens:48e3}})});if(!j.ok){let F=await j.text();throw new Error(`Gemini API error (${j.status}): ${F}`)}let J=0,H=o||(()=>{});H(je[0]);let K=setInterval(()=>{J++,H(je[Math.min(J,je.length-1)])},6e3),X="",O,k=j.body.getReader(),T=new TextDecoder,$="";try{for(;;){let{done:F,value:re}=await k.read();if(F)break;$+=T.decode(re,{stream:!0});let _e=$.split(`
816
- `);$=_e.pop()||"";for(let z of _e){if(!z.startsWith("data: "))continue;let ue=z.slice(6).trim();try{let ne=JSON.parse(ue),$e=ne.candidates?.[0]?.content?.parts?.[0]?.text;$e&&(X+=$e,s($e)),ne.usageMetadata&&(O=ne.usageMetadata)}catch{}}}}finally{clearInterval(K)}St({engine:"gemini-api",model:S,name:"vibe-chat",input:{system:w,contents:h},output:X,usage:$n(O),startTime:M,endTime:new Date}),i&&i(X)}function Yh(){if(ks)return ks;try{ks=Vh(zh(nd(),"vibespot-claude-"))}catch{ks=nd()}return ks}function qh(e){return/prompt is too long|exceed\w*\s+(the\s+)?(maximum\s+)?context|too many (input )?tokens|200000|context window/i.test(e)?"This request exceeded the model's 200k-token context window. vibeSpot isolates the Claude Code CLI from your MCP servers and project memory, so this usually means the page state itself is too large. Try: removing or splitting very large modules, starting a fresh theme, or switching to the Anthropic API engine in AI Settings (isolated per-request, no ambient context).":e}function Ir(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=sd("claude",e,{stdio:["pipe","pipe","pipe"],env:r,cwd:Yh()}),l="",c="",d="",u=!1,m=null,g=w=>{u||(u=!0,w())},h=w=>{try{if(w.type==="assistant"&&w.message?.content){for(let M of w.message.content)if(M.type==="text"&&typeof M.text=="string"){let j=M.text;l+=j,n.onChunk&&n.onChunk(j)}else if(M.type==="tool_use"){let j=M;j.name&&n.onToolUse&&n.onToolUse(j.name,j.input)}}w.type==="result"&&(m=w,!l&&typeof w.result=="string"&&(l=w.result,n.onChunk&&n.onChunk(w.result))),n.onEvent&&n.onEvent(w)}catch{}};a.stdout.on("data",w=>{d+=w.toString();let M;for(;(M=d.indexOf(`
817
- `))>=0;){let j=d.slice(0,M).trim();if(d=d.slice(M+1),!!j)try{h(JSON.parse(j))}catch{}}}),a.stderr.on("data",w=>{c+=w.toString()}),a.on("error",w=>g(()=>i(new Error(`claude failed to start: ${w.message}`)))),a.on("close",w=>{if(d.trim()){try{h(JSON.parse(d.trim()))}catch{}d=""}g(()=>{if(w!==0||m&&m.is_error){let j=`${c}
818
- ${l}`,J=qh(j);i(J!==j?new Error(J):new Error(`claude exited with code ${w}.
815
+ [Uploaded image: ${I.originalName} \u2192 available as get_asset_url("${I.assetPath}")]`);let b=[];if(r?.length)for(let I of r)I.type==="image"&&I.base64&&b.push({inlineData:{mimeType:I.mimeType,data:I.base64}});b.push({text:f}),h.push({role:"user",parts:b});let S=l||"gemini-2.5-flash",x=a||`https://generativelanguage.googleapis.com/v1beta/models/${S}:streamGenerateContent?alt=sse&key=${t}`,k=Es(c,n,u,g.pageType,g.brandAssets),$=new Date,L=await fetch(x,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:k}]},contents:h,generationConfig:{maxOutputTokens:48e3}})});if(!L.ok){let I=await L.text();throw new Error(`Gemini API error (${L.status}): ${I}`)}let j=0,J=o||(()=>{});J(Le[0]);let V=setInterval(()=>{j++,J(Le[Math.min(j,Le.length-1)])},6e3),D="",U,C=L.body.getReader(),P=new TextDecoder,O="";try{for(;;){let{done:I,value:Q}=await C.read();if(I)break;O+=P.decode(Q,{stream:!0});let et=O.split(`
816
+ `);O=et.pop()||"";for(let Fe of et){if(!Fe.startsWith("data: "))continue;let ee=Fe.slice(6).trim();try{let re=JSON.parse(ee),Z=re.candidates?.[0]?.content?.parts?.[0]?.text;Z&&(D+=Z,s(Z)),re.usageMetadata&&(U=re.usageMetadata)}catch{}}}}finally{clearInterval(V)}kt({engine:"gemini-api",model:S,name:"vibe-chat",input:{system:k,contents:h},output:D,usage:Fn(U),startTime:$,endTime:new Date}),i&&i(D)}function Uy(){if(Is)return Is;try{Is=Jy(Hy(Pd(),"vibespot-claude-"))}catch{Is=Pd()}return Is}function Gy(e){return/prompt is too long|exceed\w*\s+(the\s+)?(maximum\s+)?context|too many (input )?tokens|200000|context window/i.test(e)?"This request exceeded the model's 200k-token context window. vibeSpot isolates the Claude Code CLI from your MCP servers and project memory, so this usually means the page state itself is too large. Try: removing or splitting very large modules, starting a fresh theme, or switching to the Anthropic API engine in AI Settings (isolated per-request, no ambient context).":e}function Kr(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=Ed("claude",e,{stdio:["pipe","pipe","pipe"],env:r,cwd:Uy()}),l="",c="",d="",u=!1,m=null,g=k=>{u||(u=!0,k())},h=k=>{try{if(k.type==="assistant"&&k.message?.content){for(let $ of k.message.content)if($.type==="text"&&typeof $.text=="string"){let L=$.text;l+=L,n.onChunk&&n.onChunk(L)}else if($.type==="tool_use"){let L=$;L.name&&n.onToolUse&&n.onToolUse(L.name,L.input)}}k.type==="result"&&(m=k,!l&&typeof k.result=="string"&&(l=k.result,n.onChunk&&n.onChunk(k.result))),n.onEvent&&n.onEvent(k)}catch{}};a.stdout.on("data",k=>{d+=k.toString();let $;for(;($=d.indexOf(`
817
+ `))>=0;){let L=d.slice(0,$).trim();if(d=d.slice($+1),!!L)try{h(JSON.parse(L))}catch{}}}),a.stderr.on("data",k=>{c+=k.toString()}),a.on("error",k=>g(()=>i(new Error(`claude failed to start: ${k.message}`)))),a.on("close",k=>{if(d.trim()){try{h(JSON.parse(d.trim()))}catch{}d=""}g(()=>{if(k!==0||m&&m.is_error){let L=`${c}
818
+ ${l}`,j=Gy(L);i(j!==L?new Error(j):new Error(`claude exited with code ${k}.
819
819
  `+(c?`Stderr: ${c.slice(0,500)}
820
- `:"")+(l?`Output: ${l.slice(0,500)}`:"No output")))}else o(l)})}),a.stdin.on("error",()=>{}),a.stdin.write(t)?a.stdin.end():a.stdin.once("drain",()=>a.stdin.end());let b=s||6e5,S=Math.round(b/6e4),v=setTimeout(()=>{a.kill(),g(()=>i(new Error(`claude (stream-json) timed out after ${S} minutes.
820
+ `:"")+(l?`Output: ${l.slice(0,500)}`:"No output")))}else o(l)})}),a.stdin.on("error",()=>{}),a.stdin.write(t)?a.stdin.end():a.stdin.once("drain",()=>a.stdin.end());let b=s||6e5,S=Math.round(b/6e4),x=setTimeout(()=>{a.kill(),g(()=>i(new Error(`claude (stream-json) timed out after ${S} minutes.
821
821
  `+(c?`Stderr: ${c.slice(0,500)}
822
- `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(v))})}function Pr(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=sd(e,t,{stdio:["pipe","pipe","pipe"],env:a}),c="",d="",u=!1,m=S=>{u||(u=!0,S())};l.stdout.on("data",S=>{let v=S.toString();c+=v,s&&s(v)}),l.stderr.on("data",S=>{d+=S.toString()}),l.on("error",S=>m(()=>r(new Error(`${e} failed to start: ${S.message}`)))),l.on("close",S=>{m(()=>{S!==0?r(new Error(`${e} exited with code ${S}.
822
+ `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(x))})}function Vr(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=Ed(e,t,{stdio:["pipe","pipe","pipe"],env:a}),c="",d="",u=!1,m=S=>{u||(u=!0,S())};l.stdout.on("data",S=>{let x=S.toString();c+=x,s&&s(x)}),l.stderr.on("data",S=>{d+=S.toString()}),l.on("error",S=>m(()=>r(new Error(`${e} failed to start: ${S.message}`)))),l.on("close",S=>{m(()=>{S!==0?r(new Error(`${e} exited with code ${S}.
823
823
  `+(d?`Stderr: ${d.slice(0,500)}
824
824
  `:"")+(c?`Output: ${c.slice(0,500)}`:"No output"))):i(c)})}),l.stdin.on("error",()=>{}),l.stdin.write(n)?l.stdin.end():l.stdin.once("drain",()=>l.stdin.end());let h=o||6e5,f=Math.round(h/6e4),b=setTimeout(()=>{l.kill(),m(()=>r(new Error(`${e} timed out after ${f} minutes.
825
825
  `+(d?`Stderr: ${d.slice(0,500)}
826
- `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function cd(e,t,n,s,o,i){let r=ye(),a=R(),l=C().modules.length>0,c=Bn(),d=ws(r,t,l,c.pageType,c.brandAssets);d+=`
826
+ `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function Fd(e,t,n,s,o,i){let r=be(),a=N(),l=w().modules.length>0,c=Vn(),d=Es(r,t,l,c.pageType,c.brandAssets);d+=`
827
827
 
828
828
  ## User Request
829
- `+e,d+=Cs(),d+=id(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print",...Mr];a.claudeCodeModel&&u.push("--model",a.claudeCodeModel),a.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let m=0,g=s||(()=>{});g(je[0]);let h=setInterval(()=>{m++;let f=je[Math.min(m,je.length-1)];g(f)},6e3);try{let f=await Ir(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(Xh(b,S))}});o&&o(f)}finally{clearInterval(h)}}function Xh(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function Nr(e,t,n,s,o,i,r){let a=ye(),l=C().modules.length>0,c=Bn(),d=ws(a,n,l,c.pageType,c.brandAssets);d+=`
829
+ `+e,d+=Ms(),d+=Id(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print",...Wr];a.claudeCodeModel&&u.push("--model",a.claudeCodeModel),a.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let m=0,g=s||(()=>{});g(Le[0]);let h=setInterval(()=>{m++;let f=Le[Math.min(m,Le.length-1)];g(f)},6e3);try{let f=await Kr(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(Wy(b,S))}});o&&o(f)}finally{clearInterval(h)}}function Wy(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function zr(e,t,n,s,o,i,r){let a=be(),l=w().modules.length>0,c=Vn(),d=Es(a,n,l,c.pageType,c.brandAssets);d+=`
830
830
 
831
831
  ## User Request
832
- `+t,d+=Cs(),d+=id(r),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;e==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,h=o||(()=>{});h(je[0]);let f=setInterval(()=>{g++;let b=je[Math.min(g,je.length-1)];h(b)},6e3);try{let b=await Pr(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Tr,je,Ar,Mr,ks,Rr=N(()=>{"use strict";y();Ke();ee();_t();Ce();td();le();Be();tn();Tr=null;je=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],Ar=[10,20,40,60,120];Mr=["--strict-mcp-config"],ks=null});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function W(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function qe(e,t,n){W(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Xe=N(()=>{"use strict";y()});import{createWriteStream as Zh,mkdirSync as dd,existsSync as Or,readFileSync as Fr}from"fs";import{join as an,extname as Qh}from"path";import{randomUUID as ey}from"crypto";import ty from"busboy";function iy(e,t){if(md.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return oy[n]??t}function ry(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function ay(e,t){if(!Or(an(e,t)))return t;let n=Qh(t),s=t.slice(0,-n.length||void 0),o=1;for(;Or(an(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function ly(e){let t=(await import("pdf-parse")).default,n=Fr(e);return(await t(n)).text}async function cy(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function dy(e){return Fr(e,"utf-8")}function pd(e,t){let n=C();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],r=0,a=[],l=ty({headers:e.headers,limits:{fileSize:ny,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=iy(m,g);if(!md.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=ud.has(h),b=ry(m),S=ey(),v,w;f?(v=an(n.themePath,"assets"),dd(v,{recursive:!0}),w=ay(v,b)):(v=an(n.themePath,".vibespot","uploads"),dd(v,{recursive:!0}),w=`${S}-${b}`);let M=an(v,w),j=Zh(M),J=0,H=!1;d.on("data",K=>{J+=K.length}),d.on("limit",()=>{H=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(j),a.push(new Promise(K=>{j.on("finish",()=>{if(!H){let X={id:S,filename:w,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:J,addedAt:new Date().toISOString()};o.push(X),pc(X)}K()}),j.on("error",()=>{i.push(`Failed to write: ${m}`),K()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=an(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await ly(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await cy(d):c.extractedText=dy(d),E.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){E.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(r===0){p(t,400,{error:"No files uploaded"});return}p(t,200,{files:o.map(c=>({id:c.id,filename:c.filename,originalName:c.originalName,type:c.type,usage:c.usage,size:c.size})),errors:i.length>0?i:void 0})}),l.on("error",c=>{E.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Ko(e){let t=C();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=an(t.themePath,"assets",s.filename);Or(i)&&(o.base64=Fr(i).toString("base64")),o.assetPath=`${t.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var ny,ud,sy,md,oy,Dr=N(()=>{"use strict";y();Xe();Ce();le();ny=10*1024*1024,ud=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),sy=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),md=new Set([...ud,...sy]),oy={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var vd={};Ge(vd,{LANGDOCK_BASE_URLS:()=>Ts,callAgent:()=>Pe,callAgentAPI:()=>Sd,isAgenticCapable:()=>_s,isCLIEngine:()=>Un,resolveThinkingBudget:()=>Hn});async function Vo(e,t){for(let n=0;;n++)try{return await e()}catch(s){let o=s.status,i=s.error?.type;if(!(o===429||i==="rate_limit_error"||s instanceof Error&&s.message.includes("429"))||n>=jr.length)throw s;let a=jr[n];E.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${jr.length} \u2014 waiting ${a}s`),t&&t(`Rate limited \u2014 retrying in ${a}s...`),await new Promise(l=>setTimeout(l,a*1e3)),t&&t("Retrying...")}}function As(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;for(let n of["fieldsJson","metaJson"])t[n]&&typeof t[n]=="object"&&(t[n]=JSON.stringify(t[n]))}return e}async function yd(){return Lr||(Lr=(await import("@anthropic-ai/sdk")).default),Lr}async function gd(e,t,n,s,o,i){let r=await yd(),a=new r({apiKey:e,...s?{defaultHeaders:s}:{},...i?{baseURL:i}:{}}),l=n.messages,c=n.systemPrompt;if(n.systemBlocks?c=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(c=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let d={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Vo(async()=>{let u=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,tools:[d],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),m=et(u.usage);for(let h of u.content)if(h.type==="tool_use")return{type:"structured",data:As(h.input),usage:m};return{type:"text",text:u.content.filter(h=>h.type==="text").map(h=>h.text).join(""),usage:m}},n.onStatus)}return Vo(async()=>{let d="",u=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let g of u)g.type==="content_block_delta"&&g.delta.type==="text_delta"&&(d+=g.delta.text,n.onChunk&&n.onChunk(g.delta.text));let m;try{m=et((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:m}},n.onStatus)}async function uy(e,t,n){let s=await yd(),o=new s({authToken:e,defaultHeaders:Xn}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:Sn},...n.systemBlocks]:r=[{type:"text",text:Sn},{type:"text",text:n.systemPrompt}],n.structuredOutput){let a={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Vo(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),c=et(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:As(u.input),usage:c};return{type:"text",text:l.content.filter(u=>u.type==="text").map(u=>u.text).join(""),usage:c}},n.onStatus)}return Vo(async()=>{let a="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let d of l)d.type==="content_block_delta"&&d.delta.type==="text_delta"&&(a+=d.delta.text,n.onChunk&&n.onChunk(d.delta.text));let c;try{c=et((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus)}function Jr(e){let t={...e};if(t.type==="object"&&(t.additionalProperties=!1,t.properties&&typeof t.properties=="object")){let n={};for(let[s,o]of Object.entries(t.properties))n[s]=o&&typeof o=="object"?Jr(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Jr(t.items)),t}async function fd(e,t,n,s){let o=[{role:"system",content:n.systemPrompt},...n.messages.map(u=>({role:u.role,content:typeof u.content=="string"?u.content:u.content.map(m=>({type:"text",text:m.text}))}))],i={model:t,max_completion_tokens:n.maxTokens||16e3,messages:o};n.structuredOutput&&(i.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!1,schema:Jr(n.structuredOutput.schema)}});let a=await fetch(s||"https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(i)});if(!a.ok){let u=await a.text(),m=a.status;if(m===429){let g=new Error(`OpenAI rate limit: ${u}`);throw g.status=429,g}throw new Error(`OpenAI API error (${m}): ${u}`)}let l=await a.json(),c=l.choices?.[0]?.message?.content||"",d=_n(l.usage);if(n.structuredOutput)try{return{type:"structured",data:As(JSON.parse(c)),usage:d}}catch{return E.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:c,usage:d}}return{type:"text",text:c,usage:d}}async function hd(e,t,n,s){let o=t||"gemini-2.5-flash",i=n.messages.map(m=>({role:m.role==="assistant"?"model":"user",parts:typeof m.content=="string"?[{text:m.content}]:m.content.map(g=>({text:g.text}))})),r={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:i,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`,l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok){let m=await l.text(),g=l.status;if(g===429){let h=new Error(`Gemini rate limit: ${m}`);throw h.status=429,h}throw new Error(`Gemini API error (${g}): ${m}`)}let c=await l.json(),d=c.candidates?.[0]?.content?.parts?.[0]?.text||"",u=$n(c.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:As(JSON.parse(d)),usage:u}}catch{return E.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:d,usage:u}}return{type:"text",text:d,usage:u}}function my(e,t,n){switch(e){case"claude-code":{let s=["--print",...Mr];return t&&s.push("--model",t),n?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":{let s=[];return t&&s.push("-m",t),{bin:"gemini",args:s}}case"codex-cli":{let s=["exec","--full-auto"];return t&&s.push("-m",t),{bin:"codex",args:s}}default:throw new Error(`Not a CLI engine: ${e}`)}}function py(e){let t=[e.systemPrompt];for(let n of e.messages){let s=n.role==="user"?"User":"Assistant",o=typeof n.content=="string"?n.content:n.content.map(i=>i.text).join(`
832
+ `+t,d+=Ms(),d+=Id(r),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;e==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,h=o||(()=>{});h(Le[0]);let f=setInterval(()=>{g++;let b=Le[Math.min(g,Le.length-1)];h(b)},6e3);try{let b=await Vr(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Br,Le,Jr,Wr,Is,Yr=R(()=>{"use strict";y();Ve();oe();It();Ce();$d();de();He();an();Br=null;Le=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],Jr=[10,20,40,60,120];Wr=["--strict-mcp-config"],Is=null});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function K(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function Ze(e,t,n){K(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Qe=R(()=>{"use strict";y()});import{createWriteStream as Ky,mkdirSync as Dd,existsSync as qr,readFileSync as Xr}from"fs";import{join as mn,extname as Vy}from"path";import{randomUUID as zy}from"crypto";import Yy from"busboy";function Qy(e,t){if(Ld.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return Zy[n]??t}function eb(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function tb(e,t){if(!qr(mn(e,t)))return t;let n=Vy(t),s=t.slice(0,-n.length||void 0),o=1;for(;qr(mn(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function nb(e){let{PDFParse:t}=await import("pdf-parse"),n=Xr(e),s=new t({data:n});try{return(await s.getText()).text}finally{await s.destroy()}}async function sb(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function ob(e){return Xr(e,"utf-8")}function Bd(e,t){let n=w();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],r=0,a=[],l=Yy({headers:e.headers,limits:{fileSize:qy,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=Qy(m,g);if(!Ld.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=jd.has(h),b=eb(m),S=zy(),x,k;f?(x=mn(n.themePath,"assets"),Dd(x,{recursive:!0}),k=tb(x,b)):(x=mn(n.themePath,".vibespot","uploads"),Dd(x,{recursive:!0}),k=`${S}-${b}`);let $=mn(x,k),L=Ky($),j=0,J=!1;d.on("data",V=>{j+=V.length}),d.on("limit",()=>{J=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(L),a.push(new Promise(V=>{L.on("finish",()=>{if(!J){let D={id:S,filename:k,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:j,addedAt:new Date().toISOString()};o.push(D),Bc(D)}V()}),L.on("error",()=>{i.push(`Failed to write: ${m}`),V()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=mn(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await nb(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await sb(d):c.extractedText=ob(d),T.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){T.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(r===0){p(t,400,{error:"No files uploaded"});return}p(t,200,{files:o.map(c=>({id:c.id,filename:c.filename,originalName:c.originalName,type:c.type,usage:c.usage,size:c.size})),errors:i.length>0?i:void 0})}),l.on("error",c=>{T.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function ii(e){let t=w();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=mn(t.themePath,"assets",s.filename);qr(i)&&(o.base64=Xr(i).toString("base64")),o.assetPath=`${t.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var qy,jd,Xy,Ld,Zy,Zr=R(()=>{"use strict";y();Qe();Ce();de();qy=10*1024*1024,jd=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Xy=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),Ld=new Set([...jd,...Xy]),Zy={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});function Rs(e){if(e instanceof Re)return!0;let t=e?.name;if(t==="AbortError"||t==="APIUserAbortError")return!0;let n=e instanceof Error?e.message:"";return/\baborted\b/i.test(n)}function ri(e,t){let n=0,s=[];return t&&t.addEventListener("abort",()=>{for(;s.length>0;)s.shift().reject(new Re)},{once:!0}),async function(i){if(t?.aborted)throw new Re;if(n>=e&&(await new Promise((r,a)=>s.push({resolve:r,reject:a})),t?.aborted))throw new Re;n++;try{return await i()}finally{n--,s.length>0&&s.shift().resolve()}}}var Re,zn=R(()=>{"use strict";y();Re=class extends Error{aborted=!0;constructor(t="Pipeline aborted"){super(t),this.name="PipelineAbortError"}}});var Vd={};We(Vd,{LANGDOCK_BASE_URLS:()=>Ns,callAgent:()=>_e,callAgentAPI:()=>Kd,isAgenticCapable:()=>Fs,isCLIEngine:()=>Yn,resolveThinkingBudget:()=>pn});async function ai(e,t){for(let n=0;;n++)try{return await e()}catch(s){let o=s.status,i=s.error?.type;if(!(o===429||i==="rate_limit_error"||s instanceof Error&&s.message.includes("429"))||n>=Qr.length)throw s;let a=Qr[n];T.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${Qr.length} \u2014 waiting ${a}s`),t&&t(`Rate limited \u2014 retrying in ${a}s...`),await new Promise(l=>setTimeout(l,a*1e3)),t&&t("Retrying...")}}function Os(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;for(let n of["fieldsJson","metaJson"])t[n]&&typeof t[n]=="object"&&(t[n]=JSON.stringify(t[n]))}return e}async function Gd(){return ea||(ea=(await import("@anthropic-ai/sdk")).default),ea}async function Jd(e,t,n,s,o,i){let r=await Gd(),a=new r({apiKey:e,...s?{defaultHeaders:s}:{},...i?{baseURL:i}:{}}),l=n.messages,c=n.systemPrompt;if(n.systemBlocks?c=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(c=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let d={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return ai(async()=>{let u=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,tools:[d],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal}),m=st(u.usage);for(let h of u.content)if(h.type==="tool_use")return{type:"structured",data:Os(h.input),usage:m};return{type:"text",text:u.content.filter(h=>h.type==="text").map(h=>h.text).join(""),usage:m}},n.onStatus)}return ai(async()=>{let d="",u=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal});for await(let g of u)g.type==="content_block_delta"&&g.delta.type==="text_delta"&&(d+=g.delta.text,n.onChunk&&n.onChunk(g.delta.text));let m;try{m=st((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:m}},n.onStatus)}async function ib(e,t,n){let s=await Gd(),o=new s({authToken:e,defaultHeaders:ss}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:_n},...n.systemBlocks]:r=[{type:"text",text:_n},{type:"text",text:n.systemPrompt}],n.structuredOutput){let a={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return ai(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal}),c=st(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:Os(u.input),usage:c};return{type:"text",text:l.content.filter(u=>u.type==="text").map(u=>u.text).join(""),usage:c}},n.onStatus)}return ai(async()=>{let a="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal});for await(let d of l)d.type==="content_block_delta"&&d.delta.type==="text_delta"&&(a+=d.delta.text,n.onChunk&&n.onChunk(d.delta.text));let c;try{c=st((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus)}function ta(e){let t={...e};if(t.type==="object"&&(t.additionalProperties=!1,t.properties&&typeof t.properties=="object")){let n={};for(let[s,o]of Object.entries(t.properties))n[s]=o&&typeof o=="object"?ta(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=ta(t.items)),t}async function Hd(e,t,n,s){let o=[{role:"system",content:n.systemPrompt},...n.messages.map(u=>({role:u.role,content:typeof u.content=="string"?u.content:u.content.map(m=>({type:"text",text:m.text}))}))],i={model:t,max_completion_tokens:n.maxTokens||16e3,messages:o};n.structuredOutput&&(i.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!1,schema:ta(n.structuredOutput.schema)}});let a=await fetch(s||"https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(i),signal:n.signal});if(!a.ok){let u=await a.text(),m=a.status;if(m===429){let g=new Error(`OpenAI rate limit: ${u}`);throw g.status=429,g}throw new Error(`OpenAI API error (${m}): ${u}`)}let l=await a.json(),c=l.choices?.[0]?.message?.content||"",d=On(l.usage);if(n.structuredOutput)try{return{type:"structured",data:Os(JSON.parse(c)),usage:d}}catch{return T.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:c,usage:d}}return{type:"text",text:c,usage:d}}async function Ud(e,t,n,s){let o=t||"gemini-2.5-flash",i=n.messages.map(m=>({role:m.role==="assistant"?"model":"user",parts:typeof m.content=="string"?[{text:m.content}]:m.content.map(g=>({text:g.text}))})),r={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:i,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`,l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:n.signal});if(!l.ok){let m=await l.text(),g=l.status;if(g===429){let h=new Error(`Gemini rate limit: ${m}`);throw h.status=429,h}throw new Error(`Gemini API error (${g}): ${m}`)}let c=await l.json(),d=c.candidates?.[0]?.content?.parts?.[0]?.text||"",u=Fn(c.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:Os(JSON.parse(d)),usage:u}}catch{return T.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:d,usage:u}}return{type:"text",text:d,usage:u}}function rb(e,t,n){switch(e){case"claude-code":{let s=["--print",...Wr];return t&&s.push("--model",t),n?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":{let s=[];return t&&s.push("-m",t),{bin:"gemini",args:s}}case"codex-cli":{let s=["exec","--full-auto"];return t&&s.push("-m",t),{bin:"codex",args:s}}default:throw new Error(`Not a CLI engine: ${e}`)}}function ab(e){let t=[e.systemPrompt];for(let n of e.messages){let s=n.role==="user"?"User":"Assistant",o=typeof n.content=="string"?n.content:n.content.map(i=>i.text).join(`
833
833
  `);t.push(`
834
834
 
835
835
  ## ${s}
836
- ${o}`)}if(e.structuredOutput){let n=bd(e.structuredOutput.schema);t.push(`
836
+ ${o}`)}if(e.structuredOutput){let n=Wd(e.structuredOutput.schema);t.push(`
837
837
 
838
838
  ## Output Format \u2014 CRITICAL
839
839
  Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
840
840
 
841
841
  The JSON must match this structure:
842
- ${n}`)}return t.join("")}function bd(e,t=0){let n=" ".repeat(t),s=e.properties,o=e.required||[];if(!s)return`${n}${JSON.stringify(e)}`;let i=["{"];for(let[r,a]of Object.entries(s)){let l=o.includes(r)?" (required)":"",c=a.type||"any",d=a.description?` \u2014 ${a.description}`:"",u=a.enum?` [${a.enum.join(", ")}]`:"";if(c==="array"&&a.items){let m=a.items.type||"object";i.push(`${n} "${r}": ${c}<${m}>${l}${d}${u}`)}else c==="object"&&a.properties?i.push(`${n} "${r}": ${bd(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
843
- `)}function gy(e){let t=e.trim(),n=ct(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let a=s[1].trim(),l=ct(a);if(l&&typeof l=="object")return l;let c=xs(a);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let a=t.slice(o,i+1),l=ct(a);if(l&&typeof l=="object")return l;let c=xs(a);if(c&&typeof c=="object")return c}let r=xs(t);return r&&typeof r=="object"?r:null}async function fy(e,t,n){let{bin:s,args:o}=my(e,t,n),i=py(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Ir(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=hy(c,d);n.onStatus(u)}})}else r=await Pr(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=gy(r);return a?{type:"structured",data:As(a)}:(E.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function hy(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function Sd(e,t,n,s){E.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length});let o=new Date,i=await(async()=>{switch(e){case"anthropic-api":return gd(t,n,s);case"claude-oauth":{let{getValidAccessToken:r}=await Promise.resolve().then(()=>(_t(),Di)),a=await r();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return uy(a,n,s)}case"openai-api":return fd(t,n,s);case"gemini-api":return hd(t,n,s);case"langdock-api":{let r=R(),a=r.langdockProvider||"anthropic",l=r.langdockBaseUrl;switch(a){case"openai":case"mistral":{let c=l||Ts[a];return fd(t,n,s,`${c}/v1/chat/completions`)}case"google":{let c=l||Ts.google;return hd(t,n,s,`${c}/v1beta/models/${n}:generateContent`)}default:{let c=l||Ts.anthropic;return gd(t,n,s,void 0,void 0,c)}}}default:throw new Error(`Unsupported API engine: ${e}`)}})();return by(e,n,s,i,o,new Date),i}function by(e,t,n,s,o,i){St({engine:e,model:t,name:n.structuredOutput?.name||"generation",input:{system:n.systemPrompt,messages:n.messages},output:s.type==="structured"?s.data:s.text,usage:s.usage,startTime:o,endTime:i,metadata:{structured:!!n.structuredOutput,systemPromptLength:n.systemPrompt.length}})}async function Pe(e,t,n,s){return yy.has(e)?Sd(e,t,n,s):(E.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),fy(e,n,s))}function Hn(e){if(e==="langdock-api"){if((R().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=R();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function _s(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="langdock-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function Un(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Ts,Kk,jr,Lr,yy,dt=N(()=>{"use strict";y();Rr();Wo();ee();_t();le();tn();Be();Ts={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},Kk=Ts.anthropic,jr=[10,20,40,60,120];Lr=null;yy=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});var Br,xd=N(()=>{"use strict";y();Br={"intent-analyzer":{version:2,placeholders:["themeName","contextData"],template:`You are the Intent Analyzer for vibeSpot, a HubSpot CMS builder that generates pages, email templates, and blog templates.
842
+ ${n}`)}return t.join("")}function Wd(e,t=0){let n=" ".repeat(t),s=e.properties,o=e.required||[];if(!s)return`${n}${JSON.stringify(e)}`;let i=["{"];for(let[r,a]of Object.entries(s)){let l=o.includes(r)?" (required)":"",c=a.type||"any",d=a.description?` \u2014 ${a.description}`:"",u=a.enum?` [${a.enum.join(", ")}]`:"";if(c==="array"&&a.items){let m=a.items.type||"object";i.push(`${n} "${r}": ${c}<${m}>${l}${d}${u}`)}else c==="object"&&a.properties?i.push(`${n} "${r}": ${Wd(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
843
+ `)}function lb(e){let t=e.trim(),n=ut(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let a=s[1].trim(),l=ut(a);if(l&&typeof l=="object")return l;let c=Ps(a);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let a=t.slice(o,i+1),l=ut(a);if(l&&typeof l=="object")return l;let c=Ps(a);if(c&&typeof c=="object")return c}let r=Ps(t);return r&&typeof r=="object"?r:null}async function cb(e,t,n){let{bin:s,args:o}=rb(e,t,n),i=ab(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Kr(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=db(c,d);n.onStatus(u)}})}else r=await Vr(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=lb(r);return a?{type:"structured",data:Os(a)}:(T.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function db(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function Kd(e,t,n,s){T.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length});let o=new Date,i=await(async()=>{switch(e){case"anthropic-api":return Jd(t,n,s);case"claude-oauth":{let{getValidAccessToken:r}=await Promise.resolve().then(()=>(It(),er)),a=await r();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return ib(a,n,s)}case"openai-api":return Hd(t,n,s);case"gemini-api":return Ud(t,n,s);case"langdock-api":{let r=N(),a=r.langdockProvider||"anthropic",l=r.langdockBaseUrl;switch(a){case"openai":case"mistral":{let c=l||Ns[a];return Hd(t,n,s,`${c}/v1/chat/completions`)}case"google":{let c=l||Ns.google;return Ud(t,n,s,`${c}/v1beta/models/${n}:generateContent`)}default:{let c=l||Ns.anthropic;return Jd(t,n,s,void 0,void 0,c)}}}default:throw new Error(`Unsupported API engine: ${e}`)}})();return mb(e,n,s,i,o,new Date),i}function mb(e,t,n,s,o,i){kt({engine:e,model:t,name:n.structuredOutput?.name||"generation",input:{system:n.systemPrompt,messages:n.messages},output:s.type==="structured"?s.data:s.text,usage:s.usage,startTime:o,endTime:i,metadata:{structured:!!n.structuredOutput,systemPromptLength:n.systemPrompt.length,...n.prompt?.source?{promptSource:n.prompt.source}:{}},...n.prompt?{promptName:n.prompt.name,promptVersion:n.prompt.version}:{}})}async function _e(e,t,n,s){if(s.signal?.aborted)throw new Re;return ub.has(e)?Kd(e,t,n,s):(T.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),cb(e,n,s))}function pn(e){if(e==="langdock-api"){if((N().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=N();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Fs(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="langdock-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function Yn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Ns,sA,Qr,ea,ub,mt=R(()=>{"use strict";y();Yr();oi();oe();It();de();an();He();zn();Ns={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},sA=Ns.anthropic,Qr=[10,20,40,60,120];ea=null;ub=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});var na,zd=R(()=>{"use strict";y();na={"intent-analyzer":{version:2,placeholders:["themeName","contextData"],template:`You are the Intent Analyzer for vibeSpot, a HubSpot CMS builder that generates pages, email templates, and blog templates.
844
844
 
845
845
  Your job: classify the user's request, determine the content type (page, email, or blog), and plan which modules need work. You do NOT generate module code \u2014 you only plan. Think like a product strategist: read past the literal words to the outcome the user actually wants, then scope the smallest set of changes that delivers it.
846
846
 
@@ -1176,7 +1176,7 @@ Every style/color field you reference in CSS must ship a complete default value.
1176
1176
  - Include smooth scroll behavior in nav click handlers, and respect prefers-reduced-motion
1177
1177
 
1178
1178
  ## metaJson Template
1179
- { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`}}});function vy(){if(wd!==void 0)return wd;if($s!==void 0)return $s;try{let e=JSON.parse(P(hn(Sy)));$s=e&&typeof e=="object"&&e.prompts?e:null}catch{$s=null}return $s}function xy(e){let t=new Set;for(let n of e.matchAll(Cd))t.add(n[1]);return[...t]}function wy(e){let t=Br[e],n=vy()?.prompts?.[e];if(n&&n.version===t.version&&typeof n.template=="string"){let s=new Set(t.placeholders);if(xy(n.template).every(o=>s.has(o)))return{id:e,version:n.version,source:"langfuse-bundled",template:n.template}}return{id:e,version:t.version,source:"local-fallback",template:t.template}}function Cy(e,t,n){let s=new Set(Br[e].placeholders);return t.replace(Cd,(o,i)=>s.has(i)?n[i]??"":o)}function Rt(e,t){return Cy(e,wy(e).template,t)}var Sy,Cd,$s,wd,Es=N(()=>{"use strict";y();oe();xd();Sy="prompts.bundle.json",Cd=/\{\{\s*([a-zA-Z][\w]*)\s*\}\}/g});function kd(e,t,n,s,o){let i=t.length>0?`Current template modules (in page order):
1179
+ { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`}}});function fb(){if(Yd!==void 0)return Yd;if(Ds!==void 0)return Ds;try{let e=JSON.parse(M(Cn(gb)));Ds=e&&typeof e=="object"&&e.prompts?e:null}catch{Ds=null}return Ds}function hb(e){let t=new Set;for(let n of e.matchAll(qd))t.add(n[1]);return[...t]}function Xd(e){let t=na[e],n=fb()?.prompts?.[e];if(n&&n.version===t.version&&typeof n.template=="string"){let s=new Set(t.placeholders);if(hb(n.template).every(o=>s.has(o)))return{id:e,version:n.version,source:"langfuse-bundled",template:n.template}}return{id:e,version:t.version,source:"local-fallback",template:t.template}}function yb(e,t,n){let s=new Set(na[e].placeholders);return t.replace(qd,(o,i)=>s.has(i)?n[i]??"":o)}function pt(e){let t=Xd(e);return{name:`${pb}${e}`,version:t.version,source:t.source}}function Bt(e,t){return yb(e,Xd(e).template,t)}var pb,gb,qd,Ds,Yd,Jt=R(()=>{"use strict";y();ae();zd();pb="vibespot-stage-",gb="prompts.bundle.json",qd=/\{\{\s*([a-zA-Z][\w]*)\s*\}\}/g});function Zd(e,t,n,s,o){let i=t.length>0?`Current template modules (in page order):
1180
1180
  ${t.map((d,u)=>`${u+1}. ${d}`).join(`
1181
1181
  `)}`:"No modules yet (new page).",r=n.length>0?`
1182
1182
 
@@ -1193,10 +1193,10 @@ All pages:
1193
1193
  ${o.pages.map(d=>`- ${d.label} (${d.id}, ${d.moduleCount} modules)`).join(`
1194
1194
  `)}
1195
1195
 
1196
- The user's message applies to the current page unless they reference another page by name or say "all pages" / "every page" / "the whole site".`:"",c=`${i}${r}${a}${l}`;return Rt("intent-analyzer",{themeName:e,contextData:c})}var Td,Ad=N(()=>{"use strict";y();Es();Td={type:"object",properties:{intent:{type:"string",enum:["create","create_site","modify","add","remove","rearrange","style_change","question"]},contentType:{type:"string",enum:["page","email","blog"],description:'Content type: "page" (default), "email" for email templates, or "blog" for blog templates'},affectedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that need changes"},unchangedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that stay as-is"},newModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},position:{type:"number"}},required:["name","description","position"]},description:"New modules to create"},reuseModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},sourceTemplate:{type:"string"},position:{type:"number"}},required:["name","sourceTemplate","position"]},description:"Modules to copy from the library (immutable structure)"},guidesNeeded:{type:"array",items:{type:"string",enum:["design","content","conversion","hubspot_rules","humanify"]}},designSystemChanges:{type:"boolean",description:"True if shared CSS / design system needs regeneration"},answer:{type:"string",description:'For "question" intent only \u2014 the answer to return directly'},pages:{type:"array",items:{type:"object",properties:{id:{type:"string",description:"Kebab-case page ID (e.g. wp-home)"},label:{type:"string",description:"Human-readable page name"},pageType:{type:"string",enum:["landing_page","website_page","blog_post"]},purpose:{type:"string",description:"One-sentence page purpose"},slug:{type:"string",description:"URL path without leading /"}},required:["id","label","pageType","purpose","slug"]},description:'For "create_site" intent \u2014 list of pages to generate'},sharedModules:{type:"array",items:{type:"string"},description:'For "create_site" intent \u2014 module names shared across all pages (e.g. site-header, site-footer)'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function _d(e,t,n,s,o,i,r){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let a=t.modules.map(g=>g.moduleName),l=kd(t.themeName,a,r,t.brandAssets?.themeContext,t.sitePages?{activePageLabel:t.activePageLabel,pages:t.sitePages}:void 0),c=[],d=t.messages.slice(-6);for(let g of d)if(g.role==="user"||g.role==="assistant"){let h=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:h})}c.push({role:"user",content:e});let u=await te("intent-analyzer",()=>Pe(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Td,name:"pipeline_plan"},maxTokens:2e3}));if(u.type!=="structured"){E.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:a,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:g}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],t.contentMode==="email"?m.contentType="email":m.contentType=m.contentType==="email"?"email":"page",E.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:ky(m)}),m}function ky(e){let t=[`Intent: ${e.intent}`];return e.affectedModules.length>0&&t.push(`Modifying: ${e.affectedModules.join(", ")}`),e.unchangedModules.length>0&&t.push(`Unchanged: ${e.unchangedModules.join(", ")}`),e.newModules.length>0&&t.push(`New: ${e.newModules.map(n=>n.name).join(", ")}`),e.reuseModules?.length&&t.push(`Reuse: ${e.reuseModules.map(n=>`${n.name} from ${n.sourceTemplate}`).join(", ")}`),e.designSystemChanges&&t.push("Design system changes: yes"),t.join(" | ")}var $d=N(()=>{"use strict";y();dt();Ad();le();Be()});function zo(e,t){let n=[];n.push(Rt("design-system",{themeName:e})),n.push(`
1196
+ The user's message applies to the current page unless they reference another page by name or say "all pages" / "every page" / "the whole site".`:"",c=`${i}${r}${a}${l}`;return Bt("intent-analyzer",{themeName:e,contextData:c})}var Qd,eu=R(()=>{"use strict";y();Jt();Qd={type:"object",properties:{intent:{type:"string",enum:["create","create_site","modify","add","remove","rearrange","style_change","question"]},contentType:{type:"string",enum:["page","email","blog"],description:'Content type: "page" (default), "email" for email templates, or "blog" for blog templates'},affectedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that need changes"},unchangedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that stay as-is"},newModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},position:{type:"number"}},required:["name","description","position"]},description:"New modules to create"},reuseModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},sourceTemplate:{type:"string"},position:{type:"number"}},required:["name","sourceTemplate","position"]},description:"Modules to copy from the library (immutable structure)"},guidesNeeded:{type:"array",items:{type:"string",enum:["design","content","conversion","hubspot_rules","humanify"]}},designSystemChanges:{type:"boolean",description:"True if shared CSS / design system needs regeneration"},answer:{type:"string",description:'For "question" intent only \u2014 the answer to return directly'},pages:{type:"array",items:{type:"object",properties:{id:{type:"string",description:"Kebab-case page ID (e.g. wp-home)"},label:{type:"string",description:"Human-readable page name"},pageType:{type:"string",enum:["landing_page","website_page","blog_post"]},purpose:{type:"string",description:"One-sentence page purpose"},slug:{type:"string",description:"URL path without leading /"}},required:["id","label","pageType","purpose","slug"]},description:'For "create_site" intent \u2014 list of pages to generate'},sharedModules:{type:"array",items:{type:"string"},description:'For "create_site" intent \u2014 module names shared across all pages (e.g. site-header, site-footer)'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function tu(e,t,n,s,o,i,r){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let a=t.modules.map(g=>g.moduleName),l=Zd(t.themeName,a,r,t.brandAssets?.themeContext,t.sitePages?{activePageLabel:t.activePageLabel,pages:t.sitePages.map(g=>({id:g.id,label:g.label,moduleCount:g.moduleCount}))}:void 0),c=[],d=t.messages.slice(-6);for(let g of d)if(g.role==="user"||g.role==="assistant"){let h=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:h})}c.push({role:"user",content:e});let u=await se("intent-analyzer",()=>_e(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Qd,name:"pipeline_plan"},maxTokens:2e3,prompt:pt("intent-analyzer")}));if(u.type!=="structured"){T.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:a,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:g}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],t.contentMode==="email"?m.contentType="email":m.contentType=m.contentType==="email"?"email":"page",T.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:bb(m)}),m}function bb(e){let t=[`Intent: ${e.intent}`];return e.affectedModules.length>0&&t.push(`Modifying: ${e.affectedModules.join(", ")}`),e.unchangedModules.length>0&&t.push(`Unchanged: ${e.unchangedModules.join(", ")}`),e.newModules.length>0&&t.push(`New: ${e.newModules.map(n=>n.name).join(", ")}`),e.reuseModules?.length&&t.push(`Reuse: ${e.reuseModules.map(n=>`${n.name} from ${n.sourceTemplate}`).join(", ")}`),e.designSystemChanges&&t.push("Design system changes: yes"),t.join(" | ")}var nu=R(()=>{"use strict";y();mt();eu();Jt();de();He()});function li(e,t){let n=[];n.push(Bt("design-system",{themeName:e})),n.push(`
1197
1197
 
1198
1198
  ## Design Guide
1199
- ${Nd()}`),t?.styleguide&&n.push(`
1199
+ ${iu()}`),t?.styleguide&&n.push(`
1200
1200
 
1201
1201
  ## Brand Style Guide
1202
1202
  ${t.styleguide}`),t?.themeContext&&n.push(`
@@ -1212,11 +1212,11 @@ ${o.join(`
1212
1212
  ## No Brand Provided \u2014 Follow the Generation Recipe
1213
1213
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1214
1214
 
1215
- ${Pd()}`),n.join("")}function Hr(e,t){let n=zo(e),o=n.indexOf(`
1215
+ ${ou()}`),n.join("")}function sa(e,t){let n=li(e),o=n.indexOf(`
1216
1216
 
1217
1217
  ## Design Guide
1218
1218
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Design Guide
1219
- ${Nd()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1219
+ ${iu()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1220
1220
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1221
1221
  ${t.themeContext}`);let c=t?.brandKit&&(t.brandKit.colors?.primary||t.brandKit.colors?.secondary||t.brandKit.colors?.accent||t.brandKit.fonts?.heading||t.brandKit.fonts?.body);if(c){let d=[],u=t.brandKit;u.colors?.primary&&d.push(`- Primary color: ${u.colors.primary}`),u.colors?.secondary&&d.push(`- Secondary color: ${u.colors.secondary}`),u.colors?.accent&&d.push(`- Accent color: ${u.colors.accent}`),u.fonts?.heading&&d.push(`- Heading font: ${u.fonts.heading}`),u.fonts?.body&&d.push(`- Body font: ${u.fonts.body}`),u.logoUrl&&d.push(`- Logo URL: ${u.logoUrl}`),d.length>0&&l.push(`## Brand Kit \u2014 MANDATORY Design Constraints
1222
1222
  The following brand identity values MUST be used. Do NOT substitute or override them:
@@ -1224,13 +1224,13 @@ ${d.join(`
1224
1224
  `)}`)}return!c&&!t?.styleguide&&l.push(`## No Brand Provided \u2014 Follow the Generation Recipe
1225
1225
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1226
1226
 
1227
- ${Pd()}`),l.length>0&&a.push({type:"text",text:l.join(`
1227
+ ${ou()}`),l.length>0&&a.push({type:"text",text:l.join(`
1228
1228
 
1229
- `)}),a}function Ty(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
1230
- `)}function Md(e,t,n,s){let o=[],i=Ty(t);return o.push(Rt("module-planner",{themeName:e,cssSummary:i})),(!s||s.includes("content"))&&o.push(`
1229
+ `)}),a}function Sb(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
1230
+ `)}function ia(e,t,n,s){let o=[],i=Sb(t);return o.push(Bt("module-planner",{themeName:e,cssSummary:i})),(!s||s.includes("content"))&&o.push(`
1231
1231
 
1232
1232
  ## Content & Copywriting Guide
1233
- ${Ay()}`),n?.brandvoice&&o.push(`
1233
+ ${vb()}`),n?.brandvoice&&o.push(`
1234
1234
 
1235
1235
  ## Brand Voice
1236
1236
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1239,7 +1239,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1239
1239
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1240
1240
 
1241
1241
  ## Anti-AI Copy Rules
1242
- ${_y()}`),o.join("")}function Pd(){let e=ls(),t=Ed(e,"## 4. Color System","## 5."),n=Ed(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1242
+ ${xb()}`),o.join("")}function ou(){let e=gs(),t=su(e,"## 4. Color System","## 5."),n=su(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1243
1243
  Read the user's request carefully. What industry? What audience? What mood?
1244
1244
  Map it to ONE of these aesthetic directions \u2014 then commit fully:
1245
1245
 
@@ -1295,7 +1295,7 @@ Before finalizing, ask yourself:
1295
1295
 
1296
1296
  If any answer is "no," go bolder. The user wants personality, not safety.`),s.join(`
1297
1297
 
1298
- `)}function Ed(e,t,n){let s=e.indexOf(t);if(s===-1)return"";let o=e.indexOf(n,s);return o===-1?e.slice(s):e.slice(s,o).trim()}function Nd(){return`### Design Philosophy
1298
+ `)}function su(e,t,n){let s=e.indexOf(t);if(s===-1)return"";let o=e.indexOf(n,s);return o===-1?e.slice(s):e.slice(s,o).trim()}function iu(){return`### Design Philosophy
1299
1299
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
1300
1300
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
1301
1301
 
@@ -1402,7 +1402,7 @@ Include these in shared CSS:
1402
1402
  | All animations same speed | Stagger with increasing delays |
1403
1403
  | Skip hover/focus states | Every interactive element needs feedback |
1404
1404
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
1405
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function Ay(){return`### Mandatory Page Sections (generate all)
1405
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function vb(){return`### Mandatory Page Sections (generate all)
1406
1406
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
1407
1407
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
1408
1408
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -1490,7 +1490,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
1490
1490
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
1491
1491
  - Keep paragraphs to 2-3 sentences max
1492
1492
  - Aim for 6th-grade reading level
1493
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function _y(){return`### Banned Punctuation
1493
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function xb(){return`### Banned Punctuation
1494
1494
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
1495
1495
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
1496
1496
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -1520,12 +1520,12 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
1520
1520
  - Use plain short words: use > utilize, start > commence, help > facilitate
1521
1521
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
1522
1522
  - Front-load the benefit in the first 5 words
1523
- - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Ur,Id,Rd=N(()=>{"use strict";y();Ke();Es();Ur={type:"object",properties:{cssVariables:{type:"object",description:"CSS custom property name \u2192 value map. Every var() used in sharedCss must be defined here."},sharedCss:{type:"string",description:"Complete shared CSS file. MUST start with :root {} block defining all cssVariables, followed by reset, typography, layout, components, animations, and responsive styles."},sharedJs:{type:"string",description:"Optional shared JS for scroll animations (IntersectionObserver). Wrap in IIFE. Empty string if not needed."},aesthetic:{type:"string",description:"Brief description of the chosen aesthetic direction (e.g., 'dark luxury with warm gold accents')"}},required:["cssVariables","sharedCss","aesthetic"]};Id={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module identifier. If this module already exists in the project, use the existing name verbatim. For new modules, use kebab-case (e.g., 'hero', 'pricing-cards')."},description:{type:"string",description:"What this module does"},contentBrief:{type:"string",description:"Specific content: headlines, body copy, stats, CTAs"},layoutNotes:{type:"string",description:"Visual layout approach referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Module names in page display order"},narrative:{type:"string",description:"Brief description of the page story/flow"}},required:["modules","moduleOrder","narrative"]}});function Gr(e){if(!e)return"";let t=[];return e.colors&&(e.colors.primary&&t.push(`- Primary color: ${e.colors.primary}`),e.colors.secondary&&t.push(`- Secondary color: ${e.colors.secondary}`),e.colors.accent&&t.push(`- Accent color: ${e.colors.accent}`)),e.fonts&&(e.fonts.heading&&t.push(`- Heading font: ${e.fonts.heading}`),e.fonts.body&&t.push(`- Body font: ${e.fonts.body}`)),e.logoUrl&&t.push(`- Logo URL: ${e.logoUrl}`),t.length===0?"":`
1523
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var oa,ra,ru=R(()=>{"use strict";y();Ve();Jt();oa={type:"object",properties:{cssVariables:{type:"object",description:"CSS custom property name \u2192 value map. Every var() used in sharedCss must be defined here."},sharedCss:{type:"string",description:"Complete shared CSS file. MUST start with :root {} block defining all cssVariables, followed by reset, typography, layout, components, animations, and responsive styles."},sharedJs:{type:"string",description:"Optional shared JS for scroll animations (IntersectionObserver). Wrap in IIFE. Empty string if not needed."},aesthetic:{type:"string",description:"Brief description of the chosen aesthetic direction (e.g., 'dark luxury with warm gold accents')"}},required:["cssVariables","sharedCss","aesthetic"]};ra={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module identifier. If this module already exists in the project, use the existing name verbatim. For new modules, use kebab-case (e.g., 'hero', 'pricing-cards')."},description:{type:"string",description:"What this module does"},contentBrief:{type:"string",description:"Specific content: headlines, body copy, stats, CTAs"},layoutNotes:{type:"string",description:"Visual layout approach referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Module names in page display order"},narrative:{type:"string",description:"Brief description of the page story/flow"}},required:["modules","moduleOrder","narrative"]}});function aa(e){if(!e)return"";let t=[];return e.colors&&(e.colors.primary&&t.push(`- Primary color: ${e.colors.primary}`),e.colors.secondary&&t.push(`- Secondary color: ${e.colors.secondary}`),e.colors.accent&&t.push(`- Accent color: ${e.colors.accent}`)),e.fonts&&(e.fonts.heading&&t.push(`- Heading font: ${e.fonts.heading}`),e.fonts.body&&t.push(`- Body font: ${e.fonts.body}`)),e.logoUrl&&t.push(`- Logo URL: ${e.logoUrl}`),t.length===0?"":`
1524
1524
 
1525
1525
  ## Brand Kit \u2014 MANDATORY Design Constraints
1526
1526
  The following brand identity values MUST be used. Do NOT substitute or override them:
1527
1527
  ${t.join(`
1528
- `)}`}function Yo(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1528
+ `)}`}function ci(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1529
1529
 
1530
1530
  Your job: create a complete set of inline-safe design tokens for an email template. Email clients do NOT support CSS custom properties (var()), external stylesheets, flexbox, grid, or JavaScript. All styling must be inline.
1531
1531
 
@@ -1614,25 +1614,25 @@ Do NOT use: system-ui, -apple-system, Segoe UI, Inter, or any Google Fonts.
1614
1614
  - No external font imports`),n.push(`
1615
1615
 
1616
1616
  ## Email Design Guide
1617
- ${Fd()}`),t?.styleguide&&n.push(`
1617
+ ${au()}`),t?.styleguide&&n.push(`
1618
1618
 
1619
1619
  ## Brand Style Guide
1620
1620
  ${t.styleguide}`),t?.themeContext&&n.push(`
1621
1621
 
1622
1622
  ## Product Context
1623
- ${t.themeContext}`);let s=Gr(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
1623
+ ${t.themeContext}`);let s=aa(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
1624
1624
 
1625
1625
  ## No Brand Provided \u2014 Be Creative
1626
- No brand colors or fonts have been set. Invent an original color palette that fits the email's topic and audience. Do NOT fall back to generic grays and blues. Choose web-safe font pairings (heading + body) that match the mood \u2014 vary between serif, sans-serif, and other stacks based on what fits.`),n.join("")}function Wr(e,t){let n=Yo(e),o=n.indexOf(`
1626
+ No brand colors or fonts have been set. Invent an original color palette that fits the email's topic and audience. Do NOT fall back to generic grays and blues. Choose web-safe font pairings (heading + body) that match the mood \u2014 vary between serif, sans-serif, and other stacks based on what fits.`),n.join("")}function la(e,t){let n=ci(e),o=n.indexOf(`
1627
1627
 
1628
1628
  ## Email Design Guide
1629
1629
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Email Design Guide
1630
- ${Fd()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1630
+ ${au()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1631
1631
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1632
- ${t.themeContext}`);let c=Gr(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1632
+ ${t.themeContext}`);let c=aa(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1633
1633
  No brand colors or fonts have been set. Invent an original color palette that fits the email's topic and audience. Do NOT fall back to generic grays and blues. Choose web-safe font pairings (heading + body) that match the mood \u2014 vary between serif, sans-serif, and other stacks based on what fits.`),l.length>0&&a.push({type:"text",text:l.join(`
1634
1634
 
1635
- `)}),a}function Od(e,t,n,s){let o=[],i=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
1635
+ `)}),a}function da(e,t,n,s){let o=[],i=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
1636
1636
  `);o.push(`You are the Email Module Planner for vibeSpot, a HubSpot email template builder.
1637
1637
 
1638
1638
  Your job: plan the modules (sections) for an email template. You define what each section contains and how it should look. You do NOT write module code \u2014 downstream Email Module Developers handle that.
@@ -1691,7 +1691,7 @@ List all module names in display order (top to bottom)
1691
1691
  One sentence describing the email's purpose and flow`),(!s||s.includes("content"))&&o.push(`
1692
1692
 
1693
1693
  ## Email Content Guide
1694
- ${$y()}`),n?.brandvoice&&o.push(`
1694
+ ${wb()}`),n?.brandvoice&&o.push(`
1695
1695
 
1696
1696
  ## Brand Voice
1697
1697
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1700,7 +1700,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1700
1700
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1701
1701
 
1702
1702
  ## Anti-AI Copy Rules
1703
- ${Ey()}`);let r=Gr(n?.brandKit);return r&&o.push(r),o.join("")}function Fd(){return`### Email Design Philosophy
1703
+ ${kb()}`);let r=aa(n?.brandKit);return r&&o.push(r),o.join("")}function au(){return`### Email Design Philosophy
1704
1704
  Design for the inbox, not the browser. Email templates must look clean and professional in Gmail, Outlook, Apple Mail, and Yahoo Mail simultaneously.
1705
1705
 
1706
1706
  ### Color Strategy
@@ -1733,7 +1733,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1733
1733
  - Hero images: 600px wide, 2:1 to 3:1 aspect ratio
1734
1734
  - Always include alt text (images blocked by default in many clients)
1735
1735
  - Use display:block to prevent gaps in Outlook
1736
- - Product images: consistent sizing within a row`}function $y(){return`### Email Types and Structure
1736
+ - Product images: consistent sizing within a row`}function wb(){return`### Email Types and Structure
1737
1737
 
1738
1738
  **Welcome / Onboarding Email**
1739
1739
  - Warm greeting with first-name personalization
@@ -1779,7 +1779,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1779
1779
  - One idea per paragraph, 2-3 sentences max
1780
1780
  - Use "you" more than "we"
1781
1781
  - Specific > vague: "saves 3 hours/week" beats "saves time"
1782
- - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function Ey(){return`### Email-Specific Anti-AI Rules
1782
+ - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function kb(){return`### Email-Specific Anti-AI Rules
1783
1783
  - No em dashes (\u2014) in email copy. Period.
1784
1784
  - No "I hope this email finds you well"
1785
1785
  - No "In today's fast-paced world"
@@ -1788,61 +1788,76 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1788
1788
  - One exclamation mark per email maximum
1789
1789
  - Avoid tricolon structures ("Fast, reliable, secure")
1790
1790
  - Write like a colleague, not a press release
1791
- - Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var Kr,Dd=N(()=>{"use strict";y();Kr={type:"object",properties:{cssVariables:{type:"object",description:"Token name \u2192 literal CSS value map. NOT CSS custom properties. These are reference values for inline styles (e.g., 'bg-color': '#f4f4f4', 'font-body': 'Arial, Helvetica, sans-serif')."},sharedCss:{type:"string",description:"MUST be empty string for email templates. Email uses inline styles only."},sharedJs:{type:"string",description:"MUST be empty string for email templates. No JavaScript in email."},aesthetic:{type:"string",description:"Brief description of the chosen email design direction."}},required:["cssVariables","sharedCss","aesthetic"]}});async function jd(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?Yo(n.themeName,n.brandAssets):zo(n.themeName,n.brandAssets),d=l?a?Wr(n.themeName,n.brandAssets):Hr(n.themeName,n.brandAssets):void 0,u=`## User Request
1791
+ - Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var ca,lu=R(()=>{"use strict";y();ca={type:"object",properties:{cssVariables:{type:"object",description:"Token name \u2192 literal CSS value map. NOT CSS custom properties. These are reference values for inline styles (e.g., 'bg-color': '#f4f4f4', 'font-body': 'Arial, Helvetica, sans-serif')."},sharedCss:{type:"string",description:"MUST be empty string for email templates. Email uses inline styles only."},sharedJs:{type:"string",description:"MUST be empty string for email templates. No JavaScript in email."},aesthetic:{type:"string",description:"Brief description of the chosen email design direction."}},required:["cssVariables","sharedCss","aesthetic"]}});async function js(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?ci(n.themeName,n.brandAssets):li(n.themeName,n.brandAssets),d=l?a?la(n.themeName,n.brandAssets):sa(n.themeName,n.brandAssets):void 0,u=`## User Request
1792
1792
  ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1793
1793
 
1794
1794
  ## Current Shared CSS (update this)
1795
1795
  \`\`\`css
1796
1796
  ${n.sharedCss}
1797
- \`\`\``);let m=Hn(s),g=a?Kr:Ur,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}})),f;h.type!=="structured"?(E.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,E.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1798
- ${Object.entries(S).map(([j,J])=>` ${j.startsWith("--")?j:`--${j}`}: ${J};`).join(`
1797
+ \`\`\``);let m=pn(s),g=a?ca:oa,h=await se("design-system",()=>_e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:pt("design-system")}})),f;h.type!=="structured"?(T.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,T.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1798
+ ${Object.entries(S).map(([L,j])=>` ${L.startsWith("--")?L:`--${L}`}: ${j};`).join(`
1799
1799
  `)}
1800
1800
  }
1801
1801
 
1802
- ${b}`));let v=Object.keys(S||{}).length,w=a?[`Email design tokens: ${f.aesthetic||"created"} | ${v} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${v} variables, ${b.length} chars CSS`];return r({type:"agent_decision",step:"designing",decision:w.join(`
1803
- `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function Ld(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?Yo(n.themeName,n.brandAssets):zo(n.themeName,n.brandAssets),d=l?a?Wr(n.themeName,n.brandAssets):Hr(n.themeName,n.brandAssets):void 0,u=`## User Request
1802
+ ${b}`));let x=Object.keys(S||{}).length,k=a?[`Email design tokens: ${f.aesthetic||"created"} | ${x} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${x} variables, ${b.length} chars CSS`];return r({type:"agent_decision",step:"designing",decision:k.join(`
1803
+ `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function cu(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?ci(n.themeName,n.brandAssets):li(n.themeName,n.brandAssets),d=l?a?la(n.themeName,n.brandAssets):sa(n.themeName,n.brandAssets):void 0,u=`## User Request
1804
1804
  ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1805
1805
 
1806
1806
  ## Current Shared CSS (update this)
1807
1807
  \`\`\`css
1808
1808
  ${n.sharedCss}
1809
- \`\`\``);let m=Hn(s),g=a?Kr:Ur,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}})),f;h.type!=="structured"?(E.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,E.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1810
- ${Object.entries(S).map(([$,F])=>` ${$.startsWith("--")?$:`--${$}`}: ${F};`).join(`
1809
+ \`\`\``);let m=pn(s),g=a?ca:oa,h=await se("design-system",()=>_e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:pt("design-system")}})),f;h.type!=="structured"?(T.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,T.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1810
+ ${Object.entries(S).map(([O,I])=>` ${O.startsWith("--")?O:`--${O}`}: ${I};`).join(`
1811
1811
  `)}
1812
1812
  }
1813
1813
 
1814
- ${b}`));let v=[],w=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,M=[...new Set((e.match(w)||[]).map(T=>T.trim()))];if(M.length>0){let T=M.filter(F=>b.toLowerCase().includes(F.toLowerCase())),$=M.filter(F=>!T.includes(F));$.length>0&&v.push(`Note: ${$.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let j=Object.keys(S||{}).length,J=a?[`Email design tokens: ${f.aesthetic||"created"} | ${j} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${j} variables, ${b.length} chars CSS`,...v];r({type:"agent_decision",step:"designing",decision:J.join(`
1815
- `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let H=a?Od(n.themeName,S||{},n.brandAssets,t.guidesNeeded):Md(n.themeName,b,n.brandAssets,t.guidesNeeded),K=`## User Request
1816
- ${e}`;if(t.newModules.length>0&&(K+=`
1814
+ ${b}`));let x=[],k=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,$=[...new Set((e.match(k)||[]).map(P=>P.trim()))];if($.length>0){let P=$.filter(I=>b.toLowerCase().includes(I.toLowerCase())),O=$.filter(I=>!P.includes(I));O.length>0&&x.push(`Note: ${O.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let L=Object.keys(S||{}).length,j=a?[`Email design tokens: ${f.aesthetic||"created"} | ${L} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${L} variables, ${b.length} chars CSS`,...x];r({type:"agent_decision",step:"designing",decision:j.join(`
1815
+ `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let J=a?da(n.themeName,S||{},n.brandAssets,t.guidesNeeded):ia(n.themeName,b,n.brandAssets,t.guidesNeeded),V=`## User Request
1816
+ ${e}`;if(t.newModules.length>0&&(V+=`
1817
1817
 
1818
1818
  ## Planned Modules
1819
- ${t.newModules.map((T,$)=>`${$+1}. **${T.name}** \u2014 ${T.description}`).join(`
1820
- `)}`),n.modules.length>0){let T=new Set(t.affectedModules),$=n.modules.filter(re=>T.has(re.moduleName)),F=n.modules.filter(re=>!T.has(re.moduleName));$.length>0&&(K+=`
1819
+ ${t.newModules.map((P,O)=>`${O+1}. **${P.name}** \u2014 ${P.description}`).join(`
1820
+ `)}`),n.modules.length>0){let P=new Set(t.affectedModules),O=n.modules.filter(Q=>P.has(Q.moduleName)),I=n.modules.filter(Q=>!P.has(Q.moduleName));O.length>0&&(V+=`
1821
1821
 
1822
1822
  ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1823
1823
  These already exist and are being regenerated. Your output's module names MUST match these exactly \u2014 do NOT rename, retitle-case, or "improve" them. Their content/layout may change; their identifier must not.
1824
- `+$.map(re=>`- \`${re.moduleName}\``).join(`
1825
- `)),F.length>0&&(K+=`
1824
+ `+O.map(Q=>`- \`${Q.moduleName}\``).join(`
1825
+ `)),I.length>0&&(V+=`
1826
1826
 
1827
1827
  ## Existing Modules to Keep (do not re-plan)
1828
1828
  These stay as-is. Do NOT include them in your output. They will appear in the final \`moduleOrder\` (you can reference them by name when you list it).
1829
- `+F.map(re=>`- \`${re.moduleName}\``).join(`
1830
- `))}let X=await te("module-planner",()=>Pe(s,o,i,{systemPrompt:H,messages:[{role:"user",content:K}],structuredOutput:{schema:Id,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{}})),O,k={modules:t.newModules.map(T=>({name:T.name,description:T.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(T=>T.name),narrative:"Page generated from user request"};if(X.type!=="structured")E.warn("page-architect","Module planner: did not get structured output, using fallback"),O=k;else{let T=X.data;Array.isArray(T?.modules)&&T.modules.length>0?(O=T,O.moduleOrder=O.moduleOrder||O.modules.map($=>$.name),O.narrative=O.narrative||"Page generated from user request"):(E.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:T?Object.keys(T):[]}),O=k),E.info("page-architect","Module plan",{moduleCount:O.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${O.narrative} | ${O.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:O.modules,moduleOrder:O.moduleOrder,narrative:O.narrative}}var Jd=N(()=>{"use strict";y();dt();Rd();Dd();le();Be()});function My(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
1831
- `)}function Bd(e,t,n,s,o){let i=My(s),r=t.map(d=>`- **${d.label}** (${d.pageType}, slug: "${d.slug}"): ${d.purpose}`).join(`
1829
+ `+I.map(Q=>`- \`${Q.moduleName}\``).join(`
1830
+ `))}let D=await se("module-planner",()=>_e(s,o,i,{systemPrompt:J,messages:[{role:"user",content:V}],structuredOutput:{schema:ra,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:pt("module-planner")}})),U,C={modules:t.newModules.map(P=>({name:P.name,description:P.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(P=>P.name),narrative:"Page generated from user request"};if(D.type!=="structured")T.warn("page-architect","Module planner: did not get structured output, using fallback"),U=C;else{let P=D.data;Array.isArray(P?.modules)&&P.modules.length>0?(U=P,U.moduleOrder=U.moduleOrder||U.modules.map(O=>O.name),U.narrative=U.narrative||"Page generated from user request"):(T.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:P?Object.keys(P):[]}),U=C),T.info("page-architect","Module plan",{moduleCount:U.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${U.narrative} | ${U.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:U.modules,moduleOrder:U.moduleOrder,narrative:U.narrative}}async function ua(e,t,n,s,o,i,r,a,l){let c=t.contentType==="email",d=s.cssVariables,u=pn(i);l({type:"agent_step",step:"designing",label:"Planning modules..."});let m=c?da(n.themeName,d||{},n.brandAssets,t.guidesNeeded):ia(n.themeName,o,n.brandAssets,t.guidesNeeded),g=`## User Request
1831
+ ${e}`;if(t.newModules.length>0&&(g+=`
1832
+
1833
+ ## Planned Modules
1834
+ ${t.newModules.map((S,x)=>`${x+1}. **${S.name}** \u2014 ${S.description}`).join(`
1835
+ `)}`),n.modules.length>0){let S=new Set(t.affectedModules),x=n.modules.filter($=>S.has($.moduleName)),k=n.modules.filter($=>!S.has($.moduleName));x.length>0&&(g+=`
1836
+
1837
+ ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1838
+ These already exist and are being regenerated. Your output's module names MUST match these exactly \u2014 do NOT rename, retitle-case, or "improve" them. Their content/layout may change; their identifier must not.
1839
+ `+x.map($=>`- \`${$.moduleName}\``).join(`
1840
+ `)),k.length>0&&(g+=`
1841
+
1842
+ ## Existing Modules to Keep (do not re-plan)
1843
+ These stay as-is. Do NOT include them in your output. They will appear in the final \`moduleOrder\` (you can reference them by name when you list it).
1844
+ `+k.map($=>`- \`${$.moduleName}\``).join(`
1845
+ `))}let h=await se("module-planner",()=>_e(i,r,a,{systemPrompt:m,messages:[{role:"user",content:g}],structuredOutput:{schema:ra,name:"module_plan"},maxTokens:8e3,...u>0?{thinkingBudgetTokens:u}:{},...c?{}:{prompt:pt("module-planner")}})),f,b={modules:t.newModules.map(S=>({name:S.name,description:S.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(S=>S.name),narrative:"Page generated from user request"};if(h.type!=="structured")T.warn("page-architect","Module planner: did not get structured output, using fallback"),f=b;else{let S=h.data;Array.isArray(S?.modules)&&S.modules.length>0?(f=S,f.moduleOrder=f.moduleOrder||f.modules.map(x=>x.name),f.narrative=f.narrative||"Page generated from user request"):(T.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:S?Object.keys(S):[]}),f=b),T.info("page-architect","Module plan",{moduleCount:f.modules.length})}return l({type:"agent_decision",step:"designing",decision:`Page: ${f.narrative} | ${f.modules.length} modules planned`}),{designSystem:{cssVariables:s.cssVariables||{},sharedCss:o,sharedJs:s.sharedJs},modules:f.modules,moduleOrder:f.moduleOrder,narrative:f.narrative}}var du=R(()=>{"use strict";y();mt();ru();lu();Jt();de();He()});function Cb(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
1846
+ `)}function uu(e,t,n,s,o){let i=Cb(s),r=t.map(d=>`- **${d.label}** (${d.pageType}, slug: "${d.slug}"): ${d.purpose}`).join(`
1832
1847
  `),a=n.map(d=>`- **${d}**`).join(`
1833
1848
  `),l=[],c=t.map(d=>` - "${d.label}" \u2192 href="/${d.slug}"`).join(`
1834
- `);return l.push(Rt("site-module-planner",{themeName:e,siteMap:r,sharedList:a,cssSummary:i,navHrefs:c,sharedModuleNamesCsv:n.join(", ")})),o?.brandvoice&&l.push(`
1849
+ `);return l.push(Bt("site-module-planner",{themeName:e,siteMap:r,sharedList:a,cssSummary:i,navHrefs:c,sharedModuleNamesCsv:n.join(", ")})),o?.brandvoice&&l.push(`
1835
1850
 
1836
1851
  ## Brand Voice
1837
1852
  ${o.brandvoice}`),o?.themeContext&&l.push(`
1838
1853
 
1839
1854
  ## Product Context
1840
- ${o.themeContext}`),l.join("")}var Hd,Ud=N(()=>{"use strict";y();Es();Hd={type:"object",properties:{sharedModules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Shared module identifier (e.g., site-header, site-footer)"},description:{type:"string"},contentBrief:{type:"string",description:"Content for this shared module"},layoutNotes:{type:"string",description:"Layout referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]},description:"Modules shared across all pages (header, footer)"},pages:{type:"array",items:{type:"object",properties:{pageId:{type:"string",description:"Matches the page ID from the site map"},modules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},contentBrief:{type:"string"},layoutNotes:{type:"string"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Per-page module names in display order (excluding shared modules)"}},required:["pageId","modules","moduleOrder"]}},narrative:{type:"string",description:"Brief description of the overall site story and how pages connect"}},required:["sharedModules","pages","narrative"]}});async function Wd(e,t,n,s,o,i,r,a){a({type:"agent_step",step:"planning_site",label:`Planning modules for ${t.pages?.length||0} pages...`});let l=t.pages||[],c=t.sharedModules||["site-header","site-footer"],d=Bd(n.themeName,l,c,s,n.brandAssets),u=`## User Request
1855
+ ${o.themeContext}`),l.join("")}var mu,pu=R(()=>{"use strict";y();Jt();mu={type:"object",properties:{sharedModules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Shared module identifier (e.g., site-header, site-footer)"},description:{type:"string"},contentBrief:{type:"string",description:"Content for this shared module"},layoutNotes:{type:"string",description:"Layout referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]},description:"Modules shared across all pages (header, footer)"},pages:{type:"array",items:{type:"object",properties:{pageId:{type:"string",description:"Matches the page ID from the site map"},modules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},contentBrief:{type:"string"},layoutNotes:{type:"string"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Per-page module names in display order (excluding shared modules)"}},required:["pageId","modules","moduleOrder"]}},narrative:{type:"string",description:"Brief description of the overall site story and how pages connect"}},required:["sharedModules","pages","narrative"]}});async function fu(e,t,n,s,o,i,r,a){a({type:"agent_step",step:"planning_site",label:`Planning modules for ${t.pages?.length||0} pages...`});let l=t.pages||[],c=t.sharedModules||["site-header","site-footer"],d=uu(n.themeName,l,c,s,n.brandAssets),u=`## User Request
1841
1856
  ${e}
1842
1857
 
1843
1858
  ## Site Map
1844
- ${l.map(v=>`- ${v.label} (${v.slug}): ${v.purpose}`).join(`
1845
- `)}`,m=Hn(o),g=await te("site-module-planner",()=>Pe(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:Hd,name:"site_module_plan"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}}));if(g.type!=="structured")return E.warn("site-planner","Did not get structured output, building fallback"),Gd(t,c,s);let h=g.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return E.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),Gd(t,c,s);let f=h.sharedModules.map(v=>({name:v.name,description:v.description,contentBrief:v.contentBrief,layoutNotes:v.layoutNotes})),b=h.pages.map(v=>({pageId:v.pageId,modules:(v.modules||[]).map(w=>({name:w.name,description:w.description,contentBrief:w.contentBrief,layoutNotes:w.layoutNotes})),moduleOrder:v.moduleOrder||[]})),S=f.length+b.reduce((v,w)=>v+w.modules.length,0);return E.info("site-planner","Site plan complete",{pages:b.length,sharedModules:f.length,totalModules:S}),a({type:"agent_decision",step:"planning_site",decision:`${b.length} pages planned, ${f.length} shared modules, ${S} total modules`}),a({type:"site_blueprint_ready",pages:b.map(v=>{let w=l.find(M=>M.id===v.pageId);return{pageId:v.pageId,label:w?.label||v.pageId,moduleCount:v.modules.length}}),sharedModuleCount:f.length}),{designSystem:{cssVariables:{},sharedCss:s},pages:b,sharedModules:f,narrative:h.narrative||"Multi-page site generated from user request"}}function Gd(e,t,n){let s=e.pages||[];return{designSystem:{cssVariables:{},sharedCss:n},pages:s.map(o=>({pageId:o.id,modules:[{name:`${o.slug}-hero`,description:`Hero section for ${o.label}`,contentBrief:`Create a hero for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"},{name:`${o.slug}-content`,description:`Main content for ${o.label}`,contentBrief:`Create main content for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"}],moduleOrder:[`${o.slug}-hero`,`${o.slug}-content`]})),sharedModules:t.map(o=>({name:o,description:`Shared ${o} module`,contentBrief:`Generate ${o} for the site`,layoutNotes:"Use responsive layout matching the design system"})),narrative:"Multi-page site (fallback plan)"}}var Kd=N(()=>{"use strict";y();dt();Ud();le();Be()});function qo(e){let t=0,n=[];return async function(o){t>=e&&await new Promise(i=>n.push(i)),t++;try{return await o()}finally{t--,n.length>0&&n.shift()()}}}var Vr=N(()=>{"use strict";y()});function Ms(e,t,n,s){let o=[];return o.push(Rt("module-developer",{themeName:e})),t&&o.push(`
1859
+ ${l.map(x=>`- ${x.label} (${x.slug}): ${x.purpose}`).join(`
1860
+ `)}`,m=pn(o),g=await se("site-module-planner",()=>_e(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:mu,name:"site_module_plan"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},prompt:pt("site-module-planner")}));if(g.type!=="structured")return T.warn("site-planner","Did not get structured output, building fallback"),gu(t,c,s);let h=g.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return T.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),gu(t,c,s);let f=h.sharedModules.map(x=>({name:x.name,description:x.description,contentBrief:x.contentBrief,layoutNotes:x.layoutNotes})),b=h.pages.map(x=>({pageId:x.pageId,modules:(x.modules||[]).map(k=>({name:k.name,description:k.description,contentBrief:k.contentBrief,layoutNotes:k.layoutNotes})),moduleOrder:x.moduleOrder||[]})),S=f.length+b.reduce((x,k)=>x+k.modules.length,0);return T.info("site-planner","Site plan complete",{pages:b.length,sharedModules:f.length,totalModules:S}),a({type:"agent_decision",step:"planning_site",decision:`${b.length} pages planned, ${f.length} shared modules, ${S} total modules`}),a({type:"site_blueprint_ready",pages:b.map(x=>{let k=l.find($=>$.id===x.pageId);return{pageId:x.pageId,label:k?.label||x.pageId,moduleCount:x.modules.length}}),sharedModuleCount:f.length}),{designSystem:{cssVariables:{},sharedCss:s},pages:b,sharedModules:f,narrative:h.narrative||"Multi-page site generated from user request"}}function gu(e,t,n){let s=e.pages||[];return{designSystem:{cssVariables:{},sharedCss:n},pages:s.map(o=>({pageId:o.id,modules:[{name:`${o.slug}-hero`,description:`Hero section for ${o.label}`,contentBrief:`Create a hero for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"},{name:`${o.slug}-content`,description:`Main content for ${o.label}`,contentBrief:`Create main content for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"}],moduleOrder:[`${o.slug}-hero`,`${o.slug}-content`]})),sharedModules:t.map(o=>({name:o,description:`Shared ${o} module`,contentBrief:`Generate ${o} for the site`,layoutNotes:"Use responsive layout matching the design system"})),narrative:"Multi-page site (fallback plan)"}}var hu=R(()=>{"use strict";y();mt();pu();Jt();de();He()});function Ls(e,t,n,s){let o=[];return o.push(Bt("module-developer",{themeName:e})),t&&o.push(`
1846
1861
 
1847
1862
  ## Theme Shared CSS (use these custom properties)
1848
1863
  \`\`\`css
@@ -1853,26 +1868,26 @@ ${t}
1853
1868
  ${Je()}`),(!n||n.includes("conversion"))&&o.push(`
1854
1869
 
1855
1870
  ## Conversion Guide
1856
- ${ye()}`),s?.themeContext&&o.push(`
1871
+ ${be()}`),s?.themeContext&&o.push(`
1857
1872
 
1858
1873
  ## Product Context
1859
1874
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1860
1875
 
1861
1876
  ## Anti-AI Copy Rules
1862
- ${Vd()}`),o.join("")}function Xo(e,t,n,s){let o=[],i=Ms(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1877
+ ${yu()}`),o.join("")}function di(e,t,n,s){let o=[],i=Ls(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1863
1878
 
1864
1879
  ## Theme Shared CSS (use these custom properties)
1865
1880
  \`\`\`css
1866
1881
  ${t}
1867
1882
  \`\`\``),o.push({type:"text",text:i});let r=[];(!n||n.includes("hubspot_rules"))&&r.push(`## HubSpot CMS Rules
1868
1883
  ${Je()}`),(!n||n.includes("conversion"))&&r.push(`## Conversion Guide
1869
- ${ye()}`),r.length>0&&o.push({type:"text",text:r.join(`
1884
+ ${be()}`),r.length>0&&o.push({type:"text",text:r.join(`
1870
1885
 
1871
1886
  `),cache_control:{type:"ephemeral"}});let a=[];return s?.themeContext&&a.push(`## Product Context
1872
1887
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&a.push(`## Anti-AI Copy Rules
1873
- ${Vd()}`),a.length>0&&o.push({type:"text",text:a.join(`
1888
+ ${yu()}`),a.length>0&&o.push({type:"text",text:a.join(`
1874
1889
 
1875
- `)}),o}function Vd(){return`### Banned Punctuation
1890
+ `)}),o}function yu(){return`### Banned Punctuation
1876
1891
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1877
1892
  - **Semicolons**: Use periods instead in marketing copy.
1878
1893
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1911,7 +1926,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1911
1926
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1912
1927
  - Full names, specific roles (not "John D., CEO")
1913
1928
  - Never start with "This product is..." \u2014 start with the person's situation
1914
- - Vary length and voice across testimonials`}function zd(e,t,n){let s=[];return s.push(`## User Request
1929
+ - Vary length and voice across testimonials`}function bu(e,t,n){let s=[];return s.push(`## User Request
1915
1930
  ${e}`),s.push(`
1916
1931
 
1917
1932
  ## Module Specification
@@ -1938,7 +1953,7 @@ ${n.moduleCss}
1938
1953
  **module.js:**
1939
1954
  \`\`\`js
1940
1955
  ${n.moduleJs}
1941
- \`\`\``)),s.join("")}var Is,zr=N(()=>{"use strict";y();Ke();Es();Is={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});function Yr(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1956
+ \`\`\``)),s.join("")}var Bs,ma=R(()=>{"use strict";y();Ve();Jt();Bs={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});function pa(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1942
1957
 
1943
1958
  Your job: generate ONE HubSpot CMS email module. You receive a module specification and must produce the complete module code optimized for email client rendering.
1944
1959
 
@@ -2096,17 +2111,17 @@ Modules that serve as email footers MUST include:
2096
2111
  ${t.themeContext}`),t?.humanify!==!1&&n.push(`
2097
2112
 
2098
2113
  ## Anti-AI Copy Rules
2099
- ${qd()}`),t?.brandKit){let s=[];t.brandKit.colors&&(t.brandKit.colors.primary&&s.push(`- Primary color: ${t.brandKit.colors.primary}`),t.brandKit.colors.secondary&&s.push(`- Secondary color: ${t.brandKit.colors.secondary}`),t.brandKit.colors.accent&&s.push(`- Accent color: ${t.brandKit.colors.accent}`)),t.brandKit.fonts&&(t.brandKit.fonts.heading&&s.push(`- Heading font: ${t.brandKit.fonts.heading}`),t.brandKit.fonts.body&&s.push(`- Body font: ${t.brandKit.fonts.body}`)),t.brandKit.logoUrl&&s.push(`- Logo URL: ${t.brandKit.logoUrl}`),s.length>0&&n.push(`
2114
+ ${vu()}`),t?.brandKit){let s=[];t.brandKit.colors&&(t.brandKit.colors.primary&&s.push(`- Primary color: ${t.brandKit.colors.primary}`),t.brandKit.colors.secondary&&s.push(`- Secondary color: ${t.brandKit.colors.secondary}`),t.brandKit.colors.accent&&s.push(`- Accent color: ${t.brandKit.colors.accent}`)),t.brandKit.fonts&&(t.brandKit.fonts.heading&&s.push(`- Heading font: ${t.brandKit.fonts.heading}`),t.brandKit.fonts.body&&s.push(`- Body font: ${t.brandKit.fonts.body}`)),t.brandKit.logoUrl&&s.push(`- Logo URL: ${t.brandKit.logoUrl}`),s.length>0&&n.push(`
2100
2115
 
2101
2116
  ## Brand Kit \u2014 MANDATORY Design Constraints
2102
2117
  The following brand identity values MUST be used. Do NOT substitute or override them:
2103
2118
  ${s.join(`
2104
- `)}`)}return n.join("")}function Yd(e,t){let n=[],s=Yr(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=bl()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2119
+ `)}`)}return n.join("")}function Su(e,t){let n=[],s=pa(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=Ul()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2105
2120
  ${o}`,cache_control:{type:"ephemeral"}});let i=[];return t?.themeContext&&i.push(`## Product Context
2106
2121
  ${t.themeContext}`),t?.humanify!==!1&&i.push(`## Anti-AI Copy Rules
2107
- ${qd()}`),i.length>0&&n.push({type:"text",text:i.join(`
2122
+ ${vu()}`),i.length>0&&n.push({type:"text",text:i.join(`
2108
2123
 
2109
- `)}),n}function qd(){return`### Banned Punctuation
2124
+ `)}),n}function vu(){return`### Banned Punctuation
2110
2125
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2111
2126
  - **Semicolons**: Use periods instead.
2112
2127
  - **Exclamation marks**: One per email max. Zero ideal for B2B.
@@ -2125,7 +2140,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2125
2140
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2126
2141
  - Use plain words: use > utilize, start > commence, help > facilitate
2127
2142
  - Front-load the benefit in the first 5 words
2128
- - Email subject lines: specific, benefit-first, under 50 chars`}function Xd(e,t,n){let s=[];return s.push(`## User Request
2143
+ - Email subject lines: specific, benefit-first, under 50 chars`}function xu(e,t,n){let s=[];return s.push(`## User Request
2129
2144
  ${e}`),s.push(`
2130
2145
 
2131
2146
  ## Email Module Specification
@@ -2145,7 +2160,7 @@ ${n.fieldsJson}
2145
2160
  **module.html:**
2146
2161
  \`\`\`html
2147
2162
  ${n.moduleHtml}
2148
- \`\`\``),s.join("")}var Zd,Qd=N(()=>{"use strict";y();Ke();Zd={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types: ["EMAIL"]'},moduleHtml:{type:"string",description:"Complete module.html with TABLE-BASED layout and ALL CSS inline. No <style> blocks."},moduleCss:{type:"string",description:"Must be empty string \u2014 all CSS is inline in moduleHtml for email"},moduleJs:{type:"string",description:"Must be empty string \u2014 no JavaScript in email"}},required:["moduleName","fieldsJson","metaJson","moduleHtml"]}});function qr(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
2163
+ \`\`\``),s.join("")}var wu,ku=R(()=>{"use strict";y();Ve();wu={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types: ["EMAIL"]'},moduleHtml:{type:"string",description:"Complete module.html with TABLE-BASED layout and ALL CSS inline. No <style> blocks."},moduleCss:{type:"string",description:"Must be empty string \u2014 all CSS is inline in moduleHtml for email"},moduleJs:{type:"string",description:"Must be empty string \u2014 no JavaScript in email"}},required:["moduleName","fieldsJson","metaJson","moduleHtml"]}});function ga(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
2149
2164
 
2150
2165
  Your job: generate ONE HubSpot CMS blog module. You receive a module specification and must produce the complete module code optimized for blog templates.
2151
2166
 
@@ -2330,22 +2345,22 @@ The blog post body module wraps \`{{ content.post_body }}\` with reading-optimiz
2330
2345
  ${s.themeContext}`),s?.humanify!==!1&&o.push(`
2331
2346
 
2332
2347
  ## Anti-AI Copy Rules
2333
- ${tu()}`);let i=[];if(n?.includes("conversion"))try{let r=ye();r&&i.push(`## Conversion Guide
2348
+ ${Tu()}`);let i=[];if(n?.includes("conversion"))try{let r=be();r&&i.push(`## Conversion Guide
2334
2349
  ${r}`)}catch{}if(n?.includes("hubspot_rules"))try{let r=Je();r&&i.push(`## HubSpot Rules
2335
2350
  ${r}`)}catch{}return i.length>0&&o.push(`
2336
2351
 
2337
2352
  ${i.join(`
2338
2353
 
2339
- `)}`),o.join("")}function eu(e,t,n,s){let o=[],i=qr(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=Sl()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2340
- ${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=ye();c&&a.push(`## Conversion Guide
2354
+ `)}`),o.join("")}function Cu(e,t,n,s){let o=[],i=ga(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=Gl()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2355
+ ${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=be();c&&a.push(`## Conversion Guide
2341
2356
  ${c}`)}catch{}if(n?.includes("hubspot_rules"))try{let c=Je();c&&a.push(`## HubSpot Rules
2342
2357
  ${c}`)}catch{}a.length>0&&o.push({type:"text",text:a.join(`
2343
2358
 
2344
2359
  `),cache_control:{type:"ephemeral"}});let l=[];return s?.themeContext&&l.push(`## Product Context
2345
2360
  ${s.themeContext}`),s?.humanify!==!1&&l.push(`## Anti-AI Copy Rules
2346
- ${tu()}`),l.length>0&&o.push({type:"text",text:l.join(`
2361
+ ${Tu()}`),l.length>0&&o.push({type:"text",text:l.join(`
2347
2362
 
2348
- `)}),o}function tu(){return`### Banned Punctuation
2363
+ `)}),o}function Tu(){return`### Banned Punctuation
2349
2364
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2350
2365
  - **Semicolons**: Use periods instead.
2351
2366
  - **Exclamation marks**: Maximum one per page. Zero ideal for B2B.
@@ -2364,7 +2379,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2364
2379
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2365
2380
  - Use plain words: use > utilize, start > commence, help > facilitate
2366
2381
  - Front-load the benefit in the first 5 words
2367
- - Blog headlines: specific, benefit-first, no clickbait`}function nu(e,t,n){let s=[];return s.push(`## User Request
2382
+ - Blog headlines: specific, benefit-first, no clickbait`}function Au(e,t,n){let s=[];return s.push(`## User Request
2368
2383
  ${e}`),s.push(`
2369
2384
 
2370
2385
  ## Blog Module Specification
@@ -2389,17 +2404,66 @@ ${n.moduleHtml}
2389
2404
  **module.css:**
2390
2405
  \`\`\`css
2391
2406
  ${n.moduleCss}
2392
- \`\`\``),s.join("")}var su,ou=N(()=>{"use strict";y();Ke();Ke();su={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types with "BLOG_POST" and/or "BLOG_LISTING"'},moduleHtml:{type:"string",description:"Complete module.html using HubSpot blog variables where appropriate"},moduleCss:{type:"string",description:"Complete module.css with reading-optimized styles"},moduleJs:{type:"string",description:"Optional module.js (vanilla JS in IIFE) or empty string"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function Ps(e,t,n,s,o,i,r,a,l,c,d,u){let m=u==="email",g=u==="blog",h=m?"email module":g?"blog module":"module";l({type:"agent_step",step:"developing",label:`Generating ${t.length} ${h}${t.length===1?"":"s"}...`});let f=o==="anthropic-api"||o==="claude-oauth",b=m?Yr(s,d):g?qr(s,n,c,d):Ms(s,n,c,d),S=f?m?Yd(s,d):g?eu(s,n,c,d):Xo(s,n,c,d):void 0,v=qo(a),w=t.length,M=m?Zd:g?su:Is,j=t.map((H,K)=>v(async()=>{l({type:"module_progress",module:H.name,status:"generating",current:K+1,total:w});let X="";for(let O=0;O<2;O++)try{O>0&&(E.warn("module-developer",`${H.name}: retrying after failure (attempt ${O+1})`),l({type:"module_progress",module:H.name,status:"retrying",current:K+1,total:w}));let k=await iu(e,H,b,o,i,r,0,S,m,M,g);return l({type:"module_progress",module:H.name,status:"complete",current:K+1,total:w,moduleFiles:k}),{moduleName:H.name,module:k}}catch(k){X=k instanceof Error?k.message:typeof k=="object"&&k!==null?JSON.stringify(k):String(k),E.error("module-developer",`Failed: ${H.name} (attempt ${O+1})`,{error:X})}return l({type:"module_progress",module:H.name,status:"failed",current:K+1,total:w}),{moduleName:H.name,error:X}}));return(await Promise.allSettled(j)).map(H=>H.status==="fulfilled"?H.value:{moduleName:"unknown",error:H.reason instanceof Error?H.reason.message:String(H.reason)})}async function iu(e,t,n,s,o,i,r=0,a,l=!1,c=Is,d=!1){let u=l?Xd(e,t,t.existingCode):d?nu(e,t,t.existingCode):zd(e,t,t.existingCode),m=await Pe(s,o,i,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:u}],structuredOutput:{schema:c,name:"module_output"},maxTokens:16e3});if(m.type!=="structured"){if(r<2)return E.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),iu(e,t,n,s,o,i,r+1,a,l,c,d);throw new Error(`Module "${t.name}" failed to produce structured output after ${r+1} attempts`)}let g=m.data,h=typeof g.fieldsJson=="string"?g.fieldsJson:JSON.stringify(g.fieldsJson,null,2),f=typeof g.metaJson=="string"?g.metaJson:JSON.stringify(g.metaJson,null,2);return{moduleName:t.name,fieldsJson:h,metaJson:f,moduleHtml:String(g.moduleHtml||""),moduleCss:l?"":String(g.moduleCss||""),moduleJs:l?void 0:g.moduleJs?String(g.moduleJs):void 0}}var ru=N(()=>{"use strict";y();dt();Vr();zr();Qd();ou();le()});function ln(e,t,n,s,o){let i=s==="email",r=s==="blog";return n({type:"agent_step",step:"quality_check",label:i?"Email quality check...":r?"Blog quality check...":"Quality check..."}),e.map(a=>{let l=[],c={...a};c.fieldsJson=au(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=au(c.metaJson,c.moduleName,"metaJson",l,i,r);let d={};c.fieldsJson=Py(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=Ny(c.moduleHtml,d),c.fieldsJson=Ry(c.fieldsJson,c.moduleName,l),i?c=Wy(c,l):(c.moduleCss=Oy(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=Dy(c.moduleCss,c.moduleName,t,l),c.moduleHtml=jy(c.moduleHtml,c.moduleName,t,l),r&&(c=Ky(c,l))),c.moduleHtml=Jy(c.moduleHtml,c.moduleName,l),i||By(c,l),c.metaJson=Hy(c.metaJson,c.moduleName,l,i,r),o&&Gy(c,o,l);let u=l.every(m=>m.autoFixed);return l.length>0&&E.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(m=>m.autoFixed).length,unfixed:l.filter(m=>!m.autoFixed).length}),{module:c,issues:l,valid:u}})}function au(e,t,n,s,o=!1,i=!1){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0}):e):ct(e)===null?(s.push({module:t,field:n,message:`Invalid JSON in ${n} \u2014 reset to empty`,autoFixed:!0}),n==="fieldsJson"?"[]":JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0})):e}function Py(e,t,n,s){let o=e;for(let[i,r]of Iy)new RegExp(`"name"\\s*:\\s*"${i}"`,"g").test(o)&&(n.push({module:t,field:"fieldsJson",message:`"${i}" is a reserved field name \u2192 renamed to "${r}"`,autoFixed:!0}),o=o.replace(new RegExp(`"name"\\s*:\\s*"${i}"`,"g"),`"name": "${r}"`),s[i]=r);return o}function Ny(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`module\\.${s}\\b`,"g"),`module.${o}`);return n}function Ry(e,t,n){let s=e;return/"type"\s*:\s*"textarea"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"textarea" is deprecated \u2192 changed to "text"',autoFixed:!0}),s=s.replace(/"type"\s*:\s*"textarea"/g,'"type": "text"')),s}function Oy(e,t,n,s){if(!e)return e;let o=e,i=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return i.test(o)&&(s.push({module:t,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(i,"/* CDN import removed */")),o}function cu(e){return Fy.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Dy(e,t,n,s){if(!e)return e;let o=n+"-",i=/\.([a-zA-Z][\w-]*)/g,r=new Set,a;for(;(a=i.exec(e))!==null;){let c=a[1];!c.startsWith(o)&&!cu(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${Ly(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==e&&s.push({module:t,field:"moduleCss",message:`${r.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function jy(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,r=!1,a=e.replace(i,(l,c)=>{let d=/(\{%[-~]?[\s\S]*?[-~]?%\}|\{\{[\s\S]*?\}\})/g,u=c.split(d),m=!1,g=u.map((h,f)=>f%2===1?h:h.split(/(\s+)/).map(b=>/^\s*$/.test(b)?b:b&&!b.startsWith(o)&&!cu(b)&&/^[a-zA-Z][\w-]*$/.test(b)?(m=!0,o+b):b).join("")).join("");return m?(r=!0,`class="${g}"`):l});return r&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),a}function Ly(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Jy(e,t,n){if(!e)return e;let s=e,i=["if","elif","else","endif","for","endfor","set","do","block","endblock","macro","endmacro","call","endcall","filter","endfilter","raw","endraw","include","import","from","extends","print","unless","endunless","is","not","and","or","in"].join("|"),r=new RegExp(`\\b[a-zA-Z][\\w-]*-(${i})\\b(?!-)`,"g"),a=/(\{%[-~]?[\s\S]*?[-~]?%\})/g,l=!1;s=s.replace(a,h=>h.replace(r,(b,S)=>(l=!0,S))),l&&n.push({module:t,field:"moduleHtml",message:"Stripped CSS-class prefix from HubL keywords inside {% %} tags",autoFixed:!0});let c=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,d=[],u;for(;(u=c.exec(s))!==null;){let h=u[1],f=!h.startsWith("end"),b=f?h:h.replace("end","");d.push({tag:h,isOpen:f,baseTag:b,start:u.index,end:u.index+u[0].length})}let m=[],g=[];for(let h=0;h<d.length;h++)if(d[h].isOpen)m.push(h);else{let f=-1;for(let b=m.length-1;b>=0;b--)if(d[m[b]].baseTag===d[h].baseTag){f=b;break}f!==-1?m.splice(f,1):g.push(h)}if(g.length>0){for(let h=g.length-1;h>=0;h--){let f=d[g[h]];s=s.slice(0,f.start)+`<!-- removed orphan {% ${f.tag} %} -->`+s.slice(f.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${g.length} orphan closing tag${g.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(m.length>0){let h=m.map(b=>d[b].baseTag),f=h.reverse().map(b=>`{% end${b} %}`).join(`
2407
+ \`\`\``),s.join("")}var _u,$u=R(()=>{"use strict";y();Ve();Ve();_u={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types with "BLOG_POST" and/or "BLOG_LISTING"'},moduleHtml:{type:"string",description:"Complete module.html using HubSpot blog variables where appropriate"},moduleCss:{type:"string",description:"Complete module.css with reading-optimized styles"},moduleJs:{type:"string",description:"Optional module.js (vanilla JS in IIFE) or empty string"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function Js(e,t,n,s,o,i,r,a,l,c,d,u,m){let g=u==="email",h=u==="blog",f=g?"email module":h?"blog module":"module";l({type:"agent_step",step:"developing",label:`Generating ${t.length} ${f}${t.length===1?"":"s"}...`});let b=o==="anthropic-api"||o==="claude-oauth",S=g?pa(s,d):h?ga(s,n,c,d):Ls(s,n,c,d),x=b?g?Su(s,d):h?Cu(s,n,c,d):di(s,n,c,d):void 0,k=ri(a,m),$=t.length,L=g?wu:h?_u:Bs,j=g||h?void 0:pt("module-developer"),J=t.map((D,U)=>k(async()=>{l({type:"module_progress",module:D.name,status:"generating",current:U+1,total:$});let C="";for(let P=0;P<2;P++){if(m?.aborted)throw new Re;try{P>0&&(T.warn("module-developer",`${D.name}: retrying after failure (attempt ${P+1})`),l({type:"module_progress",module:D.name,status:"retrying",current:U+1,total:$}));let O=await Pu(e,D,S,o,i,r,0,x,g,L,h,j,m);return l({type:"module_progress",module:D.name,status:"complete",current:U+1,total:$,moduleFiles:O}),{moduleName:D.name,module:O}}catch(O){if(Rs(O))throw O instanceof Re?O:new Re;C=O instanceof Error?O.message:typeof O=="object"&&O!==null?JSON.stringify(O):String(O),T.error("module-developer",`Failed: ${D.name} (attempt ${P+1})`,{error:C})}}return l({type:"module_progress",module:D.name,status:"failed",current:U+1,total:$}),{moduleName:D.name,error:C}})),V=await Promise.allSettled(J);if(m?.aborted)throw new Re;return V.map(D=>D.status==="fulfilled"?D.value:{moduleName:"unknown",error:D.reason instanceof Error?D.reason.message:String(D.reason)})}async function Pu(e,t,n,s,o,i,r=0,a,l=!1,c=Bs,d=!1,u,m){let g=l?xu(e,t,t.existingCode):d?Au(e,t,t.existingCode):bu(e,t,t.existingCode),h=await _e(s,o,i,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:g}],structuredOutput:{schema:c,name:"module_output"},maxTokens:16e3,...u?{prompt:u}:{},signal:m});if(h.type!=="structured"){if(r<2)return T.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),Pu(e,t,n,s,o,i,r+1,a,l,c,d,u,m);throw new Error(`Module "${t.name}" failed to produce structured output after ${r+1} attempts`)}let f=h.data,b=typeof f.fieldsJson=="string"?f.fieldsJson:JSON.stringify(f.fieldsJson,null,2),S=typeof f.metaJson=="string"?f.metaJson:JSON.stringify(f.metaJson,null,2);return{moduleName:t.name,fieldsJson:b,metaJson:S,moduleHtml:String(f.moduleHtml||""),moduleCss:l?"":String(f.moduleCss||""),moduleJs:l?void 0:f.moduleJs?String(f.moduleJs):void 0}}var Eu=R(()=>{"use strict";y();mt();zn();ma();ku();$u();Jt();de()});function gn(e,t,n,s,o){let i=s==="email",r=s==="blog";return n({type:"agent_step",step:"quality_check",label:i?"Email quality check...":r?"Blog quality check...":"Quality check..."}),e.map(a=>{let l=[],c={...a};c.fieldsJson=Mu(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=Mu(c.metaJson,c.moduleName,"metaJson",l,i,r);let d={};c.fieldsJson=Ab(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=_b(c.moduleHtml,d),c.fieldsJson=$b(c.fieldsJson,c.moduleName,l),i?c=Lb(c,l):(c.moduleCss=Pb(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=Mb(c.moduleCss,c.moduleName,t,l),c.moduleHtml=Ib(c.moduleHtml,c.moduleName,t,l),r&&(c=Bb(c,l))),c.moduleHtml=Nb(c.moduleHtml,c.moduleName,l),i||Ob(c,l),c.metaJson=Fb(c.metaJson,c.moduleName,l,i,r),o&&jb(c,o,l);let u=l.every(m=>m.autoFixed);return l.length>0&&T.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(m=>m.autoFixed).length,unfixed:l.filter(m=>!m.autoFixed).length}),{module:c,issues:l,valid:u}})}function Mu(e,t,n,s,o=!1,i=!1){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0}):e):ut(e)===null?(s.push({module:t,field:n,message:`Invalid JSON in ${n} \u2014 reset to empty`,autoFixed:!0}),n==="fieldsJson"?"[]":JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0})):e}function Ab(e,t,n,s){let o=e;for(let[i,r]of Tb)new RegExp(`"name"\\s*:\\s*"${i}"`,"g").test(o)&&(n.push({module:t,field:"fieldsJson",message:`"${i}" is a reserved field name \u2192 renamed to "${r}"`,autoFixed:!0}),o=o.replace(new RegExp(`"name"\\s*:\\s*"${i}"`,"g"),`"name": "${r}"`),s[i]=r);return o}function _b(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`module\\.${s}\\b`,"g"),`module.${o}`);return n}function $b(e,t,n){let s=e;return/"type"\s*:\s*"textarea"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"textarea" is deprecated \u2192 changed to "text"',autoFixed:!0}),s=s.replace(/"type"\s*:\s*"textarea"/g,'"type": "text"')),s}function Pb(e,t,n,s){if(!e)return e;let o=e,i=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return i.test(o)&&(s.push({module:t,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(i,"/* CDN import removed */")),o}function Ru(e){return Eb.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Mb(e,t,n,s){if(!e)return e;let o=n+"-",i=/\.([a-zA-Z][\w-]*)/g,r=new Set,a;for(;(a=i.exec(e))!==null;){let c=a[1];!c.startsWith(o)&&!Ru(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${Rb(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==e&&s.push({module:t,field:"moduleCss",message:`${r.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function Ib(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,r=!1,a=e.replace(i,(l,c)=>{let d=/(\{%[-~]?[\s\S]*?[-~]?%\}|\{\{[\s\S]*?\}\})/g,u=c.split(d),m=!1,g=u.map((h,f)=>f%2===1?h:h.split(/(\s+)/).map(b=>/^\s*$/.test(b)?b:b&&!b.startsWith(o)&&!Ru(b)&&/^[a-zA-Z][\w-]*$/.test(b)?(m=!0,o+b):b).join("")).join("");return m?(r=!0,`class="${g}"`):l});return r&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),a}function Rb(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Nb(e,t,n){if(!e)return e;let s=e,i=["if","elif","else","endif","for","endfor","set","do","block","endblock","macro","endmacro","call","endcall","filter","endfilter","raw","endraw","include","import","from","extends","print","unless","endunless","is","not","and","or","in"].join("|"),r=new RegExp(`\\b[a-zA-Z][\\w-]*-(${i})\\b(?!-)`,"g"),a=/(\{%[-~]?[\s\S]*?[-~]?%\})/g,l=!1;s=s.replace(a,h=>h.replace(r,(b,S)=>(l=!0,S))),l&&n.push({module:t,field:"moduleHtml",message:"Stripped CSS-class prefix from HubL keywords inside {% %} tags",autoFixed:!0});let c=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,d=[],u;for(;(u=c.exec(s))!==null;){let h=u[1],f=!h.startsWith("end"),b=f?h:h.replace("end","");d.push({tag:h,isOpen:f,baseTag:b,start:u.index,end:u.index+u[0].length})}let m=[],g=[];for(let h=0;h<d.length;h++)if(d[h].isOpen)m.push(h);else{let f=-1;for(let b=m.length-1;b>=0;b--)if(d[m[b]].baseTag===d[h].baseTag){f=b;break}f!==-1?m.splice(f,1):g.push(h)}if(g.length>0){for(let h=g.length-1;h>=0;h--){let f=d[g[h]];s=s.slice(0,f.start)+`<!-- removed orphan {% ${f.tag} %} -->`+s.slice(f.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${g.length} orphan closing tag${g.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(m.length>0){let h=m.map(b=>d[b].baseTag),f=h.reverse().map(b=>`{% end${b} %}`).join(`
2393
2408
  `);s=`${s}
2394
- ${f}`,n.push({module:t,field:"moduleHtml",message:`Added ${h.length} missing closing tag${h.length===1?"":"s"}: ${h.map(b=>`{% end${b} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:t,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function lu(e){if(!e)return[];let t=[],n=/\b(rgba?|hsla?)\(([^()]*)\)/gi,s;for(;(s=n.exec(e))!==null;){let o=s[2];(o.trim()===""||o.split(",").some(i=>i.trim()===""))&&t.push(s[0].trim())}return t}function By(e,t){let n=ct(e.fieldsJson),s=Array.isArray(n)?rn(n):{},o=e.moduleHtml||"";try{o=jn(e.moduleHtml||"",{module:s})}catch{}let i=[...lu(o),...lu(e.moduleCss||"")];if(i.length===0)return;let r=i[0].length>60?i[0].slice(0,57)+"\u2026":i[0];t.push({module:e.moduleName,field:"moduleCss",message:`${i.length} invalid CSS color value${i.length===1?"":"s"} (e.g. \`${r}\`) \u2014 renders unstyled. A style field with no default is likely fed into rgba()/hsla().`,autoFixed:!1,code:"invalid-css"})}function Hy(e,t,n,s=!1,o=!1){let i=ct(e);if(!i||typeof i!="object")return e;let r=i,a=!1;if(r.host_template_types){if(s)r.host_template_types.includes("EMAIL")||(r.host_template_types=["EMAIL"],a=!0,n.push({module:t,field:"metaJson",message:'Fixed host_template_types to ["EMAIL"] for email module',autoFixed:!0}));else if(o){let l=r.host_template_types;l.includes("BLOG_POST")||l.includes("BLOG_LISTING")||(r.host_template_types=["BLOG_POST"],a=!0,n.push({module:t,field:"metaJson",message:"Fixed host_template_types to include blog type for blog module",autoFixed:!0}))}}else{let l=s?"EMAIL":o?"BLOG_POST":"PAGE";r.host_template_types=[l],a=!0}return r.is_available_for_new_content===void 0&&(r.is_available_for_new_content=!0,a=!0),a?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(r,null,2)):e}function du(e,t){let n=[],s=new Set(t.map(o=>`/${o}`));for(let o of e){if(!o.moduleName.includes("header")&&!o.moduleName.includes("nav")&&!o.moduleName.includes("footer"))continue;let i=/href=["'](\/?[a-z0-9][a-z0-9-]*(?:\/[a-z0-9-]*)*)["']/gi,r,a=[];for(;(r=i.exec(o.moduleHtml))!==null;){let l=r[1];l.startsWith("/")||(l="/"+l),!(l==="/"||l.startsWith("/http")||l.startsWith("/#"))&&a.push(l)}for(let l of a)s.has(l)||n.push({module:o.moduleName,message:`Nav link "${l}" does not match any page slug (valid: ${t.map(c=>"/"+c).join(", ")})`,autoFixed:!1})}return n}function Gy(e,t,n){let s=new Set;if(t.colors?.primary&&s.add(t.colors.primary.toLowerCase()),t.colors?.secondary&&s.add(t.colors.secondary.toLowerCase()),t.colors?.accent&&s.add(t.colors.accent.toLowerCase()),s.size===0&&!t.fonts?.heading&&!t.fonts?.body)return;let o=(e.moduleHtml||"")+(e.moduleCss||"");if(s.size>0){let i=new Set;for(let a of o.matchAll(Uy))i.add(a[0].toLowerCase());let r=new Set(["#ffffff","#000000","#f4f4f4","#f5f5f5","#fafafa","#eeeeee","#e0e0e0","#dddddd","#cccccc","#999999","#666666","#333333","#1a1a1a","#111111","#222222","#444444","#555555","#777777","#888888","#aaaaaa","#bbbbbb"]);for(let a of i)if(!r.has(a)&&!s.has(a)){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand color ${a} (brand colors: ${[...s].join(", ")})`,autoFixed:!1});break}}if(t.fonts?.heading||t.fonts?.body){let i=[];t.fonts.heading&&i.push(t.fonts.heading.toLowerCase()),t.fonts.body&&i.push(t.fonts.body.toLowerCase());let r=/font-family:\s*([^;}"]+)/gi;for(let a of o.matchAll(r)){let l=a[1].toLowerCase().trim();if(!i.some(c=>l.includes(c))){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand font "${a[1].trim()}" (brand fonts: ${i.join(", ")})`,autoFixed:!1});break}}}}function Wy(e,t){let n={...e},s=n.moduleHtml;n.moduleCss&&n.moduleCss.trim()&&(t.push({module:e.moduleName,field:"moduleCss",message:"Cleared moduleCss \u2014 email modules must use inline styles only",autoFixed:!0}),n.moduleCss=""),n.moduleJs&&n.moduleJs.trim()&&(t.push({module:e.moduleName,field:"moduleJs",message:"Cleared moduleJs \u2014 email clients do not support JavaScript",autoFixed:!0}),n.moduleJs=void 0),/<style[\s>]/i.test(s)&&(s=s.replace(/<style[^>]*>[\s\S]*?<\/style>/gi,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed <style> blocks \u2014 email clients strip them",autoFixed:!0})),/display\s*:\s*flex/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:flex \u2014 not supported in email clients",autoFixed:!1}),/display\s*:\s*grid/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:grid \u2014 not supported in email clients",autoFixed:!1}),/var\s*\(/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains var() \u2014 CSS custom properties not supported in email",autoFixed:!1});let o=/\{[{%].*?(?:require_css|require_js|scope_css|get_asset_url)\s*\(.*?\}[}%]/g;o.test(s)&&(s=s.replace(o,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed banned HubL functions for email (require_css, require_js, scope_css, get_asset_url)",autoFixed:!0}));let i=/<link[^>]*href="https?:\/\/[^"]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^"]*"[^>]*\/?>/gi;return i.test(s)&&(s=s.replace(i,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed CDN <link> tags \u2014 external resources not supported in email",autoFixed:!0})),n.moduleHtml=s,n}function Ky(e,t){let n={...e},s=n.moduleHtml;return/\{\{[\s]*content\.body[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.body[\s]*\}\}/g,"{{ content.post_body }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.body \u2192 content.post_body (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.title[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.title[\s]*\}\}/g,"{{ content.name }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.title \u2192 content.name (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.author_name[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.author_name[\s]*\}\}/g,"{{ content.blog_post_author }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.author_name \u2192 content.blog_post_author",autoFixed:!0})),/\{\{[\s]*content\.date[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.date[\s]*\}\}/g,"{{ content.publish_date }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.date \u2192 content.publish_date",autoFixed:!0})),/\{\{[\s]*content\.image[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.image[\s]*\}\}/g,"{{ content.featured_image }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.image \u2192 content.featured_image",autoFixed:!0})),/\{%.*dnd_area.*%\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains dnd_area \u2014 blog templates typically use fixed module positions",autoFixed:!1}),/\{\{[\s]*content\.publish_date[\s]*\}\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"publish_date used without |datetimeformat filter \u2014 dates may render as raw timestamps",autoFixed:!1}),n.moduleHtml=s,n}var Iy,Fy,Uy,Xr=N(()=>{"use strict";y();Wo();le();Sr();Iy=[["name","item_name"],["label","section_label"],["body","body_text"]];Fy=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);Uy=/#[0-9a-fA-F]{6}\b/g});import{execSync as Vy}from"child_process";async function uu(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(Un(n)){let k={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(k)try{Vy(`command -v ${k}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${k}" to be installed and on your PATH.`)}}let d=await _d(e,t,n,s,o,r,a);if(d.intent==="question"&&d.answer){let O=Date.now()-l;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:O,answer:d.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:O}}}if(d.intent==="create_site"&&d.pages&&d.pages.length>0)return zy(e,d,t,n,s,o,i,r,l);let u=null,m=t.sharedCss,g=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Ld(e,d,t,n,s,o,r),d.contentType!=="email"&&(m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g),r({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let f=[];if(u)for(let O of u.modules)f.push({name:O.name,description:O.description,contentBrief:O.contentBrief,layoutNotes:O.layoutNotes});else{for(let O of d.newModules)f.push({name:O.name,description:O.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let O of d.affectedModules){let k=t.modules.find(T=>T.moduleName===O);k&&f.push({name:O,description:`Modify existing module: ${O}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:k})}}let b=[],S=[];if(f.length>0){let O=await te("module-development",()=>Ps(e,f,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:f.length}});for(let k of O)k.module?b.push(k.module):S.push(k.moduleName)}let v=null;if(b.length>0){v=ln(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit);let O=v.filter(T=>T.issues.some($=>$.field==="fieldsJson"&&$.message.includes("reset to empty"))).map(T=>T.module.moduleName);if(O.length>0){let T=O.map($=>f.find(F=>F.name===$)).filter($=>$!=null);if(T.length>0){E.info("pipeline",`Retrying ${T.length} module(s) with broken fieldsJson: ${T.map(F=>F.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${T.length} module(s) with invalid fields JSON...`});let $=await te("module-development-retry",()=>Ps(e,T,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:T.length}});for(let F of $)if(F.module){let re=b.findIndex(_e=>_e.moduleName===F.moduleName);re>=0&&(b[re]=F.module)}v=ln(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit)}}b=v.map(T=>T.module);let k=v.reduce((T,$)=>T+$.issues.length,0);if(k>0){let T=v.reduce((F,re)=>F+re.issues.filter(_e=>_e.autoFixed).length,0);E.info("pipeline",`Quality check: ${k} issues, ${T} auto-fixed`);let $=v.flatMap(F=>F.issues).map(F=>`${F.autoFixed?"\u2713":"\u26A0"} ${F.module}: ${F.message}`).join(`
2395
- `);r({type:"agent_decision",step:"quality_check",decision:`${k} issues found, ${T} auto-fixed
2396
- ${$}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let w=qy(t,d,b,u,a),M=Xy(t,d,u,w);if(u?.moduleOrder?.length){let O=new Set(u.moduleOrder),k=w.filter(T=>!O.has(T.moduleName)).map(T=>T.moduleName);k.length>0&&r({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${k.length} module${k.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${k.join(", ")}`})}let j=Date.now()-l,J=b.length,H=d.unchangedModules.length,K=v?v.flatMap(O=>O.issues):[],X=Zy(d,J,H,S,j,u,K);return S.length>0?r({type:"pipeline_partial",succeeded:b.map(O=>O.moduleName),failed:S,durationMs:j}):r({type:"pipeline_complete",modulesGenerated:J,modulesUnchanged:H,durationMs:j,assistantMessage:X}),{modules:w,moduleOrder:M,sharedCss:m,sharedJs:g,assistantMessage:X,contentType:d.contentType,stats:{modulesGenerated:J,modulesUnchanged:H,modulesFailed:S.length,durationMs:j}}}async function zy(e,t,n,s,o,i,r,a,l){let c=t.pages,d=t.sharedModules||["site-header","site-footer"],u=await jd(e,t,n,s,o,i,a),m=u.sharedCss||n.sharedCss,g=u.sharedJs||n.sharedJs;a({type:"blueprint_ready",moduleOrder:d,sharedCss:m,sharedJs:g});let h=await Wd(e,t,n,m,s,o,i,a);a({type:"agent_step",step:"developing",label:`Generating modules for ${c.length} pages...`});let f=[];for(let $ of h.sharedModules)f.push({...$});for(let $ of h.pages)for(let F of $.modules)f.push({name:F.name,description:F.description,contentBrief:F.contentBrief,layoutNotes:F.layoutNotes});let b=c.map($=>`- "${$.label}" \u2192 /${$.slug}`).join(`
2397
- `);for(let $ of f)($.name.includes("header")||$.name.includes("nav"))&&($.layoutNotes+=`
2409
+ ${f}`,n.push({module:t,field:"moduleHtml",message:`Added ${h.length} missing closing tag${h.length===1?"":"s"}: ${h.map(b=>`{% end${b} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:t,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function Iu(e){if(!e)return[];let t=[],n=/\b(rgba?|hsla?)\(([^()]*)\)/gi,s;for(;(s=n.exec(e))!==null;){let o=s[2];(o.trim()===""||o.split(",").some(i=>i.trim()===""))&&t.push(s[0].trim())}return t}function Ob(e,t){let n=ut(e.fieldsJson),s=Array.isArray(n)?un(n):{},o=e.moduleHtml||"";try{o=Gn(e.moduleHtml||"",{module:s})}catch{}let i=[...Iu(o),...Iu(e.moduleCss||"")];if(i.length===0)return;let r=i[0].length>60?i[0].slice(0,57)+"\u2026":i[0];t.push({module:e.moduleName,field:"moduleCss",message:`${i.length} invalid CSS color value${i.length===1?"":"s"} (e.g. \`${r}\`) \u2014 renders unstyled. A style field with no default is likely fed into rgba()/hsla().`,autoFixed:!1,code:"invalid-css"})}function Fb(e,t,n,s=!1,o=!1){let i=ut(e);if(!i||typeof i!="object")return e;let r=i,a=!1;if(r.host_template_types){if(s)r.host_template_types.includes("EMAIL")||(r.host_template_types=["EMAIL"],a=!0,n.push({module:t,field:"metaJson",message:'Fixed host_template_types to ["EMAIL"] for email module',autoFixed:!0}));else if(o){let l=r.host_template_types;l.includes("BLOG_POST")||l.includes("BLOG_LISTING")||(r.host_template_types=["BLOG_POST"],a=!0,n.push({module:t,field:"metaJson",message:"Fixed host_template_types to include blog type for blog module",autoFixed:!0}))}}else{let l=s?"EMAIL":o?"BLOG_POST":"PAGE";r.host_template_types=[l],a=!0}return r.is_available_for_new_content===void 0&&(r.is_available_for_new_content=!0,a=!0),a?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(r,null,2)):e}function Nu(e,t){let n=[],s=new Set(t.map(o=>`/${o}`));for(let o of e){if(!o.moduleName.includes("header")&&!o.moduleName.includes("nav")&&!o.moduleName.includes("footer"))continue;let i=/href=["'](\/?[a-z0-9][a-z0-9-]*(?:\/[a-z0-9-]*)*)["']/gi,r,a=[];for(;(r=i.exec(o.moduleHtml))!==null;){let l=r[1];l.startsWith("/")||(l="/"+l),!(l==="/"||l.startsWith("/http")||l.startsWith("/#"))&&a.push(l)}for(let l of a)s.has(l)||n.push({module:o.moduleName,message:`Nav link "${l}" does not match any page slug (valid: ${t.map(c=>"/"+c).join(", ")})`,autoFixed:!1})}return n}function jb(e,t,n){let s=new Set;if(t.colors?.primary&&s.add(t.colors.primary.toLowerCase()),t.colors?.secondary&&s.add(t.colors.secondary.toLowerCase()),t.colors?.accent&&s.add(t.colors.accent.toLowerCase()),s.size===0&&!t.fonts?.heading&&!t.fonts?.body)return;let o=(e.moduleHtml||"")+(e.moduleCss||"");if(s.size>0){let i=new Set;for(let a of o.matchAll(Db))i.add(a[0].toLowerCase());let r=new Set(["#ffffff","#000000","#f4f4f4","#f5f5f5","#fafafa","#eeeeee","#e0e0e0","#dddddd","#cccccc","#999999","#666666","#333333","#1a1a1a","#111111","#222222","#444444","#555555","#777777","#888888","#aaaaaa","#bbbbbb"]);for(let a of i)if(!r.has(a)&&!s.has(a)){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand color ${a} (brand colors: ${[...s].join(", ")})`,autoFixed:!1});break}}if(t.fonts?.heading||t.fonts?.body){let i=[];t.fonts.heading&&i.push(t.fonts.heading.toLowerCase()),t.fonts.body&&i.push(t.fonts.body.toLowerCase());let r=/font-family:\s*([^;}"]+)/gi;for(let a of o.matchAll(r)){let l=a[1].toLowerCase().trim();if(!i.some(c=>l.includes(c))){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand font "${a[1].trim()}" (brand fonts: ${i.join(", ")})`,autoFixed:!1});break}}}}function Lb(e,t){let n={...e},s=n.moduleHtml;n.moduleCss&&n.moduleCss.trim()&&(t.push({module:e.moduleName,field:"moduleCss",message:"Cleared moduleCss \u2014 email modules must use inline styles only",autoFixed:!0}),n.moduleCss=""),n.moduleJs&&n.moduleJs.trim()&&(t.push({module:e.moduleName,field:"moduleJs",message:"Cleared moduleJs \u2014 email clients do not support JavaScript",autoFixed:!0}),n.moduleJs=void 0),/<style[\s>]/i.test(s)&&(s=s.replace(/<style[^>]*>[\s\S]*?<\/style>/gi,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed <style> blocks \u2014 email clients strip them",autoFixed:!0})),/display\s*:\s*flex/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:flex \u2014 not supported in email clients",autoFixed:!1}),/display\s*:\s*grid/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:grid \u2014 not supported in email clients",autoFixed:!1}),/var\s*\(/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains var() \u2014 CSS custom properties not supported in email",autoFixed:!1});let o=/\{[{%].*?(?:require_css|require_js|scope_css|get_asset_url)\s*\(.*?\}[}%]/g;o.test(s)&&(s=s.replace(o,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed banned HubL functions for email (require_css, require_js, scope_css, get_asset_url)",autoFixed:!0}));let i=/<link[^>]*href="https?:\/\/[^"]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^"]*"[^>]*\/?>/gi;return i.test(s)&&(s=s.replace(i,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed CDN <link> tags \u2014 external resources not supported in email",autoFixed:!0})),n.moduleHtml=s,n}function Bb(e,t){let n={...e},s=n.moduleHtml;return/\{\{[\s]*content\.body[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.body[\s]*\}\}/g,"{{ content.post_body }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.body \u2192 content.post_body (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.title[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.title[\s]*\}\}/g,"{{ content.name }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.title \u2192 content.name (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.author_name[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.author_name[\s]*\}\}/g,"{{ content.blog_post_author }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.author_name \u2192 content.blog_post_author",autoFixed:!0})),/\{\{[\s]*content\.date[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.date[\s]*\}\}/g,"{{ content.publish_date }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.date \u2192 content.publish_date",autoFixed:!0})),/\{\{[\s]*content\.image[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.image[\s]*\}\}/g,"{{ content.featured_image }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.image \u2192 content.featured_image",autoFixed:!0})),/\{%.*dnd_area.*%\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains dnd_area \u2014 blog templates typically use fixed module positions",autoFixed:!1}),/\{\{[\s]*content\.publish_date[\s]*\}\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"publish_date used without |datetimeformat filter \u2014 dates may render as raw timestamps",autoFixed:!1}),n.moduleHtml=s,n}var Tb,Eb,Db,fa=R(()=>{"use strict";y();oi();de();Nr();Tb=[["name","item_name"],["label","section_label"],["body","body_text"]];Eb=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);Db=/#[0-9a-fA-F]{6}\b/g});function Jb(e){return e.replace(/^--/,"").replace(/[-_]/g," ").replace(/\b\w/g,t=>t.toUpperCase()).trim()}function ui(e,t,n){for(let s of t)for(let[o,i]of Object.entries(e))if(o.toLowerCase().includes(s)&&Fu.test(String(i).trim()))return String(i).trim();return n}function Ou(e,t,n){for(let s of t)for(let[o,i]of Object.entries(e)){let r=o.toLowerCase();if(r.includes("font")&&r.includes(s)&&String(i).trim())return String(i).trim()}for(let[s,o]of Object.entries(e))if(s.toLowerCase().includes("font")&&String(o).trim())return String(o).trim();return n}function Hb(e){let t=[],n=new Set;for(let[s,o]of Object.entries(e)){let i=String(o).trim();if(!(!Fu.test(i)||i.startsWith("var("))&&!n.has(i.toLowerCase())&&(n.add(i.toLowerCase()),t.push({label:Jb(s),value:i}),t.length>=6))break}return t}function fn(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Ub(e,t,n){let s=ui(e,["background","bg","surface","dark"],"#0f1115"),o=ui(e,["text","foreground","fg","ink","light"],"#f5f5f7"),i=ui(e,["primary","brand","accent","cta"],"#e8613a"),r=ui(e,["on-primary","button-text","light","background"],"#ffffff");return`<!doctype html><html><head><meta charset="utf-8"><style>
2410
+ *{margin:0;box-sizing:border-box}
2411
+ body{font-family:${fn(n)};background:${fn(s)};color:${fn(o)}}
2412
+ .hero{padding:48px 40px;display:flex;flex-direction:column;gap:18px;align-items:flex-start}
2413
+ .eyebrow{font-size:12px;letter-spacing:.12em;text-transform:uppercase;opacity:.7}
2414
+ h1{font-family:${fn(t)};font-size:38px;line-height:1.08;font-weight:700;max-width:14ch}
2415
+ p{font-size:16px;line-height:1.55;opacity:.85;max-width:46ch}
2416
+ .btn{margin-top:6px;display:inline-block;padding:13px 26px;border-radius:8px;
2417
+ background:${fn(i)};color:${fn(r)};font-family:${fn(t)};
2418
+ font-weight:600;font-size:15px;text-decoration:none}
2419
+ </style></head><body>
2420
+ <section class="hero">
2421
+ <span class="eyebrow">Preview</span>
2422
+ <h1>Build pages that feel like your brand.</h1>
2423
+ <p>This is a sample hero rendered from the design system above \u2014 same palette, type, and button style your real modules will use.</p>
2424
+ <a class="btn" href="#">Get started</a>
2425
+ </section>
2426
+ </body></html>`}function Du(e){let t=e.cssVariables||{},n=Hb(t),s=Ou(t,["head","display","title","serif"],"Space Grotesk, system-ui, sans-serif"),o=Ou(t,["body","text","base","sans"],"DM Sans, system-ui, sans-serif"),i=Ub(t,s,o);return{kind:"design",headline:"Here's the look \u2014 approve before I build the page",data:{aesthetic:e.aesthetic||"custom",palette:n,typography:{heading:s,body:o},heroHtml:i}}}function ju(){return{kind:"brand_intake",headline:"Want me to match your brand, or should I surprise you?",data:{surpriseLabel:"Surprise me",surpriseHint:"I'll invent a design system that fits your request.",bringLabel:"Bring your brand",bringHint:"Paste colors, code, a tone of voice, or point me at a site/theme.",channels:[{key:"colors",label:"Brand colors",placeholder:`Primary #e8613a
2427
+ Ink #0f1115
2428
+ Surface #ffffff`,multiline:!0},{key:"code",label:"Paste CSS or HTML",placeholder:":root { --brand: #e8613a } \u2026",multiline:!0},{key:"voice",label:"Tone of voice",placeholder:"Direct, specific, no buzzword soup",multiline:!0},{key:"siteUrl",label:"Site URL",placeholder:"https://yourbrand.com",multiline:!1},{key:"themePath",label:"HubSpot theme path",placeholder:"/path/to/theme",multiline:!1}]}}}var Fu,Lu=R(()=>{"use strict";y();Fu=/^(#|rgb|hsl|var\()/i});function ha(e){return[...new Set(e.map(t=>t.trim()).filter(Boolean))]}function ya(){return{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]}}function Bu(e){let t=ya(),n,s=new RegExp(Gb.source,"g");for(;(n=s.exec(e))!==null;){let d=new RegExp(Wb.source,"g"),u;for(;(u=d.exec(n[1]))!==null;){let m=u[1].trim(),g=u[2].trim();m&&g&&!t.cssVariables[m]&&(t.cssVariables[m]=g)}}let o=new Map,i,r=new RegExp(Hu.source,"g");for(;(i=r.exec(e))!==null;){let d=i[0].trim().toLowerCase();["#fff","#ffffff","#000","#000000"].includes(d)||o.set(d,(o.get(d)??0)+1)}t.palette=[...o.entries()].sort((d,u)=>u[1]-d[1]).slice(0,12).map(([d,u])=>({value:d,count:u}));let a=[],l,c=new RegExp(Kb.source,"gi");for(;(l=c.exec(e))!==null;){let d=l[1].split(",")[0].trim().replace(/^["']|["']$/g,"");d&&!d.startsWith("var(")&&a.push(d)}return t.fontFamilies=ha(a).slice(0,8),t}function Vb(e){let t=ya(),n=e.split(/[\n,]/).map(o=>o.trim()).filter(Boolean),s=0;for(let o of n){let r=new RegExp(Hu.source,"g").exec(o);if(!r)continue;let a=r[0].trim(),l=o.slice(0,r.index).replace(/[:\-–—]+\s*$/,"").trim(),c=l?l.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):"",d=c?`--color-${c}`:s===0?"--color-primary":s===1?"--color-secondary":`--color-accent-${s-1}`;t.cssVariables[d]||(t.cssVariables[d]=a,t.palette.push({value:a.toLowerCase(),count:1}),s++)}return t}async function zb(e){let t=/^https?:\/\//i.test(e)?e:`https://${e}`,n=new AbortController,s=setTimeout(()=>n.abort(),1e4);try{let o=await fetch(t,{signal:n.signal,redirect:"follow",headers:Ju});if(!o.ok)return T.warn("brand-intake",`site fetch ${t} \u2192 HTTP ${o.status}`),"";let i=await o.text(),r="";for(let l of i.matchAll(/<style[^>]*>([\s\S]*?)<\/style>/gi))r+=`
2429
+ ${l[1]}`;for(let l of i.matchAll(/<meta[^>]+name=["']theme-color["'][^>]*>/gi)){let c=/content=["']([^"']+)["']/i.exec(l[0])?.[1];c&&(r+=`
2430
+ --theme-color: ${c};`)}for(let l of i.matchAll(/style=["']([^"']+)["']/gi))r+=`
2431
+ .inline{${l[1]}}`;let a=[];for(let l of i.matchAll(/<link\b[^>]*>/gi)){let c=l[0];if(!/rel=["'][^"']*stylesheet[^"']*["']/i.test(c))continue;let d=/href=["']([^"']+)["']/i.exec(c)?.[1];d&&a.push(d)}for(let l of a.slice(0,6))try{let c=new URL(l.startsWith("//")?`https:${l}`:l,t).toString(),d=await fetch(c,{signal:n.signal,redirect:"follow",headers:Ju});d.ok&&(r+=`
2432
+ ${await d.text()}`)}catch{}return r.trim()||(r=i),r}catch(o){return T.warn("brand-intake",`site fetch failed for ${t}: ${o instanceof Error?o.message:String(o)}`),""}finally{clearTimeout(s)}}function mi(e,t,n,s){for(let[o,i]of Object.entries(s.cssVariables))e[o]||(e[o]=i);t.push(...s.palette.map(o=>o.value)),n.push(...s.fontFamilies)}async function Uu(e){let t={},n=[],s=[],o=[],i=[];if(e.colors?.trim()){let d=Vb(e.colors);Object.keys(d.cssVariables).length>0&&(mi(t,n,s,d),o.push("colors"),i.push(`### Brand colors (provided)
2433
+ ${Object.entries(d.cssVariables).map(([u,m])=>`- ${u}: ${m}`).join(`
2434
+ `)}`))}if(e.code?.trim()){let d=Bu(e.code);(Object.keys(d.cssVariables).length>0||d.palette.length>0||d.fontFamilies.length>0)&&(mi(t,n,s,d),o.push("code"),i.push(`### From pasted code
2435
+ - Variables: ${Object.keys(d.cssVariables).length}
2436
+ - Colors: ${d.palette.slice(0,6).map(u=>u.value).join(", ")||"none"}
2437
+ - Fonts: ${d.fontFamilies.join(", ")||"none"}`))}if(e.themePath?.trim())try{let d=qt(e.themePath.trim());(Object.keys(d.cssVariables).length>0||d.palette.length>0||d.fontFamilies.length>0)&&(mi(t,n,s,d),o.push("theme"),i.push(`### From imported theme
2438
+ - Variables: ${Object.keys(d.cssVariables).length}
2439
+ - Colors: ${d.palette.slice(0,6).map(u=>u.value).join(", ")||"none"}
2440
+ - Fonts: ${d.fontFamilies.join(", ")||"none"}`))}catch(d){T.warn("brand-intake",`theme token extraction failed: ${d instanceof Error?d.message:String(d)}`)}if(e.siteUrl?.trim()){let d=await zb(e.siteUrl.trim());if(d){let u=Bu(d);(Object.keys(u.cssVariables).length>0||u.palette.length>0||u.fontFamilies.length>0)&&(mi(t,n,s,u),o.push("site"),i.push(`### From site (${e.siteUrl.trim()})
2441
+ - Colors: ${u.palette.slice(0,6).map(m=>m.value).join(", ")||"none"}
2442
+ - Fonts: ${u.fontFamilies.join(", ")||"none"}`))}}Object.keys(t).length===0&&ha(n).slice(0,6).forEach((d,u)=>{let m=u===0?"primary":u===1?"secondary":`accent-${u-1}`;t[`--color-${m}`]=d});let r=ha(s);r[0]&&!Object.keys(t).some(d=>d.includes("font")&&d.includes("head"))&&(t["--font-heading"]=r[0]),r[1]&&!Object.keys(t).some(d=>d.includes("font")&&d.includes("body"))&&(t["--font-body"]=r[1]||r[0]);let a=Object.keys(t).length?dn({...ya(),cssVariables:t}):"",l=e.voice?.trim()||void 0;l&&o.push("voice");let c;if(i.length>0||l){let d=["# Brand intake (user-provided)","Use these EXACT brand tokens as the foundation of the design system. Map the colors and fonts into `:root` variables and build every component style around them \u2014 do not invent a different palette."];i.length&&d.push(i.join(`
2443
+
2444
+ `)),l&&d.push(`### Tone of voice
2445
+ ${l}`),c=d.join(`
2446
+
2447
+ `)}return{cssVariables:t,rootCss:a,styleguide:c,brandvoice:l,channels:o}}var Hu,Gb,Wb,Kb,Ju,Gu=R(()=>{"use strict";y();Cs();de();Hu=/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/g,Gb=/:root\s*\{([^}]*)\}/g,Wb=/(--[A-Za-z0-9-_]+)\s*:\s*([^;]+?)\s*(?:;|$)/g,Kb=/font-family\s*:\s*([^;}]+)[;}]/gi;Ju={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36",Accept:"text/html,application/xhtml+xml,text/css,*/*;q=0.8","Accept-Language":"en-US,en;q=0.9"}});function Yb(e){return String(e||"").trim().toLowerCase().replace(/['"]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Wu(e){let t=new Map;e.modules.forEach((i,r)=>{t.has(i.name)||t.set(i.name,r)});let n=[],s=new Set;for(let i of e.moduleOrder||[]){let r=t.get(i);if(r==null||s.has(r))continue;s.add(r);let a=e.modules[r];n.push({name:a.name,description:a.description||"",sourceIndex:r})}return e.modules.forEach((i,r)=>{s.has(r)||n.push({name:i.name,description:i.description||"",sourceIndex:r})}),{kind:"structure",headline:"Here's the structure \u2014 reorder, cut, or add sections before I build",data:{narrative:e.narrative||"",modules:n}}}function Ku(e,t){if(!t||t.length===0)return e;let n=[],s=new Set;for(let o of t){let i=o.sourceIndex!=null?e.modules[o.sourceIndex]:void 0,r=Yb(o.name)||i?.name;r&&(s.has(r)||(s.add(r),i?n.push({name:r,description:o.description??i.description,contentBrief:i.contentBrief,layoutNotes:i.layoutNotes}):n.push({name:r,description:o.description||`User-added section: ${r}`,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use a responsive layout matching the existing design system"})))}return n.length===0?e:{...e,modules:n,moduleOrder:n.map(o=>o.name)}}var Vu=R(()=>{"use strict";y()});import{execSync as qb}from"child_process";function Yu(){return`cp_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function Hs(e){Us.delete(e)}function qu(){let e=ec();if(!(!e||e.costUsd<=0))return Math.round(e.costUsd*Xb*100)/100}async function Xu(e,t,n,s,o,i,r,a,l=!1,c){let d=Date.now(),u=i;if(Yn(n)){let x={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(x)try{qb(`command -v ${x}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${x}" to be installed and on your PATH.`)}}let m=await tu(e,t,n,s,o,r,a);if(c?.aborted)throw new Re;if(m.intent==="question"&&m.answer){let S=Date.now()-d;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:S,answer:m.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:m.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:S}}}if(m.intent==="create_site"&&m.pages&&m.pages.length>0)return tS(e,m,t,n,s,o,i,r,d,c);let g=null,h=t.sharedCss,f=t.sharedJs;if(m.intent==="create"||m.designSystemChanges){if(l&&m.contentType!=="email"){if(m.intent==="create"&&!Zb(t))return Qb({kind:"brand_intake",userMessage:e,plan:m,sharedCss:h,sharedJs:f,startTime:d,libraryModules:a},t,r);let S=await js(e,m,t,n,s,o,r);return Sa({kind:"design",userMessage:e,plan:m,designSystem:S,sharedCss:S.sharedCss,sharedJs:S.sharedJs||f,startTime:d,libraryModules:a},t,r)}g=await cu(e,m,t,n,s,o,r),m.contentType!=="email"&&(h=g.designSystem.sharedCss||h,f=g.designSystem.sharedJs||f),r({type:"blueprint_ready",moduleOrder:g.moduleOrder,sharedCss:h,sharedJs:f})}if(c?.aborted)throw new Re;return ba(e,m,t,g,h,f,n,s,o,u,r,a,d,c)}function Zu(e,t,n,s,o){let i=Yu();Us.set(i,t);let r=qu();return o({type:"checkpoint_requested",kind:e,preview:n,...r!=null?{estCostNext:r}:{}}),{modules:[...s.modules],moduleOrder:s.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:"",contentType:t.plan.contentType,stats:{modulesGenerated:0,modulesUnchanged:s.modules.length,modulesFailed:0,durationMs:Date.now()-t.startTime},pendingCheckpoint:{kind:e,resumeToken:i,preview:n,createdAt:new Date().toISOString(),resumeState:t}}}function Sa(e,t,n){if(!e.designSystem)throw new Error("Cannot park at the design checkpoint without a design system.");return Zu("design",e,Du(e.designSystem),t,n)}function zu(e,t,n){return Zu("structure",e,Wu(e.blueprint),t,n)}function Zb(e){return!!(e.brandAssets?.styleguide&&e.brandAssets.styleguide.trim()||e.sharedCss&&e.sharedCss.includes(":root"))}function Qb(e,t,n){let s=Yu();Us.set(s,e);let o=ju(),i=qu();return n({type:"checkpoint_requested",kind:"brand_intake",preview:o,...i!=null?{estCostNext:i}:{}}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,assistantMessage:"",contentType:e.plan.contentType,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:Date.now()-e.startTime},pendingCheckpoint:{kind:"brand_intake",resumeToken:s,preview:o,createdAt:new Date().toISOString(),resumeState:e}}}async function eS(e,t,n,s,o,i,r,a){Hs(e);let l=n.action==="approve"?n.brandIntake:void 0,c=s,d,u=null;if(l)if(u=await Uu(l),u.channels.length>0){let h=[s.brandAssets?.styleguide,u.styleguide].filter(f=>f&&f.trim()).join(`
2448
+
2449
+ `);d={...h?{styleguide:h}:{},...u.brandvoice?{brandvoice:u.brandvoice}:{}},c={...s,brandAssets:{...s.brandAssets,...h?{styleguide:h}:{},...u.brandvoice?{brandvoice:u.brandvoice}:{}},sharedCss:u.rootCss||s.sharedCss},a({type:"agent_decision",step:"designing",decision:`Brand intake: using ${u.channels.join(", ")} \u2192 ${Object.keys(u.cssVariables).length} brand token(s)`})}else a({type:"agent_decision",step:"designing",decision:"Brand intake: couldn't extract usable design tokens from what you provided \u2014 generating a design system instead. Try pasting your brand colors or CSS directly."});let m=await js(t.userMessage,t.plan,c,o,i,r,a);u&&Object.keys(u.cssVariables).length>0&&(m.cssVariables={...m.cssVariables||{},...u.cssVariables},u.rootCss&&!m.sharedCss.includes(u.rootCss.trim())&&(m.sharedCss=`${m.sharedCss}
2450
+
2451
+ /* Brand intake overrides (VIB-1878) */
2452
+ ${u.rootCss}`));let g=Sa({kind:"design",userMessage:t.userMessage,plan:t.plan,designSystem:m,sharedCss:m.sharedCss,sharedJs:m.sharedJs||t.sharedJs,startTime:t.startTime,libraryModules:t.libraryModules},s,a);return d&&(g.brandAssetsUpdate=d),g}async function Qu(e,t,n,s,o,i,r,a,l,c){let d=Us.get(e);if(!d&&c&&(d=c,Us.set(e,d)),!d)throw new Error("This checkpoint has expired (the server may have restarted). Send your request again to start over.");if(t.action==="cancel")return Hs(e),{modules:[...n.modules],moduleOrder:n.moduleOrder,sharedCss:n.sharedCss,sharedJs:n.sharedJs,assistantMessage:"Cancelled \u2014 nothing was built.",canceled:!0,stats:{modulesGenerated:0,modulesUnchanged:n.modules.length,modulesFailed:0,durationMs:0}};if(d.kind==="brand_intake")return eS(e,d,t,n,s,o,i,a);if(d.kind==="structure"){if(Hs(e),t.action==="steer"){let f=(t.note||"").trim(),b=f?`${d.userMessage}
2453
+
2454
+ ## Structure steer (revise the module plan to honor this)
2455
+ ${f}`:d.userMessage,S=await ua(b,d.plan,n,d.designSystem,d.sharedCss,s,o,i,a);return zu({...d,userMessage:b,blueprint:S},n,a)}let h=Ku(d.blueprint,t.outline);return a({type:"blueprint_ready",moduleOrder:h.moduleOrder,sharedCss:d.sharedCss,sharedJs:d.sharedJs}),ba(d.userMessage,d.plan,n,h,d.sharedCss,d.sharedJs??"",s,o,i,r,a,d.libraryModules,d.startTime,l)}if(t.action==="steer"){Hs(e);let h=(t.note||"").trim(),f=h?`${d.userMessage}
2456
+
2457
+ ## Design steer (revise the design system to honor this)
2458
+ ${h}`:d.userMessage,b=await js(f,d.plan,n,s,o,i,a);return Sa({...d,userMessage:f,designSystem:b,sharedCss:b.sharedCss,sharedJs:b.sharedJs||d.sharedJs},n,a)}if(Hs(e),!d.designSystem)throw new Error("Checkpoint resume state is missing its design system. Send your request again to start over.");let u=await ua(d.userMessage,d.plan,n,d.designSystem,d.sharedCss,s,o,i,a),m=d.plan.contentType!=="email"&&u.designSystem.sharedCss||d.sharedCss,g=d.plan.contentType!=="email"&&u.designSystem.sharedJs||d.sharedJs;return t.action!=="skip"?zu({kind:"structure",userMessage:d.userMessage,plan:d.plan,designSystem:d.designSystem,blueprint:u,sharedCss:m,sharedJs:g??"",startTime:d.startTime,libraryModules:d.libraryModules},n,a):(a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}),ba(d.userMessage,d.plan,n,u,m,g??"",s,o,i,r,a,d.libraryModules,d.startTime,l))}async function ba(e,t,n,s,o,i,r,a,l,c,d,u,m,g){let h=[];if(s)for(let D of s.modules)h.push({name:D.name,description:D.description,contentBrief:D.contentBrief,layoutNotes:D.layoutNotes});else{for(let D of t.newModules)h.push({name:D.name,description:D.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let D of t.affectedModules){let U=n.modules.find(C=>C.moduleName===D);U&&h.push({name:D,description:`Modify existing module: ${D}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:U})}}let f=[],b=[];if(h.length>0){let D=await se("module-development",()=>Js(e,h,o,n.themeName,r,a,l,c,d,t.guidesNeeded,n.brandAssets,t.contentType,g),{metadata:{moduleCount:h.length}});for(let U of D)U.module?f.push(U.module):b.push(U.moduleName)}let S=null;if(f.length>0){S=gn(f,n.themeName,d,t.contentType,n.brandAssets?.brandKit);let D=S.filter(C=>C.issues.some(P=>P.field==="fieldsJson"&&P.message.includes("reset to empty"))).map(C=>C.module.moduleName);if(D.length>0){let C=D.map(P=>h.find(O=>O.name===P)).filter(P=>P!=null);if(C.length>0){T.info("pipeline",`Retrying ${C.length} module(s) with broken fieldsJson: ${C.map(O=>O.name).join(", ")}`),d({type:"agent_decision",step:"quality_check",decision:`Regenerating ${C.length} module(s) with invalid fields JSON...`});let P=await se("module-development-retry",()=>Js(e,C,o,n.themeName,r,a,l,c,d,t.guidesNeeded,n.brandAssets,t.contentType,g),{metadata:{moduleCount:C.length}});for(let O of P)if(O.module){let I=f.findIndex(Q=>Q.moduleName===O.moduleName);I>=0&&(f[I]=O.module)}S=gn(f,n.themeName,d,t.contentType,n.brandAssets?.brandKit)}}f=S.map(C=>C.module);let U=S.reduce((C,P)=>C+P.issues.length,0);if(U>0){let C=S.reduce((O,I)=>O+I.issues.filter(Q=>Q.autoFixed).length,0);T.info("pipeline",`Quality check: ${U} issues, ${C} auto-fixed`);let P=S.flatMap(O=>O.issues).map(O=>`${O.autoFixed?"\u2713":"\u26A0"} ${O.module}: ${O.message}`).join(`
2459
+ `);d({type:"agent_decision",step:"quality_check",decision:`${U} issues found, ${C} auto-fixed
2460
+ ${P}`})}else d({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let x=sS(n,t,f,s,u),k=oS(n,t,s,x);if(s?.moduleOrder?.length){let D=new Set(s.moduleOrder),U=x.filter(C=>!D.has(C.moduleName)).map(C=>C.moduleName);U.length>0&&d({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${U.length} module${U.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${U.join(", ")}`})}let $=Date.now()-m,L=f.length,j=t.unchangedModules.length,J=S?S.flatMap(D=>D.issues):[],V=iS(t,L,j,b,$,s,J);return b.length>0?d({type:"pipeline_partial",succeeded:f.map(D=>D.moduleName),failed:b,durationMs:$}):d({type:"pipeline_complete",modulesGenerated:L,modulesUnchanged:j,durationMs:$,assistantMessage:V}),{modules:x,moduleOrder:k,sharedCss:o,sharedJs:i,assistantMessage:V,contentType:t.contentType,stats:{modulesGenerated:L,modulesUnchanged:j,modulesFailed:b.length,durationMs:$}}}async function tS(e,t,n,s,o,i,r,a,l,c){let d=t.pages,u=t.sharedModules||["site-header","site-footer"],m=await js(e,t,n,s,o,i,a),g=m.sharedCss||n.sharedCss,h=m.sharedJs||n.sharedJs;a({type:"blueprint_ready",moduleOrder:u,sharedCss:g,sharedJs:h});let f=await fu(e,t,n,g,s,o,i,a);a({type:"agent_step",step:"developing",label:`Generating modules for ${d.length} pages...`});let b=[];for(let I of f.sharedModules)b.push({...I});for(let I of f.pages)for(let Q of I.modules)b.push({name:Q.name,description:Q.description,contentBrief:Q.contentBrief,layoutNotes:Q.layoutNotes});let S=d.map(I=>`- "${I.label}" \u2192 /${I.slug}`).join(`
2461
+ `);for(let I of b)(I.name.includes("header")||I.name.includes("nav"))&&(I.layoutNotes+=`
2398
2462
 
2399
2463
  ## Site Navigation
2400
2464
  This is a multi-page site. Include navigation links to all pages:
2401
- ${b}
2402
- Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await te("module-development",()=>Ps(e,f,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:f.length}}),v=[],w=[];for(let $ of S)$.module?v.push($.module):w.push($.moduleName);let M=v,j=[];if(v.length>0){let $=ln(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit),F=$.filter(z=>z.issues.some(ue=>ue.field==="fieldsJson"&&ue.message.includes("reset to empty"))).map(z=>z.module.moduleName);if(F.length>0){let z=F.map(ue=>f.find(ne=>ne.name===ue)).filter(ue=>ue!=null);if(z.length>0){E.info("pipeline",`Retrying ${z.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${z.length} module(s) with invalid fields JSON...`});let ue=await te("module-development-retry",()=>Ps(e,z,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:z.length}});for(let ne of ue)if(ne.module){let $e=v.findIndex(Us=>Us.moduleName===ne.moduleName);$e>=0&&(v[$e]=ne.module)}$=ln(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}M=$.map(z=>z.module),j=$.flatMap(z=>z.issues);let re=du(M,c.map(z=>z.slug));j.push(...re);let _e=j.length;if(_e>0){let z=j.filter(ue=>ue.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${_e} issues found, ${z} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let J=new Map(M.map($=>[$.moduleName,$])),H=h.sharedModules.map($=>J.get($.name)).filter($=>!!$),K=new Map(c.map($=>[$.id,$])),X=h.pages.map($=>{let F=$.modules.map(ne=>J.get(ne.name)).filter(ne=>!!ne),re=d.filter(ne=>ne.includes("header")||ne.includes("nav")),_e=d.filter(ne=>ne.includes("footer")),z=[...re,...$.moduleOrder,..._e],ue=K.get($.pageId);return{pageId:$.pageId,templateId:$.pageId,label:ue?.label||$.pageId,pageType:ue?.pageType||"website_page",modules:[...H,...F],moduleOrder:z}}),O=Date.now()-l,k=Yy(c,v.length,w,O,h.narrative,j);return w.length>0?a({type:"pipeline_partial",succeeded:v.map($=>$.moduleName),failed:w,durationMs:O}):a({type:"pipeline_complete",modulesGenerated:v.length,modulesUnchanged:0,durationMs:O,assistantMessage:k}),{modules:M,moduleOrder:M.map($=>$.moduleName),sharedCss:m,sharedJs:g||"",assistantMessage:k,stats:{modulesGenerated:v.length,modulesUnchanged:0,modulesFailed:w.length,durationMs:O},multiPage:{pages:X,sharedModules:H,sharedCss:m,sharedJs:g||"",assistantMessage:k,stats:{pagesGenerated:c.length,modulesGenerated:v.length,modulesFailed:w.length,durationMs:O}}}}function Yy(e,t,n,s,o,i){let r=Math.round(s/1e3),a=[];a.push(`Created ${e.length}-page site with ${t} modules in ${r}s.`),a.push(`
2465
+ ${S}
2466
+ Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let x=await se("module-development",()=>Js(e,b,g,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType,c),{metadata:{moduleCount:b.length}}),k=[],$=[];for(let I of x)I.module?k.push(I.module):$.push(I.moduleName);let L=k,j=[];if(k.length>0){let I=gn(k,n.themeName,a,t.contentType,n.brandAssets?.brandKit),Q=I.filter(ee=>ee.issues.some(re=>re.field==="fieldsJson"&&re.message.includes("reset to empty"))).map(ee=>ee.module.moduleName);if(Q.length>0){let ee=Q.map(re=>b.find(Z=>Z.name===re)).filter(re=>re!=null);if(ee.length>0){T.info("pipeline",`Retrying ${ee.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${ee.length} module(s) with invalid fields JSON...`});let re=await se("module-development-retry",()=>Js(e,ee,g,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType,c),{metadata:{moduleCount:ee.length}});for(let Z of re)if(Z.module){let ts=k.findIndex(Qg=>Qg.moduleName===Z.moduleName);ts>=0&&(k[ts]=Z.module)}I=gn(k,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}L=I.map(ee=>ee.module),j=I.flatMap(ee=>ee.issues);let et=Nu(L,d.map(ee=>ee.slug));j.push(...et);let Fe=j.length;if(Fe>0){let ee=j.filter(re=>re.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${Fe} issues found, ${ee} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let J=new Map(L.map(I=>[I.moduleName,I])),V=f.sharedModules.map(I=>J.get(I.name)).filter(I=>!!I),D=new Map(d.map(I=>[I.id,I])),U=f.pages.map(I=>{let Q=I.modules.map(Z=>J.get(Z.name)).filter(Z=>!!Z),et=u.filter(Z=>Z.includes("header")||Z.includes("nav")),Fe=u.filter(Z=>Z.includes("footer")),ee=[...et,...I.moduleOrder,...Fe],re=D.get(I.pageId);return{pageId:I.pageId,templateId:I.pageId,label:re?.label||I.pageId,pageType:re?.pageType||"website_page",modules:[...V,...Q],moduleOrder:ee}}),C=Date.now()-l,P=nS(d,k.length,$,C,f.narrative,j);return $.length>0?a({type:"pipeline_partial",succeeded:k.map(I=>I.moduleName),failed:$,durationMs:C}):a({type:"pipeline_complete",modulesGenerated:k.length,modulesUnchanged:0,durationMs:C,assistantMessage:P}),{modules:L,moduleOrder:L.map(I=>I.moduleName),sharedCss:g,sharedJs:h||"",assistantMessage:P,stats:{modulesGenerated:k.length,modulesUnchanged:0,modulesFailed:$.length,durationMs:C},multiPage:{pages:U,sharedModules:V,sharedCss:g,sharedJs:h||"",assistantMessage:P,stats:{pagesGenerated:d.length,modulesGenerated:k.length,modulesFailed:$.length,durationMs:C}}}}function nS(e,t,n,s,o,i){let r=Math.round(s/1e3),a=[];a.push(`Created ${e.length}-page site with ${t} modules in ${r}s.`),a.push(`
2403
2467
 
2404
2468
  **Pages:** ${e.map(d=>d.label).join(", ")}`),o&&a.push(`
2405
2469
 
@@ -2408,17 +2472,74 @@ ${o}`),n.length>0&&a.push(`
2408
2472
  **Failed:** ${n.join(", ")}. You can retry these individually.`);let l=i.filter(d=>!d.autoFixed),c=i.filter(d=>d.autoFixed);if(c.length>0||l.length>0){let d=[];c.length>0&&d.push(`**Auto-fixed:** ${c.map(u=>`${u.module}: ${u.message}`).join(", ")}`),l.length>0&&d.push(`**Warnings:** ${l.map(u=>`${u.module}: ${u.message}`).join(", ")}`),a.push(`
2409
2473
 
2410
2474
  ${d.join(`
2411
- `)}`)}return a.join("")}function qy(e,t,n,s,o){let i=[],r=new Set;for(let a of n)i.push(a),r.add(a.moduleName);for(let a of t.unchangedModules){if(r.has(a))continue;let l=e.modules.find(c=>c.moduleName===a);l&&(i.push(l),r.add(a))}if(t.reuseModules)for(let a of t.reuseModules){if(r.has(a.name))continue;let l=o.find(c=>c.name===a.name&&c.module);l&&l.module&&(i.push(l.module),r.add(a.name))}return i}function Xy(e,t,n,s){if(n?.moduleOrder?.length){let a=[...n.moduleOrder],l=new Set(a);for(let c of s)if(!l.has(c.moduleName)){let d=a.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?a.splice(d,0,c.moduleName):a.push(c.moduleName),l.add(c.moduleName),E.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return a}if(t.intent==="create")return s.map(a=>a.moduleName);let o=[...e.moduleOrder],i=[...t.newModules.map(a=>({name:a.name,position:a.position})),...(t.reuseModules||[]).map(a=>({name:a.name,position:a.position}))].sort((a,l)=>a.position-l.position);for(let a of i){let l=Math.min(a.position,o.length);o.splice(l,0,a.name)}let r=new Set(s.map(a=>a.moduleName));return o.filter(a=>r.has(a))}function Zy(e,t,n,s,o,i,r){let a=Math.round(o/1e3),l=[];if(e.intent==="create")l.push(`Created ${t} module${t===1?"":"s"} in ${a}s.`);else if(e.intent==="modify"||e.intent==="style_change")l.push(`Updated ${t} module${t===1?"":"s"} in ${a}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(e.intent==="add"){let u=e.newModules.map(m=>m.name).join(", ");l.push(`Added ${u} in ${a}s.`)}else e.intent==="remove"?l.push(`Removed modules in ${a}s.`):e.intent==="rearrange"&&l.push(`Rearranged modules in ${a}s.`);i?.narrative&&l.push(`
2475
+ `)}`)}return a.join("")}function sS(e,t,n,s,o){let i=[],r=new Set;for(let a of n)i.push(a),r.add(a.moduleName);for(let a of t.unchangedModules){if(r.has(a))continue;let l=e.modules.find(c=>c.moduleName===a);l&&(i.push(l),r.add(a))}if(t.reuseModules)for(let a of t.reuseModules){if(r.has(a.name))continue;let l=o.find(c=>c.name===a.name&&c.module);l&&l.module&&(i.push(l.module),r.add(a.name))}return i}function oS(e,t,n,s){if(n?.moduleOrder?.length){let a=[...n.moduleOrder],l=new Set(a);for(let c of s)if(!l.has(c.moduleName)){let d=a.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?a.splice(d,0,c.moduleName):a.push(c.moduleName),l.add(c.moduleName),T.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return a}if(t.intent==="create")return s.map(a=>a.moduleName);let o=[...e.moduleOrder],i=[...t.newModules.map(a=>({name:a.name,position:a.position})),...(t.reuseModules||[]).map(a=>({name:a.name,position:a.position}))].sort((a,l)=>a.position-l.position);for(let a of i){let l=Math.min(a.position,o.length);o.splice(l,0,a.name)}let r=new Set(s.map(a=>a.moduleName));return o.filter(a=>r.has(a))}function iS(e,t,n,s,o,i,r){let a=Math.round(o/1e3),l=[];if(e.intent==="create")l.push(`Created ${t} module${t===1?"":"s"} in ${a}s.`);else if(e.intent==="modify"||e.intent==="style_change")l.push(`Updated ${t} module${t===1?"":"s"} in ${a}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(e.intent==="add"){let u=e.newModules.map(m=>m.name).join(", ");l.push(`Added ${u} in ${a}s.`)}else e.intent==="remove"?l.push(`Removed modules in ${a}s.`):e.intent==="rearrange"&&l.push(`Rearranged modules in ${a}s.`);i?.narrative&&l.push(`
2412
2476
 
2413
2477
  ${i.narrative}`),s.length>0&&l.push(`
2414
2478
 
2415
2479
  **Failed:** ${s.join(", ")}. You can retry these individually.`);let c=r.filter(u=>!u.autoFixed),d=r.filter(u=>u.autoFixed);if(d.length>0||c.length>0){let u=[];d.length>0&&u.push(`**Auto-fixed:** ${d.map(m=>`${m.module}: ${m.message}`).join(", ")}`),c.length>0&&u.push(`**Warnings:** ${c.map(m=>`${m.module}: ${m.message}`).join(", ")}`),l.push(`
2416
2480
 
2417
2481
  ${u.join(`
2418
- `)}`)}return l.join("")}var mu=N(()=>{"use strict";y();dt();$d();Jd();Kd();ru();Xr();le();Be();dt()});var yu={};Ge(yu,{runFigmaConversion:()=>Qy});import{basename as fu}from"path";async function Qy(e,t,n,s,o,i,r,a,l){let c=Date.now();r({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=eb(e.designTokens,t);r({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),r({type:"agent_decision",step:"designing",decision:`Generated CSS variables and utility classes from ${e.designTokens.colors.length} colors, ${e.designTokens.typography.length} typography styles`});let{specs:m,moduleOrder:g}=nb(e.sections,e.assets,t);r({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),r({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${g.join(", ")}`}),r({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let h=n==="anthropic-api"||n==="claude-oauth",f=Ms(t,d,["hubspot_rules","conversion"],a),b=h?Xo(t,d,["hubspot_rules","conversion"],a):void 0,S=qo(i),v=m.length,M=(await te("module-development",()=>{let T=m.map(($,F)=>{let re=e.sections[F];return S(async()=>{r({type:"module_progress",module:$.name,status:"generating",current:F+1,total:v});let _e=ib(re,$,e.assets,t,l!==!1),z="";for(let ue=0;ue<2;ue++)try{ue>0&&(E.warn("figma-pipeline",`${$.name}: retrying (attempt ${ue+1})`),r({type:"module_progress",module:$.name,status:"retrying",current:F+1,total:v}));let ne=await Pe(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:_e}],structuredOutput:{schema:Is,name:"module_output"},maxTokens:16e3});if(ne.type!=="structured")throw new Error("No structured output returned");let $e=ne.data,Us={moduleName:$.name,fieldsJson:typeof $e.fieldsJson=="string"?$e.fieldsJson:JSON.stringify($e.fieldsJson,null,2),metaJson:typeof $e.metaJson=="string"?$e.metaJson:JSON.stringify($e.metaJson,null,2),moduleHtml:String($e.moduleHtml||""),moduleCss:String($e.moduleCss||""),moduleJs:$e.moduleJs?String($e.moduleJs):void 0};return r({type:"module_progress",module:$.name,status:"complete",current:F+1,total:v,moduleFiles:Us}),{moduleName:$.name,module:Us}}catch(ne){z=ne instanceof Error?ne.message:String(ne),E.error("figma-pipeline",`Failed: ${$.name} (attempt ${ue+1}): ${z}`)}return r({type:"module_progress",module:$.name,status:"failed",current:F+1,total:v}),{moduleName:$.name,error:z}})});return Promise.allSettled(T)},{metadata:{moduleCount:v}})).map(T=>T.status==="fulfilled"?T.value:{moduleName:"unknown",error:String(T.reason)}),j=M.filter(T=>T.module).map(T=>T.module),J=M.filter(T=>T.error).map(T=>T.moduleName),K=ln(j,t,r).map(T=>T.module),X=Date.now()-c,O=Math.round(X/1e3),k=`Imported ${K.length} modules from Figma design "${e.fileName}" in ${O}s.`;return J.length>0?r({type:"pipeline_partial",succeeded:K.map(T=>T.moduleName),failed:J,durationMs:X}):r({type:"pipeline_complete",modulesGenerated:K.length,modulesUnchanged:0,durationMs:X,assistantMessage:k}),{modules:K,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:k,stats:{modulesGenerated:K.length,modulesUnchanged:0,modulesFailed:J.length,durationMs:X}}}function Zo(e){let t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,s=parseInt(e.slice(5,7),16)/255,o=Math.max(t,n,s),i=Math.min(t,n,s),r=(o+i)/2;if(o===i)return{h:0,s:0,l:r};let a=o-i,l=r>.5?a/(2-o-i):a/(o+i),c=0;return o===t?c=((n-s)/a+(n<s?6:0))/6:o===n?c=((s-t)/a+2)/6:c=((t-n)/a+4)/6,{h:c*360,s:l,l:r}}function eb(e,t){let n=[],s=t,o=[...e.colors].sort((k,T)=>T.occurrences-k.occurrences),i=o.filter(k=>k.usage==="background"||k.usage==="fill"),r=o.filter(k=>k.usage==="text"),a=i[0]||o[0],l=a?Zo(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(k=>Zo(k.hex).l>.7):o.find(k=>Zo(k.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(k=>!d.has(k.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(k=>!d.has(k.hex)).slice(0,6).forEach((k,T)=>n.push(` --${s}-color-${T+1}: ${k.hex}`)),a){let k=Zo(a.hex).l;n.push(` --${s}-color-surface: ${l?pu(a.hex,.05):gu(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?pu(a.hex,.15):gu(a.hex,.12)}`)}let g=e.typography.filter(k=>k.role==="heading"||k.role==="subheading"),h=e.typography.filter(k=>k.role==="body"||k.role==="label"||k.role==="caption"),f=g[0]?.fontFamily||h[0]?.fontFamily||"system-ui",b=h[0]?.fontFamily||f;n.push(` --${s}-font-display: "${f}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let S=g.sort((k,T)=>T.fontSize-k.fontSize);S[0]&&n.push(` --${s}-size-h1: ${S[0].fontSize}px`),S[1]&&n.push(` --${s}-size-h2: ${S[1].fontSize}px`),S[2]&&n.push(` --${s}-size-h3: ${S[2].fontSize}px`);let v=h.sort((k,T)=>T.occurrences-k.occurrences)[0];v&&n.push(` --${s}-size-body: ${v.fontSize}px`);let w=[...new Set(e.spacing.map(k=>k.value))].sort((k,T)=>k-T),M=["xs","sm","md","lg","xl","2xl","section"];w.slice(0,M.length).forEach((k,T)=>{n.push(` --${s}-space-${M[T]}: ${k}px`)});let j=e.effects.filter(k=>k.type==="shadow"),J=e.effects.filter(k=>k.type==="radius");j[0]&&n.push(` --${s}-shadow: ${j[0].cssValue}`),J.sort((k,T)=>parseFloat(k.cssValue)-parseFloat(T.cssValue)),J[0]&&n.push(` --${s}-radius: ${J[0].cssValue}`),J[1]&&n.push(` --${s}-radius-lg: ${J[1].cssValue}`);let H=`:root {
2482
+ `)}`)}return l.join("")}var Xb,Us,em=R(()=>{"use strict";y();mt();zn();nu();du();hu();Eu();fa();Lu();Gu();Vu();$o();de();He();mt();Xb=6,Us=new Map});var Ws={};We(Ws,{collectThemeFiles:()=>nm,extractDesignContext:()=>dS});import{existsSync as pi,readdirSync as gi,readFileSync as rS}from"fs";import{join as At}from"path";import{spawn as aS}from"child_process";async function tm(){return va||(va=(await import("@anthropic-ai/sdk")).default),va}function Gs(e){try{return rS(e,"utf-8")}catch{return""}}function nm(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2483
+ ### ${a}
2484
+ \`\`\`
2485
+ ${l}
2486
+ \`\`\`
2487
+ `;return n+c.length>lS?!1:(t.push(c),n+=c.length,!0)}let o=Gs(At(e,"theme.json"));o&&s("theme.json",o);let i=At(e,"css");if(pi(i)){for(let a of gi(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,Gs(At(i,a))))break}let r=At(e,"modules");if(pi(r))for(let a of gi(r).filter(l=>l.endsWith(".module"))){let l=At(r,a),c=Gs(At(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(pi(r))for(let a of gi(r).filter(l=>l.endsWith(".module"))){let l=At(r,a),c=Gs(At(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(pi(r))for(let a of gi(r).filter(l=>l.endsWith(".module"))){let l=At(r,a),c=Gs(At(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function cS(){if(!fi)try{fi=M(Cn("extraction-prompt.md"))}catch{fi=""}return fi}function xa(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=aS(e,t,{stdio:["pipe","pipe","pipe"],env:i,shell:!0}),a="",l="";r.stdout.on("data",c=>{a+=c.toString()}),r.stderr.on("data",c=>{l+=c.toString()}),r.on("error",c=>o(new Error(`${e} failed to start: ${c.message}`))),r.on("close",c=>{c===0||a.trim()?s(a.trim()):o(new Error(`${e} exited with code ${c}: ${l.trim()}`))}),r.stdin.write(n),r.stdin.end()})}async function dS(e,t){t?.({status:"Collecting theme files..."});let n=nm(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=cS();if(!s)throw new Error("Extraction prompt not found (assets/extraction-prompt.md).");let o=`Analyze this HubSpot CMS theme and extract the design system:
2488
+ ${n}`;t?.({status:"Analyzing design patterns..."});let i=N(),r=i.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(r){case"anthropic-api":case"api":{let u=De("anthropic-api");if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");let m=await tm(),g=new m({apiKey:u});d=i.anthropicApiModel||"claude-sonnet-4-6";let h=await g.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=h.content.map(f=>f.type==="text"?f.text:"").join(""),c=st(h.usage);break}case"claude-oauth":{let{getValidAccessToken:u,OAUTH_EXTRA_HEADERS:m,OAUTH_SYSTEM_PREFIX:g}=await Promise.resolve().then(()=>(It(),er)),h=await u();if(!h)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let f=await tm(),b=new f({authToken:h,defaultHeaders:m});d=i.anthropicApiModel||"claude-sonnet-4-6";let S=await b.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:g},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=S.content.map(x=>x.type==="text"?x.text:"").join(""),c=st(S.usage);break}case"openai-api":{let u=De("openai-api");if(!u)throw new Error("OpenAI API key not configured. Open Settings to add one.");d=i.openaiApiModel||"gpt-4o";let m=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`},body:JSON.stringify({model:d,max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!m.ok)throw new Error(`OpenAI API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.choices?.[0]?.message?.content||"",c=On(g.usage);break}case"gemini-api":{let u=De("gemini-api");if(!u)throw new Error("Gemini API key not configured. Open Settings to add one.");d=i.geminiApiModel||"gemini-2.5-flash";let m=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${d}:generateContent?key=${u}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!m.ok)throw new Error(`Gemini API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.candidates?.[0]?.content?.parts?.map(h=>h.text).join("")||"",c=Fn(g.usageMetadata);break}case"claude-code":{let u=`${s}
2489
+
2490
+ ## User Request
2491
+ ${o}`,m=["--print"];i.claudeCodeModel&&m.push("--model",i.claudeCodeModel),a=await xa("claude",m,u);break}case"gemini-cli":{let u=`${s}
2492
+
2493
+ ## User Request
2494
+ ${o}`;a=await xa("gemini",[],u);break}case"codex-cli":{let u=`${s}
2495
+
2496
+ ## User Request
2497
+ ${o}`;a=await xa("codex",[],u);break}default:throw new Error(`Unknown AI engine: ${r}. Open Settings to configure one.`)}if(!a.trim())throw new Error("AI returned empty response.");return d&&kt({engine:r,model:d,name:"styleguide-extraction",input:{system:s,messages:[{role:"user",content:o}]},output:a,usage:c,startTime:l,endTime:new Date}),t?.({status:"Design extraction complete."}),a}var va,lS,fi,Ks=R(()=>{"use strict";y();ae();oe();He();an();va=null;lS=8e4;fi=""});var wa={};We(wa,{extractBrandvoice:()=>uS});async function uS(e,t,n,s){if(!e||e.length<50)return null;let o=`You are a brand strategist. Analyze the rendered landing page HTML below and extract a concise brand voice guide. The HTML contains the actual text content with all template variables resolved to their default values.
2498
+
2499
+ Return a markdown document with these sections (skip any section where the content provides no signal):
2500
+
2501
+ ## Tone
2502
+ Overall communication style (e.g., confident but approachable, technical but clear, playful, authoritative).
2503
+
2504
+ ## Voice Characteristics
2505
+ 3-5 bullet points describing how this brand "sounds" (e.g., "Uses short, punchy sentences", "Addresses reader directly with 'you'").
2506
+
2507
+ ## Vocabulary
2508
+ - **Preferred words**: Terms used repeatedly or intentionally
2509
+ - **Avoided patterns**: Any notable absences or anti-patterns
2510
+
2511
+ ## Sentence Style
2512
+ Typical sentence length, structure, use of questions, imperatives, etc.
2513
+
2514
+ ## Dos and Don'ts
2515
+ 3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
2516
+
2517
+ Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await _e(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),r=i.type==="text"?i.text:JSON.stringify(i.data);return!r||r.trim().length<20?null:(T.info("brandvoice-extractor",`Extracted brand voice (${r.length} chars)`),r.trim())}catch(i){let r=i instanceof Error?i.message:String(i);return T.warn("brandvoice-extractor",`Brand voice extraction failed: ${r}`),null}}var ka=R(()=>{"use strict";y();mt();de()});var hi={};We(hi,{extractThemeContext:()=>mS});async function mS(e,t,n,s,o){if(!e||e.length<50)return null;let r=`You are a content analyst. Extract a concise product/company brief from the rendered landing page HTML below. The HTML contains the actual text content (headings, paragraphs, button labels, image alt text, etc.) with all template variables resolved to their default values.
2518
+
2519
+ Return a markdown document with these sections (skip any section where the content provides no information):
2520
+
2521
+ ## Product / Company
2522
+ Name, one-line description, and what it does.
2523
+
2524
+ ## Value Propositions
2525
+ Key benefits or features (bulleted list).
2526
+
2527
+ ## Target Audience
2528
+ Who this product/service is for.
2529
+
2530
+ ## Tone & Voice
2531
+ Communication style (e.g., professional, casual, technical, friendly).
2532
+
2533
+ ## Key Terminology
2534
+ Specific terms, product names, or branded language used consistently.
2535
+
2536
+ Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
2537
+
2538
+ Existing product context (update if the new content adds info, keep what's still accurate):
2539
+ ${t}`:""}`;try{let a=await _e(n,s,o,{systemPrompt:r,messages:[{role:"user",content:e}],maxTokens:1e3}),l=a.type==="text"?a.text:JSON.stringify(a.data);return!l||l.trim().length<20?null:(T.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return T.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var yi=R(()=>{"use strict";y();mt();de()});import{join as sm}from"path";function pS(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function bi(e,t,n){e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=sm(e.themePath,".vibespot");Ie(o),H(sm(o,s),n)}async function om(e,t){let n=pS(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:ze({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>gS(e,t,n,s))}async function gS(e,t,n,s){let o=fS(t)?t:{...await hS(e),...t??{}};n.includes("styleguide")&&await Ca(e,"styleguide",s,()=>se("extract-styleguide",()=>o.extractStyleguide(e)));let i=n.filter(a=>a==="brandvoice"||a==="themeContext");if(i.length===0)return s;let r="";try{r=o.buildPreviewHtml()}catch(a){let l=a instanceof Error?a.message:String(a);for(let c of i)s.skipped.push(c),s.errors.push({asset:c,message:`Could not render preview HTML: ${l}`});return s}if(!r||r.length<50){for(let a of i)s.skipped.push(a);return s}return n.includes("brandvoice")&&await Ca(e,"brandvoice",s,()=>se("extract-brandvoice",()=>o.extractBrandvoice(e,r))),n.includes("themeContext")&&await Ca(e,"themeContext",s,()=>se("extract-theme-context",()=>o.extractThemeContext(e,r))),s}async function Ca(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}bi(e,t,o),n.extracted.push(t)}catch(o){let i=o instanceof Error?o.message:String(o);n.skipped.push(t),n.errors.push({asset:t,message:i}),T.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function fS(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function hS(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(Ks(),Ws)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(_s(),si)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(qn(),Aa)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(ka(),wa)),{extractThemeContext:i}=await Promise.resolve().then(()=>(yi(),hi)),r=N();return{extractStyleguide:()=>t(e.themePath),buildPreviewHtml:n,extractBrandvoice:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return o(l,c,d,u)},extractThemeContext:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return i(l,a.brandAssets?.themeContext,c,d,u)}}}var Ta=R(()=>{"use strict";y();ae();oe();de();He()});var cm={};We(cm,{runFigmaConversion:()=>yS});import{basename as am}from"path";async function yS(e,t,n,s,o,i,r,a,l){let c=Date.now();r({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=bS(e.designTokens,t);r({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),r({type:"agent_decision",step:"designing",decision:`Generated CSS variables and utility classes from ${e.designTokens.colors.length} colors, ${e.designTokens.typography.length} typography styles`});let{specs:m,moduleOrder:g}=vS(e.sections,e.assets,t);r({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),r({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${g.join(", ")}`}),r({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let h=n==="anthropic-api"||n==="claude-oauth",f=Ls(t,d,["hubspot_rules","conversion"],a),b=h?di(t,d,["hubspot_rules","conversion"],a):void 0,S=ri(i),x=m.length,$=(await se("module-development",()=>{let P=m.map((O,I)=>{let Q=e.sections[I];return S(async()=>{r({type:"module_progress",module:O.name,status:"generating",current:I+1,total:x});let et=kS(Q,O,e.assets,t,l!==!1),Fe="";for(let ee=0;ee<2;ee++)try{ee>0&&(T.warn("figma-pipeline",`${O.name}: retrying (attempt ${ee+1})`),r({type:"module_progress",module:O.name,status:"retrying",current:I+1,total:x}));let re=await _e(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:et}],structuredOutput:{schema:Bs,name:"module_output"},maxTokens:16e3});if(re.type!=="structured")throw new Error("No structured output returned");let Z=re.data,ts={moduleName:O.name,fieldsJson:typeof Z.fieldsJson=="string"?Z.fieldsJson:JSON.stringify(Z.fieldsJson,null,2),metaJson:typeof Z.metaJson=="string"?Z.metaJson:JSON.stringify(Z.metaJson,null,2),moduleHtml:String(Z.moduleHtml||""),moduleCss:String(Z.moduleCss||""),moduleJs:Z.moduleJs?String(Z.moduleJs):void 0};return r({type:"module_progress",module:O.name,status:"complete",current:I+1,total:x,moduleFiles:ts}),{moduleName:O.name,module:ts}}catch(re){Fe=re instanceof Error?re.message:String(re),T.error("figma-pipeline",`Failed: ${O.name} (attempt ${ee+1}): ${Fe}`)}return r({type:"module_progress",module:O.name,status:"failed",current:I+1,total:x}),{moduleName:O.name,error:Fe}})});return Promise.allSettled(P)},{metadata:{moduleCount:x}})).map(P=>P.status==="fulfilled"?P.value:{moduleName:"unknown",error:String(P.reason)}),L=$.filter(P=>P.module).map(P=>P.module),j=$.filter(P=>P.error).map(P=>P.moduleName),V=gn(L,t,r).map(P=>P.module),D=Date.now()-c,U=Math.round(D/1e3),C=`Imported ${V.length} modules from Figma design "${e.fileName}" in ${U}s.`;return j.length>0?r({type:"pipeline_partial",succeeded:V.map(P=>P.moduleName),failed:j,durationMs:D}):r({type:"pipeline_complete",modulesGenerated:V.length,modulesUnchanged:0,durationMs:D,assistantMessage:C}),{modules:V,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:C,stats:{modulesGenerated:V.length,modulesUnchanged:0,modulesFailed:j.length,durationMs:D}}}function Si(e){let t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,s=parseInt(e.slice(5,7),16)/255,o=Math.max(t,n,s),i=Math.min(t,n,s),r=(o+i)/2;if(o===i)return{h:0,s:0,l:r};let a=o-i,l=r>.5?a/(2-o-i):a/(o+i),c=0;return o===t?c=((n-s)/a+(n<s?6:0))/6:o===n?c=((s-t)/a+2)/6:c=((t-n)/a+4)/6,{h:c*360,s:l,l:r}}function bS(e,t){let n=[],s=t,o=[...e.colors].sort((C,P)=>P.occurrences-C.occurrences),i=o.filter(C=>C.usage==="background"||C.usage==="fill"),r=o.filter(C=>C.usage==="text"),a=i[0]||o[0],l=a?Si(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(C=>Si(C.hex).l>.7):o.find(C=>Si(C.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(C=>!d.has(C.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(C=>!d.has(C.hex)).slice(0,6).forEach((C,P)=>n.push(` --${s}-color-${P+1}: ${C.hex}`)),a){let C=Si(a.hex).l;n.push(` --${s}-color-surface: ${l?im(a.hex,.05):rm(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?im(a.hex,.15):rm(a.hex,.12)}`)}let g=e.typography.filter(C=>C.role==="heading"||C.role==="subheading"),h=e.typography.filter(C=>C.role==="body"||C.role==="label"||C.role==="caption"),f=g[0]?.fontFamily||h[0]?.fontFamily||"system-ui",b=h[0]?.fontFamily||f;n.push(` --${s}-font-display: "${f}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let S=g.sort((C,P)=>P.fontSize-C.fontSize);S[0]&&n.push(` --${s}-size-h1: ${S[0].fontSize}px`),S[1]&&n.push(` --${s}-size-h2: ${S[1].fontSize}px`),S[2]&&n.push(` --${s}-size-h3: ${S[2].fontSize}px`);let x=h.sort((C,P)=>P.occurrences-C.occurrences)[0];x&&n.push(` --${s}-size-body: ${x.fontSize}px`);let k=[...new Set(e.spacing.map(C=>C.value))].sort((C,P)=>C-P),$=["xs","sm","md","lg","xl","2xl","section"];k.slice(0,$.length).forEach((C,P)=>{n.push(` --${s}-space-${$[P]}: ${C}px`)});let L=e.effects.filter(C=>C.type==="shadow"),j=e.effects.filter(C=>C.type==="radius");L[0]&&n.push(` --${s}-shadow: ${L[0].cssValue}`),j.sort((C,P)=>parseFloat(C.cssValue)-parseFloat(P.cssValue)),j[0]&&n.push(` --${s}-radius: ${j[0].cssValue}`),j[1]&&n.push(` --${s}-radius-lg: ${j[1].cssValue}`);let J=`:root {
2419
2540
  ${n.join(`;
2420
2541
  `)};
2421
- }`,K=`
2542
+ }`,V=`
2422
2543
  /* Reset */
2423
2544
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
2424
2545
 
@@ -2502,8 +2623,8 @@ body {
2502
2623
  h1 { font-size: 2rem; }
2503
2624
  h2 { font-size: 1.5rem; }
2504
2625
  h3 { font-size: 1.25rem; }
2505
- }`;return{sharedCss:H+`
2506
- `+K,sharedJs:`(function() {
2626
+ }`;return{sharedCss:J+`
2627
+ `+V,sharedJs:`(function() {
2507
2628
  var observer = new IntersectionObserver(function(entries) {
2508
2629
  entries.forEach(function(entry) {
2509
2630
  if (entry.isIntersecting) {
@@ -2513,11 +2634,11 @@ body {
2513
2634
  });
2514
2635
  }, { threshold: 0.1 });
2515
2636
  document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
2516
- })();`}}function pu(e,t){return hu(e,t)}function gu(e,t){return hu(e,-t)}function hu(e,t){let n=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return n=Math.min(255,Math.max(0,Math.round(n+255*t))),s=Math.min(255,Math.max(0,Math.round(s+255*t))),o=Math.min(255,Math.max(0,Math.round(o+255*t))),`#${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${o.toString(16).padStart(2,"0")}`}function tb(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function nb(e,t,n){let s=new Set,o=[];for(let i of e){let r=tb(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=sb(i.textContent),l=ob(i,t,n),c=`Figma section "${i.name}" \u2014 ${i.width}x${i.height}px, ${i.textContent.length} text elements, ${i.children.length} children`;o.push({name:r,description:c,contentBrief:a,layoutNotes:l})}return{specs:o,moduleOrder:o.map(i=>i.name)}}function sb(e){let t={};for(let o of e){let i=o.role;t[i]||(t[i]=[]),t[i].push(o.text)}let n=[],s=["headline","subheadline","body","cta","label","caption"];for(let o of s)if(t[o])for(let i of t[o])n.push(`**${o}** (use as field default): "${i}"`);return n.join(`
2517
- `)}function ob(e,t,n){let s=[];if(s.push(`Dimensions: ${e.width}x${e.height}px`),e.backgroundColor&&s.push(`Background: ${e.backgroundColor}`),e.layoutMode&&s.push(`Layout: ${e.layoutMode}`),e.itemSpacing&&s.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&s.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`),e.children.length>0){s.push(`
2637
+ })();`}}function im(e,t){return lm(e,t)}function rm(e,t){return lm(e,-t)}function lm(e,t){let n=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return n=Math.min(255,Math.max(0,Math.round(n+255*t))),s=Math.min(255,Math.max(0,Math.round(s+255*t))),o=Math.min(255,Math.max(0,Math.round(o+255*t))),`#${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${o.toString(16).padStart(2,"0")}`}function SS(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function vS(e,t,n){let s=new Set,o=[];for(let i of e){let r=SS(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=xS(i.textContent),l=wS(i,t,n),c=`Figma section "${i.name}" \u2014 ${i.width}x${i.height}px, ${i.textContent.length} text elements, ${i.children.length} children`;o.push({name:r,description:c,contentBrief:a,layoutNotes:l})}return{specs:o,moduleOrder:o.map(i=>i.name)}}function xS(e){let t={};for(let o of e){let i=o.role;t[i]||(t[i]=[]),t[i].push(o.text)}let n=[],s=["headline","subheadline","body","cta","label","caption"];for(let o of s)if(t[o])for(let i of t[o])n.push(`**${o}** (use as field default): "${i}"`);return n.join(`
2638
+ `)}function wS(e,t,n){let s=[];if(s.push(`Dimensions: ${e.width}x${e.height}px`),e.backgroundColor&&s.push(`Background: ${e.backgroundColor}`),e.layoutMode&&s.push(`Layout: ${e.layoutMode}`),e.itemSpacing&&s.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&s.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`),e.children.length>0){s.push(`
2518
2639
  Children (${e.children.length}):`);for(let o of e.children){let i=` - ${o.type} "${o.name}" (${o.width}x${o.height})`;o.layoutMode&&(i+=` [${o.layoutMode}]`),o.childCount>0&&(i+=` [${o.childCount} children]`),o.characters&&(i+=` text: "${o.characters.slice(0,60)}"`),s.push(i)}}if(t.length>0){s.push(`
2519
- Available image assets:`);for(let o of t){let i=fu(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2520
- `)}function ib(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
2640
+ Available image assets:`);for(let o of t){let i=am(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2641
+ `)}function kS(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
2521
2642
 
2522
2643
  TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
2523
2644
  - Use the EXACT text content from the design as field default values
@@ -2542,12 +2663,12 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
2542
2663
  ### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let r of e.textContent)i.push(`- **${r.role}** (${r.fontSize}px, weight ${r.fontWeight}): "${r.text}"`)}if(e.children.length>0){i.push(`
2543
2664
  ### Structure (${e.children.length} children)`);for(let r of e.children){let a=`- ${r.type} "${r.name}" (${r.width}x${r.height})`;r.layoutMode&&(a+=` layout: ${r.layoutMode}`),r.childCount>0&&(a+=`, ${r.childCount} children`),r.characters&&(a+=`
2544
2665
  text: "${r.characters.slice(0,100)}"`),i.push(a)}}if(n.length>0)if(o){i.push(`
2545
- ### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let r of n){let a=fu(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2666
+ ### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let r of n){let a=am(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2546
2667
  ### Images \u2014 USE IMAGE FIELDS WITH PLACEHOLDERS`),i.push('Do NOT use get_asset_url(). Instead, create "image" type fields in fields.json for each image.'),i.push('Set a descriptive default.src (e.g. "https://placehold.co/600x400?text=Hero+Image") and default.alt text.'),i.push("In the module HTML, use: {{ module.field_name.src }} and {{ module.field_name.alt }}"),i.push("This gives content editors full control to replace images in HubSpot.");for(let r of n)i.push(`- "${r.name}" \u2014 create an image field for this`)}return i.push(`
2547
2668
  ## Module Specification
2548
2669
  - **Name**: ${t.name}
2549
2670
  - **Description**: ${t.description}`),i.join(`
2550
- `)}var bu=N(()=>{"use strict";y();dt();Vr();zr();Xr();le();Be()});var Su={};Ge(Su,{buildPlanModePrompt:()=>rb});function rb(e,t,n,s,o){let i=ab(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
2671
+ `)}var dm=R(()=>{"use strict";y();mt();zn();ma();fa();de();He()});var um={};We(um,{buildPlanModePrompt:()=>CS});function CS(e,t,n,s,o){let i=TS(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
2551
2672
 
2552
2673
  Plan mode is a DELIBERATION PHASE. Your job is to help the user articulate what they want to build BEFORE any code is generated. You do NOT write modules, HTML, or CSS in this mode. You ask questions, surface gaps, and maintain a living plan document.
2553
2674
 
@@ -2616,15 +2737,15 @@ Drive toward filling these gaps in priority order:
2616
2737
  The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
2617
2738
 
2618
2739
  \`\`\`
2619
- ${Zr(t.styleguide,1500)}
2740
+ ${_a(t.styleguide,1500)}
2620
2741
  \`\`\``),t?.brandvoice&&r.push(`## Available brand voice
2621
2742
 
2622
2743
  \`\`\`
2623
- ${Zr(t.brandvoice,1e3)}
2744
+ ${_a(t.brandvoice,1e3)}
2624
2745
  \`\`\``),t?.themeContext&&r.push(`## Theme context
2625
2746
 
2626
2747
  \`\`\`
2627
- ${Zr(t.themeContext,1e3)}
2748
+ ${_a(t.themeContext,1e3)}
2628
2749
  \`\`\``),n.length>0&&r.push(`## Existing modules in this theme
2629
2750
 
2630
2751
  These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
@@ -2645,101 +2766,44 @@ ${t.plan}
2645
2766
 
2646
2767
  ${i}`),r.join(`
2647
2768
 
2648
- `)}function ab(e,t){return e===0&&!t?"**Phase 1: UNDERSTAND.** This is the user's first message in plan mode. Acknowledge what they said, then ask 2\u20133 high-leverage questions to surface gaps. The plan block should be a skeleton with TBDs and an **Open questions** section. Do NOT propose specific sections or content yet \u2014 you don't know enough.":e===0&&t?`**Phase 1-T: TEMPLATED START.** The user picked a plan-mode template, so a structured plan already exists. Your job on this turn is to:
2769
+ `)}function TS(e,t){return e===0&&!t?"**Phase 1: UNDERSTAND.** This is the user's first message in plan mode. Acknowledge what they said, then ask 2\u20133 high-leverage questions to surface gaps. The plan block should be a skeleton with TBDs and an **Open questions** section. Do NOT propose specific sections or content yet \u2014 you don't know enough.":e===0&&t?`**Phase 1-T: TEMPLATED START.** The user picked a plan-mode template, so a structured plan already exists. Your job on this turn is to:
2649
2770
  - Briefly acknowledge the template and that you'll work from this structure (1\u20132 sentences in chat).
2650
2771
  - Pick 2\u20133 of the highest-leverage items from the plan's **Open questions** section and ask the user about them. Prefer questions about: product/page name + one-line pitch, primary CTA, and target audience. Save tone/visual questions for later turns.
2651
2772
  - Do NOT propose new sections or rewrite the existing structure on this turn \u2014 the user explicitly chose this scaffold. Keep the plan block VERBATIM (same headings, same sections, same open-questions list) and only re-emit it.
2652
2773
  - If the user's first message already supplies content (e.g. "It's for Acme, a fintech startup, primary CTA is book a demo"), thread that into the plan's TBDs and check those items off the **Open questions** list before asking your follow-ups.
2653
- - Use \`vibespot-choices\` chips when one of your questions is multiple-choice (e.g. "Primary CTA?", "Cuisine?").`:e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function Zr(e,t){return e.length<=t?e:e.slice(0,t)+`
2654
- ... [truncated]`}var vu=N(()=>{"use strict";y()});var ra={};Ge(ra,{applyPipelineResult:()=>cn,handleAgenticGenerate:()=>Qo,handleFigmaImport:()=>Rs,handleGenerate:()=>lb,handleGenerateStream:()=>Ns,handlePlanModeStream:()=>sa,isGenerating:()=>Kt,isPlanModeActive:()=>oa,resolveAgenticEngine:()=>Gn,setParseWarningCallback:()=>ta,shouldUseAgenticMode:()=>ia});import{execSync as Qr}from"child_process";function ta(e){ea=e}function Kt(){return Ot!==null}function wt(e){if(Ot){let t=C();if(!t||t.id!==Ot){E.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}lt("assistant",e),Zc(e,ea||void 0),L()}async function Ns(e,t,n,s){let o=C();if(!o)throw new Error("No active session");Ot=o.id;let r=s?.length?Ko(s):void 0;try{let a=R(),l=a.aiEngine||na();switch(l){case"anthropic-api":case"api":{let c=Fe("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await _r(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,wt,r);break}case"claude-oauth":{await ld(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,wt,r);break}case"openai-api":{let c=Fe("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await $r(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,wt,r);break}case"gemini-api":{let c=Fe("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await Er(e,c,o.themeName,t,n,wt,r);break}case"claude-code":await cd(e,o.themeName,t,n,wt,r);break;case"gemini-cli":await Nr("gemini",e,o.themeName,t,n,wt,r);break;case"codex-cli":await Nr("codex",e,o.themeName,t,n,wt,r);break;case"langdock-api":{let c=Fe("langdock-api",a);if(!c)throw new Error("Langdock API key not configured. Open Settings to add one.");let d=a.langdockProvider||"anthropic",u={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},m=a.langdockBaseUrl||u[d],g=a.langdockApiModel;switch(d){case"openai":case"mistral":await $r(e,c,o.themeName,g||"gpt-4.1",t,n,wt,r,`${m}/v1/chat/completions`);break;case"google":await Er(e,c,o.themeName,t,n,wt,r,`${m}/v1beta/models/${g||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,g);break;default:await _r(e,c,o.themeName,g||"claude-sonnet-4-6",t,n,wt,r,m);break}break}default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{Ot=null,ea=null}}function na(){let e=R();if(Ze())return"claude-oauth";if(e.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(e.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(e.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return Qr("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return Qr("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return Qr("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function lb(e){let t="";return await Ns(e,n=>{t+=n}),t}function xu(){let e=C(),t=ke(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder],o={modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,contentMode:t?.contentMode,brandAssets:e.brandAssets?{...e.brandAssets}:void 0};return e.templates.length>1&&(o.activePageLabel=t?.label,o.sitePages=e.templates.map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))),o}function Gn(e){let t=e.aiEngine||na();if(!_s(t))throw new Error("Agentic pipeline is not available for this engine.");if(Un(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Ze())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=Fe(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=e.geminiApiModel||"gemini-2.5-pro";break;case"langdock-api":{let o={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-flash",mistral:"mistral-large-latest"};s=e.langdockApiModel||o[e.langdockProvider||"anthropic"];break}case"claude-code":s=e.claudeCodeModel||"";break;case"codex-cli":s=e.codexCliModel||"";break;case"gemini-cli":s=e.geminiCliModel||"";break;default:s=""}return{engine:t,apiKey:n,model:s}}async function Qo(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=s.id;Ot=o;try{let i=R(),{engine:r,apiKey:a,model:l}=Gn(i),c=i.agenticConcurrency||20,d=xu(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
2774
+ - Use \`vibespot-choices\` chips when one of your questions is multiple-choice (e.g. "Primary CTA?", "Cuisine?").`:e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function _a(e,t){return e.length<=t?e:e.slice(0,t)+`
2775
+ ... [truncated]`}var mm=R(()=>{"use strict";y()});var Aa={};We(Aa,{applyPipelineResult:()=>yn,cancelActiveGeneration:()=>Ma,handleAgenticGenerate:()=>vi,handleAgenticResume:()=>Oa,handleFigmaImport:()=>Ys,handleGenerate:()=>_S,handleGenerateStream:()=>zs,handlePlanModeStream:()=>Fa,isGenerating:()=>$t,isPlanModeActive:()=>Da,resolveAgenticEngine:()=>hn,setParseWarningCallback:()=>Ea,shouldUseAgenticMode:()=>ja});import{execSync as $a}from"child_process";function Ea(e){Pa=e}function $t(){return gt!==null}function pm(){let e={id:++AS,abort:new AbortController};return Vs=e,{run:e,signal:e.abort.signal}}function gm(e){Vs===e&&(Vs=null)}function Ma(){return Vs?(Vs.abort.abort(),!0):!1}function _t(e){if(gt){let t=w();if(!t||t.id!==gt){T.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}dt("assistant",e),Td(e,Pa||void 0),F()}async function zs(e,t,n,s){let o=w();if(!o)throw new Error("No active session");gt=o.id;let r=s?.length?ii(s):void 0;try{let a=N(),l=a.aiEngine||Ia();switch(l){case"anthropic-api":case"api":{let c=De("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await Hr(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,_t,r);break}case"claude-oauth":{await Od(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,_t,r);break}case"openai-api":{let c=De("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await Ur(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,_t,r);break}case"gemini-api":{let c=De("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await Gr(e,c,o.themeName,t,n,_t,r);break}case"claude-code":await Fd(e,o.themeName,t,n,_t,r);break;case"gemini-cli":await zr("gemini",e,o.themeName,t,n,_t,r);break;case"codex-cli":await zr("codex",e,o.themeName,t,n,_t,r);break;case"langdock-api":{let c=De("langdock-api",a);if(!c)throw new Error("Langdock API key not configured. Open Settings to add one.");let d=a.langdockProvider||"anthropic",u={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},m=a.langdockBaseUrl||u[d],g=a.langdockApiModel;switch(d){case"openai":case"mistral":await Ur(e,c,o.themeName,g||"gpt-4.1",t,n,_t,r,`${m}/v1/chat/completions`);break;case"google":await Gr(e,c,o.themeName,t,n,_t,r,`${m}/v1beta/models/${g||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,g);break;default:await Hr(e,c,o.themeName,g||"claude-sonnet-4-6",t,n,_t,r,m);break}break}default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{gt=null,Pa=null}}function Ia(){let e=N();if(tt())return"claude-oauth";if(e.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(e.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(e.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return $a("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return $a("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return $a("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function _S(e){let t="";return await zs(e,n=>{t+=n}),t}function Ra(){let e=w(),t=Te(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder],o={modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,contentMode:t?.contentMode,brandAssets:e.brandAssets?{...e.brandAssets}:void 0};return e.templates.length>1&&(o.activePageLabel=t?.label,o.sitePages=e.templates.map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))),o}function hn(e){let t=e.aiEngine||Ia();if(!Fs(t))throw new Error("Agentic pipeline is not available for this engine.");if(Yn(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!tt())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=De(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=e.geminiApiModel||"gemini-2.5-pro";break;case"langdock-api":{let o={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-flash",mistral:"mistral-large-latest"};s=e.langdockApiModel||o[e.langdockProvider||"anthropic"];break}case"claude-code":s=e.claudeCodeModel||"";break;case"codex-cli":s=e.codexCliModel||"";break;case"gemini-cli":s=e.geminiCliModel||"";break;default:s=""}return{engine:t,apiKey:n,model:s}}function Na(e){let t=e.multiPage;return{modules:e.modules.map(n=>n.moduleName),moduleCount:e.modules.length,moduleOrder:e.moduleOrder,stats:e.stats,...t?{pages:t.pages.map(n=>n.pageId)}:{},assistantMessage:e.assistantMessage}}async function vi(e,t,n,s=!1){let o=w();if(!o)throw new Error("No active session");let i=o.id;gt=i;let{run:r,signal:a}=pm();try{let l=N(),{engine:c,apiKey:d,model:u}=hn(l),m=l.agenticConcurrency||20,g=Ra(),h=g.brandAssets?.plan,f=e;h&&h.trim()&&(f=`## Approved plan
2655
2776
 
2656
2777
  Build the page according to this plan exactly. The user reviewed and approved it; do not deviate from its goal, audience, sections, or content unless the user message below explicitly requests changes.
2657
2778
 
2658
- ${u}
2779
+ ${h}
2659
2780
 
2660
2781
  ---
2661
2782
 
2662
2783
  ## User message
2663
2784
 
2664
- ${e}`);let g=n?.length?Ko(n):void 0;if(g?.length)for(let M of g)M.type==="document"&&M.extractedText&&(m+=`
2785
+ ${e}`);let b=n?.length?ii(n):void 0;if(b?.length)for(let J of b)J.type==="document"&&J.extractedText&&(f+=`
2665
2786
 
2666
2787
  ---
2667
- [Attached document: ${M.originalName}]
2668
- ${M.extractedText}`),M.type==="image"&&M.usage==="asset"&&M.assetPath&&(m+=`
2788
+ [Attached document: ${J.originalName}]
2789
+ ${J.extractedText}`),J.type==="image"&&J.usage==="asset"&&J.assetPath&&(f+=`
2669
2790
 
2670
- [Uploaded image: ${M.originalName} \u2192 available as get_asset_url("${M.assetPath}")]`);let h=Nt(),f=new Set(d.modules.map(M=>M.moduleName)),b=h.filter(M=>!f.has(M.module.moduleName)).map(M=>({name:M.module.moduleName,usedIn:M.usedIn})),{result:S,cost:v}=await Qi(()=>tt({name:"agent_pipeline",sessionId:d.themeName,input:e,metadata:{engine:r,model:l,concurrency:c},tags:["vibespot","agentic-pipeline"]},()=>uu(m,d,r,a,l,c,t,b)));S.cost=v;let w=C();if(!w||w.id!==o)throw E.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return S}finally{Ot=null}}async function Rs(e,t,n,s){let o=C();if(!o)throw new Error("No active session");let i=o.id;Ot=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(bu(),yu)),a=R(),{engine:l,apiKey:c,model:d}=Gn(a),u=a.agenticConcurrency||20,m=xu(),{result:g,cost:h}=await Qi(()=>tt({name:"figma_import",sessionId:t,input:{fileName:e.fileName,sections:e.sections.length},metadata:{engine:l,model:d,concurrency:u},tags:["vibespot","figma-import"]},()=>r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets)));g.cost=h;let f=C();if(!f||f.id!==i)throw E.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{Ot=null}}function cn(e,t){let n=e.multiPage;if(n&&n.pages.length>0){let s=new Map;for(let o of n.pages)s.set(o.pageId,{label:o.label||o.pageId,pageType:o.pageType||"website_page"});Sc({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(He({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Ht(e.moduleOrder),e.contentType==="email"){let o=ke();o&&!o.contentMode&&(o.contentMode="email")}t?.cost&&gc(t.cost),lt("assistant",e.assistantMessage,t),L()}async function sa(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=R(),{engine:i,apiKey:r,model:a}=Gn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(vu(),Su)),Promise.resolve().then(()=>(dt(),vd))]),d=s.messages.filter(w=>w.role==="assistant").length,u=s.modules.map(w=>w.moduleName),m=Nt(),g=new Set(u),h=m.filter(w=>!g.has(w.module.moduleName)).map(w=>({name:w.module.moduleName,usedIn:w.usedIn})),f=l(s.themeName,s.brandAssets,u,h,d),b=n?.length?Ko(n):void 0,S=e;if(b?.length)for(let w of b)w.type==="document"&&w.extractedText&&(S+=`
2791
+ [Uploaded image: ${J.originalName} \u2192 available as get_asset_url("${J.assetPath}")]`);let S=Lt(),x=new Set(g.modules.map(J=>J.moduleName)),k=S.filter(J=>!x.has(J.module.moduleName)).map(J=>({name:J.module.moduleName,usedIn:J.usedIn})),{result:$,cost:L}=await _o(()=>ze({name:"agent_pipeline",sessionId:g.themeName,input:e,metadata:{engine:c,model:u,concurrency:m},tags:["vibespot","agentic-pipeline"]},async()=>{let J=await Xu(f,g,c,d,u,m,t,k,s,a);return Eo(Na(J)),J})).catch(J=>{if(Rs(J))return T.info("ai-handler","Agentic run cancelled (barge-in)"),{result:fm(g),cost:void 0};throw J});if($.cost=L,$.canceled)return $;let j=w();if(!j||j.id!==i)throw T.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return $}finally{gt=null,gm(r)}}function fm(e){return{modules:[...e.modules],moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,assistantMessage:"",canceled:!0,stats:{modulesGenerated:0,modulesUnchanged:e.modules.length,modulesFailed:0,durationMs:0}}}async function Oa(e,t,n,s){let o=w();if(!o)throw new Error("No active session");let i=o.id;gt=i;let{run:r,signal:a}=pm();try{let l=N(),{engine:c,apiKey:d,model:u}=hn(l),m=l.agenticConcurrency||20,g=Ra(),{result:h,cost:f}=await _o(()=>ze({name:"agent_pipeline_resume",sessionId:g.themeName,input:{action:t.action,kind:t.kind},metadata:{engine:c,model:u,concurrency:m},tags:["vibespot","agentic-pipeline","checkpoint-resume"]},async()=>{let S=await Qu(e,t,g,c,d,u,m,n,a,s);return Eo(Na(S)),S})).catch(S=>{if(Rs(S))return T.info("ai-handler","Checkpoint resume cancelled (barge-in)"),{result:fm(g),cost:void 0};throw S});if(h.cost=f,h.canceled)return h;let b=w();if(!b||b.id!==i)throw T.warn("ai-handler","Session changed during checkpoint resume \u2014 discarding output"),new Error("Session changed during generation");return h.brandAssetsUpdate&&(h.brandAssetsUpdate.styleguide&&bi(b,"styleguide",h.brandAssetsUpdate.styleguide),h.brandAssetsUpdate.brandvoice&&bi(b,"brandvoice",h.brandAssetsUpdate.brandvoice),F()),h}finally{gt=null,gm(r)}}async function Ys(e,t,n,s){let o=w();if(!o)throw new Error("No active session");let i=o.id;gt=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(dm(),cm)),a=N(),{engine:l,apiKey:c,model:d}=hn(a),u=a.agenticConcurrency||20,m=Ra(),{result:g,cost:h}=await _o(()=>ze({name:"figma_import",sessionId:t,input:{fileName:e.fileName,sections:e.sections.length},metadata:{engine:l,model:d,concurrency:u},tags:["vibespot","figma-import"]},async()=>{let b=await r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets);return Eo(Na(b)),b}));g.cost=h;let f=w();if(!f||f.id!==i)throw T.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{gt=null}}function yn(e,t){let n=e.multiPage;if(n&&n.pages.length>0){let s=new Map;for(let o of n.pages)s.set(o.pageId,{label:o.label||o.pageId,pageType:o.pageType||"website_page"});Kc({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(Ue({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Vt(e.moduleOrder),e.contentType==="email"){let o=Te();o&&!o.contentMode&&(o.contentMode="email")}t?.cost&&Jc(t.cost),dt("assistant",e.assistantMessage,t),F()}async function Fa(e,t,n){let s=w();if(!s)throw new Error("No active session");let o=N(),{engine:i,apiKey:r,model:a}=hn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(mm(),um)),Promise.resolve().then(()=>(mt(),Vd))]),d=s.messages.filter(k=>k.role==="assistant").length,u=s.modules.map(k=>k.moduleName),m=Lt(),g=new Set(u),h=m.filter(k=>!g.has(k.module.moduleName)).map(k=>({name:k.module.moduleName,usedIn:k.usedIn})),f=l(s.themeName,s.brandAssets,u,h,d),b=n?.length?ii(n):void 0,S=e;if(b?.length)for(let k of b)k.type==="document"&&k.extractedText&&(S+=`
2671
2792
 
2672
2793
  ---
2673
- [Attached document: ${w.originalName}]
2674
- ${w.extractedText}`);let v=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return v.type==="text"?v.text:JSON.stringify(v.data)}function oa(){return!!R().planMode}function ia(){let e=R(),t=e.aiEngine||na();return _s(t)?e.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:e.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var ea,Ot,Wn=N(()=>{"use strict";y();ee();Ce();Wo();le();er();Rr();_t();Dr();mu();Be();ea=null;Ot=null});import{readFileSync as cb,readdirSync as db,existsSync as ub}from"fs";import{dirname as mb,join as ei}from"path";import{fileURLToPath as pb}from"url";function fb(e){let t=e.match(gb);if(!t)return null;let[,n,s]=t,o={};for(let i of n.split(/\r?\n/)){let r=i.indexOf(":");if(r===-1)continue;let a=i.slice(0,r).trim(),l=i.slice(r+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),a&&(o[a]=l)}return{fields:o,body:s.trimStart()}}function hb(e){let t=fb(e);if(!t)return null;let{fields:n,body:s}=t,o=n.id,i=n.label,r=n.description??"";if(!o||!i)return null;let a=n.order?Number(n.order):NaN,l=n.contentType==="email"?"email":void 0;return{id:o,label:i,description:r,icon:n.icon||void 0,order:Number.isFinite(a)?a:9999,contentType:l,body:s.trimEnd()+`
2675
- `}}function yb(){let e=[ei(wu,"../../assets/plan-templates"),ei(wu,"../assets/plan-templates"),ei(process.cwd(),"assets/plan-templates")];for(let t of e)if(ub(t))return t;return null}function Cu(){if(Vt)return Vt;let e=yb();if(!e)return Vt=[],Vt;let t=[],n=[];try{n=db(e)}catch{return Vt=[],Vt}for(let s of n)if(s.endsWith(".md"))try{let o=cb(ei(e,s),"utf-8"),i=hb(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),Vt=t,Vt}function ku(e){return Cu().find(t=>t.id===e)??null}function Tu(){return Cu().map(({id:e,label:t,description:n,icon:s,order:o,contentType:i})=>({id:e,label:t,description:n,icon:s,order:o,contentType:i}))}var wu,gb,Vt,Au=N(()=>{"use strict";y();wu=mb(pb(import.meta.url)),gb=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;Vt=null});import{existsSync as _u,mkdirSync as bb,writeFileSync as Sb,rmSync as vb}from"fs";import{join as $u}from"path";function Eu(e){return $u(e,".vibespot",xb)}function ti(e){let t=C();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=ke();n&&(n.plan=e);try{let s=$u(t.themePath,".vibespot");_u(s)||bb(s,{recursive:!0}),Sb(Eu(t.themePath),e,"utf-8")}catch(s){E.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return L(),e}function aa(){let e=C();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=ke();t&&delete t.plan;try{let n=Eu(e.themePath);_u(n)&&vb(n)}catch(n){E.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}L()}function Mu(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(t,400,{error:"Plan content cannot be empty"});return}ti(o),p(t,200,{ok:!0,plan:o})})}function Iu(e,t){qe(e,t,()=>{aa(),Y({planMode:!1}),p(t,200,{ok:!0})})}function Pu(e,t){p(t,200,{templates:Tu()})}function Nu(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.templateId=="string"?n.templateId.trim():"";if(!o){p(t,400,{error:"templateId is required"});return}let i=ku(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}ti(i.body),Y({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var xb,Ru=N(()=>{"use strict";y();Xe();Ce();Ut();ee();le();Au();xb="plan.md"});function Ou(e){let t,n,s;for(la.lastIndex=0;(s=la.exec(e))!==null;)t=s[1].trim();let o;for(ca.lastIndex=0;(o=ca.exec(e))!==null;)try{let r=JSON.parse(o[1].trim());r&&typeof r.question=="string"&&Array.isArray(r.options)&&r.options.every(a=>typeof a=="string")&&r.options.length>0&&(n={question:r.question,options:r.options})}catch{}return{cleanedContent:e.replace(la,"").replace(ca,"").replace(/\n{3,}/g,`
2794
+ [Attached document: ${k.originalName}]
2795
+ ${k.extractedText}`);let x=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return x.type==="text"?x.text:JSON.stringify(x.data)}function Da(){return!!N().planMode}function ja(){let e=N(),t=e.aiEngine||Ia();return Fs(t)?e.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:e.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var Pa,gt,Vs,AS,qn=R(()=>{"use strict";y();oe();Ce();oi();de();$o();Yr();It();Zr();em();Ta();zn();He();Pa=null;gt=null;Vs=null,AS=0});import{readFileSync as $S,readdirSync as PS,existsSync as ES}from"fs";import{dirname as MS,join as xi}from"path";import{fileURLToPath as IS}from"url";function NS(e){let t=e.match(RS);if(!t)return null;let[,n,s]=t,o={};for(let i of n.split(/\r?\n/)){let r=i.indexOf(":");if(r===-1)continue;let a=i.slice(0,r).trim(),l=i.slice(r+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),a&&(o[a]=l)}return{fields:o,body:s.trimStart()}}function OS(e){let t=NS(e);if(!t)return null;let{fields:n,body:s}=t,o=n.id,i=n.label,r=n.description??"";if(!o||!i)return null;let a=n.order?Number(n.order):NaN,l=n.contentType==="email"?"email":void 0;return{id:o,label:i,description:r,icon:n.icon||void 0,order:Number.isFinite(a)?a:9999,contentType:l,body:s.trimEnd()+`
2796
+ `}}function FS(){let e=[xi(hm,"../../assets/plan-templates"),xi(hm,"../assets/plan-templates"),xi(process.cwd(),"assets/plan-templates")];for(let t of e)if(ES(t))return t;return null}function ym(){if(Zt)return Zt;let e=FS();if(!e)return Zt=[],Zt;let t=[],n=[];try{n=PS(e)}catch{return Zt=[],Zt}for(let s of n)if(s.endsWith(".md"))try{let o=$S(xi(e,s),"utf-8"),i=OS(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),Zt=t,Zt}function bm(e){return ym().find(t=>t.id===e)??null}function Sm(){return ym().map(({id:e,label:t,description:n,icon:s,order:o,contentType:i})=>({id:e,label:t,description:n,icon:s,order:o,contentType:i}))}var hm,RS,Zt,vm=R(()=>{"use strict";y();hm=MS(IS(import.meta.url)),RS=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;Zt=null});import{existsSync as xm,mkdirSync as DS,writeFileSync as jS,rmSync as LS}from"fs";import{join as wm}from"path";function km(e){return wm(e,".vibespot",BS)}function wi(e){let t=w();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=Te();n&&(n.plan=e);try{let s=wm(t.themePath,".vibespot");xm(s)||DS(s,{recursive:!0}),jS(km(t.themePath),e,"utf-8")}catch(s){T.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return F(),e}function La(){let e=w();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=Te();t&&delete t.plan;try{let n=km(e.themePath);xm(n)&&LS(n)}catch(n){T.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}F()}function Cm(e,t){Ze(e,t,n=>{if(!w()){p(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(t,400,{error:"Plan content cannot be empty"});return}wi(o),p(t,200,{ok:!0,plan:o})})}function Tm(e,t){Ze(e,t,()=>{La(),q({planMode:!1}),p(t,200,{ok:!0})})}function Am(e,t){p(t,200,{templates:Sm()})}function _m(e,t){Ze(e,t,n=>{if(!w()){p(t,400,{error:"No active session"});return}let o=typeof n.templateId=="string"?n.templateId.trim():"";if(!o){p(t,400,{error:"templateId is required"});return}let i=bm(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}wi(i.body),q({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var BS,$m=R(()=>{"use strict";y();Qe();Ce();zt();oe();de();vm();BS="plan.md"});function Pm(e){let t,n,s;for(Ba.lastIndex=0;(s=Ba.exec(e))!==null;)t=s[1].trim();let o;for(Ja.lastIndex=0;(o=Ja.exec(e))!==null;)try{let r=JSON.parse(o[1].trim());r&&typeof r.question=="string"&&Array.isArray(r.options)&&r.options.every(a=>typeof a=="string")&&r.options.length>0&&(n={question:r.question,options:r.options})}catch{}return{cleanedContent:e.replace(Ba,"").replace(Ja,"").replace(/\n{3,}/g,`
2676
2797
 
2677
- `).trim(),plan:t,choices:n}}var la,ca,Fu=N(()=>{"use strict";y();la=/```vibespot-plan\s*\n([\s\S]*?)```/g,ca=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as da}from"child_process";function Du(e,t,n){e.stdout?.on("data",o=>{t.output+=o.toString()}),e.stderr?.on("data",o=>{t.output+=o.toString()}),e.on("close",o=>{t.status=o===0?"completed":"failed",t.exitCode=o,t.completedAt=Date.now()}),e.on("error",o=>{t.status="failed",t.output+=`
2798
+ `).trim(),plan:t,choices:n}}var Ba,Ja,Em=R(()=>{"use strict";y();Ba=/```vibespot-plan\s*\n([\s\S]*?)```/g,Ja=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as Ha}from"child_process";function Mm(e,t,n){e.stdout?.on("data",o=>{t.output+=o.toString()}),e.stderr?.on("data",o=>{t.output+=o.toString()}),e.on("close",o=>{t.status=o===0?"completed":"failed",t.exitCode=o,t.completedAt=Date.now()}),e.on("error",o=>{t.status="failed",t.output+=`
2678
2799
  Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
2679
- Process timed out`,t.completedAt=Date.now())},n||3e5)}function Os(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};zt.set(o,i);let r=da(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&r.stdin&&(r.stdin.write(s.stdin),r.stdin.end()),Du(r,i,s?.timeout),o}function dn(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};zt.set(s,o);let i=e.split(" "),r=da(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Du(r,o,n?.timeout),s}function ni(e){return zt.get(e)}function wb(){let e=Date.now()-18e5;for(let[t,n]of zt)n.completedAt&&n.completedAt<e&&zt.delete(t)}function si(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};zt.set(s,o);let i=e.split(" "),r=da(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),a=c=>{for(let d of o.listeners)try{d(c)}catch{}};r.stdout?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.stderr?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),r.on("error",c=>{o.status="failed",o.output+=`
2800
+ Process timed out`,t.completedAt=Date.now())},n||3e5)}function qs(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};Qt.set(o,i);let r=Ha(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&r.stdin&&(r.stdin.write(s.stdin),r.stdin.end()),Mm(r,i,s?.timeout),o}function bn(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};Qt.set(s,o);let i=e.split(" "),r=Ha(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Mm(r,o,n?.timeout),s}function ki(e){return Qt.get(e)}function JS(){let e=Date.now()-18e5;for(let[t,n]of Qt)n.completedAt&&n.completedAt<e&&Qt.delete(t)}function Ci(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};Qt.set(s,o);let i=e.split(" "),r=Ha(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),a=c=>{for(let d of o.listeners)try{d(c)}catch{}};r.stdout?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.stderr?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),r.on("error",c=>{o.status="failed",o.output+=`
2680
2801
  Process error: ${c.message}`,o.completedAt=Date.now(),o.listeners.clear()});let l=n?.timeout||3e5;return setTimeout(()=>{o.status==="running"&&(r.kill(),o.status="failed",o.output+=`
2681
- Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function ju(e,t){let n=zt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Lu(e,t){let n=zt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var zt,oi=N(()=>{"use strict";y();zt=new Map;setInterval(wb,600*1e3)});import{readFileSync as Cb,readdirSync as kb,existsSync as Tb}from"fs";import{dirname as Ab,join as ii}from"path";import{fileURLToPath as _b}from"url";function $b(){let e=[ii(Ju,"../../starters"),ii(Ju,"../starters"),ii(process.cwd(),"starters")];for(let t of e)if(Tb(t))return t;return null}function Bu(){if(Kn!==null)return Kn;let e=$b();if(!e)return Kn=[],Kn;let t=[];for(let n of kb(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(Cb(ii(e,n),"utf-8"));t.push({id:s.id,name:s.name,description:s.description,category:s.category||"General",contentType:s.contentType==="email"?"email":void 0,modules:s.modules||[],moduleOrder:s.moduleOrder||[],sharedCss:s.sharedCss||"",sharedJs:s.sharedJs||""})}catch{}return Kn=t,Kn}function Hu(){return Bu().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function ua(e){return Bu().find(t=>t.id===e)||null}var Ju,Kn,Uu=N(()=>{"use strict";y();Ju=Ab(_b(import.meta.url)),Kn=null});var Ds={};Ge(Ds,{collectThemeFiles:()=>Wu,extractDesignContext:()=>Nb});import{existsSync as ri,readdirSync as ai,readFileSync as Eb}from"fs";import{join as Ct}from"path";import{spawn as Mb}from"child_process";async function Gu(){return ma||(ma=(await import("@anthropic-ai/sdk")).default),ma}function Fs(e){try{return Eb(e,"utf-8")}catch{return""}}function Wu(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2682
- ### ${a}
2683
- \`\`\`
2684
- ${l}
2685
- \`\`\`
2686
- `;return n+c.length>Ib?!1:(t.push(c),n+=c.length,!0)}let o=Fs(Ct(e,"theme.json"));o&&s("theme.json",o);let i=Ct(e,"css");if(ri(i)){for(let a of ai(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,Fs(Ct(i,a))))break}let r=Ct(e,"modules");if(ri(r))for(let a of ai(r).filter(l=>l.endsWith(".module"))){let l=Ct(r,a),c=Fs(Ct(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(ri(r))for(let a of ai(r).filter(l=>l.endsWith(".module"))){let l=Ct(r,a),c=Fs(Ct(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(ri(r))for(let a of ai(r).filter(l=>l.endsWith(".module"))){let l=Ct(r,a),c=Fs(Ct(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function Pb(){if(!li)try{li=P(hn("extraction-prompt.md"))}catch{li=""}return li}function pa(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=Mb(e,t,{stdio:["pipe","pipe","pipe"],env:i,shell:!0}),a="",l="";r.stdout.on("data",c=>{a+=c.toString()}),r.stderr.on("data",c=>{l+=c.toString()}),r.on("error",c=>o(new Error(`${e} failed to start: ${c.message}`))),r.on("close",c=>{c===0||a.trim()?s(a.trim()):o(new Error(`${e} exited with code ${c}: ${l.trim()}`))}),r.stdin.write(n),r.stdin.end()})}async function Nb(e,t){t?.({status:"Collecting theme files..."});let n=Wu(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=Pb();if(!s)throw new Error("Extraction prompt not found (assets/extraction-prompt.md).");let o=`Analyze this HubSpot CMS theme and extract the design system:
2687
- ${n}`;t?.({status:"Analyzing design patterns..."});let i=R(),r=i.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(r){case"anthropic-api":case"api":{let u=Fe("anthropic-api");if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");let m=await Gu(),g=new m({apiKey:u});d=i.anthropicApiModel||"claude-sonnet-4-6";let h=await g.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=h.content.map(f=>f.type==="text"?f.text:"").join(""),c=et(h.usage);break}case"claude-oauth":{let{getValidAccessToken:u,OAUTH_EXTRA_HEADERS:m,OAUTH_SYSTEM_PREFIX:g}=await Promise.resolve().then(()=>(_t(),Di)),h=await u();if(!h)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let f=await Gu(),b=new f({authToken:h,defaultHeaders:m});d=i.anthropicApiModel||"claude-sonnet-4-6";let S=await b.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:g},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=S.content.map(v=>v.type==="text"?v.text:"").join(""),c=et(S.usage);break}case"openai-api":{let u=Fe("openai-api");if(!u)throw new Error("OpenAI API key not configured. Open Settings to add one.");d=i.openaiApiModel||"gpt-4o";let m=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`},body:JSON.stringify({model:d,max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!m.ok)throw new Error(`OpenAI API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.choices?.[0]?.message?.content||"",c=_n(g.usage);break}case"gemini-api":{let u=Fe("gemini-api");if(!u)throw new Error("Gemini API key not configured. Open Settings to add one.");d=i.geminiApiModel||"gemini-2.5-flash";let m=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${d}:generateContent?key=${u}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!m.ok)throw new Error(`Gemini API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.candidates?.[0]?.content?.parts?.map(h=>h.text).join("")||"",c=$n(g.usageMetadata);break}case"claude-code":{let u=`${s}
2688
-
2689
- ## User Request
2690
- ${o}`,m=["--print"];i.claudeCodeModel&&m.push("--model",i.claudeCodeModel),a=await pa("claude",m,u);break}case"gemini-cli":{let u=`${s}
2691
-
2692
- ## User Request
2693
- ${o}`;a=await pa("gemini",[],u);break}case"codex-cli":{let u=`${s}
2694
-
2695
- ## User Request
2696
- ${o}`;a=await pa("codex",[],u);break}default:throw new Error(`Unknown AI engine: ${r}. Open Settings to configure one.`)}if(!a.trim())throw new Error("AI returned empty response.");return d&&St({engine:r,model:d,name:"styleguide-extraction",input:{system:s,messages:[{role:"user",content:o}]},output:a,usage:c,startTime:l,endTime:new Date}),t?.({status:"Design extraction complete."}),a}var ma,Ib,li,js=N(()=>{"use strict";y();oe();ee();Be();tn();ma=null;Ib=8e4;li=""});var ga={};Ge(ga,{extractBrandvoice:()=>Rb});async function Rb(e,t,n,s){if(!e||e.length<50)return null;let o=`You are a brand strategist. Analyze the rendered landing page HTML below and extract a concise brand voice guide. The HTML contains the actual text content with all template variables resolved to their default values.
2697
-
2698
- Return a markdown document with these sections (skip any section where the content provides no signal):
2699
-
2700
- ## Tone
2701
- Overall communication style (e.g., confident but approachable, technical but clear, playful, authoritative).
2702
-
2703
- ## Voice Characteristics
2704
- 3-5 bullet points describing how this brand "sounds" (e.g., "Uses short, punchy sentences", "Addresses reader directly with 'you'").
2705
-
2706
- ## Vocabulary
2707
- - **Preferred words**: Terms used repeatedly or intentionally
2708
- - **Avoided patterns**: Any notable absences or anti-patterns
2709
-
2710
- ## Sentence Style
2711
- Typical sentence length, structure, use of questions, imperatives, etc.
2712
-
2713
- ## Dos and Don'ts
2714
- 3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
2715
-
2716
- Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Pe(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),r=i.type==="text"?i.text:JSON.stringify(i.data);return!r||r.trim().length<20?null:(E.info("brandvoice-extractor",`Extracted brand voice (${r.length} chars)`),r.trim())}catch(i){let r=i instanceof Error?i.message:String(i);return E.warn("brandvoice-extractor",`Brand voice extraction failed: ${r}`),null}}var fa=N(()=>{"use strict";y();dt();le()});var ci={};Ge(ci,{extractThemeContext:()=>Ob});async function Ob(e,t,n,s,o){if(!e||e.length<50)return null;let r=`You are a content analyst. Extract a concise product/company brief from the rendered landing page HTML below. The HTML contains the actual text content (headings, paragraphs, button labels, image alt text, etc.) with all template variables resolved to their default values.
2717
-
2718
- Return a markdown document with these sections (skip any section where the content provides no information):
2719
-
2720
- ## Product / Company
2721
- Name, one-line description, and what it does.
2722
-
2723
- ## Value Propositions
2724
- Key benefits or features (bulleted list).
2725
-
2726
- ## Target Audience
2727
- Who this product/service is for.
2728
-
2729
- ## Tone & Voice
2730
- Communication style (e.g., professional, casual, technical, friendly).
2731
-
2732
- ## Key Terminology
2733
- Specific terms, product names, or branded language used consistently.
2734
-
2735
- Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
2736
-
2737
- Existing product context (update if the new content adds info, keep what's still accurate):
2738
- ${t}`:""}`;try{let a=await Pe(n,s,o,{systemPrompt:r,messages:[{role:"user",content:e}],maxTokens:1e3}),l=a.type==="text"?a.text:JSON.stringify(a.data);return!l||l.trim().length<20?null:(E.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return E.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var di=N(()=>{"use strict";y();dt();le()});import{join as Ku}from"path";function Fb(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function Db(e,t,n){e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Ku(e.themePath,".vibespot");Re(o),B(Ku(o,s),n)}async function Vu(e,t){let n=Fb(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:tt({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>jb(e,t,n,s))}async function jb(e,t,n,s){let o=Lb(t)?t:{...await Jb(e),...t??{}};n.includes("styleguide")&&await ha(e,"styleguide",s,()=>te("extract-styleguide",()=>o.extractStyleguide(e)));let i=n.filter(a=>a==="brandvoice"||a==="themeContext");if(i.length===0)return s;let r="";try{r=o.buildPreviewHtml()}catch(a){let l=a instanceof Error?a.message:String(a);for(let c of i)s.skipped.push(c),s.errors.push({asset:c,message:`Could not render preview HTML: ${l}`});return s}if(!r||r.length<50){for(let a of i)s.skipped.push(a);return s}return n.includes("brandvoice")&&await ha(e,"brandvoice",s,()=>te("extract-brandvoice",()=>o.extractBrandvoice(e,r))),n.includes("themeContext")&&await ha(e,"themeContext",s,()=>te("extract-theme-context",()=>o.extractThemeContext(e,r))),s}async function ha(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}Db(e,t,o),n.extracted.push(t)}catch(o){let i=o instanceof Error?o.message:String(o);n.skipped.push(t),n.errors.push({asset:t,message:i}),E.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function Lb(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function Jb(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(js(),Ds)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(Ss(),Go)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Wn(),ra)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(fa(),ga)),{extractThemeContext:i}=await Promise.resolve().then(()=>(di(),ci)),r=R();return{extractStyleguide:()=>t(e.themePath),buildPreviewHtml:n,extractBrandvoice:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return o(l,c,d,u)},extractThemeContext:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return i(l,a.brandAssets?.themeContext,c,d,u)}}}var zu=N(()=>{"use strict";y();oe();ee();le();Be()});import{existsSync as Vn,readdirSync as Yu,rmSync as Bb,writeFileSync as un,mkdirSync as ui}from"fs";import{join as Ne,basename as Hb}from"path";import{homedir as Ub}from"os";import{execFileSync as Xu}from"child_process";function pi(){if(mi&&Date.now()-mi.ts<Gb)return mi.data;let e=[];if(Vn(ut))try{for(let t of Yu(ut,{withFileTypes:!0}))if(t.isDirectory()){let n=Ne(ut,t.name,"theme.json");if(Vn(n)){let s=0,o=Ne(ut,t.name,"modules");if(Vn(o))try{s=Yu(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return mi={data:e,ts:Date.now()},e}function Qu(e){let t=C(),n=so(),s=!1;try{Xu("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Zu}),s=!0}catch{}let o=On().sort((r,a)=>a.updatedAt-r.updatedAt),i=pi();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length,isImported:!!t.isImported}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i,contentMode:Ln()})}function em(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s,starterId:o,assetType:i}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let r=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!r){p(t,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Ne(ut,r);if(Re(ut),Vn(a)&&Bb(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!ua(o)){p(t,400,{error:`Starter template "${o}" not found`});return}os(a,r),Rn(a,r),o&&typeof o=="string"?(Wb(a,r,o),Te()):i==="email"&&(Pt("module_only","Email","email"),An(a,r)),L(),p(t,200,{ok:!0,themeName:r,themePath:a,starterId:o||void 0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Wb(e,t,n){let s=ua(n);if(!s)return;let o=C();if(!o)return;let i=s.contentType==="email",r=s.modules.map(u=>({...u})),a=[...s.moduleOrder],l=i?`email-${t}`:`lp-${t}`,c={id:l,label:`${s.name}`,pageType:i?"module_only":"landing_page",contentMode:i?"email":void 0,templateFile:i?"templates/email.html":`templates/${l}.html`,modules:r,moduleOrder:a,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};i&&An(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Ne(e,"modules");ui(d,{recursive:!0});for(let u of s.modules){let m=Ne(d,`${u.moduleName}.module`);ui(m,{recursive:!0}),un(Ne(m,"fields.json"),u.fieldsJson,"utf-8"),un(Ne(m,"meta.json"),u.metaJson,"utf-8"),un(Ne(m,"module.html"),u.moduleHtml,"utf-8"),un(Ne(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&un(Ne(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Ne(e,"css");ui(u,{recursive:!0}),un(Ne(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Ne(e,"js");ui(u,{recursive:!0}),un(Ne(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function tm(e){p(e,200,{starters:Hu()})}function nm(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Le(),r=R(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Ne(ut,a);Re(ut),r.hubspotUploadMode==="cli"||!i?(async()=>{Xu("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Zu});let c=await qu(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})})().catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})}):rs(i,o,l).then(async()=>{let c=await qu(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})}).catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}async function qu(e,t){Rn(e,t,{isImported:!0}),Uo(e),L();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await Vu(n),L()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function sm(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme path is required"});return}let o=s;if(Vn(o)||(o=Ne(ut,s)),!Vn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Hb(o);Rn(o,i),Uo(o),L(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:C()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function om(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Session ID is required"});return}let o=Do(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function im(e,t){W(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}Y({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function rm(e){let t=Le();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await ll(t);if(n.length===0){p(e,200,{themes:[]});return}let s=[],o=n.map(async a=>{let l=a.path||a.name;try{let c=await ro(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:a.name,path:l})}catch{}});await Promise.all(o),s.sort((a,l)=>a.name.localeCompare(l.name));let i=pi(),r=new Set(i.map(a=>a.name));p(e,200,{themes:s.map(a=>({...a,existsLocally:r.has(a.name)}))})})().catch(n=>{p(e,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}var Zu,ut,mi,Gb,gi=N(()=>{"use strict";y();Xe();ee();is();uo();en();Ce();Ut();Wn();Qt();ee();oe();Uu();vs();zu();Zu=process.platform==="win32"?{shell:!0}:{},ut=Ne(Ub(),"vibespot-themes"),mi=null,Gb=5e3});import{existsSync as Kb,readFileSync as Vb,appendFileSync as zb}from"fs";import{join as am}from"path";import{homedir as lm}from"os";function Xb(e){let t=e.match(/^gpt-(\d+(?:\.\d+)?)(?:-(.+))?$/);if(t){let n=t[1],s=t[2];if(!s)return`GPT-${n}`;let o=s.replace(/-/g," ").replace(/\b\w/g,i=>i.toUpperCase());return`GPT-${n} ${o}`}return e.startsWith("codex-")?`Codex ${e.slice(6).replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}`:/^o\d/.test(e)?e.replace(/-/g," "):e}async function ba(e,t={},n=pm){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function Zb(e){let t=await ba("https://api.anthropic.com/v1/models",{headers:{"x-api-key":e,"anthropic-version":"2023-06-01"}});return t.ok?(await t.json()).data.filter(s=>!s.id.startsWith("claude-3-")&&!s.id.startsWith("claude-2")).map(s=>({id:s.id,label:s.display_name})):[]}async function Qb(e){let t=await ba("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function dm(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:Xb(n)}))}async function eS(e){let t=await ba(`https://generativelanguage.googleapis.com/v1beta/models?key=${e}`);return t.ok?(await t.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function tS(e=!1){if(!e&&Date.now()-zn.ts<Yb&&Object.keys(zn.data).length>0)return zn.data;let t=R(),n={...ya},s=[],o=Fe("anthropic-api",t);o&&s.push(Zb(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c,n["claude-code"]=c)}).catch(()=>{}));let i=Fe("openai-api",t);i&&s.push(Qb(i).then(c=>{if(!c.length)return;let d=dm(c,mm);d.length&&(n["openai-api"]=d);let u=dm(c,qb);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let r=Fe("gemini-api",t);r&&s.push(eS(r).then(c=>{c.length&&(n["gemini-api"]=c,n["gemini-cli"]=c)}).catch(()=>{}));let a=!1;await Promise.race([Promise.all(s).then(()=>{a=!0}),new Promise(c=>setTimeout(c,pm+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=cm[l]||cm.anthropic,a&&(zn.data=n,zn.ts=Date.now()),n}function gm(e){let t=tl(),n=R(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,codexCliModel:n.codexCliModel||null,geminiCliModel:n.geminiCliModel||null,geminiApiModel:n.geminiApiModel||null,langdockApiModel:n.langdockApiModel||null,langdockBaseUrl:n.langdockBaseUrl||null,langdockProvider:n.langdockProvider||"anthropic",hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(o=>({portalId:o.portalId,portalName:o.portalName,dataCenter:o.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null,langfuseEnabled:n.langfuseEnabled,langfuseBaseUrl:n.langfuseBaseUrl||null};p(e,200,{version:yn(),environment:t,config:s,models:ya,sessionCount:On().length,localThemeCount:pi().length})}function fm(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");tS(n).then(s=>p(t,200,{models:s})).catch(()=>p(t,200,{models:ya}))}function hm(e,t){let n=new URL(e.url||"/","http://localhost"),s=n.searchParams.get("group")||"all",o=s==="ai"||s==="platform"?s:"all",i=n.searchParams.get("refresh")==="1",r=um[o];if(!i&&Date.now()-r.ts<nS&&Object.keys(r.data).length>0){p(t,200,{...r.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=nl();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:sl()};else{let l=so();a={tools:l.tools,availableEngines:l.availableEngines}}um[o]={data:a,ts:Date.now()},p(t,200,{...a,group:o,cached:!1})}function ym(e,t){W(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli","langdock-api"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let r={aiEngine:s};if(o)switch(s){case"claude-code":r.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":r.anthropicApiModel=o;break;case"openai-api":r.openaiApiModel=o;break;case"codex-cli":r.codexCliModel=o;break;case"gemini-cli":r.geminiCliModel=o;break;case"gemini-api":r.geminiApiModel=o;break;case"langdock-api":r.langdockApiModel=o;break}Y(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function bm(e,t){W(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"langdock":l.langdockApiKey="";break;case"figma":l.figmaToken="";break;case"langfuse-public":l.langfusePublicKey="";break;case"langfuse-secret":l.langfuseSecretKey="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"langdock":i.langdockApiKey=o;break;case"figma":i.figmaToken=o;break;case"langfuse-public":i.langfusePublicKey=o;break;case"langfuse-secret":i.langfuseSecretKey=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(i);let r=null;if(!R().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(Y({aiEngine:c}),r=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Sm(e,t){W(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let r=dn(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function vm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}"),o=R(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){io(s.personalAccessKey).then(r=>{qn(s.personalAccessKey,r.portalId,r.portalName,r.dataCenter),p(t,200,{ok:!0,portalName:r.portalName,portalId:r.portalId,dataCenter:r.dataCenter})}).catch(r=>{p(t,400,{error:r instanceof Error?r.message:String(r)})});return}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=Os("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:a});return}if(i==="api"){let r=o.hubspotAccounts||[];if(r.length>0&&!s.force){let a=r.find(l=>l.portalId===o.activeHubSpotAccount)||r[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ht();if(a.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function xm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}");if(!eo().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=to();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=Os("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=dn("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:r,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function wm(e,t){W(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((R().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Pi(s),p(t,200,{ok:!0});return}if(s){Ni(s),p(t,200,{ok:!0});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=Os("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=Os("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}}p(t,400,{error:"portalId required"})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Cm(e){let t=dn("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function km(e,t){W(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=dn("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=dn("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,Y({openaiApiKey:i}),process.platform!=="win32"){let r=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(r){let a=`export OPENAI_API_KEY="${r}"`,l=process.env.SHELL?.includes("zsh")?am(lm(),".zshrc"):am(lm(),".bashrc");try{(Kb(l)?Vb(l,"utf-8"):"").includes("OPENAI_API_KEY")||zb(l,`
2802
+ Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Im(e,t){let n=Qt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Rm(e,t){let n=Qt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var Qt,Ti=R(()=>{"use strict";y();Qt=new Map;setInterval(JS,600*1e3)});import{readFileSync as HS,readdirSync as US,existsSync as GS}from"fs";import{dirname as WS,join as Ai}from"path";import{fileURLToPath as KS}from"url";function VS(){let e=[Ai(Nm,"../../starters"),Ai(Nm,"../starters"),Ai(process.cwd(),"starters")];for(let t of e)if(GS(t))return t;return null}function Om(){if(Xn!==null)return Xn;let e=VS();if(!e)return Xn=[],Xn;let t=[];for(let n of US(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(HS(Ai(e,n),"utf-8"));t.push({id:s.id,name:s.name,description:s.description,category:s.category||"General",contentType:s.contentType==="email"?"email":void 0,modules:s.modules||[],moduleOrder:s.moduleOrder||[],sharedCss:s.sharedCss||"",sharedJs:s.sharedJs||""})}catch{}return Xn=t,Xn}function Fm(){return Om().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function Ua(e){return Om().find(t=>t.id===e)||null}var Nm,Xn,Dm=R(()=>{"use strict";y();Nm=WS(KS(import.meta.url)),Xn=null});import{existsSync as Zn,readdirSync as jm,rmSync as zS,writeFileSync as Sn,mkdirSync as _i}from"fs";import{join as Me,basename as YS}from"path";import{homedir as qS}from"os";import{execFileSync as Bm}from"child_process";function Pi(){if($i&&Date.now()-$i.ts<XS)return $i.data;let e=[];if(Zn(ft))try{for(let t of jm(ft,{withFileTypes:!0}))if(t.isDirectory()){let n=Me(ft,t.name,"theme.json");if(Zn(n)){let s=0,o=Me(ft,t.name,"modules");if(Zn(o))try{s=jm(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return $i={data:e,ts:Date.now()},e}function Hm(e){let t=w(),n=ho(),s=!1;try{Bm("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Jm}),s=!0}catch{}let o=Hn().sort((r,a)=>a.updatedAt-r.updatedAt),i=Pi();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length,isImported:!!t.isImported}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i,contentMode:Wn()})}function Um(e,t){K(e,n=>{try{if($t()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s,starterId:o,assetType:i}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let r=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!r){p(t,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Me(ft,r);if(Ie(ft),Zn(a)&&zS(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!Ua(o)){p(t,400,{error:`Starter template "${o}" not found`});return}ds(a,r),Jn(a,r),o&&typeof o=="string"?(ZS(a,r,o),Ae()):i==="email"&&(jt("module_only","Email","email"),Nn(a,r)),F(),p(t,200,{ok:!0,themeName:r,themePath:a,starterId:o||void 0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function ZS(e,t,n){let s=Ua(n);if(!s)return;let o=w();if(!o)return;let i=s.contentType==="email",r=s.modules.map(u=>({...u})),a=[...s.moduleOrder],l=i?`email-${t}`:`lp-${t}`,c={id:l,label:`${s.name}`,pageType:i?"module_only":"landing_page",contentMode:i?"email":void 0,templateFile:i?"templates/email.html":`templates/${l}.html`,modules:r,moduleOrder:a,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};i&&Nn(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Me(e,"modules");_i(d,{recursive:!0});for(let u of s.modules){let m=Me(d,`${u.moduleName}.module`);_i(m,{recursive:!0}),Sn(Me(m,"fields.json"),u.fieldsJson,"utf-8"),Sn(Me(m,"meta.json"),u.metaJson,"utf-8"),Sn(Me(m,"module.html"),u.moduleHtml,"utf-8"),Sn(Me(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&Sn(Me(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Me(e,"css");_i(u,{recursive:!0}),Sn(Me(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Me(e,"js");_i(u,{recursive:!0}),Sn(Me(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function Gm(e){p(e,200,{starters:Fm()})}function Wm(e,t){K(e,n=>{try{if($t()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Be(),r=N(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Me(ft,a);Ie(ft),r.hubspotUploadMode==="cli"||!i?(async()=>{Bm("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Jm});let c=await Lm(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})})().catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})}):ms(i,o,l).then(async()=>{let c=await Lm(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})}).catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}async function Lm(e,t){Jn(e,t,{isImported:!0}),ni(e),F();let n=w(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await om(n),F()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function Km(e,t){K(e,n=>{try{if($t()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme path is required"});return}let o=s;if(Zn(o)||(o=Me(ft,s)),!Zn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=YS(o);Jn(o,i),ni(o),F(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:w()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Vm(e,t){K(e,n=>{try{if($t()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Session ID is required"});return}let o=Xo(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function zm(e,t){K(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}q({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ym(e){let t=Be();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Rl(t);if(n.length===0){p(e,200,{themes:[]});return}let s=[],o=n.map(async a=>{let l=a.path||a.name;try{let c=await So(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:a.name,path:l})}catch{}});await Promise.all(o),s.sort((a,l)=>a.name.localeCompare(l.name));let i=Pi(),r=new Set(i.map(a=>a.name));p(e,200,{themes:s.map(a=>({...a,existsLocally:r.has(a.name)}))})})().catch(n=>{p(e,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}var Jm,ft,$i,XS,Ei=R(()=>{"use strict";y();Qe();oe();us();ko();rn();Ce();zt();qn();on();oe();ae();Dm();$s();Ta();Jm=process.platform==="win32"?{shell:!0}:{},ft=Me(qS(),"vibespot-themes"),$i=null,XS=5e3});import{existsSync as QS,readFileSync as ev,appendFileSync as tv}from"fs";import{join as qm}from"path";import{homedir as Xm}from"os";function ov(e){let t=e.match(/^gpt-(\d+(?:\.\d+)?)(?:-(.+))?$/);if(t){let n=t[1],s=t[2];if(!s)return`GPT-${n}`;let o=s.replace(/-/g," ").replace(/\b\w/g,i=>i.toUpperCase());return`GPT-${n} ${o}`}return e.startsWith("codex-")?`Codex ${e.slice(6).replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}`:/^o\d/.test(e)?e.replace(/-/g," "):e}async function Wa(e,t={},n=np){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function iv(e){let t=await Wa("https://api.anthropic.com/v1/models",{headers:{"x-api-key":e,"anthropic-version":"2023-06-01"}});return t.ok?(await t.json()).data.filter(s=>!s.id.startsWith("claude-3-")&&!s.id.startsWith("claude-2")).map(s=>({id:s.id,label:s.display_name})):[]}async function rv(e){let t=await Wa("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function Qm(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:ov(n)}))}async function av(e){let t=await Wa(`https://generativelanguage.googleapis.com/v1beta/models?key=${e}`);return t.ok?(await t.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function lv(e=!1){if(!e&&Date.now()-Qn.ts<nv&&Object.keys(Qn.data).length>0)return Qn.data;let t=N(),n={...Ga},s=[],o=De("anthropic-api",t);o&&s.push(iv(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c,n["claude-code"]=c)}).catch(()=>{}));let i=De("openai-api",t);i&&s.push(rv(i).then(c=>{if(!c.length)return;let d=Qm(c,tp);d.length&&(n["openai-api"]=d);let u=Qm(c,sv);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let r=De("gemini-api",t);r&&s.push(av(r).then(c=>{c.length&&(n["gemini-api"]=c,n["gemini-cli"]=c)}).catch(()=>{}));let a=!1;await Promise.race([Promise.all(s).then(()=>{a=!0}),new Promise(c=>setTimeout(c,np+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=Zm[l]||Zm.anthropic,a&&(Qn.data=n,Qn.ts=Date.now()),n}function sp(e){let t=Al(),n=N(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,codexCliModel:n.codexCliModel||null,geminiCliModel:n.geminiCliModel||null,geminiApiModel:n.geminiApiModel||null,langdockApiModel:n.langdockApiModel||null,langdockBaseUrl:n.langdockBaseUrl||null,langdockProvider:n.langdockProvider||"anthropic",hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(o=>({portalId:o.portalId,portalName:o.portalName,dataCenter:o.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null,langfuseEnabled:n.langfuseEnabled,langfuseBaseUrl:n.langfuseBaseUrl||null};p(e,200,{version:Tn(),environment:t,config:s,models:Ga,sessionCount:Hn().length,localThemeCount:Pi().length})}function op(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");lv(n).then(s=>p(t,200,{models:s})).catch(()=>p(t,200,{models:Ga}))}function ip(e,t){let n=new URL(e.url||"/","http://localhost"),s=n.searchParams.get("group")||"all",o=s==="ai"||s==="platform"?s:"all",i=n.searchParams.get("refresh")==="1",r=ep[o];if(!i&&Date.now()-r.ts<cv&&Object.keys(r.data).length>0){p(t,200,{...r.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=_l();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:$l()};else{let l=ho();a={tools:l.tools,availableEngines:l.availableEngines}}ep[o]={data:a,ts:Date.now()},p(t,200,{...a,group:o,cached:!1})}function rp(e,t){K(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli","langdock-api"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let r={aiEngine:s};if(o)switch(s){case"claude-code":r.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":r.anthropicApiModel=o;break;case"openai-api":r.openaiApiModel=o;break;case"codex-cli":r.codexCliModel=o;break;case"gemini-cli":r.geminiCliModel=o;break;case"gemini-api":r.geminiApiModel=o;break;case"langdock-api":r.langdockApiModel=o;break}q(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function ap(e,t){K(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"langdock":l.langdockApiKey="";break;case"figma":l.figmaToken="";break;case"langfuse-public":l.langfusePublicKey="";break;case"langfuse-secret":l.langfuseSecretKey="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}q(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"langdock":i.langdockApiKey=o;break;case"figma":i.figmaToken=o;break;case"langfuse-public":i.langfusePublicKey=o;break;case"langfuse-secret":i.langfuseSecretKey=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}q(i);let r=null;if(!N().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(q({aiEngine:c}),r=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function lp(e,t){K(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let r=bn(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function cp(e,t){K(e,n=>{try{let s=JSON.parse(n||"{}"),o=N(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){bo(s.personalAccessKey).then(r=>{ns(s.personalAccessKey,r.portalId,r.portalName,r.dataCenter),p(t,200,{ok:!0,portalName:r.portalName,portalId:r.portalId,dataCenter:r.dataCenter})}).catch(r=>{p(t,400,{error:r instanceof Error?r.message:String(r)})});return}else{if(!St().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=qs("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:a});return}if(i==="api"){let r=o.hubspotAccounts||[];if(r.length>0&&!s.force){let a=r.find(l=>l.portalId===o.activeHubSpotAccount)||r[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!St().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=vt();if(a.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function dp(e,t){K(e,n=>{try{let s=JSON.parse(n||"{}");if(!po().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=go();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=qs("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=bn("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:r,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function up(e,t){K(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((N().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Yi(s),p(t,200,{ok:!0});return}if(s){qi(s),p(t,200,{ok:!0});return}}else{if(!St().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=qs("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=qs("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}}p(t,400,{error:"portalId required"})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function mp(e){let t=bn("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function pp(e,t){K(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=bn("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=bn("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,q({openaiApiKey:i}),process.platform!=="win32"){let r=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(r){let a=`export OPENAI_API_KEY="${r}"`,l=process.env.SHELL?.includes("zsh")?qm(Xm(),".zshrc"):qm(Xm(),".bashrc");try{(QS(l)?ev(l,"utf-8"):"").includes("OPENAI_API_KEY")||tv(l,`
2739
2803
  # Added by vibeSpot
2740
2804
  ${a}
2741
- `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=dn("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:p(t,400,{error:`Unknown CLI: ${s}`})}}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Tm(e,t){W(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}Y({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Am(e,t){W(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(t,400,{error:"toolId (string) and enabled (boolean) required"});return}Ri(s,o),p(t,200,{ok:!0,toolId:s,enabled:o})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function _m(e,t){W(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider","langfuseEnabled","langfuseBaseUrl"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langfuseEnabled!==void 0&&typeof s.langfuseEnabled!="boolean"){p(t,400,{error:"langfuseEnabled must be a boolean"});return}if(s.langfuseBaseUrl!==void 0&&typeof s.langfuseBaseUrl!="string"){p(t,400,{error:"langfuseBaseUrl must be a string"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){p(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(i.langdockProvider){let r={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};i.langdockApiModel=r[i.langdockProvider]||"",zn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}Y(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function $m(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=ni(n);if(!s){p(t,404,{error:"Job not found"});return}p(t,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}var zn,Yb,ya,cm,mm,qb,pm,nS,um,Em=N(()=>{"use strict";y();Xe();ee();Ce();gi();Qt();en();oe();oi();zn={data:{},ts:0},Yb=600*1e3,ya={"claude-code":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}],"codex-cli":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"},{id:"gpt-5.2-codex",label:"GPT-5.2 Codex"},{id:"gpt-5.1-codex-max",label:"GPT-5.1 Codex Max"},{id:"gpt-5.1-codex-mini",label:"GPT-5.1 Codex Mini"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"codex-mini-latest",label:"Codex Mini (latest)"}],"anthropic-api":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"claude-oauth":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"openai-api":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"}],"gemini-api":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],"gemini-cli":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}]},cm={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],openai:[{id:"gpt-4.1",label:"GPT-4.1 (default)"},{id:"gpt-4.1-mini",label:"GPT-4.1 Mini"},{id:"gpt-4.1-nano",label:"GPT-4.1 Nano"},{id:"gpt-4o",label:"GPT-4o"},{id:"o3-mini",label:"o3 Mini"}],google:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],mistral:[{id:"mistral-large-latest",label:"Mistral Large (default)"},{id:"mistral-medium-latest",label:"Mistral Medium"},{id:"mistral-small-latest",label:"Mistral Small"},{id:"codestral-latest",label:"Codestral"},{id:"pixtral-large-latest",label:"Pixtral Large"}]},mm=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,qb=mm;pm=2500;nS=60*1e3,um={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}}});function Mm(e,t){W(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"access_token is required"});return}Oi(s.trim(),(o||"").trim());let i=R();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&Y({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Im(e,t){let n=Ze(),s=Xt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Pm(e,t){try{qs(),R().aiEngine==="claude-oauth"&&Y({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var Nm=N(()=>{"use strict";y();Xe();ee();_t()});import{existsSync as sS,rmSync as oS}from"fs";import{join as iS}from"path";function Rm(e,t,n){if(e==="GET"){let s=C(),o=On().sort((i,r)=>r.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName,isImported:!!s.isImported}:null,sessions:o});return}if(e==="DELETE"){W(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);$c(o,i),p(n,200,{ok:!0})}catch(o){p(n,500,{error:o instanceof Error?o.message:String(o)})}});return}p(n,405,{error:"Method not allowed"})}function Om(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=Do(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Fm(e,t){W(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}if(/[\/\\]|\.\./.test(s)||s==="."||!s.replace(/[^a-z0-9]/gi,"")){p(t,400,{error:"Invalid theme name"});return}let o=iS(ut,s);if(!sS(o)){p(t,404,{error:"Theme not found on disk"});return}oS(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Dm(e,t){W(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){p(t,400,{error:"Invalid name"});return}let r=Ec(s,i);r.ok?p(t,200,{ok:!0,newName:i}):p(t,400,{error:r.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function jm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=Mc(s);o.ok?p(t,200,{ok:!0,newName:o.newName,newSessionId:o.newSessionId}):p(t,400,{error:o.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var Lm=N(()=>{"use strict";y();Xe();Ce();gi()});import{existsSync as fi,readFileSync as rS,readdirSync as aS,rmSync as Gm}from"fs";import{join as Oe,basename as lS,relative as cS,sep as dS}from"path";import uS from"jszip";function Wm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=Nt();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.contentMode==="email"?"email":s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1,hasBrandKit:!!t.brandAssets?.brandKit&&Object.keys(t.brandAssets.brandKit).length>0,brandKit:t.brandAssets?.brandKit||null}})}function Km(e,t=[]){for(let n of aS(e,{withFileTypes:!0}))if(n.isDirectory()){if(mS.has(n.name))continue;Km(Oe(e,n.name),t)}else n.isFile()&&t.push(Oe(e,n.name));return t}async function Vm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!fi(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=lS(n);try{let i=new uS;for(let a of Km(n)){let l=Oe(o,cS(n,a)).split(dS).join("/");i.file(l,rS(a))}let r=await i.generateAsync({type:"nodebuffer",compression:"DEFLATE",compressionOptions:{level:6}});e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${s}.zip"`,"Content-Length":r.length}),e.end(r)}catch(i){E.error("download-zip","Failed to create zip archive",i),p(e,500,{error:"Failed to create zip archive"})}}function zm(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.contentMode==="email"?"email":o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){W(t,o=>{try{let{pageType:i,label:r}=JSON.parse(o);if(!i||!r){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only","email"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=i==="email",d=Pt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&An(s.themePath,s.themeName),L(),p(n,200,{ok:!0,template:{id:d.id,label:d.label,pageType:d.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!kc(i,!!r)){p(n,404,{error:"Template not found"});return}L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function Ym(e,t){W(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!ms(s)){p(t,404,{error:"Template not found"});return}L();let i=C();p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function qm(e,t){W(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"templateId and newLabel are required"});return}if(!Cc(s,o.trim())){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Xm(e,t){W(e,n=>{try{let{templateIds:s}=JSON.parse(n);if(!Array.isArray(s)||s.some(i=>typeof i!="string")){p(t,400,{error:"templateIds must be an array of strings"});return}if(!wc(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}L(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Zm(e,t){W(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=xc(s,o);if(!i){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Qm(e){let t=Nt();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function ep(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}W(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=Nt().find(d=>d.module.moduleName===i);if(!a){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...a.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function tp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){W(t,o=>{try{let{type:i,content:r}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=r==="on",s.updatedAt=Date.now(),L(),p(n,200,{ok:!0});return}if(!r){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let a=i,l=a==="themeContext"?"theme-context.md":`${a}.md`;s.brandAssets[a]=r,s.updatedAt=Date.now();let c=Oe(s.themePath,".vibespot");Re(c),B(Oe(c,l),r);let d=null;a==="styleguide"&&(d=Sa(s,r)),L(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let r=i;s.brandAssets&&delete s.brandAssets[r],s.updatedAt=Date.now();let a=r==="themeContext"?"theme-context.md":`${r}.md`,l=Oe(s.themePath,".vibespot",a);fi(l)&&Gm(l),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function sp(e,t){p(t,200,np)}function gS(e){let t=[],n=[],s=e.split(`
2742
- `),o=!1,i=!1;for(let r of s){let a=r.trim();if(/^##\s+color/i.test(a)){o=!0,i=!1;continue}if(/^##\s+typography/i.test(a)){i=!0,o=!1;continue}if(/^##\s+/.test(a)&&!(/color/i.test(a)||/typography/i.test(a))){o=!1,i=!1;continue}if(o){let l=a.match(pS);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Jm.exec(a);if(Jm.lastIndex=0,l){let c=l[1].trim().replace(/['"`]/g,"").split(",")[0].trim();c&&!n.includes(c)&&n.push(c)}if(/\bheading|body|display|monospace\b/i.test(a)&&!l){let c=a.split(":").slice(1).join(":").trim();if(c){let d=c.replace(/['"`*]/g,"").split(",")[0].trim().split("(")[0].trim();d&&d.length<60&&!/^\d/.test(d)&&!n.includes(d)&&n.push(d)}}}}return{colors:t.slice(0,6),fonts:n.slice(0,4)}}function Sa(e,t){let{colors:n,fonts:s}=gS(t);if(n.length===0&&s.length===0)return null;e.brandAssets||(e.brandAssets={});let o=e.brandAssets.brandKit||{};if(n.length>0&&(o.colors||(o.colors={}),n[0]&&(o.colors.primary=n[0]),n[1]&&(o.colors.secondary=n[1]),n[2]&&(o.colors.accent=n[2])),s.length>0){o.fonts||(o.fonts={});let r=a=>{let l=a.toLowerCase(),c=np.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=r(s[0])),s[1]?o.fonts.body=r(s[1]):s[0]&&(o.fonts.body=r(s[0]))}e.brandAssets.brandKit=o;let i=Oe(e.themePath,".vibespot");return Re(i),B(Oe(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function op(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){W(t,o=>{try{let i=JSON.parse(o);s.brandAssets||(s.brandAssets={});let r={};if(i.colors&&typeof i.colors=="object"){let l={};for(let c of["primary","secondary","accent"])typeof i.colors[c]=="string"&&fS.test(i.colors[c])&&(l[c]=i.colors[c]);Object.keys(l).length>0&&(r.colors=l)}if(i.fonts&&typeof i.fonts=="object"){let l={};for(let c of["heading","body"])typeof i.fonts[c]=="string"&&i.fonts[c].trim()&&(l[c]=i.fonts[c].trim());Object.keys(l).length>0&&(r.fonts=l)}typeof i.logoUrl=="string"&&i.logoUrl.trim()&&(r.logoUrl=i.logoUrl.trim()),s.brandAssets.brandKit=r,s.updatedAt=Date.now();let a=Oe(s.themePath,".vibespot");Re(a),B(Oe(a,"brand-kit.json"),JSON.stringify(r,null,2)),L(),p(n,200,{ok:!0,brandKit:r})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Oe(s.themePath,".vibespot","brand-kit.json");fi(o)&&Gm(o),L(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Bm(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Oe(e.themePath,".vibespot");Re(o),B(Oe(o,s),n)}function Hm(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function Um(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(js(),Ds));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Wn(),ra)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),Ya)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Ss(),Go)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(fa(),ga));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(di(),ci));return u(d,e.brandAssets?.themeContext,r,a,l)}function ip(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",r=o.sourcePath;if(i==="all"){let c=["styleguide","brandvoice","themeContext"],d=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>te(Hm(g),()=>Um(n,g,r))))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Bm(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=Sa(n,u.styleguide)),L(),p(t,200,{ok:!0,type:"all",extracted:u,brandKit:m});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let a=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:i},tags:["vibespot","brand-extract"]},()=>te(Hm(i),()=>Um(n,i,r)));if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Bm(n,i,a);let l=null;i==="styleguide"&&(l=Sa(n,a)),L(),p(t,200,{ok:!0,type:i,content:a,brandKit:l})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function rp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:r}=JSON.parse(s),a;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Le();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),f=Oe(h(),"vibespot-themes",".references",g);Re(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(uo(),hl));await b(u,m,f),a=f}else if(o==="local"){if(!r){p(t,400,{error:"localPath is required for local import"});return}if(!fi(r)){p(t,400,{error:`Path not found: ${r}`});return}a=r}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(js(),Ds)),c=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Oe(n.themePath,".vibespot");Re(d),B(Oe(d,"styleguide.md"),c),L(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var mS,np,pS,Jm,fS,ap=N(()=>{"use strict";y();Xe();le();Be();ee();is();Ce();oe();mS=new Set([".git",".vibespot","node_modules"]);np=[{name:"System Default",stack:"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",category:"system"},{name:"Inter",stack:"Inter, system-ui, sans-serif",category:"sans-serif"},{name:"DM Sans",stack:"'DM Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Open Sans",stack:"'Open Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Roboto",stack:"Roboto, system-ui, sans-serif",category:"sans-serif"},{name:"Lato",stack:"Lato, system-ui, sans-serif",category:"sans-serif"},{name:"Montserrat",stack:"Montserrat, system-ui, sans-serif",category:"sans-serif"},{name:"Poppins",stack:"Poppins, system-ui, sans-serif",category:"sans-serif"},{name:"Nunito",stack:"Nunito, system-ui, sans-serif",category:"sans-serif"},{name:"Raleway",stack:"Raleway, system-ui, sans-serif",category:"sans-serif"},{name:"Work Sans",stack:"'Work Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Source Sans 3",stack:"'Source Sans 3', system-ui, sans-serif",category:"sans-serif"},{name:"Manrope",stack:"Manrope, system-ui, sans-serif",category:"sans-serif"},{name:"Plus Jakarta Sans",stack:"'Plus Jakarta Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Outfit",stack:"Outfit, system-ui, sans-serif",category:"sans-serif"},{name:"Space Grotesk",stack:"'Space Grotesk', system-ui, sans-serif",category:"sans-serif"},{name:"Albert Sans",stack:"'Albert Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Figtree",stack:"Figtree, system-ui, sans-serif",category:"sans-serif"},{name:"Helvetica",stack:"Helvetica, Arial, sans-serif",category:"sans-serif"},{name:"Arial",stack:"Arial, Helvetica, sans-serif",category:"sans-serif"},{name:"Verdana",stack:"Verdana, Geneva, sans-serif",category:"sans-serif"},{name:"Georgia",stack:"Georgia, 'Times New Roman', serif",category:"serif"},{name:"Playfair Display",stack:"'Playfair Display', Georgia, serif",category:"serif"},{name:"Merriweather",stack:"Merriweather, Georgia, serif",category:"serif"},{name:"Lora",stack:"Lora, Georgia, serif",category:"serif"},{name:"PT Serif",stack:"'PT Serif', Georgia, serif",category:"serif"},{name:"Libre Baskerville",stack:"'Libre Baskerville', Georgia, serif",category:"serif"},{name:"Source Serif 4",stack:"'Source Serif 4', Georgia, serif",category:"serif"},{name:"Cormorant Garamond",stack:"'Cormorant Garamond', Garamond, serif",category:"serif"},{name:"Times New Roman",stack:"'Times New Roman', Times, serif",category:"serif"},{name:"Sora",stack:"Sora, system-ui, sans-serif",category:"display"},{name:"Clash Display",stack:"'Clash Display', system-ui, sans-serif",category:"display"},{name:"Cabinet Grotesk",stack:"'Cabinet Grotesk', system-ui, sans-serif",category:"display"},{name:"Satoshi",stack:"Satoshi, system-ui, sans-serif",category:"display"},{name:"General Sans",stack:"'General Sans', system-ui, sans-serif",category:"display"},{name:"JetBrains Mono",stack:"'JetBrains Mono', 'Fira Code', monospace",category:"monospace"},{name:"Fira Code",stack:"'Fira Code', 'Courier New', monospace",category:"monospace"},{name:"Source Code Pro",stack:"'Source Code Pro', monospace",category:"monospace"},{name:"Courier New",stack:"'Courier New', Courier, monospace",category:"monospace"}];pS=/#[0-9a-fA-F]{6}\b/g,Jm=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;fS=/^#[0-9a-fA-F]{6}$/});import{join as hS}from"path";function lp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function cp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=ve();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){qe(t,n,o=>{o.deleteEntirely?fc(o.moduleName):hc(o.moduleName),L(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function dp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=ke();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:r,content:a}=o;if(!i||!r){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(r){case"html":l.moduleHtml=a;break;case"css":l.moduleCss=a;break;case"js":l.moduleJs=a||void 0;break;case"fields":try{JSON.parse(a)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:p(t,400,{error:`Invalid fileType: ${r}`});return}n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function up(e,t){qe(e,t,n=>{Array.isArray(n.order)?(Ht(n.order),L(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function mp(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}try{Te();let n=To(t.themePath),s=si(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:hS(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function pp(e,t){W(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);yc(s,o,i),L(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function gp(e,t){W(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=pl(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2805
+ `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=bn("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:p(t,400,{error:`Unknown CLI: ${s}`})}}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function gp(e,t){K(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}q({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function fp(e,t){K(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(t,400,{error:"toolId (string) and enabled (boolean) required"});return}Xi(s,o),p(t,200,{ok:!0,toolId:s,enabled:o})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function hp(e,t){K(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider","langfuseEnabled","langfuseBaseUrl"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langfuseEnabled!==void 0&&typeof s.langfuseEnabled!="boolean"){p(t,400,{error:"langfuseEnabled must be a boolean"});return}if(s.langfuseBaseUrl!==void 0&&typeof s.langfuseBaseUrl!="string"){p(t,400,{error:"langfuseBaseUrl must be a string"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){p(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(i.langdockProvider){let r={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};i.langdockApiModel=r[i.langdockProvider]||"",Qn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}q(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function yp(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=ki(n);if(!s){p(t,404,{error:"Job not found"});return}p(t,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}var Qn,nv,Ga,Zm,tp,sv,np,cv,ep,bp=R(()=>{"use strict";y();Qe();oe();Ce();Ei();on();rn();ae();Ti();Qn={data:{},ts:0},nv=600*1e3,Ga={"claude-code":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}],"codex-cli":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"},{id:"gpt-5.2-codex",label:"GPT-5.2 Codex"},{id:"gpt-5.1-codex-max",label:"GPT-5.1 Codex Max"},{id:"gpt-5.1-codex-mini",label:"GPT-5.1 Codex Mini"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"codex-mini-latest",label:"Codex Mini (latest)"}],"anthropic-api":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"claude-oauth":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"openai-api":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"}],"gemini-api":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],"gemini-cli":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}]},Zm={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],openai:[{id:"gpt-4.1",label:"GPT-4.1 (default)"},{id:"gpt-4.1-mini",label:"GPT-4.1 Mini"},{id:"gpt-4.1-nano",label:"GPT-4.1 Nano"},{id:"gpt-4o",label:"GPT-4o"},{id:"o3-mini",label:"o3 Mini"}],google:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],mistral:[{id:"mistral-large-latest",label:"Mistral Large (default)"},{id:"mistral-medium-latest",label:"Mistral Medium"},{id:"mistral-small-latest",label:"Mistral Small"},{id:"codestral-latest",label:"Codestral"},{id:"pixtral-large-latest",label:"Pixtral Large"}]},tp=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,sv=tp;np=2500;cv=60*1e3,ep={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}}});function Sp(e,t){K(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"access_token is required"});return}Zi(s.trim(),(o||"").trim());let i=N();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&q({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function vp(e,t){let n=tt(),s=nn();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function xp(e,t){try{lo(),N().aiEngine==="claude-oauth"&&q({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var wp=R(()=>{"use strict";y();Qe();oe();It()});import{existsSync as dv,rmSync as uv}from"fs";import{join as mv}from"path";function kp(e,t,n){if(e==="GET"){let s=w(),o=Hn().sort((i,r)=>r.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName,isImported:!!s.isImported}:null,sessions:o});return}if(e==="DELETE"){K(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);td(o,i),p(n,200,{ok:!0})}catch(o){p(n,500,{error:o instanceof Error?o.message:String(o)})}});return}p(n,405,{error:"Method not allowed"})}function Cp(e,t){K(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=Xo(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Tp(e,t){K(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}if(/[\/\\]|\.\./.test(s)||s==="."||!s.replace(/[^a-z0-9]/gi,"")){p(t,400,{error:"Invalid theme name"});return}let o=mv(ft,s);if(!dv(o)){p(t,404,{error:"Theme not found on disk"});return}uv(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Ap(e,t){K(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){p(t,400,{error:"Invalid name"});return}let r=nd(s,i);r.ok?p(t,200,{ok:!0,newName:i}):p(t,400,{error:r.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function _p(e,t){K(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=sd(s);o.ok?p(t,200,{ok:!0,newName:o.newName,newSessionId:o.newSessionId}):p(t,400,{error:o.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var $p=R(()=>{"use strict";y();Qe();Ce();Ei()});import{existsSync as Mi,readFileSync as pv,readdirSync as gv,rmSync as Rp}from"fs";import{join as Ne,basename as fv,relative as hv,sep as yv}from"path";import bv from"jszip";function Np(e){let t=w();if(!t){p(e,404,{error:"No active session"});return}let n=Lt();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.contentMode==="email"?"email":s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1,hasBrandKit:!!t.brandAssets?.brandKit&&Object.keys(t.brandAssets.brandKit).length>0,brandKit:t.brandAssets?.brandKit||null}})}function Op(e,t=[]){for(let n of gv(e,{withFileTypes:!0}))if(n.isDirectory()){if(Sv.has(n.name))continue;Op(Ne(e,n.name),t)}else n.isFile()&&t.push(Ne(e,n.name));return t}async function Fp(e){let t=w();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!Mi(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=fv(n);try{let i=new bv;for(let a of Op(n)){let l=Ne(o,hv(n,a)).split(yv).join("/");i.file(l,pv(a))}let r=await i.generateAsync({type:"nodebuffer",compression:"DEFLATE",compressionOptions:{level:6}});e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${s}.zip"`,"Content-Length":r.length}),e.end(r)}catch(i){T.error("download-zip","Failed to create zip archive",i),p(e,500,{error:"Failed to create zip archive"})}}function Dp(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.contentMode==="email"?"email":o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){K(t,o=>{try{let{pageType:i,label:r}=JSON.parse(o);if(!i||!r){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only","email"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=i==="email",d=jt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&Nn(s.themePath,s.themeName),F(),p(n,200,{ok:!0,template:{id:d.id,label:d.label,pageType:d.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){K(t,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Xc(i,!!r)){p(n,404,{error:"Template not found"});return}F(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function jp(e,t){K(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!vs(s)){p(t,404,{error:"Template not found"});return}F();let i=w();p(t,200,{ok:!0,modules:xe().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Lp(e,t){K(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"templateId and newLabel are required"});return}if(!qc(s,o.trim())){p(t,404,{error:"Template not found"});return}F(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Bp(e,t){K(e,n=>{try{let{templateIds:s}=JSON.parse(n);if(!Array.isArray(s)||s.some(i=>typeof i!="string")){p(t,400,{error:"templateIds must be an array of strings"});return}if(!Yc(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}F(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Jp(e,t){K(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=zc(s,o);if(!i){p(t,404,{error:"Template not found"});return}F(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Hp(e){let t=Lt();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Up(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}K(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=Lt().find(d=>d.module.moduleName===i);if(!a){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...a.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),F(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function Gp(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){K(t,o=>{try{let{type:i,content:r}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=r==="on",s.updatedAt=Date.now(),F(),p(n,200,{ok:!0});return}if(!r){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let a=i,l=a==="themeContext"?"theme-context.md":`${a}.md`;s.brandAssets[a]=r,s.updatedAt=Date.now();let c=Ne(s.themePath,".vibespot");Ie(c),H(Ne(c,l),r);let d=null;a==="styleguide"&&(d=Ka(s,r)),F(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){K(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let r=i;s.brandAssets&&delete s.brandAssets[r],s.updatedAt=Date.now();let a=r==="themeContext"?"theme-context.md":`${r}.md`,l=Ne(s.themePath,".vibespot",a);Mi(l)&&Rp(l),F(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function Kp(e,t){p(t,200,Wp)}function xv(e){let t=[],n=[],s=e.split(`
2806
+ `),o=!1,i=!1;for(let r of s){let a=r.trim();if(/^##\s+color/i.test(a)){o=!0,i=!1;continue}if(/^##\s+typography/i.test(a)){i=!0,o=!1;continue}if(/^##\s+/.test(a)&&!(/color/i.test(a)||/typography/i.test(a))){o=!1,i=!1;continue}if(o){let l=a.match(vv);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Pp.exec(a);if(Pp.lastIndex=0,l){let c=l[1].trim().replace(/['"`]/g,"").split(",")[0].trim();c&&!n.includes(c)&&n.push(c)}if(/\bheading|body|display|monospace\b/i.test(a)&&!l){let c=a.split(":").slice(1).join(":").trim();if(c){let d=c.replace(/['"`*]/g,"").split(",")[0].trim().split("(")[0].trim();d&&d.length<60&&!/^\d/.test(d)&&!n.includes(d)&&n.push(d)}}}}return{colors:t.slice(0,6),fonts:n.slice(0,4)}}function Ka(e,t){let{colors:n,fonts:s}=xv(t);if(n.length===0&&s.length===0)return null;e.brandAssets||(e.brandAssets={});let o=e.brandAssets.brandKit||{};if(n.length>0&&(o.colors||(o.colors={}),n[0]&&(o.colors.primary=n[0]),n[1]&&(o.colors.secondary=n[1]),n[2]&&(o.colors.accent=n[2])),s.length>0){o.fonts||(o.fonts={});let r=a=>{let l=a.toLowerCase(),c=Wp.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=r(s[0])),s[1]?o.fonts.body=r(s[1]):s[0]&&(o.fonts.body=r(s[0]))}e.brandAssets.brandKit=o;let i=Ne(e.themePath,".vibespot");return Ie(i),H(Ne(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function Vp(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){K(t,o=>{try{let i=JSON.parse(o);s.brandAssets||(s.brandAssets={});let r={};if(i.colors&&typeof i.colors=="object"){let l={};for(let c of["primary","secondary","accent"])typeof i.colors[c]=="string"&&wv.test(i.colors[c])&&(l[c]=i.colors[c]);Object.keys(l).length>0&&(r.colors=l)}if(i.fonts&&typeof i.fonts=="object"){let l={};for(let c of["heading","body"])typeof i.fonts[c]=="string"&&i.fonts[c].trim()&&(l[c]=i.fonts[c].trim());Object.keys(l).length>0&&(r.fonts=l)}typeof i.logoUrl=="string"&&i.logoUrl.trim()&&(r.logoUrl=i.logoUrl.trim()),s.brandAssets.brandKit=r,s.updatedAt=Date.now();let a=Ne(s.themePath,".vibespot");Ie(a),H(Ne(a,"brand-kit.json"),JSON.stringify(r,null,2)),F(),p(n,200,{ok:!0,brandKit:r})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Ne(s.themePath,".vibespot","brand-kit.json");Mi(o)&&Rp(o),F(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Ep(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Ne(e.themePath,".vibespot");Ie(o),H(Ne(o,s),n)}function Mp(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function Ip(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Ks(),Ws));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(qn(),Aa)),{loadConfig:o}=await Promise.resolve().then(()=>(oe(),vl)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(_s(),si)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(ka(),wa));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(yi(),hi));return u(d,e.brandAssets?.themeContext,r,a,l)}function zp(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}K(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",r=o.sourcePath;if(i==="all"){let c=["styleguide","brandvoice","themeContext"],d=await ze({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>se(Mp(g),()=>Ip(n,g,r))))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Ep(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=Ka(n,u.styleguide)),F(),p(t,200,{ok:!0,type:"all",extracted:u,brandKit:m});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let a=await ze({name:"brand_extract",sessionId:n.themeName,metadata:{type:i},tags:["vibespot","brand-extract"]},()=>se(Mp(i),()=>Ip(n,i,r)));if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Ep(n,i,a);let l=null;i==="styleguide"&&(l=Ka(n,a)),F(),p(t,200,{ok:!0,type:i,content:a,brandKit:l})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function Yp(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}K(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:r}=JSON.parse(s),a;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Be();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),f=Ne(h(),"vibespot-themes",".references",g);Ie(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(ko(),Jl));await b(u,m,f),a=f}else if(o==="local"){if(!r){p(t,400,{error:"localPath is required for local import"});return}if(!Mi(r)){p(t,400,{error:`Path not found: ${r}`});return}a=r}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(Ks(),Ws)),c=await ze({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>se("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ne(n.themePath,".vibespot");Ie(d),H(Ne(d,"styleguide.md"),c),F(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var Sv,Wp,vv,Pp,wv,qp=R(()=>{"use strict";y();Qe();de();He();oe();us();Ce();ae();Sv=new Set([".git",".vibespot","node_modules"]);Wp=[{name:"System Default",stack:"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",category:"system"},{name:"Inter",stack:"Inter, system-ui, sans-serif",category:"sans-serif"},{name:"DM Sans",stack:"'DM Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Open Sans",stack:"'Open Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Roboto",stack:"Roboto, system-ui, sans-serif",category:"sans-serif"},{name:"Lato",stack:"Lato, system-ui, sans-serif",category:"sans-serif"},{name:"Montserrat",stack:"Montserrat, system-ui, sans-serif",category:"sans-serif"},{name:"Poppins",stack:"Poppins, system-ui, sans-serif",category:"sans-serif"},{name:"Nunito",stack:"Nunito, system-ui, sans-serif",category:"sans-serif"},{name:"Raleway",stack:"Raleway, system-ui, sans-serif",category:"sans-serif"},{name:"Work Sans",stack:"'Work Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Source Sans 3",stack:"'Source Sans 3', system-ui, sans-serif",category:"sans-serif"},{name:"Manrope",stack:"Manrope, system-ui, sans-serif",category:"sans-serif"},{name:"Plus Jakarta Sans",stack:"'Plus Jakarta Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Outfit",stack:"Outfit, system-ui, sans-serif",category:"sans-serif"},{name:"Space Grotesk",stack:"'Space Grotesk', system-ui, sans-serif",category:"sans-serif"},{name:"Albert Sans",stack:"'Albert Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Figtree",stack:"Figtree, system-ui, sans-serif",category:"sans-serif"},{name:"Helvetica",stack:"Helvetica, Arial, sans-serif",category:"sans-serif"},{name:"Arial",stack:"Arial, Helvetica, sans-serif",category:"sans-serif"},{name:"Verdana",stack:"Verdana, Geneva, sans-serif",category:"sans-serif"},{name:"Georgia",stack:"Georgia, 'Times New Roman', serif",category:"serif"},{name:"Playfair Display",stack:"'Playfair Display', Georgia, serif",category:"serif"},{name:"Merriweather",stack:"Merriweather, Georgia, serif",category:"serif"},{name:"Lora",stack:"Lora, Georgia, serif",category:"serif"},{name:"PT Serif",stack:"'PT Serif', Georgia, serif",category:"serif"},{name:"Libre Baskerville",stack:"'Libre Baskerville', Georgia, serif",category:"serif"},{name:"Source Serif 4",stack:"'Source Serif 4', Georgia, serif",category:"serif"},{name:"Cormorant Garamond",stack:"'Cormorant Garamond', Garamond, serif",category:"serif"},{name:"Times New Roman",stack:"'Times New Roman', Times, serif",category:"serif"},{name:"Sora",stack:"Sora, system-ui, sans-serif",category:"display"},{name:"Clash Display",stack:"'Clash Display', system-ui, sans-serif",category:"display"},{name:"Cabinet Grotesk",stack:"'Cabinet Grotesk', system-ui, sans-serif",category:"display"},{name:"Satoshi",stack:"Satoshi, system-ui, sans-serif",category:"display"},{name:"General Sans",stack:"'General Sans', system-ui, sans-serif",category:"display"},{name:"JetBrains Mono",stack:"'JetBrains Mono', 'Fira Code', monospace",category:"monospace"},{name:"Fira Code",stack:"'Fira Code', 'Courier New', monospace",category:"monospace"},{name:"Source Code Pro",stack:"'Source Code Pro', monospace",category:"monospace"},{name:"Courier New",stack:"'Courier New', Courier, monospace",category:"monospace"}];vv=/#[0-9a-fA-F]{6}\b/g,Pp=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;wv=/^#[0-9a-fA-F]{6}$/});import{join as kv}from"path";function Xp(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function Zp(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=xe();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){Ze(t,n,o=>{o.deleteEntirely?Hc(o.moduleName):Uc(o.moduleName),F(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function Qp(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}K(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=Te();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),ct(),F(),Ae(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:r,content:a}=o;if(!i||!r){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(r){case"html":l.moduleHtml=a;break;case"css":l.moduleCss=a;break;case"js":l.moduleJs=a||void 0;break;case"fields":try{JSON.parse(a)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:p(t,400,{error:`Invalid fileType: ${r}`});return}n.updatedAt=Date.now(),ct(),F(),Ae(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function eg(e,t){Ze(e,t,n=>{Array.isArray(n.order)?(Vt(n.order),F(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function tg(e){let t=w();if(!t){p(e,404,{error:"No active session"});return}try{Ae();let n=Lo(t.themePath),s=Ci(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:kv(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function ng(e,t){K(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Gc(s,o,i),F(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function sg(e,t){K(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=jl(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2743
2807
  `),r={sourceDir:o.sourceDir,componentCount:o.components.length,components:o.components.map(a=>({name:a.name,description:a.description})),hasTailwind:o.hasTailwind,cssVarCount:o.cssVarCount,fonts:o.fonts,interactions:o.interactions,conversionPrompt:`Import and convert the React landing page from ${s} to native HubSpot modules.
2744
2808
 
2745
2809
  Source analysis found ${o.components.length} components:
@@ -2749,19 +2813,19 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
2749
2813
  Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
2750
2814
  Interactions: ${o.interactions.join(", ")}
2751
2815
 
2752
- Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};p(t,200,r)}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function fp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}if(!rt()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?lc(n.themePath,o,50):ac(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function hp(e,t){W(e,n=>{try{let s=C();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(lt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let r=s.templates.find(c=>c.id===i);if(!r){p(t,404,{error:"Template not found"});return}let a=r.moduleOrder.map(c=>`modules/${c}.module`);r.templateFile&&a.push(r.templateFile);let l=dc(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}Bc()}else{let r=cc(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}Jc()}L(),p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var yp=N(()=>{"use strict";y();Xe();Ce();Ao();oi();co();In()});import{writeFileSync as yS,mkdirSync as Sp}from"fs";import{join as hi}from"path";import{randomUUID as bS}from"crypto";function vp(e){let t=e.match(SS);if(!t)return null;let n=t[1],s=t[2]?decodeURIComponent(t[2].replace(/-/g," ")):void 0,o;try{let r=new URL(e).searchParams.get("node-id");r&&(o=r.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function bi(e,t){let n=await fetch(`${vS}${e}`,{headers:{"X-Figma-Token":t}});if(!n.ok){let s=await n.text().catch(()=>""),o=new Error(`Figma API ${n.status}: ${s.slice(0,200)}`);throw o.status=n.status,o}return n.json()}async function xa(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=bp.length)throw s;let r=bp[n];E.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${r}s`),t&&t(`Figma rate limited \u2014 retrying in ${r}s...`),await new Promise(a=>setTimeout(a,r*1e3))}}function mn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)mn(s,t,n+1)}function xp(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=xp(n,t);if(s)return s}return null}function xS(e,t){if(t){let s=xp(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>va.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>va.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>va.has(s.type)):[]}function yi(e){let t=Math.round(e.r*255),n=Math.round(e.g*255),s=Math.round(e.b*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}`}function wS(e){let t=new Map;for(let n of e)mn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=yi(o.color),r=t.get(i),a=s.type==="TEXT",l=a?"text":"fill";r?(r.occurrences++,a&&r.usage!=="text"&&(r.usage="text")):t.set(i,{hex:i,opacity:o.opacity??o.color.a,occurrences:1,usage:l})}}if(s.strokes){for(let o of s.strokes)if(o.type==="SOLID"&&o.color){let i=yi(o.color),r=t.get(i);r?r.occurrences++:t.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function CS(e){let t=new Map;for(let n of e)mn(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,r=o.fontWeight||400,a=o.lineHeightPx?Math.round(o.lineHeightPx/i*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";i>=32?d="heading":i>=20?d="subheading":i<=12?d="caption":r>=600&&i<=14&&(d="label");let u=`${c}-${i}-${r}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:r,lineHeight:a,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function kS(e){let t=[],n=new Set;for(let s of e)mn(s,o=>{if(!o.layoutMode||o.layoutMode==="NONE")return;if(o.itemSpacing&&o.itemSpacing>0){let c=`gap-${o.itemSpacing}-${o.name}`;n.has(c)||(n.add(c),t.push({context:`${o.name} gap`,value:o.itemSpacing,type:"gap"}))}let i=o.paddingTop||0,r=o.paddingRight||0,a=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||r>0||a>0||l>0){let c=`pad-${i}-${r}-${a}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===a&&l===r&&i===l?i:Math.max(i,r,a,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function TS(e){let t=[],n=new Set;for(let s of e)mn(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r,g:a,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(r*255)},${Math.round(a*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let i=`${o.cornerRadius}px`;n.has(`radius-${i}`)||(n.add(`radius-${i}`),t.push({type:"radius",cssValue:i,context:o.name}))}});return t}function AS(e,t){let n=[];return mn(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,r="body";o>=32?r="headline":o>=20?r="subheadline":o<=12?r="caption":i>=600&&o<=16&&(r="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(r="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:r,sectionName:t})}),n}function _S(e){let t=e.absoluteBoundingBox;return{name:e.name,type:e.type,nodeId:e.id,width:t?.width||0,height:t?.height||0,layoutMode:e.layoutMode==="NONE"?void 0:e.layoutMode,childCount:e.children?.length||0,characters:e.type==="TEXT"?e.characters:void 0}}function $S(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return yi(t.color)}if(e.backgroundColor)return yi(e.backgroundColor)}function ES(e){return e.map(t=>{let n=t.absoluteBoundingBox;return{name:t.name,nodeId:t.id,width:n?.width||0,height:n?.height||0,textContent:AS(t,t.name),children:(t.children||[]).slice(0,20).map(_S),backgroundColor:$S(t),layoutMode:t.layoutMode==="NONE"?void 0:t.layoutMode,itemSpacing:t.itemSpacing,paddingTop:t.paddingTop,paddingRight:t.paddingRight,paddingBottom:t.paddingBottom,paddingLeft:t.paddingLeft}})}function MS(e){let t=[];for(let n of e)mn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="IMAGE"&&o.imageRef){t.push({nodeId:s.id,name:s.name||"image"});break}}});return t}async function wp(e,t){let n=await fetch(e);if(!n.ok)throw new Error(`Failed to download image: ${n.status}`);let s=Buffer.from(await n.arrayBuffer());yS(t,s)}async function IS(e,t,n,s,o){if(t.length===0)return new Map;Sp(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await xa(()=>bi(`/v1/images/${e}?ids=${r}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(a.images)){if(!d)continue;let u=c.replace(/:/g,"-"),m=hi(s,`frame-${u}.png`);try{await wp(d,m),l.set(c,m),E.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){E.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function PS(e,t,n,s,o){if(t.length===0)return[];Sp(s,{recursive:!0});let i=50,r=[];for(let a=0;a<t.length;a+=i){let l=t.slice(a,a+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${a+1}-${Math.min(a+i,t.length)} of ${t.length})...`);let d=await xa(()=>bi(`/v1/images/${e}?ids=${c}&format=png&scale=2`,n),o);for(let u of l){let m=d.images[u.nodeId];if(!m)continue;let h=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${bS().slice(0,6)}.png`,f=hi(s,h);try{await wp(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),E.info("figma",`Downloaded asset: ${h}`)}catch(b){E.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function Cp(e,t,n,s,o){o&&o("Fetching Figma file...");let i=t?`/v1/files/${e}?ids=${t}&geometry=paths`:`/v1/files/${e}?geometry=paths`,r=await xa(()=>bi(i,n),o);E.info("figma",`Fetched file: ${r.name}`);let a=xS(r.document,t);if(a.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");E.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:wS(a),typography:CS(a),spacing:kS(a),effects:TS(a)};E.info("figma","Design tokens extracted",{colors:l.colors.length,typography:l.typography.length,spacing:l.spacing.length,effects:l.effects.length}),o&&o("Mapping page structure...");let c=ES(a),d=hi(s,".vibespot","figma-frames"),u=await IS(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=MS(a),h=hi(s,"assets"),f=await PS(e,g,n,h,o);return E.info("figma",`Extraction complete: ${m.length} sections, ${f.length} assets`),{fileName:r.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:f}}function kp(e){let t=e.fileName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,30);return{fileName:e.fileName,fileUrl:e.fileUrl,sectionNames:e.sections.map(n=>n.name),sectionCount:e.sections.length,colorPalette:e.designTokens.colors.slice(0,10).map(n=>n.hex),fontFamilies:[...new Set(e.designTokens.typography.map(n=>n.fontFamily))],textBlockCount:e.sections.reduce((n,s)=>n+s.textContent.length,0),assetCount:e.assets.length,suggestedThemeName:t}}async function Tp(e){return await bi("/v1/me",e)}var SS,vS,bp,va,Ap=N(()=>{"use strict";y();le();SS=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;vS="https://api.figma.com",bp=[10,20,40,60,120];va=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var Pp={};Ge(Pp,{getCachedExtraction:()=>Ip,handleFigmaExtractRoute:()=>Ca,handleFigmaGenerateRoute:()=>ka,handleFigmaTestTokenRoute:()=>wa});import{randomUUID as _p}from"crypto";import{existsSync as $p,mkdirSync as Ep,writeFileSync as NS,copyFileSync as RS}from"fs";import{join as Si,basename as OS}from"path";function Mp(){let e=Date.now();for(let[t,n]of Ls)n.expires<e&&Ls.delete(t)}function Ip(e){Mp();let t=Ls.get(e);return t?(Ls.delete(e),t.extraction):null}function wa(e,t){qe(e,t,async n=>{let s=n.token||R().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Tp(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);E.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function Ca(e,t){qe(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||R().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=vp(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=C()?.themePath||`/tmp/vibespot-figma-${_p().slice(0,8)}`;t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
2816
+ Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};p(t,200,r)}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function og(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}if(!lt()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?Oc(n.themePath,o,50):Nc(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function ig(e,t){K(e,n=>{try{let s=w();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(dt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let r=s.templates.find(c=>c.id===i);if(!r){p(t,404,{error:"Template not found"});return}let a=r.moduleOrder.map(c=>`modules/${c}.module`);r.templateFile&&a.push(r.templateFile);let l=Dc(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}gd()}else{let r=Fc(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}pd()}F(),p(t,200,{ok:!0,modules:xe().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var rg=R(()=>{"use strict";y();Qe();Ce();Bo();Ti();wo();jn()});import{writeFileSync as Cv,mkdirSync as lg}from"fs";import{join as Ii}from"path";import{randomUUID as Tv}from"crypto";function cg(e){let t=e.match(Av);if(!t)return null;let n=t[1],s=t[2]?decodeURIComponent(t[2].replace(/-/g," ")):void 0,o;try{let r=new URL(e).searchParams.get("node-id");r&&(o=r.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function Ni(e,t){let n=await fetch(`${_v}${e}`,{headers:{"X-Figma-Token":t}});if(!n.ok){let s=await n.text().catch(()=>""),o=new Error(`Figma API ${n.status}: ${s.slice(0,200)}`);throw o.status=n.status,o}return n.json()}async function za(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=ag.length)throw s;let r=ag[n];T.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${r}s`),t&&t(`Figma rate limited \u2014 retrying in ${r}s...`),await new Promise(a=>setTimeout(a,r*1e3))}}function vn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)vn(s,t,n+1)}function dg(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=dg(n,t);if(s)return s}return null}function $v(e,t){if(t){let s=dg(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>Va.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>Va.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>Va.has(s.type)):[]}function Ri(e){let t=Math.round(e.r*255),n=Math.round(e.g*255),s=Math.round(e.b*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}`}function Pv(e){let t=new Map;for(let n of e)vn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=Ri(o.color),r=t.get(i),a=s.type==="TEXT",l=a?"text":"fill";r?(r.occurrences++,a&&r.usage!=="text"&&(r.usage="text")):t.set(i,{hex:i,opacity:o.opacity??o.color.a,occurrences:1,usage:l})}}if(s.strokes){for(let o of s.strokes)if(o.type==="SOLID"&&o.color){let i=Ri(o.color),r=t.get(i);r?r.occurrences++:t.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function Ev(e){let t=new Map;for(let n of e)vn(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,r=o.fontWeight||400,a=o.lineHeightPx?Math.round(o.lineHeightPx/i*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";i>=32?d="heading":i>=20?d="subheading":i<=12?d="caption":r>=600&&i<=14&&(d="label");let u=`${c}-${i}-${r}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:r,lineHeight:a,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function Mv(e){let t=[],n=new Set;for(let s of e)vn(s,o=>{if(!o.layoutMode||o.layoutMode==="NONE")return;if(o.itemSpacing&&o.itemSpacing>0){let c=`gap-${o.itemSpacing}-${o.name}`;n.has(c)||(n.add(c),t.push({context:`${o.name} gap`,value:o.itemSpacing,type:"gap"}))}let i=o.paddingTop||0,r=o.paddingRight||0,a=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||r>0||a>0||l>0){let c=`pad-${i}-${r}-${a}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===a&&l===r&&i===l?i:Math.max(i,r,a,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function Iv(e){let t=[],n=new Set;for(let s of e)vn(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r,g:a,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(r*255)},${Math.round(a*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let i=`${o.cornerRadius}px`;n.has(`radius-${i}`)||(n.add(`radius-${i}`),t.push({type:"radius",cssValue:i,context:o.name}))}});return t}function Rv(e,t){let n=[];return vn(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,r="body";o>=32?r="headline":o>=20?r="subheadline":o<=12?r="caption":i>=600&&o<=16&&(r="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(r="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:r,sectionName:t})}),n}function Nv(e){let t=e.absoluteBoundingBox;return{name:e.name,type:e.type,nodeId:e.id,width:t?.width||0,height:t?.height||0,layoutMode:e.layoutMode==="NONE"?void 0:e.layoutMode,childCount:e.children?.length||0,characters:e.type==="TEXT"?e.characters:void 0}}function Ov(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Ri(t.color)}if(e.backgroundColor)return Ri(e.backgroundColor)}function Fv(e){return e.map(t=>{let n=t.absoluteBoundingBox;return{name:t.name,nodeId:t.id,width:n?.width||0,height:n?.height||0,textContent:Rv(t,t.name),children:(t.children||[]).slice(0,20).map(Nv),backgroundColor:Ov(t),layoutMode:t.layoutMode==="NONE"?void 0:t.layoutMode,itemSpacing:t.itemSpacing,paddingTop:t.paddingTop,paddingRight:t.paddingRight,paddingBottom:t.paddingBottom,paddingLeft:t.paddingLeft}})}function Dv(e){let t=[];for(let n of e)vn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="IMAGE"&&o.imageRef){t.push({nodeId:s.id,name:s.name||"image"});break}}});return t}async function ug(e,t){let n=await fetch(e);if(!n.ok)throw new Error(`Failed to download image: ${n.status}`);let s=Buffer.from(await n.arrayBuffer());Cv(t,s)}async function jv(e,t,n,s,o){if(t.length===0)return new Map;lg(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await za(()=>Ni(`/v1/images/${e}?ids=${r}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(a.images)){if(!d)continue;let u=c.replace(/:/g,"-"),m=Ii(s,`frame-${u}.png`);try{await ug(d,m),l.set(c,m),T.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){T.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function Lv(e,t,n,s,o){if(t.length===0)return[];lg(s,{recursive:!0});let i=50,r=[];for(let a=0;a<t.length;a+=i){let l=t.slice(a,a+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${a+1}-${Math.min(a+i,t.length)} of ${t.length})...`);let d=await za(()=>Ni(`/v1/images/${e}?ids=${c}&format=png&scale=2`,n),o);for(let u of l){let m=d.images[u.nodeId];if(!m)continue;let h=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${Tv().slice(0,6)}.png`,f=Ii(s,h);try{await ug(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),T.info("figma",`Downloaded asset: ${h}`)}catch(b){T.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function mg(e,t,n,s,o){o&&o("Fetching Figma file...");let i=t?`/v1/files/${e}?ids=${t}&geometry=paths`:`/v1/files/${e}?geometry=paths`,r=await za(()=>Ni(i,n),o);T.info("figma",`Fetched file: ${r.name}`);let a=$v(r.document,t);if(a.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");T.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:Pv(a),typography:Ev(a),spacing:Mv(a),effects:Iv(a)};T.info("figma","Design tokens extracted",{colors:l.colors.length,typography:l.typography.length,spacing:l.spacing.length,effects:l.effects.length}),o&&o("Mapping page structure...");let c=Fv(a),d=Ii(s,".vibespot","figma-frames"),u=await jv(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=Dv(a),h=Ii(s,"assets"),f=await Lv(e,g,n,h,o);return T.info("figma",`Extraction complete: ${m.length} sections, ${f.length} assets`),{fileName:r.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:f}}function pg(e){let t=e.fileName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,30);return{fileName:e.fileName,fileUrl:e.fileUrl,sectionNames:e.sections.map(n=>n.name),sectionCount:e.sections.length,colorPalette:e.designTokens.colors.slice(0,10).map(n=>n.hex),fontFamilies:[...new Set(e.designTokens.typography.map(n=>n.fontFamily))],textBlockCount:e.sections.reduce((n,s)=>n+s.textContent.length,0),assetCount:e.assets.length,suggestedThemeName:t}}async function gg(e){return await Ni("/v1/me",e)}var Av,_v,ag,Va,fg=R(()=>{"use strict";y();de();Av=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;_v="https://api.figma.com",ag=[10,20,40,60,120];Va=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var xg={};We(xg,{getCachedExtraction:()=>vg,handleFigmaExtractRoute:()=>qa,handleFigmaGenerateRoute:()=>Xa,handleFigmaTestTokenRoute:()=>Ya});import{randomUUID as hg}from"crypto";import{existsSync as yg,mkdirSync as bg,writeFileSync as Bv,copyFileSync as Jv}from"fs";import{join as Oi,basename as Hv}from"path";function Sg(){let e=Date.now();for(let[t,n]of Xs)n.expires<e&&Xs.delete(t)}function vg(e){Sg();let t=Xs.get(e);return t?(Xs.delete(e),t.extraction):null}function Ya(e,t){Ze(e,t,async n=>{let s=n.token||N().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await gg(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);T.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function qa(e,t){Ze(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||N().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=cg(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=w()?.themePath||`/tmp/vibespot-figma-${hg().slice(0,8)}`;t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
2753
2817
 
2754
- `)};try{let c=await Cp(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=_p();Mp(),Ls.set(d,{extraction:c,expires:Date.now()+FS});let u=kp(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);E.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function DS(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((a,l)=>l.count-a.count),i=o[0],r=o[1];i&&s.push(`- **Primary:** \`${i.hex}\` (${i.name||"dominant color"})`),r&&s.push(`- **Secondary:** \`${r.hex}\` (${r.name||"accent color"})`),s.push(""),s.push("### Full palette","");for(let a of o.slice(0,15)){let l=a.name?`${a.name}`:`${a.count}\xD7 used`;s.push(`- \`${a.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(r=>r.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let i=new Set;for(let r of t.typography){let a=`${r.role}-${r.fontSize}-${r.fontWeight}`;i.has(a)||(i.add(a),s.push(`| ${r.role} | ${r.fontFamily} | ${r.fontSize}px | ${r.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(i=>i.value))].sort((i,r)=>i-r);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let i of t.spacing)s.push(`- **${i.property}** (${i.context}): ${i.value}px`);s.push("")}if(t.effects.length>0){s.push("## Effects","");for(let o of t.effects)o.boxShadow&&s.push(`- **Box shadow:** \`${o.boxShadow}\``),o.borderRadius&&s.push(`- **Border radius:** ${o.borderRadius}px`);s.push("")}return s.join(`
2755
- `)}function ka(e,t){qe(e,t,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(t,400,{error:"Missing extractionId or themeName"});return}let r=Ip(s);if(!r){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=C();if(!a){p(t,400,{error:"No active session. Create a theme first."});return}t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
2818
+ `)};try{let c=await mg(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=hg();Sg(),Xs.set(d,{extraction:c,expires:Date.now()+Uv});let u=pg(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);T.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function Gv(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((a,l)=>l.occurrences-a.occurrences),i=o[0],r=o[1];i&&s.push(`- **Primary:** \`${i.hex}\` (${i.variableName||"dominant color"})`),r&&s.push(`- **Secondary:** \`${r.hex}\` (${r.variableName||"accent color"})`),s.push(""),s.push("### Full palette","");for(let a of o.slice(0,15)){let l=a.variableName?`${a.variableName}`:`${a.occurrences}\xD7 used`;s.push(`- \`${a.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(r=>r.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let i=new Set;for(let r of t.typography){let a=`${r.role}-${r.fontSize}-${r.fontWeight}`;i.has(a)||(i.add(a),s.push(`| ${r.role} | ${r.fontFamily} | ${r.fontSize}px | ${r.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(i=>i.value))].sort((i,r)=>i-r);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let i of t.spacing)s.push(`- **${i.type}** (${i.context}): ${i.value}px`);s.push("")}if(t.effects.length>0){s.push("## Effects","");for(let o of t.effects)o.type==="shadow"?s.push(`- **Box shadow** (${o.context}): \`${o.cssValue}\``):o.type==="radius"?s.push(`- **Border radius** (${o.context}): ${o.cssValue}`):o.type==="blur"&&s.push(`- **Blur** (${o.context}): ${o.cssValue}`);s.push("")}return s.join(`
2819
+ `)}function Xa(e,t){Ze(e,t,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(t,400,{error:"Missing extractionId or themeName"});return}let r=vg(s);if(!r){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=w();if(!a){p(t,400,{error:"No active session. Create a theme first."});return}t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
2756
2820
 
2757
- `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=DS(r),d=Si(a.themePath,".vibespot");if($p(d)||Ep(d,{recursive:!0}),NS(Si(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,L(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)Pt("landing_page","Landing Page");else{a.modules=[],a.moduleOrder=[],a.sharedCss="",a.sharedJs="";let f=a.templates.find(b=>b.id===a.activeTemplateId);f&&(f.modules=[],f.moduleOrder=[],f.sharedCss="",f.sharedJs="")}if(L(),i&&r.assets.length>0){let f=Si(a.themePath,"assets");Ep(f,{recursive:!0});let b=0;for(let S of r.assets)if($p(S.localPath)){let v=Si(f,OS(S.localPath));try{RS(S.localPath,v),S.localPath=v,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],g=await Rs(r,o,f=>{if(f.type==="agent_step")u.push({step:f.step,label:f.label}),l({type:"progress",message:`${f.label}...`});else if(f.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(f.decision)),l({type:"progress",message:` ${f.decision}`})}else f.type==="design_system_ready"?He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Ht(f.moduleOrder),l({type:"progress",message:`Planned ${f.moduleOrder.length} modules`})):f.type==="module_progress"&&(f.status==="generating"?l({type:"progress",message:`Generating module: ${f.module}`}):f.status==="complete"&&f.moduleFiles?(He({modules:[{moduleName:f.module,fieldsJson:f.moduleFiles.fieldsJson,metaJson:f.moduleFiles.metaJson,moduleHtml:f.moduleFiles.moduleHtml,moduleCss:f.moduleFiles.moduleCss,moduleJs:f.moduleFiles.moduleJs}]}),m.push({name:f.module,status:"complete"}),l({type:"progress",message:`Module complete: ${f.module}`})):f.status==="failed"&&(m.push({name:f.module,status:"failed"}),l({type:"progress",message:`Module failed: ${f.module}`})))},{useAssets:i});cn(g,{steps:u,modules:m,stats:g.stats}),Te(),sn(a.themePath,`Figma import: ${r.fileName}`);let h=ve().map(f=>f.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${h.length} modules generated`}),l({type:"complete",ok:!0,modules:h})}catch(c){let d=c instanceof Error?c.message:String(c);E.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Ls,FS,Ta=N(()=>{"use strict";y();Xe();ee();le();Ap();Ce();us();fr();In();Wn();Ut();Ls=new Map,FS=1800*1e3});import{readdirSync as $a,statSync as jS}from"fs";import{join as q,relative as LS}from"path";function Yn(e){let t=q(e,Ft);if(!x(t))return null;try{return JSON.parse(P(t))}catch{return null}}function xi(e,t){let n=q(e,Ft);B(n,JSON.stringify(t,null,2)+`
2758
- `)}function Js(e){let t=[];if(!x(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),Aa(e,t,null);let n=_a(q(e,"theme.json"));if(!n)return t.push({severity:"error",rule:"theme.json.missing",file:"theme.json",message:"theme.json is missing or invalid JSON",fix:"Recreate the theme so theme.json is generated, or restore it from version control."}),Aa(e,t,Yn(e));HS(e,n,t),US(e,n,t),GS(e,t),KS(e,t),VS(e,t),zS(e,t);let s=Yn(e);return YS(s,t),Aa(e,t,s)}function Aa(e,t,n){let s=t.filter(r=>r.severity==="error").length,o=t.filter(r=>r.severity==="warning").length,i=t.filter(r=>r.severity==="info").length;return{themePath:e,passed:s===0,errorCount:s,warningCount:o,infoCount:i,findings:t,metadata:n}}function HS(e,t,n){let s={documentation_url:'Add a "documentation_url" entry pointing to public docs for the theme.',license:'Add a "license" entry \u2014 an SPDX identifier or URL (e.g. "MIT").',example_url:'Add an "example_url" entry pointing to a public live preview of the theme.'};for(let r of JS)kt(t,r)||n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json is missing required field "${r}"`,fix:s[r]??`Add a "${r}" entry to theme.json.`});for(let r of BS)(!(r in t)||typeof t[r]!="boolean")&&n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json must declare boolean "${r}"`,fix:`Add "${r}": true (or false) to theme.json.`});let o=t.author;!o||typeof o!="object"?n.push({severity:"error",rule:"theme.json.author.missing",file:"theme.json",message:'theme.json is missing required "author" block',fix:'Add { "author": { "name": "...", "email": "...", "url": "..." } } to theme.json.'}):(kt(o,"name")||n.push({severity:"error",rule:"theme.json.author.name.missing",file:"theme.json",message:"theme.json author.name is missing",fix:"Provide a publisher name in theme.json author.name."}),kt(o,"email")||n.push({severity:"error",rule:"theme.json.author.email.missing",file:"theme.json",message:"theme.json author.email is missing",fix:"Provide a contact email in theme.json author.email."}),kt(o,"url")||n.push({severity:"error",rule:"theme.json.author.url.missing",file:"theme.json",message:"theme.json author.url is missing",fix:"Add a public URL for the publisher (homepage or support page)."}));let i=t.preview_path;if(typeof i=="string"&&i.length>0){let r=Fp(e,i);x(r)||n.push({severity:"error",rule:"theme.json.preview_path.invalid",file:"theme.json",message:`preview_path "${i}" does not point to an existing file`,fix:"Update preview_path to a real template, e.g. ./templates/home.html."})}}function US(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Fp(e,s);if(!x(o)){n.push({severity:"error",rule:"theme.json.screenshot.missing",file:"theme.json",message:`Screenshot not found at ${s}`,fix:"Place a 1500\xD71000 PNG at the screenshot_path declared in theme.json."});return}/\.(png|jpg|jpeg)$/i.test(s)||n.push({severity:"warning",rule:"theme.json.screenshot.format",file:s,message:"Screenshot should be a PNG or JPG",fix:"Re-export the screenshot as PNG (1500\xD71000) or JPG."})}function GS(e,t){let n=q(e,"modules");if(!x(n)){t.push({severity:"warning",rule:"modules.empty",message:"Theme has no modules/ directory",fix:"Generate at least one module before submitting to Marketplace."});return}let s=0,o=[];try{o=$a(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=q(n,i);WS(e,r,i,t)}s===0&&t.push({severity:"warning",rule:"modules.empty",message:"Theme has no .module directories",fix:"Generate at least one module before submitting to Marketplace."})}function WS(e,t,n,s){let o=_a(q(t,"meta.json")),i=mt(e,q(t,"meta.json"));o?(kt(o,"label")||s.push({severity:"error",rule:"module.meta.label.missing",file:i,message:`${n}: meta.json is missing "label"`,fix:`Add a "label" entry to the module's meta.json.`,autoFixable:!0}),o.is_available_for_new_content===!1&&s.push({severity:"info",rule:"module.meta.unavailable",file:i,message:`${n}: is_available_for_new_content=false (won\u2019t be selectable in HubSpot UI)`})):s.push({severity:"error",rule:"module.meta.missing",file:i,message:`${n}: meta.json is missing or invalid`,fix:"Recreate the module so meta.json is generated."});let r=q(t,"fields.json"),a=mt(e,r);if(!x(r))s.push({severity:"warning",rule:"module.fields.missing",file:a,message:`${n}: fields.json is missing`,fix:"Add a fields.json (an empty array [] is acceptable for static modules)."});else{let c=_a(r);Array.isArray(c)?Rp(c,n,a,s):s.push({severity:"warning",rule:"module.fields.invalid",file:a,message:`${n}: fields.json is not a JSON array`})}let l=q(t,"module.html");x(l)||s.push({severity:"error",rule:"module.html.missing",file:mt(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function Rp(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)";kt(i,"label")||s.push({severity:"error",rule:"module.field.label.missing",file:n,message:`${t}.${r}: field is missing "label"`,fix:`Add a human-readable "label" to the "${r}" field in fields.json.`,autoFixable:!0}),!kt(i,"help_text")&&i.type!=="group"&&s.push({severity:"info",rule:"module.field.help_text.missing",file:n,message:`${t}.${r}: consider adding "help_text"`,fix:`Add a short "help_text" describing what "${r}" controls.`}),Array.isArray(i.children)&&Rp(i.children,t,n,s)}}function KS(e,t){let n=[],s=q(e,"css");vi(s,".css").forEach(i=>{Np(i,n,e)});let o=q(e,"modules");if(x(o))for(let i of Bs(o)){if(!i.endsWith(".module"))continue;let r=q(o,i);["module.css","module.html"].forEach(a=>{let l=q(r,a);x(l)&&Np(l,n,e)})}for(let i of n)t.push({severity:"error",rule:"asset.cdn-import",file:i.file,message:`External CDN reference found: ${i.match}`,fix:"Remove external @import / <link> URLs and bundle the asset locally.",autoFixable:!0})}function Np(e,t,n){let s;try{s=P(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:mt(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:mt(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:mt(n,e),match:r[0]})}function VS(e,t){let n=[{rule:"asset.hardcoded.hubfs",re:/https?:\/\/[\w.-]*hubfs[\w.-]*\/(\d+)\//i,message:"Hardcoded portal-specific HubFS URL detected"},{rule:"asset.hardcoded.usercontent",re:/hubspotusercontent[-\w]*\.net\/(\w+\/)?(\d+)\//i,message:"Hardcoded portal-specific HubSpot user-content URL detected"},{rule:"asset.hardcoded.preview",re:/\d+\.hs-sites\.com|hubspotpagebuilder\.com\/\d+/i,message:"Hardcoded portal preview URL detected"}],s=[],o=q(e,"css");vi(o,".css").forEach(a=>s.push(a));let i=q(e,"js");vi(i,".js").forEach(a=>s.push(a));let r=q(e,"modules");if(x(r))for(let a of Bs(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=q(r,a,l);x(c)&&s.push(c)});for(let a of s){let l;try{l=P(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:mt(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function zS(e,t){let n=q(e,"modules");if(x(n))for(let s of Bs(n)){if(!s.endsWith(".module"))continue;let o=q(n,s,"module.html");if(!x(o))continue;let i;try{i=P(o)}catch{continue}let r=/<img\b([^>]*)>/gi,a;for(;a=r.exec(i);){let c=a[1];/\balt\s*=/.test(c)||t.push({severity:"warning",rule:"a11y.img.alt-missing",file:mt(e,o),message:`${s}: <img> without alt attribute`,fix:'Add an alt attribute (alt="" is fine for purely decorative images).'})}/<(section|article|header|footer|main|nav|aside|h[1-6])\b/i.test(i)||t.push({severity:"info",rule:"a11y.semantics.missing",file:mt(e,o),message:`${s}: module.html has no semantic landmarks (section/article/header/etc.)`,fix:"Wrap the module's main content in a <section> with a heading."})}}function YS(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Ft,message:"marketplace.json sidecar not found",fix:"Run `vibespot marketplace edit` (CLI) or open the Marketplace panel in the editor to fill in listing details."});return}e.category?Yt.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Ft,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${Yt.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Ft,message:"marketplace.json has no category",fix:`Pick one of: ${Yt.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Ft,message:"marketplace.json description is missing or short (<40 chars)",fix:"Provide a 1\u20132 sentence description of the theme for the Marketplace listing."}),e.supportUrl||t.push({severity:"warning",rule:"marketplace.json.supportUrl.missing",file:Ft,message:"marketplace.json has no supportUrl",fix:"Add a public support URL where buyers can reach the publisher."});let n=e.features?.length??0;n<2?t.push({severity:"warning",rule:"marketplace.json.features.too_few",file:Ft,message:`marketplace.json needs at least 2 features (has ${n})`,fix:"Add 2\u20135 short bullet points highlighting what the theme does well."}):n>5&&t.push({severity:"warning",rule:"marketplace.json.features.too_many",file:Ft,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function wi(e){let t=[],n=[],s=q(e,"modules");if(x(s))for(let i of Bs(s)){if(!i.endsWith(".module"))continue;let r=q(s,i),a=i.replace(/\.module$/,""),l=q(r,"meta.json");if(x(l))try{let d=JSON.parse(P(l));kt(d,"label")||(d.label=Dp(a),B(l,JSON.stringify(d,null,2)+`
2759
- `),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=q(r,"fields.json");if(x(c))try{let d=JSON.parse(P(c));if(Array.isArray(d)){let u=Op(d);u>0&&(B(c,JSON.stringify(d,null,2)+`
2760
- `),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=qS(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function qS(e){let t=[],n=/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,s=/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,o=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*><\/script>/gi,i=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*\/>/gi;function r(c){let d;try{d=P(c)}catch{return}let u=d.replace(n,"");u!==d&&(B(c,u),t.push(mt(e,c)))}function a(c){let d;try{d=P(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(B(c,u),t.push(mt(e,c)))}vi(q(e,"css"),".css").forEach(r);let l=q(e,"modules");if(x(l))for(let c of Bs(l)){if(!c.endsWith(".module"))continue;let d=q(l,c),u=q(d,"module.css"),m=q(d,"module.html");x(u)&&r(u),x(m)&&a(m)}return t}function Op(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!kt(s,"label")&&kt(s,"name")&&(s.label=Dp(String(s.name)),t++),Array.isArray(s.children)&&(t+=Op(s.children))}return t}function _a(e){if(!x(e))return null;try{let t=JSON.parse(P(e));return t&&typeof t=="object"?t:null}catch{return null}}function kt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Fp(e,t){let n=t.replace(/^\.?\//,"");return q(e,n)}function mt(e,t){return LS(e,t).split("\\").join("/")}function Bs(e){try{return $a(e)}catch{return[]}}function vi(e,t){if(!x(e))return[];try{let n=[];for(let s of $a(e)){let o=q(e,s);jS(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Dp(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var Yt,JS,BS,Ft,Ea=N(()=>{"use strict";y();oe();Yt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],JS=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],BS=["enable_domain_stylesheets","is_available_for_new_content"],Ft="marketplace.json"});function Ma(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Te()}catch{}return t.themePath}function jp(e,t){let n=Ma(t);if(!n)return;let s=Js(n);p(t,200,{report:s,categories:Yt})}function Lp(e,t){let n=Ma(t);if(!n)return;let s=wi(n),o=Js(n);p(t,200,{fix:s,report:o})}function Jp(e,t,n){let s=Ma(n);if(s){if(e==="GET"){p(n,200,{metadata:Yn(s),categories:Yt});return}if(e==="POST"){qe(t,n,o=>{let i={category:typeof o.category=="string"?o.category:void 0,description:typeof o.description=="string"?o.description:void 0,features:Array.isArray(o.features)?o.features.filter(r=>typeof r=="string"&&r.trim().length>0):void 0,supportUrl:typeof o.supportUrl=="string"?o.supportUrl:void 0,documentationUrl:typeof o.documentationUrl=="string"?o.documentationUrl:void 0,pricingTier:o.pricingTier==="free"||o.pricingTier==="paid"?o.pricingTier:void 0,tags:Array.isArray(o.tags)?o.tags.filter(r=>typeof r=="string"):void 0};xi(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Bp=N(()=>{"use strict";y();Xe();Ce();Ea()});function XS(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Te()}catch{}return t.themePath}function Hp(e,t){let n=XS(t);if(!n)return;let s=Jo(n);p(t,200,{report:s})}function Up(e,t){let n=C();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=Fn(n.themePath),o=fs(s);if(!o){p(t,200,{applied:!1,reason:"No tokens to apply."});return}if(!n.sharedCss||n.sharedCss.trim().length===0){n.sharedCss=o,n.updatedAt=Date.now(),L(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=Bo(n.themePath,n.themeName);i?p(t,200,{applied:!0,written:i,rootBlock:o}):p(t,200,{applied:!1,reason:"Theme already has shared CSS."})}var Gp=N(()=>{"use strict";y();Xe();Ce();Ho()});import{createServer as ZS}from"http";import{readFileSync as Na,existsSync as Hs}from"fs";import{join as jt,extname as Kp}from"path";import{WebSocketServer as QS,WebSocket as ev}from"ws";function Ae(e){ki&&ki.readyState===ev.OPEN&&ki.send(JSON.stringify(e))}function Ci(e){Ti.push(e),Ae(e)}function Dt(){Ti=[]}function Ia(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;Ci(o)}else Ci(n);if(n.type==="agent_step")e.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=e[e.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Ht(n.moduleOrder),Ci({type:"modules_updated",modules:ve().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(He({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),Ci({type:"modules_updated",modules:ve().map(s=>s.moduleName)}),t.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&t.push({name:n.module,status:"failed"})}}function Pa(e){let t=e.cost;if(!t||t.calls===0)return;let n=C();Ae({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}function Ln(){return zp}function Ai(e){let{port:t,uiDir:n}=e;zp=e.contentMode||"page";let s=ZS((i,r)=>tv(i,r,n)),o=new QS({server:s});return o.on("connection",i=>sv(i)),new Promise((i,r)=>{s.on("error",a=>{a.code==="EADDRINUSE"?s.listen(t+1,"0.0.0.0",()=>{i({port:t+1,close:()=>{s.close(),o.close()}})}):r(a)}),s.listen(t,"0.0.0.0",()=>{i({port:t,close:()=>{s.close(),o.close()}})})})}function tv(e,t,n){let s=new URL(e.url||"/",`http://${e.headers.host}`),o=e.method||"GET";if(t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("X-XSS-Protection","1; mode=block"),t.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname==="/healthz"){t.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify({status:"ok"}));return}if(s.pathname.startsWith("/api/")){nv(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=xr();t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",r=wr(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){ov(s.pathname.slice(14),t);return}if(s.pathname==="/docs"){t.writeHead(301,{Location:"/docs/"}),t.end();return}if(s.pathname.startsWith("/docs/")){let i=s.pathname.slice(5)||"/index.html";Wp(i,jt(n,"docs"),e,t);return}Wp(s.pathname,n,e,t)}function nv(e,t,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1|100\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|10\.\d+\.\d+\.\d+)(:\d+)?$/.test(o)&&s.setHeader("Access-Control-Allow-Origin",o),s.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type"),e==="OPTIONS"){s.writeHead(204),s.end();return}switch(t){case"/api/session":lp(e,s);break;case"/api/modules":cp(e,n,s);break;case"/api/modules/reorder":up(n,s);break;case"/api/modules/code":dp(n,s);break;case"/api/upload":mp(s);break;case"/api/upload-files":e==="POST"?pd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":pp(n,s);break;case"/api/import":gp(n,s);break;case"/api/setup":Qu(s);break;case"/api/setup/create":em(n,s);break;case"/api/setup/fetch":nm(n,s);break;case"/api/setup/open":sm(n,s);break;case"/api/setup/resume":om(n,s);break;case"/api/setup/apikey":im(n,s);break;case"/api/setup/remote-themes":e==="GET"?rm(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?tm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?gm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/models":e==="GET"?fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/tools":e==="GET"?hm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?ym(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?bm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Sm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?vm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?xm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?wm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Cm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?km(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Am(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Mm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Im(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Pm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?_m(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Ga()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Rm(e,n,s);break;case"/api/themes/switch":e==="POST"?Om(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Dm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?jm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?fp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Wm(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":zm(e,n,s);break;case"/api/templates/activate":e==="POST"?Ym(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?qm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?Zm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?Xm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?Qm(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":tp(e,n,s);break;case"/api/brand-kit":op(e,n,s);break;case"/api/fonts":e==="GET"?sp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?ip(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?rp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Vm(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?wa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?Ca(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?ka(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Mu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Iu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Pu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?Nu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?jp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?Lp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Jp(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Up(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?$m(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?ep(t,n,s):p(s,404,{error:"Not found"})}}function sv(e){e.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{e.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;let i=Array.isArray(s.fileIds)?s.fileIds:void 0;if(oa()){lt("user",o),L();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await sa(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=Ou(l||a);c.plan&&(ti(c.plan),e.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&e.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),lt("assistant",c.cleanedContent),L(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(a){e.send(JSON.stringify({type:"error",message:a instanceof Error?a.message:String(a)}))}break}lt("user",o),L();let r=ia();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Dt();let l=[],c=[],d=await Qo(o,Ia(l,c),i);cn(d,{steps:l,modules:c,stats:d.stats,cost:d.cost}),Pa(d)}else ta(l=>{Ae({type:"parse_warning",message:l})}),await Ns(o,l=>{Ae({type:"stream",content:l})},l=>{Ae({type:"stream_status",content:l})},i);let a=C();if(a){Te();let l=ke(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${a.themeName}-theme.css`),l.sharedJs&&d.push(`js/${a.themeName}-animations.js`),c=or(a.themePath,l.id,o,d)}else c=sn(a.themePath,o);c&&Ae({type:"version_created",hash:c})}Ae({type:"generation_complete"});{let l=C();Ae({type:"modules_updated",modules:ve().map(c=>c.moduleName),templateId:l?.activeTemplateId||null,templates:(l?.templates||[]).map(c=>({id:c.id,label:c.label,pageType:c.pageType,moduleCount:c.modules.length}))})}Dt();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Ae({type:"suggest_brand_extraction"})}}catch(a){Dt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:r}=await Promise.resolve().then(()=>(Ta(),Pp)),a=r(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=C();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:h}=await import("fs"),{createThemeScaffold:f}=await Promise.resolve().then(()=>(is(),gl)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!h(b)){let{mkdirSync:v}=await import("fs");v(b,{recursive:!0})}h(S)||f(S,i),Rn(S,i),L()}Ae({type:"figma_import_started",fileName:a.fileName}),Dt();let c=[],d=[],u=await Rs(a,i,Ia(c,d));cn(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),Pa(u),Te(),sn(C().themePath,`Figma import: ${a.fileName}`),Ae({type:"generation_complete"});{let m=C();Ae({type:"modules_updated",modules:ve().map(g=>g.moduleName),templateId:m?.activeTemplateId||null,templates:(m?.templates||[]).map(g=>({id:g.id,label:g.label,pageType:g.pageType,moduleCount:g.modules.length}))})}Dt()}catch(l){Dt(),Ae({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=R(),{engine:r,apiKey:a,model:l}=Gn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Ss(),Go)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(di(),ci)),m=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>te("extract-theme-context",()=>u(d,o.brandAssets?.themeContext,r,a,l))),{mkdirSync:g,writeFileSync:h}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let f=jt(o.themePath,".vibespot");Hs(f)||g(f,{recursive:!0}),h(jt(f,"theme-context.md"),m),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(js(),Ds)),b=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>f(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=jt(o.themePath,".vibespot");Hs(S)||g(S,{recursive:!0}),h(jt(S,"styleguide.md"),b),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Te();let i=To(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(R().hubspotUploadMode||"api")==="api"){let l=Le();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await _o(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2821
+ `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=Gv(r),d=Oi(a.themePath,".vibespot");if(yg(d)||bg(d,{recursive:!0}),Bv(Oi(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,F(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)jt("landing_page","Landing Page");else{a.modules=[],a.moduleOrder=[],a.sharedCss="",a.sharedJs="";let f=a.templates.find(b=>b.id===a.activeTemplateId);f&&(f.modules=[],f.moduleOrder=[],f.sharedCss="",f.sharedJs="")}if(F(),i&&r.assets.length>0){let f=Oi(a.themePath,"assets");bg(f,{recursive:!0});let b=0;for(let S of r.assets)if(yg(S.localPath)){let x=Oi(f,Hv(S.localPath));try{Jv(S.localPath,x),S.localPath=x,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],g=await Ys(r,o,f=>{if(f.type==="agent_step")u.push({step:f.step,label:f.label}),l({type:"progress",message:`${f.label}...`});else if(f.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(f.decision)),l({type:"progress",message:` ${f.decision}`})}else f.type==="design_system_ready"?Ue({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(Ue({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Vt(f.moduleOrder),l({type:"progress",message:`Planned ${f.moduleOrder.length} modules`})):f.type==="module_progress"&&(f.status==="generating"?l({type:"progress",message:`Generating module: ${f.module}`}):f.status==="complete"&&f.moduleFiles?(Ue({modules:[{moduleName:f.module,fieldsJson:f.moduleFiles.fieldsJson,metaJson:f.moduleFiles.metaJson,moduleHtml:f.moduleFiles.moduleHtml,moduleCss:f.moduleFiles.moduleCss,moduleJs:f.moduleFiles.moduleJs}]}),m.push({name:f.module,status:"complete"}),l({type:"progress",message:`Module complete: ${f.module}`})):f.status==="failed"&&(m.push({name:f.module,status:"failed"}),l({type:"progress",message:`Module failed: ${f.module}`})))},{useAssets:i});yn(g,{steps:u,modules:m,stats:g.stats}),Ae(),ln(a.themePath,`Figma import: ${r.fileName}`);let h=xe().map(f=>f.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${h.length} modules generated`}),l({type:"complete",ok:!0,modules:h})}catch(c){let d=c instanceof Error?c.message:String(c);T.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Xs,Uv,Za=R(()=>{"use strict";y();Qe();oe();de();fg();Ce();Ss();Er();jn();qn();zt();Xs=new Map,Uv=1800*1e3});import{readdirSync as tl,statSync as Wv}from"fs";import{join as X,relative as Kv}from"path";function es(e){let t=X(e,Ht);if(!v(t))return null;try{return JSON.parse(M(t))}catch{return null}}function Di(e,t){let n=X(e,Ht);H(n,JSON.stringify(t,null,2)+`
2822
+ `)}function Zs(e){let t=[];if(!v(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),Qa(e,t,null);let n=el(X(e,"theme.json"));if(!n)return t.push({severity:"error",rule:"theme.json.missing",file:"theme.json",message:"theme.json is missing or invalid JSON",fix:"Recreate the theme so theme.json is generated, or restore it from version control."}),Qa(e,t,es(e));Yv(e,n,t),qv(e,n,t),Xv(e,t),Qv(e,t),ex(e,t),tx(e,t);let s=es(e);return nx(s,t),Qa(e,t,s)}function Qa(e,t,n){let s=t.filter(r=>r.severity==="error").length,o=t.filter(r=>r.severity==="warning").length,i=t.filter(r=>r.severity==="info").length;return{themePath:e,passed:s===0,errorCount:s,warningCount:o,infoCount:i,findings:t,metadata:n}}function Yv(e,t,n){let s={documentation_url:'Add a "documentation_url" entry pointing to public docs for the theme.',license:'Add a "license" entry \u2014 an SPDX identifier or URL (e.g. "MIT").',example_url:'Add an "example_url" entry pointing to a public live preview of the theme.'};for(let r of Vv)Pt(t,r)||n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json is missing required field "${r}"`,fix:s[r]??`Add a "${r}" entry to theme.json.`});for(let r of zv)(!(r in t)||typeof t[r]!="boolean")&&n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json must declare boolean "${r}"`,fix:`Add "${r}": true (or false) to theme.json.`});let o=t.author;!o||typeof o!="object"?n.push({severity:"error",rule:"theme.json.author.missing",file:"theme.json",message:'theme.json is missing required "author" block',fix:'Add { "author": { "name": "...", "email": "...", "url": "..." } } to theme.json.'}):(Pt(o,"name")||n.push({severity:"error",rule:"theme.json.author.name.missing",file:"theme.json",message:"theme.json author.name is missing",fix:"Provide a publisher name in theme.json author.name."}),Pt(o,"email")||n.push({severity:"error",rule:"theme.json.author.email.missing",file:"theme.json",message:"theme.json author.email is missing",fix:"Provide a contact email in theme.json author.email."}),Pt(o,"url")||n.push({severity:"error",rule:"theme.json.author.url.missing",file:"theme.json",message:"theme.json author.url is missing",fix:"Add a public URL for the publisher (homepage or support page)."}));let i=t.preview_path;if(typeof i=="string"&&i.length>0){let r=Tg(e,i);v(r)||n.push({severity:"error",rule:"theme.json.preview_path.invalid",file:"theme.json",message:`preview_path "${i}" does not point to an existing file`,fix:"Update preview_path to a real template, e.g. ./templates/home.html."})}}function qv(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Tg(e,s);if(!v(o)){n.push({severity:"error",rule:"theme.json.screenshot.missing",file:"theme.json",message:`Screenshot not found at ${s}`,fix:"Place a 1500\xD71000 PNG at the screenshot_path declared in theme.json."});return}/\.(png|jpg|jpeg)$/i.test(s)||n.push({severity:"warning",rule:"theme.json.screenshot.format",file:s,message:"Screenshot should be a PNG or JPG",fix:"Re-export the screenshot as PNG (1500\xD71000) or JPG."})}function Xv(e,t){let n=X(e,"modules");if(!v(n)){t.push({severity:"warning",rule:"modules.empty",message:"Theme has no modules/ directory",fix:"Generate at least one module before submitting to Marketplace."});return}let s=0,o=[];try{o=tl(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=X(n,i);Zv(e,r,i,t)}s===0&&t.push({severity:"warning",rule:"modules.empty",message:"Theme has no .module directories",fix:"Generate at least one module before submitting to Marketplace."})}function Zv(e,t,n,s){let o=el(X(t,"meta.json")),i=ht(e,X(t,"meta.json"));o?(Pt(o,"label")||s.push({severity:"error",rule:"module.meta.label.missing",file:i,message:`${n}: meta.json is missing "label"`,fix:`Add a "label" entry to the module's meta.json.`,autoFixable:!0}),o.is_available_for_new_content===!1&&s.push({severity:"info",rule:"module.meta.unavailable",file:i,message:`${n}: is_available_for_new_content=false (won\u2019t be selectable in HubSpot UI)`})):s.push({severity:"error",rule:"module.meta.missing",file:i,message:`${n}: meta.json is missing or invalid`,fix:"Recreate the module so meta.json is generated."});let r=X(t,"fields.json"),a=ht(e,r);if(!v(r))s.push({severity:"warning",rule:"module.fields.missing",file:a,message:`${n}: fields.json is missing`,fix:"Add a fields.json (an empty array [] is acceptable for static modules)."});else{let c=el(r);Array.isArray(c)?kg(c,n,a,s):s.push({severity:"warning",rule:"module.fields.invalid",file:a,message:`${n}: fields.json is not a JSON array`})}let l=X(t,"module.html");v(l)||s.push({severity:"error",rule:"module.html.missing",file:ht(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function kg(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)";Pt(i,"label")||s.push({severity:"error",rule:"module.field.label.missing",file:n,message:`${t}.${r}: field is missing "label"`,fix:`Add a human-readable "label" to the "${r}" field in fields.json.`,autoFixable:!0}),!Pt(i,"help_text")&&i.type!=="group"&&s.push({severity:"info",rule:"module.field.help_text.missing",file:n,message:`${t}.${r}: consider adding "help_text"`,fix:`Add a short "help_text" describing what "${r}" controls.`}),Array.isArray(i.children)&&kg(i.children,t,n,s)}}function Qv(e,t){let n=[],s=X(e,"css");Fi(s,".css").forEach(i=>{wg(i,n,e)});let o=X(e,"modules");if(v(o))for(let i of Qs(o)){if(!i.endsWith(".module"))continue;let r=X(o,i);["module.css","module.html"].forEach(a=>{let l=X(r,a);v(l)&&wg(l,n,e)})}for(let i of n)t.push({severity:"error",rule:"asset.cdn-import",file:i.file,message:`External CDN reference found: ${i.match}`,fix:"Remove external @import / <link> URLs and bundle the asset locally.",autoFixable:!0})}function wg(e,t,n){let s;try{s=M(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:ht(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:ht(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:ht(n,e),match:r[0]})}function ex(e,t){let n=[{rule:"asset.hardcoded.hubfs",re:/https?:\/\/[\w.-]*hubfs[\w.-]*\/(\d+)\//i,message:"Hardcoded portal-specific HubFS URL detected"},{rule:"asset.hardcoded.usercontent",re:/hubspotusercontent[-\w]*\.net\/(\w+\/)?(\d+)\//i,message:"Hardcoded portal-specific HubSpot user-content URL detected"},{rule:"asset.hardcoded.preview",re:/\d+\.hs-sites\.com|hubspotpagebuilder\.com\/\d+/i,message:"Hardcoded portal preview URL detected"}],s=[],o=X(e,"css");Fi(o,".css").forEach(a=>s.push(a));let i=X(e,"js");Fi(i,".js").forEach(a=>s.push(a));let r=X(e,"modules");if(v(r))for(let a of Qs(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=X(r,a,l);v(c)&&s.push(c)});for(let a of s){let l;try{l=M(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:ht(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function tx(e,t){let n=X(e,"modules");if(v(n))for(let s of Qs(n)){if(!s.endsWith(".module"))continue;let o=X(n,s,"module.html");if(!v(o))continue;let i;try{i=M(o)}catch{continue}let r=/<img\b([^>]*)>/gi,a;for(;a=r.exec(i);){let c=a[1];/\balt\s*=/.test(c)||t.push({severity:"warning",rule:"a11y.img.alt-missing",file:ht(e,o),message:`${s}: <img> without alt attribute`,fix:'Add an alt attribute (alt="" is fine for purely decorative images).'})}/<(section|article|header|footer|main|nav|aside|h[1-6])\b/i.test(i)||t.push({severity:"info",rule:"a11y.semantics.missing",file:ht(e,o),message:`${s}: module.html has no semantic landmarks (section/article/header/etc.)`,fix:"Wrap the module's main content in a <section> with a heading."})}}function nx(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Ht,message:"marketplace.json sidecar not found",fix:"Run `vibespot marketplace edit` (CLI) or open the Marketplace panel in the editor to fill in listing details."});return}e.category?en.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Ht,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${en.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Ht,message:"marketplace.json has no category",fix:`Pick one of: ${en.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Ht,message:"marketplace.json description is missing or short (<40 chars)",fix:"Provide a 1\u20132 sentence description of the theme for the Marketplace listing."}),e.supportUrl||t.push({severity:"warning",rule:"marketplace.json.supportUrl.missing",file:Ht,message:"marketplace.json has no supportUrl",fix:"Add a public support URL where buyers can reach the publisher."});let n=e.features?.length??0;n<2?t.push({severity:"warning",rule:"marketplace.json.features.too_few",file:Ht,message:`marketplace.json needs at least 2 features (has ${n})`,fix:"Add 2\u20135 short bullet points highlighting what the theme does well."}):n>5&&t.push({severity:"warning",rule:"marketplace.json.features.too_many",file:Ht,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function ji(e){let t=[],n=[],s=X(e,"modules");if(v(s))for(let i of Qs(s)){if(!i.endsWith(".module"))continue;let r=X(s,i),a=i.replace(/\.module$/,""),l=X(r,"meta.json");if(v(l))try{let d=JSON.parse(M(l));Pt(d,"label")||(d.label=Ag(a),H(l,JSON.stringify(d,null,2)+`
2823
+ `),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=X(r,"fields.json");if(v(c))try{let d=JSON.parse(M(c));if(Array.isArray(d)){let u=Cg(d);u>0&&(H(c,JSON.stringify(d,null,2)+`
2824
+ `),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=sx(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function sx(e){let t=[],n=/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,s=/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,o=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*><\/script>/gi,i=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*\/>/gi;function r(c){let d;try{d=M(c)}catch{return}let u=d.replace(n,"");u!==d&&(H(c,u),t.push(ht(e,c)))}function a(c){let d;try{d=M(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(H(c,u),t.push(ht(e,c)))}Fi(X(e,"css"),".css").forEach(r);let l=X(e,"modules");if(v(l))for(let c of Qs(l)){if(!c.endsWith(".module"))continue;let d=X(l,c),u=X(d,"module.css"),m=X(d,"module.html");v(u)&&r(u),v(m)&&a(m)}return t}function Cg(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!Pt(s,"label")&&Pt(s,"name")&&(s.label=Ag(String(s.name)),t++),Array.isArray(s.children)&&(t+=Cg(s.children))}return t}function el(e){if(!v(e))return null;try{let t=JSON.parse(M(e));return t&&typeof t=="object"?t:null}catch{return null}}function Pt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Tg(e,t){let n=t.replace(/^\.?\//,"");return X(e,n)}function ht(e,t){return Kv(e,t).split("\\").join("/")}function Qs(e){try{return tl(e)}catch{return[]}}function Fi(e,t){if(!v(e))return[];try{let n=[];for(let s of tl(e)){let o=X(e,s);Wv(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Ag(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var en,Vv,zv,Ht,nl=R(()=>{"use strict";y();ae();en=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],Vv=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],zv=["enable_domain_stylesheets","is_available_for_new_content"],Ht="marketplace.json"});function sl(e){let t=w();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Ae()}catch{}return t.themePath}function _g(e,t){let n=sl(t);if(!n)return;let s=Zs(n);p(t,200,{report:s,categories:en})}function $g(e,t){let n=sl(t);if(!n)return;let s=ji(n),o=Zs(n);p(t,200,{fix:s,report:o})}function Pg(e,t,n){let s=sl(n);if(s){if(e==="GET"){p(n,200,{metadata:es(s),categories:en});return}if(e==="POST"){Ze(t,n,o=>{let i={category:typeof o.category=="string"?o.category:void 0,description:typeof o.description=="string"?o.description:void 0,features:Array.isArray(o.features)?o.features.filter(r=>typeof r=="string"&&r.trim().length>0):void 0,supportUrl:typeof o.supportUrl=="string"?o.supportUrl:void 0,documentationUrl:typeof o.documentationUrl=="string"?o.documentationUrl:void 0,pricingTier:o.pricingTier==="free"||o.pricingTier==="paid"?o.pricingTier:void 0,tags:Array.isArray(o.tags)?o.tags.filter(r=>typeof r=="string"):void 0};Di(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Eg=R(()=>{"use strict";y();Qe();Ce();nl()});function ox(e){let t=w();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Ae()}catch{}return t.themePath}function Mg(e,t){let n=ox(t);if(!n)return;let s=ei(n);p(t,200,{report:s})}function Ig(e,t){let n=w();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=qt(n.themePath),o=dn(s);if(!o){p(t,200,{applied:!1,reason:"No tokens to apply."});return}if(!n.sharedCss||n.sharedCss.trim().length===0){n.sharedCss=o,n.updatedAt=Date.now(),F(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=ti(n.themePath,n.themeName);i?p(t,200,{applied:!0,written:i,rootBlock:o}):p(t,200,{applied:!1,reason:"Theme already has shared CSS."})}var Rg=R(()=>{"use strict";y();Qe();Ce();Cs()});import{createServer as ix}from"http";import{readFileSync as ol,existsSync as to}from"fs";import{join as Ut,extname as jg}from"path";import{WebSocketServer as rx,WebSocket as ax}from"ws";function z(e){Bi&&Bi.readyState===ax.OPEN&&Bi.send(JSON.stringify(e))}function Li(e){Hi.push(e),z(e)}function Oe(){Hi=[]}function Ji(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;Li(o)}else Li(n);if(n.type==="agent_step")e.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=e[e.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?Ue({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(Ue({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Vt(n.moduleOrder),Li({type:"modules_updated",modules:xe().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(Ue({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),Li({type:"modules_updated",modules:xe().map(s=>s.moduleName)}),t.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&t.push({name:n.module,status:"failed"})}}function eo(e){let t=e.cost;if(!t||t.calls===0)return;let n=w();z({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}async function lx(e=1e4){let t=Date.now();for(;$t()&&Date.now()-t<e;)await new Promise(n=>setTimeout(n,50))}function Bg(e,t){yn(e,{steps:t.steps,modules:t.modules,stats:e.stats,cost:e.cost}),eo(e);let n=w();if(n){Ae();let s=Te(),o=null;if(s){let i=s.moduleOrder.map(r=>`modules/${r}.module`);s.templateFile&&i.push(s.templateFile),s.sharedCss&&i.push(`css/${n.themeName}-theme.css`),s.sharedJs&&i.push(`js/${n.themeName}-animations.js`),o=Sr(n.themePath,s.id,t.commitLabel,i)}else o=ln(n.themePath,t.commitLabel);o&&z({type:"version_created",hash:o})}z({type:"generation_complete"});{let s=w();z({type:"modules_updated",modules:xe().map(o=>o.moduleName),templateId:s?.activeTemplateId||null,templates:(s?.templates||[]).map(o=>({id:o.id,label:o.label,pageType:o.pageType,moduleCount:o.modules.length}))})}Oe()}async function Ng(e,t){dt("user",e),F();try{z({type:"stream_status",content:"Planning..."});let n="",s=await Fa(e,i=>{n+=i,z({type:"stream",content:i})},t),o=Pm(s||n);if(o.plan){wi(o.plan),z({type:"plan_updated",plan:o.plan});let i=w();i&&(i.pendingCheckpoint={kind:"plan",resumeToken:"plan",preview:{kind:"plan",headline:"Plan ready for review",data:{plan:o.plan}},createdAt:new Date().toISOString()},F())}o.choices&&z({type:"plan_choices",question:o.choices.question,options:o.choices.options}),dt("assistant",o.cleanedContent),F(),z({type:"plan_complete",cleanedContent:o.cleanedContent}),z({type:"generation_complete"})}catch(n){z({type:"error",message:n instanceof Error?n.message:String(n)})}}async function Og(){let e=w();if(!e){z({type:"error",message:"No active session"});return}let t=e.brandAssets?.plan;if(!t||!t.trim()){z({type:"error",message:"No plan to approve. Send a chat message first."});return}q({planMode:!1}),e.pendingCheckpoint?.kind==="plan"&&(e.pendingCheckpoint=void 0);let n="Implement the approved plan.";dt("user",n),F();try{Oe();let s=[],o=[],i=await vi(n,Ji(s,o));if(i.canceled){Oe();return}Bg(i,{steps:s,modules:o,commitLabel:"Approved plan: implementation"})}catch(s){Oe(),z({type:"error",message:s instanceof Error?s.message:String(s)})}}function Fg(){let e=w();e?.pendingCheckpoint?.kind==="plan"&&(e.pendingCheckpoint=void 0),La(),q({planMode:!1}),F(),z({type:"plan_discarded"})}function Wn(){return Jg}function Ui(e){let{port:t,uiDir:n}=e;Jg=e.contentMode||"page";let s=ix((i,r)=>cx(i,r,n)),o=new rx({server:s});return o.on("connection",i=>ux(i)),new Promise((i,r)=>{s.on("error",a=>{a.code==="EADDRINUSE"?s.listen(t+1,"0.0.0.0",()=>{i({port:t+1,close:()=>{s.close(),o.close()}})}):r(a)}),s.listen(t,"0.0.0.0",()=>{i({port:t,close:()=>{s.close(),o.close()}})})})}function cx(e,t,n){let s=new URL(e.url||"/",`http://${e.headers.host}`),o=e.method||"GET";if(t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("X-XSS-Protection","1; mode=block"),t.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname==="/healthz"){t.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify({status:"ok"}));return}if(s.pathname.startsWith("/api/")){dx(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=Fr();t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",r=Dr(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){mx(s.pathname.slice(14),t);return}if(s.pathname==="/docs"){t.writeHead(301,{Location:"/docs/"}),t.end();return}if(s.pathname.startsWith("/docs/")){let i=s.pathname.slice(5)||"/index.html";Dg(i,Ut(n,"docs"),e,t);return}Dg(s.pathname,n,e,t)}function dx(e,t,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1|100\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|10\.\d+\.\d+\.\d+)(:\d+)?$/.test(o)&&s.setHeader("Access-Control-Allow-Origin",o),s.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type"),e==="OPTIONS"){s.writeHead(204),s.end();return}switch(t){case"/api/session":Xp(e,s);break;case"/api/modules":Zp(e,n,s);break;case"/api/modules/reorder":eg(n,s);break;case"/api/modules/code":Qp(n,s);break;case"/api/upload":tg(s);break;case"/api/upload-files":e==="POST"?Bd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":ng(n,s);break;case"/api/import":sg(n,s);break;case"/api/setup":Hm(s);break;case"/api/setup/create":Um(n,s);break;case"/api/setup/fetch":Wm(n,s);break;case"/api/setup/open":Km(n,s);break;case"/api/setup/resume":Vm(n,s);break;case"/api/setup/apikey":zm(n,s);break;case"/api/setup/remote-themes":e==="GET"?Ym(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?Gm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?sp(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/models":e==="GET"?op(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/tools":e==="GET"?ip(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?rp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?ap(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?lp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?cp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?dp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?up(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?mp(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?pp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?gp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?fp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Sp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?vp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?xp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:fl()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":kp(e,n,s);break;case"/api/themes/switch":e==="POST"?Cp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Tp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Ap(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?_p(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?og(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?ig(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Np(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Dp(e,n,s);break;case"/api/templates/activate":e==="POST"?jp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?Lp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?Jp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?Bp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?Hp(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":Gp(e,n,s);break;case"/api/brand-kit":Vp(e,n,s);break;case"/api/fonts":e==="GET"?Kp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?zp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?Yp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Fp(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?Ya(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?qa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?Xa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Cm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Am(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?_m(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?_g(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?$g(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Pg(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Mg(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Ig(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?yp(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?Up(t,n,s):p(s,404,{error:"Not found"})}}function ux(e){e.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{e.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;let i=Array.isArray(s.fileIds)?s.fileIds:void 0;$t()&&(Ma()&&z({type:"generation_superseded"}),await lx());{let a=w();a?.pendingCheckpoint&&(a.pendingCheckpoint=void 0,F())}if(Da()){await Ng(o,i);break}dt("user",o),F();let r=ja();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Oe();let l=[],c=[],d=!s.oneShot,u=await vi(o,Ji(l,c),i,d);if(u.canceled){Oe();break}if(u.pendingCheckpoint){let m=w();m&&(m.pendingCheckpoint=u.pendingCheckpoint,F()),eo(u),Oe();break}yn(u,{steps:l,modules:c,stats:u.stats,cost:u.cost}),eo(u)}else Ea(l=>{z({type:"parse_warning",message:l})}),await zs(o,l=>{z({type:"stream",content:l})},l=>{z({type:"stream_status",content:l})},i);let a=w();if(a){Ae();let l=Te(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${a.themeName}-theme.css`),l.sharedJs&&d.push(`js/${a.themeName}-animations.js`),c=Sr(a.themePath,l.id,o,d)}else c=ln(a.themePath,o);c&&z({type:"version_created",hash:c})}z({type:"generation_complete"});{let l=w();z({type:"modules_updated",modules:xe().map(c=>c.moduleName),templateId:l?.activeTemplateId||null,templates:(l?.templates||[]).map(c=>({id:c.id,label:c.label,pageType:c.pageType,moduleCount:c.modules.length}))})}Oe();{let l=w();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&z({type:"suggest_brand_extraction"})}}catch(a){Oe(),z({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:r}=await Promise.resolve().then(()=>(Za(),xg)),a=r(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=w();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:h}=await import("fs"),{createThemeScaffold:f}=await Promise.resolve().then(()=>(us(),Ll)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!h(b)){let{mkdirSync:x}=await import("fs");x(b,{recursive:!0})}h(S)||f(S,i),Jn(S,i),F()}z({type:"figma_import_started",fileName:a.fileName}),Oe();let c=[],d=[],u=await Ys(a,i,Ji(c,d));yn(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),eo(u),Ae(),ln(w().themePath,`Figma import: ${a.fileName}`),z({type:"generation_complete"});{let m=w();z({type:"modules_updated",modules:xe().map(g=>g.moduleName),templateId:m?.activeTemplateId||null,templates:(m?.templates||[]).map(g=>({id:g.id,label:g.label,pageType:g.pageType,moduleCount:g.modules.length}))})}Oe()}catch(l){Oe(),z({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=w();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=N(),{engine:r,apiKey:a,model:l}=hn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(_s(),si)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(yi(),hi)),m=await ze({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>se("extract-theme-context",()=>u(d,o.brandAssets?.themeContext,r,a,l))),{mkdirSync:g,writeFileSync:h}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let f=Ut(o.themePath,".vibespot");to(f)||g(f,{recursive:!0}),h(Ut(f,"theme-context.md"),m),F(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(Ks(),Ws)),b=await ze({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>se("extract-styleguide",()=>f(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=Ut(o.themePath,".vibespot");to(S)||g(S,{recursive:!0}),h(Ut(S,"styleguide.md"),b),F(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=w();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Ae();let i=Lo(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(N().hubspotUploadMode||"api")==="api"){let l=Be();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await Jo(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2761
2825
  `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
2762
2826
  `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
2763
- `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Lt();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:Ln()}))}else{let d=Co(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2764
- `),errors:d}))}}else{let l=si(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:jt(o.themePath,".."),timeout:18e4});e.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{e.send(JSON.stringify({type:"upload_output",chunk:u}))};ju(l,c);let d=setInterval(()=>{let u=ni(l);if(!(!u||u.status==="running"))if(clearInterval(d),Lu(l,c),u.status==="completed"){let m=ht(),g=m.portalId?es(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:Ln()}))}else{let m=ko(u.output);e.send(JSON.stringify({type:"upload_failed",output:u.output,errors:m,exitCode:u.exitCode}))}},500)}}catch(i){e.send(JSON.stringify({type:"error",message:i instanceof Error?i.message:String(i)}))}break}case"upload_fix_with_ai":{let o=String(s.errorContext||"");if(!o.trim()){e.send(JSON.stringify({type:"error",message:"No error context provided"}));break}let i=`The HubSpot upload ("hs cms upload") failed. Below is the upload log output containing the errors.
2827
+ `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Gt();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:Wn()}))}else{let d=Do(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2828
+ `),errors:d}))}}else{let l=Ci(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:Ut(o.themePath,".."),timeout:18e4});e.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{e.send(JSON.stringify({type:"upload_output",chunk:u}))};Im(l,c);let d=setInterval(()=>{let u=ki(l);if(!(!u||u.status==="running"))if(clearInterval(d),Rm(l,c),u.status==="completed"){let m=vt(),g=m.portalId?rs(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:Wn()}))}else{let m=jo(u.output);e.send(JSON.stringify({type:"upload_failed",output:u.output,errors:m,exitCode:u.exitCode}))}},500)}}catch(i){e.send(JSON.stringify({type:"error",message:i instanceof Error?i.message:String(i)}))}break}case"upload_fix_with_ai":{let o=String(s.errorContext||"");if(!o.trim()){e.send(JSON.stringify({type:"error",message:"No error context provided"}));break}let i=`The HubSpot upload ("hs cms upload") failed. Below is the upload log output containing the errors.
2765
2829
 
2766
2830
  IMPORTANT: Be verbose in your response. For each error:
2767
2831
  1. State exactly which file has the problem and what the error is
@@ -2774,27 +2838,27 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
2774
2838
  After fixing all errors, summarize the changes you made.
2775
2839
 
2776
2840
  Upload log:
2777
- ${o}`;lt("user",i),L(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await Ns(i,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=C();if(r){Te();let a=sn(r.themePath,"AI fix: upload errors");a&&e.send(JSON.stringify({type:"version_created",hash:a}))}e.send(JSON.stringify({type:"upload_fix_complete"}));{let a=C();e.send(JSON.stringify({type:"modules_updated",modules:ve().map(l=>l.moduleName),templateId:a?.activeTemplateId||null,templates:(a?.templates||[]).map(l=>({id:l.id,label:l.label,pageType:l.pageType,moduleCount:l.modules.length}))}))}}catch(r){e.send(JSON.stringify({type:"upload_failed",output:r instanceof Error?r.message:String(r),errors:[{file:"AI fix",message:r instanceof Error?r.message:String(r),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.brandAssets?.plan;if(!i||!i.trim()){e.send(JSON.stringify({type:"error",message:"No plan to approve. Send a chat message first."}));break}Y({planMode:!1});let r="Implement the approved plan.";lt("user",r),L();try{Dt();let a=[],l=[],c=await Qo(r,Ia(a,l));cn(c,{steps:a,modules:l,stats:c.stats,cost:c.cost}),Pa(c);let d=C();if(d){Te();let u=ke(),m=null;if(u){let g=u.moduleOrder.map(h=>`modules/${h}.module`);u.templateFile&&g.push(u.templateFile),u.sharedCss&&g.push(`css/${d.themeName}-theme.css`),u.sharedJs&&g.push(`js/${d.themeName}-animations.js`),m=or(d.themePath,u.id,"Approved plan: implementation",g)}else m=sn(d.themePath,"Approved plan: implementation");m&&Ae({type:"version_created",hash:m})}Ae({type:"generation_complete"});{let u=C();Ae({type:"modules_updated",modules:ve().map(m=>m.moduleName),templateId:u?.activeTemplateId||null,templates:(u?.templates||[]).map(m=>({id:m.id,label:m.label,pageType:m.pageType,moduleCount:m.modules.length}))})}Dt()}catch(a){Dt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{aa(),Y({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),ki=e;let t=C();if(t){let n=R(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Kt(),i=ke();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:ve().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:rt(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",updatedAt:t.updatedAt,templateId:i?.id||null,pageType:i?.pageType||null,templates:(t.templates||[]).map(r=>({id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||"",isGenerating:o,costTotal:t.costTotal||null})),o&&Ti.length>0)for(let r of Ti)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function ov(e,t){let n=C();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=jt(n.themePath,"assets",e);if(!Hs(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Kp(s),i=Vp[o]||"application/octet-stream",r=Na(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Wp(e,t,n,s){let i=jt(t,e==="/"?"/index.html":e);if(!Hs(i)){let c=jt(t,"index.html");if(Hs(c)){let d=Na(c);s.writeHead(200,{"Content-Type":"text/html","Cache-Control":"no-cache"}),s.end(d)}else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not found");return}let r=Kp(i),a=Vp[r]||"application/octet-stream",l=r===".html";try{let c=Na(i);s.writeHead(200,{"Content-Type":a,"Cache-Control":"no-store"}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}var Vp,ki,Ti,zp,vs=N(()=>{"use strict";y();Ce();In();Ss();Wn();Ru();Fu();ee();Qt();Ao();oi();nr();Xe();oe();Be();gi();Em();Nm();Lm();ap();yp();Dr();Ta();Bp();Gp();Vp={".html":"text/html",".css":"text/css",".js":"application/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".ico":"image/x-icon",".woff2":"font/woff2"},ki=null,Ti=[];zp="page"});y();y();import{Command as yv}from"commander";y();y();gt();oe();function Ee(){let e=I.vibes,t=I.accent,n=I.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${I.dim(`v${yn()}`)}`),console.log()}y();Qt();_t();qt();ee();en();Qe();gt();async function ao(){await ge("Checking your environment");let e=Zn();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),no(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),G(`Node.js v${e.version}`);let t=Qn();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),G(`Git ${t.version}`);let n=R(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Le(),S=Lt();if(b)o=S?.portalId||"",i=S?.portalName||"",G(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{se("No HubSpot account connected"),await yt(`You need a Personal Access Key to deploy themes.
2841
+ ${o}`;dt("user",i),F(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await zs(i,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=w();if(r){Ae();let a=ln(r.themePath,"AI fix: upload errors");a&&e.send(JSON.stringify({type:"version_created",hash:a}))}e.send(JSON.stringify({type:"upload_fix_complete"}));{let a=w();e.send(JSON.stringify({type:"modules_updated",modules:xe().map(l=>l.moduleName),templateId:a?.activeTemplateId||null,templates:(a?.templates||[]).map(l=>({id:l.id,label:l.label,pageType:l.pageType,moduleCount:l.modules.length}))}))}}catch(r){e.send(JSON.stringify({type:"upload_failed",output:r instanceof Error?r.message:String(r),errors:[{file:"AI fix",message:r instanceof Error?r.message:String(r),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{await Og();break}case"plan_discard":{Fg();break}case"checkpoint_resolve":{let o=w();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.pendingCheckpoint;if(!i){e.send(JSON.stringify({type:"error",message:"No checkpoint is awaiting resolution."}));break}let r=String(s.action||"");if(!["approve","steer","skip","cancel"].includes(r)){e.send(JSON.stringify({type:"error",message:`Invalid checkpoint action: ${r}`}));break}let a=Array.isArray(s.outline)?s.outline.filter(d=>!!d&&typeof d.name=="string").map(d=>({name:String(d.name),description:typeof d.description=="string"?d.description:void 0,sourceIndex:Number.isInteger(d.sourceIndex)?d.sourceIndex:void 0})):void 0,l={kind:i.kind,action:r,note:typeof s.note=="string"?s.note:void 0,outline:a,...i.kind==="brand_intake"&&s.brandIntake&&typeof s.brandIntake=="object"?{brandIntake:s.brandIntake}:{}};if(i.kind==="plan"){o.pendingCheckpoint=void 0,F(),r==="cancel"?Fg():r==="steer"?await Ng(l.note?.trim()||"Refine the plan further."):await Og();break}let c=i.resumeToken;o.pendingCheckpoint=void 0,F();try{Oe();let d=[],u=[],m=await Oa(c,l,Ji(d,u),i.resumeState);if(m.canceled){z({type:"checkpoint_cancelled"}),z({type:"generation_complete"}),Oe();break}if(m.pendingCheckpoint){let g=w();g&&(g.pendingCheckpoint=m.pendingCheckpoint,F()),eo(m),Oe();break}Bg(m,{steps:d,modules:u,commitLabel:"Checkpoint approved: implementation"})}catch(d){Oe(),z({type:"error",message:d instanceof Error?d.message:String(d)})}break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),Bi=e;let t=w();if(t){let n=N(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=$t(),i=Te();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:xe().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:lt(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",updatedAt:t.updatedAt,templateId:i?.id||null,pageType:i?.pageType||null,templates:(t.templates||[]).map(r=>({id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||"",isGenerating:o,pendingCheckpoint:t.pendingCheckpoint?{...t.pendingCheckpoint,resumeState:void 0}:null,costTotal:t.costTotal||null})),o&&Hi.length>0)for(let r of Hi)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function mx(e,t){let n=w();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=Ut(n.themePath,"assets",e);if(!to(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=jg(s),i=Lg[o]||"application/octet-stream",r=ol(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Dg(e,t,n,s){let i=Ut(t,e==="/"?"/index.html":e);if(!to(i)){let c=Ut(t,"index.html");if(to(c)){let d=ol(c);s.writeHead(200,{"Content-Type":"text/html","Cache-Control":"no-cache"}),s.end(d)}else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not found");return}let r=jg(i),a=Lg[r]||"application/octet-stream",l=r===".html";try{let c=ol(i);s.writeHead(200,{"Content-Type":a,"Cache-Control":"no-store"}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}var Lg,Bi,Hi,Jg,$s=R(()=>{"use strict";y();Ce();jn();_s();qn();$m();Em();oe();on();Bo();Ti();yr();Qe();ae();He();Ei();bp();wp();$p();qp();rg();Zr();Za();Eg();Rg();Lg={".html":"text/html",".css":"text/css",".js":"application/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".ico":"image/x-icon",".woff2":"font/woff2"},Bi=null,Hi=[];Jg="page"});y();y();import{Command as Tx}from"commander";y();y();bt();ae();function $e(){let e=E.vibes,t=E.accent,n=E.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${E.dim(`v${Tn()}`)}`),console.log()}y();on();It();tn();oe();rn();nt();bt();async function vo(){await fe("Checking your environment");let e=os();e.found||(Y("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),fo(e.version)||(Y(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),W(`Node.js v${e.version}`);let t=is();t.found||(Y("Git not found. Install it from https://git-scm.com"),process.exit(1)),W(`Git ${t.version}`);let n=N(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Be(),S=Gt();if(b)o=S?.portalId||"",i=S?.portalName||"",W(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{ie("No HubSpot account connected"),await xt(`You need a Personal Access Key to deploy themes.
2778
2842
  Create one at: https://app.hubspot.com/l/personal-access-key
2779
- Make sure the Content scope is enabled.`,"HubSpot connection required");let v=await Se({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:M=>M.trim()?void 0:"Key is required"}),w=await De();w.start("Validating key...");try{let M=await io(v);qn(v,M.portalId,M.portalName,M.dataCenter),b=v,o=M.portalId,i=M.portalName,w.stop(`Connected to ${M.portalName} (${M.portalId})`)}catch(M){w.stop("Validation failed"),V(`Invalid key: ${M instanceof Error?M.message:String(M)}`),process.exit(1)}}}else{let b=ft();if(b.found)G(`HubSpot CLI v${b.version}`);else{se("HubSpot CLI not found"),await Me({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let w=await De();w.start("Installing HubSpot CLI..."),ie("npm install -g @hubspot/cli").success||(w.stop("Failed"),V("Try: npm install -g @hubspot/cli"),process.exit(1)),b=ft(),w.stop(`HubSpot CLI v${b.version} installed`)}let S=ht();if(S.authenticated)G(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{se("HubSpot not authenticated"),await Me({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let w=await De();w.start("Waiting for HubSpot authentication..."),Ka("hs init")||(w.stop("Authentication failed"),process.exit(1)),S=ht(),w.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,i=S.portalName}let r=wn(),a=Cn(),l=kn(),c=Qa(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex","langdock-api":"Langdock (EU)"},u=Ze(),m,g=n.aiEngine,h=[];if(r.found&&h.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&h.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&h.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&h.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&h.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&h.sort((b,S)=>b.value===g?-1:S.value===g?1:0),h.length===1)m=h[0].value,G(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await Et({message:"Choose your AI engine:",options:h});else if(await yt(`You need an AI coding assistant to power the conversion.
2843
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let x=await ve({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:$=>$.trim()?void 0:"Key is required"}),k=await je();k.start("Validating key...");try{let $=await bo(x);ns(x,$.portalId,$.portalName,$.dataCenter),b=x,o=$.portalId,i=$.portalName,k.stop(`Connected to ${$.portalName} (${$.portalId})`)}catch($){k.stop("Validation failed"),Y(`Invalid key: ${$ instanceof Error?$.message:String($)}`),process.exit(1)}}}else{let b=St();if(b.found)W(`HubSpot CLI v${b.version}`);else{ie("HubSpot CLI not found"),await Pe({message:"Install HubSpot CLI globally?"})||(Y("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let k=await je();k.start("Installing HubSpot CLI..."),le("npm install -g @hubspot/cli").success||(k.stop("Failed"),Y("Try: npm install -g @hubspot/cli"),process.exit(1)),b=St(),k.stop(`HubSpot CLI v${b.version} installed`)}let S=vt();if(S.authenticated)W(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{ie("HubSpot not authenticated"),await Pe({message:"Run `hs init` now?"})||(Y("Run `hs init` manually."),process.exit(1));let k=await je();k.start("Waiting for HubSpot authentication..."),yl("hs init")||(k.stop("Authentication failed"),process.exit(1)),S=vt(),k.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,i=S.portalName}let r=En(),a=Mn(),l=In(),c=Cl(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex","langdock-api":"Langdock (EU)"},u=tt(),m,g=n.aiEngine,h=[];if(r.found&&h.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&h.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&h.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&h.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&h.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&h.sort((b,S)=>b.value===g?-1:S.value===g?1:0),h.length===1)m=h[0].value,W(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await Nt({message:"Choose your AI engine:",options:h});else if(await xt(`You need an AI coding assistant to power the conversion.
2780
2844
 
2781
- ${I.bold("Option 1:")} Install Claude Code ${I.muted("(recommended)")}
2845
+ ${E.bold("Option 1:")} Install Claude Code ${E.muted("(recommended)")}
2782
2846
  https://claude.ai/code
2783
2847
 
2784
- ${I.bold("Option 2:")} Install Gemini CLI
2848
+ ${E.bold("Option 2:")} Install Gemini CLI
2785
2849
  https://github.com/google-gemini/gemini-cli
2786
2850
 
2787
- ${I.bold("Option 3:")} Install OpenAI Codex
2851
+ ${E.bold("Option 3:")} Install OpenAI Codex
2788
2852
  https://github.com/openai/codex
2789
2853
 
2790
- ${I.bold("Option 4:")} Set an Anthropic API key
2854
+ ${E.bold("Option 4:")} Set an Anthropic API key
2791
2855
  export ANTHROPIC_API_KEY=sk-ant-...
2792
- (get one at https://console.anthropic.com)`,"AI engine required"),m=await Et({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),m==="api"){let b=await Se({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:S=>S.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,Y({anthropicApiKey:b})}let f;return m==="claude-code"&&(f=await Et({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),Y({aiEngine:m}),await fe("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}co();y();qt();oe();Qe();gt();ee();is();uo();import{join as as}from"path";async function mo(){await ge("HubSpot Theme Setup");let e=await Et({message:"Do you have an existing HubSpot theme?",options:[{value:"fetch",label:"Fetch my existing theme from HubSpot",hint:"downloads your current theme"},{value:"create",label:"Start fresh (HubSpot Boilerplate)",hint:"creates a new starter theme"}]}),t,n,s=as(process.cwd(),"workspace");if(Re(s),e==="fetch"){t=await Se({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=as(s,t);let l=await De();l.start("Fetching theme from HubSpot...");let c=R(),d=Le();if(c.hubspotUploadMode==="cli"||!d)ie(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),V(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await rs(d,t,n)}catch(u){l.stop("Fetch failed"),V(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${I.dim(n)}`)}else{t=await Se({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=as(s,t);let l=await De();l.start("Creating theme...");try{os(n,t)}catch(c){l.stop("Creation failed"),V(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${I.dim(n)}`)}await ge("Checking theme compatibility");let o=as(n,"templates/layouts/base.html");x(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),G("base.html found");let i=P(o),r=!1;if(i.includes("template_css"))G("template_css support");else{se("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2856
+ (get one at https://console.anthropic.com)`,"AI engine required"),m=await Nt({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),m==="api"){let b=await ve({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:S=>S.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,q({anthropicApiKey:b})}let f;return m==="claude-code"&&(f=await Nt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),q({aiEngine:m}),await he("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}wo();y();tn();ae();nt();bt();oe();us();ko();import{join as ps}from"path";async function Co(){await fe("HubSpot Theme Setup");let e=await Nt({message:"Do you have an existing HubSpot theme?",options:[{value:"fetch",label:"Fetch my existing theme from HubSpot",hint:"downloads your current theme"},{value:"create",label:"Start fresh (HubSpot Boilerplate)",hint:"creates a new starter theme"}]}),t,n,s=ps(process.cwd(),"workspace");if(Ie(s),e==="fetch"){t=await ve({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=ps(s,t);let l=await je();l.start("Fetching theme from HubSpot...");let c=N(),d=Be();if(c.hubspotUploadMode==="cli"||!d)le(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),Y(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await ms(d,t,n)}catch(u){l.stop("Fetch failed"),Y(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${E.dim(n)}`)}else{t=await ve({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=ps(s,t);let l=await je();l.start("Creating theme...");try{ds(n,t)}catch(c){l.stop("Creation failed"),Y(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${E.dim(n)}`)}await fe("Checking theme compatibility");let o=ps(n,"templates/layouts/base.html");v(o)||(Y(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),W("base.html found");let i=M(o),r=!1;if(i.includes("template_css"))W("template_css support");else{ie("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2793
2857
  `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
2794
2858
  `,l);i=i.slice(0,c)+`
2795
2859
  {% if template_css %}
2796
2860
  {{ require_css(get_asset_url(template_css)) }}
2797
- {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))G("template_js support");else{se("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2861
+ {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))W("template_js support");else{ie("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2798
2862
  `,l),d=i.indexOf(`
2799
2863
  `,c+1),u=`
2800
2864
  {% if template_js %}
@@ -2802,17 +2866,17 @@ ${I.bold("Option 4:")} Set an Anthropic API key
2802
2866
  {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
2803
2867
  `)+1;i=i.slice(0,i.indexOf(`
2804
2868
  `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
2805
- `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await De();l.start("Patching base.html..."),B(o,i),l.stop("base.html patched with template_css/template_js support")}let a=as(n,".hsignore");if(x(a)){let l=P(a);l.includes("docs/")||(B(a,l+`
2869
+ `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await je();l.start("Patching base.html..."),H(o,i),l.stop("base.html patched with template_css/template_js support")}let a=ps(n,".hsignore");if(v(a)){let l=M(a);l.includes("docs/")||(H(a,l+`
2806
2870
  docs/
2807
- `),G("Added docs/ to .hsignore"))}else B(a,`docs/
2871
+ `),W("Added docs/ to .hsignore"))}else H(a,`docs/
2808
2872
  *.md
2809
2873
  node_modules/
2810
2874
  .git
2811
- `),G("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}y();import{join as nt}from"path";import{readdirSync as ds,rmSync as Nl}from"fs";y();Ke();oe();import{spawn as Dg}from"child_process";import{join as Q,basename as jg}from"path";import{readdirSync as bt,statSync as Tl,writeFileSync as Lg}from"fs";var Jg=new Set(["about.html","blog-index.html","blog-post.html","contact.html","home.html","hubdb.html","landing-page.html","pricing.html","qa-test.html","base.html"]),po=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(t){this.model=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(Q(s,"css")),c=this.listDir(Q(s,"js")),d=this.listDir(Q(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${r} source components found)...`);let m="",g="",h=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((v,w)=>{let M={...process.env};delete M.CLAUDECODE;let j=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&j.push("--model",this.model);let J=Dg("claude",j,{cwd:s,stdio:["pipe","pipe","pipe"],env:M,shell:!0});J.stdout.on("data",H=>{m+=H.toString()}),J.stderr.on("data",H=>{g+=H.toString()}),J.on("error",H=>w(new Error(`Claude Code failed to start: ${H.message}`))),J.on("close",H=>{H!==0?w(new Error(`Claude Code exited with code ${H}.
2875
+ `),W("Created .hsignore");return await he("Theme ready!"),{themePath:n,themeName:t}}y();import{join as ot}from"path";import{readdirSync as bs,rmSync as rc}from"fs";y();Ve();ae();import{spawn as If}from"child_process";import{join as ne,basename as Rf}from"path";import{readdirSync as wt,statSync as ql,writeFileSync as Nf}from"fs";var Of=new Set(["about.html","blog-index.html","blog-post.html","contact.html","home.html","hubdb.html","landing-page.html","pricing.html","qa-test.html","base.html"]),To=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(t){this.model=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||be();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(ne(s,"css")),c=this.listDir(ne(s,"js")),d=this.listDir(ne(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${r} source components found)...`);let m="",g="",h=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((x,k)=>{let $={...process.env};delete $.CLAUDECODE;let L=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&L.push("--model",this.model);let j=If("claude",L,{cwd:s,stdio:["pipe","pipe","pipe"],env:$,shell:!0});j.stdout.on("data",J=>{m+=J.toString()}),j.stderr.on("data",J=>{g+=J.toString()}),j.on("error",J=>k(new Error(`Claude Code failed to start: ${J.message}`))),j.on("close",J=>{J!==0?k(new Error(`Claude Code exited with code ${J}.
2812
2876
  `+(g?`Stderr: ${g.slice(0,500)}
2813
- `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):v()}),J.stdin.on("error",()=>{}),J.stdin.write(u),J.stdin.end(),setTimeout(()=>{J.kill(),w(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let f=Q(s,"..","vibespot-conversion.log");try{let w=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
2877
+ `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):x()}),j.stdin.on("error",()=>{}),j.stdin.write(u),j.stdin.end(),setTimeout(()=>{j.kill(),k(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let f=ne(s,"..","vibespot-conversion.log");try{let k=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
2814
2878
  ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
2815
- `);Lg(f,w,"utf-8"),o("status",`Log written to ${jg(f)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(v=>!a.has(v.moduleName+".module")).length===0){let v=m.slice(0,1500)||"(no output)",w=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
2879
+ `);Nf(f,k,"utf-8"),o("status",`Log written to ${Rf(f)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(x=>!a.has(x.moduleName+".module")).length===0){let x=m.slice(0,1500)||"(no output)",k=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
2816
2880
 
2817
2881
  This usually means the model described the conversion instead of using Write tool to create files.
2818
2882
 
@@ -2823,12 +2887,12 @@ Possible causes:
2823
2887
 
2824
2888
  Source: ${t.sourceDir}
2825
2889
  Theme: ${s}
2826
- `+(w?`
2890
+ `+(k?`
2827
2891
  Stderr:
2828
- ${w}
2892
+ ${k}
2829
2893
  `:"")+`
2830
2894
  Claude output:
2831
- ${v}`)}return b}reportProgress(t,n,s,o,i,r){let a=0,l=this.listDir(Q(t,"css"));for(let m of l){if(s.has(m)||!m.endsWith(".css"))continue;let g=`css:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared CSS (${m})`),a++)}let c=this.listDir(Q(t,"js"));for(let m of c){if(o.has(m)||!m.endsWith(".js"))continue;let g=`js:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared JS (${m})`),a++)}this.expectedModules===0&&(this.expectedModules=this.detectExpectedModules(t,i));let d=this.listModules(t);for(let m of d){if(n.has(m))continue;let g=`module:${m}`;if(!this.reported.has(g)){this.reported.add(g),this.moduleCount++;let h=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;r("created",`Module ${h}: ${m.replace(".module","")}`),a++}}let u=this.listDir(Q(t,"templates"));for(let m of u){if(i.has(m)||!m.endsWith(".html"))continue;let g=`template:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Page template (${m})`),a++)}if(a===0)if(this.moduleCount>0){let m=this.expectedModules>0?`/${this.expectedModules}`:"";r("status",`${this.moduleCount}${m} modules created, conversion continuing...`)}else this.reported.size>0?r("status","Shared assets created, building modules..."):r("status","Claude Code is analyzing source files...")}buildFullPrompt(t,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
2895
+ ${x}`)}return b}reportProgress(t,n,s,o,i,r){let a=0,l=this.listDir(ne(t,"css"));for(let m of l){if(s.has(m)||!m.endsWith(".css"))continue;let g=`css:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared CSS (${m})`),a++)}let c=this.listDir(ne(t,"js"));for(let m of c){if(o.has(m)||!m.endsWith(".js"))continue;let g=`js:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared JS (${m})`),a++)}this.expectedModules===0&&(this.expectedModules=this.detectExpectedModules(t,i));let d=this.listModules(t);for(let m of d){if(n.has(m))continue;let g=`module:${m}`;if(!this.reported.has(g)){this.reported.add(g),this.moduleCount++;let h=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;r("created",`Module ${h}: ${m.replace(".module","")}`),a++}}let u=this.listDir(ne(t,"templates"));for(let m of u){if(i.has(m)||!m.endsWith(".html"))continue;let g=`template:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Page template (${m})`),a++)}if(a===0)if(this.moduleCount>0){let m=this.expectedModules>0?`/${this.expectedModules}`:"";r("status",`${this.moduleCount}${m} modules created, conversion continuing...`)}else this.reported.size>0?r("status","Shared assets created, building modules..."):r("status","Claude Code is analyzing source files...")}buildFullPrompt(t,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
2832
2896
 
2833
2897
  SOURCE DIRECTORY: ${t}
2834
2898
  THEME DIRECTORY: ${n}
@@ -2874,13 +2938,13 @@ HUBSPOT CMS RULES:
2874
2938
  ${Je()}
2875
2939
 
2876
2940
  CONVERSION GUIDE:
2877
- ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Q(t,"css");if(x(s)){for(let a of bt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Q(s,a));break}}let o=Q(t,"js");if(x(o)){for(let a of bt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Q(o,a));break}}let i=Q(t,"templates");if(x(i)){for(let a of bt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=P(Q(i,a));break}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!Jg.has(a)&&!a.startsWith("system")){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=Q(t,"modules");if(x(r))for(let a of bt(r)){if(!a.endsWith(".module"))continue;let l=Q(r,a);if(!Tl(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Q(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Q(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Q(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Q(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Q(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=Q(t,"modules");return x(n)?new Set(bt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return x(t)?new Set(bt(t)):new Set}detectExpectedModules(t,n){let s=Q(t,"templates");if(!x(s))return 0;for(let o of bt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=P(Q(s,o));if(i.includes("dnd_area")){let r=i.match(/dnd_module/g);return r?r.length:0}}catch{}return 0}countSourceComponents(t){let n=Q(t,"src");return x(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of bt(t)){let o=Q(t,s);try{Tl(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};y();Ke();oe();Be();tn();import rf from"@anthropic-ai/sdk";import{join as ce,basename as af}from"path";import{readdirSync as Pl}from"fs";var yo=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new rf({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=vl(o),a=af(n)||"page",l=a.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);i("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(r,wl(c,d,l)),m=ce(s,"css",`${l}-theme.css`);B(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),h=this.findInteractiveComponents(n),f=await this.complete(r,Cl(g,h,l)),b=ce(s,"js",`${l}-animations.js`);B(b,f),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let S=this.findComponents(n),v=[];for(let J=0;J<S.length;J++){let H=S[J],K=H.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${K}.module (${J+1}/${S.length})...`);let X=P(H.path),O=await this.complete(r,xl(X,K,`See css/${l}-theme.css`));try{let k=JSON.parse(O),T={moduleName:K,fieldsJson:typeof k.fieldsJson=="string"?k.fieldsJson:JSON.stringify(k.fieldsJson,null,2),metaJson:typeof k.metaJson=="string"?k.metaJson:JSON.stringify(k.metaJson,null,2),moduleHtml:k.moduleHtml||"",moduleCss:k.moduleCss||"",moduleJs:k.moduleJs||void 0},$=ce(s,"modules",`${K}.module`);Re($),B(ce($,"fields.json"),T.fieldsJson),B(ce($,"meta.json"),T.metaJson),B(ce($,"module.html"),T.moduleHtml),B(ce($,"module.css"),T.moduleCss),T.moduleJs&&B(ce($,"module.js"),T.moduleJs),v.push(T),i("module-done",`${K}.module (${this.countFiles(T)} files)`)}catch{i("module-error",`Failed to parse ${K} \u2014 skipping`)}}i("template","Creating page template...");let w=v.map(J=>J.moduleName),M=await this.complete(r,kl(w,a,l)),j=ce(s,"templates",`lp-${l}.html`);return B(j,M),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:M,modules:v}}async complete(t,n){let s=new Date,o=await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]}),r=o.content.find(a=>a.type==="text")?.text||"";return St({engine:"anthropic-api",model:this.model,name:"react-conversion",input:{system:t,messages:[{role:"user",content:n}]},output:r,usage:et(o.usage),startTime:s,endTime:new Date}),r}findAndReadCSS(t){let n=[ce(t,"src/index.css"),ce(t,"src/globals.css"),ce(t,"src/app/globals.css"),ce(t,"app/globals.css")];for(let s of n)if(x(s))return P(s);return""}findAndReadTailwind(t){let n=[ce(t,"tailwind.config.ts"),ce(t,"tailwind.config.js"),ce(t,"tailwind.config.mjs")];for(let s of n)if(x(s))return P(s);return""}findAndReadHooks(t){let n=ce(t,"src/hooks");if(!x(n))return"";try{return Pl(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2878
- ${P(ce(n,s))}`).join(`
2941
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ne(t,"css");if(v(s)){for(let a of wt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(ne(s,a));break}}let o=ne(t,"js");if(v(o)){for(let a of wt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(ne(o,a));break}}let i=ne(t,"templates");if(v(i)){for(let a of wt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=M(ne(i,a));break}if(!n.template){for(let a of wt(i))if(a.endsWith(".html")&&!Of.has(a)&&!a.startsWith("system")){let l=M(ne(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of wt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(ne(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=ne(t,"modules");if(v(r))for(let a of wt(r)){if(!a.endsWith(".module"))continue;let l=ne(r,a);if(!ql(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=ne(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=ne(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=ne(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=ne(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=ne(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=ne(t,"modules");return v(n)?new Set(wt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return v(t)?new Set(wt(t)):new Set}detectExpectedModules(t,n){let s=ne(t,"templates");if(!v(s))return 0;for(let o of wt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=M(ne(s,o));if(i.includes("dnd_area")){let r=i.match(/dnd_module/g);return r?r.length:0}}catch{}return 0}countSourceComponents(t){let n=ne(t,"src");return v(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of wt(t)){let o=ne(t,s);try{ql(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};y();Ve();ae();He();an();import eh from"@anthropic-ai/sdk";import{join as ue,basename as th}from"path";import{readdirSync as ic}from"fs";var Mo=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new eh({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=Wl(o),a=th(n)||"page",l=a.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);i("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(r,Vl(c,d,l)),m=ue(s,"css",`${l}-theme.css`);H(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),h=this.findInteractiveComponents(n),f=await this.complete(r,zl(g,h,l)),b=ue(s,"js",`${l}-animations.js`);H(b,f),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let S=this.findComponents(n),x=[];for(let j=0;j<S.length;j++){let J=S[j],V=J.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${V}.module (${j+1}/${S.length})...`);let D=M(J.path),U=await this.complete(r,Kl(D,V,`See css/${l}-theme.css`));try{let C=JSON.parse(U),P={moduleName:V,fieldsJson:typeof C.fieldsJson=="string"?C.fieldsJson:JSON.stringify(C.fieldsJson,null,2),metaJson:typeof C.metaJson=="string"?C.metaJson:JSON.stringify(C.metaJson,null,2),moduleHtml:C.moduleHtml||"",moduleCss:C.moduleCss||"",moduleJs:C.moduleJs||void 0},O=ue(s,"modules",`${V}.module`);Ie(O),H(ue(O,"fields.json"),P.fieldsJson),H(ue(O,"meta.json"),P.metaJson),H(ue(O,"module.html"),P.moduleHtml),H(ue(O,"module.css"),P.moduleCss),P.moduleJs&&H(ue(O,"module.js"),P.moduleJs),x.push(P),i("module-done",`${V}.module (${this.countFiles(P)} files)`)}catch{i("module-error",`Failed to parse ${V} \u2014 skipping`)}}i("template","Creating page template...");let k=x.map(j=>j.moduleName),$=await this.complete(r,Yl(k,a,l)),L=ue(s,"templates",`lp-${l}.html`);return H(L,$),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:$,modules:x}}async complete(t,n){let s=new Date,o=await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]}),r=o.content.find(a=>a.type==="text")?.text||"";return kt({engine:"anthropic-api",model:this.model,name:"react-conversion",input:{system:t,messages:[{role:"user",content:n}]},output:r,usage:st(o.usage),startTime:s,endTime:new Date}),r}findAndReadCSS(t){let n=[ue(t,"src/index.css"),ue(t,"src/globals.css"),ue(t,"src/app/globals.css"),ue(t,"app/globals.css")];for(let s of n)if(v(s))return M(s);return""}findAndReadTailwind(t){let n=[ue(t,"tailwind.config.ts"),ue(t,"tailwind.config.js"),ue(t,"tailwind.config.mjs")];for(let s of n)if(v(s))return M(s);return""}findAndReadHooks(t){let n=ue(t,"src/hooks");if(!v(n))return"";try{return ic(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2942
+ ${M(ue(n,s))}`).join(`
2879
2943
 
2880
- `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=P(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
2944
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=M(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
2881
2945
  ${i}`)}return s.join(`
2882
2946
 
2883
- `)}findComponents(t){let n=[ce(t,"src/components/landing"),ce(t,"src/components/sections"),ce(t,"src/components")];for(let s of n)if(x(s))try{return Pl(s).filter(o=>(o.endsWith(".tsx")||o.endsWith(".jsx"))&&!o.startsWith("ui")&&o!=="index.tsx"&&o!=="index.jsx").map(o=>({name:o.replace(/\.(tsx|jsx)$/,""),path:ce(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();Ke();oe();import{spawn as lf}from"child_process";import{join as Ve}from"path";import{readdirSync as bo,statSync as cf}from"fs";var So=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((a,l)=>{let c=lf("gemini",["-p",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Gemini CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Gemini CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Gemini CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
2947
+ `)}findComponents(t){let n=[ue(t,"src/components/landing"),ue(t,"src/components/sections"),ue(t,"src/components")];for(let s of n)if(v(s))try{return ic(s).filter(o=>(o.endsWith(".tsx")||o.endsWith(".jsx"))&&!o.startsWith("ui")&&o!=="index.tsx"&&o!=="index.jsx").map(o=>({name:o.replace(/\.(tsx|jsx)$/,""),path:ue(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();Ve();ae();import{spawn as nh}from"child_process";import{join as Ye}from"path";import{readdirSync as Io,statSync as sh}from"fs";var Ro=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||be(),r=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((a,l)=>{let c=nh("gemini",["-p",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Gemini CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Gemini CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Gemini CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
2884
2948
 
2885
2949
  INSTRUCTIONS:
2886
2950
  1. Analyze all .tsx/.jsx components in the React source
@@ -2895,7 +2959,7 @@ CONVERSION GUIDE:
2895
2959
  ${s}
2896
2960
 
2897
2961
  Do NOT run hs upload \u2014 I will handle that separately.
2898
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ve(t,"css");if(x(s)){for(let a of bo(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Ve(s,a));break}}let o=Ve(t,"js");if(x(o)){for(let a of bo(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Ve(o,a));break}}let i=Ve(t,"templates");if(x(i)){for(let a of bo(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Ve(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ve(t,"modules");if(x(r))for(let a of bo(r)){if(!a.endsWith(".module"))continue;let l=Ve(r,a);if(!cf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ve(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Ve(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Ve(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Ve(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Ve(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ke();oe();import{spawn as df}from"child_process";import{join as ze}from"path";import{readdirSync as vo,statSync as uf}from"fs";var xo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((a,l)=>{let c=df("codex",["exec","--full-auto",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Codex CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Codex CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Codex CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
2962
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ye(t,"css");if(v(s)){for(let a of Io(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(Ye(s,a));break}}let o=Ye(t,"js");if(v(o)){for(let a of Io(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(Ye(o,a));break}}let i=Ye(t,"templates");if(v(i)){for(let a of Io(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(Ye(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ye(t,"modules");if(v(r))for(let a of Io(r)){if(!a.endsWith(".module"))continue;let l=Ye(r,a);if(!sh(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ye(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=Ye(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=Ye(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=Ye(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=Ye(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ve();ae();import{spawn as oh}from"child_process";import{join as qe}from"path";import{readdirSync as No,statSync as ih}from"fs";var Oo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||be(),r=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((a,l)=>{let c=oh("codex",["exec","--full-auto",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Codex CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Codex CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Codex CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
2899
2963
 
2900
2964
  INSTRUCTIONS:
2901
2965
  1. Analyze all .tsx/.jsx components in the React source
@@ -2910,15 +2974,15 @@ CONVERSION GUIDE:
2910
2974
  ${s}
2911
2975
 
2912
2976
  Do NOT run hs upload \u2014 I will handle that separately.
2913
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ze(t,"css");if(x(s)){for(let a of vo(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(ze(s,a));break}}let o=ze(t,"js");if(x(o)){for(let a of vo(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(ze(o,a));break}}let i=ze(t,"templates");if(x(i)){for(let a of vo(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(ze(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=ze(t,"modules");if(x(r))for(let a of vo(r)){if(!a.endsWith(".module"))continue;let l=ze(r,a);if(!uf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=ze(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=ze(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=ze(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=ze(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=ze(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ke();oe();Qe();function mf(e,t){switch(e){case"claude-code":return new po(t);case"gemini-cli":return new So;case"codex-cli":return new xo;case"api":return new yo}}async function wo(e){await ge("Converting React to HubSpot Modules"),await yt(`AI will now analyze your React code and create
2914
- HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=mf(e.aiEngine,e.model),n=ye(),s=await De();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(h,f)=>{h==="created"?G(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=pf(e.themePath);for(let h of a)G(`Auto-fixed: ${h}`);let l=gf(e.themePath,i),c=[];for(let h of l){let f=h.passed?"\u2705":"\u274C",b=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${f} ${h.label}${b}`)}let d=l.filter(h=>h.passed).length;c.push(`
2915
- ${d}/${l.length} checks passed`),await yt(c.join(`
2916
- `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(V(`${u.length} critical issue(s) \u2014 upload will likely fail:
2977
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=qe(t,"css");if(v(s)){for(let a of No(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(qe(s,a));break}}let o=qe(t,"js");if(v(o)){for(let a of No(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(qe(o,a));break}}let i=qe(t,"templates");if(v(i)){for(let a of No(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(qe(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=qe(t,"modules");if(v(r))for(let a of No(r)){if(!a.endsWith(".module"))continue;let l=qe(r,a);if(!ih(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=qe(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=qe(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=qe(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=qe(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=qe(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ve();ae();nt();function rh(e,t){switch(e){case"claude-code":return new To(t);case"gemini-cli":return new Ro;case"codex-cli":return new Oo;case"api":case"anthropic-api":case"claude-oauth":return new Mo;default:throw new Error(`The wizard does not support the "${e}" engine. Use claude-code, gemini-cli, codex-cli, or the Anthropic API.`)}}async function Fo(e){await fe("Converting React to HubSpot Modules"),await xt(`AI will now analyze your React code and create
2978
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=rh(e.aiEngine,e.model),n=be(),s=await je();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(h,f)=>{h==="created"?W(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=ah(e.themePath);for(let h of a)W(`Auto-fixed: ${h}`);let l=lh(e.themePath,i),c=[];for(let h of l){let f=h.passed?"\u2705":"\u274C",b=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${f} ${h.label}${b}`)}let d=l.filter(h=>h.passed).length;c.push(`
2979
+ ${d}/${l.length} checks passed`),await xt(c.join(`
2980
+ `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(Y(`${u.length} critical issue(s) \u2014 upload will likely fail:
2917
2981
  `+u.map(f=>` - ${f.label}`).join(`
2918
- `)),!await Me({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&se(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2982
+ `)),!await Pe({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&ie(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2919
2983
  `+m.map(h=>` - ${h.label}`).join(`
2920
- `));let g=nt(e.themePath,"..","vibespot-conversion.log");return x(g)&&(await Me({message:"Keep conversion log file for debugging?",initialValue:!1})?G(`Log saved: ${g}`):Nl(g)),await fe("Files ready for upload!"),i}function pf(e){let t=[];ff(e),hf(e);let n=nt(e,"modules");if(x(n))for(let o of ds(n)){if(!o.endsWith(".module"))continue;let i=nt(n,o,"fields.json");if(!x(i))continue;let r=o.replace(".module",""),a=P(i),l=!1;a.includes('"textarea"')&&(a=a.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${r}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(a)&&(a=a.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${r}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(a),u=!1;Rl(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),Ol(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2921
- `,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&B(i,a);let c=nt(n,o,"module.html");if(x(c)){let d=P(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),B(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=nt(e,"templates");if(x(s))for(let o of ds(s)){if(!o.endsWith(".html"))continue;let i=nt(s,o),r=P(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(Nl(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Rl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let r=i.charAt(0).toUpperCase()+i.slice(1);return[i,r]}return i}),t=!0),Array.isArray(s.children)&&Rl(s.children)&&(t=!0)}return t}function Ol(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&Ol(s.children)&&(t=!0)}return t}function gf(e,t){let n=[],s=t.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of t.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let r=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),a=r.length===0;n.push({label:a?"module.css created for each module":`module.css missing for: ${r.join(", ")}`,passed:s>0&&a,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=nt(e,"templates"),d=!1;if(x(c))for(let u of ds(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=P(nt(c,u));if(m.includes("dnd_area")&&/templateType\s*:\s*page/i.test(m)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function ff(e){let t=nt(e,"templates");if(x(t))for(let n of ds(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=nt(t,n),o=P(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),r=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&r)continue;let a=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);i||(c+=`
2984
+ `));let g=ot(e.themePath,"..","vibespot-conversion.log");return v(g)&&(await Pe({message:"Keep conversion log file for debugging?",initialValue:!1})?W(`Log saved: ${g}`):rc(g)),await he("Files ready for upload!"),i}function ah(e){let t=[];ch(e),dh(e);let n=ot(e,"modules");if(v(n))for(let o of bs(n)){if(!o.endsWith(".module"))continue;let i=ot(n,o,"fields.json");if(!v(i))continue;let r=o.replace(".module",""),a=M(i),l=!1;a.includes('"textarea"')&&(a=a.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${r}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(a)&&(a=a.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${r}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(a),u=!1;ac(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),lc(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2985
+ `,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&H(i,a);let c=ot(n,o,"module.html");if(v(c)){let d=M(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),H(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=ot(e,"templates");if(v(s))for(let o of bs(s)){if(!o.endsWith(".html"))continue;let i=ot(s,o),r=M(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(rc(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function ac(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let r=i.charAt(0).toUpperCase()+i.slice(1);return[i,r]}return i}),t=!0),Array.isArray(s.children)&&ac(s.children)&&(t=!0)}return t}function lc(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&lc(s.children)&&(t=!0)}return t}function lh(e,t){let n=[],s=t.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of t.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let r=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),a=r.length===0;n.push({label:a?"module.css created for each module":`module.css missing for: ${r.join(", ")}`,passed:s>0&&a,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=ot(e,"templates"),d=!1;if(v(c))for(let u of bs(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=M(ot(c,u));if(m.includes("dnd_area")&&/templateType\s*:\s*page/i.test(m)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function ch(e){let t=ot(e,"templates");if(v(t))for(let n of bs(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=ot(t,n),o=M(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),r=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&r)continue;let a=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);i||(c+=`
2922
2986
  templateType: page`),r||(c+=`
2923
2987
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
2924
2988
  label: ${a}`),o=c+o.slice(l)}else o=`<!--
@@ -2926,31 +2990,31 @@ ${d}/${l.length} checks passed`),await yt(c.join(`
2926
2990
  isAvailableForNewContent: true
2927
2991
  label: ${a}
2928
2992
  -->
2929
- `+o;B(s,o),G(`Template "${n}" \u2014 annotations verified`)}}function hf(e){let t=nt(e,"modules");if(x(t))for(let n of ds(t)){if(!n.endsWith(".module"))continue;let s=nt(t,n,"meta.json");if(x(s))try{let o=JSON.parse(P(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&B(s,JSON.stringify(o,null,2)+`
2930
- `)}catch{}}}y();qt();Qe();Ao();ee();nr();import{join as zl,basename as Af}from"path";function _f(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Mn(e){await ge("Uploading to HubSpot");let t=Af(e)||e,n=R(),s=Le(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await De(),r=3;for(let a=1;a<=r;a++){i.start(a===1?"Uploading theme...":`Retrying upload (attempt ${a}/${r})...`);let l=[],c=0,d=!1;if(o){let m=await _o(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Co(m.errors)}else{let m=ie(`hs cms upload "${e}" "${t}"`,{cwd:zl(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2931
- `);c=_f(g),d=m.success,d||(l=ko(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await fe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(V("Upload failed with unknown error."),c>0&&(se(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2932
- You can check your HubSpot Design Manager to verify.`),await Me({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Me({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?Fl(e,m)?(G(`Auto-fixed: ${m.message}`),u=!0):se(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&a<r)){if(c>0&&(se(`${c} files uploaded successfully despite errors.
2933
- The theme may work \u2014 check HubSpot Design Manager.`),await Me({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await Bi(s,`${t}/modules`)}catch{}else ie(`hs cms delete "${t}/modules"`,{cwd:zl(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}y();Qe();gt();Qt();oe();import{execFileSync as sr}from"child_process";import{rmSync as $f}from"fs";import{basename as Yl}from"path";async function ql(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ge("You're all set!");let r=es(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await yt(`Your React page has been converted and uploaded to HubSpot.
2993
+ `+o;H(s,o),W(`Template "${n}" \u2014 annotations verified`)}}function dh(e){let t=ot(e,"modules");if(v(t))for(let n of bs(t)){if(!n.endsWith(".module"))continue;let s=ot(t,n,"meta.json");if(v(s))try{let o=JSON.parse(M(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&H(s,JSON.stringify(o,null,2)+`
2994
+ `)}catch{}}}y();tn();nt();Bo();oe();yr();import{join as xc,basename as vh}from"path";function xh(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Dn(e){await fe("Uploading to HubSpot");let t=vh(e)||e,n=N(),s=Be(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await je(),r=3;for(let a=1;a<=r;a++){i.start(a===1?"Uploading theme...":`Retrying upload (attempt ${a}/${r})...`);let l=[],c=0,d=!1;if(o){let m=await Jo(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Do(m.errors)}else{let m=le(`hs cms upload "${e}" "${t}"`,{cwd:xc(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2995
+ `);c=xh(g),d=m.success,d||(l=jo(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await he("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(Y("Upload failed with unknown error."),c>0&&(ie(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2996
+ You can check your HubSpot Design Manager to verify.`),await Pe({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Pe({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?cc(e,m)?(W(`Auto-fixed: ${m.message}`),u=!0):ie(`Could not auto-fix: ${m.message}`):Y(m.message);if(!(u&&a<r)){if(c>0&&(ie(`${c} files uploaded successfully despite errors.
2997
+ The theme may work \u2014 check HubSpot Design Manager.`),await Pe({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await or(s,`${t}/modules`)}catch{}else le(`hs cms delete "${t}/modules"`,{cwd:xc(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return Y("Upload failed after multiple attempts."),!1}y();nt();bt();on();ae();import{execFileSync as br}from"child_process";import{rmSync as wh}from"fs";import{basename as wc}from"path";async function kc(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await fe("You're all set!");let r=rs(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await xt(`Your React page has been converted and uploaded to HubSpot.
2934
2998
  The theme and modules are now in your account, but you still
2935
- need to ${I.bold("create a new landing page")} that uses them.
2999
+ need to ${E.bold("create a new landing page")} that uses them.
2936
3000
 
2937
3001
  Next steps:
2938
3002
 
2939
- ${I.bold("1.")} Go to HubSpot ${I.muted("\u2192")} Content ${I.muted("\u2192")} Landing Pages ${I.muted("\u2192")} Create
2940
- ${I.bold("2.")} Choose your uploaded theme from the theme picker
2941
- ${I.bold("3.")} Select the landing page template that was just created
2942
- ${I.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
2943
- ${I.bold("5.")} Click each section to edit text, images, and colors
2944
- ${I.bold("6.")} Upload images via File Manager ${I.muted("(Settings \u2192 Files)")}
2945
- ${I.bold("7.")} Preview and publish!`,"What's next"),await Me({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${r}/page-ui/${t}/management/pages/landing`:`https://${r}`;try{let d=process.platform;d==="darwin"?sr("open",[c],{stdio:"ignore"}):d==="win32"?sr("cmd",["/c","start","",c],{stdio:"ignore"}):sr("xdg-open",[c],{stdio:"ignore"}),G("Opening HubSpot Landing Pages...")}catch{D(`Open this URL in your browser: ${I.info(c)}`)}}let l=[];if(o&&x(n)&&l.push({path:n,label:`Cloned source (${Yl(n)})`}),x(s)&&l.push({path:s,label:`Theme directory (${Yl(s)})`}),l.length>0&&await Me({message:"Clean up local working directories?"}))for(let d of l)try{$f(d.path,{recursive:!0,force:!0}),G(`Removed ${d.label}`)}catch{se(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await fe(`Thanks for using hub${I.vibes("Vibes")}! ${I.vibes("~")}`)}ee();async function Xl(){Ee();let e=await ao(),t=await lo();Y({lastSourcePath:t.sourceDir});let n=await mo();Y({lastThemePath:n.themePath}),await wo({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Mn(n.themePath),await ql({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function Zl(){Ee(),await ao()}y();co();ee();Qe();async function Ql(){Ee();let e=R();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await lo(),n=await mo();await wo({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();ee();Qe();async function ec(){Ee();let e=R();if(e.lastThemePath)if(await Me({message:`Upload from ${e.lastThemePath}?`}))await Mn(e.lastThemePath);else{let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Mn(n)}else{let t=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Mn(t)}}y();Qt();ee();Qe();gt();async function tc(){Ee(),await ge("Environment Diagnostics");let e=0,t=Zn();t.found?no(t.version)?G(`Node.js v${t.version}`):(se(`Node.js v${t.version} \u2014 too old (need 18+)`),D(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),D(" Install from https://nodejs.org"),e++);let n=Qn();n.found?G(`Git ${n.version}`):(V("Git \u2014 not installed"),D(" Install from https://git-scm.com"),e++);let s=ft();if(!s.found)se("HubSpot CLI \u2014 not installed (only needed for deployment)"),D(" Install: npm install -g @hubspot/cli");else if(!el(s.version))se(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),D(" Update: npm install -g @hubspot/cli@latest"),e++;else{G(`HubSpot CLI v${s.version}`);let m=ht();m.authenticated?G(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(se("HubSpot \u2014 not authenticated"),D(" Run: hs init"))}let o=wn();o.found?G(`Claude Code ${o.version} at ${o.path}`):D(I.muted("Claude Code \u2014 not installed"));let i=Cn();i.found?G(`Gemini CLI ${i.version} at ${i.path}`):D(I.muted("Gemini CLI \u2014 not installed"));let r=kn();r.found?G(`OpenAI Codex ${r.version} at ${r.path}`):D(I.muted("OpenAI Codex \u2014 not installed"));let a=R(),l=!!(a.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(a.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(a.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?G("Anthropic API key configured"):D(I.muted("Anthropic API key \u2014 not set")),c?G("OpenAI API key configured"):D(I.muted("OpenAI API key \u2014 not set")),d?G("Google AI API key configured"):D(I.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};a.aiEngine&&G(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&D(I.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(se("No AI engine available"),D(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),D(" Or install: Claude Code \u2014 https://claude.ai/code"),D(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),D(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await fe("Everything looks good!"):await fe(I.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}y();vs();Ce();import{dirname as iv,join as _i}from"path";import{existsSync as rv}from"fs";import{fileURLToPath as av}from"url";import{execFileSync as Ra}from"child_process";import $i from"chalk";var Yp=iv(av(import.meta.url)),lv=4200;async function qp(){let e=$i.hex("#e8613a"),t=$i.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
2946
- `));let n=cv();n||(console.error($i.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||lv;try{let{port:o,close:i}=await Ai({port:s,uiDir:n}),r=`http://localhost:${o}`;if(console.log(e(` v ${r}`)),console.log(t(` Press Ctrl+C to stop
2947
- `)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?Ra("open",[r],{stdio:"ignore"}):process.platform==="win32"?Ra("cmd",["/c","start","",r],{stdio:"ignore"}):Ra("xdg-open",[r],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
2948
- Saving session...`)),L(),i(),console.log(t(` Goodbye!
2949
- `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error($i.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function cv(){let e=[_i(Yp,"../../ui"),_i(Yp,"../ui"),_i(process.cwd(),"ui")];for(let t of e)if(rv(_i(t,"index.html")))return t;return null}y();import{resolve as Xp}from"path";import{existsSync as Oa}from"fs";gt();Qe();ee();Ea();async function Zp(e={}){let t=await eg(e.path);if(e.fix){let o=wi(t);if(o.applied.length>0){G(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)D(` ${i}`)}else D(I.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)se(i)}let n=Js(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
2950
- `),n.passed||process.exit(1);return}Ee(),await ge("Marketplace check");let s=`${n.errorCount} error${Da(n.errorCount)}, ${n.warningCount} warning${Da(n.warningCount)}, ${n.infoCount} note${Da(n.infoCount)}`;n.passed?G(`Theme passes Marketplace checks (${s}).`):V(`Theme is not yet ready: ${s}.`),Fa("Errors",n.findings.filter(o=>o.severity==="error")),Fa("Warnings",n.findings.filter(o=>o.severity==="warning")),Fa("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(D(""),D(`Tip: run ${I.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await fe("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function Qp(e={}){let t=await eg(e.path);Ee(),await ge("Marketplace listing details");let n=Yn(t)??{},s=await Et({message:"Category",options:Yt.map(u=>({value:u,label:u}))}),o=await Se({message:"Description (1\u20132 sentences shown on the listing)",placeholder:"A clean, fast SaaS landing page theme...",defaultValue:n.description??"",validate:u=>u.trim().length<40?"Aim for at least 40 characters.":void 0}),r=(await Se({message:"Key features (comma-separated, 2\u20135 items)",placeholder:"Hero, Pricing, Testimonials, Footer",defaultValue:(n.features??[]).join(", "),validate:u=>{let m=u.split(",").map(g=>g.trim()).filter(Boolean).length;if(m<2)return"Provide at least 2 features.";if(m>5)return"Provide at most 5 features."}})).split(",").map(u=>u.trim()).filter(Boolean),a=await Se({message:"Public support URL",placeholder:"https://example.com/support",defaultValue:n.supportUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),l=await Se({message:"Documentation URL (optional)",placeholder:"https://example.com/docs",defaultValue:n.documentationUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),c=await Et({message:"Pricing tier",options:[{value:"free",label:"Free"},{value:"paid",label:"Paid"}]}),d={category:s,description:o.trim(),features:r,supportUrl:a.trim()||void 0,documentationUrl:l.trim()||void 0,pricingTier:c,tags:n.tags};xi(t,d),G("Saved marketplace.json"),await fe(`Run ${I.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function eg(e){if(e){let o=Xp(e);if(!Oa(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&Oa(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Xp(n);if(!Oa(s))throw new Error(`Theme not found: ${s}`);return s}function Fa(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}function Da(e){return e===1?"":"s"}y();import{resolve as tg}from"path";import{existsSync as ja}from"fs";import{basename as dv}from"path";gt();Qe();ee();Ho();async function ng(e={}){let t=await uv(e.path),n=dv(t);if(e.applyTokens){let i=Bo(t,n);i?G(`Wrote design tokens to ${i}`):D(I.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=ur(t);e.json||G(`Wrote imported theme snapshot to ${i}`)}let s=Jo(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
2951
- `),process.exit(0)),Ee(),await ge("Inverse pipeline analyzer");let o=s.summary;if(D(`${I.heading("Summary")} ${o.moduleCount} module(s), ${o.templateCount} template(s), ${o.orphanCount} orphan, ${o.paletteSize} colour(s), ${o.cssVarCount} CSS var(s), ${o.customMacroCount} macro(s)`),s.designTokens.palette.length>0){D(""),D(I.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?I.muted(` (${i.varName})`):"";D(` ${i.value} ${I.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){D(""),D(I.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))D(` ${i}`)}if(s.graph.templates.length>0){D(""),D(I.heading("Template \u2192 modules"));for(let i of s.graph.templates)D(` ${i.id}: ${i.modules.length===0?I.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){D(""),D(I.heading("Orphan modules"));for(let i of s.graph.orphanModules)D(` ${i}`)}if(s.roundTripDiff.hasSnapshot){D(""),D(I.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)D(` ${I.muted("No changes from imported snapshot.")}`);else{D(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))D(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&D(` ${I.muted(`...and ${i.files.length-12} more`)}`)}}La("Errors",s.findings.filter(i=>i.severity==="error")),La("Warnings",s.findings.filter(i=>i.severity==="warning")),La("Notes",s.findings.filter(i=>i.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(D(""),D(`Tip: run ${I.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await fe("Analysis complete."),process.exit(0)}async function uv(e){if(e){let o=tg(e);if(!ja(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&ja(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=tg(n);if(!ja(s))throw new Error(`Theme not found: ${s}`);return s}function La(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}y();vs();Ce();import{dirname as mv,join as Ei}from"path";import{existsSync as pv}from"fs";import{fileURLToPath as gv}from"url";import{execFileSync as Ja}from"child_process";import Mi from"chalk";var sg=mv(gv(import.meta.url)),fv=4200;async function og(){let e=Mi.hex("#e8613a"),t=Mi.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
2952
- `));let n=hv();n||(console.error(Mi.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await Ai({port:fv,uiDir:n,contentMode:"email"}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Email template mode \u2014 Press Ctrl+C to stop
2953
- `));try{process.platform==="darwin"?Ja("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ja("cmd",["/c","start","",i],{stdio:"ignore"}):Ja("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
2954
- Saving session...`)),L(),o(),console.log(t(` Goodbye!
2955
- `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Mi.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function hv(){let e=[Ei(sg,"../../ui"),Ei(sg,"../ui"),Ei(process.cwd(),"ui")];for(let t of e)if(pv(Ei(t,"index.html")))return t;return null}oe();function ig(){let e=new yv;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(yn()).action(qp),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Xl),e.command("init").description("Check and install required tools").action(Zl),e.command("convert").description("Convert a React project to HubSpot modules").action(Ql),e.command("upload").description("Upload theme to HubSpot").action(ec),e.command("doctor").description("Diagnose environment issues").action(tc);let t=e.command("marketplace").description("Prepare a theme for HubSpot Marketplace submission");return t.command("check").description("Audit the theme against Marketplace requirements").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--fix","Apply auto-fixable findings before checking").action(n=>Zp(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>Qp(n)),e.command("email").description("Launch email template generation mode").action(og),e.command("inverse").description("Analyze an imported HubSpot theme: design tokens, module graph, field flags, round-trip risks").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--apply-tokens","Seed css/<theme>-theme.css with the inferred :root block when missing").option("--snapshot","Capture the current theme as the imported round-trip baseline before analysis").action(n=>ng(n)),e}var bv=ig();bv.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
3003
+ ${E.bold("1.")} Go to HubSpot ${E.muted("\u2192")} Content ${E.muted("\u2192")} Landing Pages ${E.muted("\u2192")} Create
3004
+ ${E.bold("2.")} Choose your uploaded theme from the theme picker
3005
+ ${E.bold("3.")} Select the landing page template that was just created
3006
+ ${E.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
3007
+ ${E.bold("5.")} Click each section to edit text, images, and colors
3008
+ ${E.bold("6.")} Upload images via File Manager ${E.muted("(Settings \u2192 Files)")}
3009
+ ${E.bold("7.")} Preview and publish!`,"What's next"),await Pe({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${r}/page-ui/${t}/management/pages/landing`:`https://${r}`;try{let d=process.platform;d==="darwin"?br("open",[c],{stdio:"ignore"}):d==="win32"?br("cmd",["/c","start","",c],{stdio:"ignore"}):br("xdg-open",[c],{stdio:"ignore"}),W("Opening HubSpot Landing Pages...")}catch{B(`Open this URL in your browser: ${E.info(c)}`)}}let l=[];if(o&&v(n)&&l.push({path:n,label:`Cloned source (${wc(n)})`}),v(s)&&l.push({path:s,label:`Theme directory (${wc(s)})`}),l.length>0&&await Pe({message:"Clean up local working directories?"}))for(let d of l)try{wh(d.path,{recursive:!0,force:!0}),W(`Removed ${d.label}`)}catch{ie(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await he(`Thanks for using hub${E.vibes("Vibes")}! ${E.vibes("~")}`)}oe();async function Cc(){$e();let e=await vo(),t=await xo();q({lastSourcePath:t.sourceDir});let n=await Co();q({lastThemePath:n.themePath}),await Fo({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Dn(n.themePath),await kc({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function Tc(){$e(),await vo()}y();wo();oe();nt();async function Ac(){$e();let e=N();e.aiEngine||(Y("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await xo(),n=await Co();await Fo({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();oe();nt();async function _c(){$e();let e=N();if(e.lastThemePath)if(await Pe({message:`Upload from ${e.lastThemePath}?`}))await Dn(e.lastThemePath);else{let n=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Dn(n)}else{let t=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Dn(t)}}y();on();oe();nt();bt();async function $c(){$e(),await fe("Environment Diagnostics");let e=0,t=os();t.found?fo(t.version)?W(`Node.js v${t.version}`):(ie(`Node.js v${t.version} \u2014 too old (need 18+)`),B(" Update at https://nodejs.org"),e++):(Y("Node.js \u2014 not installed"),B(" Install from https://nodejs.org"),e++);let n=is();n.found?W(`Git ${n.version}`):(Y("Git \u2014 not installed"),B(" Install from https://git-scm.com"),e++);let s=St();if(!s.found)ie("HubSpot CLI \u2014 not installed (only needed for deployment)"),B(" Install: npm install -g @hubspot/cli");else if(!Tl(s.version))ie(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),B(" Update: npm install -g @hubspot/cli@latest"),e++;else{W(`HubSpot CLI v${s.version}`);let m=vt();m.authenticated?W(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(ie("HubSpot \u2014 not authenticated"),B(" Run: hs init"))}let o=En();o.found?W(`Claude Code ${o.version} at ${o.path}`):B(E.muted("Claude Code \u2014 not installed"));let i=Mn();i.found?W(`Gemini CLI ${i.version} at ${i.path}`):B(E.muted("Gemini CLI \u2014 not installed"));let r=In();r.found?W(`OpenAI Codex ${r.version} at ${r.path}`):B(E.muted("OpenAI Codex \u2014 not installed"));let a=N(),l=!!(a.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(a.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(a.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?W("Anthropic API key configured"):B(E.muted("Anthropic API key \u2014 not set")),c?W("OpenAI API key configured"):B(E.muted("OpenAI API key \u2014 not set")),d?W("Google AI API key configured"):B(E.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};a.aiEngine&&W(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&B(E.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(ie("No AI engine available"),B(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),B(" Or install: Claude Code \u2014 https://claude.ai/code"),B(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),B(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await he("Everything looks good!"):await he(E.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}y();$s();Ce();import{dirname as px,join as Gi}from"path";import{existsSync as gx}from"fs";import{fileURLToPath as fx}from"url";import{execFileSync as il}from"child_process";import Wi from"chalk";var Hg=px(fx(import.meta.url)),hx=4200;async function Ug(){let e=Wi.hex("#e8613a"),t=Wi.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
3010
+ `));let n=yx();n||(console.error(Wi.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||hx;try{let{port:o,close:i}=await Ui({port:s,uiDir:n}),r=`http://localhost:${o}`;if(console.log(e(` v ${r}`)),console.log(t(` Press Ctrl+C to stop
3011
+ `)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?il("open",[r],{stdio:"ignore"}):process.platform==="win32"?il("cmd",["/c","start","",r],{stdio:"ignore"}):il("xdg-open",[r],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
3012
+ Saving session...`)),F(),i(),console.log(t(` Goodbye!
3013
+ `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(Wi.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function yx(){let e=[Gi(Hg,"../../ui"),Gi(Hg,"../ui"),Gi(process.cwd(),"ui")];for(let t of e)if(gx(Gi(t,"index.html")))return t;return null}y();import{resolve as Gg}from"path";import{existsSync as rl}from"fs";bt();nt();oe();nl();async function Wg(e={}){let t=await Vg(e.path);if(e.fix){let o=ji(t);if(o.applied.length>0){W(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)B(` ${i}`)}else B(E.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)ie(i)}let n=Zs(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
3014
+ `),n.passed||process.exit(1);return}$e(),await fe("Marketplace check");let s=`${n.errorCount} error${ll(n.errorCount)}, ${n.warningCount} warning${ll(n.warningCount)}, ${n.infoCount} note${ll(n.infoCount)}`;n.passed?W(`Theme passes Marketplace checks (${s}).`):Y(`Theme is not yet ready: ${s}.`),al("Errors",n.findings.filter(o=>o.severity==="error")),al("Warnings",n.findings.filter(o=>o.severity==="warning")),al("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(B(""),B(`Tip: run ${E.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await he("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function Kg(e={}){let t=await Vg(e.path);$e(),await fe("Marketplace listing details");let n=es(t)??{},s=await Nt({message:"Category",options:en.map(u=>({value:u,label:u}))}),o=await ve({message:"Description (1\u20132 sentences shown on the listing)",placeholder:"A clean, fast SaaS landing page theme...",defaultValue:n.description??"",validate:u=>u.trim().length<40?"Aim for at least 40 characters.":void 0}),r=(await ve({message:"Key features (comma-separated, 2\u20135 items)",placeholder:"Hero, Pricing, Testimonials, Footer",defaultValue:(n.features??[]).join(", "),validate:u=>{let m=u.split(",").map(g=>g.trim()).filter(Boolean).length;if(m<2)return"Provide at least 2 features.";if(m>5)return"Provide at most 5 features."}})).split(",").map(u=>u.trim()).filter(Boolean),a=await ve({message:"Public support URL",placeholder:"https://example.com/support",defaultValue:n.supportUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),l=await ve({message:"Documentation URL (optional)",placeholder:"https://example.com/docs",defaultValue:n.documentationUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),c=await Nt({message:"Pricing tier",options:[{value:"free",label:"Free"},{value:"paid",label:"Paid"}]}),d={category:s,description:o.trim(),features:r,supportUrl:a.trim()||void 0,documentationUrl:l.trim()||void 0,pricingTier:c,tags:n.tags};Di(t,d),W("Saved marketplace.json"),await he(`Run ${E.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function Vg(e){if(e){let o=Gg(e);if(!rl(o))throw new Error(`Theme not found: ${o}`);return o}let t=N();if(t.lastThemePath&&rl(t.lastThemePath))return t.lastThemePath;$e();let n=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Gg(n);if(!rl(s))throw new Error(`Theme not found: ${s}`);return s}function al(e,t){if(t.length!==0){B(""),B(E.heading(e));for(let n of t){let s=n.file?E.muted(`[${n.file}] `):"",o=n.severity==="error"?E.error("\u2717"):n.severity==="warning"?E.warn("!"):E.muted("\xB7");B(` ${o} ${s}${n.message}`),n.fix&&B(` ${E.muted("\u2192 "+n.fix)}`)}}}function ll(e){return e===1?"":"s"}y();import{resolve as zg}from"path";import{existsSync as cl}from"fs";import{basename as bx}from"path";bt();nt();oe();Cs();async function Yg(e={}){let t=await Sx(e.path),n=bx(t);if(e.applyTokens){let i=ti(t,n);i?W(`Wrote design tokens to ${i}`):B(E.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=Ar(t);e.json||W(`Wrote imported theme snapshot to ${i}`)}let s=ei(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
3015
+ `),process.exit(0)),$e(),await fe("Inverse pipeline analyzer");let o=s.summary;if(B(`${E.heading("Summary")} ${o.moduleCount} module(s), ${o.templateCount} template(s), ${o.orphanCount} orphan, ${o.paletteSize} colour(s), ${o.cssVarCount} CSS var(s), ${o.customMacroCount} macro(s)`),s.designTokens.palette.length>0){B(""),B(E.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?E.muted(` (${i.varName})`):"";B(` ${i.value} ${E.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){B(""),B(E.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))B(` ${i}`)}if(s.graph.templates.length>0){B(""),B(E.heading("Template \u2192 modules"));for(let i of s.graph.templates)B(` ${i.id}: ${i.modules.length===0?E.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){B(""),B(E.heading("Orphan modules"));for(let i of s.graph.orphanModules)B(` ${i}`)}if(s.roundTripDiff.hasSnapshot){B(""),B(E.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)B(` ${E.muted("No changes from imported snapshot.")}`);else{B(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))B(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&B(` ${E.muted(`...and ${i.files.length-12} more`)}`)}}dl("Errors",s.findings.filter(i=>i.severity==="error")),dl("Warnings",s.findings.filter(i=>i.severity==="warning")),dl("Notes",s.findings.filter(i=>i.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(B(""),B(`Tip: run ${E.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await he("Analysis complete."),process.exit(0)}async function Sx(e){if(e){let o=zg(e);if(!cl(o))throw new Error(`Theme not found: ${o}`);return o}let t=N();if(t.lastThemePath&&cl(t.lastThemePath))return t.lastThemePath;$e();let n=await ve({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=zg(n);if(!cl(s))throw new Error(`Theme not found: ${s}`);return s}function dl(e,t){if(t.length!==0){B(""),B(E.heading(e));for(let n of t){let s=n.file?E.muted(`[${n.file}] `):"",o=n.severity==="error"?E.error("\u2717"):n.severity==="warning"?E.warn("!"):E.muted("\xB7");B(` ${o} ${s}${n.message}`),n.fix&&B(` ${E.muted("\u2192 "+n.fix)}`)}}}y();$s();Ce();import{dirname as vx,join as Ki}from"path";import{existsSync as xx}from"fs";import{fileURLToPath as wx}from"url";import{execFileSync as ul}from"child_process";import Vi from"chalk";var qg=vx(wx(import.meta.url)),kx=4200;async function Xg(){let e=Vi.hex("#e8613a"),t=Vi.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
3016
+ `));let n=Cx();n||(console.error(Vi.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await Ui({port:kx,uiDir:n,contentMode:"email"}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Email template mode \u2014 Press Ctrl+C to stop
3017
+ `));try{process.platform==="darwin"?ul("open",[i],{stdio:"ignore"}):process.platform==="win32"?ul("cmd",["/c","start","",i],{stdio:"ignore"}):ul("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
3018
+ Saving session...`)),F(),o(),console.log(t(` Goodbye!
3019
+ `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Vi.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Cx(){let e=[Ki(qg,"../../ui"),Ki(qg,"../ui"),Ki(process.cwd(),"ui")];for(let t of e)if(xx(Ki(t,"index.html")))return t;return null}ae();function Zg(){let e=new Tx;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Tn()).action(Ug),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Cc),e.command("init").description("Check and install required tools").action(Tc),e.command("convert").description("Convert a React project to HubSpot modules").action(Ac),e.command("upload").description("Upload theme to HubSpot").action(_c),e.command("doctor").description("Diagnose environment issues").action($c);let t=e.command("marketplace").description("Prepare a theme for HubSpot Marketplace submission");return t.command("check").description("Audit the theme against Marketplace requirements").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--fix","Apply auto-fixable findings before checking").action(n=>Wg(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>Kg(n)),e.command("email").description("Launch email template generation mode").action(Xg),e.command("inverse").description("Analyze an imported HubSpot theme: design tokens, module graph, field flags, round-trip risks").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--apply-tokens","Seed css/<theme>-theme.css with the inferred :root block when missing").option("--snapshot","Capture the current theme as the imported round-trip baseline before analysis").action(n=>Yg(n)),e}var Ax=Zg();Ax.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
2956
3020
  //# sourceMappingURL=index.js.map