vibespot 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
- var tp=Object.defineProperty;var R=(t,e)=>()=>(t&&(e=t(t=0)),e);var Be=(t,e)=>{for(var n in e)tp(t,n,{get:e[n],enumerable:!0})};import Gb from"path";import{fileURLToPath as Kb}from"url";var y=R(()=>{"use strict"});import en from"chalk";function bt(t){return ia?en:en.hex(t)}var rt,ia,_,at=R(()=>{"use strict";y();rt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ia=!!process.env.NO_COLOR;_={accent:bt(rt.accent),accentBright:bt(rt.accentBright),success:bt(rt.success),info:bt(rt.info),warn:bt(rt.warn),error:bt(rt.error),muted:bt(rt.muted),vibes:bt(rt.vibes),heading:ia?en.bold:en.bold.hex(rt.accent),command:bt(rt.accentBright),dim:en.dim,bold:en.bold}});import{readFileSync as li,writeFileSync as np,mkdirSync as ra,existsSync as ks}from"fs";import{dirname as aa,join as St}from"path";import{fileURLToPath as sp}from"url";function M(t){return li(t,"utf-8")}function J(t,e){ra(aa(t),{recursive:!0}),np(t,e,"utf-8")}function v(t){return ks(t)}function Ie(t){ra(t,{recursive:!0})}function Ts(t){let e=[St(nn,"../../assets",t),St(nn,"../assets",t),St(process.cwd(),"assets",t)];for(let n of e)if(ks(n))return n;throw new Error(`Asset not found: ${t}`)}function sn(){if(tn)return tn;let t=[St(nn,"../../package.json"),St(nn,"../package.json"),St(process.cwd(),"package.json")];for(let e of t)if(ks(e))try{let n=JSON.parse(li(e,"utf-8"));if(n.name==="vibespot"&&n.version)return tn=n.version,tn}catch{}return tn="dev",tn}function la(){if(Cs)return Cs;let t=[St(nn,"../../CHANGELOG.md"),St(nn,"../CHANGELOG.md"),St(process.cwd(),"CHANGELOG.md")];for(let e of t)if(ks(e))try{return Cs=li(e,"utf-8"),Cs}catch{}return""}var nn,tn,Cs,ne=R(()=>{"use strict";y();nn=aa(sp(import.meta.url));tn="";Cs=""});import{execSync as ca,execFileSync as op}from"child_process";function te(t,e={}){try{return{stdout:ca(t,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...e}).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 X(t,e={}){try{return{stdout:op("git",t,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...e}).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 da(t,e={}){try{return ca(t,{stdio:"inherit",timeout:3e5,...e}),!0}catch{return!1}}var Jt=R(()=>{"use strict";y()});var pa={};Be(pa,{addHubSpotAccount:()=>An,getActiveHubSpotAccount:()=>It,getApiKeyForEngine:()=>Oe,getConfigDir:()=>ap,getHubSpotPak:()=>Fe,isCliToolEnabled:()=>$n,loadConfig:()=>O,maskApiKey:()=>$s,removeHubSpotAccount:()=>ci,saveConfig:()=>Y,setActiveHubSpotAccount:()=>di,setCliToolEnabled:()=>ui});import{join as ua}from"path";import{homedir as ip}from"os";import{chmodSync as rp}from"fs";function O(){if(!v(As))return{};try{let t=JSON.parse(M(As));return t.aiEngine==="api"&&(t.aiEngine="anthropic-api"),t}catch{return{}}}function Oe(t,e){let n=e||O();switch(t){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;default:return}}function $s(t){return t.length<=12?"***":t.slice(0,7)+"..."+t.slice(-4)}function Y(t){let n={...O(),...t};if(J(As,JSON.stringify(n,null,2)),process.platform!=="win32")try{rp(As,384)}catch{}}function ap(){return ma}function It(){let t=O();if(!t.hubspotAccounts?.length)return null;let e=t.activeHubSpotAccount;if(e){let n=t.hubspotAccounts.find(s=>s.portalId===e);if(n)return n}return t.hubspotAccounts[0]||null}function An(t,e,n,s){let i=O().hubspotAccounts||[],r=i.findIndex(l=>l.portalId===e),a={portalId:e,portalName:n,personalAccessKey:t,dataCenter:s,addedAt:new Date().toISOString()};r>=0?i[r]=a:i.push(a),Y({hubspotAccounts:i,activeHubSpotAccount:e})}function ci(t){let e=O(),n=(e.hubspotAccounts||[]).filter(o=>o.portalId!==t),s={hubspotAccounts:n};e.activeHubSpotAccount===t&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),Y(s)}function di(t){Y({activeHubSpotAccount:t})}function Fe(){return It()?.personalAccessKey||null}function $n(t){return O().enabledCLITools?.includes(t)??!1}function ui(t,e){let n=O(),s=new Set(n.enabledCLITools||[]);e?s.add(t):s.delete(t),Y({enabledCLITools:[...s]})}var ma,As,Q=R(()=>{"use strict";y();ne();ma=ua(ip(),".vibespot"),As=ua(ma,"config.json")});var gi={};Be(gi,{OAUTH_EXTRA_HEADERS:()=>_n,OAUTH_SYSTEM_PREFIX:()=>rn,clearOAuthTokens:()=>Es,getOAuthTokenInfo:()=>Mn,getValidAccessToken:()=>pi,hasValidOAuthToken:()=>lt,saveInitialToken:()=>mi});import{join as lp}from"path";import{homedir as cp}from"os";import{chmodSync as dp,unlinkSync as up}from"fs";function Ms(){if(!v(on))return null;try{return JSON.parse(M(on))}catch{return null}}function ga(t){if(J(on,JSON.stringify(t,null,2)),process.platform!=="win32")try{dp(on,384)}catch{}}async function fp(t){let e=await fetch(pp,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:t,client_id:mp})});if(!e.ok)throw Es(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await e.json();ga({access_token:n.access_token,refresh_token:n.refresh_token||t,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function mi(t,e=""){ga({access_token:t,refresh_token:e,expires_at:Date.now()+28800*1e3})}function lt(){let t=Ms();return t?t.expires_at>Date.now():!1}async function pi(){let t=Ms();if(!t)return null;if(t.expires_at-Date.now()>gp)return t.access_token;if(t.refresh_token){_s||(_s=fp(t.refresh_token).finally(()=>{_s=null}));try{await _s}catch{return null}return Ms()?.access_token??null}return t.access_token}function Mn(){let t=Ms();return t?{expiresAt:new Date(t.expires_at).toISOString()}:null}function Es(){if(v(on))try{up(on)}catch{}}var mp,pp,on,gp,_n,rn,_s,xt=R(()=>{"use strict";y();ne();mp="9d1c250a-e61b-44d9-88ed-5944d1962f5e",pp="https://console.anthropic.com/v1/oauth/token",on=lp(cp(),".vibespot","claude-oauth.json"),gp=300*1e3,_n={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},rn="You are Claude Code, Anthropic's official CLI for Claude.";_s=null});import{join as Is}from"path";import{homedir as Ps}from"os";import{readFileSync as fa,existsSync as Rs,readdirSync as hp}from"fs";function En(){let t=te("node --version");return{name:"Node.js",found:t.success,version:t.stdout.replace(/^v/,""),path:te(`${Bt} node`).stdout}}function In(){let t=te("git --version");return{name:"Git",found:t.success,version:t.stdout.replace("git version ",""),path:te(`${Bt} git`).stdout}}function ct(){let t=te("hs --version");return{name:"HubSpot CLI",found:t.success,version:t.stdout,path:te(`${Bt} hs`).stdout}}function Pn(){let t=te("claude --version");if(!t.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=Is(Ps(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Rs(e)){let o=hp(e);(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:t.stdout,path:te(`${Bt} claude`).stdout,authenticated:n,authDetail:s}}function Rn(t){try{let e=Is(Ps(),".hscli","config.yml");if(!Rs(e))return"na1";let n=fa(e,"utf-8"),s=n.indexOf(`accountId: ${t}`);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 dt(){let t=te("hs accounts list");if(!t.success||!t.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let e=[],n="",s="",o=t.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=t.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";e.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:e}:e.length>0?{authenticated:!0,portalName:e[0].name,portalId:e[0].portalId,accounts:e}:{authenticated:t.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Nn(){let t=te("gemini --version");if(!t.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=Is(Ps(),".config","gcloud","application_default_credentials.json"),n=Rs(e),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:t.stdout,path:te(`${Bt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function On(){let t=te("codex --version");if(!t.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=!!process.env.OPENAI_API_KEY,n=!1;try{let i=Is(Ps(),".codex","auth.json");Rs(i)&&(n=fa(i,"utf-8").length>10)}catch{}let s=e||n,o=n?"Authenticated (OAuth)":e?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:t.stdout,path:te(`${Bt} codex`).stdout,authenticated:s,authDetail:o}}function hi(){let t=te("gh --version");return{name:"GitHub CLI",found:t.success,version:t.stdout.split(`
3
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:te(`${Bt} gh`).stdout}}function yi(){let t=te("gh auth status 2>&1");if(!t.success&&!t.stdout)return{authenticated:!1,username:""};let e=t.stdout||t.stderr||"",n=e.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=e.match(/account\s+(\S+)/);return s&&e.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:e.includes("Logged in"),username:""}}function ha(){return!!process.env.ANTHROPIC_API_KEY}function Ns(t){return parseInt(t.split(".")[0],10)>=18}function ya(t){let e=parseInt(t.split(".")[0],10);return!isNaN(e)&&e>=8}function yp(){let t=O(),e=t.hubspotUploadMode||"api",n=t.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(t.activeHubSpotAccount||n[0]?.portalId)})),o=It();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:e}}function Os(){let t=O(),e=En(),n=In(),s=t.hubspotUploadMode||"api",o;if(s==="cli"){let S=ct(),x=S.found?dt():{authenticated:!1,portalName:"",portalId:"",accounts:[]},w=x.portalId?Rn(x.portalId):"na1";o={...S,...x,dataCenter:w,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...yp()};let i=hi(),r=i.found?yi():{authenticated:!1,username:""},a={authenticated:lt(),expiresAt:Mn()?.expiresAt},l=t.enabledCLITools||[],c=$n("claude-code")?Pn():{...fi,name:"Claude Code"},d=$n("gemini-cli")?Nn():{...fi,name:"Gemini CLI"},u=$n("codex-cli")?On():{...fi,name:"OpenAI Codex CLI"};function m(S,...x){if(S)return{configured:!0,masked:$s(S),source:"config"};for(let w of x)if(process.env[w])return{configured:!0,masked:$s(process.env[w]),source:"env"};return{configured:!1,masked:"",source:null}}let g=m(t.anthropicApiKey,"ANTHROPIC_API_KEY"),h=m(t.openaiApiKey,"OPENAI_API_KEY"),f=m(t.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),b=[];return c.found&&c.authenticated&&b.push("claude-code"),a.authenticated&&b.push("claude-oauth"),g.configured&&b.push("anthropic-api"),h.configured&&b.push("openai-api"),d.found&&d.authenticated&&b.push("gemini-cli"),f.configured&&b.push("gemini-api"),u.found&&u.authenticated&&b.push("codex-cli"),{tools:{node:e,git:n,hubspot:o,github:{...i,...r},claudeCode:c,claudeOAuth:a,geminiCli:d,codexCli:u},apiKeys:{anthropic:g,openai:h,gemini:f},activeEngine:t.aiEngine||null,availableEngines:b,enabledCLITools:l}}var Bt,fi,Ht=R(()=>{"use strict";y();Jt();Q();xt();Bt=process.platform==="win32"?"where":"which";fi={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as bp}from"fs";import{basename as Sp}from"path";async function Sa(t){let e=ba.get(t);if(e&&e.expiresAt-Date.now()>wp)return e;let n=await fetch(`${vt}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:t})});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 ba.set(t,o),o}async function an(t){let{accessToken:e}=await Sa(t);return{Authorization:`Bearer ${e}`}}function Fs(t){return t.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function Cp(t){return t.startsWith("pat-eu1-")?"eu1":t.startsWith("pat-na1-")?"na1":t.startsWith("CiRldTE")?"eu1":"na1"}function kp(t){return new Promise(e=>setTimeout(e,t))}async function Fn(t,e){let n=`HTTP ${t.status}`,s,o;try{let i=await t.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 t.text();i&&(n=i.slice(0,500))}catch{}}return{status:t.status,message:e?`${n} (${e})`:n,category:s,detail:o}}async function jn(t,e,n=xp){for(let s=0;s<=n;s++){let o=await fetch(t,e);if(o.status===429||o.status>=500&&s<n){let i=vp*Math.pow(2,s);await kp(i);continue}return o}return fetch(t,e)}async function js(t){let e=await Sa(t),n=`${vt}/account-info/v3/details`,s=await jn(n,{headers:await an(t)});if(!s.ok){let a=await Fn(s);throw new Error(`Failed to get account info: ${a.message}`)}let o=await s.json(),i=String(o.portalId||e.hubId||""),r=e.hubName||o.uiDomain||i;return{portalId:i,portalName:r,dataCenter:Cp(t)}}async function xa(t,e,n){let s=bp(n),o=Sp(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${vt}/cms/v3/source-code/published/content/${Fs(e)}`,l=await jn(a,{method:"PUT",headers:await an(t),body:i});if(!l.ok){let c=await Fn(l,e);return{success:!1,path:e,error:c}}return{success:!0,path:e}}async function bi(t,e){let n=`${vt}/cms/v3/source-code/published/content/${Fs(e)}`,s=await jn(n,{method:"DELETE",headers:await an(t)});if(!s.ok&&s.status!==404){let o=await Fn(s,e);throw new Error(`Failed to delete ${e}: ${o.message}`)}}async function va(t,e){let n=`${vt}/cms/v3/source-code/published/content/${Fs(e)}`,s=await jn(n,{method:"GET",headers:await an(t)});if(!s.ok){let i=await Fn(s,e);throw new Error(`Failed to download ${e}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Ds(t,e){let n=`${vt}/cms/v3/source-code/published/metadata/${Fs(e)}`,s=await jn(n,{method:"GET",headers:await an(t)});if(s.status===404)return null;if(!s.ok){let o=await Fn(s,e);throw new Error(`Failed to get metadata for ${e}: ${o.message}`)}return await s.json()}async function wa(t){let e=await an(t),n=[`${vt}/cms/v3/source-code/published/metadata`,`${vt}/cms/v3/source-code/published/metadata/`,`${vt}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:e});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 vt,xp,vp,wp,ba,Ut=R(()=>{"use strict";y();vt="https://api.hubapi.com",xp=3,vp=1e3,wp=300*1e3,ba=new Map});import*as se from"@clack/prompts";function Si(t){se.isCancel(t)&&(se.cancel(_.muted("Operation cancelled.")),process.exit(0))}async function me(t){se.intro(_.heading(t))}async function pe(t){se.outro(_.success(t))}async function ut(t,e){se.note(t,e?_.heading(e):void 0)}async function be(t){let e=await se.text({message:_.accent(t.message),placeholder:t.placeholder,defaultValue:t.defaultValue,validate:t.validate});return Si(e),e}async function Ae(t){let e=await se.confirm({message:_.accent(t.message),initialValue:t.initialValue??!0});return Si(e),e}async function wt(t){let e=await se.select({message:_.accent(t.message),options:t.options});return Si(e),e}async function Pe(){let t=se.spinner();return{start:e=>t.start(_.muted(e)),stop:e=>t.stop(_.success(e)),message:e=>t.message(_.muted(e))}}function j(t){se.log.info(t)}function G(t){se.log.success(_.success(t))}function ee(t){se.log.warn(_.warn(t))}function z(t){se.log.error(_.error(t))}var Ye=R(()=>{"use strict";y();at()});import{readdirSync as xi,statSync as Tp}from"fs";import{join as ge,basename as vi,extname as Ap}from"path";function Ca(t){return typeof t!="string"||t.length===0||t.length>2048||/[\s;&|`$()<>\\]/.test(t)?!1:!!(/^https?:\/\/[^\s]+$/.test(t)||/^git@[\w.-]+:[\w./~+-]+$/.test(t))}function ka(t){let e=[],n=[ge(t,"src/components/landing"),ge(t,"src/components/sections"),ge(t,"src/components"),ge(t,"src/pages"),ge(t,"app/components"),ge(t,"components")];for(let s of n)if(v(s))try{let o=xi(s);for(let i of o){let r=ge(s,i);if(!Tp(r).isFile())continue;let l=Ap(i);if(![".tsx",".jsx"].includes(l))continue;let c=vi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=M(r),u=$p(c,d);e.push({name:c,path:r,description:u})}}catch{}return e}function $p(t,e){let n=[];return/carousel|slider|swiper|embla/i.test(e)&&n.push("carousel"),/accordion|collapsible|expand/i.test(e)&&n.push("accordion"),/form|submit|input.*email/i.test(e)&&n.push("form"),/nav|navigation|menu/i.test(e)&&n.push("navigation"),/hero|headline|tagline/i.test(e)&&n.push("hero"),/footer|copyright/i.test(e)&&n.push("footer"),/testimonial|quote|review/i.test(e)&&n.push("testimonials"),/pricing|plan|tier/i.test(e)&&n.push("pricing"),/faq|question.*answer/i.test(e)&&n.push("FAQ"),/feature|benefit|advantage/i.test(e)&&n.push("features"),/contact|get.in.touch/i.test(e)&&n.push("contact"),/cta|call.to.action/i.test(e)&&n.push("CTA"),/team|member|bio/i.test(e)&&n.push("team"),n.length===0?t.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function Ta(t){let e=[ge(t,"src/index.css"),ge(t,"src/globals.css"),ge(t,"src/app/globals.css"),ge(t,"app/globals.css")],n=0,s=[];for(let o of e){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 Aa(t){let e=[],n=ge(t,"src/hooks");if(v(n))try{let o=xi(n);for(let i of o)/scroll/i.test(i)&&e.push("Scroll animations"),/intersection/i.test(i)&&e.push("Scroll animations")}catch{}let s=ge(t,"src/components/landing");if(v(s))try{let o=xi(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=M(ge(s,i));/carousel|embla|swiper/i.test(r)&&!e.includes("Carousel")&&e.push("Carousel"),/accordion|collapsible/i.test(r)&&!e.includes("Accordion")&&e.push("Accordion"),/typing|typewriter/i.test(r)&&!e.includes("Typing animation")&&e.push("Typing animation"),/parallax|requestAnimationFrame/i.test(r)&&!e.includes("Parallax")&&e.push("Parallax")}}catch{}return e.length===0&&e.push("Scroll animations"),e}function $a(t){let e,n=!1;if(t.startsWith("http")||t.startsWith("git@")){if(!Ca(t))throw new Error(`Refusing to clone unsafe source URL: ${t}. Only http(s):// and git@host:path URLs without shell metacharacters are allowed.`);n=!0;let l=vi(t.replace(/\.git$/,""))||"react-source";if(e=ge(process.cwd(),"workspace",l),!v(e)){let c=X(["clone","--depth","1","--",t,e]);if(!c.success)throw new Error(`Failed to clone ${t}: ${c.stderr}`)}}else if(e=t,!v(e))throw new Error(`Directory not found: ${e}`);let s=ka(e),o=v(ge(e,"tailwind.config.ts"))||v(ge(e,"tailwind.config.js")),{varCount:i,fonts:r}=Ta(e),a=Aa(e);return{sourceDir:e,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function Js(){await me("Source Project");let t=await be({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"}}),e,n=!1;if(t.startsWith("http")||t.startsWith("git@")){Ca(t)||(z("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=vi(t.replace(/\.git$/,""))||"react-source";if(e=ge(process.cwd(),"workspace",h),v(e))G(`Using existing clone: ${_.dim(e)}`);else{let f=await Pe();f.start("Cloning repository..."),X(["clone","--depth","1","--",t,e]).success||(f.stop("Clone failed"),z(`Failed to clone ${t}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${_.dim(e)}`)}}else e=t,v(e)||(z(`Directory not found: ${e}`),process.exit(1)),G(`Using local source: ${_.dim(e)}`);let s=await Pe();s.start("Analyzing project structure...");let o=ka(e),i=v(ge(e,"tailwind.config.ts"))||v(ge(e,"tailwind.config.js")),{varCount:r,fonts:a}=Ta(e),l=Aa(e);s.stop(`Found ${o.length} landing page components`),o.length===0&&(ee("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${_.dim(`${f+1}.`)} ${_.bold(h.name)} ${_.muted(`\u2014 ${h.description}`)}`).join(`
1
+ var np=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var Be=(e,t)=>{for(var n in t)np(e,n,{get:t[n],enumerable:!0})};import Wb from"path";import{fileURLToPath as Vb}from"url";var y=R(()=>{"use strict"});import en from"chalk";function bt(e){return ia?en:en.hex(e)}var rt,ia,_,at=R(()=>{"use strict";y();rt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ia=!!process.env.NO_COLOR;_={accent:bt(rt.accent),accentBright:bt(rt.accentBright),success:bt(rt.success),info:bt(rt.info),warn:bt(rt.warn),error:bt(rt.error),muted:bt(rt.muted),vibes:bt(rt.vibes),heading:ia?en.bold:en.bold.hex(rt.accent),command:bt(rt.accentBright),dim:en.dim,bold:en.bold}});import{readFileSync as li,writeFileSync as sp,mkdirSync as ra,existsSync as ks}from"fs";import{dirname as aa,join as St}from"path";import{fileURLToPath as op}from"url";function E(e){return li(e,"utf-8")}function J(e,t){ra(aa(e),{recursive:!0}),sp(e,t,"utf-8")}function w(e){return ks(e)}function Ie(e){ra(e,{recursive:!0})}function Ts(e){let t=[St(nn,"../../assets",e),St(nn,"../assets",e),St(process.cwd(),"assets",e)];for(let n of t)if(ks(n))return n;throw new Error(`Asset not found: ${e}`)}function sn(){if(tn)return tn;let e=[St(nn,"../../package.json"),St(nn,"../package.json"),St(process.cwd(),"package.json")];for(let t of e)if(ks(t))try{let n=JSON.parse(li(t,"utf-8"));if(n.name==="vibespot"&&n.version)return tn=n.version,tn}catch{}return tn="dev",tn}function la(){if(Cs)return Cs;let e=[St(nn,"../../CHANGELOG.md"),St(nn,"../CHANGELOG.md"),St(process.cwd(),"CHANGELOG.md")];for(let t of e)if(ks(t))try{return Cs=li(t,"utf-8"),Cs}catch{}return""}var nn,tn,Cs,ne=R(()=>{"use strict";y();nn=aa(op(import.meta.url));tn="";Cs=""});import{execSync as ca,execFileSync as ip}from"child_process";function te(e,t={}){try{return{stdout:ca(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 X(e,t={}){try{return{stdout:ip("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 da(e,t={}){try{return ca(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var Jt=R(()=>{"use strict";y()});var pa={};Be(pa,{addHubSpotAccount:()=>An,getActiveHubSpotAccount:()=>It,getApiKeyForEngine:()=>Oe,getConfigDir:()=>lp,getHubSpotPak:()=>Fe,isCliToolEnabled:()=>$n,loadConfig:()=>O,maskApiKey:()=>$s,removeHubSpotAccount:()=>ci,saveConfig:()=>Y,setActiveHubSpotAccount:()=>di,setCliToolEnabled:()=>ui});import{join as ua}from"path";import{homedir as rp}from"os";import{chmodSync as ap}from"fs";function O(){let e={};if(w(As))try{e=JSON.parse(E(As)),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.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"),e}function Oe(e,t){let n=t||O();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 $s(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function Y(e){let n={...O(),...e};if(J(As,JSON.stringify(n,null,2)),process.platform!=="win32")try{ap(As,384)}catch{}}function lp(){return ma}function It(){let e=O();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 An(e,t,n,s){let i=O().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 ci(e){let t=O(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),Y(s)}function di(e){Y({activeHubSpotAccount:e})}function Fe(){return It()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function $n(e){return O().enabledCLITools?.includes(e)??!1}function ui(e,t){let n=O(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),Y({enabledCLITools:[...s]})}var ma,As,Q=R(()=>{"use strict";y();ne();ma=ua(rp(),".vibespot"),As=ua(ma,"config.json")});var gi={};Be(gi,{OAUTH_EXTRA_HEADERS:()=>_n,OAUTH_SYSTEM_PREFIX:()=>rn,clearOAuthTokens:()=>Ms,getOAuthTokenInfo:()=>En,getValidAccessToken:()=>pi,hasValidOAuthToken:()=>lt,saveInitialToken:()=>mi});import{join as cp}from"path";import{homedir as dp}from"os";import{chmodSync as up,unlinkSync as mp}from"fs";function Es(){if(!w(on))return null;try{return JSON.parse(E(on))}catch{return null}}function ga(e){if(J(on,JSON.stringify(e,null,2)),process.platform!=="win32")try{up(on,384)}catch{}}async function hp(e){let t=await fetch(gp,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:pp})});if(!t.ok)throw Ms(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();ga({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function mi(e,t=""){ga({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function lt(){let e=Es();return e?e.expires_at>Date.now():!1}async function pi(){let e=Es();if(!e)return null;if(e.expires_at-Date.now()>fp)return e.access_token;if(e.refresh_token){_s||(_s=hp(e.refresh_token).finally(()=>{_s=null}));try{await _s}catch{return null}return Es()?.access_token??null}return e.access_token}function En(){let e=Es();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function Ms(){if(w(on))try{mp(on)}catch{}}var pp,gp,on,fp,_n,rn,_s,xt=R(()=>{"use strict";y();ne();pp="9d1c250a-e61b-44d9-88ed-5944d1962f5e",gp="https://console.anthropic.com/v1/oauth/token",on=cp(dp(),".vibespot","claude-oauth.json"),fp=300*1e3,_n={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},rn="You are Claude Code, Anthropic's official CLI for Claude.";_s=null});import{join as Is}from"path";import{homedir as Ps}from"os";import{readFileSync as fa,existsSync as Rs,readdirSync as yp}from"fs";function Mn(){let e=te("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:te(`${Bt} node`).stdout}}function In(){let e=te("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:te(`${Bt} git`).stdout}}function ct(){let e=te("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:te(`${Bt} hs`).stdout}}function Pn(){let e=te("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Is(Ps(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Rs(t)){let o=yp(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:te(`${Bt} claude`).stdout,authenticated:n,authDetail:s}}function Rn(e){try{let t=Is(Ps(),".hscli","config.yml");if(!Rs(t))return"na1";let n=fa(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 dt(){let e=te("hs accounts list");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 Nn(){let e=te("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Is(Ps(),".config","gcloud","application_default_credentials.json"),n=Rs(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:te(`${Bt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function On(){let e=te("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=Is(Ps(),".codex","auth.json");Rs(i)&&(n=fa(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:te(`${Bt} codex`).stdout,authenticated:s,authDetail:o}}function hi(){let e=te("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
3
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:te(`${Bt} gh`).stdout}}function yi(){let e=te("gh auth status 2>&1");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 ha(){return!!process.env.ANTHROPIC_API_KEY}function Ns(e){return parseInt(e.split(".")[0],10)>=18}function ya(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function bp(){let e=O(),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=It();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function Os(){let e=O(),t=Mn(),n=In(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let x=ct(),v=x.found?dt():{authenticated:!1,portalName:"",portalId:"",accounts:[]},I=v.portalId?Rn(v.portalId):"na1";o={...x,...v,dataCenter:I,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...bp()};let i=hi(),r=i.found?yi():{authenticated:!1,username:""},a={authenticated:lt(),expiresAt:En()?.expiresAt},l=e.enabledCLITools||[],c=$n("claude-code")?Pn():{...fi,name:"Claude Code"},d=$n("gemini-cli")?Nn():{...fi,name:"Gemini CLI"},u=$n("codex-cli")?On():{...fi,name:"OpenAI Codex CLI"};function m(x,...v){if(x)return{configured:!0,masked:$s(x),source:"config"};for(let I of v)if(process.env[I])return{configured:!0,masked:$s(process.env[I]),source:"env"};return{configured:!1,masked:"",source:null}}let g=m(e.anthropicApiKey,"ANTHROPIC_API_KEY"),h=m(e.openaiApiKey,"OPENAI_API_KEY"),f=m(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),b=m(e.langdockApiKey,"LANGDOCK_API_KEY"),S=[];return c.found&&c.authenticated&&S.push("claude-code"),a.authenticated&&S.push("claude-oauth"),g.configured&&S.push("anthropic-api"),h.configured&&S.push("openai-api"),d.found&&d.authenticated&&S.push("gemini-cli"),f.configured&&S.push("gemini-api"),u.found&&u.authenticated&&S.push("codex-cli"),b.configured&&S.push("langdock-api"),{tools:{node:t,git:n,hubspot:o,github:{...i,...r},claudeCode:c,claudeOAuth:a,geminiCli:d,codexCli:u},apiKeys:{anthropic:g,openai:h,gemini:f,langdock:b},activeEngine:e.aiEngine||null,availableEngines:S,enabledCLITools:l}}var Bt,fi,Ht=R(()=>{"use strict";y();Jt();Q();xt();Bt=process.platform==="win32"?"where":"which";fi={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as Sp}from"fs";import{basename as xp}from"path";async function Sa(e){let t=ba.get(e);if(t&&t.expiresAt-Date.now()>Cp)return t;let n=await fetch(`${vt}/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 ba.set(e,o),o}async function an(e){let{accessToken:t}=await Sa(e);return{Authorization:`Bearer ${t}`}}function Fs(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function kp(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Tp(e){return new Promise(t=>setTimeout(t,e))}async function Fn(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 jn(e,t,n=vp){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=wp*Math.pow(2,s);await Tp(i);continue}return o}return fetch(e,t)}async function js(e){let t=await Sa(e),n=`${vt}/account-info/v3/details`,s=await jn(n,{headers:await an(e)});if(!s.ok){let a=await Fn(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:kp(e)}}async function xa(e,t,n){let s=Sp(n),o=xp(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${vt}/cms/v3/source-code/published/content/${Fs(t)}`,l=await jn(a,{method:"PUT",headers:await an(e),body:i});if(!l.ok){let c=await Fn(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function bi(e,t){let n=`${vt}/cms/v3/source-code/published/content/${Fs(t)}`,s=await jn(n,{method:"DELETE",headers:await an(e)});if(!s.ok&&s.status!==404){let o=await Fn(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function va(e,t){let n=`${vt}/cms/v3/source-code/published/content/${Fs(t)}`,s=await jn(n,{method:"GET",headers:await an(e)});if(!s.ok){let i=await Fn(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Ds(e,t){let n=`${vt}/cms/v3/source-code/published/metadata/${Fs(t)}`,s=await jn(n,{method:"GET",headers:await an(e)});if(s.status===404)return null;if(!s.ok){let o=await Fn(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function wa(e){let t=await an(e),n=[`${vt}/cms/v3/source-code/published/metadata`,`${vt}/cms/v3/source-code/published/metadata/`,`${vt}/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 vt,vp,wp,Cp,ba,Gt=R(()=>{"use strict";y();vt="https://api.hubapi.com",vp=3,wp=1e3,Cp=300*1e3,ba=new Map});import*as se from"@clack/prompts";function Si(e){se.isCancel(e)&&(se.cancel(_.muted("Operation cancelled.")),process.exit(0))}async function me(e){se.intro(_.heading(e))}async function pe(e){se.outro(_.success(e))}async function ut(e,t){se.note(e,t?_.heading(t):void 0)}async function be(e){let t=await se.text({message:_.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return Si(t),t}async function Ae(e){let t=await se.confirm({message:_.accent(e.message),initialValue:e.initialValue??!0});return Si(t),t}async function wt(e){let t=await se.select({message:_.accent(e.message),options:e.options});return Si(t),t}async function Pe(){let e=se.spinner();return{start:t=>e.start(_.muted(t)),stop:t=>e.stop(_.success(t)),message:t=>e.message(_.muted(t))}}function j(e){se.log.info(e)}function U(e){se.log.success(_.success(e))}function ee(e){se.log.warn(_.warn(e))}function z(e){se.log.error(_.error(e))}var Ye=R(()=>{"use strict";y();at()});import{readdirSync as xi,statSync as Ap}from"fs";import{join as ge,basename as vi,extname as $p}from"path";function Ca(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 ka(e){let t=[],n=[ge(e,"src/components/landing"),ge(e,"src/components/sections"),ge(e,"src/components"),ge(e,"src/pages"),ge(e,"app/components"),ge(e,"components")];for(let s of n)if(w(s))try{let o=xi(s);for(let i of o){let r=ge(s,i);if(!Ap(r).isFile())continue;let l=$p(i);if(![".tsx",".jsx"].includes(l))continue;let c=vi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=E(r),u=_p(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function _p(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 Ta(e){let t=[ge(e,"src/index.css"),ge(e,"src/globals.css"),ge(e,"src/app/globals.css"),ge(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!w(o))continue;let i=E(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 Aa(e){let t=[],n=ge(e,"src/hooks");if(w(n))try{let o=xi(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=ge(e,"src/components/landing");if(w(s))try{let o=xi(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=E(ge(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 $a(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!Ca(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=vi(e.replace(/\.git$/,""))||"react-source";if(t=ge(process.cwd(),"workspace",l),!w(t)){let c=X(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!w(t))throw new Error(`Directory not found: ${t}`);let s=ka(t),o=w(ge(t,"tailwind.config.ts"))||w(ge(t,"tailwind.config.js")),{varCount:i,fonts:r}=Ta(t),a=Aa(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function Js(){await me("Source Project");let e=await be({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@")){Ca(e)||(z("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=vi(e.replace(/\.git$/,""))||"react-source";if(t=ge(process.cwd(),"workspace",h),w(t))U(`Using existing clone: ${_.dim(t)}`);else{let f=await Pe();f.start("Cloning repository..."),X(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),z(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${_.dim(t)}`)}}else t=e,w(t)||(z(`Directory not found: ${t}`),process.exit(1)),U(`Using local source: ${_.dim(t)}`);let s=await Pe();s.start("Analyzing project structure...");let o=ka(t),i=w(ge(t,"tailwind.config.ts"))||w(ge(t,"tailwind.config.js")),{varCount:r,fonts:a}=Ta(t),l=Aa(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(ee("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${_.dim(`${f+1}.`)} ${_.bold(h.name)} ${_.muted(`\u2014 ${h.description}`)}`).join(`
4
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 ut(`${c}
5
5
 
6
6
  CSS: ${d}
7
7
  JS: ${m}
8
- Font: ${u}`,`${o.length} components detected`),await Ae({message:"Does this look right?"})||(z("Please adjust your source directory and try again."),process.exit(0)),await pe("Source analyzed!"),{sourceDir:e,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var Bs=R(()=>{"use strict";y();Jt();ne();Ye();at()});var _a={};Be(_a,{addEmailTemplateToTheme:()=>ln,createThemeScaffold:()=>Ln});import{mkdirSync as Ct,writeFileSync as Dn}from"fs";import{join as He}from"path";function Ln(t,e){Ct(t,{recursive:!0}),Ct(He(t,"templates"),{recursive:!0}),Ct(He(t,"modules"),{recursive:!0}),Ct(He(t,"css"),{recursive:!0}),Ct(He(t,"js"),{recursive:!0}),Ct(He(t,"images"),{recursive:!0}),Ct(He(t,"assets"),{recursive:!0});let n={label:e,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"}};Dn(He(t,"theme.json"),JSON.stringify(n,null,2)+`
9
- `),Dn(He(t,"fields.json"),`[]
8
+ Font: ${u}`,`${o.length} components detected`),await Ae({message:"Does this look right?"})||(z("Please adjust your source directory and try again."),process.exit(0)),await pe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var Bs=R(()=>{"use strict";y();Jt();ne();Ye();at()});var _a={};Be(_a,{addEmailTemplateToTheme:()=>ln,createThemeScaffold:()=>Ln});import{mkdirSync as Ct,writeFileSync as Dn}from"fs";import{join as He}from"path";function Ln(e,t){Ct(e,{recursive:!0}),Ct(He(e,"templates"),{recursive:!0}),Ct(He(e,"modules"),{recursive:!0}),Ct(He(e,"css"),{recursive:!0}),Ct(He(e,"js"),{recursive:!0}),Ct(He(e,"images"),{recursive:!0}),Ct(He(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"}};Dn(He(e,"theme.json"),JSON.stringify(n,null,2)+`
9
+ `),Dn(He(e,"fields.json"),`[]
10
10
  `);let s=`<!--
11
11
  templateType: page
12
12
  isAvailableForNewContent: false
13
- label: ${e} (placeholder)
13
+ label: ${t} (placeholder)
14
14
  screenshotPath: ../images/template-previews/home.png
15
15
  -->
16
16
  {% extends "./layouts/base.html" %}
@@ -18,11 +18,11 @@ var tp=Object.defineProperty;var R=(t,e)=>()=>(t&&(e=t(t=0)),e);var Be=(t,e)=>{f
18
18
  {% block body %}
19
19
  {% dnd_area "main_content"
20
20
  label="Main Content",
21
- class="body-container body-container--${e}"
21
+ class="body-container body-container--${t}"
22
22
  %}
23
23
  {% end_dnd_area %}
24
24
  {% endblock body %}
25
- `;Dn(He(t,"templates","home.html"),s);let o=`<!--
25
+ `;Dn(He(e,"templates","home.html"),s);let o=`<!--
26
26
  templateType: none
27
27
  isAvailableForNewContent: false
28
28
  label: Base Layout
@@ -45,10 +45,10 @@ var tp=Object.defineProperty;var R=(t,e)=>()=>(t&&(e=t(t=0)),e);var Be=(t,e)=>{f
45
45
  {{ standard_footer_includes }}
46
46
  </body>
47
47
  </html>
48
- `;Ct(He(t,"templates","layouts"),{recursive:!0}),Dn(He(t,"templates","layouts","base.html"),o)}function ln(t,e){let n=`<!--
48
+ `;Ct(He(e,"templates","layouts"),{recursive:!0}),Dn(He(e,"templates","layouts","base.html"),o)}function ln(e,t){let n=`<!--
49
49
  templateType: email
50
50
  isAvailableForNewContent: true
51
- label: ${e} Email Template
51
+ label: ${t} Email Template
52
52
  screenshotPath: ../images/template-previews/email.png
53
53
  -->
54
54
  <!DOCTYPE html>
@@ -84,8 +84,8 @@ var tp=Object.defineProperty;var R=(t,e)=>()=>(t&&(e=t(t=0)),e);var Be=(t,e)=>{f
84
84
  {{ standard_footer_includes }}
85
85
  </body>
86
86
  </html>
87
- `;Ct(He(t,"templates"),{recursive:!0}),Dn(He(t,"templates","email.html"),n)}var Jn=R(()=>{"use strict";y()});var Ea={};Be(Ea,{fetchTheme:()=>Bn});import{mkdirSync as Ma,writeFileSync as _p}from"fs";import{join as Mp,dirname as Ep}from"path";async function wi(t,e){let n=await Ds(t,e);if(!n)return[];if(!n.folder)return[n.path||e];let s=[],o=n.children||[];for(let i of o){let r=typeof i=="string"?i:i.name;if(!r)continue;let a=`${e}/${r}`;if(typeof i=="string")s.push(...await wi(t,a));else{let l=i;l.folder?s.push(...await wi(t,l.path||a)):s.push(l.path||a)}}return s}async function Ip(t,e,n){let s=0;async function o(){for(;s<t.length;){let r=s++;await n(t[r])}}let i=Array.from({length:Math.min(e,t.length)},()=>o());await Promise.all(i)}async function Bn(t,e,n,s={}){let o=s.concurrency??5,i=await wi(t,e);if(i.length===0)throw new Error(`Theme "${e}" not found on HubSpot or is empty`);Ma(n,{recursive:!0}),await Ip(i,o,async r=>{let a=r.startsWith(e+"/")?r.slice(e.length+1):r,l=Mp(n,a);Ma(Ep(l),{recursive:!0});let c=await va(t,r);_p(l,c),s.onFile?.(a)})}var Hs=R(()=>{"use strict";y();Ut()});function Pt(t){let e=Ia.get(t);if(e!==void 0)return e;try{e=M(Ts(t))}catch{e=""}return Ia.set(t,e),e}function fe(){return Pt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function Un(){return Pt("design-guide.md")}function Ci(){return Pt("content-guide.md")}function je(){return Pt("hubspot-rules.md")}function ki(){return Pt("humanify-guide.md")}function Pa(){return Pt("email-rules.md")}function Ra(){return Pt("blog-rules.md")}function Ti(t){let e=Pt("page-types.md");if(!e)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[t];if(!s)return"";let o=e.indexOf(s);if(o<0)return"";let i=e.indexOf(`
88
- ## `,o+s.length);return i>=0?e.slice(o,i).trim():e.slice(o).trim()}function Na(t){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
87
+ `;Ct(He(e,"templates"),{recursive:!0}),Dn(He(e,"templates","email.html"),n)}var Jn=R(()=>{"use strict";y()});var Ma={};Be(Ma,{fetchTheme:()=>Bn});import{mkdirSync as Ea,writeFileSync as Ep}from"fs";import{join as Mp,dirname as Ip}from"path";async function wi(e,t){let n=await Ds(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 Pp(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 Bn(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`);Ea(n,{recursive:!0}),await Pp(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=Mp(n,a);Ea(Ip(l),{recursive:!0});let c=await va(e,r);Ep(l,c),s.onFile?.(a)})}var Hs=R(()=>{"use strict";y();Gt()});function Pt(e){let t=Ia.get(e);if(t!==void 0)return t;try{t=E(Ts(e))}catch{t=""}return Ia.set(e,t),t}function fe(){return Pt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function Gn(){return Pt("design-guide.md")}function Ci(){return Pt("content-guide.md")}function je(){return Pt("hubspot-rules.md")}function ki(){return Pt("humanify-guide.md")}function Pa(){return Pt("email-rules.md")}function Ra(){return Pt("blog-rules.md")}function Ti(e){let t=Pt("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 Na(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
- ${t}`}function Oa(t,e,n){return`Convert this React component to a HubSpot module named "${e}".
108
+ ${e}`}function Oa(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)
@@ -118,9 +118,9 @@ Design system CSS variables available:
118
118
  ${n}
119
119
 
120
120
  React component source:
121
- ${t}
121
+ ${e}
122
122
 
123
- Return ONLY valid JSON, no markdown fences.`}function Fa(t,e,n){return`Create a shared CSS file for a HubSpot CMS landing page.
123
+ Return ONLY valid JSON, no markdown fences.`}function Fa(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.
@@ -139,12 +139,12 @@ Requirements:
139
139
  - Responsive grid fallbacks
140
140
 
141
141
  Source CSS:
142
- ${t}
142
+ ${e}
143
143
 
144
144
  Tailwind config:
145
- ${e}
145
+ ${t}
146
146
 
147
- Return ONLY the CSS content, no markdown fences.`}function ja(t,e,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
147
+ Return ONLY the CSS content, no markdown fences.`}function ja(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.
@@ -157,14 +157,14 @@ Requirements:
157
157
  - DOMContentLoaded / readyState check
158
158
 
159
159
  React hooks source:
160
- ${t}
160
+ ${e}
161
161
 
162
162
  Interactive component sources:
163
- ${e}
163
+ ${t}
164
164
 
165
- Return ONLY the JavaScript content, no markdown fences.`}function Da(t,e,n){return`Create a HubSpot page template that assembles these modules:
165
+ Return ONLY the JavaScript content, no markdown fences.`}function Da(e,t,n){return`Create a HubSpot page template that assembles these modules:
166
166
 
167
- ${t.map((s,o)=>`${o+1}. ${s}.module`).join(`
167
+ ${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
168
168
  `)}
169
169
 
170
170
  Template requirements:
@@ -175,39 +175,39 @@ Template requirements:
175
175
  - Empty header and footer blocks (modules handle them)
176
176
  - Wrap content in <div class="${n}-page">
177
177
  - Each module in its own dnd_section with padding zeroed and full_width=true
178
- - dnd_area label: "${e} Landing Page"
179
-
180
- Return ONLY the template HTML content, no markdown fences.`}var Ia,Ue=R(()=>{"use strict";y();ne();Ia=new Map});import{join as ce}from"path";import{readdirSync as Ze,rmSync as Vp}from"fs";function Xs(t){let e=[];for(let n of t){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),e.push({file:n.file||"unknown",message:s,fixable:o})}return e}function Zs(t){let e=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(t)){let n=t.match(/(?:in|file:?)\s+(\S+fields\.json)/i);e.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(t)){let n=t.match(/(?:in|file:?)\s+(\S+fields\.json)/i);e.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(t)&&e.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(t)&&e.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(t)){let n=t.match(/field.*?(\w+)\s+has an invalid/i);e.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(t)){let n=t.match(/file '([^']+)'/i);e.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(t)&&e.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(t)&&e.push({file:"templates/email.html",message:'Dnd area can only have name "main"',fixable:!0}),e}function Qs(t){let e=[];return Wa(t)&&e.push("textarea \u2192 text"),Ka(t)&&e.push("name \u2192 item_name"),Va(t)&&e.push("now() \u2192 local_dt"),za(t)&&e.push("Removed HubDB templates"),Ya(t)&&e.push("Fixed link field defaults"),qa(t)&&e.push("Fixed rgba/invalid color values \u2192 hex"),zp(t)&&e.push("Stripped CDN @import statements"),Za(t)&&e.push('dnd_area \u2192 "main" in email templates'),Qa(t)&&e.push("Added {{ dnd_area_stylesheet }} to email templates"),e}function Ga(t,e){return e.message.includes("textarea")?Wa(t):e.message.includes("reserved field name")?Ka(t):e.message.includes("now()")?Va(t):e.message.includes("HubDB")?za(t):e.message.includes("invalid default value")||e.message.includes("deserialization")?Ya(t):e.message.includes("invalid format")&&e.message.includes("color")?qa(t):e.message.includes("dnd")||e.message.includes("Dnd area")?Za(t):e.message.includes("dnd_area_stylesheet")?Qa(t):!1}function Wa(t){let e=!1,n=ce(t,"modules");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"fields.json");if(!v(o))continue;let i=M(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),J(o,i),e=!0)}return e}function Ka(t){let e=!1,n=ce(t,"modules");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(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"'),J(o,i),e=!0)}return e}function Va(t){let e=!1,n=ce(t,"modules");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"module.html");if(!v(o))continue;let i=M(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),J(o,i),e=!0)}return e}function za(t){let e=!1,n=ce(t,"templates");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".html"))continue;let o=ce(n,s),i=M(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Vp(o),e=!0)}return e}function Ya(t){let e=!1,n=ce(t,"modules");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"fields.json");if(v(o))try{let i=JSON.parse(M(o));el(i)&&(J(o,JSON.stringify(i,null,2)+`
181
- `),e=!0)}catch{}}return e}function zp(t){let e=!1,n=ce(t,"css");if(v(n))for(let o of Ze(n)){if(!o.endsWith(".css"))continue;let i=ce(n,o),r=M(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(J(i,a),e=!0)}let s=ce(t,"modules");if(v(s))for(let o of Ze(s)){if(!o.endsWith(".module"))continue;let i=ce(s,o,"module.css");if(!v(i))continue;let r=M(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(J(i,a),e=!0)}if(v(s))for(let o of Ze(s)){if(!o.endsWith(".module"))continue;let i=ce(s,o,"module.html");if(!v(i))continue;let r=M(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(J(i,a),e=!0)}return e}function qa(t){let e=!1,n=ce(t,"modules");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"fields.json");if(v(o))try{let i=JSON.parse(M(o));Xa(i)&&(J(o,JSON.stringify(i,null,2)+`
182
- `),e=!0)}catch{}}return e}function Xa(t){let e=!1;for(let n of t){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"&&!Yp(i)){let r=qp(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),e=!0)}}Array.isArray(s.children)&&Xa(s.children)&&(e=!0)}return e}function Yp(t){return/^#[0-9a-fA-F]{6}$/.test(t)}function qp(t){let e=t.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(e)return{hex:`#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}`};let n=t.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=t.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function Za(t){let e=!1,n=ce(t,"templates");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".html"))continue;let o=ce(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&&(J(o,r),e=!0)}return e}function Qa(t){let e=!1,n=ce(t,"templates");if(!v(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".html"))continue;let o=ce(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
183
- {{ dnd_area_stylesheet }}`);r!==i&&(J(o,r),e=!0)}return e}function el(t){let e=!1;for(let n of t){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},e=!0}}Array.isArray(s.children)&&el(s.children)&&(e=!0)}return e}var eo=R(()=>{"use strict";y();ne()});import{readdirSync as Xp}from"fs";import{join as Zp,relative as Qp}from"path";function tl(t){let e=[];for(let n of Xp(t,{withFileTypes:!0})){if(eg.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=Zp(t,n.name);n.isDirectory()?e.push(...tl(s)):n.isFile()&&e.push(s)}return e}async function tg(t,e,n){let s=0;async function o(){for(;s<t.length;){let r=s++;await n(t[r])}}let i=Array.from({length:Math.min(e,t.length)},()=>o());await Promise.all(i)}async function to(t,e,n,s={}){let o=s.concurrency??5,i=tl(e),r=i.length,a=0,l=0,c=[];return await tg(i,o,async d=>{let u=Qp(e,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await xa(t,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 eg,Ai=R(()=>{"use strict";y();Ut();Ut();eg=new Set([".git","node_modules",".vibespot",".DS_Store"])});var dl=R(()=>{"use strict";y()});import{existsSync as kt,writeFileSync as ig,mkdirSync as rg}from"fs";import{join as pt}from"path";function ml(t){return/^[0-9a-f]{4,40}$/i.test(t)}function pl(t){return Number.isInteger(t)&&t>0&&t<1e3}function Qe(){return no!==null||(no=X(["--version"]).success),no}function so(t){if(!Qe())return!1;if(kt(pt(t,".git")))return ul(t),!0;let e=X(["init"],{cwd:t});return e.success?(ag(t),ul(t),X(["add","-A"],{cwd:t}),X(["commit","-m","Initial theme"],{cwd:t}),!0):(console.warn(`[project-git] git init failed in ${t}: ${e.stderr}`),!1)}function ul(t){let e=pt(t,".vibespot");kt(e)||rg(e,{recursive:!0})}function ag(t){let e=pt(t,".gitignore");ig(e,[".vibespot/","node_modules/",""].join(`
184
- `),"utf-8")}function Gt(t,e){if(!Qe()||!kt(pt(t,".git"))||(X(["add","-A"],{cwd:t}),X(["diff","--cached","--quiet"],{cwd:t}).success))return null;let s=e.length>72?e.slice(0,69)+"...":e,o=X(["commit","-m",s],{cwd:t});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=X(["rev-parse","--short","HEAD"],{cwd:t});return i.success?i.stdout:null}function _i(t,e,n,s){if(!Qe()||!kt(pt(t,".git")))return null;for(let u of s){let m=pt(t,u);kt(m)&&X(["add","--",u],{cwd:t})}if(X(["diff","--cached","--quiet"],{cwd:t}).success)return null;let i=`[${e}] `,r=72-i.length,a=n.length>r?n.slice(0,r-3)+"...":n,l=i+a,c=X(["commit","-m",l],{cwd:t});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=X(["rev-parse","--short","HEAD"],{cwd:t});return d.success?d.stdout:null}function gl(t){let e=[],n=null;for(let s of t.split(`
185
- `)){let o=s.trimEnd();if(o.startsWith("COMMIT|")){n&&e.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&&e.push(n);for(let s of e){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 e}function fl(t,e=50){if(!Qe())return[];if(!kt(pt(t,".git")))return[];if(!pl(e))return[];let n=X(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(e)],{cwd:t});return!n.success||!n.stdout.trim()?[]:gl(n.stdout)}function hl(t,e,n=50){if(!Qe())return[];if(!kt(pt(t,".git")))return[];if(!pl(n))return[];let s=e.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=X(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:t});return!o.success||!o.stdout.trim()?[]:gl(o.stdout)}function yl(t,e){if(!Qe())return{success:!1,error:"Git not available"};if(!kt(pt(t,".git")))return{success:!1,error:"Not a git repo"};if(!ml(e))return{success:!1,error:"Invalid commit hash"};let n=X(["cat-file","-t",e],{cwd:t});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${e} not found`};let s=X(["log","--format=%s","-1",e],{cwd:t}),o=s.success?s.stdout:e,i=X(["checkout",e,"--","."],{cwd:t});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return X(["commit","-m",r],{cwd:t}),{success:!0}}function bl(t,e,n,s){if(!Qe())return{success:!1,error:"Git not available"};if(!kt(pt(t,".git")))return{success:!1,error:"Not a git repo"};if(!ml(n))return{success:!1,error:"Invalid commit hash"};let o=X(["cat-file","-t",n],{cwd:t});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=X(["log","--format=%s","-1",n],{cwd:t}),r=i.success?i.stdout:n,a=0;for(let d of s)X(["checkout",n,"--",d],{cwd:t}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};X(["add","-A"],{cwd:t});let c=`${`[${e}] `}Rollback to: ${r}`.slice(0,72);return X(["commit","-m",c],{cwd:t}),{success:!0}}var no,dn=R(()=>{"use strict";y();Jt();no=null});import{appendFileSync as lg,mkdirSync as cg,readdirSync as dg,unlinkSync as ug}from"fs";import{join as Pi}from"path";import{homedir as mg}from"os";function gg(){if(!Ei)try{cg(oo,{recursive:!0}),Ei=!0}catch{}}function fg(){if(!Ii){Ii=!0;try{let t=Date.now()-pg*864e5;for(let e of dg(oo)){if(!e.startsWith("vibespot-")||!e.endsWith(".log"))continue;let n=e.slice(9,19),s=new Date(n).getTime();if(s&&s<t)try{ug(Pi(oo,e))}catch{}}}catch{}}}function hg(){let e=new Date().toISOString().slice(0,10);return Pi(oo,`vibespot-${e}.log`)}function yg(){return new Date().toISOString().slice(11,23)}function Mi(t,e){if(gg(),!!Ei){Ii||fg();try{lg(hg(),`${yg()} ${t} ${e}
186
- `)}catch{}}}var oo,pg,Ei,Ii,E,de=R(()=>{"use strict";y();oo=Pi(mg(),".vibespot","logs"),pg=7,Ei=!1,Ii=!1;E={info(t,e,n){let s=n?`[${t}] ${e} ${JSON.stringify(n)}`:`[${t}] ${e}`;console.log(s),Mi("INFO",s)},warn(t,e,n){let s=n?`[${t}] ${e} ${JSON.stringify(n)}`:`[${t}] ${e}`;console.warn(s),Mi("WARN",s)},error(t,e,n){let s=n instanceof Error?n.message:n?String(n):"",o=s?`[${t}] ${e}: ${s}`:`[${t}] ${e}`;console.error(o),Mi("ERROR",o)}}});import{readFileSync as bg,existsSync as xl,writeFileSync as Sg,mkdirSync as xg,rmSync as vg}from"fs";import{join as io}from"path";function Wt(t){let e=C();e&&(e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages,e.brandAssets||(e.brandAssets={}),e.brandAssets.plan=t.plan)}function et(){let t=C();if(!t)return;let e=Ce();if(!e){if(t.modules.length===0)return;let n={modules:t.modules,moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,template:t.template,messages:t.messages,plan:t.brandAssets?.plan};e=Tt("landing_page",`${t.themeName} Landing Page`),t.activeTemplateId=e.id,t.modules=n.modules,t.moduleOrder=n.moduleOrder,t.sharedCss=n.sharedCss,t.sharedJs=n.sharedJs,t.template=n.template,t.messages=n.messages,t.brandAssets&&(t.brandAssets.plan=n.plan)}e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages,e.plan=t.brandAssets?.plan}function tt(t,e,n){let s=C();if(!s)return;let o={role:t,content:e,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),et(),Cg()}function vl(t){let e=C();e&&(e.assets||(e.assets=[]),e.assets.push(t),e.updatedAt=Date.now(),D())}function Sl(t){return t.toLowerCase().replace(/[\s\-_]+/g,"")}function wg(t,e){let n=Sl(t),s=Sl(e);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 De(t){let e=C();if(e){if(t.sharedCss!==void 0&&(e.sharedCss=t.sharedCss),t.sharedJs!==void 0&&(e.sharedJs=t.sharedJs),t.template!==void 0&&(e.template=t.template),t.modules)for(let n of t.modules){let s=n.moduleName.toLowerCase(),o=e.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)e.modules[o]=n;else{let i=e.modules.find(r=>wg(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.`),e.modules.push(n),e.moduleOrder.some(r=>r.toLowerCase()===s)||e.moduleOrder.push(n.moduleName)}}e.updatedAt=Date.now(),et()}}function Rt(t){let e=C();e&&(e.moduleOrder=t,e.updatedAt=Date.now(),et())}function wl(t){let e=C();if(e){e.modules=e.modules.filter(n=>n.moduleName!==t),e.moduleOrder=e.moduleOrder.filter(n=>n!==t);for(let n of e.templates)n.modules=n.modules.filter(s=>s.moduleName!==t),n.moduleOrder=n.moduleOrder.filter(s=>s!==t);if(e.themePath){let n=io(e.themePath,"modules",`${t}.module`);xl(n)&&vg(n,{recursive:!0,force:!0})}e.updatedAt=Date.now(),et()}}function Cl(t){let e=C();e&&(e.moduleOrder=e.moduleOrder.filter(n=>n!==t),e.updatedAt=Date.now(),et())}function kl(t,e,n){let s=C();if(!s)return;let o=s.modules.find(i=>i.moduleName===t);if(o)try{let i=JSON.parse(o.fieldsJson);$l(i,e,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),et()}catch{}}function Se(){let t=C();if(!t)return[];let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function Cg(){let t=C();if(t)try{let e=io(t.themePath,".vibespot");xg(e,{recursive:!0});let n={sessionId:t.id,themeName:t.themeName,messages:t.messages,updatedAt:Date.now()};Sg(io(e,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Tl(t){let e=io(t,".vibespot","chat.json");if(!xl(e))return[];try{let n=JSON.parse(bg(e,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Al(t){let e=C();if(e){for(let n of e.templates)n.sharedCss=t.sharedCss,n.sharedJs=t.sharedJs;e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs;for(let n of t.pages){let s=t.pageLabels.get(n.pageId),o=s?.label||n.pageId,i=s?.pageType||"website_page",r=e.templates.find(a=>a.id===n.templateId);r||(r=Tt(i,o),r.id=n.templateId,r.templateFile=`templates/${n.templateId}.html`),r.modules=n.modules,r.moduleOrder=n.moduleOrder,r.sharedCss=t.sharedCss,r.sharedJs=t.sharedJs}t.pages.length>0&&Kn(t.pages[0].templateId),e.updatedAt=Date.now()}}function $l(t,e,n){let s=e.split("."),o=s[0],i=t.find(r=>r.name===o);i&&(s.length===1?i.default=n:i.children&&$l(i.children,s.slice(1).join("."),n))}var Wn=R(()=>{"use strict";y();Vn();Nt();de()});import{existsSync as ro,rmSync as ao}from"fs";import{join as un}from"path";function lo(t){if(t.templates&&t.templates.length>0)return;if(!t.modules||t.modules.length===0){t.templates=[],t.activeTemplateId="";return}let e=`lp-${t.themeName}`,n={id:e,label:`${t.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${t.themeName}.html`,modules:[...t.modules],moduleOrder:[...t.moduleOrder],sharedCss:t.sharedCss||"",sharedJs:t.sharedJs||"",template:t.template||"",messages:[...t.messages]};t.templates=[n],t.activeTemplateId=e}function Ce(){let t=C();return!t||!t.activeTemplateId||!t.templates?.length?null:t.templates.find(e=>e.id===t.activeTemplateId)||null}function Kn(t){let e=C();if(!e)return!1;let n=e.templates.find(s=>s.id===t);return n?(e.activeTemplateId=t,Wt(n),e.updatedAt=Date.now(),!0):!1}function Tt(t,e,n){let s=C();if(!s)throw new Error("No active session");let o=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=n==="email",a=`${i?"email":t==="blog_post"?"bp":t==="website_page"?"wp":t==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:e,pageType:t,contentMode:n,templateFile:i?"templates/email.html":t==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,Wt(l),s.updatedAt=Date.now(),l}function _l(t,e){let n=C();if(!n)return null;let s=n.templates.find(c=>c.id===t);if(!s)return null;let o=e||`${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,Wt(l),n.updatedAt=Date.now(),l}function Ml(t){let e=C();if(!e||!Array.isArray(t)||t.length===0)return!1;let n=new Map(e.templates.map(i=>[i.id,i])),s=new Set,o=[];for(let i of t){let r=n.get(i);!r||s.has(i)||(o.push(r),s.add(i))}for(let i of e.templates)s.has(i.id)||o.push(i);return o.length!==e.templates.length?!1:(e.templates=o,e.updatedAt=Date.now(),!0)}function El(t,e){let n=C();if(!n)return!1;let s=n.templates.find(o=>o.id===t);return s?(s.label=e,n.updatedAt=Date.now(),!0):!1}function Il(t,e=!1){let n=C();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===t);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=un(n.themePath,"templates"),r=`${o.id}.html`,a=un(i,r);if(ro(a)&&ao(a,{force:!0}),o.pageType==="blog_post"){let l=un(i,`${o.id}-listing.html`);ro(l)&&ao(l,{force:!0})}}if(e&&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=un(n.themePath,"modules");for(let l of r){let c=un(a,`${l}.module`);ro(c)&&ao(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===t&&(n.templates.length>0?Kn(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=un(n.themePath,".vibespot","plan.md");ro(r)&&ao(r,{force:!0})}return n.updatedAt=Date.now(),!0}function At(){let t=C();if(!t)return[];let e=new Map;for(let n of t.templates)for(let s of n.modules){let o=e.get(s.moduleName);o?o.usedIn.push(n.label):e.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of t.modules)e.has(n.moduleName)||e.set(n.moduleName,{module:n,usedIn:[]});return Array.from(e.values())}var Nt=R(()=>{"use strict";y();Vn();Wn()});import{readFileSync as gt,readdirSync as ji,existsSync as $e,writeFileSync as zn,mkdirSync as co,rmSync as Ri,renameSync as Ni,cpSync as kg}from"fs";import{join as ue,dirname as Pl}from"path";import{homedir as Tg}from"os";function uo(){if(mn)return mn;try{return $e(Oi)?(mn=JSON.parse(gt(Oi,"utf-8")),mn):Fi()}catch{return Fi()}}function mo(t){mn=t;try{co(ae,{recursive:!0}),zn(Oi,JSON.stringify(t),"utf-8")}catch{}}function Fi(){if(!$e(ae))return[];let t=[];for(let e of ji(ae).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(gt(ue(ae,e),"utf-8")),s=n.templates||[];t.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 mn=t,mo(t),t}function Rl(t){let e=uo(),n=t.templates||[],s={id:t.id,themeName:t.themeName,updatedAt:t.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:!!(t.brandAssets&&(t.brandAssets.styleguide||t.brandAssets.brandvoice||t.brandAssets.brandKit)),isImported:!!t.isImported},o=e.findIndex(i=>i.id===t.id);o>=0?e[o]=s:e.push(s),mo(e)}function Ag(t){let e=uo().filter(n=>n.id!==t);mo(e)}function $g(t){let e=uo().filter(n=>n.themeName!==t);mo(e)}function C(){return Le}function Nl(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function pn(t,e,n={}){let s={id:Nl(),themePath:t,themeName:e,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Le=s,so(t),s}function D(){if(!Le)return;co(ae,{recursive:!0});let t=ue(ae,`${Le.id}.json`);zn(t,JSON.stringify(Le,null,2),"utf-8"),Rl(Le)}function po(t){let e=ue(ae,t+".json");if(!$e(e))return null;try{let n=JSON.parse(gt(e,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),lo(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 Le=n,n}catch{return null}}function gn(){return $e(ae)?uo():[]}function Ol(t,e=!1){let n=ue(ae,t+".json"),s="";if(e)try{let o=JSON.parse(gt(n,"utf-8"));s=o.themeName||"",o.themePath&&$e(o.themePath)&&Ri(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(gt(n,"utf-8")).themeName||""}catch{}try{$e(n)&&Ri(n)}catch{}if(s&&$e(ae)){for(let o of ji(ae).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(gt(ue(ae,o),"utf-8")).themeName===s&&Ri(ue(ae,o))}catch{}$g(s)}else Ag(t);Le?.id===t&&(Le=null)}function Fl(t,e){let n=ue(ae,t+".json");if(!$e(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(gt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===e)return{ok:!0};let i=s.themePath,r=ue(Pl(i),e);if($e(i)){if($e(r))return{ok:!1,error:"A project with that name already exists"};try{Ni(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=ue(r,"css",`${o}-theme.css`),l=ue(r,"css",`${e}-theme.css`);if($e(a))try{Ni(a,l)}catch{}let c=ue(r,"js",`${o}-animations.js`),d=ue(r,"js",`${e}-animations.js`);if($e(c))try{Ni(c,d)}catch{}let u=ue(r,"theme.json");if($e(u))try{let m=JSON.parse(gt(u,"utf-8"));m.label=e,m.name=e,zn(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if($e(ae))for(let a of ji(ae).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(gt(ue(ae,a),"utf-8"));l.themeName===o&&(l.themeName=e,l.themePath=r,l.updatedAt=Date.now(),zn(ue(ae,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Le&&Le.themeName===o&&(Le.themeName=e,Le.themePath=r,Le.updatedAt=Date.now()),Fi(),{ok:!0}}function jl(t){let e=ue(ae,t+".json");if(!$e(e))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(gt(e,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=Pl(n.themePath),i=`${s}-copy`,r=1;for(;$e(ue(o,i));)r++,i=`${s}-copy-${r}`;let a=ue(o,i);if($e(n.themePath))try{kg(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else co(a,{recursive:!0});let l=Nl(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return co(ae,{recursive:!0}),zn(ue(ae,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Rl(c),{ok:!0,newName:i,newSessionId:l}}var ae,Oi,mn,Le,Vn=R(()=>{"use strict";y();dn();Nt();ae=ue(Tg(),".vibespot","sessions"),Oi=ue(ae,"_index.json"),mn=null;Le=null});import{readFileSync as _g,readdirSync as Jl,statSync as Di}from"fs";import{createHash as Mg}from"crypto";import{join as he,relative as Eg}from"path";function ho(t){let e=[];if(!v(t))return tf(t,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${t}`}]);let n=fn(t),s=Xg(t),o=Qg(t),i=ef(t),r=Og(t);Object.keys(n.cssVariables).length===0&&e.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&&e.push({severity:"info",rule:"design.palette.empty",message:"Could not infer a colour palette from the theme CSS."}),s.orphanModules.length>0&&e.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&&e.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)e.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)e.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&&e.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:t,designTokens:n,graph:s,fieldFlags:o,roundTripRisks:i,roundTripDiff:r,findings:e,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 Yn(t){let e=[];for(let[n,s]of Object.entries(t.cssVariables))e.push(` ${n}: ${s};`);return Object.keys(t.cssVariables).length===0&&(t.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;e.push(` --color-${o}: ${n.value};`)}),t.fontFamilies[0]&&e.push(` --font-family-base: ${t.fontFamilies[0]};`),t.fontFamilies[1]&&e.push(` --font-family-heading: ${t.fontFamilies[1]};`)),e.length===0?"":`:root {
187
- ${e.join(`
178
+ - dnd_area label: "${t} Landing Page"
179
+
180
+ Return ONLY the template HTML content, no markdown fences.`}var Ia,Ge=R(()=>{"use strict";y();ne();Ia=new Map});import{join as ce}from"path";import{readdirSync as Ze,rmSync as zp}from"fs";function Xs(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 Zs(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 Qs(e){let t=[];return Wa(e)&&t.push("textarea \u2192 text"),Ka(e)&&t.push("name \u2192 item_name"),Va(e)&&t.push("now() \u2192 local_dt"),za(e)&&t.push("Removed HubDB templates"),Ya(e)&&t.push("Fixed link field defaults"),qa(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),Yp(e)&&t.push("Stripped CDN @import statements"),Za(e)&&t.push('dnd_area \u2192 "main" in email templates'),Qa(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function Ua(e,t){return t.message.includes("textarea")?Wa(e):t.message.includes("reserved field name")?Ka(e):t.message.includes("now()")?Va(e):t.message.includes("HubDB")?za(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?Ya(e):t.message.includes("invalid format")&&t.message.includes("color")?qa(e):t.message.includes("dnd")||t.message.includes("Dnd area")?Za(e):t.message.includes("dnd_area_stylesheet")?Qa(e):!1}function Wa(e){let t=!1,n=ce(e,"modules");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"fields.json");if(!w(o))continue;let i=E(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),J(o,i),t=!0)}return t}function Ka(e){let t=!1,n=ce(e,"modules");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"fields.json");if(!w(o))continue;let i=E(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),J(o,i),t=!0)}return t}function Va(e){let t=!1,n=ce(e,"modules");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"module.html");if(!w(o))continue;let i=E(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),J(o,i),t=!0)}return t}function za(e){let t=!1,n=ce(e,"templates");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".html"))continue;let o=ce(n,s),i=E(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(zp(o),t=!0)}return t}function Ya(e){let t=!1,n=ce(e,"modules");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"fields.json");if(w(o))try{let i=JSON.parse(E(o));el(i)&&(J(o,JSON.stringify(i,null,2)+`
181
+ `),t=!0)}catch{}}return t}function Yp(e){let t=!1,n=ce(e,"css");if(w(n))for(let o of Ze(n)){if(!o.endsWith(".css"))continue;let i=ce(n,o),r=E(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(J(i,a),t=!0)}let s=ce(e,"modules");if(w(s))for(let o of Ze(s)){if(!o.endsWith(".module"))continue;let i=ce(s,o,"module.css");if(!w(i))continue;let r=E(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(J(i,a),t=!0)}if(w(s))for(let o of Ze(s)){if(!o.endsWith(".module"))continue;let i=ce(s,o,"module.html");if(!w(i))continue;let r=E(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(J(i,a),t=!0)}return t}function qa(e){let t=!1,n=ce(e,"modules");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".module"))continue;let o=ce(n,s,"fields.json");if(w(o))try{let i=JSON.parse(E(o));Xa(i)&&(J(o,JSON.stringify(i,null,2)+`
182
+ `),t=!0)}catch{}}return t}function Xa(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"&&!qp(i)){let r=Xp(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&Xa(s.children)&&(t=!0)}return t}function qp(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function Xp(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 Za(e){let t=!1,n=ce(e,"templates");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".html"))continue;let o=ce(n,s),i=E(o);if(!/templateType:\s*email/i.test(i))continue;let r=i.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');r!==i&&(J(o,r),t=!0)}return t}function Qa(e){let t=!1,n=ce(e,"templates");if(!w(n))return!1;for(let s of Ze(n)){if(!s.endsWith(".html"))continue;let o=ce(n,s),i=E(o);if(!/templateType:\s*email/i.test(i)||i.includes("dnd_area_stylesheet"))continue;let r=i.replace(/(\{\{\s*standard_header_includes\s*\}\})/,`$1
183
+ {{ dnd_area_stylesheet }}`);r!==i&&(J(o,r),t=!0)}return t}function el(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)&&el(s.children)&&(t=!0)}return t}var eo=R(()=>{"use strict";y();ne()});import{readdirSync as Zp}from"fs";import{join as Qp,relative as eg}from"path";function tl(e){let t=[];for(let n of Zp(e,{withFileTypes:!0})){if(tg.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=Qp(e,n.name);n.isDirectory()?t.push(...tl(s)):n.isFile()&&t.push(s)}return t}async function ng(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 to(e,t,n,s={}){let o=s.concurrency??5,i=tl(t),r=i.length,a=0,l=0,c=[];return await ng(i,o,async d=>{let u=eg(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await xa(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 tg,Ai=R(()=>{"use strict";y();Gt();Gt();tg=new Set([".git","node_modules",".vibespot",".DS_Store"])});var dl=R(()=>{"use strict";y()});import{existsSync as kt,writeFileSync as rg,mkdirSync as ag}from"fs";import{join as pt}from"path";function ml(e){return/^[0-9a-f]{4,40}$/i.test(e)}function pl(e){return Number.isInteger(e)&&e>0&&e<1e3}function Qe(){return no!==null||(no=X(["--version"]).success),no}function so(e){if(!Qe())return!1;if(kt(pt(e,".git")))return ul(e),!0;let t=X(["init"],{cwd:e});return t.success?(lg(e),ul(e),X(["add","-A"],{cwd:e}),X(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function ul(e){let t=pt(e,".vibespot");kt(t)||ag(t,{recursive:!0})}function lg(e){let t=pt(e,".gitignore");rg(t,[".vibespot/","node_modules/",""].join(`
184
+ `),"utf-8")}function Ut(e,t){if(!Qe()||!kt(pt(e,".git"))||(X(["add","-A"],{cwd:e}),X(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=X(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=X(["rev-parse","--short","HEAD"],{cwd:e});return i.success?i.stdout:null}function _i(e,t,n,s){if(!Qe()||!kt(pt(e,".git")))return null;for(let u of s){let m=pt(e,u);kt(m)&&X(["add","--",u],{cwd:e})}if(X(["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=X(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=X(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function gl(e){let t=[],n=null;for(let s of e.split(`
185
+ `)){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 fl(e,t=50){if(!Qe())return[];if(!kt(pt(e,".git")))return[];if(!pl(t))return[];let n=X(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:gl(n.stdout)}function hl(e,t,n=50){if(!Qe())return[];if(!kt(pt(e,".git")))return[];if(!pl(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=X(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:gl(o.stdout)}function yl(e,t){if(!Qe())return{success:!1,error:"Git not available"};if(!kt(pt(e,".git")))return{success:!1,error:"Not a git repo"};if(!ml(t))return{success:!1,error:"Invalid commit hash"};let n=X(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=X(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=X(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return X(["commit","-m",r],{cwd:e}),{success:!0}}function bl(e,t,n,s){if(!Qe())return{success:!1,error:"Git not available"};if(!kt(pt(e,".git")))return{success:!1,error:"Not a git repo"};if(!ml(n))return{success:!1,error:"Invalid commit hash"};let o=X(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=X(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)X(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};X(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return X(["commit","-m",c],{cwd:e}),{success:!0}}var no,dn=R(()=>{"use strict";y();Jt();no=null});import{appendFileSync as cg,mkdirSync as dg,readdirSync as ug,unlinkSync as mg}from"fs";import{join as Pi}from"path";import{homedir as pg}from"os";function fg(){if(!Mi)try{dg(oo,{recursive:!0}),Mi=!0}catch{}}function hg(){if(!Ii){Ii=!0;try{let e=Date.now()-gg*864e5;for(let t of ug(oo)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{mg(Pi(oo,t))}catch{}}}catch{}}}function yg(){let t=new Date().toISOString().slice(0,10);return Pi(oo,`vibespot-${t}.log`)}function bg(){return new Date().toISOString().slice(11,23)}function Ei(e,t){if(fg(),!!Mi){Ii||hg();try{cg(yg(),`${bg()} ${e} ${t}
186
+ `)}catch{}}}var oo,gg,Mi,Ii,M,de=R(()=>{"use strict";y();oo=Pi(pg(),".vibespot","logs"),gg=7,Mi=!1,Ii=!1;M={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),Ei("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),Ei("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),Ei("ERROR",o)}}});import{readFileSync as Sg,existsSync as xl,writeFileSync as xg,mkdirSync as vg,rmSync as wg}from"fs";import{join as io}from"path";function Wt(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 et(){let e=C();if(!e)return;let t=Ce();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=Tt("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 tt(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(),et(),kg()}function vl(e){let t=C();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),D())}function Sl(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function Cg(e,t){let n=Sl(e),s=Sl(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 De(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=>Cg(r.moduleName,n.moduleName));i&&M.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(),et()}}function Rt(e){let t=C();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),et())}function wl(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=io(t.themePath,"modules",`${e}.module`);xl(n)&&wg(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),et()}}function Cl(e){let t=C();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),et())}function kl(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);$l(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),et()}catch{}}function Se(){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 kg(){let e=C();if(e)try{let t=io(e.themePath,".vibespot");vg(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};xg(io(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Tl(e){let t=io(e,".vibespot","chat.json");if(!xl(t))return[];try{let n=JSON.parse(Sg(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Al(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=Tt(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&&Kn(e.pages[0].templateId),t.updatedAt=Date.now()}}function $l(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&&$l(i.children,s.slice(1).join("."),n))}var Wn=R(()=>{"use strict";y();Vn();Nt();de()});import{existsSync as ro,rmSync as ao}from"fs";import{join as un}from"path";function lo(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 Ce(){let e=C();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function Kn(e){let t=C();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,Wt(n),t.updatedAt=Date.now(),!0):!1}function Tt(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,Wt(l),s.updatedAt=Date.now(),l}function _l(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,Wt(l),n.updatedAt=Date.now(),l}function El(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 Ml(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 Il(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=un(n.themePath,"templates"),r=`${o.id}.html`,a=un(i,r);if(ro(a)&&ao(a,{force:!0}),o.pageType==="blog_post"){let l=un(i,`${o.id}-listing.html`);ro(l)&&ao(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=un(n.themePath,"modules");for(let l of r){let c=un(a,`${l}.module`);ro(c)&&ao(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?Kn(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=un(n.themePath,".vibespot","plan.md");ro(r)&&ao(r,{force:!0})}return n.updatedAt=Date.now(),!0}function At(){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 Nt=R(()=>{"use strict";y();Vn();Wn()});import{readFileSync as gt,readdirSync as ji,existsSync as $e,writeFileSync as zn,mkdirSync as co,rmSync as Ri,renameSync as Ni,cpSync as Tg}from"fs";import{join as ue,dirname as Pl}from"path";import{homedir as Ag}from"os";function uo(){if(mn)return mn;try{return $e(Oi)?(mn=JSON.parse(gt(Oi,"utf-8")),mn):Fi()}catch{return Fi()}}function mo(e){mn=e;try{co(ae,{recursive:!0}),zn(Oi,JSON.stringify(e),"utf-8")}catch{}}function Fi(){if(!$e(ae))return[];let e=[];for(let t of ji(ae).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(gt(ue(ae,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 mn=e,mo(e),e}function Rl(e){let t=uo(),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),mo(t)}function $g(e){let t=uo().filter(n=>n.id!==e);mo(t)}function _g(e){let t=uo().filter(n=>n.themeName!==e);mo(t)}function C(){return Le}function Nl(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function pn(e,t,n={}){let s={id:Nl(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Le=s,so(e),s}function D(){if(!Le)return;co(ae,{recursive:!0});let e=ue(ae,`${Le.id}.json`);zn(e,JSON.stringify(Le,null,2),"utf-8"),Rl(Le)}function po(e){let t=ue(ae,e+".json");if(!$e(t))return null;try{let n=JSON.parse(gt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),lo(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 Le=n,n}catch{return null}}function gn(){return $e(ae)?uo():[]}function Ol(e,t=!1){let n=ue(ae,e+".json"),s="";if(t)try{let o=JSON.parse(gt(n,"utf-8"));s=o.themeName||"",o.themePath&&$e(o.themePath)&&Ri(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(gt(n,"utf-8")).themeName||""}catch{}try{$e(n)&&Ri(n)}catch{}if(s&&$e(ae)){for(let o of ji(ae).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(gt(ue(ae,o),"utf-8")).themeName===s&&Ri(ue(ae,o))}catch{}_g(s)}else $g(e);Le?.id===e&&(Le=null)}function Fl(e,t){let n=ue(ae,e+".json");if(!$e(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(gt(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=ue(Pl(i),t);if($e(i)){if($e(r))return{ok:!1,error:"A project with that name already exists"};try{Ni(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=ue(r,"css",`${o}-theme.css`),l=ue(r,"css",`${t}-theme.css`);if($e(a))try{Ni(a,l)}catch{}let c=ue(r,"js",`${o}-animations.js`),d=ue(r,"js",`${t}-animations.js`);if($e(c))try{Ni(c,d)}catch{}let u=ue(r,"theme.json");if($e(u))try{let m=JSON.parse(gt(u,"utf-8"));m.label=t,m.name=t,zn(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if($e(ae))for(let a of ji(ae).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(gt(ue(ae,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),zn(ue(ae,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Le&&Le.themeName===o&&(Le.themeName=t,Le.themePath=r,Le.updatedAt=Date.now()),Fi(),{ok:!0}}function jl(e){let t=ue(ae,e+".json");if(!$e(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(gt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=Pl(n.themePath),i=`${s}-copy`,r=1;for(;$e(ue(o,i));)r++,i=`${s}-copy-${r}`;let a=ue(o,i);if($e(n.themePath))try{Tg(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else co(a,{recursive:!0});let l=Nl(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return co(ae,{recursive:!0}),zn(ue(ae,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Rl(c),{ok:!0,newName:i,newSessionId:l}}var ae,Oi,mn,Le,Vn=R(()=>{"use strict";y();dn();Nt();ae=ue(Ag(),".vibespot","sessions"),Oi=ue(ae,"_index.json"),mn=null;Le=null});import{readFileSync as Eg,readdirSync as Jl,statSync as Di}from"fs";import{createHash as Mg}from"crypto";import{join as he,relative as Ig}from"path";function ho(e){let t=[];if(!w(e))return nf(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=fn(e),s=Zg(e),o=ef(e),i=tf(e),r=Fg(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 Yn(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
+ ${t.join(`
188
188
  `)}
189
189
  }
190
- `}function yo(t,e){let n=he(t,"css");if(v(n))try{for(let r of Jl(n))if(r.endsWith("-theme.css"))return null}catch{}let s=fn(t),o=Yn(s);if(!o)return null;let i=he(n,`${e}-theme.css`);return J(i,o),i}function qn(t){return he(t,Ig)}function Rg(t,e=new Date().toISOString()){return{version:1,createdAt:e,files:Ul(t)}}function Li(t,e){let n=Rg(t,e),s=qn(t);return J(s,JSON.stringify(n,null,2)+`
191
- `),s}function Bl(t){let e=qn(t);return v(e)?null:Li(t)}function Ng(t){let e=qn(t);if(!v(e))return null;try{let n=JSON.parse(M(e));return sf(n)?n:null}catch{return null}}function Og(t){let e=qn(t),n=Ng(t);if(!n)return{hasSnapshot:!1,snapshotPath:e,filesChanged:0,added:0,modified:0,deleted:0,files:[]};let s=new Map(n.files.map(d=>[d.path,d])),o=Ul(t),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:fo(d.text),afterLines:fo(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:fo(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:fo(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:e,filesChanged:r.length,added:a,modified:l,deleted:c,files:r}}function fn(t){let e=qg(t),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 e){let m;try{m=M(u)}catch{continue}let g,h=new RegExp(Gg.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(Wg.source,"g"),S;for(;(S=b.exec(f))!==null;){let x=S[1].trim(),w=S[2].trim();n[x]||(n[x]=w);let P=w.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if(P){let F=Dl(P[0]);o.set(F,x)}}}for(let f of[Fg,jg,Dg]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let x=Dl(S[0]);x&&s.set(x,(s.get(x)??0)+1)}}go(m,Lg,i,Vg),go(m,Jg,r,f=>f.trim()),Kg(m,a),go(m,Hg,l,f=>f.trim()),go(m,Ug,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!Yg(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 go(t,e,n,s){let o=new RegExp(e.source,"g"),i;for(;(i=o.exec(t))!==null;){let r=s(i[1]);r&&!r.startsWith("var(")&&n.add(r)}}function Kg(t,e){let n=new RegExp(Bg.source,"g"),s;for(;(s=n.exec(t))!==null;){let o=s[1].trim();if(!o.startsWith("var("))for(let i of o.split(/\s+/))/^-?\d+(\.\d+)?(rem|em|px|%)$/.test(i)&&e.add(i)}}function Vg(t){return t.split(",")[0].trim().replace(/^["']|["']$/g,"")}function Dl(t){let e=t.trim().toLowerCase();if(e.startsWith("#")){if(/^#[0-9a-f]{3}$/.test(e)){let[,n,s,o]=e.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);return`#${n}${n}${s}${s}${o}${o}`}return e}return e.replace(/\s+/g,"")}function Yg(t){return zg.has(t)}function qg(t){let e=[],n=he(t,"css");if(v(n))for(let o of Ot(n))o.endsWith(".css")&&e.push(he(n,o));let s=he(t,"modules");if(v(s))for(let o of Ot(s)){if(!o.endsWith(".module"))continue;let i=he(s,o,"module.css");v(i)&&e.push(i)}return e}function Xg(t){let e=he(t,"modules"),n=he(t,"templates"),s=new Set,o=new Map;if(v(e))for(let c of Ot(e)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,v(he(e,c,"module.js")))}let i=[],r=new Map;if(v(n))for(let c of Ot(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=he(n,c),u;try{u=Di(d)}catch{continue}if(!u.isFile())continue;let m;try{m=M(d)}catch{continue}let g=Ji(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:of(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 Ji(t){let e=[],n=/{%\s*dnd_module\b[\s\S]*?%}/g,s;for(;(s=n.exec(t))!==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&&e.push(r)}return e}function Qg(t){let e=[],n=he(t,"modules");if(!v(n))return e;for(let s of Ot(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=he(n,s,"fields.json");if(!v(i))continue;let r;try{r=JSON.parse(M(i))}catch{continue}Array.isArray(r)&&Hl(r,o,e,0)}return e}function Hl(t,e,n,s){for(let o of t){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:e,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:e,field:r,reason:"repeater (occurrence) field"})}(a==="hubdb_table"||a==="hubdbtable")&&n.push({module:e,field:r,reason:"HubDB-backed field"}),(a==="crm_object"||a==="crm_object_property")&&n.push({module:e,field:r,reason:"CRM object field"}),a==="embed"&&typeof i.embed=="object"&&n.push({module:e,field:r,reason:"rich embed field"}),a&&!Zg.has(a)&&a!=="module"&&n.push({module:e,field:r,reason:`field type "${a}" not in vibeSpot's generation set`}),i.visibility&&typeof i.visibility=="object"&&n.push({module:e,field:r,reason:"conditional visibility rule"}),Array.isArray(i.children)&&Hl(i.children,e,n,s+1)}}function ef(t){let e=[],n=he(t,"modules");if(v(n))for(let i of Ot(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=he(n,i,"module.html");v(a)&&Ll(a,t,r,e);let l=he(n,i,"module.js");if(v(l))try{M(l).trim().length>0&&e.push({file:Bi(t,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=he(t,"templates");if(v(s))for(let i of Ot(s)){if(!i.endsWith(".html"))continue;let r=he(s,i);if(!v(r))continue;let a;try{a=Di(r)}catch{continue}a.isFile()&&Ll(r,t,i,e)}let o=he(t,"import_modules.json");return v(o)&&e.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),e}function Ll(t,e,n,s){let o;try{o=M(t)}catch{return}let i=Bi(e,t);/{%\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 tf(t,e){let n={hasSnapshot:!1,snapshotPath:qn(t),filesChanged:0,added:0,modified:0,deleted:0,files:[]};return{themePath:t,designTokens:{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]},graph:{templates:[],modules:[],orphanModules:[]},fieldFlags:[],roundTripRisks:[],roundTripDiff:n,findings:e,summary:{moduleCount:0,templateCount:0,orphanCount:0,paletteSize:0,cssVarCount:0,customMacroCount:0,roundTripChangedCount:0}}}function Ul(t){let e=[];function n(s){for(let o of Ot(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=he(s,o),r;try{r=Di(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=Bi(t,i),l=_g(i),c={path:a,sha256:Mg("sha256").update(l).digest("hex"),size:l.length};nf(a)&&(c.text=l.toString("utf8")),e.push(c)}}return n(t),e.sort((s,o)=>s.path.localeCompare(o.path))}function nf(t){let e=t.lastIndexOf(".");return e<0?!1:Pg.has(t.slice(e).toLowerCase())}function sf(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.version!==1||typeof e.createdAt!="string"||!Array.isArray(e.files)?!1:e.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 fo(t){if(t!==void 0)return t.length===0?0:t.split(/\r\n|\r|\n/).length}function Ot(t){try{return Jl(t)}catch{return[]}}function Bi(t,e){return Eg(t,e).split("\\").join("/")}function of(t){return[...new Set(t)]}var Ig,Pg,Fg,jg,Dg,Lg,Jg,Bg,Hg,Ug,Gg,Wg,zg,Zg,bo=R(()=>{"use strict";y();ne();Ig=".vibespot/import-snapshot.json",Pg=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);Fg=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,jg=/\brgba?\([^)]+\)/g,Dg=/\bhsla?\([^)]+\)/g,Lg=/font-family\s*:\s*([^;}\n]+)/g,Jg=/font-size\s*:\s*([^;}\n]+)/g,Bg=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,Hg=/border-radius\s*:\s*([^;}\n]+)/g,Ug=/box-shadow\s*:\s*([^;}\n]+)/g,Gg=/:root\s*\{([\s\S]*?)\}/g,Wg=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;zg=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);Zg=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 Hi,readdirSync as Zn,existsSync as xe,writeFileSync as Ke,mkdirSync as Xn,rmSync as Gl}from"fs";import{join as U}from"path";function ve(t){try{return Hi(t,"utf-8")}catch{return""}}function Kl(t){let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function rf(t,e){let n=ve(t);if(!n||e==="home.html"||e.endsWith("-listing.html"))return null;let s=e.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=Ji(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:e}}function af(t,e,n,s,o){if(!xe(t))return[];let i=[],r=Zn(t).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=U(t,a),c=rf(l,a);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let g=e.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 So(t){let e=C();if(!e)return;let n=Tl(t);n.length>0&&e.messages.length===0&&(e.messages=n),so(t),Bl(t);let s=U(t,"modules");if(!xe(s))return;let o=Zn(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let x=U(s,S.name),w=S.name.replace(/\.module$/,""),P={moduleName:w,fieldsJson:ve(U(x,"fields.json")),metaJson:ve(U(x,"meta.json")),moduleHtml:ve(U(x,"module.html")),moduleCss:ve(U(x,"module.css")),moduleJs:ve(U(x,"module.js"))||void 0};P.fieldsJson&&P.moduleHtml&&(e.modules.push(P),e.moduleOrder.push(w))}let i=U(t,"css"),r=U(t,"js"),a="",l="";if(xe(i)){let S=Zn(i).filter(x=>x.endsWith("-theme.css"));S.length>0&&(a=ve(U(i,S[0])),e.sharedCss=a)}if(xe(r)){let S=Zn(r).filter(x=>x.endsWith("-animations.js"));S.length>0&&(l=ve(U(r,S[0])),e.sharedJs=l)}if(!a&&e.modules.length>0){let S=fn(t),x=Yn(S);x&&(e.sharedCss=x,a=x)}let c=U(t,".vibespot","styleguide.md"),d=U(t,".vibespot","brandvoice.md"),u=U(t,".vibespot","theme-context.md"),m=U(t,".vibespot","plan.md"),g=U(t,".vibespot","brand-kit.json");if((xe(c)||xe(d)||xe(u)||xe(m)||xe(g))&&(e.brandAssets||(e.brandAssets={}),xe(c)&&(e.brandAssets.styleguide=ve(c)),xe(d)&&(e.brandAssets.brandvoice=ve(d)),xe(u)&&(e.brandAssets.themeContext=ve(u)),xe(m)&&(e.brandAssets.plan=ve(m)),xe(g)))try{e.brandAssets.brandKit=JSON.parse(ve(g))}catch{}let h=U(t,"templates"),f=new Map(e.modules.map(S=>[S.moduleName,S])),b=af(h,f,a,l,e.messages);if(b.length>0){e.templates=b,e.activeTemplateId=b[0].id,e.brandAssets?.plan&&!b[0].plan&&(b[0].plan=e.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let x=new Set(e.moduleOrder),w=S.filter(P=>x.has(P));for(let P of e.moduleOrder)w.includes(P)||w.push(P);e.moduleOrder=w}Wt(b[0])}else e.templates||(e.templates=[]),e.activeTemplateId||(e.activeTemplateId=""),lo(e)}function ke(){let t=C();if(!t)return;let e=t.themePath,n=new Map;if(t.templates.length>0)for(let l of t.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of t.modules)n.set(l.moduleName,l);let s=U(e,"modules");Xn(s,{recursive:!0});for(let l of n.values())Xn(U(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=U(s,`${l.moduleName}.module`);Ke(U(c,"fields.json"),l.fieldsJson,"utf-8"),Ke(U(c,"meta.json"),l.metaJson,"utf-8"),Ke(U(c,"module.html"),l.moduleHtml,"utf-8"),Ke(U(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ke(U(c,"module.js"),l.moduleJs,"utf-8")}if(t.sharedCss){let l=U(e,"css");Xn(l,{recursive:!0}),Ke(U(l,`${t.themeName}-theme.css`),t.sharedCss,"utf-8")}if(t.sharedJs){let l=U(e,"js");Xn(l,{recursive:!0}),Ke(U(l,`${t.themeName}-animations.js`),t.sharedJs,"utf-8")}let o=U(e,"templates");Xn(o,{recursive:!0});let i=U(o,"home.html");(t.templates.length>0||t.modules.length>0)&&xe(i)&&Gl(i,{force:!0});let a=new Set;if(t.templates.length>0)for(let l of t.templates){if(l.contentMode==="email"){if(l.modules.length===0)continue;let m=uf(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ke(U(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||df(l),d=Wl(c,l.label,l.pageType),u=`${l.id}.html`;Ke(U(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(mf(o,l),a.add(`${l.id}-listing.html`))}else if(t.modules.length>0){let l=t.template||pf(),c=Wl(l,`${t.themeName} Landing Page`),d=`lp-${t.themeName}.html`;Ke(U(o,d),c,"utf-8"),a.add(d)}try{for(let l of Zn(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&Gl(U(o,l),{force:!0})}catch{}lf(),cf()}function Vl(){let t=C();t&&(t.modules=[],t.moduleOrder=[],t.sharedCss="",t.sharedJs="",t.template="",So(t.themePath),t.updatedAt=Date.now(),et())}function zl(){let t=C();if(!t)return;let e=Ce();if(!e)return;let n=t.themePath,s=U(n,"modules");e.modules=[];for(let o of e.moduleOrder){let i=U(s,`${o}.module`);if(!xe(i))continue;let r={moduleName:o,fieldsJson:ve(U(i,"fields.json")),metaJson:ve(U(i,"meta.json")),moduleHtml:ve(U(i,"module.html")),moduleCss:ve(U(i,"module.css")),moduleJs:ve(U(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&e.modules.push(r)}if(e.templateFile){let o=U(n,e.templateFile);xe(o)&&(e.template=ve(o))}Wt(e),t.updatedAt=Date.now()}function lf(){let t=C();if(!t)return;let e=U(t.themePath,"templates","layouts","base.html");if(xe(e))try{let n=Hi(e,"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 yo(e,t){let n=he(e,"css");if(w(n))try{for(let r of Jl(n))if(r.endsWith("-theme.css"))return null}catch{}let s=fn(e),o=Yn(s);if(!o)return null;let i=he(n,`${t}-theme.css`);return J(i,o),i}function qn(e){return he(e,Pg)}function Ng(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:Gl(e)}}function Li(e,t){let n=Ng(e,t),s=qn(e);return J(s,JSON.stringify(n,null,2)+`
191
+ `),s}function Bl(e){let t=qn(e);return w(t)?null:Li(e)}function Og(e){let t=qn(e);if(!w(t))return null;try{let n=JSON.parse(E(t));return of(n)?n:null}catch{return null}}function Fg(e){let t=qn(e),n=Og(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=Gl(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:fo(d.text),afterLines:fo(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:fo(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:fo(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=Xg(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=E(u)}catch{continue}let g,h=new RegExp(Wg.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(Kg.source,"g"),S;for(;(S=b.exec(f))!==null;){let x=S[1].trim(),v=S[2].trim();n[x]||(n[x]=v);let I=v.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if(I){let F=Dl(I[0]);o.set(F,x)}}}for(let f of[jg,Dg,Lg]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let x=Dl(S[0]);x&&s.set(x,(s.get(x)??0)+1)}}go(m,Jg,i,zg),go(m,Bg,r,f=>f.trim()),Vg(m,a),go(m,Gg,l,f=>f.trim()),go(m,Ug,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!qg(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 go(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 Vg(e,t){let n=new RegExp(Hg.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 zg(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function Dl(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 qg(e){return Yg.has(e)}function Xg(e){let t=[],n=he(e,"css");if(w(n))for(let o of Ot(n))o.endsWith(".css")&&t.push(he(n,o));let s=he(e,"modules");if(w(s))for(let o of Ot(s)){if(!o.endsWith(".module"))continue;let i=he(s,o,"module.css");w(i)&&t.push(i)}return t}function Zg(e){let t=he(e,"modules"),n=he(e,"templates"),s=new Set,o=new Map;if(w(t))for(let c of Ot(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,w(he(t,c,"module.js")))}let i=[],r=new Map;if(w(n))for(let c of Ot(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=he(n,c),u;try{u=Di(d)}catch{continue}if(!u.isFile())continue;let m;try{m=E(d)}catch{continue}let g=Ji(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:rf(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 Ji(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 ef(e){let t=[],n=he(e,"modules");if(!w(n))return t;for(let s of Ot(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=he(n,s,"fields.json");if(!w(i))continue;let r;try{r=JSON.parse(E(i))}catch{continue}Array.isArray(r)&&Hl(r,o,t,0)}return t}function Hl(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&&!Qg.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)&&Hl(i.children,t,n,s+1)}}function tf(e){let t=[],n=he(e,"modules");if(w(n))for(let i of Ot(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=he(n,i,"module.html");w(a)&&Ll(a,e,r,t);let l=he(n,i,"module.js");if(w(l))try{E(l).trim().length>0&&t.push({file:Bi(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=he(e,"templates");if(w(s))for(let i of Ot(s)){if(!i.endsWith(".html"))continue;let r=he(s,i);if(!w(r))continue;let a;try{a=Di(r)}catch{continue}a.isFile()&&Ll(r,e,i,t)}let o=he(e,"import_modules.json");return w(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 Ll(e,t,n,s){let o;try{o=E(e)}catch{return}let i=Bi(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 nf(e,t){let n={hasSnapshot:!1,snapshotPath:qn(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 Gl(e){let t=[];function n(s){for(let o of Ot(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=he(s,o),r;try{r=Di(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=Bi(e,i),l=Eg(i),c={path:a,sha256:Mg("sha256").update(l).digest("hex"),size:l.length};sf(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function sf(e){let t=e.lastIndexOf(".");return t<0?!1:Rg.has(e.slice(t).toLowerCase())}function of(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 fo(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Ot(e){try{return Jl(e)}catch{return[]}}function Bi(e,t){return Ig(e,t).split("\\").join("/")}function rf(e){return[...new Set(e)]}var Pg,Rg,jg,Dg,Lg,Jg,Bg,Hg,Gg,Ug,Wg,Kg,Yg,Qg,bo=R(()=>{"use strict";y();ne();Pg=".vibespot/import-snapshot.json",Rg=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);jg=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Dg=/\brgba?\([^)]+\)/g,Lg=/\bhsla?\([^)]+\)/g,Jg=/font-family\s*:\s*([^;}\n]+)/g,Bg=/font-size\s*:\s*([^;}\n]+)/g,Hg=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,Gg=/border-radius\s*:\s*([^;}\n]+)/g,Ug=/box-shadow\s*:\s*([^;}\n]+)/g,Wg=/:root\s*\{([\s\S]*?)\}/g,Kg=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;Yg=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);Qg=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 Hi,readdirSync as Zn,existsSync as xe,writeFileSync as Ke,mkdirSync as Xn,rmSync as Ul}from"fs";import{join as G}from"path";function ve(e){try{return Hi(e,"utf-8")}catch{return""}}function Kl(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 af(e,t){let n=ve(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=Ji(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function lf(e,t,n,s,o){if(!xe(e))return[];let i=[],r=Zn(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=G(e,a),c=af(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 So(e){let t=C();if(!t)return;let n=Tl(e);n.length>0&&t.messages.length===0&&(t.messages=n),so(e),Bl(e);let s=G(e,"modules");if(!xe(s))return;let o=Zn(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let x=G(s,S.name),v=S.name.replace(/\.module$/,""),I={moduleName:v,fieldsJson:ve(G(x,"fields.json")),metaJson:ve(G(x,"meta.json")),moduleHtml:ve(G(x,"module.html")),moduleCss:ve(G(x,"module.css")),moduleJs:ve(G(x,"module.js"))||void 0};I.fieldsJson&&I.moduleHtml&&(t.modules.push(I),t.moduleOrder.push(v))}let i=G(e,"css"),r=G(e,"js"),a="",l="";if(xe(i)){let S=Zn(i).filter(x=>x.endsWith("-theme.css"));S.length>0&&(a=ve(G(i,S[0])),t.sharedCss=a)}if(xe(r)){let S=Zn(r).filter(x=>x.endsWith("-animations.js"));S.length>0&&(l=ve(G(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=fn(e),x=Yn(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((xe(c)||xe(d)||xe(u)||xe(m)||xe(g))&&(t.brandAssets||(t.brandAssets={}),xe(c)&&(t.brandAssets.styleguide=ve(c)),xe(d)&&(t.brandAssets.brandvoice=ve(d)),xe(u)&&(t.brandAssets.themeContext=ve(u)),xe(m)&&(t.brandAssets.plan=ve(m)),xe(g)))try{t.brandAssets.brandKit=JSON.parse(ve(g))}catch{}let h=G(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=lf(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),v=S.filter(I=>x.has(I));for(let I of t.moduleOrder)v.includes(I)||v.push(I);t.moduleOrder=v}Wt(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),lo(t)}function ke(){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=G(t,"modules");Xn(s,{recursive:!0});for(let l of n.values())Xn(G(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=G(s,`${l.moduleName}.module`);Ke(G(c,"fields.json"),l.fieldsJson,"utf-8"),Ke(G(c,"meta.json"),l.metaJson,"utf-8"),Ke(G(c,"module.html"),l.moduleHtml,"utf-8"),Ke(G(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ke(G(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=G(t,"css");Xn(l,{recursive:!0}),Ke(G(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=G(t,"js");Xn(l,{recursive:!0}),Ke(G(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=G(t,"templates");Xn(o,{recursive:!0});let i=G(o,"home.html");(e.templates.length>0||e.modules.length>0)&&xe(i)&&Ul(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=mf(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ke(G(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||uf(l),d=Wl(c,l.label,l.pageType),u=`${l.id}.html`;Ke(G(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(pf(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||gf(),c=Wl(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ke(G(o,d),c,"utf-8"),a.add(d)}try{for(let l of Zn(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&Ul(G(o,l),{force:!0})}catch{}cf(),df()}function Vl(){let e=C();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",So(e.themePath),e.updatedAt=Date.now(),et())}function zl(){let e=C();if(!e)return;let t=Ce();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(!xe(i))continue;let r={moduleName:o,fieldsJson:ve(G(i,"fields.json")),metaJson:ve(G(i,"meta.json")),moduleHtml:ve(G(i,"module.html")),moduleCss:ve(G(i,"module.css")),moduleJs:ve(G(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=G(n,t.templateFile);xe(o)&&(t.template=ve(o))}Wt(t),e.updatedAt=Date.now()}function cf(){let e=C();if(!e)return;let t=G(e.themePath,"templates","layouts","base.html");if(xe(t))try{let n=Hi(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 }}`),Ke(e,n,"utf-8")}catch{}}function cf(){let t=C();if(!t)return;let e=U(t.themePath,"theme.json");if(xe(e))try{let n=JSON.parse(Hi(e,"utf-8"));n.label=t.themeName,n.name=t.themeName,Ke(e,JSON.stringify(n,null,2),"utf-8")}catch{}}function Wl(t,e,n="landing_page"){return t.includes("templateType")?t:`<!--
197
+ {{ standard_footer_includes }}`),Ke(t,n,"utf-8")}catch{}}function df(){let e=C();if(!e)return;let t=G(e.themePath,"theme.json");if(xe(t))try{let n=JSON.parse(Hi(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ke(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Wl(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
198
198
  templateType: ${n==="blog_post"?"blog_post":"page"}
199
199
  isAvailableForNewContent: true
200
- label: "${e}"
200
+ label: "${t}"
201
201
  -->
202
- `+t}function df(t){if(t.modules.length===0)return"";let n=C().themeName,o=Kl(t).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
202
+ `+e}function uf(e){if(e.modules.length===0)return"";let n=C().themeName,o=Kl(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(`
206
206
 
207
207
  `);return`<!--
208
- templateType: ${t.pageType==="blog_post"?"blog_post":"page"}
208
+ templateType: ${e.pageType==="blog_post"?"blog_post":"page"}
209
209
  isAvailableForNewContent: true
210
- label: "${t.label}"
210
+ label: "${e.label}"
211
211
  -->
212
212
  {% extends "./layouts/base.html" %}
213
213
 
@@ -219,7 +219,7 @@ ${e.join(`
219
219
 
220
220
  {% block body %}
221
221
  <div class="${n}-page">
222
- {% dnd_area "main_content" label="${t.label}" %}
222
+ {% dnd_area "main_content" label="${e.label}" %}
223
223
 
224
224
  ${o}
225
225
 
@@ -230,7 +230,7 @@ ${o}
230
230
 
231
231
  {% block footer %}
232
232
  {% endblock footer %}
233
- `}function uf(t){let n=Kl(t).map(s=>` {% dnd_section %}
233
+ `}function mf(e){let n=Kl(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(`
@@ -238,7 +238,7 @@ ${o}
238
238
  `);return`<!--
239
239
  templateType: email
240
240
  isAvailableForNewContent: true
241
- label: "${t.label}"
241
+ label: "${e.label}"
242
242
  screenshotPath: ../images/template-previews/email.png
243
243
  -->
244
244
  <!DOCTYPE html>
@@ -277,10 +277,10 @@ ${n}
277
277
  {{ standard_footer_includes }}
278
278
  </body>
279
279
  </html>
280
- `}function mf(t,e){let n=`<!--
280
+ `}function pf(e,t){let n=`<!--
281
281
  templateType: blog_listing
282
282
  isAvailableForNewContent: true
283
- label: "${e.label} - Listing"
283
+ label: "${t.label} - Listing"
284
284
  -->
285
285
  {% extends "./layouts/base.html" %}
286
286
 
@@ -302,7 +302,7 @@ ${n}
302
302
  {% endif %}
303
303
  </div>
304
304
  {% endblock body %}
305
- `;Ke(U(t,`${e.id}-listing.html`),n,"utf-8")}function pf(){let t=C();if(!t||t.modules.length===0)return"";let e=t.themeName,s=Se().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
305
+ `;Ke(G(e,`${t.id}-listing.html`),n,"utf-8")}function gf(){let e=C();if(!e||e.modules.length===0)return"";let t=e.themeName,s=Se().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(`
@@ -310,38 +310,38 @@ ${n}
310
310
  `);return`<!--
311
311
  templateType: page
312
312
  isAvailableForNewContent: true
313
- label: "${e} Landing Page"
313
+ label: "${t} Landing Page"
314
314
  -->
315
315
  {% extends "./layouts/base.html" %}
316
316
 
317
- {% set template_css = "../../css/${e}-theme.css" %}
318
- {% set template_js = "../../js/${e}-animations.js" %}
317
+ {% set template_css = "../../css/${t}-theme.css" %}
318
+ {% set template_js = "../../js/${t}-animations.js" %}
319
319
 
320
320
  {% block header %}
321
321
  {% endblock header %}
322
322
 
323
323
  {% block body %}
324
- <div class="${e}-page">
325
- {% dnd_area "main_content" label="${e} Landing Page" %}
324
+ <div class="${t}-page">
325
+ {% dnd_area "main_content" label="${t} Landing Page" %}
326
326
 
327
327
  ${s}
328
328
 
329
329
  {% end_dnd_area %}
330
330
  </div>
331
- {{ require_js(get_asset_url("../../js/${e}-animations.js")) }}
331
+ {{ require_js(get_asset_url("../../js/${t}-animations.js")) }}
332
332
  {% endblock body %}
333
333
 
334
334
  {% block footer %}
335
335
  {% endblock footer %}
336
- `}var Ui=R(()=>{"use strict";y();Vn();Wn();Nt();dn();bo()});var Yl=R(()=>{"use strict";y();dl();Vn();Wn();Ui();Nt()});var we=R(()=>{"use strict";y();Yl()});function Qn(t){let e={};for(let n of t)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?e[n.name]=n.default:n.type==="group"&&n.children?e[n.name]=Qn(n.children):e[n.name]=n.default??"";return e}function xo(t,e){let n=t;return n=wf(n),n=Ql(n,e),n=ec(n,e),n=tc(n,e),n=kf(n),n}function Wi(t){let e=[t.sharedCss||"",...t.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
337
- `),n=[t.sharedJs||"",...t.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
338
- `),s=t.renderedModules.join(`
336
+ `}var Gi=R(()=>{"use strict";y();Vn();Wn();Nt();dn();bo()});var Yl=R(()=>{"use strict";y();dl();Vn();Wn();Gi();Nt()});var we=R(()=>{"use strict";y();Yl()});function Qn(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]=Qn(n.children):t[n.name]=n.default??"";return t}function xo(e,t){let n=e;return n=Cf(n),n=Ql(n,t),n=ec(n,t),n=tc(n,t),n=Tf(n),n}function Wi(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
337
+ `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
338
+ `),s=e.renderedModules.join(`
339
339
  `);return`<!DOCTYPE html>
340
340
  <html lang="en">
341
341
  <head>
342
342
  <meta charset="utf-8">
343
343
  <meta name="viewport" content="width=device-width, initial-scale=1">
344
- ${e}
344
+ ${t}
345
345
  <style>
346
346
  html{scroll-behavior:smooth}
347
347
  .vsp-img-wrap{position:relative;display:inline-block}
@@ -380,11 +380,11 @@ document.querySelectorAll('img').forEach(function(img){
380
380
  });
381
381
  </script>
382
382
  </body>
383
- </html>`}function wf(t){return t=t.replace(gf,""),t=t.replace(ff,""),t=t.replace(hf,""),ql.lastIndex=0,t=t.replace(ql,(e,n)=>`/theme-assets/${n}`),Xl.lastIndex=0,t=t.replace(Xl,""),t=t.replace(yf,""),t=t.replace(bf,""),t=t.replace(Sf,""),t=t.replace(xf,""),t=t.replace(vf,""),t}function Ql(t,e){let n=t,s=0;for(;s<30;){s++;let o=Cf(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Tf(r,e),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let h={...e,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},f=Ql(a,h);return f=ec(f,h),f=tc(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Cf(t){let e=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=e.exec(t);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(t))!==null;)if(l[1].startsWith("for"))a++;else if(a--,a===0){let c=t.slice(r,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function ec(t,e){let n=t,s=0;for(;Gi.test(n)&&s<50;)s++,n=n.replace(Gi,(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(hn(i,e))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(hn(m,e))return g}return c}return hn(i,e)?l:c}),Gi.lastIndex=0;return n}function tc(t,e){return t.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Kt(e,r);for(let c=1;c<i.length;c++)a=sc(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 kf(t){return t=t.replace(/\{%.*?%\}/gs,""),t=t.replace(/\{\{.*?\}\}/gs,""),t}function Tf(t,e){let n=t.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Zl(n[1],e),i=Zl(n[2],e),r=[];for(let a=o;a<i;a++)r.push(a);return r}let s=t.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=Kt(e,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Kt(e,t)}function Zl(t,e){let s=t.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Kt(e,o);for(let r=1;r<s.length;r++)i=sc(i,s[r].trim());return Number(i)||0}function Kt(t,e){let n=e.split("."),s=t;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function hn(t,e){let n=t.trim();if(n.startsWith("not "))return!hn(n.slice(4),e);if(n.includes(" and "))return n.split(" and ").every(i=>hn(i,e));if(n.includes(" or "))return n.split(" or ").some(i=>hn(i,e));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=Kt(e,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=Kt(e,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=Kt(e,n);return nc(o)}function nc(t){return!(t==null||t===""||t===0||t===!1||Array.isArray(t)&&t.length===0)}function sc(t,e){let n=t==null?"":String(t),s=e.match(/^(\w+)\((.*)\)$/),o=s?s[1]:e,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 nc(t)?t:i??"";case"length":return Array.isArray(t)?t.length:n.length;case"join":return Array.isArray(t)?t.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));default:return t}}var gf,ff,hf,ql,Xl,yf,bf,Sf,xf,vf,Gi,oc=R(()=>{"use strict";y();gf=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,ff=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,hf=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,ql=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Xl=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,yf=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,bf=/\{%[-\s]*module\b.*?%\}/gs,Sf=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,xf=/\{#.*?#\}/gs,vf=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Gi=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var vo={};Be(vo,{buildModulePreviewHtml:()=>zi,buildPreviewHtml:()=>Vi});function Af(t){if(yn()==="email")return!0;for(let e of t)try{let n=JSON.parse(e.metaJson);if(Array.isArray(n.host_template_types)&&n.host_template_types.includes("EMAIL"))return!0}catch{}return!1}function $f(t){if(!t)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let e=(a,l)=>{for(let c of a){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=t.match(d);if(u)return u[1].trim()}return l},n=e(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=e(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=e(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=e(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),r=e(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:r}}function Ki(t,e){if(!Array.isArray(e))return t;let n=new Map;for(let o of e)n.set(o.name,o.type);let s=t;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 Vi(){let t=C();if(!t)return ic();let e=Se(),n=t.moduleOrder||[];if(e.length===0&&n.length===0)return ic();if(Af(e))return _f(e,n);let s=[],o=[],i=[],r=new Set;for(let c of e){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:Qn(u)}}catch{d={module:{}}}let m=Ki(c.moduleHtml,u),g=xo(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=$f(t.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 Cf(e){return e=e.replace(ff,""),e=e.replace(hf,""),e=e.replace(yf,""),ql.lastIndex=0,e=e.replace(ql,(t,n)=>`/theme-assets/${n}`),Xl.lastIndex=0,e=e.replace(Xl,""),e=e.replace(bf,""),e=e.replace(Sf,""),e=e.replace(xf,""),e=e.replace(vf,""),e=e.replace(wf,""),e}function Ql(e,t){let n=e,s=0;for(;s<30;){s++;let o=kf(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Af(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=Ql(a,h);return f=ec(f,h),f=tc(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function kf(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 ec(e,t){let n=e,s=0;for(;Ui.test(n)&&s<50;)s++,n=n.replace(Ui,(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(hn(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(hn(m,t))return g}return c}return hn(i,t)?l:c}),Ui.lastIndex=0;return n}function tc(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Kt(t,r);for(let c=1;c<i.length;c++)a=sc(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 Tf(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Af(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Zl(n[1],t),i=Zl(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=Kt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Kt(t,e)}function Zl(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Kt(t,o);for(let r=1;r<s.length;r++)i=sc(i,s[r].trim());return Number(i)||0}function Kt(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 hn(e,t){let n=e.trim();if(n.startsWith("not "))return!hn(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>hn(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>hn(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=Kt(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=Kt(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=Kt(t,n);return nc(o)}function nc(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function sc(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 nc(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));default:return e}}var ff,hf,yf,ql,Xl,bf,Sf,xf,vf,wf,Ui,oc=R(()=>{"use strict";y();ff=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,hf=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,yf=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,ql=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Xl=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,bf=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Sf=/\{%[-\s]*module\b.*?%\}/gs,xf=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,vf=/\{#.*?#\}/gs,wf=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Ui=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var vo={};Be(vo,{buildModulePreviewHtml:()=>zi,buildPreviewHtml:()=>Vi});function $f(e){if(yn()==="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 _f(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 Ki(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 Vi(){let e=C();if(!e)return ic();let t=Se(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return ic();if($f(t))return Ef(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:Qn(u)}}catch{d={module:{}}}let m=Ki(c.moduleHtml,u),g=xo(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=_f(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 Wi({renderedModules:s,sharedCss:t.sharedCss,moduleCssArray:[l,...o],sharedJs:t.sharedJs,moduleJsArray:i})}function ic(){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 Wi({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function ic(){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 zi(t){let e=C();if(!e)return"";let n;for(let a of e.templates)if(n=a.modules.find(l=>l.moduleName===t),n)break;if(n||(n=e.modules.find(a=>a.moduleName===t)),!n)return"";let s,o=[];try{let a=JSON.parse(n.fieldsJson);o=Array.isArray(a)?a:[],s={module:Qn(o)}}catch{s={module:{}}}let i=Ki(n.moduleHtml,o),r=xo(i,s);return Wi({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${r}</div>`],sharedCss:e.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:e.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}function _f(t,e){let n=[],s=new Set;for(let i of t){let r,a=[];try{let u=JSON.parse(i.fieldsJson);a=Array.isArray(u)?u:[],r={module:Qn(a)}}catch{r={module:{}}}let l=Ki(i.moduleHtml,a),c=xo(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 e)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 zi(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:Qn(o)}}catch{s={module:{}}}let i=Ki(n.moduleHtml,o),r=xo(i,s);return Wi({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 Ef(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:Qn(a)}}catch{r={module:{}}}let l=Ki(i.moduleHtml,a),c=xo(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,11 +485,11 @@ document.addEventListener('click', function(e) {
485
485
  });
486
486
  </script>
487
487
  </body>
488
- </html>`}var es=R(()=>{"use strict";y();oc();we();ts()});function ft(t){try{return JSON.parse(t)}catch{}let e=t,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(e)}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=e.slice(a,r+1).lastIndexOf('"');if(c===-1)return null;let d=a+c;if(d>0&&e[d-1]==="\\")return null;e=e.slice(0,d)+'\\"'+e.slice(d+1)}return null}function ns(t){let e=t.indexOf('"modules"');if(e===-1)return null;let n=t.indexOf("[",e);if(n===-1)return null;let s=-1,o=0,i=!1,r=!1;for(let d=n+1;d<t.length;d++){let u=t[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=t.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ft(c)}function Yi(t){return{moduleName:String(t.moduleName||""),fieldsJson:typeof t.fieldsJson=="string"?t.fieldsJson:JSON.stringify(t.fieldsJson,null,2),metaJson:typeof t.metaJson=="string"?t.metaJson:JSON.stringify(t.metaJson,null,2),moduleHtml:String(t.moduleHtml||""),moduleCss:String(t.moduleCss||""),moduleJs:t.moduleJs?String(t.moduleJs):void 0}}function rc(t,e){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(t))!==null;)try{E.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ft(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)&&(De({modules:r.modules.map(a=>Yi(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(t))!==null;)if(s[1].includes('"modules"'))try{let r=ft(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(De({modules:a.modules.map(l=>Yi(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&&(t.match(/```/g)||[]).length%2!==0&&t.includes('"modules"')){E.info("parse","Detected truncated response (odd fence count), attempting salvage");let r=t.lastIndexOf("```"),a=t.slice(r+3);a=a.replace(/^[\w-]*\s*\n?/,"");let l=ns(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}),De({modules:c.modules.map(d=>Yi(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,e&&e("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:t.length,hasVibespot:t.includes("vibespot-modules"),hasModules:t.includes('"modules"'),fenceCount:(t.match(/```/g)||[]).length});let i=t.includes("vibespot-modules")||t.includes('"modules"'),r=/\bmodule|modul/i.test(t)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(t)||/\|.*\|.*\|/m.test(t));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),e&&e(a)}}}var wo=R(()=>{"use strict";y();we();de()});function bn(){let t=C();return t?{pageType:Ce()?.pageType,brandAssets:t.brandAssets}:{}}function ac(t,e,n=!1,s,o){let r=[{type:"text",text:Ef(e,n)}];if(n){let l=`## HubSpot CMS Rules
488
+ </html>`}var es=R(()=>{"use strict";y();oc();we();ts()});function ft(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 ns(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 ft(c)}function Yi(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 rc(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{M.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ft(s[1]);if(!i||typeof i!="object")throw M.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let r=i;r.modules&&Array.isArray(r.modules)&&(De({modules:r.modules.map(a=>Yi(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){M.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=ft(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(De({modules:a.modules.map(l=>Yi(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){M.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"')){M.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=ns(a);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(M.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),De({modules:c.modules.map(d=>Yi(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){M.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.";M.warn("parse",a),t&&t(a)}}}var wo=R(()=>{"use strict";y();we();de()});function bn(){let e=C();return e?{pageType:Ce()?.pageType,brandAssets:e.brandAssets}:{}}function ac(e,t,n=!1,s,o){let r=[{type:"text",text:If(t,n)}];if(n){let l=`## HubSpot CMS Rules
489
489
  ${je()}
490
490
 
491
491
  ## Conversion Guide Reference
492
- ${t}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
492
+ ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
493
493
  - Use modern, clean design with proper spacing and typography
494
494
  - Include responsive CSS (mobile breakpoint at 767px)
495
495
  - Add scroll animation classes where appropriate
@@ -512,7 +512,7 @@ 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
- ${Un()}
515
+ ${Gn()}
516
516
 
517
517
  ## Content & Copywriting Guide
518
518
  ${Ci()}
@@ -521,13 +521,13 @@ ${Ci()}
521
521
  ${je()}
522
522
 
523
523
  ## Conversion Guide Reference
524
- ${t}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=Mf(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 Mf(t,e){let n=[];if(t){let s=Ti(t);s&&n.push(`## Page Type Context
525
- ${s}`)}if(e?.styleguide&&n.push(`## Brand Style Guide
526
- ${e.styleguide}`),e?.brandvoice&&n.push(`## Brand Voice
527
- ${e.brandvoice}`),e?.humanify!==!1){let s=ki();s&&n.push(`## Anti-AI Copy Rules (Humanify)
524
+ ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=Mf(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 Mf(e,t){let n=[];if(e){let s=Ti(e);s&&n.push(`## Page Type Context
525
+ ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
526
+ ${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
527
+ ${t.brandvoice}`),t?.humanify!==!1){let s=ki();s&&n.push(`## Anti-AI Copy Rules (Humanify)
528
528
  ${s}`)}return n.join(`
529
529
 
530
- `)}function Ef(t,e){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
530
+ `)}function If(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.
@@ -569,8 +569,8 @@ NEVER respond with only a text summary. The vibespot-modules JSON block is manda
569
569
  - NEVER use "name": "name" (reserved) \u2014 use "item_name" instead
570
570
  - NEVER put literal \\n newline sequences in field default values \u2014 use plain text without line breaks
571
571
  - Wrap style fields in a "styles" group with "tab": "STYLE"
572
- - All CSS classes must use a unique prefix "${t}-" to avoid theme conflicts
573
- - Use BEM naming: ${t}-module__element--modifier
572
+ - All CSS classes must use a unique prefix "${e}-" to avoid theme conflicts
573
+ - Use BEM naming: ${e}-module__element--modifier
574
574
  - metaJson must include: host_template_types: ["PAGE"], is_available_for_new_content: true
575
575
  - For repeater groups, use "occurrence": { "min": 0, "max": 100 } and iterate with {% for %}
576
576
  - Color fields: type "color", default { "color": "#hex", "opacity": 100 }
@@ -579,9 +579,9 @@ NEVER respond with only a text summary. The vibespot-modules JSON block is manda
579
579
 
580
580
  ## Images & Media
581
581
  - Users can upload images that get placed in the theme's assets/ folder automatically
582
- - When the user uploads an image and wants it on the page, reference it with: {{ get_asset_url("${t}/assets/filename.ext") }}
583
- - IMPORTANT: get_asset_url() paths must include the theme name prefix "${t}/" because HubSpot resolves from the Design Manager root
584
- - For background images with uploaded assets: style="background-image: url('{{ get_asset_url(\\"${t}/assets/filename.ext\\") }}')"
582
+ - When the user uploads an image and wants it on the page, reference it with: {{ get_asset_url("${e}/assets/filename.ext") }}
583
+ - IMPORTANT: get_asset_url() paths must include the theme name prefix "${e}/" because HubSpot resolves from the Design Manager root
584
+ - For background images with uploaded assets: style="background-image: url('{{ get_asset_url(\\"${e}/assets/filename.ext\\") }}')"
585
585
  - For images without an uploaded asset, use image fields (type "image") with placehold.co defaults
586
586
  - ALWAYS use image fields (type "image") so users can swap images in the page editor
587
587
  - Use placehold.co URLs as defaults so the preview looks complete (e.g. https://placehold.co/800x600/1a1a2e/ffffff?text=Hero+Image)
@@ -596,7 +596,7 @@ NEVER respond with only a text summary. The vibespot-modules JSON block is manda
596
596
  - The id should be the moduleName lowercased with spaces replaced by hyphens (e.g. "Pricing Cards" \u2192 id="pricing-cards")
597
597
  - For navigation/menu modules, use anchor links that match these ids: e.g. href="#features"
598
598
  - Always include smooth scrolling behavior in navigation link clicks
599
- - For nav modules, make menu items editable via a repeater group with "label" (text) and "anchor" (text) fields`+(e?`
599
+ - For nav modules, make menu items editable via a repeater group with "label" (text) and "anchor" (text) fields`+(t?`
600
600
 
601
601
  ## When modifying existing modules
602
602
  The current template's modules are listed in page order in the user message. This sequence forms the page narrative.
@@ -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 ss(t,e,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 ss(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.
@@ -648,8 +648,8 @@ NEVER respond with only a text summary. The vibespot-modules JSON block is manda
648
648
  - NEVER use "name": "name" (reserved) \u2014 use "item_name" instead
649
649
  - NEVER put literal \\n newline sequences in field default values \u2014 use plain text without line breaks
650
650
  - Wrap style fields in a "styles" group with "tab": "STYLE"
651
- - All CSS classes must use a unique prefix "${e}-" to avoid theme conflicts
652
- - Use BEM naming: ${e}-module__element--modifier
651
+ - All CSS classes must use a unique prefix "${t}-" to avoid theme conflicts
652
+ - Use BEM naming: ${t}-module__element--modifier
653
653
  - metaJson must include: host_template_types: ["PAGE"], is_available_for_new_content: true
654
654
  - For repeater groups, use "occurrence": { "min": 0, "max": 100 } and iterate with {% for %}
655
655
  - Color fields: type "color", default { "color": "#hex", "opacity": 100 }
@@ -658,9 +658,9 @@ NEVER respond with only a text summary. The vibespot-modules JSON block is manda
658
658
 
659
659
  ## Images & Media
660
660
  - Users can upload images that get placed in the theme's assets/ folder automatically
661
- - When the user uploads an image and wants it on the page, reference it with: {{ get_asset_url("${e}/assets/filename.ext") }}
662
- - IMPORTANT: get_asset_url() paths must include the theme name prefix "${e}/" because HubSpot resolves from the Design Manager root
663
- - For background images with uploaded assets: style="background-image: url('{{ get_asset_url(\\"${e}/assets/filename.ext\\") }}')"
661
+ - When the user uploads an image and wants it on the page, reference it with: {{ get_asset_url("${t}/assets/filename.ext") }}
662
+ - IMPORTANT: get_asset_url() paths must include the theme name prefix "${t}/" because HubSpot resolves from the Design Manager root
663
+ - For background images with uploaded assets: style="background-image: url('{{ get_asset_url(\\"${t}/assets/filename.ext\\") }}')"
664
664
  - For images without an uploaded asset, use image fields (type "image") with placehold.co defaults
665
665
  - ALWAYS use image fields (type "image") so users can swap images in the page editor
666
666
  - Use placehold.co URLs as defaults so the preview looks complete (e.g. https://placehold.co/800x600/1a1a2e/ffffff?text=Hero+Image)
@@ -703,7 +703,7 @@ ${d}`)}let c="\n\n## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUS
703
703
  ${je()}
704
704
 
705
705
  ## Conversion Guide Reference
706
- ${t}`+c:i+a+l+`
706
+ ${e}`+c:i+a+l+`
707
707
 
708
708
  ## Design Quality
709
709
  - Use modern, clean design with proper spacing and typography
@@ -728,7 +728,7 @@ 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
- ${Un()}
731
+ ${Gn()}
732
732
 
733
733
  ## Content & Copywriting Guide
734
734
  ${Ci()}
@@ -737,107 +737,107 @@ ${Ci()}
737
737
  ${je()}
738
738
 
739
739
  ## Conversion Guide Reference
740
- ${t}`+c}function os(){let t=C(),e=[],n=t.modules,s=n.length;if(s>0){e.push(`
740
+ ${e}`+c}function os(){let e=C(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
741
741
 
742
742
  ## Page Narrative (module sequence)
743
- `),e.push(`This template has ${s} module${s===1?"":"s"} in this order:
744
- `);for(let a=0;a<s;a++)e.push(`${a+1}. ${n[a].moduleName}
745
- `);e.push(`
743
+ `),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
744
+ `);for(let a=0;a<s;a++)t.push(`${a+1}. ${n[a].moduleName}
745
+ `);t.push(`
746
746
  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.
747
- `),e.push(`
747
+ `),t.push(`
748
748
  ## Current Module State
749
- `);for(let a=0;a<s;a++){let l=n[a];e.push(`
749
+ `);for(let a=0;a<s;a++){let l=n[a];t.push(`
750
750
  ### ${a+1}/${s}: ${l.moduleName}.module
751
- `),e.push(`**fields.json:**
751
+ `),t.push(`**fields.json:**
752
752
  \`\`\`json
753
753
  ${l.fieldsJson}
754
754
  \`\`\`
755
- `),e.push(`**module.html:**
755
+ `),t.push(`**module.html:**
756
756
  \`\`\`html
757
757
  ${l.moduleHtml}
758
758
  \`\`\`
759
- `),e.push(`**module.css:**
759
+ `),t.push(`**module.css:**
760
760
  \`\`\`css
761
761
  ${l.moduleCss}
762
762
  \`\`\`
763
- `),l.moduleJs&&e.push(`**module.js:**
763
+ `),l.moduleJs&&t.push(`**module.js:**
764
764
  \`\`\`js
765
765
  ${l.moduleJs}
766
766
  \`\`\`
767
- `)}t.sharedCss&&e.push(`
767
+ `)}e.sharedCss&&t.push(`
768
768
  ### Shared CSS
769
769
  \`\`\`css
770
- ${t.sharedCss}
770
+ ${e.sharedCss}
771
771
  \`\`\`
772
- `),t.sharedJs&&e.push(`
772
+ `),e.sharedJs&&t.push(`
773
773
  ### Shared JS
774
774
  \`\`\`js
775
- ${t.sharedJs}
775
+ ${e.sharedJs}
776
776
  \`\`\`
777
- `)}let o=At(),i=new Set(t.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){e.push(`
777
+ `)}let o=At(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
778
778
 
779
779
  ## Available modules in this theme (reusable)
780
- `);for(let a of r)e.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
781
- `);e.push(`
780
+ `);for(let a of r)t.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
781
+ `);t.push(`
782
782
  The user can ask to reuse any of these modules by name.
783
- `)}return e.join("")}function qi(t,e){let n=C(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===t&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=os(),r="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(r=`
783
+ `)}return t.join("")}function qi(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=os(),r="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(r=`
784
784
 
785
785
  ## Available Theme Assets
786
786
  These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
787
787
  ${d.map(u=>`- ${u.filename} (${u.originalName}) \u2192 get_asset_url("${n.themeName}/assets/${u.filename}")`).join(`
788
- `)}`)}let a=t;i&&(a+=`
788
+ `)}`)}let a=e;i&&(a+=`
789
789
 
790
790
  ---
791
- ${i}`),r&&(a+=r),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let l=e&&e.length>0;if(l)for(let d of e)d.type==="document"&&d.extractedText&&(a+=`
791
+ ${i}`),r&&(a+=r),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let l=t&&t.length>0;if(l)for(let d of t)d.type==="document"&&d.extractedText&&(a+=`
792
792
 
793
793
  ---
794
794
  [Attached document: ${d.originalName}]
795
795
  ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(a+=`
796
796
 
797
- [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?e.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 lc=R(()=>{"use strict";y();Ue();we()});import{spawn as cc}from"child_process";async function dc(){return Xi||(Xi=(await import("@anthropic-ai/sdk")).default),Xi}function uc(t){if(!t?.length)return"";let e=[];for(let n of t)n.type==="image"&&n.usage==="asset"&&n.assetPath&&e.push(`
798
- [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&e.push(`
797
+ [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 lc=R(()=>{"use strict";y();Ge();we()});import{spawn as cc}from"child_process";async function dc(){return Xi||(Xi=(await import("@anthropic-ai/sdk")).default),Xi}function uc(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
798
+ [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
799
799
 
800
800
  ---
801
801
  [Attached document: ${n.originalName}]
802
- ${n.extractedText}`);return e.join("")}async function mc(t,e,n,s,o,i,r){for(let a=0;;a++)try{let l="",c=0,d=i||(()=>{});d(Re[0]);let u=setInterval(()=>{c++,d(Re[Math.min(c,Re.length-1)])},6e3);try{let m=t.messages.stream({model:s,max_tokens:48e3,system:e,messages:n});for await(let g of m)if(g.type==="content_block_delta"&&g.delta.type==="text_delta"){let h=g.delta.text;l+=h,o(h)}}finally{clearInterval(u)}r&&r(l);return}catch(l){let c=l.status,d=l.error?.type;if(!(c===429||d==="rate_limit_error"||l instanceof Error&&l.message.includes("429"))||a>=Zi.length)throw l;let m=Zi[a];E.warn("ai-engine",`Rate limited (429), attempt ${a+1}/${Zi.length} \u2014 waiting ${m}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${m}s...`),await new Promise(g=>setTimeout(g,m*1e3)),i&&i("Retrying...")}}function pc(t,e,n){let s=fe(),i=C().modules.length>0,r=qi(t,n),a=bn(),l=ac(s,e,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function gc(t,e,n,s,o,i,r,a){let l=await dc(),c=new l({apiKey:e}),{messages:d,systemBlocks:u}=pc(t,n,a);E.info("anthropic","API call",{model:s,systemBlockCount:u.length,cachedBlocks:u.filter(m=>m.cache_control).length,messageCount:d.length}),await mc(c,u,d,s,o,i,r)}async function fc(t,e,n,s,o,i,r){let a=await pi();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await dc(),c=new l({authToken:a,defaultHeaders:_n}),{messages:d,systemBlocks:u}=pc(t,e,r),m=[{type:"text",text:rn},...u];E.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await mc(c,m,d,n,s,o,i)}async function hc(t,e,n,s,o,i,r,a){let l=fe(),c=C().modules.length>0,d=qi(t,a),u=bn(),m=d.map(F=>typeof F.content=="string"?F:{role:F.role,content:F.content.map(H=>H.type==="text"?{type:"text",text:H.text}:{type:"image_url",image_url:{url:`data:${H.source.media_type};base64,${H.source.data}`}})}),g=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:ss(l,n,c,u.pageType,u.brandAssets)},...m]})});if(!g.ok){let F=await g.text();throw new Error(`OpenAI API error (${g.status}): ${F}`)}let h=0,f=i||(()=>{});f(Re[0]);let b=setInterval(()=>{h++,f(Re[Math.min(h,Re.length-1)])},6e3),S="",x=g.body.getReader(),w=new TextDecoder,P="";try{for(;;){let{done:F,value:H}=await x.read();if(F)break;P+=w.decode(H,{stream:!0});let L=P.split(`
803
- `);P=L.pop()||"";for(let V of L){if(!V.startsWith("data: "))continue;let B=V.slice(6).trim();if(B==="[DONE]")break;try{let T=JSON.parse(B).choices?.[0]?.delta?.content;T&&(S+=T,o(T))}catch{}}}}finally{clearInterval(b)}r&&r(S)}async function yc(t,e,n,s,o,i,r){let a=fe(),l=C(),c=l.modules.length>0,d=os(),u=bn(),m=[];for(let B of l.messages.slice(-20))m.push({role:B.role==="assistant"?"model":"user",parts:[{text:B.content}]});let g=d?`${t}
802
+ ${n.extractedText}`);return t.join("")}async function mc(e,t,n,s,o,i,r){for(let a=0;;a++)try{let l="",c=0,d=i||(()=>{});d(Re[0]);let u=setInterval(()=>{c++,d(Re[Math.min(c,Re.length-1)])},6e3);try{let m=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});for await(let g of m)if(g.type==="content_block_delta"&&g.delta.type==="text_delta"){let h=g.delta.text;l+=h,o(h)}}finally{clearInterval(u)}r&&r(l);return}catch(l){let c=l.status,d=l.error?.type;if(!(c===429||d==="rate_limit_error"||l instanceof Error&&l.message.includes("429"))||a>=Zi.length)throw l;let m=Zi[a];M.warn("ai-engine",`Rate limited (429), attempt ${a+1}/${Zi.length} \u2014 waiting ${m}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${m}s...`),await new Promise(g=>setTimeout(g,m*1e3)),i&&i("Retrying...")}}function pc(e,t,n){let s=fe(),i=C().modules.length>0,r=qi(e,n),a=bn(),l=ac(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function gc(e,t,n,s,o,i,r,a){let l=await dc(),c=new l({apiKey:t}),{messages:d,systemBlocks:u}=pc(e,n,a);M.info("anthropic","API call",{model:s,systemBlockCount:u.length,cachedBlocks:u.filter(m=>m.cache_control).length,messageCount:d.length}),await mc(c,u,d,s,o,i,r)}async function fc(e,t,n,s,o,i,r){let a=await pi();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await dc(),c=new l({authToken:a,defaultHeaders:_n}),{messages:d,systemBlocks:u}=pc(e,t,r),m=[{type:"text",text:rn},...u];M.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await mc(c,m,d,n,s,o,i)}async function hc(e,t,n,s,o,i,r,a){let l=fe(),c=C().modules.length>0,d=qi(e,a),u=bn(),m=d.map(F=>typeof F.content=="string"?F:{role:F.role,content:F.content.map(H=>H.type==="text"?{type:"text",text:H.text}:{type:"image_url",image_url:{url:`data:${H.source.media_type};base64,${H.source.data}`}})}),g=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:ss(l,n,c,u.pageType,u.brandAssets)},...m]})});if(!g.ok){let F=await g.text();throw new Error(`OpenAI API error (${g.status}): ${F}`)}let h=0,f=i||(()=>{});f(Re[0]);let b=setInterval(()=>{h++,f(Re[Math.min(h,Re.length-1)])},6e3),S="",x=g.body.getReader(),v=new TextDecoder,I="";try{for(;;){let{done:F,value:H}=await x.read();if(F)break;I+=v.decode(H,{stream:!0});let L=I.split(`
803
+ `);I=L.pop()||"";for(let V of L){if(!V.startsWith("data: "))continue;let B=V.slice(6).trim();if(B==="[DONE]")break;try{let T=JSON.parse(B).choices?.[0]?.delta?.content;T&&(S+=T,o(T))}catch{}}}}finally{clearInterval(b)}r&&r(S)}async function yc(e,t,n,s,o,i,r){let a=fe(),l=C(),c=l.modules.length>0,d=os(),u=bn(),m=[];for(let B of l.messages.slice(-20))m.push({role:B.role==="assistant"?"model":"user",parts:[{text:B.content}]});let g=d?`${e}
804
804
 
805
805
  ---
806
- ${d}`:t;if(r?.length)for(let B of r)B.type==="document"&&B.extractedText&&(g+=`
806
+ ${d}`:e;if(r?.length)for(let B of r)B.type==="document"&&B.extractedText&&(g+=`
807
807
 
808
808
  ---
809
809
  [Attached document: ${B.originalName}]
810
810
  ${B.extractedText}`),B.type==="image"&&B.usage==="asset"&&B.assetPath&&(g+=`
811
811
 
812
- [Uploaded image: ${B.originalName} \u2192 available as get_asset_url("${B.assetPath}")]`);let h=[];if(r?.length)for(let B of r)B.type==="image"&&B.base64&&h.push({inlineData:{mimeType:B.mimeType,data:B.base64}});h.push({text:g}),m.push({role:"user",parts:h});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${e}`,S=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:ss(a,n,c,u.pageType,u.brandAssets)}]},contents:m,generationConfig:{maxOutputTokens:48e3}})});if(!S.ok){let B=await S.text();throw new Error(`Gemini API error (${S.status}): ${B}`)}let x=0,w=o||(()=>{});w(Re[0]);let P=setInterval(()=>{x++,w(Re[Math.min(x,Re.length-1)])},6e3),F="",H=S.body.getReader(),L=new TextDecoder,V="";try{for(;;){let{done:B,value:N}=await H.read();if(B)break;V+=L.decode(N,{stream:!0});let T=V.split(`
813
- `);V=T.pop()||"";for(let I of T){if(!I.startsWith("data: "))continue;let k=I.slice(6).trim();try{let oe=JSON.parse(k).candidates?.[0]?.content?.parts?.[0]?.text;oe&&(F+=oe,s(oe))}catch{}}}}finally{clearInterval(P)}i&&i(F)}function Qi(t,e,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=cc("claude",t,{stdio:["pipe","pipe","pipe"],env:r}),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 P of w.message.content)if(P.type==="text"&&typeof P.text=="string"){let F=P.text;l+=F,n.onChunk&&n.onChunk(F)}else if(P.type==="tool_use"){let F=P;F.name&&n.onToolUse&&n.onToolUse(F.name,F.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 P;for(;(P=d.indexOf(`
814
- `))>=0;){let F=d.slice(0,P).trim();if(d=d.slice(P+1),!!F)try{h(JSON.parse(F))}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(()=>{w!==0||m&&m.is_error?i(new Error(`claude exited with code ${w}.
812
+ [Uploaded image: ${B.originalName} \u2192 available as get_asset_url("${B.assetPath}")]`);let h=[];if(r?.length)for(let B of r)B.type==="image"&&B.base64&&h.push({inlineData:{mimeType:B.mimeType,data:B.base64}});h.push({text:g}),m.push({role:"user",parts:h});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${t}`,S=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:ss(a,n,c,u.pageType,u.brandAssets)}]},contents:m,generationConfig:{maxOutputTokens:48e3}})});if(!S.ok){let B=await S.text();throw new Error(`Gemini API error (${S.status}): ${B}`)}let x=0,v=o||(()=>{});v(Re[0]);let I=setInterval(()=>{x++,v(Re[Math.min(x,Re.length-1)])},6e3),F="",H=S.body.getReader(),L=new TextDecoder,V="";try{for(;;){let{done:B,value:N}=await H.read();if(B)break;V+=L.decode(N,{stream:!0});let T=V.split(`
813
+ `);V=T.pop()||"";for(let P of T){if(!P.startsWith("data: "))continue;let k=P.slice(6).trim();try{let oe=JSON.parse(k).candidates?.[0]?.content?.parts?.[0]?.text;oe&&(F+=oe,s(oe))}catch{}}}}finally{clearInterval(I)}i&&i(F)}function Qi(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=cc("claude",e,{stdio:["pipe","pipe","pipe"],env:r}),l="",c="",d="",u=!1,m=null,g=v=>{u||(u=!0,v())},h=v=>{try{if(v.type==="assistant"&&v.message?.content){for(let I of v.message.content)if(I.type==="text"&&typeof I.text=="string"){let F=I.text;l+=F,n.onChunk&&n.onChunk(F)}else if(I.type==="tool_use"){let F=I;F.name&&n.onToolUse&&n.onToolUse(F.name,F.input)}}v.type==="result"&&(m=v,!l&&typeof v.result=="string"&&(l=v.result,n.onChunk&&n.onChunk(v.result))),n.onEvent&&n.onEvent(v)}catch{}};a.stdout.on("data",v=>{d+=v.toString();let I;for(;(I=d.indexOf(`
814
+ `))>=0;){let F=d.slice(0,I).trim();if(d=d.slice(I+1),!!F)try{h(JSON.parse(F))}catch{}}}),a.stderr.on("data",v=>{c+=v.toString()}),a.on("error",v=>g(()=>i(new Error(`claude failed to start: ${v.message}`)))),a.on("close",v=>{if(d.trim()){try{h(JSON.parse(d.trim()))}catch{}d=""}g(()=>{v!==0||m&&m.is_error?i(new Error(`claude exited with code ${v}.
815
815
  `+(c?`Stderr: ${c.slice(0,500)}
816
- `:"")+(l?`Output: ${l.slice(0,500)}`:"No output"))):o(l)})}),a.stdin.on("error",()=>{}),a.stdin.write(e)?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.
816
+ `:"")+(l?`Output: ${l.slice(0,500)}`:"No output"))):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.
817
817
  `+(c?`Stderr: ${c.slice(0,500)}
818
- `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(x))})}function er(t,e,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=cc(t,e,{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(`${t} failed to start: ${S.message}`)))),l.on("close",S=>{m(()=>{S!==0?r(new Error(`${t} exited with code ${S}.
818
+ `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(x))})}function er(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=cc(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}.
819
819
  `+(d?`Stderr: ${d.slice(0,500)}
820
- `:"")+(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(`${t} timed out after ${f} minutes.
820
+ `:"")+(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.
821
821
  `+(d?`Stderr: ${d.slice(0,500)}
822
- `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function bc(t,e,n,s,o,i){let r=fe(),a=O(),l=C().modules.length>0,c=bn(),d=ss(r,e,l,c.pageType,c.brandAssets);d+=`
822
+ `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function bc(e,t,n,s,o,i){let r=fe(),a=O(),l=C().modules.length>0,c=bn(),d=ss(r,t,l,c.pageType,c.brandAssets);d+=`
823
823
 
824
824
  ## User Request
825
- `+t,d+=os(),d+=uc(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print"];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(Re[0]);let h=setInterval(()=>{m++;let f=Re[Math.min(m,Re.length-1)];g(f)},6e3);try{let f=await Qi(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(If(b,S))}});o&&o(f)}finally{clearInterval(h)}}function If(t,e){let n=e||{};switch(t){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 ${t}`}}async function tr(t,e,n,s,o,i,r){let a=fe(),l=C().modules.length>0,c=bn(),d=ss(a,n,l,c.pageType,c.brandAssets);d+=`
825
+ `+e,d+=os(),d+=uc(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print"];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(Re[0]);let h=setInterval(()=>{m++;let f=Re[Math.min(m,Re.length-1)];g(f)},6e3);try{let f=await Qi(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(Pf(b,S))}});o&&o(f)}finally{clearInterval(h)}}function Pf(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 tr(e,t,n,s,o,i,r){let a=fe(),l=C().modules.length>0,c=bn(),d=ss(a,n,l,c.pageType,c.brandAssets);d+=`
826
826
 
827
827
  ## User Request
828
- `+e,d+=os(),d+=uc(r),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;t==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,h=o||(()=>{});h(Re[0]);let f=setInterval(()=>{g++;let b=Re[Math.min(g,Re.length-1)];h(b)},6e3);try{let b=await er(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Xi,Re,Zi,nr=R(()=>{"use strict";y();Ue();Q();xt();we();lc();de();Xi=null;Re=["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..."],Zi=[10,20,40,60,120]});function p(t,e,n){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(n))}function W(t,e){let n=[];t.on("data",s=>n.push(s)),t.on("end",()=>e(Buffer.concat(n).toString("utf-8")))}function Ve(t,e,n){W(t,s=>{try{n(JSON.parse(s||"{}"))}catch{p(e,400,{error:"Invalid JSON in request body"})}})}var ze=R(()=>{"use strict";y()});import{createWriteStream as Pf,mkdirSync as Sc,existsSync as sr,readFileSync as or}from"fs";import{join as Vt,extname as Rf}from"path";import{randomUUID as Nf}from"crypto";import Of from"busboy";function Lf(t,e){if(vc.has(e))return e;let n=t.slice(t.lastIndexOf(".")).toLowerCase();return Df[n]??e}function Jf(t){return t.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Bf(t,e){if(!sr(Vt(t,e)))return e;let n=Rf(e),s=e.slice(0,-n.length||void 0),o=1;for(;sr(Vt(t,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function Hf(t){let e=(await import("pdf-parse")).default,n=or(t);return(await e(n)).text}async function Uf(t){return(await(await import("mammoth")).extractRawText({path:t})).value}function Gf(t){return or(t,"utf-8")}function wc(t,e){let n=C();if(!n){p(e,400,{error:"No active session"});return}if(!(t.headers["content-type"]||"").includes("multipart/form-data")){p(e,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],r=0,a=[],l=Of({headers:t.headers,limits:{fileSize:Ff,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=Lf(m,g);if(!vc.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=xc.has(h),b=Jf(m),S=Nf(),x,w;f?(x=Vt(n.themePath,"assets"),Sc(x,{recursive:!0}),w=Bf(x,b)):(x=Vt(n.themePath,".vibespot","uploads"),Sc(x,{recursive:!0}),w=`${S}-${b}`);let P=Vt(x,w),F=Pf(P),H=0,L=!1;d.on("data",V=>{H+=V.length}),d.on("limit",()=>{L=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(F),a.push(new Promise(V=>{F.on("finish",()=>{if(!L){let B={id:S,filename:w,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:H,addedAt:new Date().toISOString()};o.push(B),vl(B)}V()}),F.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=Vt(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await Hf(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await Uf(d):c.extractedText=Gf(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(e,400,{error:"No files uploaded"});return}p(e,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(e,500,{error:"Upload failed"})}),t.pipe(l)}function Co(t){let e=C();return e?.assets?t.map(n=>{let s=e.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=Vt(e.themePath,"assets",s.filename);sr(i)&&(o.base64=or(i).toString("base64")),o.assetPath=`${e.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var Ff,xc,jf,vc,Df,ir=R(()=>{"use strict";y();ze();we();de();Ff=10*1024*1024,xc=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),jf=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),vc=new Set([...xc,...jf]),Df={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var Ac={};Be(Ac,{callAgent:()=>_e,callAgentAPI:()=>Tc,isAgenticCapable:()=>rs,isCLIEngine:()=>xn,resolveThinkingBudget:()=>Sn});async function ko(t,e){for(let n=0;;n++)try{return await t()}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>=rr.length)throw s;let a=rr[n];E.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${rr.length} \u2014 waiting ${a}s`),e&&e(`Rate limited \u2014 retrying in ${a}s...`),await new Promise(l=>setTimeout(l,a*1e3)),e&&e("Retrying...")}}function is(t){if(t&&typeof t=="object"&&!Array.isArray(t)){let e=t;for(let n of["fieldsJson","metaJson"])e[n]&&typeof e[n]=="object"&&(e[n]=JSON.stringify(e[n]))}return t}async function Cc(){return ar||(ar=(await import("@anthropic-ai/sdk")).default),ar}async function Wf(t,e,n,s,o){let i=await Cc(),r=new i({apiKey:t,...s?{defaultHeaders:s}:{}}),a=n.messages,l=n.systemPrompt;if(n.systemBlocks?l=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(l=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let c={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 ko(async()=>{let d=await r.messages.create({model:e,max_tokens:n.maxTokens||16e3,system:l,messages:a,tools:[c],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for(let m of d.content)if(m.type==="tool_use")return{type:"structured",data:is(m.input)};return{type:"text",text:d.content.filter(m=>m.type==="text").map(m=>m.text).join("")}},n.onStatus)}return ko(async()=>{let c="",d=r.messages.stream({model:e,max_tokens:n.maxTokens||16e3,system:l,messages:a,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let u of d)u.type==="content_block_delta"&&u.delta.type==="text_delta"&&(c+=u.delta.text,n.onChunk&&n.onChunk(u.delta.text));return{type:"text",text:c}},n.onStatus)}async function Kf(t,e,n){let s=await Cc(),o=new s({authToken:t,defaultHeaders:_n}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:rn},...n.systemBlocks]:r=[{type:"text",text:rn},{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 ko(async()=>{let l=await o.messages.create({model:e,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}}:{}});for(let d of l.content)if(d.type==="tool_use")return{type:"structured",data:is(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return ko(async()=>{let a="",l=o.messages.stream({model:e,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 c of l)c.type==="content_block_delta"&&c.delta.type==="text_delta"&&(a+=c.delta.text,n.onChunk&&n.onChunk(c.delta.text));return{type:"text",text:a}},n.onStatus)}function lr(t){let e={...t};if(e.type==="object"&&(e.additionalProperties=!1,e.properties&&typeof e.properties=="object")){let n={};for(let[s,o]of Object.entries(e.properties))n[s]=o&&typeof o=="object"?lr(o):o;e.properties=n}return e.items&&typeof e.items=="object"&&(e.items=lr(e.items)),e}async function Vf(t,e,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:e,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:lr(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let a=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:is(JSON.parse(a))}}catch{return E.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:a}}return{type:"text",text:a}}async function zf(t,e,n){let s=e||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},r=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${t}`,a=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!a.ok){let d=await a.text(),u=a.status;if(u===429){let m=new Error(`Gemini rate limit: ${d}`);throw m.status=429,m}throw new Error(`Gemini API error (${u}): ${d}`)}let c=(await a.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:is(JSON.parse(c))}}catch{return E.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function Yf(t,e,n){switch(t){case"claude-code":{let s=["--print"];return e&&s.push("--model",e),n?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":{let s=[];return e&&s.push("-m",e),{bin:"gemini",args:s}}case"codex-cli":{let s=["exec","--full-auto"];return e&&s.push("-m",e),{bin:"codex",args:s}}default:throw new Error(`Not a CLI engine: ${t}`)}}function qf(t){let e=[t.systemPrompt];for(let n of t.messages){let s=n.role==="user"?"User":"Assistant",o=typeof n.content=="string"?n.content:n.content.map(i=>i.text).join(`
829
- `);e.push(`
828
+ `+t,d+=os(),d+=uc(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(Re[0]);let f=setInterval(()=>{g++;let b=Re[Math.min(g,Re.length-1)];h(b)},6e3);try{let b=await er(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Xi,Re,Zi,nr=R(()=>{"use strict";y();Ge();Q();xt();we();lc();de();Xi=null;Re=["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..."],Zi=[10,20,40,60,120]});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 Ve(e,t,n){W(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var ze=R(()=>{"use strict";y()});import{createWriteStream as Rf,mkdirSync as Sc,existsSync as sr,readFileSync as or}from"fs";import{join as Vt,extname as Nf}from"path";import{randomUUID as Of}from"crypto";import Ff from"busboy";function Jf(e,t){if(vc.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return Lf[n]??t}function Bf(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Hf(e,t){if(!sr(Vt(e,t)))return t;let n=Nf(t),s=t.slice(0,-n.length||void 0),o=1;for(;sr(Vt(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function Gf(e){let t=(await import("pdf-parse")).default,n=or(e);return(await t(n)).text}async function Uf(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function Wf(e){return or(e,"utf-8")}function wc(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=Ff({headers:e.headers,limits:{fileSize:jf,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=Jf(m,g);if(!vc.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=xc.has(h),b=Bf(m),S=Of(),x,v;f?(x=Vt(n.themePath,"assets"),Sc(x,{recursive:!0}),v=Hf(x,b)):(x=Vt(n.themePath,".vibespot","uploads"),Sc(x,{recursive:!0}),v=`${S}-${b}`);let I=Vt(x,v),F=Rf(I),H=0,L=!1;d.on("data",V=>{H+=V.length}),d.on("limit",()=>{L=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(F),a.push(new Promise(V=>{F.on("finish",()=>{if(!L){let B={id:S,filename:v,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:H,addedAt:new Date().toISOString()};o.push(B),vl(B)}V()}),F.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=Vt(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await Gf(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await Uf(d):c.extractedText=Wf(d),M.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){M.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=>{M.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Co(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=Vt(t.themePath,"assets",s.filename);sr(i)&&(o.base64=or(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 jf,xc,Df,vc,Lf,ir=R(()=>{"use strict";y();ze();we();de();jf=10*1024*1024,xc=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Df=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),vc=new Set([...xc,...Df]),Lf={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var $c={};Be($c,{callAgent:()=>_e,callAgentAPI:()=>Ac,isAgenticCapable:()=>rs,isCLIEngine:()=>xn,resolveThinkingBudget:()=>Sn});async function ko(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>=rr.length)throw s;let a=rr[n];M.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${rr.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 is(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 kc(){return ar||(ar=(await import("@anthropic-ai/sdk")).default),ar}async function Cc(e,t,n,s,o,i){let r=await kc(),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 ko(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}}:{}});for(let g of u.content)if(g.type==="tool_use")return{type:"structured",data:is(g.input)};return{type:"text",text:u.content.filter(g=>g.type==="text").map(g=>g.text).join("")}},n.onStatus)}return ko(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 m of u)m.type==="content_block_delta"&&m.delta.type==="text_delta"&&(d+=m.delta.text,n.onChunk&&n.onChunk(m.delta.text));return{type:"text",text:d}},n.onStatus)}async function Vf(e,t,n){let s=await kc(),o=new s({authToken:e,defaultHeaders:_n}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:rn},...n.systemBlocks]:r=[{type:"text",text:rn},{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 ko(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}}:{}});for(let d of l.content)if(d.type==="tool_use")return{type:"structured",data:is(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return ko(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 c of l)c.type==="content_block_delta"&&c.delta.type==="text_delta"&&(a+=c.delta.text,n.onChunk&&n.onChunk(c.delta.text));return{type:"text",text:a}},n.onStatus)}function lr(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"?lr(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=lr(t.items)),t}async function zf(e,t,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:t,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:lr(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let a=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:is(JSON.parse(a))}}catch{return M.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:a}}return{type:"text",text:a}}async function Yf(e,t,n){let s=t||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},r=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${e}`,a=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!a.ok){let d=await a.text(),u=a.status;if(u===429){let m=new Error(`Gemini rate limit: ${d}`);throw m.status=429,m}throw new Error(`Gemini API error (${u}): ${d}`)}let c=(await a.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:is(JSON.parse(c))}}catch{return M.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function qf(e,t,n){switch(e){case"claude-code":{let s=["--print"];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 Xf(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(`
829
+ `);t.push(`
830
830
 
831
831
  ## ${s}
832
- ${o}`)}if(t.structuredOutput){let n=kc(t.structuredOutput.schema);e.push(`
832
+ ${o}`)}if(e.structuredOutput){let n=Tc(e.structuredOutput.schema);t.push(`
833
833
 
834
834
  ## Output Format \u2014 CRITICAL
835
835
  Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
836
836
 
837
837
  The JSON must match this structure:
838
- ${n}`)}return e.join("")}function kc(t,e=0){let n=" ".repeat(e),s=t.properties,o=t.required||[];if(!s)return`${n}${JSON.stringify(t)}`;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}": ${kc(a,e+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
839
- `)}function Xf(t){let e=t.trim(),n=ft(e);if(n&&typeof n=="object")return n;let s=e.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let a=s[1].trim(),l=ft(a);if(l&&typeof l=="object")return l;let c=ns(a);if(c&&typeof c=="object")return c}let o=e.indexOf("{"),i=e.lastIndexOf("}");if(o!==-1&&i>o){let a=e.slice(o,i+1),l=ft(a);if(l&&typeof l=="object")return l;let c=ns(a);if(c&&typeof c=="object")return c}let r=ns(e);return r&&typeof r=="object"?r:null}async function Zf(t,e,n){let{bin:s,args:o}=Yf(t,e,n),i=qf(n),r;if(t==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Qi(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=Qf(c,d);n.onStatus(u)}})}else r=await er(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=Xf(r);return a?{type:"structured",data:is(a)}:(E.warn("agent-cli",`${t}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function Qf(t,e){let n=e||{};switch(t){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 ${t}`}}async function Tc(t,e,n,s){switch(E.info("agent-adapter",`${t} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),t){case"anthropic-api":return Wf(e,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(xt(),gi)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return Kf(i,n,s)}case"openai-api":return Vf(e,n,s);case"gemini-api":return zf(e,n,s);default:throw new Error(`Unsupported API engine: ${t}`)}}async function _e(t,e,n,s){return eh.has(t)?Tc(t,e,n,s):(E.info("agent-adapter",`${t} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),Zf(t,n,s))}function Sn(t){if(t!=="anthropic-api"&&t!=="claude-oauth")return 0;let e=O();if(!e.extendedThinking)return 0;switch(e.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function rs(t){return t==="anthropic-api"||t==="claude-oauth"||t==="openai-api"||t==="gemini-api"||t==="claude-code"||t==="gemini-cli"||t==="codex-cli"}function xn(t){return t==="claude-code"||t==="gemini-cli"||t==="codex-cli"}var rr,ar,eh,nt=R(()=>{"use strict";y();nr();wo();Q();xt();de();rr=[10,20,40,60,120];ar=null;eh=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api"])});function $c(t,e,n,s,o){let i=e.length>0?`Current template modules (in page order):
840
- ${e.map((c,d)=>`${d+1}. ${c}`).join(`
838
+ ${n}`)}return t.join("")}function Tc(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}": ${Tc(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
839
+ `)}function Zf(e){let t=e.trim(),n=ft(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=ft(a);if(l&&typeof l=="object")return l;let c=ns(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=ft(a);if(l&&typeof l=="object")return l;let c=ns(a);if(c&&typeof c=="object")return c}let r=ns(t);return r&&typeof r=="object"?r:null}async function Qf(e,t,n){let{bin:s,args:o}=qf(e,t,n),i=Xf(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Qi(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=eh(c,d);n.onStatus(u)}})}else r=await er(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=Zf(r);return a?{type:"structured",data:is(a)}:(M.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function eh(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 Ac(e,t,n,s){switch(M.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),e){case"anthropic-api":return Cc(t,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(xt(),gi)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return Vf(i,n,s)}case"openai-api":return zf(t,n,s);case"gemini-api":return Yf(t,n,s);case"langdock-api":{let i=O().langdockBaseUrl||Kf;return Cc(t,n,s,void 0,void 0,i)}default:throw new Error(`Unsupported API engine: ${e}`)}}async function _e(e,t,n,s){return th.has(e)?Ac(e,t,n,s):(M.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),Qf(e,n,s))}function Sn(e){if(e!=="anthropic-api"&&e!=="claude-oauth"&&e!=="langdock-api")return 0;let t=O();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function rs(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 xn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Kf,rr,ar,th,nt=R(()=>{"use strict";y();nr();wo();Q();xt();de();Kf="https://api.langdock.com/anthropic",rr=[10,20,40,60,120];ar=null;th=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});function _c(e,t,n,s,o){let i=t.length>0?`Current template modules (in page order):
840
+ ${t.map((c,d)=>`${d+1}. ${c}`).join(`
841
841
  `)}`:"No modules yet (new page).",r=n.length>0?`
842
842
 
843
843
  Module library (reusable from other templates):
@@ -857,7 +857,7 @@ The user's message applies to the current page unless they reference another pag
857
857
 
858
858
  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.
859
859
 
860
- ## Theme: "${t}"
860
+ ## Theme: "${e}"
861
861
 
862
862
  ${i}${r}${a}${l}
863
863
 
@@ -929,11 +929,11 @@ If the user asks for multiple things (e.g., "make hero taller AND add testimonia
929
929
 
930
930
  ## Content Type Detection
931
931
 
932
- Set \`contentType\` to "email" when the user explicitly asks for an email template, newsletter, email campaign, welcome email, promotional email, or similar email content. Leave as "page" (default) for landing pages, websites, and web content.`}var _c,Mc=R(()=>{"use strict";y();_c={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 Ec(t,e,n,s,o,i,r){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let a=e.modules.map(g=>g.moduleName),l=$c(e.themeName,a,r,e.brandAssets?.themeContext,e.sitePages?{activePageLabel:e.activePageLabel,pages:e.sitePages}:void 0),c=[],d=e.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:t});let u=await _e(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:_c,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){E.warn("intent-analyzer","Did not get structured output, falling back");let g=e.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||[],e.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:th(m)}),m}function th(t){let e=[`Intent: ${t.intent}`];return t.affectedModules.length>0&&e.push(`Modifying: ${t.affectedModules.join(", ")}`),t.unchangedModules.length>0&&e.push(`Unchanged: ${t.unchangedModules.join(", ")}`),t.newModules.length>0&&e.push(`New: ${t.newModules.map(n=>n.name).join(", ")}`),t.reuseModules?.length&&e.push(`Reuse: ${t.reuseModules.map(n=>`${n.name} from ${n.sourceTemplate}`).join(", ")}`),t.designSystemChanges&&e.push("Design system changes: yes"),e.join(" | ")}var Ic=R(()=>{"use strict";y();nt();Mc();de()});function To(t,e){let n=[];n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
932
+ Set \`contentType\` to "email" when the user explicitly asks for an email template, newsletter, email campaign, welcome email, promotional email, or similar email content. Leave as "page" (default) for landing pages, websites, and web content.`}var Ec,Mc=R(()=>{"use strict";y();Ec={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 Ic(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=_c(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 _e(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Ec,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){M.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",M.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:nh(m)}),m}function nh(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 Pc=R(()=>{"use strict";y();nt();Mc();de()});function To(e,t){let n=[];n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
933
933
 
934
934
  Your job: create a complete, production-ready CSS design system for a landing page theme. You produce the :root custom properties, shared utility/component CSS, and optional shared JS (scroll animations). Downstream agents will use YOUR CSS classes and variables to build individual modules.
935
935
 
936
- ## Theme: "${t}"
936
+ ## Theme: "${e}"
937
937
 
938
938
  ## Output Requirements
939
939
 
@@ -941,36 +941,36 @@ Your job: create a complete, production-ready CSS design system for a landing pa
941
941
  A flat object mapping CSS custom property names to values. Every variable your CSS references MUST be defined here. Include ALL of these categories:
942
942
 
943
943
  **Colors** (at minimum):
944
- - --${t}-color-bg: page background
945
- - --${t}-color-surface: card/section background
946
- - --${t}-color-dark: dark section background
947
- - --${t}-color-dark-surface: card bg inside dark sections
948
- - --${t}-color-text: primary text color
949
- - --${t}-color-text-inverse: text on dark backgrounds
950
- - --${t}-color-text-muted: secondary/muted text
951
- - --${t}-color-primary: primary brand color
952
- - --${t}-color-primary-dark: darker variant for hover states
953
- - --${t}-color-accent: accent/highlight color
954
- - --${t}-color-accent-light: light tint for pill/badge backgrounds
955
- - --${t}-color-border: default border color
956
- - --${t}-color-border-hover: border on hover
944
+ - --${e}-color-bg: page background
945
+ - --${e}-color-surface: card/section background
946
+ - --${e}-color-dark: dark section background
947
+ - --${e}-color-dark-surface: card bg inside dark sections
948
+ - --${e}-color-text: primary text color
949
+ - --${e}-color-text-inverse: text on dark backgrounds
950
+ - --${e}-color-text-muted: secondary/muted text
951
+ - --${e}-color-primary: primary brand color
952
+ - --${e}-color-primary-dark: darker variant for hover states
953
+ - --${e}-color-accent: accent/highlight color
954
+ - --${e}-color-accent-light: light tint for pill/badge backgrounds
955
+ - --${e}-color-border: default border color
956
+ - --${e}-color-border-hover: border on hover
957
957
 
958
958
  **Typography**:
959
- - --${t}-font-display: display/heading font stack (system fonts only)
960
- - --${t}-font-body: body text font stack (system fonts only)
961
- - --${t}-size-h1 through --${t}-size-h3: heading sizes using clamp()
962
- - --${t}-size-body, --${t}-size-lg, --${t}-size-small, --${t}-size-label
963
- - --${t}-leading-tight, --${t}-leading-snug, --${t}-leading-body: line heights
964
- - --${t}-tracking-tight, --${t}-tracking-wide: letter spacing
959
+ - --${e}-font-display: display/heading font stack (system fonts only)
960
+ - --${e}-font-body: body text font stack (system fonts only)
961
+ - --${e}-size-h1 through --${e}-size-h3: heading sizes using clamp()
962
+ - --${e}-size-body, --${e}-size-lg, --${e}-size-small, --${e}-size-label
963
+ - --${e}-leading-tight, --${e}-leading-snug, --${e}-leading-body: line heights
964
+ - --${e}-tracking-tight, --${e}-tracking-wide: letter spacing
965
965
 
966
966
  **Spacing**:
967
- - --${t}-space-xs through --${t}-space-xl, --${t}-space-section
968
- - --${t}-max-width: content max-width (1152-1280px)
967
+ - --${e}-space-xs through --${e}-space-xl, --${e}-space-section
968
+ - --${e}-max-width: content max-width (1152-1280px)
969
969
 
970
970
  **Effects**:
971
- - --${t}-radius-sm, --${t}-radius-md, --${t}-radius-lg, --${t}-radius-full
972
- - --${t}-shadow-card-hover, --${t}-shadow-button
973
- - --${t}-transition-fast, --${t}-transition-base, --${t}-transition-slow
971
+ - --${e}-radius-sm, --${e}-radius-md, --${e}-radius-lg, --${e}-radius-full
972
+ - --${e}-shadow-card-hover, --${e}-shadow-button
973
+ - --${e}-transition-fast, --${e}-transition-base, --${e}-transition-slow
974
974
 
975
975
  ### sharedCss
976
976
  Complete CSS file content. MUST include:
@@ -978,15 +978,15 @@ Complete CSS file content. MUST include:
978
978
  2. Reset (box-sizing, margin, padding)
979
979
  3. Body styles referencing your variables
980
980
  4. Typography rules (h1-h6, p)
981
- 5. Layout utilities (.${t}-container, .${t}-section, .${t}-section--dark)
982
- 6. Grid system (.${t}-grid, .${t}-grid--2/3/4 with responsive breakpoints)
983
- 7. Card component (.${t}-card with hover lift)
984
- 8. Button component (.${t}-btn, .${t}-btn--primary, .${t}-btn--secondary)
981
+ 5. Layout utilities (.${e}-container, .${e}-section, .${e}-section--dark)
982
+ 6. Grid system (.${e}-grid, .${e}-grid--2/3/4 with responsive breakpoints)
983
+ 7. Card component (.${e}-card with hover lift)
984
+ 8. Button component (.${e}-btn, .${e}-btn--primary, .${e}-btn--secondary)
985
985
  CRITICAL: Re-declare color, text-decoration:none, and font-family on :hover/:focus \u2014 HubSpot overrides link hover styles
986
- 9. Pill/badge (.${t}-pill)
986
+ 9. Pill/badge (.${e}-pill)
987
987
  10. Decorative elements (at least one background treatment: grid pattern, noise, gradient orb)
988
988
  11. Scroll animation CSS ([data-animate], [data-animate-stagger]) with 3s CSS-only fallback
989
- 12. Section label (.${t}-label) \u2014 uppercase, letter-spacing, accent color
989
+ 12. Section label (.${e}-label) \u2014 uppercase, letter-spacing, accent color
990
990
  13. Stat number styling
991
991
  14. Responsive mobile styles (@media max-width: 767px)
992
992
 
@@ -994,8 +994,8 @@ Complete CSS file content. MUST include:
994
994
  IntersectionObserver-based scroll animation JS. Wrap in IIFE.
995
995
 
996
996
  ## CSS Rules \u2014 CRITICAL
997
- - All classes MUST use prefix "${t}-"
998
- - Use BEM naming: ${t}-module__element--modifier
997
+ - All classes MUST use prefix "${e}-"
998
+ - Use BEM naming: ${e}-module__element--modifier
999
999
  - Use system font stacks ONLY (no Google Fonts @import, no external CDN)
1000
1000
  - Every var() reference in CSS must have a matching declaration in :root
1001
1001
  - No Tailwind, no Sass, no PostCSS
@@ -1019,44 +1019,44 @@ Use system font stacks that approximate the desired aesthetic. Pick TWO stacks:
1019
1019
  | Contrast pair | Georgia, serif (display) | system-ui, sans-serif (body) | When you want serif/sans tension |`),n.push(`
1020
1020
 
1021
1021
  ## Design Guide
1022
- ${Fc()}`),e?.styleguide&&n.push(`
1022
+ ${jc()}`),t?.styleguide&&n.push(`
1023
1023
 
1024
1024
  ## Brand Style Guide
1025
- ${e.styleguide}`),e?.themeContext&&n.push(`
1025
+ ${t.styleguide}`),t?.themeContext&&n.push(`
1026
1026
 
1027
1027
  ## Product Context
1028
- ${e.themeContext}`);let s=e?.brandKit&&(e.brandKit.colors?.primary||e.brandKit.colors?.secondary||e.brandKit.colors?.accent||e.brandKit.fonts?.heading||e.brandKit.fonts?.body);if(s){let o=[],i=e.brandKit;i.colors?.primary&&o.push(`- Primary color: ${i.colors.primary}`),i.colors?.secondary&&o.push(`- Secondary color: ${i.colors.secondary}`),i.colors?.accent&&o.push(`- Accent color: ${i.colors.accent}`),i.fonts?.heading&&o.push(`- Heading font: ${i.fonts.heading}`),i.fonts?.body&&o.push(`- Body font: ${i.fonts.body}`),i.logoUrl&&o.push(`- Logo URL: ${i.logoUrl}`),o.length>0&&n.push(`
1028
+ ${t.themeContext}`);let s=t?.brandKit&&(t.brandKit.colors?.primary||t.brandKit.colors?.secondary||t.brandKit.colors?.accent||t.brandKit.fonts?.heading||t.brandKit.fonts?.body);if(s){let o=[],i=t.brandKit;i.colors?.primary&&o.push(`- Primary color: ${i.colors.primary}`),i.colors?.secondary&&o.push(`- Secondary color: ${i.colors.secondary}`),i.colors?.accent&&o.push(`- Accent color: ${i.colors.accent}`),i.fonts?.heading&&o.push(`- Heading font: ${i.fonts.heading}`),i.fonts?.body&&o.push(`- Body font: ${i.fonts.body}`),i.logoUrl&&o.push(`- Logo URL: ${i.logoUrl}`),o.length>0&&n.push(`
1029
1029
 
1030
1030
  ## Brand Kit \u2014 MANDATORY Design Constraints
1031
1031
  The following brand identity values MUST be used. Do NOT substitute or override them:
1032
1032
  ${o.join(`
1033
- `)}`)}return!s&&!e?.styleguide&&n.push(`
1033
+ `)}`)}return!s&&!t?.styleguide&&n.push(`
1034
1034
 
1035
1035
  ## No Brand Provided \u2014 Follow the Generation Recipe
1036
1036
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1037
1037
 
1038
- ${Oc()}`),n.join("")}function cr(t,e){let n=To(t),o=n.indexOf(`
1038
+ ${Fc()}`),n.join("")}function cr(e,t){let n=To(e),o=n.indexOf(`
1039
1039
 
1040
1040
  ## Design Guide
1041
1041
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Design Guide
1042
- ${Fc()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];e?.styleguide&&l.push(`## Brand Style Guide
1043
- ${e.styleguide}`),e?.themeContext&&l.push(`## Product Context
1044
- ${e.themeContext}`);let c=e?.brandKit&&(e.brandKit.colors?.primary||e.brandKit.colors?.secondary||e.brandKit.colors?.accent||e.brandKit.fonts?.heading||e.brandKit.fonts?.body);if(c){let d=[],u=e.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
1042
+ ${jc()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1043
+ ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1044
+ ${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
1045
1045
  The following brand identity values MUST be used. Do NOT substitute or override them:
1046
1046
  ${d.join(`
1047
- `)}`)}return!c&&!e?.styleguide&&l.push(`## No Brand Provided \u2014 Follow the Generation Recipe
1047
+ `)}`)}return!c&&!t?.styleguide&&l.push(`## No Brand Provided \u2014 Follow the Generation Recipe
1048
1048
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1049
1049
 
1050
- ${Oc()}`),l.length>0&&a.push({type:"text",text:l.join(`
1050
+ ${Fc()}`),l.length>0&&a.push({type:"text",text:l.join(`
1051
1051
 
1052
- `)}),a}function nh(t){let e=[...new Set([...t.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...t.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...t.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),e.length>0&&o.push(`CSS Classes: ${e.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
1053
- `)}function Rc(t,e,n,s){let o=[],i=nh(e);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
1052
+ `)}),a}function sh(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(`
1053
+ `)}function Nc(e,t,n,s){let o=[],i=sh(t);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
1054
1054
 
1055
1055
  Your job: plan the modules for a landing page. You define what each module contains (content brief) and how it should be laid out. You do NOT write module code \u2014 downstream Module Developers handle that.
1056
1056
 
1057
1057
  The Design System has already been created. Your module plans MUST reference the existing CSS classes and variables.
1058
1058
 
1059
- ## Theme: "${t}"
1059
+ ## Theme: "${e}"
1060
1060
 
1061
1061
  ## Available CSS Classes & Variables
1062
1062
  Reference these in your layoutNotes:
@@ -1073,7 +1073,7 @@ ${i}
1073
1073
  ### Content & layout
1074
1074
  - Content briefs: describe the actual copy/content each module needs (headlines, body text, CTAs, stats)
1075
1075
  - Layout notes: describe the visual layout using the available CSS classes above
1076
- - Reference specific CSS classes from the shared CSS in your layout notes (e.g., "Use ${t}-grid--3 for card layout, ${t}-section--dark for background")
1076
+ - Reference specific CSS classes from the shared CSS in your layout notes (e.g., "Use ${e}-grid--3 for card layout, ${e}-section--dark for background")
1077
1077
 
1078
1078
  ### Module order
1079
1079
  - \`moduleOrder\`: list **all** modules' names in the order they should appear on the page, including:
@@ -1081,7 +1081,7 @@ ${i}
1081
1081
  - any "Existing Modules to Keep" the user listed (these are not in \`modules\`, but still belong in \`moduleOrder\`)`),(!s||s.includes("content"))&&o.push(`
1082
1082
 
1083
1083
  ## Content & Copywriting Guide
1084
- ${sh()}`),n?.brandvoice&&o.push(`
1084
+ ${oh()}`),n?.brandvoice&&o.push(`
1085
1085
 
1086
1086
  ## Brand Voice
1087
1087
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1090,7 +1090,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1090
1090
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1091
1091
 
1092
1092
  ## Anti-AI Copy Rules
1093
- ${oh()}`),o.join("")}function Oc(){let t=Un(),e=Pc(t,"## 4. Color System","## 5."),n=Pc(t,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1093
+ ${ih()}`),o.join("")}function Fc(){let e=Gn(),t=Rc(e,"## 4. Color System","## 5."),n=Rc(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1094
1094
  Read the user's request carefully. What industry? What audience? What mood?
1095
1095
  Map it to ONE of these aesthetic directions \u2014 then commit fully:
1096
1096
 
@@ -1136,8 +1136,8 @@ ${n}
1136
1136
  - Bold display (Archivo Black, Bebas Neue, Syne) \u2192 Impact, "Arial Black", sans-serif
1137
1137
  - Classic serif (Book Antiqua) \u2192 "Book Antiqua", Palatino, "Palatino Linotype", serif
1138
1138
 
1139
- Choose the pairing that matches the MOOD of the content, not the same one every time.`),e&&s.push(`### Reference: Design Guide Color Philosophy
1140
- ${e}`),s.push(`### Step 4: Verify uniqueness
1139
+ Choose the pairing that matches the MOOD of the content, not the same one every time.`),t&&s.push(`### Reference: Design Guide Color Philosophy
1140
+ ${t}`),s.push(`### Step 4: Verify uniqueness
1141
1141
  Before finalizing, ask yourself:
1142
1142
  - Would this palette look DIFFERENT from a page I just designed for a different topic?
1143
1143
  - Is the primary color something other than blue, brown, or purple?
@@ -1146,7 +1146,7 @@ Before finalizing, ask yourself:
1146
1146
 
1147
1147
  If any answer is "no," go bolder. The user wants personality, not safety.`),s.join(`
1148
1148
 
1149
- `)}function Pc(t,e,n){let s=t.indexOf(e);if(s===-1)return"";let o=t.indexOf(n,s);return o===-1?t.slice(s):t.slice(s,o).trim()}function Fc(){return`### Design Philosophy
1149
+ `)}function Rc(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 jc(){return`### Design Philosophy
1150
1150
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
1151
1151
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
1152
1152
 
@@ -1253,7 +1253,7 @@ Include these in shared CSS:
1253
1253
  | All animations same speed | Stagger with increasing delays |
1254
1254
  | Skip hover/focus states | Every interactive element needs feedback |
1255
1255
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
1256
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function sh(){return`### Mandatory Page Sections (generate all)
1256
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function oh(){return`### Mandatory Page Sections (generate all)
1257
1257
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
1258
1258
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
1259
1259
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -1341,7 +1341,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
1341
1341
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
1342
1342
  - Keep paragraphs to 2-3 sentences max
1343
1343
  - Aim for 6th-grade reading level
1344
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function oh(){return`### Banned Punctuation
1344
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function ih(){return`### Banned Punctuation
1345
1345
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
1346
1346
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
1347
1347
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -1371,18 +1371,18 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
1371
1371
  - Use plain short words: use > utilize, start > commence, help > facilitate
1372
1372
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
1373
1373
  - Front-load the benefit in the first 5 words
1374
- - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var dr,Nc,jc=R(()=>{"use strict";y();Ue();dr={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"]};Nc={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 ur(t){if(!t)return"";let e=[];return t.colors&&(t.colors.primary&&e.push(`- Primary color: ${t.colors.primary}`),t.colors.secondary&&e.push(`- Secondary color: ${t.colors.secondary}`),t.colors.accent&&e.push(`- Accent color: ${t.colors.accent}`)),t.fonts&&(t.fonts.heading&&e.push(`- Heading font: ${t.fonts.heading}`),t.fonts.body&&e.push(`- Body font: ${t.fonts.body}`)),t.logoUrl&&e.push(`- Logo URL: ${t.logoUrl}`),e.length===0?"":`
1374
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var dr,Oc,Dc=R(()=>{"use strict";y();Ge();dr={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"]};Oc={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 ur(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?"":`
1375
1375
 
1376
1376
  ## Brand Kit \u2014 MANDATORY Design Constraints
1377
1377
  The following brand identity values MUST be used. Do NOT substitute or override them:
1378
- ${e.join(`
1379
- `)}`}function Ao(t,e){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1378
+ ${t.join(`
1379
+ `)}`}function Ao(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1380
1380
 
1381
1381
  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.
1382
1382
 
1383
1383
  You produce a token map (colors, fonts, sizes) and a style guide string that downstream email module developers will reference when writing inline styles.
1384
1384
 
1385
- ## Theme: "${t}"
1385
+ ## Theme: "${e}"
1386
1386
 
1387
1387
  ## Output Requirements
1388
1388
 
@@ -1465,32 +1465,32 @@ Do NOT use: system-ui, -apple-system, Segoe UI, Inter, or any Google Fonts.
1465
1465
  - No external font imports`),n.push(`
1466
1466
 
1467
1467
  ## Email Design Guide
1468
- ${Lc()}`),e?.styleguide&&n.push(`
1468
+ ${Jc()}`),t?.styleguide&&n.push(`
1469
1469
 
1470
1470
  ## Brand Style Guide
1471
- ${e.styleguide}`),e?.themeContext&&n.push(`
1471
+ ${t.styleguide}`),t?.themeContext&&n.push(`
1472
1472
 
1473
1473
  ## Product Context
1474
- ${e.themeContext}`);let s=ur(e?.brandKit);return s?n.push(s):e?.styleguide||n.push(`
1474
+ ${t.themeContext}`);let s=ur(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
1475
1475
 
1476
1476
  ## No Brand Provided \u2014 Be Creative
1477
- 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 mr(t,e){let n=Ao(t),o=n.indexOf(`
1477
+ 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 mr(e,t){let n=Ao(e),o=n.indexOf(`
1478
1478
 
1479
1479
  ## Email Design Guide
1480
1480
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Email Design Guide
1481
- ${Lc()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];e?.styleguide&&l.push(`## Brand Style Guide
1482
- ${e.styleguide}`),e?.themeContext&&l.push(`## Product Context
1483
- ${e.themeContext}`);let c=ur(e?.brandKit);return c?l.push(c):e?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1481
+ ${Jc()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1482
+ ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1483
+ ${t.themeContext}`);let c=ur(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1484
1484
  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(`
1485
1485
 
1486
- `)}),a}function Dc(t,e,n,s){let o=[],i=Object.entries(e).map(([a,l])=>` ${a}: ${l}`).join(`
1486
+ `)}),a}function Lc(e,t,n,s){let o=[],i=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
1487
1487
  `);o.push(`You are the Email Module Planner for vibeSpot, a HubSpot email template builder.
1488
1488
 
1489
1489
  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.
1490
1490
 
1491
1491
  The Design Tokens have already been created. Your module plans MUST reference these tokens for consistent styling.
1492
1492
 
1493
- ## Theme: "${t}"
1493
+ ## Theme: "${e}"
1494
1494
 
1495
1495
  ## Design Tokens
1496
1496
  These literal values will be used in inline styles by module developers:
@@ -1542,7 +1542,7 @@ List all module names in display order (top to bottom)
1542
1542
  One sentence describing the email's purpose and flow`),(!s||s.includes("content"))&&o.push(`
1543
1543
 
1544
1544
  ## Email Content Guide
1545
- ${ih()}`),n?.brandvoice&&o.push(`
1545
+ ${rh()}`),n?.brandvoice&&o.push(`
1546
1546
 
1547
1547
  ## Brand Voice
1548
1548
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1551,7 +1551,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1551
1551
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1552
1552
 
1553
1553
  ## Anti-AI Copy Rules
1554
- ${rh()}`);let r=ur(n?.brandKit);return r&&o.push(r),o.join("")}function Lc(){return`### Email Design Philosophy
1554
+ ${ah()}`);let r=ur(n?.brandKit);return r&&o.push(r),o.join("")}function Jc(){return`### Email Design Philosophy
1555
1555
  Design for the inbox, not the browser. Email templates must look clean and professional in Gmail, Outlook, Apple Mail, and Yahoo Mail simultaneously.
1556
1556
 
1557
1557
  ### Color Strategy
@@ -1584,7 +1584,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1584
1584
  - Hero images: 600px wide, 2:1 to 3:1 aspect ratio
1585
1585
  - Always include alt text (images blocked by default in many clients)
1586
1586
  - Use display:block to prevent gaps in Outlook
1587
- - Product images: consistent sizing within a row`}function ih(){return`### Email Types and Structure
1587
+ - Product images: consistent sizing within a row`}function rh(){return`### Email Types and Structure
1588
1588
 
1589
1589
  **Welcome / Onboarding Email**
1590
1590
  - Warm greeting with first-name personalization
@@ -1630,7 +1630,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1630
1630
  - One idea per paragraph, 2-3 sentences max
1631
1631
  - Use "you" more than "we"
1632
1632
  - Specific > vague: "saves 3 hours/week" beats "saves time"
1633
- - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function rh(){return`### Email-Specific Anti-AI Rules
1633
+ - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function ah(){return`### Email-Specific Anti-AI Rules
1634
1634
  - No em dashes (\u2014) in email copy. Period.
1635
1635
  - No "I hope this email finds you well"
1636
1636
  - No "In today's fast-paced world"
@@ -1639,36 +1639,36 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1639
1639
  - One exclamation mark per email maximum
1640
1640
  - Avoid tricolon structures ("Fast, reliable, secure")
1641
1641
  - Write like a colleague, not a press release
1642
- - Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var pr,Jc=R(()=>{"use strict";y();pr={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 Bc(t,e,n,s,o,i,r){let a=e.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?Ao(n.themeName,n.brandAssets):To(n.themeName,n.brandAssets),d=l?a?mr(n.themeName,n.brandAssets):cr(n.themeName,n.brandAssets):void 0,u=`## User Request
1643
- ${t}`;n.modules.length>0&&e.designSystemChanges&&(u+=`
1642
+ - Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var pr,Bc=R(()=>{"use strict";y();pr={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 Hc(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?Ao(n.themeName,n.brandAssets):To(n.themeName,n.brandAssets),d=l?a?mr(n.themeName,n.brandAssets):cr(n.themeName,n.brandAssets):void 0,u=`## User Request
1643
+ ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1644
1644
 
1645
1645
  ## Current Shared CSS (update this)
1646
1646
  \`\`\`css
1647
1647
  ${n.sharedCss}
1648
- \`\`\``);let m=Sn(s),h=await _e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:a?pr:dr,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 {
1648
+ \`\`\``);let m=Sn(s),h=await _e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:a?pr:dr,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}}),f;h.type!=="structured"?(M.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,M.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 {
1649
1649
  ${Object.entries(S).map(([F,H])=>` ${F.startsWith("--")?F:`--${F}`}: ${H};`).join(`
1650
1650
  `)}
1651
1651
  }
1652
1652
 
1653
- ${b}`));let x=Object.keys(S||{}).length,w=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:w.join(`
1654
- `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function Hc(t,e,n,s,o,i,r){let a=e.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?Ao(n.themeName,n.brandAssets):To(n.themeName,n.brandAssets),d=l?a?mr(n.themeName,n.brandAssets):cr(n.themeName,n.brandAssets):void 0,u=`## User Request
1655
- ${t}`;n.modules.length>0&&e.designSystemChanges&&(u+=`
1653
+ ${b}`));let x=Object.keys(S||{}).length,v=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:v.join(`
1654
+ `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function Gc(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?Ao(n.themeName,n.brandAssets):To(n.themeName,n.brandAssets),d=l?a?mr(n.themeName,n.brandAssets):cr(n.themeName,n.brandAssets):void 0,u=`## User Request
1655
+ ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1656
1656
 
1657
1657
  ## Current Shared CSS (update this)
1658
1658
  \`\`\`css
1659
1659
  ${n.sharedCss}
1660
- \`\`\``);let m=Sn(s),h=await _e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:a?pr:dr,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 {
1660
+ \`\`\``);let m=Sn(s),h=await _e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:a?pr:dr,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}}),f;h.type!=="structured"?(M.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,M.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 {
1661
1661
  ${Object.entries(S).map(([k,K])=>` ${k.startsWith("--")?k:`--${k}`}: ${K};`).join(`
1662
1662
  `)}
1663
1663
  }
1664
1664
 
1665
- ${b}`));let x=[],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,P=[...new Set((t.match(w)||[]).map(I=>I.trim()))];if(P.length>0){let I=P.filter(K=>b.toLowerCase().includes(K.toLowerCase())),k=P.filter(K=>!I.includes(K));k.length>0&&x.push(`Note: ${k.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let F=Object.keys(S||{}).length,H=a?[`Email design tokens: ${f.aesthetic||"created"} | ${F} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${F} variables, ${b.length} chars CSS`,...x];r({type:"agent_decision",step:"designing",decision:H.join(`
1666
- `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let L=a?Dc(n.themeName,S||{},n.brandAssets,e.guidesNeeded):Rc(n.themeName,b,n.brandAssets,e.guidesNeeded),V=`## User Request
1667
- ${t}`;if(e.newModules.length>0&&(V+=`
1665
+ ${b}`));let x=[],v=/\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,I=[...new Set((e.match(v)||[]).map(P=>P.trim()))];if(I.length>0){let P=I.filter(K=>b.toLowerCase().includes(K.toLowerCase())),k=I.filter(K=>!P.includes(K));k.length>0&&x.push(`Note: ${k.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let F=Object.keys(S||{}).length,H=a?[`Email design tokens: ${f.aesthetic||"created"} | ${F} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${F} variables, ${b.length} chars CSS`,...x];r({type:"agent_decision",step:"designing",decision:H.join(`
1666
+ `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let L=a?Lc(n.themeName,S||{},n.brandAssets,t.guidesNeeded):Nc(n.themeName,b,n.brandAssets,t.guidesNeeded),V=`## User Request
1667
+ ${e}`;if(t.newModules.length>0&&(V+=`
1668
1668
 
1669
1669
  ## Planned Modules
1670
- ${e.newModules.map((I,k)=>`${k+1}. **${I.name}** \u2014 ${I.description}`).join(`
1671
- `)}`),n.modules.length>0){let I=new Set(e.affectedModules),k=n.modules.filter(oe=>I.has(oe.moduleName)),K=n.modules.filter(oe=>!I.has(oe.moduleName));k.length>0&&(V+=`
1670
+ ${t.newModules.map((P,k)=>`${k+1}. **${P.name}** \u2014 ${P.description}`).join(`
1671
+ `)}`),n.modules.length>0){let P=new Set(t.affectedModules),k=n.modules.filter(oe=>P.has(oe.moduleName)),K=n.modules.filter(oe=>!P.has(oe.moduleName));k.length>0&&(V+=`
1672
1672
 
1673
1673
  ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1674
1674
  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.
@@ -1678,14 +1678,14 @@ These already exist and are being regenerated. Your output's module names MUST m
1678
1678
  ## Existing Modules to Keep (do not re-plan)
1679
1679
  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).
1680
1680
  `+K.map(oe=>`- \`${oe.moduleName}\``).join(`
1681
- `))}let B=await _e(s,o,i,{systemPrompt:L,messages:[{role:"user",content:V}],structuredOutput:{schema:Nc,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{}}),N,T={modules:e.newModules.map(I=>({name:I.name,description:I.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:e.newModules.map(I=>I.name),narrative:"Page generated from user request"};if(B.type!=="structured")E.warn("page-architect","Module planner: did not get structured output, using fallback"),N=T;else{let I=B.data;Array.isArray(I?.modules)&&I.modules.length>0?(N=I,N.moduleOrder=N.moduleOrder||N.modules.map(k=>k.name),N.narrative=N.narrative||"Page generated from user request"):(E.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:I?Object.keys(I):[]}),N=T),E.info("page-architect","Module plan",{moduleCount:N.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${N.narrative} | ${N.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:N.modules,moduleOrder:N.moduleOrder,narrative:N.narrative}}var Uc=R(()=>{"use strict";y();nt();jc();Jc();de()});function ah(t){let e=[...new Set([...t.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...t.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...t.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),e.length>0&&o.push(`CSS Classes: ${e.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
1682
- `)}function Gc(t,e,n,s,o){let i=ah(s),r=e.map(c=>`- **${c.label}** (${c.pageType}, slug: "${c.slug}"): ${c.purpose}`).join(`
1681
+ `))}let B=await _e(s,o,i,{systemPrompt:L,messages:[{role:"user",content:V}],structuredOutput:{schema:Oc,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{}}),N,T={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(B.type!=="structured")M.warn("page-architect","Module planner: did not get structured output, using fallback"),N=T;else{let P=B.data;Array.isArray(P?.modules)&&P.modules.length>0?(N=P,N.moduleOrder=N.moduleOrder||N.modules.map(k=>k.name),N.narrative=N.narrative||"Page generated from user request"):(M.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:P?Object.keys(P):[]}),N=T),M.info("page-architect","Module plan",{moduleCount:N.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${N.narrative} | ${N.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:N.modules,moduleOrder:N.moduleOrder,narrative:N.narrative}}var Uc=R(()=>{"use strict";y();nt();Dc();Bc();de()});function lh(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(`
1682
+ `)}function Wc(e,t,n,s,o){let i=lh(s),r=t.map(c=>`- **${c.label}** (${c.pageType}, slug: "${c.slug}"): ${c.purpose}`).join(`
1683
1683
  `),a=n.map(c=>`- **${c}**`).join(`
1684
1684
  `),l=[];return l.push(`You are the Site Module Planner for vibeSpot, a HubSpot CMS page builder.
1685
1685
 
1686
1686
  Your job: plan modules for a MULTI-PAGE website. You plan ALL pages in one pass to ensure cross-page coherence. You also plan shared modules (header, footer, navigation) that appear on every page identically.
1687
1687
 
1688
- ## Theme: "${t}"
1688
+ ## Theme: "${e}"
1689
1689
 
1690
1690
  ## Site Map
1691
1691
  ${r}
@@ -1705,9 +1705,9 @@ ${i}
1705
1705
  ### site-header (Navigation)
1706
1706
  - Logo on the left, nav links center or right, CTA button far right
1707
1707
  - Nav links: one for each page in the site map. Use relative hrefs matching slugs:
1708
- ${e.map(c=>` - "${c.label}" \u2192 href="/${c.slug}"`).join(`
1708
+ ${t.map(c=>` - "${c.label}" \u2192 href="/${c.slug}"`).join(`
1709
1709
  `)}
1710
- - Active page link uses CSS class "${t}-nav__link--active"
1710
+ - Active page link uses CSS class "${e}-nav__link--active"
1711
1711
  - Sticky with backdrop-blur, transitions on scroll
1712
1712
  - Mobile: hamburger menu with slide-in nav
1713
1713
 
@@ -1742,16 +1742,16 @@ Return a JSON object with:
1742
1742
  ${o.brandvoice}`),o?.themeContext&&l.push(`
1743
1743
 
1744
1744
  ## Product Context
1745
- ${o.themeContext}`),l.join("")}var Wc,Kc=R(()=>{"use strict";y();Wc={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 zc(t,e,n,s,o,i,r,a){a({type:"agent_step",step:"planning_site",label:`Planning modules for ${e.pages?.length||0} pages...`});let l=e.pages||[],c=e.sharedModules||["site-header","site-footer"],d=Gc(n.themeName,l,c,s,n.brandAssets),u=`## User Request
1746
- ${t}
1745
+ ${o.themeContext}`),l.join("")}var Kc,Vc=R(()=>{"use strict";y();Kc={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 Yc(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=Wc(n.themeName,l,c,s,n.brandAssets),u=`## User Request
1746
+ ${e}
1747
1747
 
1748
1748
  ## Site Map
1749
1749
  ${l.map(x=>`- ${x.label} (${x.slug}): ${x.purpose}`).join(`
1750
- `)}`,m=Sn(o),g=await _e(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:Wc,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"),Vc(e,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):[]}),Vc(e,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(w=>({name:w.name,description:w.description,contentBrief:w.contentBrief,layoutNotes:w.layoutNotes})),moduleOrder:x.moduleOrder||[]})),S=f.length+b.reduce((x,w)=>x+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(x=>{let w=l.find(P=>P.id===x.pageId);return{pageId:x.pageId,label:w?.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 Vc(t,e,n){let s=t.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:e.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 Yc=R(()=>{"use strict";y();nt();Kc();de()});function $o(t){let e=0,n=[];return async function(o){e>=t&&await new Promise(i=>n.push(i)),e++;try{return await o()}finally{e--,n.length>0&&n.shift()()}}}var gr=R(()=>{"use strict";y()});function as(t,e,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1750
+ `)}`,m=Sn(o),g=await _e(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:Kc,name:"site_module_plan"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}});if(g.type!=="structured")return M.warn("site-planner","Did not get structured output, building fallback"),zc(t,c,s);let h=g.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return M.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),zc(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(v=>({name:v.name,description:v.description,contentBrief:v.contentBrief,layoutNotes:v.layoutNotes})),moduleOrder:x.moduleOrder||[]})),S=f.length+b.reduce((x,v)=>x+v.modules.length,0);return M.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 v=l.find(I=>I.id===x.pageId);return{pageId:x.pageId,label:v?.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 zc(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 qc=R(()=>{"use strict";y();nt();Vc();de()});function $o(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 gr=R(()=>{"use strict";y()});function as(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1751
1751
 
1752
1752
  Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code.
1753
1753
 
1754
- ## Theme: "${t}"
1754
+ ## Theme: "${e}"
1755
1755
 
1756
1756
  ## Output Rules \u2014 CRITICAL
1757
1757
  You produce a single module with these fields:
@@ -1763,8 +1763,8 @@ You produce a single module with these fields:
1763
1763
  - **moduleJs**: Optional vanilla JS wrapped in IIFE, or null
1764
1764
 
1765
1765
  ## CSS Rules
1766
- - All CSS classes must use prefix "${t}-"
1767
- - Use BEM naming: ${t}-moduleName__element--modifier
1766
+ - All CSS classes must use prefix "${e}-"
1767
+ - Use BEM naming: ${e}-moduleName__element--modifier
1768
1768
  - Reference the theme's CSS custom properties (shown below)
1769
1769
  - No CDN imports (@import url(), external <link> tags)
1770
1770
  - Use system font stacks \u2014 no Google Fonts
@@ -1781,7 +1781,7 @@ You produce a single module with these fields:
1781
1781
  - For repeater groups, use "occurrence": { "min": 0, "max": 100 }
1782
1782
 
1783
1783
  ## Images & Assets
1784
- - Use get_asset_url("${t}/assets/filename.ext") for uploaded assets
1784
+ - Use get_asset_url("${e}/assets/filename.ext") for uploaded assets
1785
1785
  - For placeholder images, use image fields with placehold.co defaults
1786
1786
  - Size placeholders appropriately (hero: 1920x800, cards: 600x400, icons: 200x200)
1787
1787
 
@@ -1791,11 +1791,11 @@ You produce a single module with these fields:
1791
1791
  - Include smooth scroll behavior in nav click handlers
1792
1792
 
1793
1793
  ## metaJson Template
1794
- { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`),e&&o.push(`
1794
+ { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`),t&&o.push(`
1795
1795
 
1796
1796
  ## Theme Shared CSS (use these custom properties)
1797
1797
  \`\`\`css
1798
- ${e}
1798
+ ${t}
1799
1799
  \`\`\``),(!n||n.includes("hubspot_rules"))&&o.push(`
1800
1800
 
1801
1801
  ## HubSpot CMS Rules
@@ -1808,20 +1808,20 @@ ${fe()}`),s?.themeContext&&o.push(`
1808
1808
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1809
1809
 
1810
1810
  ## Anti-AI Copy Rules
1811
- ${qc()}`),o.join("")}function _o(t,e,n,s){let o=[],i=as(t,"",[],s?{...s,humanify:!1}:void 0);e&&(i+=`
1811
+ ${Xc()}`),o.join("")}function _o(e,t,n,s){let o=[],i=as(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1812
1812
 
1813
1813
  ## Theme Shared CSS (use these custom properties)
1814
1814
  \`\`\`css
1815
- ${e}
1815
+ ${t}
1816
1816
  \`\`\``),o.push({type:"text",text:i});let r=[];(!n||n.includes("hubspot_rules"))&&r.push(`## HubSpot CMS Rules
1817
1817
  ${je()}`),(!n||n.includes("conversion"))&&r.push(`## Conversion Guide
1818
1818
  ${fe()}`),r.length>0&&o.push({type:"text",text:r.join(`
1819
1819
 
1820
1820
  `),cache_control:{type:"ephemeral"}});let a=[];return s?.themeContext&&a.push(`## Product Context
1821
1821
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&a.push(`## Anti-AI Copy Rules
1822
- ${qc()}`),a.length>0&&o.push({type:"text",text:a.join(`
1822
+ ${Xc()}`),a.length>0&&o.push({type:"text",text:a.join(`
1823
1823
 
1824
- `)}),o}function qc(){return`### Banned Punctuation
1824
+ `)}),o}function Xc(){return`### Banned Punctuation
1825
1825
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1826
1826
  - **Semicolons**: Use periods instead in marketing copy.
1827
1827
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1860,14 +1860,14 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1860
1860
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1861
1861
  - Full names, specific roles (not "John D., CEO")
1862
1862
  - Never start with "This product is..." \u2014 start with the person's situation
1863
- - Vary length and voice across testimonials`}function Xc(t,e,n){let s=[];return s.push(`## User Request
1864
- ${t}`),s.push(`
1863
+ - Vary length and voice across testimonials`}function Zc(e,t,n){let s=[];return s.push(`## User Request
1864
+ ${e}`),s.push(`
1865
1865
 
1866
1866
  ## Module Specification
1867
- - **Name**: ${e.name}
1868
- - **Description**: ${e.description}
1869
- - **Content Brief**: ${e.contentBrief}
1870
- - **Layout Notes**: ${e.layoutNotes}`),n&&(s.push(`
1867
+ - **Name**: ${t.name}
1868
+ - **Description**: ${t.description}
1869
+ - **Content Brief**: ${t.contentBrief}
1870
+ - **Layout Notes**: ${t.layoutNotes}`),n&&(s.push(`
1871
1871
 
1872
1872
  ## Existing Module Code (modify this)
1873
1873
  **fields.json:**
@@ -1887,11 +1887,11 @@ ${n.moduleCss}
1887
1887
  **module.js:**
1888
1888
  \`\`\`js
1889
1889
  ${n.moduleJs}
1890
- \`\`\``)),s.join("")}var ls,fr=R(()=>{"use strict";y();Ue();ls={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 hr(t,e){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1890
+ \`\`\``)),s.join("")}var ls,fr=R(()=>{"use strict";y();Ge();ls={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 hr(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1891
1891
 
1892
1892
  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.
1893
1893
 
1894
- ## Theme: "${t}"
1894
+ ## Theme: "${e}"
1895
1895
 
1896
1896
  ## CRITICAL: Email vs. Page Differences
1897
1897
  This is an EMAIL module, not a page module. Email clients (Gmail, Outlook, Apple Mail) have severe rendering limitations:
@@ -2039,23 +2039,23 @@ NEVER use:
2039
2039
  Modules that serve as email footers MUST include:
2040
2040
  - Unsubscribe link: <a href="{{ unsubscribe_link }}">Unsubscribe</a>
2041
2041
  - Physical address: {{ site_settings.company_street_address_1 }}, {{ site_settings.company_city }}, {{ site_settings.company_state }}
2042
- - Company name: {{ site_settings.company_name }}`),e?.themeContext&&n.push(`
2042
+ - Company name: {{ site_settings.company_name }}`),t?.themeContext&&n.push(`
2043
2043
 
2044
2044
  ## Product Context
2045
- ${e.themeContext}`),e?.humanify!==!1&&n.push(`
2045
+ ${t.themeContext}`),t?.humanify!==!1&&n.push(`
2046
2046
 
2047
2047
  ## Anti-AI Copy Rules
2048
- ${Qc()}`),e?.brandKit){let s=[];e.brandKit.colors&&(e.brandKit.colors.primary&&s.push(`- Primary color: ${e.brandKit.colors.primary}`),e.brandKit.colors.secondary&&s.push(`- Secondary color: ${e.brandKit.colors.secondary}`),e.brandKit.colors.accent&&s.push(`- Accent color: ${e.brandKit.colors.accent}`)),e.brandKit.fonts&&(e.brandKit.fonts.heading&&s.push(`- Heading font: ${e.brandKit.fonts.heading}`),e.brandKit.fonts.body&&s.push(`- Body font: ${e.brandKit.fonts.body}`)),e.brandKit.logoUrl&&s.push(`- Logo URL: ${e.brandKit.logoUrl}`),s.length>0&&n.push(`
2048
+ ${ed()}`),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(`
2049
2049
 
2050
2050
  ## Brand Kit \u2014 MANDATORY Design Constraints
2051
2051
  The following brand identity values MUST be used. Do NOT substitute or override them:
2052
2052
  ${s.join(`
2053
- `)}`)}return n.join("")}function Zc(t,e){let n=[],s=hr(t,{...e,humanify:!1});n.push({type:"text",text:s});let o;try{o=Pa()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2054
- ${o}`,cache_control:{type:"ephemeral"}});let i=[];return e?.themeContext&&i.push(`## Product Context
2055
- ${e.themeContext}`),e?.humanify!==!1&&i.push(`## Anti-AI Copy Rules
2056
- ${Qc()}`),i.length>0&&n.push({type:"text",text:i.join(`
2053
+ `)}`)}return n.join("")}function Qc(e,t){let n=[],s=hr(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=Pa()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2054
+ ${o}`,cache_control:{type:"ephemeral"}});let i=[];return t?.themeContext&&i.push(`## Product Context
2055
+ ${t.themeContext}`),t?.humanify!==!1&&i.push(`## Anti-AI Copy Rules
2056
+ ${ed()}`),i.length>0&&n.push({type:"text",text:i.join(`
2057
2057
 
2058
- `)}),n}function Qc(){return`### Banned Punctuation
2058
+ `)}),n}function ed(){return`### Banned Punctuation
2059
2059
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2060
2060
  - **Semicolons**: Use periods instead.
2061
2061
  - **Exclamation marks**: One per email max. Zero ideal for B2B.
@@ -2074,14 +2074,14 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2074
2074
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2075
2075
  - Use plain words: use > utilize, start > commence, help > facilitate
2076
2076
  - Front-load the benefit in the first 5 words
2077
- - Email subject lines: specific, benefit-first, under 50 chars`}function ed(t,e,n){let s=[];return s.push(`## User Request
2078
- ${t}`),s.push(`
2077
+ - Email subject lines: specific, benefit-first, under 50 chars`}function td(e,t,n){let s=[];return s.push(`## User Request
2078
+ ${e}`),s.push(`
2079
2079
 
2080
2080
  ## Email Module Specification
2081
- - **Name**: ${e.name}
2082
- - **Description**: ${e.description}
2083
- - **Content Brief**: ${e.contentBrief}
2084
- - **Layout Notes**: ${e.layoutNotes}
2081
+ - **Name**: ${t.name}
2082
+ - **Description**: ${t.description}
2083
+ - **Content Brief**: ${t.contentBrief}
2084
+ - **Layout Notes**: ${t.layoutNotes}
2085
2085
 
2086
2086
  REMEMBER: This is an EMAIL module. ALL layout must use tables. ALL CSS must be inline. NO external stylesheets. NO JavaScript.`),n&&s.push(`
2087
2087
 
@@ -2094,11 +2094,11 @@ ${n.fieldsJson}
2094
2094
  **module.html:**
2095
2095
  \`\`\`html
2096
2096
  ${n.moduleHtml}
2097
- \`\`\``),s.join("")}var td,nd=R(()=>{"use strict";y();Ue();td={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 yr(t,e,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
2097
+ \`\`\``),s.join("")}var nd,sd=R(()=>{"use strict";y();Ge();nd={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 yr(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
2098
2098
 
2099
2099
  Your job: generate ONE HubSpot CMS blog module. You receive a module specification and must produce the complete module code optimized for blog templates.
2100
2100
 
2101
- ## Theme: "${t}"
2101
+ ## Theme: "${e}"
2102
2102
 
2103
2103
  ## CRITICAL: Blog Template Context
2104
2104
  This is a BLOG module. Blog modules are used in HubSpot blog post and blog listing templates. They differ from page modules in these key ways:
@@ -2117,8 +2117,8 @@ You produce a single module with these fields:
2117
2117
  - **moduleJs**: Optional vanilla JS wrapped in IIFE, or null
2118
2118
 
2119
2119
  ## CSS Rules
2120
- - All CSS classes must use prefix "${t}-"
2121
- - Use BEM naming: ${t}-moduleName__element--modifier
2120
+ - All CSS classes must use prefix "${e}-"
2121
+ - Use BEM naming: ${e}-moduleName__element--modifier
2122
2122
  - Reference the theme's CSS custom properties (shown below)
2123
2123
  - No CDN imports (@import url(), external <link> tags)
2124
2124
  - Use system font stacks \u2014 no Google Fonts
@@ -2134,7 +2134,7 @@ Blog modules should use these design principles:
2134
2134
 
2135
2135
  ## Shared CSS (use these variables)
2136
2136
  \`\`\`css
2137
- ${e||"/* No shared CSS yet \u2014 create appropriate custom properties */"}
2137
+ ${t||"/* No shared CSS yet \u2014 create appropriate custom properties */"}
2138
2138
  \`\`\`
2139
2139
 
2140
2140
  ## HubSpot Blog Variables \u2014 Use These
@@ -2246,8 +2246,8 @@ Determine the correct host_template_types from the module specification:
2246
2246
  ### Blog Post Body Wrapper
2247
2247
  The blog post body module wraps \`{{ content.post_body }}\` with reading-optimized styles:
2248
2248
  \`\`\`html
2249
- <article class="${t}-post-body">
2250
- <div class="${t}-post-body__content">
2249
+ <article class="${e}-post-body">
2250
+ <div class="${e}-post-body__content">
2251
2251
  {{ content.post_body }}
2252
2252
  </div>
2253
2253
  </article>
@@ -2256,20 +2256,20 @@ The blog post body module wraps \`{{ content.post_body }}\` with reading-optimiz
2256
2256
  ### Post Card (for listing)
2257
2257
  \`\`\`html
2258
2258
  {% for content in contents %}
2259
- <article class="${t}-post-card">
2259
+ <article class="${e}-post-card">
2260
2260
  {% if content.featured_image %}
2261
2261
  <img src="{{ content.featured_image }}" alt="{{ content.featured_image_alt_text }}"
2262
- class="${t}-post-card__image" loading="lazy" />
2262
+ class="${e}-post-card__image" loading="lazy" />
2263
2263
  {% endif %}
2264
- <div class="${t}-post-card__content">
2265
- <span class="${t}-post-card__date">
2264
+ <div class="${e}-post-card__content">
2265
+ <span class="${e}-post-card__date">
2266
2266
  {{ content.publish_date|datetimeformat('%B %d, %Y') }}
2267
2267
  </span>
2268
- <h2 class="${t}-post-card__title">
2268
+ <h2 class="${e}-post-card__title">
2269
2269
  <a href="{{ content.absolute_url }}">{{ content.name }}</a>
2270
2270
  </h2>
2271
- <p class="${t}-post-card__excerpt">{{ content.meta_description|truncate(160) }}</p>
2272
- <span class="${t}-post-card__author">{{ content.blog_post_author }}</span>
2271
+ <p class="${e}-post-card__excerpt">{{ content.meta_description|truncate(160) }}</p>
2272
+ <span class="${e}-post-card__author">{{ content.blog_post_author }}</span>
2273
2273
  </div>
2274
2274
  </article>
2275
2275
  {% endfor %}
@@ -2279,22 +2279,22 @@ The blog post body module wraps \`{{ content.post_body }}\` with reading-optimiz
2279
2279
  ${s.themeContext}`),s?.humanify!==!1&&o.push(`
2280
2280
 
2281
2281
  ## Anti-AI Copy Rules
2282
- ${od()}`);let i=[];if(n?.includes("conversion"))try{let r=fe();r&&i.push(`## Conversion Guide
2282
+ ${id()}`);let i=[];if(n?.includes("conversion"))try{let r=fe();r&&i.push(`## Conversion Guide
2283
2283
  ${r}`)}catch{}if(n?.includes("hubspot_rules"))try{let r=je();r&&i.push(`## HubSpot Rules
2284
2284
  ${r}`)}catch{}return i.length>0&&o.push(`
2285
2285
 
2286
2286
  ${i.join(`
2287
2287
 
2288
- `)}`),o.join("")}function sd(t,e,n,s){let o=[],i=yr(t,e,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=Ra()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2288
+ `)}`),o.join("")}function od(e,t,n,s){let o=[],i=yr(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=Ra()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2289
2289
  ${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=fe();c&&a.push(`## Conversion Guide
2290
2290
  ${c}`)}catch{}if(n?.includes("hubspot_rules"))try{let c=je();c&&a.push(`## HubSpot Rules
2291
2291
  ${c}`)}catch{}a.length>0&&o.push({type:"text",text:a.join(`
2292
2292
 
2293
2293
  `),cache_control:{type:"ephemeral"}});let l=[];return s?.themeContext&&l.push(`## Product Context
2294
2294
  ${s.themeContext}`),s?.humanify!==!1&&l.push(`## Anti-AI Copy Rules
2295
- ${od()}`),l.length>0&&o.push({type:"text",text:l.join(`
2295
+ ${id()}`),l.length>0&&o.push({type:"text",text:l.join(`
2296
2296
 
2297
- `)}),o}function od(){return`### Banned Punctuation
2297
+ `)}),o}function id(){return`### Banned Punctuation
2298
2298
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2299
2299
  - **Semicolons**: Use periods instead.
2300
2300
  - **Exclamation marks**: Maximum one per page. Zero ideal for B2B.
@@ -2313,14 +2313,14 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2313
2313
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2314
2314
  - Use plain words: use > utilize, start > commence, help > facilitate
2315
2315
  - Front-load the benefit in the first 5 words
2316
- - Blog headlines: specific, benefit-first, no clickbait`}function id(t,e,n){let s=[];return s.push(`## User Request
2317
- ${t}`),s.push(`
2316
+ - Blog headlines: specific, benefit-first, no clickbait`}function rd(e,t,n){let s=[];return s.push(`## User Request
2317
+ ${e}`),s.push(`
2318
2318
 
2319
2319
  ## Blog Module Specification
2320
- - **Name**: ${e.name}
2321
- - **Description**: ${e.description}
2322
- - **Content Brief**: ${e.contentBrief}
2323
- - **Layout Notes**: ${e.layoutNotes}
2320
+ - **Name**: ${t.name}
2321
+ - **Description**: ${t.description}
2322
+ - **Content Brief**: ${t.contentBrief}
2323
+ - **Layout Notes**: ${t.layoutNotes}
2324
2324
 
2325
2325
  REMEMBER: This is a BLOG module. Use HubSpot blog variables where appropriate (content.post_body, content.author, content.tag_list, etc.). Set the correct host_template_types in meta.json (BLOG_POST, BLOG_LISTING, or both).`),n&&s.push(`
2326
2326
 
@@ -2338,33 +2338,33 @@ ${n.moduleHtml}
2338
2338
  **module.css:**
2339
2339
  \`\`\`css
2340
2340
  ${n.moduleCss}
2341
- \`\`\``),s.join("")}var rd,ad=R(()=>{"use strict";y();Ue();Ue();rd={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 cs(t,e,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 ${e.length} ${h}${e.length===1?"":"s"}...`});let f=o==="anthropic-api"||o==="claude-oauth",b=m?hr(s,d):g?yr(s,n,c,d):as(s,n,c,d),S=f?m?Zc(s,d):g?sd(s,n,c,d):_o(s,n,c,d):void 0,x=$o(a),w=e.length,P=m?td:g?rd:ls,F=e.map((L,V)=>x(async()=>{l({type:"module_progress",module:L.name,status:"generating",current:V+1,total:w});let B="";for(let N=0;N<2;N++)try{N>0&&(E.warn("module-developer",`${L.name}: retrying after failure (attempt ${N+1})`),l({type:"module_progress",module:L.name,status:"retrying",current:V+1,total:w}));let T=await ld(t,L,b,o,i,r,0,S,m,P,g);return l({type:"module_progress",module:L.name,status:"complete",current:V+1,total:w,moduleFiles:T}),{moduleName:L.name,module:T}}catch(T){B=T instanceof Error?T.message:typeof T=="object"&&T!==null?JSON.stringify(T):String(T),E.error("module-developer",`Failed: ${L.name} (attempt ${N+1})`,{error:B})}return l({type:"module_progress",module:L.name,status:"failed",current:V+1,total:w}),{moduleName:L.name,error:B}}));return(await Promise.allSettled(F)).map(L=>L.status==="fulfilled"?L.value:{moduleName:"unknown",error:L.reason instanceof Error?L.reason.message:String(L.reason)})}async function ld(t,e,n,s,o,i,r=0,a,l=!1,c=ls,d=!1){let u=l?ed(t,e,e.existingCode):d?id(t,e,e.existingCode):Xc(t,e,e.existingCode),m=await _e(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",`${e.name}: no structured output, retry ${r+1}`),ld(t,e,n,s,o,i,r+1,a,l,c,d);throw new Error(`Module "${e.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:e.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 cd=R(()=>{"use strict";y();nt();gr();fr();nd();ad();de()});function zt(t,e,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..."}),t.map(a=>{let l=[],c={...a};c.fieldsJson=dd(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=dd(c.metaJson,c.moduleName,"metaJson",l,i,r),c.fieldsJson=lh(c.fieldsJson,c.moduleName,l),c.fieldsJson=ch(c.fieldsJson,c.moduleName,l),i?c=Sh(c,l):(c.moduleCss=dh(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=mh(c.moduleCss,c.moduleName,e,l),c.moduleHtml=ph(c.moduleHtml,c.moduleName,e,l),r&&(c=xh(c,l))),c.moduleHtml=fh(c.moduleHtml,c.moduleName,l),c.metaJson=hh(c.metaJson,c.moduleName,l,i,r),o&&bh(c,o,l);let d=l.every(u=>u.autoFixed);return l.length>0&&E.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(u=>u.autoFixed).length,unfixed:l.filter(u=>!u.autoFixed).length}),{module:c,issues:l,valid:d}})}function dd(t,e,n,s,o=!1,i=!1){return!t||t.trim()===""?(s.push({module:e,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}):t):ft(t)===null?(s.push({module:e,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})):t}function lh(t,e,n){let s=t;return/"name"\s*:\s*"name"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"name" is a reserved field name \u2192 renamed to "item_name"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"name"/g,'"name": "item_name"')),/"name"\s*:\s*"label"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"label" is a reserved field name \u2192 renamed to "section_label"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"label"/g,'"name": "section_label"')),s}function ch(t,e,n){let s=t;return/"type"\s*:\s*"textarea"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"textarea" is deprecated \u2192 changed to "text"',autoFixed:!0}),s=s.replace(/"type"\s*:\s*"textarea"/g,'"type": "text"')),s}function dh(t,e,n,s){if(!t)return t;let o=t,i=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return i.test(o)&&(s.push({module:e,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(i,"/* CDN import removed */")),o}function ud(t){return uh.has(t)||t.startsWith("body-wrapper")||t.startsWith("dnd-")||t.startsWith("row-")||t.startsWith("hs-")||t.startsWith("hs_")}function mh(t,e,n,s){if(!t)return t;let o=n+"-",i=/\.([a-zA-Z][\w-]*)/g,r=new Set,a;for(;(a=i.exec(t))!==null;){let c=a[1];!c.startsWith(o)&&!ud(c)&&r.add(c)}if(r.size<=3)return t;let l=t;for(let c of r){let d=new RegExp(`\\.${gh(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==t&&s.push({module:e,field:"moduleCss",message:`${r.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function ph(t,e,n,s){if(!t)return t;let o=n+"-",i=/class="([^"]*)"/g,r=!1,a=t.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)&&!ud(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:e,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),a}function gh(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function fh(t,e,n){if(!t)return t;let s=t,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:e,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:e,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(`
2341
+ \`\`\``),s.join("")}var ad,ld=R(()=>{"use strict";y();Ge();Ge();ad={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 cs(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?hr(s,d):g?yr(s,n,c,d):as(s,n,c,d),S=f?m?Qc(s,d):g?od(s,n,c,d):_o(s,n,c,d):void 0,x=$o(a),v=t.length,I=m?nd:g?ad:ls,F=t.map((L,V)=>x(async()=>{l({type:"module_progress",module:L.name,status:"generating",current:V+1,total:v});let B="";for(let N=0;N<2;N++)try{N>0&&(M.warn("module-developer",`${L.name}: retrying after failure (attempt ${N+1})`),l({type:"module_progress",module:L.name,status:"retrying",current:V+1,total:v}));let T=await cd(e,L,b,o,i,r,0,S,m,I,g);return l({type:"module_progress",module:L.name,status:"complete",current:V+1,total:v,moduleFiles:T}),{moduleName:L.name,module:T}}catch(T){B=T instanceof Error?T.message:typeof T=="object"&&T!==null?JSON.stringify(T):String(T),M.error("module-developer",`Failed: ${L.name} (attempt ${N+1})`,{error:B})}return l({type:"module_progress",module:L.name,status:"failed",current:V+1,total:v}),{moduleName:L.name,error:B}}));return(await Promise.allSettled(F)).map(L=>L.status==="fulfilled"?L.value:{moduleName:"unknown",error:L.reason instanceof Error?L.reason.message:String(L.reason)})}async function cd(e,t,n,s,o,i,r=0,a,l=!1,c=ls,d=!1){let u=l?td(e,t,t.existingCode):d?rd(e,t,t.existingCode):Zc(e,t,t.existingCode),m=await _e(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 M.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),cd(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 dd=R(()=>{"use strict";y();nt();gr();fr();sd();ld();de()});function zt(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=ud(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=ud(c.metaJson,c.moduleName,"metaJson",l,i,r),c.fieldsJson=ch(c.fieldsJson,c.moduleName,l),c.fieldsJson=dh(c.fieldsJson,c.moduleName,l),i?c=xh(c,l):(c.moduleCss=uh(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=ph(c.moduleCss,c.moduleName,t,l),c.moduleHtml=gh(c.moduleHtml,c.moduleName,t,l),r&&(c=vh(c,l))),c.moduleHtml=hh(c.moduleHtml,c.moduleName,l),c.metaJson=yh(c.metaJson,c.moduleName,l,i,r),o&&Sh(c,o,l);let d=l.every(u=>u.autoFixed);return l.length>0&&M.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(u=>u.autoFixed).length,unfixed:l.filter(u=>!u.autoFixed).length}),{module:c,issues:l,valid:d}})}function ud(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):ft(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 ch(e,t,n){let s=e;return/"name"\s*:\s*"name"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"name" is a reserved field name \u2192 renamed to "item_name"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"name"/g,'"name": "item_name"')),/"name"\s*:\s*"label"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"label" is a reserved field name \u2192 renamed to "section_label"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"label"/g,'"name": "section_label"')),s}function dh(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 uh(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 md(e){return mh.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function ph(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)&&!md(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${fh(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 gh(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)&&!md(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 fh(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function hh(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(`
2342
2342
  `);s=`${s}
2343
- ${f}`,n.push({module:e,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:e,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function hh(t,e,n,s=!1,o=!1){let i=ft(t);if(!i||typeof i!="object")return t;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:e,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:e,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:e,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(r,null,2)):t}function md(t,e){let n=[],s=new Set(e.map(o=>`/${o}`));for(let o of t){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: ${e.map(c=>"/"+c).join(", ")})`,autoFixed:!1})}return n}function bh(t,e,n){let s=new Set;if(e.colors?.primary&&s.add(e.colors.primary.toLowerCase()),e.colors?.secondary&&s.add(e.colors.secondary.toLowerCase()),e.colors?.accent&&s.add(e.colors.accent.toLowerCase()),s.size===0&&!e.fonts?.heading&&!e.fonts?.body)return;let o=(t.moduleHtml||"")+(t.moduleCss||"");if(s.size>0){let i=new Set;for(let a of o.matchAll(yh))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:t.moduleName,field:"moduleHtml",message:`Off-brand color ${a} (brand colors: ${[...s].join(", ")})`,autoFixed:!1});break}}if(e.fonts?.heading||e.fonts?.body){let i=[];e.fonts.heading&&i.push(e.fonts.heading.toLowerCase()),e.fonts.body&&i.push(e.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:t.moduleName,field:"moduleHtml",message:`Off-brand font "${a[1].trim()}" (brand fonts: ${i.join(", ")})`,autoFixed:!1});break}}}}function Sh(t,e){let n={...t},s=n.moduleHtml;n.moduleCss&&n.moduleCss.trim()&&(e.push({module:t.moduleName,field:"moduleCss",message:"Cleared moduleCss \u2014 email modules must use inline styles only",autoFixed:!0}),n.moduleCss=""),n.moduleJs&&n.moduleJs.trim()&&(e.push({module:t.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,""),e.push({module:t.moduleName,field:"moduleHtml",message:"Removed <style> blocks \u2014 email clients strip them",autoFixed:!0})),/display\s*:\s*flex/i.test(s)&&e.push({module:t.moduleName,field:"moduleHtml",message:"Contains display:flex \u2014 not supported in email clients",autoFixed:!1}),/display\s*:\s*grid/i.test(s)&&e.push({module:t.moduleName,field:"moduleHtml",message:"Contains display:grid \u2014 not supported in email clients",autoFixed:!1}),/var\s*\(/i.test(s)&&e.push({module:t.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,""),e.push({module:t.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,""),e.push({module:t.moduleName,field:"moduleHtml",message:"Removed CDN <link> tags \u2014 external resources not supported in email",autoFixed:!0})),n.moduleHtml=s,n}function xh(t,e){let n={...t},s=n.moduleHtml;return/\{\{[\s]*content\.body[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.body[\s]*\}\}/g,"{{ content.post_body }}"),e.push({module:t.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 }}"),e.push({module:t.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 }}"),e.push({module:t.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 }}"),e.push({module:t.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 }}"),e.push({module:t.moduleName,field:"moduleHtml",message:"Fixed content.image \u2192 content.featured_image",autoFixed:!0})),/\{%.*dnd_area.*%\}/g.test(s)&&e.push({module:t.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)&&e.push({module:t.moduleName,field:"moduleHtml",message:"publish_date used without |datetimeformat filter \u2014 dates may render as raw timestamps",autoFixed:!1}),n.moduleHtml=s,n}var uh,yh,br=R(()=>{"use strict";y();wo();de();uh=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);yh=/#[0-9a-fA-F]{6}\b/g});import{execSync as vh}from"child_process";async function pd(t,e,n,s,o,i,r,a){let l=Date.now(),c=i;if(xn(n)){let T={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(T)try{vh(`command -v ${T}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${T}" to be installed and on your PATH.`)}}let d=await Ec(t,e,n,s,o,r,a);if(d.intent==="question"&&d.answer){let N=Date.now()-l;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:e.modules.length,durationMs:N,answer:d.answer}),{modules:[...e.modules],moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:e.modules.length,modulesFailed:0,durationMs:N}}}if(d.intent==="create_site"&&d.pages&&d.pages.length>0)return wh(t,d,e,n,s,o,i,r,l);let u=null,m=e.sharedCss,g=e.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Hc(t,d,e,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 N of u.modules)f.push({name:N.name,description:N.description,contentBrief:N.contentBrief,layoutNotes:N.layoutNotes});else{for(let N of d.newModules)f.push({name:N.name,description:N.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let N of d.affectedModules){let T=e.modules.find(I=>I.moduleName===N);T&&f.push({name:N,description:`Modify existing module: ${N}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:T})}}let b=[],S=[];if(f.length>0){let N=await cs(t,f,m,e.themeName,n,s,o,c,r,d.guidesNeeded,e.brandAssets,d.contentType);for(let T of N)T.module?b.push(T.module):S.push(T.moduleName)}let x=null;if(b.length>0){x=zt(b,e.themeName,r,d.contentType,e.brandAssets?.brandKit);let N=x.filter(I=>I.issues.some(k=>k.field==="fieldsJson"&&k.message.includes("reset to empty"))).map(I=>I.module.moduleName);if(N.length>0){let I=N.map(k=>f.find(K=>K.name===k)).filter(k=>k!=null);if(I.length>0){E.info("pipeline",`Retrying ${I.length} module(s) with broken fieldsJson: ${I.map(K=>K.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${I.length} module(s) with invalid fields JSON...`});let k=await cs(t,I,m,e.themeName,n,s,o,c,r,d.guidesNeeded,e.brandAssets,d.contentType);for(let K of k)if(K.module){let oe=b.findIndex(it=>it.moduleName===K.moduleName);oe>=0&&(b[oe]=K.module)}x=zt(b,e.themeName,r,d.contentType,e.brandAssets?.brandKit)}}b=x.map(I=>I.module);let T=x.reduce((I,k)=>I+k.issues.length,0);if(T>0){let I=x.reduce((K,oe)=>K+oe.issues.filter(it=>it.autoFixed).length,0);E.info("pipeline",`Quality check: ${T} issues, ${I} auto-fixed`);let k=x.flatMap(K=>K.issues).map(K=>`${K.autoFixed?"\u2713":"\u26A0"} ${K.module}: ${K.message}`).join(`
2344
- `);r({type:"agent_decision",step:"quality_check",decision:`${T} issues found, ${I} auto-fixed
2345
- ${k}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let w=kh(e,d,b,u,a),P=Th(e,d,u,w);if(u?.moduleOrder?.length){let N=new Set(u.moduleOrder),T=w.filter(I=>!N.has(I.moduleName)).map(I=>I.moduleName);T.length>0&&r({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${T.length} module${T.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${T.join(", ")}`})}let F=Date.now()-l,H=b.length,L=d.unchangedModules.length,V=x?x.flatMap(N=>N.issues):[],B=Ah(d,H,L,S,F,u,V);return S.length>0?r({type:"pipeline_partial",succeeded:b.map(N=>N.moduleName),failed:S,durationMs:F}):r({type:"pipeline_complete",modulesGenerated:H,modulesUnchanged:L,durationMs:F,assistantMessage:B}),{modules:w,moduleOrder:P,sharedCss:m,sharedJs:g,assistantMessage:B,contentType:d.contentType,stats:{modulesGenerated:H,modulesUnchanged:L,modulesFailed:S.length,durationMs:F}}}async function wh(t,e,n,s,o,i,r,a,l){let c=e.pages,d=e.sharedModules||["site-header","site-footer"],u=await Bc(t,e,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 zc(t,e,n,m,s,o,i,a);a({type:"agent_step",step:"developing",label:`Generating modules for ${c.length} pages...`});let f=[];for(let k of h.sharedModules)f.push({...k});for(let k of h.pages)for(let K of k.modules)f.push({name:K.name,description:K.description,contentBrief:K.contentBrief,layoutNotes:K.layoutNotes});let b=c.map(k=>`- "${k.label}" \u2192 /${k.slug}`).join(`
2343
+ ${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 yh(e,t,n,s=!1,o=!1){let i=ft(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 pd(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 Sh(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(bh))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 xh(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 vh(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 mh,bh,br=R(()=>{"use strict";y();wo();de();mh=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);bh=/#[0-9a-fA-F]{6}\b/g});import{execSync as wh}from"child_process";async function gd(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(xn(n)){let T={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(T)try{wh(`command -v ${T}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${T}" to be installed and on your PATH.`)}}let d=await Ic(e,t,n,s,o,r,a);if(d.intent==="question"&&d.answer){let N=Date.now()-l;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:N,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:N}}}if(d.intent==="create_site"&&d.pages&&d.pages.length>0)return Ch(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 Gc(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 N of u.modules)f.push({name:N.name,description:N.description,contentBrief:N.contentBrief,layoutNotes:N.layoutNotes});else{for(let N of d.newModules)f.push({name:N.name,description:N.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let N of d.affectedModules){let T=t.modules.find(P=>P.moduleName===N);T&&f.push({name:N,description:`Modify existing module: ${N}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:T})}}let b=[],S=[];if(f.length>0){let N=await cs(e,f,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType);for(let T of N)T.module?b.push(T.module):S.push(T.moduleName)}let x=null;if(b.length>0){x=zt(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit);let N=x.filter(P=>P.issues.some(k=>k.field==="fieldsJson"&&k.message.includes("reset to empty"))).map(P=>P.module.moduleName);if(N.length>0){let P=N.map(k=>f.find(K=>K.name===k)).filter(k=>k!=null);if(P.length>0){M.info("pipeline",`Retrying ${P.length} module(s) with broken fieldsJson: ${P.map(K=>K.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${P.length} module(s) with invalid fields JSON...`});let k=await cs(e,P,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType);for(let K of k)if(K.module){let oe=b.findIndex(it=>it.moduleName===K.moduleName);oe>=0&&(b[oe]=K.module)}x=zt(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit)}}b=x.map(P=>P.module);let T=x.reduce((P,k)=>P+k.issues.length,0);if(T>0){let P=x.reduce((K,oe)=>K+oe.issues.filter(it=>it.autoFixed).length,0);M.info("pipeline",`Quality check: ${T} issues, ${P} auto-fixed`);let k=x.flatMap(K=>K.issues).map(K=>`${K.autoFixed?"\u2713":"\u26A0"} ${K.module}: ${K.message}`).join(`
2344
+ `);r({type:"agent_decision",step:"quality_check",decision:`${T} issues found, ${P} auto-fixed
2345
+ ${k}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let v=Th(t,d,b,u,a),I=Ah(t,d,u,v);if(u?.moduleOrder?.length){let N=new Set(u.moduleOrder),T=v.filter(P=>!N.has(P.moduleName)).map(P=>P.moduleName);T.length>0&&r({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${T.length} module${T.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${T.join(", ")}`})}let F=Date.now()-l,H=b.length,L=d.unchangedModules.length,V=x?x.flatMap(N=>N.issues):[],B=$h(d,H,L,S,F,u,V);return S.length>0?r({type:"pipeline_partial",succeeded:b.map(N=>N.moduleName),failed:S,durationMs:F}):r({type:"pipeline_complete",modulesGenerated:H,modulesUnchanged:L,durationMs:F,assistantMessage:B}),{modules:v,moduleOrder:I,sharedCss:m,sharedJs:g,assistantMessage:B,contentType:d.contentType,stats:{modulesGenerated:H,modulesUnchanged:L,modulesFailed:S.length,durationMs:F}}}async function Ch(e,t,n,s,o,i,r,a,l){let c=t.pages,d=t.sharedModules||["site-header","site-footer"],u=await Hc(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 Yc(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 k of h.sharedModules)f.push({...k});for(let k of h.pages)for(let K of k.modules)f.push({name:K.name,description:K.description,contentBrief:K.contentBrief,layoutNotes:K.layoutNotes});let b=c.map(k=>`- "${k.label}" \u2192 /${k.slug}`).join(`
2346
2346
  `);for(let k of f)(k.name.includes("header")||k.name.includes("nav"))&&(k.layoutNotes+=`
2347
2347
 
2348
2348
  ## Site Navigation
2349
2349
  This is a multi-page site. Include navigation links to all pages:
2350
2350
  ${b}
2351
- Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await cs(t,f,m,n.themeName,s,o,i,r,a,e.guidesNeeded,n.brandAssets,e.contentType),x=[],w=[];for(let k of S)k.module?x.push(k.module):w.push(k.moduleName);let P=x,F=[];if(x.length>0){let k=zt(x,n.themeName,a,e.contentType,n.brandAssets?.brandKit),K=k.filter(ie=>ie.issues.some(ye=>ye.field==="fieldsJson"&&ye.message.includes("reset to empty"))).map(ie=>ie.module.moduleName);if(K.length>0){let ie=K.map(ye=>f.find(le=>le.name===ye)).filter(ye=>ye!=null);if(ie.length>0){E.info("pipeline",`Retrying ${ie.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${ie.length} module(s) with invalid fields JSON...`});let ye=await cs(t,ie,m,n.themeName,s,o,i,r,a,e.guidesNeeded,n.brandAssets,e.contentType);for(let le of ye)if(le.module){let Je=x.findIndex(ws=>ws.moduleName===le.moduleName);Je>=0&&(x[Je]=le.module)}k=zt(x,n.themeName,a,e.contentType,n.brandAssets?.brandKit)}}P=k.map(ie=>ie.module),F=k.flatMap(ie=>ie.issues);let oe=md(P,c.map(ie=>ie.slug));F.push(...oe);let it=F.length;if(it>0){let ie=F.filter(ye=>ye.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${it} issues found, ${ie} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let H=new Map(P.map(k=>[k.moduleName,k])),L=h.sharedModules.map(k=>H.get(k.name)).filter(k=>!!k),V=new Map(c.map(k=>[k.id,k])),B=h.pages.map(k=>{let K=k.modules.map(le=>H.get(le.name)).filter(le=>!!le),oe=d.filter(le=>le.includes("header")||le.includes("nav")),it=d.filter(le=>le.includes("footer")),ie=[...oe,...k.moduleOrder,...it],ye=V.get(k.pageId);return{pageId:k.pageId,templateId:k.pageId,label:ye?.label||k.pageId,pageType:ye?.pageType||"website_page",modules:[...L,...K],moduleOrder:ie}}),N=Date.now()-l,T=Ch(c,x.length,w,N,h.narrative,F);return w.length>0?a({type:"pipeline_partial",succeeded:x.map(k=>k.moduleName),failed:w,durationMs:N}):a({type:"pipeline_complete",modulesGenerated:x.length,modulesUnchanged:0,durationMs:N,assistantMessage:T}),{modules:P,moduleOrder:P.map(k=>k.moduleName),sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{modulesGenerated:x.length,modulesUnchanged:0,modulesFailed:w.length,durationMs:N},multiPage:{pages:B,sharedModules:L,sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{pagesGenerated:c.length,modulesGenerated:x.length,modulesFailed:w.length,durationMs:N}}}}function Ch(t,e,n,s,o,i){let r=Math.round(s/1e3),a=[];a.push(`Created ${t.length}-page site with ${e} modules in ${r}s.`),a.push(`
2351
+ Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await cs(e,f,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),x=[],v=[];for(let k of S)k.module?x.push(k.module):v.push(k.moduleName);let I=x,F=[];if(x.length>0){let k=zt(x,n.themeName,a,t.contentType,n.brandAssets?.brandKit),K=k.filter(ie=>ie.issues.some(ye=>ye.field==="fieldsJson"&&ye.message.includes("reset to empty"))).map(ie=>ie.module.moduleName);if(K.length>0){let ie=K.map(ye=>f.find(le=>le.name===ye)).filter(ye=>ye!=null);if(ie.length>0){M.info("pipeline",`Retrying ${ie.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${ie.length} module(s) with invalid fields JSON...`});let ye=await cs(e,ie,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType);for(let le of ye)if(le.module){let Je=x.findIndex(ws=>ws.moduleName===le.moduleName);Je>=0&&(x[Je]=le.module)}k=zt(x,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}I=k.map(ie=>ie.module),F=k.flatMap(ie=>ie.issues);let oe=pd(I,c.map(ie=>ie.slug));F.push(...oe);let it=F.length;if(it>0){let ie=F.filter(ye=>ye.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${it} issues found, ${ie} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let H=new Map(I.map(k=>[k.moduleName,k])),L=h.sharedModules.map(k=>H.get(k.name)).filter(k=>!!k),V=new Map(c.map(k=>[k.id,k])),B=h.pages.map(k=>{let K=k.modules.map(le=>H.get(le.name)).filter(le=>!!le),oe=d.filter(le=>le.includes("header")||le.includes("nav")),it=d.filter(le=>le.includes("footer")),ie=[...oe,...k.moduleOrder,...it],ye=V.get(k.pageId);return{pageId:k.pageId,templateId:k.pageId,label:ye?.label||k.pageId,pageType:ye?.pageType||"website_page",modules:[...L,...K],moduleOrder:ie}}),N=Date.now()-l,T=kh(c,x.length,v,N,h.narrative,F);return v.length>0?a({type:"pipeline_partial",succeeded:x.map(k=>k.moduleName),failed:v,durationMs:N}):a({type:"pipeline_complete",modulesGenerated:x.length,modulesUnchanged:0,durationMs:N,assistantMessage:T}),{modules:I,moduleOrder:I.map(k=>k.moduleName),sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{modulesGenerated:x.length,modulesUnchanged:0,modulesFailed:v.length,durationMs:N},multiPage:{pages:B,sharedModules:L,sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{pagesGenerated:c.length,modulesGenerated:x.length,modulesFailed:v.length,durationMs:N}}}}function kh(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(`
2352
2352
 
2353
- **Pages:** ${t.map(d=>d.label).join(", ")}`),o&&a.push(`
2353
+ **Pages:** ${e.map(d=>d.label).join(", ")}`),o&&a.push(`
2354
2354
 
2355
2355
  ${o}`),n.length>0&&a.push(`
2356
2356
 
2357
2357
  **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(`
2358
2358
 
2359
2359
  ${d.join(`
2360
- `)}`)}return a.join("")}function kh(t,e,n,s,o){let i=[],r=new Set;for(let a of n)i.push(a),r.add(a.moduleName);for(let a of e.unchangedModules){if(r.has(a))continue;let l=t.modules.find(c=>c.moduleName===a);l&&(i.push(l),r.add(a))}if(e.reuseModules)for(let a of e.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 Th(t,e,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(e.intent==="create")return s.map(a=>a.moduleName);let o=[...t.moduleOrder],i=[...e.newModules.map(a=>({name:a.name,position:a.position})),...(e.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 Ah(t,e,n,s,o,i,r){let a=Math.round(o/1e3),l=[];if(t.intent==="create")l.push(`Created ${e} module${e===1?"":"s"} in ${a}s.`);else if(t.intent==="modify"||t.intent==="style_change")l.push(`Updated ${e} module${e===1?"":"s"} in ${a}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(t.intent==="add"){let u=t.newModules.map(m=>m.name).join(", ");l.push(`Added ${u} in ${a}s.`)}else t.intent==="remove"?l.push(`Removed modules in ${a}s.`):t.intent==="rearrange"&&l.push(`Rearranged modules in ${a}s.`);i?.narrative&&l.push(`
2360
+ `)}`)}return a.join("")}function Th(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 Ah(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),M.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 $h(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(`
2361
2361
 
2362
2362
  ${i.narrative}`),s.length>0&&l.push(`
2363
2363
 
2364
2364
  **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(`
2365
2365
 
2366
2366
  ${u.join(`
2367
- `)}`)}return l.join("")}var gd=R(()=>{"use strict";y();nt();Ic();Uc();Yc();cd();br();de();nt()});var Sd={};Be(Sd,{runFigmaConversion:()=>$h});import{basename as yd}from"path";async function $h(t,e,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}=_h(t.designTokens,e);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 ${t.designTokens.colors.length} colors, ${t.designTokens.typography.length} typography styles`});let{specs:m,moduleOrder:g}=Eh(t.sections,t.assets,e);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=as(e,d,["hubspot_rules","conversion"],a),b=h?_o(e,d,["hubspot_rules","conversion"],a):void 0,S=$o(i),x=m.length,w=m.map((k,K)=>{let oe=t.sections[K];return S(async()=>{r({type:"module_progress",module:k.name,status:"generating",current:K+1,total:x});let it=Rh(oe,k,t.assets,e,l!==!1),ie="";for(let ye=0;ye<2;ye++)try{ye>0&&(E.warn("figma-pipeline",`${k.name}: retrying (attempt ${ye+1})`),r({type:"module_progress",module:k.name,status:"retrying",current:K+1,total:x}));let le=await _e(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:it}],structuredOutput:{schema:ls,name:"module_output"},maxTokens:16e3});if(le.type!=="structured")throw new Error("No structured output returned");let Je=le.data,ws={moduleName:k.name,fieldsJson:typeof Je.fieldsJson=="string"?Je.fieldsJson:JSON.stringify(Je.fieldsJson,null,2),metaJson:typeof Je.metaJson=="string"?Je.metaJson:JSON.stringify(Je.metaJson,null,2),moduleHtml:String(Je.moduleHtml||""),moduleCss:String(Je.moduleCss||""),moduleJs:Je.moduleJs?String(Je.moduleJs):void 0};return r({type:"module_progress",module:k.name,status:"complete",current:K+1,total:x,moduleFiles:ws}),{moduleName:k.name,module:ws}}catch(le){ie=le instanceof Error?le.message:String(le),E.error("figma-pipeline",`Failed: ${k.name} (attempt ${ye+1}): ${ie}`)}return r({type:"module_progress",module:k.name,status:"failed",current:K+1,total:x}),{moduleName:k.name,error:ie}})}),F=(await Promise.allSettled(w)).map(k=>k.status==="fulfilled"?k.value:{moduleName:"unknown",error:String(k.reason)}),H=F.filter(k=>k.module).map(k=>k.module),L=F.filter(k=>k.error).map(k=>k.moduleName),B=zt(H,e,r).map(k=>k.module),N=Date.now()-c,T=Math.round(N/1e3),I=`Imported ${B.length} modules from Figma design "${t.fileName}" in ${T}s.`;return L.length>0?r({type:"pipeline_partial",succeeded:B.map(k=>k.moduleName),failed:L,durationMs:N}):r({type:"pipeline_complete",modulesGenerated:B.length,modulesUnchanged:0,durationMs:N,assistantMessage:I}),{modules:B,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:I,stats:{modulesGenerated:B.length,modulesUnchanged:0,modulesFailed:L.length,durationMs:N}}}function Mo(t){let e=parseInt(t.slice(1,3),16)/255,n=parseInt(t.slice(3,5),16)/255,s=parseInt(t.slice(5,7),16)/255,o=Math.max(e,n,s),i=Math.min(e,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===e?c=((n-s)/a+(n<s?6:0))/6:o===n?c=((s-e)/a+2)/6:c=((e-n)/a+4)/6,{h:c*360,s:l,l:r}}function _h(t,e){let n=[],s=e,o=[...t.colors].sort((T,I)=>I.occurrences-T.occurrences),i=o.filter(T=>T.usage==="background"||T.usage==="fill"),r=o.filter(T=>T.usage==="text"),a=i[0]||o[0],l=a?Mo(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(T=>Mo(T.hex).l>.7):o.find(T=>Mo(T.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(T=>!d.has(T.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(T=>!d.has(T.hex)).slice(0,6).forEach((T,I)=>n.push(` --${s}-color-${I+1}: ${T.hex}`)),a){let T=Mo(a.hex).l;n.push(` --${s}-color-surface: ${l?fd(a.hex,.05):hd(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?fd(a.hex,.15):hd(a.hex,.12)}`)}let g=t.typography.filter(T=>T.role==="heading"||T.role==="subheading"),h=t.typography.filter(T=>T.role==="body"||T.role==="label"||T.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((T,I)=>I.fontSize-T.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((T,I)=>I.occurrences-T.occurrences)[0];x&&n.push(` --${s}-size-body: ${x.fontSize}px`);let w=[...new Set(t.spacing.map(T=>T.value))].sort((T,I)=>T-I),P=["xs","sm","md","lg","xl","2xl","section"];w.slice(0,P.length).forEach((T,I)=>{n.push(` --${s}-space-${P[I]}: ${T}px`)});let F=t.effects.filter(T=>T.type==="shadow"),H=t.effects.filter(T=>T.type==="radius");F[0]&&n.push(` --${s}-shadow: ${F[0].cssValue}`),H.sort((T,I)=>parseFloat(T.cssValue)-parseFloat(I.cssValue)),H[0]&&n.push(` --${s}-radius: ${H[0].cssValue}`),H[1]&&n.push(` --${s}-radius-lg: ${H[1].cssValue}`);let L=`:root {
2367
+ `)}`)}return l.join("")}var fd=R(()=>{"use strict";y();nt();Pc();Uc();qc();dd();br();de();nt()});var xd={};Be(xd,{runFigmaConversion:()=>_h});import{basename as bd}from"path";async function _h(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}=Eh(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}=Ih(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=as(t,d,["hubspot_rules","conversion"],a),b=h?_o(t,d,["hubspot_rules","conversion"],a):void 0,S=$o(i),x=m.length,v=m.map((k,K)=>{let oe=e.sections[K];return S(async()=>{r({type:"module_progress",module:k.name,status:"generating",current:K+1,total:x});let it=Nh(oe,k,e.assets,t,l!==!1),ie="";for(let ye=0;ye<2;ye++)try{ye>0&&(M.warn("figma-pipeline",`${k.name}: retrying (attempt ${ye+1})`),r({type:"module_progress",module:k.name,status:"retrying",current:K+1,total:x}));let le=await _e(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:it}],structuredOutput:{schema:ls,name:"module_output"},maxTokens:16e3});if(le.type!=="structured")throw new Error("No structured output returned");let Je=le.data,ws={moduleName:k.name,fieldsJson:typeof Je.fieldsJson=="string"?Je.fieldsJson:JSON.stringify(Je.fieldsJson,null,2),metaJson:typeof Je.metaJson=="string"?Je.metaJson:JSON.stringify(Je.metaJson,null,2),moduleHtml:String(Je.moduleHtml||""),moduleCss:String(Je.moduleCss||""),moduleJs:Je.moduleJs?String(Je.moduleJs):void 0};return r({type:"module_progress",module:k.name,status:"complete",current:K+1,total:x,moduleFiles:ws}),{moduleName:k.name,module:ws}}catch(le){ie=le instanceof Error?le.message:String(le),M.error("figma-pipeline",`Failed: ${k.name} (attempt ${ye+1}): ${ie}`)}return r({type:"module_progress",module:k.name,status:"failed",current:K+1,total:x}),{moduleName:k.name,error:ie}})}),F=(await Promise.allSettled(v)).map(k=>k.status==="fulfilled"?k.value:{moduleName:"unknown",error:String(k.reason)}),H=F.filter(k=>k.module).map(k=>k.module),L=F.filter(k=>k.error).map(k=>k.moduleName),B=zt(H,t,r).map(k=>k.module),N=Date.now()-c,T=Math.round(N/1e3),P=`Imported ${B.length} modules from Figma design "${e.fileName}" in ${T}s.`;return L.length>0?r({type:"pipeline_partial",succeeded:B.map(k=>k.moduleName),failed:L,durationMs:N}):r({type:"pipeline_complete",modulesGenerated:B.length,modulesUnchanged:0,durationMs:N,assistantMessage:P}),{modules:B,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:P,stats:{modulesGenerated:B.length,modulesUnchanged:0,modulesFailed:L.length,durationMs:N}}}function Eo(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 Eh(e,t){let n=[],s=t,o=[...e.colors].sort((T,P)=>P.occurrences-T.occurrences),i=o.filter(T=>T.usage==="background"||T.usage==="fill"),r=o.filter(T=>T.usage==="text"),a=i[0]||o[0],l=a?Eo(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(T=>Eo(T.hex).l>.7):o.find(T=>Eo(T.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(T=>!d.has(T.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(T=>!d.has(T.hex)).slice(0,6).forEach((T,P)=>n.push(` --${s}-color-${P+1}: ${T.hex}`)),a){let T=Eo(a.hex).l;n.push(` --${s}-color-surface: ${l?hd(a.hex,.05):yd(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?hd(a.hex,.15):yd(a.hex,.12)}`)}let g=e.typography.filter(T=>T.role==="heading"||T.role==="subheading"),h=e.typography.filter(T=>T.role==="body"||T.role==="label"||T.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((T,P)=>P.fontSize-T.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((T,P)=>P.occurrences-T.occurrences)[0];x&&n.push(` --${s}-size-body: ${x.fontSize}px`);let v=[...new Set(e.spacing.map(T=>T.value))].sort((T,P)=>T-P),I=["xs","sm","md","lg","xl","2xl","section"];v.slice(0,I.length).forEach((T,P)=>{n.push(` --${s}-space-${I[P]}: ${T}px`)});let F=e.effects.filter(T=>T.type==="shadow"),H=e.effects.filter(T=>T.type==="radius");F[0]&&n.push(` --${s}-shadow: ${F[0].cssValue}`),H.sort((T,P)=>parseFloat(T.cssValue)-parseFloat(P.cssValue)),H[0]&&n.push(` --${s}-radius: ${H[0].cssValue}`),H[1]&&n.push(` --${s}-radius-lg: ${H[1].cssValue}`);let L=`:root {
2368
2368
  ${n.join(`;
2369
2369
  `)};
2370
2370
  }`,V=`
@@ -2462,11 +2462,11 @@ body {
2462
2462
  });
2463
2463
  }, { threshold: 0.1 });
2464
2464
  document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
2465
- })();`}}function fd(t,e){return bd(t,e)}function hd(t,e){return bd(t,-e)}function bd(t,e){let n=parseInt(t.slice(1,3),16),s=parseInt(t.slice(3,5),16),o=parseInt(t.slice(5,7),16);return n=Math.min(255,Math.max(0,Math.round(n+255*e))),s=Math.min(255,Math.max(0,Math.round(s+255*e))),o=Math.min(255,Math.max(0,Math.round(o+255*e))),`#${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${o.toString(16).padStart(2,"0")}`}function Mh(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Eh(t,e,n){let s=new Set,o=[];for(let i of t){let r=Mh(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=Ih(i.textContent),l=Ph(i,e,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 Ih(t){let e={};for(let o of t){let i=o.role;e[i]||(e[i]=[]),e[i].push(o.text)}let n=[],s=["headline","subheadline","body","cta","label","caption"];for(let o of s)if(e[o])for(let i of e[o])n.push(`**${o}** (use as field default): "${i}"`);return n.join(`
2466
- `)}function Ph(t,e,n){let s=[];if(s.push(`Dimensions: ${t.width}x${t.height}px`),t.backgroundColor&&s.push(`Background: ${t.backgroundColor}`),t.layoutMode&&s.push(`Layout: ${t.layoutMode}`),t.itemSpacing&&s.push(`Gap: ${t.itemSpacing}px`),(t.paddingTop||t.paddingRight||t.paddingBottom||t.paddingLeft)&&s.push(`Padding: ${t.paddingTop||0}px ${t.paddingRight||0}px ${t.paddingBottom||0}px ${t.paddingLeft||0}px`),t.children.length>0){s.push(`
2467
- Children (${t.children.length}):`);for(let o of t.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(e.length>0){s.push(`
2468
- Available image assets:`);for(let o of e){let i=yd(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2469
- `)}function Rh(t,e,n,s,o){let i=[];if(i.push(`## Figma Design Translation
2465
+ })();`}}function hd(e,t){return Sd(e,t)}function yd(e,t){return Sd(e,-t)}function Sd(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 Mh(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Ih(e,t,n){let s=new Set,o=[];for(let i of e){let r=Mh(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=Ph(i.textContent),l=Rh(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 Ph(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(`
2466
+ `)}function Rh(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(`
2467
+ 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(`
2468
+ Available image assets:`);for(let o of t){let i=bd(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2469
+ `)}function Nh(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
2470
2470
 
2471
2471
  TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
2472
2472
  - Use the EXACT text content from the design as field default values
@@ -2486,17 +2486,17 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
2486
2486
  - Hide purely decorative elements if they break mobile layout
2487
2487
  - Add a \`@media (max-width: 1023px)\` block for tablet if the layout has 3+ columns
2488
2488
 
2489
- ## Section: "${t.name}" (${t.width}x${t.height}px)`),t.backgroundColor&&i.push(`Background: ${t.backgroundColor}`),(t.layoutMode||t.itemSpacing||t.paddingTop)&&(i.push(`
2490
- ### Layout`),t.layoutMode&&i.push(`Direction: ${t.layoutMode}`),t.itemSpacing&&i.push(`Gap: ${t.itemSpacing}px`),(t.paddingTop||t.paddingRight||t.paddingBottom||t.paddingLeft)&&i.push(`Padding: ${t.paddingTop||0}px ${t.paddingRight||0}px ${t.paddingBottom||0}px ${t.paddingLeft||0}px`)),t.textContent.length>0){i.push(`
2491
- ### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let r of t.textContent)i.push(`- **${r.role}** (${r.fontSize}px, weight ${r.fontWeight}): "${r.text}"`)}if(t.children.length>0){i.push(`
2492
- ### Structure (${t.children.length} children)`);for(let r of t.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+=`
2489
+ ## Section: "${e.name}" (${e.width}x${e.height}px)`),e.backgroundColor&&i.push(`Background: ${e.backgroundColor}`),(e.layoutMode||e.itemSpacing||e.paddingTop)&&(i.push(`
2490
+ ### Layout`),e.layoutMode&&i.push(`Direction: ${e.layoutMode}`),e.itemSpacing&&i.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&i.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`)),e.textContent.length>0){i.push(`
2491
+ ### 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(`
2492
+ ### 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+=`
2493
2493
  text: "${r.characters.slice(0,100)}"`),i.push(a)}}if(n.length>0)if(o){i.push(`
2494
- ### 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=yd(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2494
+ ### 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=bd(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2495
2495
  ### 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(`
2496
2496
  ## Module Specification
2497
- - **Name**: ${e.name}
2498
- - **Description**: ${e.description}`),i.join(`
2499
- `)}var xd=R(()=>{"use strict";y();nt();gr();fr();br();de()});var vd={};Be(vd,{buildPlanModePrompt:()=>Nh});function Nh(t,e,n,s,o){let i=Oh(o,!!e?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${t}".
2497
+ - **Name**: ${t.name}
2498
+ - **Description**: ${t.description}`),i.join(`
2499
+ `)}var vd=R(()=>{"use strict";y();nt();gr();fr();br();de()});var wd={};Be(wd,{buildPlanModePrompt:()=>Oh});function Oh(e,t,n,s,o){let i=Fh(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
2500
2500
 
2501
2501
  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.
2502
2502
 
@@ -2560,20 +2560,20 @@ Drive toward filling these gaps in priority order:
2560
2560
  4. **Sections / modules** \u2014 high-level page structure (hero, features, testimonials, pricing, FAQ, footer, etc.)
2561
2561
  5. **Content** \u2014 actual copy, value props, social proof, key messages
2562
2562
  6. **Brand voice and visual style** \u2014 formal/casual, palette preferences, reference sites
2563
- 7. **Constraints** \u2014 must-haves, must-avoids, integrations needed`),e?.styleguide&&r.push(`## Available styleguide
2563
+ 7. **Constraints** \u2014 must-haves, must-avoids, integrations needed`),t?.styleguide&&r.push(`## Available styleguide
2564
2564
 
2565
2565
  The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
2566
2566
 
2567
2567
  \`\`\`
2568
- ${Sr(e.styleguide,1500)}
2569
- \`\`\``),e?.brandvoice&&r.push(`## Available brand voice
2568
+ ${Sr(t.styleguide,1500)}
2569
+ \`\`\``),t?.brandvoice&&r.push(`## Available brand voice
2570
2570
 
2571
2571
  \`\`\`
2572
- ${Sr(e.brandvoice,1e3)}
2573
- \`\`\``),e?.themeContext&&r.push(`## Theme context
2572
+ ${Sr(t.brandvoice,1e3)}
2573
+ \`\`\``),t?.themeContext&&r.push(`## Theme context
2574
2574
 
2575
2575
  \`\`\`
2576
- ${Sr(e.themeContext,1e3)}
2576
+ ${Sr(t.themeContext,1e3)}
2577
2577
  \`\`\``),n.length>0&&r.push(`## Existing modules in this theme
2578
2578
 
2579
2579
  These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
@@ -2584,23 +2584,23 @@ ${n.map(a=>`- ${a}`).join(`
2584
2584
  These modules exist in other templates and could be reused here. Reference them by name in the plan if appropriate.
2585
2585
 
2586
2586
  ${s.map(a=>`- **${a.name}** (used in: ${a.usedIn.join(", ")})`).join(`
2587
- `)}`),e?.plan&&r.push(`## Current plan (continue refining)
2587
+ `)}`),t?.plan&&r.push(`## Current plan (continue refining)
2588
2588
 
2589
2589
  The plan in progress so far. Build on it \u2014 preserve what's there, only update sections that are changing based on the user's latest message.
2590
2590
 
2591
2591
  \`\`\`markdown
2592
- ${e.plan}
2592
+ ${t.plan}
2593
2593
  \`\`\``),r.push(`## Phase guidance for this turn
2594
2594
 
2595
2595
  ${i}`),r.join(`
2596
2596
 
2597
- `)}function Oh(t,e){return t===0&&!e?"**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.":t===0&&e?`**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:
2597
+ `)}function Fh(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:
2598
2598
  - Briefly acknowledge the template and that you'll work from this structure (1\u20132 sentences in chat).
2599
2599
  - 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.
2600
2600
  - 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.
2601
2601
  - 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.
2602
- - Use \`vibespot-choices\` chips when one of your questions is multiple-choice (e.g. "Primary CTA?", "Cuisine?").`:t<=2&&!e?"**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 Sr(t,e){return t.length<=e?t:t.slice(0,e)+`
2603
- ... [truncated]`}var wd=R(()=>{"use strict";y()});var $r={};Be($r,{applyPipelineResult:()=>qt,handleAgenticGenerate:()=>Eo,handleFigmaImport:()=>us,handleGenerate:()=>Fh,handleGenerateStream:()=>ds,handlePlanModeStream:()=>kr,isGenerating:()=>Ft,isPlanModeActive:()=>Tr,resolveAgenticEngine:()=>vn,setParseWarningCallback:()=>wr,shouldUseAgenticMode:()=>Ar});import{execSync as xr}from"child_process";function wr(t){vr=t}function Ft(){return $t!==null}function Yt(t){if($t){let e=C();if(!e||e.id!==$t){E.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}tt("assistant",t),rc(t,vr||void 0),D()}async function ds(t,e,n,s){let o=C();if(!o)throw new Error("No active session");$t=o.id;let r=s?.length?Co(s):void 0;try{let a=O(),l=a.aiEngine||Cr();switch(l){case"anthropic-api":case"api":{let c=Oe("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await gc(t,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",e,n,Yt,r);break}case"claude-oauth":{await fc(t,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",e,n,Yt,r);break}case"openai-api":{let c=Oe("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await hc(t,c,o.themeName,a.openaiApiModel||"gpt-4o",e,n,Yt,r);break}case"gemini-api":{let c=Oe("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await yc(t,c,o.themeName,e,n,Yt,r);break}case"claude-code":await bc(t,o.themeName,e,n,Yt,r);break;case"gemini-cli":await tr("gemini",t,o.themeName,e,n,Yt,r);break;case"codex-cli":await tr("codex",t,o.themeName,e,n,Yt,r);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{$t=null,vr=null}}function Cr(){let t=O();if(lt())return"claude-oauth";if(t.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(t.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(t.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return xr("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return xr("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return xr("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Fh(t){let e="";return await ds(t,n=>{e+=n}),e}function Cd(){let t=C(),e=Ce(),n=e?[...e.modules]:[...t.modules],s=e?[...e.moduleOrder]:[...t.moduleOrder],o={modules:n,moduleOrder:s,sharedCss:e?.sharedCss||t.sharedCss,sharedJs:e?.sharedJs||t.sharedJs,messages:[...t.messages],themeName:t.themeName,themePath:t.themePath,contentMode:e?.contentMode,brandAssets:t.brandAssets?{...t.brandAssets}:void 0};return t.templates.length>1&&(o.activePageLabel=e?.label,o.sitePages=t.templates.map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))),o}function vn(t){let e=t.aiEngine||Cr();if(!rs(e))throw new Error("Agentic pipeline is not available for this engine.");if(xn(e)){let o="";return e==="claude-code"&&(o=t.claudeCodeModel||""),{engine:e,apiKey:"",model:o}}let n;if(e==="claude-oauth"){if(!lt())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=Oe(e,t);if(!n)throw new Error(`API key not configured for ${e}. Open Settings to add one.`);let s;switch(e){case"anthropic-api":case"claude-oauth":s=t.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=t.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=t.geminiApiModel||"gemini-2.5-pro";break;case"claude-code":s=t.claudeCodeModel||"";break;case"codex-cli":s=t.codexCliModel||"";break;case"gemini-cli":s=t.geminiCliModel||"";break;default:s=""}return{engine:e,apiKey:n,model:s}}async function Eo(t,e,n){let s=C();if(!s)throw new Error("No active session");let o=s.id;$t=o;try{let i=O(),{engine:r,apiKey:a,model:l}=vn(i),c=i.agenticConcurrency||20,d=Cd(),u=d.brandAssets?.plan,m=t;u&&u.trim()&&(m=`## Approved plan
2602
+ - 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 Sr(e,t){return e.length<=t?e:e.slice(0,t)+`
2603
+ ... [truncated]`}var Cd=R(()=>{"use strict";y()});var $r={};Be($r,{applyPipelineResult:()=>qt,handleAgenticGenerate:()=>Mo,handleFigmaImport:()=>us,handleGenerate:()=>jh,handleGenerateStream:()=>ds,handlePlanModeStream:()=>kr,isGenerating:()=>Ft,isPlanModeActive:()=>Tr,resolveAgenticEngine:()=>vn,setParseWarningCallback:()=>wr,shouldUseAgenticMode:()=>Ar});import{execSync as xr}from"child_process";function wr(e){vr=e}function Ft(){return $t!==null}function Yt(e){if($t){let t=C();if(!t||t.id!==$t){M.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}tt("assistant",e),rc(e,vr||void 0),D()}async function ds(e,t,n,s){let o=C();if(!o)throw new Error("No active session");$t=o.id;let r=s?.length?Co(s):void 0;try{let a=O(),l=a.aiEngine||Cr();switch(l){case"anthropic-api":case"api":{let c=Oe("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await gc(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,Yt,r);break}case"claude-oauth":{await fc(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,Yt,r);break}case"openai-api":{let c=Oe("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await hc(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,Yt,r);break}case"gemini-api":{let c=Oe("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await yc(e,c,o.themeName,t,n,Yt,r);break}case"claude-code":await bc(e,o.themeName,t,n,Yt,r);break;case"gemini-cli":await tr("gemini",e,o.themeName,t,n,Yt,r);break;case"codex-cli":await tr("codex",e,o.themeName,t,n,Yt,r);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{$t=null,vr=null}}function Cr(){let e=O();if(lt())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 xr("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return xr("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return xr("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function jh(e){let t="";return await ds(e,n=>{t+=n}),t}function kd(){let e=C(),t=Ce(),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 vn(e){let t=e.aiEngine||Cr();if(!rs(t))throw new Error("Agentic pipeline is not available for this engine.");if(xn(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!lt())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=Oe(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":s=e.langdockApiModel||"claude-sonnet-4-20250514";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 Mo(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=s.id;$t=o;try{let i=O(),{engine:r,apiKey:a,model:l}=vn(i),c=i.agenticConcurrency||20,d=kd(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
2604
2604
 
2605
2605
  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.
2606
2606
 
@@ -2610,30 +2610,30 @@ ${u}
2610
2610
 
2611
2611
  ## User message
2612
2612
 
2613
- ${t}`);let g=n?.length?Co(n):void 0;if(g?.length)for(let w of g)w.type==="document"&&w.extractedText&&(m+=`
2613
+ ${e}`);let g=n?.length?Co(n):void 0;if(g?.length)for(let v of g)v.type==="document"&&v.extractedText&&(m+=`
2614
2614
 
2615
2615
  ---
2616
- [Attached document: ${w.originalName}]
2617
- ${w.extractedText}`),w.type==="image"&&w.usage==="asset"&&w.assetPath&&(m+=`
2616
+ [Attached document: ${v.originalName}]
2617
+ ${v.extractedText}`),v.type==="image"&&v.usage==="asset"&&v.assetPath&&(m+=`
2618
2618
 
2619
- [Uploaded image: ${w.originalName} \u2192 available as get_asset_url("${w.assetPath}")]`);let h=At(),f=new Set(d.modules.map(w=>w.moduleName)),b=h.filter(w=>!f.has(w.module.moduleName)).map(w=>({name:w.module.moduleName,usedIn:w.usedIn})),S=await pd(m,d,r,a,l,c,e,b),x=C();if(!x||x.id!==o)throw E.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return S}finally{$t=null}}async function us(t,e,n,s){let o=C();if(!o)throw new Error("No active session");let i=o.id;$t=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(xd(),Sd)),a=O(),{engine:l,apiKey:c,model:d}=vn(a),u=a.agenticConcurrency||20,m=Cd(),g=await r(t,e,l,c,d,u,n,m.brandAssets,s?.useAssets),h=C();if(!h||h.id!==i)throw E.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{$t=null}}function qt(t,e){let n=t.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"});Al({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(De({modules:t.modules,sharedCss:t.sharedCss,sharedJs:t.sharedJs}),Rt(t.moduleOrder),t.contentType==="email"){let o=Ce();o&&!o.contentMode&&(o.contentMode="email")}tt("assistant",t.assistantMessage,e),D()}async function kr(t,e,n){let s=C();if(!s)throw new Error("No active session");let o=O(),{engine:i,apiKey:r,model:a}=vn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(wd(),vd)),Promise.resolve().then(()=>(nt(),Ac))]),d=s.messages.filter(w=>w.role==="assistant").length,u=s.modules.map(w=>w.moduleName),m=At(),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?Co(n):void 0,S=t;if(b?.length)for(let w of b)w.type==="document"&&w.extractedText&&(S+=`
2619
+ [Uploaded image: ${v.originalName} \u2192 available as get_asset_url("${v.assetPath}")]`);let h=At(),f=new Set(d.modules.map(v=>v.moduleName)),b=h.filter(v=>!f.has(v.module.moduleName)).map(v=>({name:v.module.moduleName,usedIn:v.usedIn})),S=await gd(m,d,r,a,l,c,t,b),x=C();if(!x||x.id!==o)throw M.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return S}finally{$t=null}}async function us(e,t,n,s){let o=C();if(!o)throw new Error("No active session");let i=o.id;$t=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(vd(),xd)),a=O(),{engine:l,apiKey:c,model:d}=vn(a),u=a.agenticConcurrency||20,m=kd(),g=await r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets),h=C();if(!h||h.id!==i)throw M.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{$t=null}}function qt(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"});Al({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(De({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Rt(e.moduleOrder),e.contentType==="email"){let o=Ce();o&&!o.contentMode&&(o.contentMode="email")}tt("assistant",e.assistantMessage,t),D()}async function kr(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=O(),{engine:i,apiKey:r,model:a}=vn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(Cd(),wd)),Promise.resolve().then(()=>(nt(),$c))]),d=s.messages.filter(v=>v.role==="assistant").length,u=s.modules.map(v=>v.moduleName),m=At(),g=new Set(u),h=m.filter(v=>!g.has(v.module.moduleName)).map(v=>({name:v.module.moduleName,usedIn:v.usedIn})),f=l(s.themeName,s.brandAssets,u,h,d),b=n?.length?Co(n):void 0,S=e;if(b?.length)for(let v of b)v.type==="document"&&v.extractedText&&(S+=`
2620
2620
 
2621
2621
  ---
2622
- [Attached document: ${w.originalName}]
2623
- ${w.extractedText}`);let x=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:e,enableWebSearch:!!o.webSearch});return x.type==="text"?x.text:JSON.stringify(x.data)}function Tr(){return!!O().planMode}function Ar(){let t=O(),e=t.aiEngine||Cr();return rs(e)?t.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:t.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var vr,$t,wn=R(()=>{"use strict";y();Q();we();wo();de();nr();xt();ir();gd();vr=null;$t=null});import{readFileSync as jh,readdirSync as Dh,existsSync as Lh}from"fs";import{dirname as Jh,join as Io}from"path";import{fileURLToPath as Bh}from"url";function Uh(t){let e=t.match(Hh);if(!e)return null;let[,n,s]=e,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 Gh(t){let e=Uh(t);if(!e)return null;let{fields:n,body:s}=e,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()+`
2624
- `}}function Wh(){let t=[Io(kd,"../../assets/plan-templates"),Io(kd,"../assets/plan-templates"),Io(process.cwd(),"assets/plan-templates")];for(let e of t)if(Lh(e))return e;return null}function Td(){if(jt)return jt;let t=Wh();if(!t)return jt=[],jt;let e=[],n=[];try{n=Dh(t)}catch{return jt=[],jt}for(let s of n)if(s.endsWith(".md"))try{let o=jh(Io(t,s),"utf-8"),i=Gh(o);i&&e.push(i)}catch{}return e.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),jt=e,jt}function Ad(t){return Td().find(e=>e.id===t)??null}function $d(){return Td().map(({id:t,label:e,description:n,icon:s,order:o,contentType:i})=>({id:t,label:e,description:n,icon:s,order:o,contentType:i}))}var kd,Hh,jt,_d=R(()=>{"use strict";y();kd=Jh(Bh(import.meta.url)),Hh=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;jt=null});import{existsSync as Md,mkdirSync as Kh,writeFileSync as Vh,rmSync as zh}from"fs";import{join as Ed}from"path";function Id(t){return Ed(t,".vibespot",Yh)}function Po(t){let e=C();if(!e)return null;e.brandAssets||(e.brandAssets={}),e.brandAssets.plan=t;let n=Ce();n&&(n.plan=t);try{let s=Ed(e.themePath,".vibespot");Md(s)||Kh(s,{recursive:!0}),Vh(Id(e.themePath),t,"utf-8")}catch(s){E.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return D(),t}function _r(){let t=C();if(!t)return;t.brandAssets&&delete t.brandAssets.plan;let e=Ce();e&&delete e.plan;try{let n=Id(t.themePath);Md(n)&&zh(n)}catch(n){E.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}D()}function Pd(t,e){Ve(t,e,n=>{if(!C()){p(e,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(e,400,{error:"Plan content cannot be empty"});return}Po(o),p(e,200,{ok:!0,plan:o})})}function Rd(t,e){Ve(t,e,()=>{_r(),Y({planMode:!1}),p(e,200,{ok:!0})})}function Nd(t,e){p(e,200,{templates:$d()})}function Od(t,e){Ve(t,e,n=>{if(!C()){p(e,400,{error:"No active session"});return}let o=typeof n.templateId=="string"?n.templateId.trim():"";if(!o){p(e,400,{error:"templateId is required"});return}let i=Ad(o);if(!i){p(e,404,{error:`Unknown plan template: ${o}`});return}Po(i.body),Y({planMode:!0}),p(e,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var Yh,Fd=R(()=>{"use strict";y();ze();we();Nt();Q();de();_d();Yh="plan.md"});function jd(t){let e,n,s;for(Mr.lastIndex=0;(s=Mr.exec(t))!==null;)e=s[1].trim();let o;for(Er.lastIndex=0;(o=Er.exec(t))!==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:t.replace(Mr,"").replace(Er,"").replace(/\n{3,}/g,`
2622
+ [Attached document: ${v.originalName}]
2623
+ ${v.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 Tr(){return!!O().planMode}function Ar(){let e=O(),t=e.aiEngine||Cr();return rs(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 vr,$t,wn=R(()=>{"use strict";y();Q();we();wo();de();nr();xt();ir();fd();vr=null;$t=null});import{readFileSync as Dh,readdirSync as Lh,existsSync as Jh}from"fs";import{dirname as Bh,join as Io}from"path";import{fileURLToPath as Hh}from"url";function Uh(e){let t=e.match(Gh);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 Wh(e){let t=Uh(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()+`
2624
+ `}}function Kh(){let e=[Io(Td,"../../assets/plan-templates"),Io(Td,"../assets/plan-templates"),Io(process.cwd(),"assets/plan-templates")];for(let t of e)if(Jh(t))return t;return null}function Ad(){if(jt)return jt;let e=Kh();if(!e)return jt=[],jt;let t=[],n=[];try{n=Lh(e)}catch{return jt=[],jt}for(let s of n)if(s.endsWith(".md"))try{let o=Dh(Io(e,s),"utf-8"),i=Wh(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),jt=t,jt}function $d(e){return Ad().find(t=>t.id===e)??null}function _d(){return Ad().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 Td,Gh,jt,Ed=R(()=>{"use strict";y();Td=Bh(Hh(import.meta.url)),Gh=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;jt=null});import{existsSync as Md,mkdirSync as Vh,writeFileSync as zh,rmSync as Yh}from"fs";import{join as Id}from"path";function Pd(e){return Id(e,".vibespot",qh)}function Po(e){let t=C();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=Ce();n&&(n.plan=e);try{let s=Id(t.themePath,".vibespot");Md(s)||Vh(s,{recursive:!0}),zh(Pd(t.themePath),e,"utf-8")}catch(s){M.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return D(),e}function _r(){let e=C();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=Ce();t&&delete t.plan;try{let n=Pd(e.themePath);Md(n)&&Yh(n)}catch(n){M.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}D()}function Rd(e,t){Ve(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}Po(o),p(t,200,{ok:!0,plan:o})})}function Nd(e,t){Ve(e,t,()=>{_r(),Y({planMode:!1}),p(t,200,{ok:!0})})}function Od(e,t){p(t,200,{templates:_d()})}function Fd(e,t){Ve(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=$d(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}Po(i.body),Y({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var qh,jd=R(()=>{"use strict";y();ze();we();Nt();Q();de();Ed();qh="plan.md"});function Dd(e){let t,n,s;for(Er.lastIndex=0;(s=Er.exec(e))!==null;)t=s[1].trim();let o;for(Mr.lastIndex=0;(o=Mr.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(Er,"").replace(Mr,"").replace(/\n{3,}/g,`
2625
2625
 
2626
- `).trim(),plan:e,choices:n}}var Mr,Er,Dd=R(()=>{"use strict";y();Mr=/```vibespot-plan\s*\n([\s\S]*?)```/g,Er=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as Ir}from"child_process";function Ld(t,e,n){t.stdout?.on("data",o=>{e.output+=o.toString()}),t.stderr?.on("data",o=>{e.output+=o.toString()}),t.on("close",o=>{e.status=o===0?"completed":"failed",e.exitCode=o,e.completedAt=Date.now()}),t.on("error",o=>{e.status="failed",e.output+=`
2627
- Process error: ${o.message}`,e.completedAt=Date.now()}),setTimeout(()=>{e.status==="running"&&(t.kill(),e.status="failed",e.output+=`
2628
- Process timed out`,e.completedAt=Date.now())},n||3e5)}function ms(t,e,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${t} ${e.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};Dt.set(o,i);let r=Ir(t,e,{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()),Ld(r,i,s?.timeout),o}function Xt(t,e,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:t,description:e,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};Dt.set(s,o);let i=t.split(" "),r=Ir(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Ld(r,o,n?.timeout),s}function Ro(t){return Dt.get(t)}function qh(){let t=Date.now()-18e5;for(let[e,n]of Dt)n.completedAt&&n.completedAt<t&&Dt.delete(e)}function No(t,e,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:t,description:e,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};Dt.set(s,o);let i=t.split(" "),r=Ir(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+=`
2626
+ `).trim(),plan:t,choices:n}}var Er,Mr,Ld=R(()=>{"use strict";y();Er=/```vibespot-plan\s*\n([\s\S]*?)```/g,Mr=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as Ir}from"child_process";function Jd(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+=`
2627
+ Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
2628
+ Process timed out`,t.completedAt=Date.now())},n||3e5)}function ms(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};Dt.set(o,i);let r=Ir(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()),Jd(r,i,s?.timeout),o}function Xt(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};Dt.set(s,o);let i=e.split(" "),r=Ir(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Jd(r,o,n?.timeout),s}function Ro(e){return Dt.get(e)}function Xh(){let e=Date.now()-18e5;for(let[t,n]of Dt)n.completedAt&&n.completedAt<e&&Dt.delete(t)}function No(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};Dt.set(s,o);let i=e.split(" "),r=Ir(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+=`
2629
2629
  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+=`
2630
- Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Jd(t,e){let n=Dt.get(t);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{e(s.output)}catch{}s.listeners.add(e)}function Bd(t,e){let n=Dt.get(t);!n||!("listeners"in n)||n.listeners.delete(e)}var Dt,Oo=R(()=>{"use strict";y();Dt=new Map;setInterval(qh,600*1e3)});import{readFileSync as Xh,readdirSync as Zh,existsSync as Qh}from"fs";import{dirname as ey,join as Fo}from"path";import{fileURLToPath as ty}from"url";function ny(){let t=[Fo(Hd,"../../starters"),Fo(Hd,"../starters"),Fo(process.cwd(),"starters")];for(let e of t)if(Qh(e))return e;return null}function Ud(){if(Cn!==null)return Cn;let t=ny();if(!t)return Cn=[],Cn;let e=[];for(let n of Zh(t).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(Xh(Fo(t,n),"utf-8"));e.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 Cn=e,Cn}function Gd(){return Ud().map(t=>({id:t.id,name:t.name,description:t.description,category:t.category,contentType:t.contentType,moduleCount:t.modules.length}))}function Pr(t){return Ud().find(e=>e.id===t)||null}var Hd,Cn,Wd=R(()=>{"use strict";y();Hd=ey(ty(import.meta.url)),Cn=null});var gs={};Be(gs,{collectThemeFiles:()=>Vd,extractDesignContext:()=>ay});import{existsSync as jo,readdirSync as Do,readFileSync as sy}from"fs";import{join as ht}from"path";import{spawn as oy}from"child_process";async function Kd(){return Rr||(Rr=(await import("@anthropic-ai/sdk")).default),Rr}function ps(t){try{return sy(t,"utf-8")}catch{return""}}function Vd(t){let e=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2630
+ Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Bd(e,t){let n=Dt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Hd(e,t){let n=Dt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var Dt,Oo=R(()=>{"use strict";y();Dt=new Map;setInterval(Xh,600*1e3)});import{readFileSync as Zh,readdirSync as Qh,existsSync as ey}from"fs";import{dirname as ty,join as Fo}from"path";import{fileURLToPath as ny}from"url";function sy(){let e=[Fo(Gd,"../../starters"),Fo(Gd,"../starters"),Fo(process.cwd(),"starters")];for(let t of e)if(ey(t))return t;return null}function Ud(){if(Cn!==null)return Cn;let e=sy();if(!e)return Cn=[],Cn;let t=[];for(let n of Qh(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(Zh(Fo(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 Cn=t,Cn}function Wd(){return Ud().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function Pr(e){return Ud().find(t=>t.id===e)||null}var Gd,Cn,Kd=R(()=>{"use strict";y();Gd=ty(ny(import.meta.url)),Cn=null});var gs={};Be(gs,{collectThemeFiles:()=>zd,extractDesignContext:()=>ly});import{existsSync as jo,readdirSync as Do,readFileSync as oy}from"fs";import{join as ht}from"path";import{spawn as iy}from"child_process";async function Vd(){return Rr||(Rr=(await import("@anthropic-ai/sdk")).default),Rr}function ps(e){try{return oy(e,"utf-8")}catch{return""}}function zd(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2631
2631
  ### ${a}
2632
2632
  \`\`\`
2633
2633
  ${l}
2634
2634
  \`\`\`
2635
- `;return n+c.length>iy?!1:(e.push(c),n+=c.length,!0)}let o=ps(ht(t,"theme.json"));o&&s("theme.json",o);let i=ht(t,"css");if(jo(i)){for(let a of Do(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,ps(ht(i,a))))break}let r=ht(t,"modules");if(jo(r))for(let a of Do(r).filter(l=>l.endsWith(".module"))){let l=ht(r,a),c=ps(ht(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(jo(r))for(let a of Do(r).filter(l=>l.endsWith(".module"))){let l=ht(r,a),c=ps(ht(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(jo(r))for(let a of Do(r).filter(l=>l.endsWith(".module"))){let l=ht(r,a),c=ps(ht(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return e.join("")}function ry(){if(!Lo)try{Lo=M(Ts("extraction-prompt.md"))}catch{Lo=""}return Lo}function Nr(t,e,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=oy(t,e,{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(`${t} failed to start: ${c.message}`))),r.on("close",c=>{c===0||a.trim()?s(a.trim()):o(new Error(`${t} exited with code ${c}: ${l.trim()}`))}),r.stdin.write(n),r.stdin.end()})}async function ay(t,e){e?.({status:"Collecting theme files..."});let n=Vd(t);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=ry();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:
2636
- ${n}`;e?.({status:"Analyzing design patterns..."});let i=O(),r=i.aiEngine||"anthropic-api",a="";switch(r){case"anthropic-api":case"api":{let l=Oe("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Kd();a=(await new c({apiKey:l}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(m=>m.type==="text"?m.text:"").join("");break}case"claude-oauth":{let{getValidAccessToken:l,OAUTH_EXTRA_HEADERS:c,OAUTH_SYSTEM_PREFIX:d}=await Promise.resolve().then(()=>(xt(),gi)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await Kd();a=(await new m({authToken:u,defaultHeaders:c}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:d},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(f=>f.type==="text"?f.text:"").join("");break}case"openai-api":{let l=Oe("openai-api");if(!l)throw new Error("OpenAI API key not configured. Open Settings to add one.");let c=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify({model:i.openaiApiModel||"gpt-4o",max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!c.ok)throw new Error(`OpenAI API error: ${c.status} ${await c.text()}`);a=(await c.json()).choices?.[0]?.message?.content||"";break}case"gemini-api":{let l=Oe("gemini-api");if(!l)throw new Error("Gemini API key not configured. Open Settings to add one.");let c=i.geminiApiModel||"gemini-2.5-flash",d=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${c}:generateContent?key=${l}`,{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(!d.ok)throw new Error(`Gemini API error: ${d.status} ${await d.text()}`);a=(await d.json()).candidates?.[0]?.content?.parts?.map(m=>m.text).join("")||"";break}case"claude-code":{let l=`${s}
2635
+ `;return n+c.length>ry?!1:(t.push(c),n+=c.length,!0)}let o=ps(ht(e,"theme.json"));o&&s("theme.json",o);let i=ht(e,"css");if(jo(i)){for(let a of Do(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,ps(ht(i,a))))break}let r=ht(e,"modules");if(jo(r))for(let a of Do(r).filter(l=>l.endsWith(".module"))){let l=ht(r,a),c=ps(ht(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(jo(r))for(let a of Do(r).filter(l=>l.endsWith(".module"))){let l=ht(r,a),c=ps(ht(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(jo(r))for(let a of Do(r).filter(l=>l.endsWith(".module"))){let l=ht(r,a),c=ps(ht(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function ay(){if(!Lo)try{Lo=E(Ts("extraction-prompt.md"))}catch{Lo=""}return Lo}function Nr(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=iy(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 ly(e,t){t?.({status:"Collecting theme files..."});let n=zd(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=ay();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:
2636
+ ${n}`;t?.({status:"Analyzing design patterns..."});let i=O(),r=i.aiEngine||"anthropic-api",a="";switch(r){case"anthropic-api":case"api":{let l=Oe("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Vd();a=(await new c({apiKey:l}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(m=>m.type==="text"?m.text:"").join("");break}case"claude-oauth":{let{getValidAccessToken:l,OAUTH_EXTRA_HEADERS:c,OAUTH_SYSTEM_PREFIX:d}=await Promise.resolve().then(()=>(xt(),gi)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await Vd();a=(await new m({authToken:u,defaultHeaders:c}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:d},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(f=>f.type==="text"?f.text:"").join("");break}case"openai-api":{let l=Oe("openai-api");if(!l)throw new Error("OpenAI API key not configured. Open Settings to add one.");let c=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify({model:i.openaiApiModel||"gpt-4o",max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!c.ok)throw new Error(`OpenAI API error: ${c.status} ${await c.text()}`);a=(await c.json()).choices?.[0]?.message?.content||"";break}case"gemini-api":{let l=Oe("gemini-api");if(!l)throw new Error("Gemini API key not configured. Open Settings to add one.");let c=i.geminiApiModel||"gemini-2.5-flash",d=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${c}:generateContent?key=${l}`,{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(!d.ok)throw new Error(`Gemini API error: ${d.status} ${await d.text()}`);a=(await d.json()).candidates?.[0]?.content?.parts?.map(m=>m.text).join("")||"";break}case"claude-code":{let l=`${s}
2637
2637
 
2638
2638
  ## User Request
2639
2639
  ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),a=await Nr("claude",c,l);break}case"gemini-cli":{let l=`${s}
@@ -2642,7 +2642,7 @@ ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),a=awa
2642
2642
  ${o}`;a=await Nr("gemini",[],l);break}case"codex-cli":{let l=`${s}
2643
2643
 
2644
2644
  ## User Request
2645
- ${o}`;a=await Nr("codex",[],l);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 e?.({status:"Design extraction complete."}),a}var Rr,iy,Lo,fs=R(()=>{"use strict";y();ne();Q();Rr=null;iy=8e4;Lo=""});var Or={};Be(Or,{extractBrandvoice:()=>ly});async function ly(t,e,n,s){if(!t||t.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.
2645
+ ${o}`;a=await Nr("codex",[],l);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 t?.({status:"Design extraction complete."}),a}var Rr,ry,Lo,fs=R(()=>{"use strict";y();ne();Q();Rr=null;ry=8e4;Lo=""});var Or={};Be(Or,{extractBrandvoice:()=>cy});async function cy(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.
2646
2646
 
2647
2647
  Return a markdown document with these sections (skip any section where the content provides no signal):
2648
2648
 
@@ -2662,7 +2662,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
2662
2662
  ## Dos and Don'ts
2663
2663
  3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
2664
2664
 
2665
- Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await _e(e,n,s,{systemPrompt:o,messages:[{role:"user",content:t}],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 Fr=R(()=>{"use strict";y();nt();de()});var Jo={};Be(Jo,{extractThemeContext:()=>cy});async function cy(t,e,n,s,o){if(!t||t.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.
2665
+ 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:(M.info("brandvoice-extractor",`Extracted brand voice (${r.length} chars)`),r.trim())}catch(i){let r=i instanceof Error?i.message:String(i);return M.warn("brandvoice-extractor",`Brand voice extraction failed: ${r}`),null}}var Fr=R(()=>{"use strict";y();nt();de()});var Jo={};Be(Jo,{extractThemeContext:()=>dy});async function dy(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.
2666
2666
 
2667
2667
  Return a markdown document with these sections (skip any section where the content provides no information):
2668
2668
 
@@ -2681,14 +2681,14 @@ Communication style (e.g., professional, casual, technical, friendly).
2681
2681
  ## Key Terminology
2682
2682
  Specific terms, product names, or branded language used consistently.
2683
2683
 
2684
- Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${e?`
2684
+ Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
2685
2685
 
2686
2686
  Existing product context (update if the new content adds info, keep what's still accurate):
2687
- ${e}`:""}`;try{let a=await _e(n,s,o,{systemPrompt:r,messages:[{role:"user",content:t}],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 Bo=R(()=>{"use strict";y();nt();de()});import{join as zd}from"path";function dy(t){let e=[];return t.brandAssets?.styleguide||e.push("styleguide"),t.brandAssets?.brandvoice||e.push("brandvoice"),t.brandAssets?.themeContext||e.push("themeContext"),e}function uy(t,e,n){t.brandAssets||(t.brandAssets={}),t.brandAssets[e]=n,t.updatedAt=Date.now();let s=e==="themeContext"?"theme-context.md":`${e}.md`,o=zd(t.themePath,".vibespot");Ie(o),J(zd(o,s),n)}async function Yd(t,e){let n=dy(t),s={attempted:[],extracted:[],skipped:[],errors:[]};if(n.length===0)return s;let o=my(e)?e:{...await py(t),...e??{}};n.includes("styleguide")&&await jr(t,"styleguide",s,()=>o.extractStyleguide(t));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 jr(t,"brandvoice",s,()=>o.extractBrandvoice(t,r)),n.includes("themeContext")&&await jr(t,"themeContext",s,()=>o.extractThemeContext(t,r)),s}async function jr(t,e,n,s){n.attempted.push(e);try{let o=await s();if(!o){n.skipped.push(e);return}uy(t,e,o),n.extracted.push(e)}catch(o){let i=o instanceof Error?o.message:String(o);n.skipped.push(e),n.errors.push({asset:e,message:i}),E.warn("brand-enrichment",`${e} enrichment skipped: ${i}`)}}function my(t){return!!t?.extractStyleguide&&!!t.extractBrandvoice&&!!t.extractThemeContext&&!!t.buildPreviewHtml}async function py(t){let{extractDesignContext:e}=await Promise.resolve().then(()=>(fs(),gs)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(es(),vo)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(wn(),$r)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(Fr(),Or)),{extractThemeContext:i}=await Promise.resolve().then(()=>(Bo(),Jo)),r=O();return{extractStyleguide:()=>e(t.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 qd=R(()=>{"use strict";y();ne();Q();de()});import{existsSync as kn,readdirSync as Xd,rmSync as gy,writeFileSync as Zt,mkdirSync as Ho}from"fs";import{join as Me,basename as fy}from"path";import{homedir as hy}from"os";import{execFileSync as Qd}from"child_process";function Go(){if(Uo&&Date.now()-Uo.ts<yy)return Uo.data;let t=[];if(kn(st))try{for(let e of Xd(st,{withFileTypes:!0}))if(e.isDirectory()){let n=Me(st,e.name,"theme.json");if(kn(n)){let s=0,o=Me(st,e.name,"modules");if(kn(o))try{s=Xd(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}t.push({name:e.name,moduleCount:s})}}}catch{}return Uo={data:t,ts:Date.now()},t}function tu(t){let e=C(),n=Os(),s=!1;try{Qd("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...eu}),s=!0}catch{}let o=gn().sort((r,a)=>a.updatedAt-r.updatedAt),i=Go();p(t,200,{hasActiveSession:!!e,activeSession:e?{id:e.id,themeName:e.themeName,moduleCount:e.modules.length,isImported:!!e.isImported}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i,contentMode:yn()})}function nu(t,e){W(t,n=>{try{if(Ft()){p(e,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(e,400,{error:"Theme name is required"});return}let r=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!r){p(e,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Me(st,r);if(Ie(st),kn(a)&&gy(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!Pr(o)){p(e,400,{error:`Starter template "${o}" not found`});return}Ln(a,r),pn(a,r),o&&typeof o=="string"?(by(a,r,o),ke()):i==="email"&&(Tt("module_only","Email","email"),ln(a,r)),D(),p(e,200,{ok:!0,themeName:r,themePath:a,starterId:o||void 0})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function by(t,e,n){let s=Pr(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-${e}`:`lp-${e}`,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&&ln(t,e),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Me(t,"modules");Ho(d,{recursive:!0});for(let u of s.modules){let m=Me(d,`${u.moduleName}.module`);Ho(m,{recursive:!0}),Zt(Me(m,"fields.json"),u.fieldsJson,"utf-8"),Zt(Me(m,"meta.json"),u.metaJson,"utf-8"),Zt(Me(m,"module.html"),u.moduleHtml,"utf-8"),Zt(Me(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&Zt(Me(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Me(t,"css");Ho(u,{recursive:!0}),Zt(Me(u,`${e}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Me(t,"js");Ho(u,{recursive:!0}),Zt(Me(u,`${e}-animations.js`),s.sharedJs,"utf-8")}}function su(t){p(t,200,{starters:Gd()})}function ou(t,e){W(t,n=>{try{if(Ft()){p(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(e,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(e,400,{error:"Theme name is required"});return}let i=Fe(),r=O(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Me(st,a);Ie(st),r.hubspotUploadMode==="cli"||!i?(async()=>{Qd("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...eu});let c=await Zd(l,a);p(e,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})})().catch(c=>{p(e,500,{error:c instanceof Error?c.message:String(c)})}):Bn(i,o,l).then(async()=>{let c=await Zd(l,a);p(e,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})}).catch(c=>{p(e,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}async function Zd(t,e){pn(t,e,{isImported:!0}),So(t),D();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await Yd(n),D()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function iu(t,e){W(t,n=>{try{if(Ft()){p(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){p(e,400,{error:"Theme path is required"});return}let o=s;if(kn(o)||(o=Me(st,s)),!kn(o)){p(e,400,{error:`Theme folder not found: ${s}`});return}let i=fy(o);pn(o,i),So(o),D(),p(e,200,{ok:!0,themeName:i,themePath:o,moduleCount:C()?.modules.length||0})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ru(t,e){W(t,n=>{try{if(Ft()){p(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){p(e,400,{error:"Session ID is required"});return}let o=po(s);if(!o){p(e,404,{error:"Session not found"});return}p(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function au(t,e){W(t,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(e,400,{error:"API key is required"});return}Y({anthropicApiKey:s}),p(e,200,{ok:!0})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function lu(t){let e=Fe();if(!e){p(t,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await wa(e);if(n.length===0){p(t,200,{themes:[]});return}let s=[],o=n.map(async a=>{let l=a.path||a.name;try{let c=await Ds(e,`${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=Go(),r=new Set(i.map(a=>a.name));p(t,200,{themes:s.map(a=>({...a,existsLocally:r.has(a.name)}))})})().catch(n=>{p(t,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}var eu,st,Uo,yy,Wo=R(()=>{"use strict";y();ze();Q();Jn();Hs();Ut();we();Nt();wn();Ht();Q();ne();Wd();ts();qd();eu=process.platform==="win32"?{shell:!0}:{},st=Me(hy(),"vibespot-themes"),Uo=null,yy=5e3});import{existsSync as Sy,readFileSync as xy,appendFileSync as vy}from"fs";import{join as cu}from"path";import{homedir as du}from"os";function ky(t){let e=t.match(/^gpt-(\d+(?:\.\d+)?)(?:-(.+))?$/);if(e){let n=e[1],s=e[2];if(!s)return`GPT-${n}`;let o=s.replace(/-/g," ").replace(/\b\w/g,i=>i.toUpperCase());return`GPT-${n} ${o}`}return t.startsWith("codex-")?`Codex ${t.slice(6).replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}`:/^o\d/.test(t)?t.replace(/-/g," "):t}async function Ty(t){let e=await fetch("https://api.anthropic.com/v1/models",{headers:{"x-api-key":t,"anthropic-version":"2023-06-01"}});return e.ok?(await e.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 Ay(t){let e=await fetch("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${t}`}});return e.ok?(await e.json()).data.map(s=>s.id):[]}function uu(t,e){return t.filter(n=>e.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:ky(n)}))}async function $y(t){let e=await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${t}`);return e.ok?(await e.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function _y(){if(Date.now()-hs.ts<wy&&Object.keys(hs.data).length>0)return hs.data;let t=O(),e={...mu},n=[],s=Oe("anthropic-api",t);s&&n.push(Ty(s).then(r=>{r.length&&(e["anthropic-api"]=r,e["claude-oauth"]=r)}).catch(()=>{}));let o=Oe("openai-api",t);o&&n.push(Ay(o).then(r=>{if(!r.length)return;let a=uu(r,pu);a.length&&(e["openai-api"]=a);let l=uu(r,Cy);l.length&&(e["codex-cli"]=l)}).catch(()=>{}));let i=Oe("gemini-api",t);return i&&n.push($y(i).then(r=>{r.length&&(e["gemini-api"]=r,e["gemini-cli"]=r)}).catch(()=>{})),await Promise.all(n),hs.data=e,hs.ts=Date.now(),e}function gu(t){let e=Os(),n=O(),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,hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(a=>({portalId:a.portalId,portalName:a.portalName,dataCenter:a.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},o=gn().length,i=Go().length,r=sn();_y().then(a=>{p(t,200,{version:r,environment:e,config:s,models:a,sessionCount:o,localThemeCount:i})}).catch(()=>{p(t,200,{version:r,environment:e,config:s,models:mu,sessionCount:o,localThemeCount:i})})}function fu(t,e){W(t,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"].includes(s)){p(e,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}Y(r),p(e,200,{ok:!0,engine:s})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function hu(t,e){W(t,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(e,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"figma":l.figmaToken="";break;default:p(e,400,{error:`Unknown provider: ${s}`});return}Y(l),p(e,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"figma":i.figmaToken=o;break;default:p(e,400,{error:`Unknown provider: ${s}`});return}Y(i);let r=null;if(!O().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(Y({aiEngine:c}),r=c)}p(e,200,{ok:!0,provider:s,autoSelectedEngine:r})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function yu(t,e){W(t,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(e,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let r=Xt(i.cmd,i.desc,{timeout:12e4});p(e,200,{ok:!0,jobId:r})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function bu(t,e){W(t,n=>{try{let s=JSON.parse(n||"{}"),o=O(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){js(s.personalAccessKey).then(r=>{An(s.personalAccessKey,r.portalId,r.portalName,r.dataCenter),p(e,200,{ok:!0,portalName:r.portalName,portalId:r.portalId,dataCenter:r.dataCenter})}).catch(r=>{p(e,400,{error:r instanceof Error?r.message:String(r)})});return}else{if(!ct().found){p(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ms("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(e,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(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!ct().found){p(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=dt();if(a.authenticated&&!s.force){p(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}p(e,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(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Su(t,e){W(t,n=>{try{let s=JSON.parse(n||"{}");if(!hi().found){p(e,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=yi();if(i.authenticated&&!s.force){p(e,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=ms("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(e,200,{ok:!0,jobId:a});return}let r=Xt("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(e,200,{ok:!0,jobId:r,browserAuthRequired:!0})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function xu(t,e){W(t,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((O().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){ci(s),p(e,200,{ok:!0});return}if(s){di(s),p(e,200,{ok:!0});return}}else{if(!ct().found){p(e,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(e,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=ms("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(e,200,{ok:!0,jobId:c});return}if(l){let c=ms("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});p(e,200,{ok:!0,jobId:c});return}}p(e,400,{error:"portalId required"})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function vu(t){let e=Xt("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(t,200,{ok:!0,jobId:e})}function wu(t,e){W(t,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=Xt("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});p(e,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=Xt("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(e,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")?cu(du(),".zshrc"):cu(du(),".bashrc");try{(Sy(l)?xy(l,"utf-8"):"").includes("OPENAI_API_KEY")||vy(l,`
2687
+ ${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:(M.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return M.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var Bo=R(()=>{"use strict";y();nt();de()});import{join as Yd}from"path";function uy(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function my(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=Yd(e.themePath,".vibespot");Ie(o),J(Yd(o,s),n)}async function qd(e,t){let n=uy(e),s={attempted:[],extracted:[],skipped:[],errors:[]};if(n.length===0)return s;let o=py(t)?t:{...await gy(e),...t??{}};n.includes("styleguide")&&await jr(e,"styleguide",s,()=>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 jr(e,"brandvoice",s,()=>o.extractBrandvoice(e,r)),n.includes("themeContext")&&await jr(e,"themeContext",s,()=>o.extractThemeContext(e,r)),s}async function jr(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}my(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}),M.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function py(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function gy(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(fs(),gs)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(es(),vo)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(wn(),$r)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(Fr(),Or)),{extractThemeContext:i}=await Promise.resolve().then(()=>(Bo(),Jo)),r=O();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 Xd=R(()=>{"use strict";y();ne();Q();de()});import{existsSync as kn,readdirSync as Zd,rmSync as fy,writeFileSync as Zt,mkdirSync as Ho}from"fs";import{join as Ee,basename as hy}from"path";import{homedir as yy}from"os";import{execFileSync as eu}from"child_process";function Uo(){if(Go&&Date.now()-Go.ts<by)return Go.data;let e=[];if(kn(st))try{for(let t of Zd(st,{withFileTypes:!0}))if(t.isDirectory()){let n=Ee(st,t.name,"theme.json");if(kn(n)){let s=0,o=Ee(st,t.name,"modules");if(kn(o))try{s=Zd(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return Go={data:e,ts:Date.now()},e}function nu(e){let t=C(),n=Os(),s=!1;try{eu("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...tu}),s=!0}catch{}let o=gn().sort((r,a)=>a.updatedAt-r.updatedAt),i=Uo();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:yn()})}function su(e,t){W(e,n=>{try{if(Ft()){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=Ee(st,r);if(Ie(st),kn(a)&&fy(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!Pr(o)){p(t,400,{error:`Starter template "${o}" not found`});return}Ln(a,r),pn(a,r),o&&typeof o=="string"?(Sy(a,r,o),ke()):i==="email"&&(Tt("module_only","Email","email"),ln(a,r)),D(),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 Sy(e,t,n){let s=Pr(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&&ln(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Ee(e,"modules");Ho(d,{recursive:!0});for(let u of s.modules){let m=Ee(d,`${u.moduleName}.module`);Ho(m,{recursive:!0}),Zt(Ee(m,"fields.json"),u.fieldsJson,"utf-8"),Zt(Ee(m,"meta.json"),u.metaJson,"utf-8"),Zt(Ee(m,"module.html"),u.moduleHtml,"utf-8"),Zt(Ee(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&Zt(Ee(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Ee(e,"css");Ho(u,{recursive:!0}),Zt(Ee(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Ee(e,"js");Ho(u,{recursive:!0}),Zt(Ee(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function ou(e){p(e,200,{starters:Wd()})}function iu(e,t){W(e,n=>{try{if(Ft()){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=Fe(),r=O(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Ee(st,a);Ie(st),r.hubspotUploadMode==="cli"||!i?(async()=>{eu("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...tu});let c=await Qd(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)})}):Bn(i,o,l).then(async()=>{let c=await Qd(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 Qd(e,t){pn(e,t,{isImported:!0}),So(e),D();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await qd(n),D()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function ru(e,t){W(e,n=>{try{if(Ft()){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(kn(o)||(o=Ee(st,s)),!kn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=hy(o);pn(o,i),So(o),D(),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 au(e,t){W(e,n=>{try{if(Ft()){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=po(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 lu(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 cu(e){let t=Fe();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await wa(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 Ds(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=Uo(),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 tu,st,Go,by,Wo=R(()=>{"use strict";y();ze();Q();Jn();Hs();Gt();we();Nt();wn();Ht();Q();ne();Kd();ts();Xd();tu=process.platform==="win32"?{shell:!0}:{},st=Ee(yy(),"vibespot-themes"),Go=null,by=5e3});import{existsSync as xy,readFileSync as vy,appendFileSync as wy}from"fs";import{join as du}from"path";import{homedir as uu}from"os";function Ty(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 Ay(e){let t=await fetch("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 $y(e){let t=await fetch("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function mu(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:Ty(n)}))}async function _y(e){let t=await fetch(`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 Ey(){if(Date.now()-hs.ts<Cy&&Object.keys(hs.data).length>0)return hs.data;let e=O(),t={...pu},n=[],s=Oe("anthropic-api",e);s&&n.push(Ay(s).then(r=>{r.length&&(t["anthropic-api"]=r,t["claude-oauth"]=r)}).catch(()=>{}));let o=Oe("openai-api",e);o&&n.push($y(o).then(r=>{if(!r.length)return;let a=mu(r,gu);a.length&&(t["openai-api"]=a);let l=mu(r,ky);l.length&&(t["codex-cli"]=l)}).catch(()=>{}));let i=Oe("gemini-api",e);return i&&n.push(_y(i).then(r=>{r.length&&(t["gemini-api"]=r,t["gemini-cli"]=r)}).catch(()=>{})),await Promise.all(n),hs.data=t,hs.ts=Date.now(),t}function fu(e){let t=Os(),n=O(),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,hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(a=>({portalId:a.portalId,portalName:a.portalName,dataCenter:a.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},o=gn().length,i=Uo().length,r=sn();Ey().then(a=>{p(e,200,{version:r,environment:t,config:s,models:a,sessionCount:o,localThemeCount:i})}).catch(()=>{p(e,200,{version:r,environment:t,config:s,models:pu,sessionCount:o,localThemeCount:i})})}function hu(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 yu(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;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;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(i);let r=null;if(!O().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 bu(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=Xt(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 Su(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}"),o=O(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){js(s.personalAccessKey).then(r=>{An(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(!ct().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ms("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(!ct().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=dt();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 xu(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}");if(!hi().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=yi();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=ms("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=Xt("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 vu(e,t){W(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((O().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){ci(s),p(t,200,{ok:!0});return}if(s){di(s),p(t,200,{ok:!0});return}}else{if(!ct().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=ms("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=ms("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 wu(e){let t=Xt("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function Cu(e,t){W(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=Xt("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=Xt("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")?du(uu(),".zshrc"):du(uu(),".bashrc");try{(xy(l)?vy(l,"utf-8"):"").includes("OPENAI_API_KEY")||wy(l,`
2688
2688
  # Added by vibeSpot
2689
2689
  ${a}
2690
- `)}catch{}}}p(e,200,{ok:!0,message:"API key saved"})}else{let i=Xt("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});p(e,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:p(e,400,{error:`Unknown CLI: ${s}`})}}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Cu(t,e){W(t,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(e,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}Y({hubspotUploadMode:s}),p(e,200,{ok:!0,mode:s})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ku(t,e){W(t,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(e,400,{error:"toolId (string) and enabled (boolean) required"});return}ui(s,o),p(e,200,{ok:!0,toolId:s,enabled:o})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Tu(t,e){W(t,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(e,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(Object.keys(i).length===0){p(e,400,{error:"No valid settings fields provided"});return}Y(i),p(e,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Au(t,e){let n=t.replace("/api/settings/job/","");if(!n){p(e,400,{error:"Job ID required"});return}let s=Ro(n);if(!s){p(e,404,{error:"Job not found"});return}p(e,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}var hs,wy,mu,pu,Cy,$u=R(()=>{"use strict";y();ze();Q();we();Wo();Ht();Ut();ne();Oo();hs={data:{},ts:0},wy=600*1e3,mu={"claude-code":[{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-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-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"}]},pu=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,Cy=pu});function _u(t,e){W(t,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(e,400,{error:"access_token is required"});return}mi(s.trim(),(o||"").trim());let i=O();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&Y({aiEngine:"claude-oauth"}),p(e,200,{ok:!0})}catch(s){p(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Mu(t,e){let n=lt(),s=Mn();p(e,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Eu(t,e){try{Es(),O().aiEngine==="claude-oauth"&&Y({aiEngine:void 0}),p(e,200,{ok:!0})}catch(n){p(e,500,{error:n instanceof Error?n.message:String(n)})}}var Iu=R(()=>{"use strict";y();ze();Q();xt()});import{existsSync as My,rmSync as Ey}from"fs";import{join as Iy}from"path";function Pu(t,e,n){if(t==="GET"){let s=C(),o=gn().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(t==="DELETE"){W(e,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Ol(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 Ru(t,e){W(t,n=>{try{let{sessionId:s}=JSON.parse(n),o=po(s);if(!o){p(e,404,{error:"Session not found"});return}p(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Nu(t,e){W(t,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(e,400,{error:"Theme name is required"});return}if(/[\/\\]|\.\./.test(s)||s==="."||!s.replace(/[^a-z0-9]/gi,"")){p(e,400,{error:"Invalid theme name"});return}let o=Iy(st,s);if(!My(o)){p(e,404,{error:"Theme not found on disk"});return}Ey(o,{recursive:!0,force:!0}),p(e,200,{ok:!0})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ou(t,e){W(t,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(e,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(e,400,{error:"Invalid name"});return}let r=Fl(s,i);r.ok?p(e,200,{ok:!0,newName:i}):p(e,400,{error:r.error})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Fu(t,e){W(t,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(e,400,{error:"sessionId is required"});return}let o=jl(s);o.ok?p(e,200,{ok:!0,newName:o.newName,newSessionId:o.newSessionId}):p(e,400,{error:o.error})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}var ju=R(()=>{"use strict";y();ze();we();Wo()});import{existsSync as ys,readFileSync as Py,rmSync as Ko}from"fs";import{join as Ne,basename as Ry}from"path";import{execFileSync as Ny}from"child_process";function Bu(t){let e=C();if(!e){p(t,404,{error:"No active session"});return}let n=At();p(t,200,{themeName:e.themeName,themePath:e.themePath,templates:e.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:e.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!e.brandAssets?.styleguide,hasBrandvoice:!!e.brandAssets?.brandvoice,hasThemeContext:!!e.brandAssets?.themeContext,humanify:e.brandAssets?.humanify!==!1,hasBrandKit:!!e.brandAssets?.brandKit&&Object.keys(e.brandAssets.brandKit).length>0,brandKit:e.brandAssets?.brandKit||null}})}function Hu(t){let e=C();if(!e){p(t,404,{error:"No active session"});return}let n=e.themePath;if(!ys(n)){p(t,404,{error:"Theme directory not found"});return}let s=e.themeName||"theme",o=Ne(n,".."),i=Ry(n);try{let r=`${s}.zip`,a=Ne(o,r);ys(a)&&Ko(a),Ny("zip",["-r",r,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...Oy});let l=Py(a);Ko(a),t.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${r}"`,"Content-Length":l.length}),t.end(l)}catch(r){E.error("download-zip","Failed to create zip archive",r),p(t,500,{error:"Failed to create zip archive"})}}function Uu(t,e,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(t==="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(t==="POST"){W(e,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=Tt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&ln(s.themePath,s.themeName),D(),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(t==="DELETE"){W(e,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Il(i,!!r)){p(n,404,{error:"Template not found"});return}D(),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 Gu(t,e){W(t,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(e,400,{error:"templateId is required"});return}if(!Kn(s)){p(e,404,{error:"Template not found"});return}D();let i=C();p(e,200,{ok:!0,modules:Se().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Wu(t,e){W(t,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(e,400,{error:"templateId and newLabel are required"});return}if(!El(s,o.trim())){p(e,404,{error:"Template not found"});return}D(),p(e,200,{ok:!0,newLabel:o.trim()})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ku(t,e){W(t,n=>{try{let{templateIds:s}=JSON.parse(n);if(!Array.isArray(s)||s.some(i=>typeof i!="string")){p(e,400,{error:"templateIds must be an array of strings"});return}if(!Ml(s)){p(e,400,{error:"Reorder rejected (length mismatch or no session)"});return}D(),p(e,200,{ok:!0})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Vu(t,e){W(t,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(e,400,{error:"templateId is required"});return}let i=_l(s,o);if(!i){p(e,404,{error:"Template not found"});return}D(),p(e,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function zu(t){let e=At();p(t,200,{modules:e.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Yu(t,e,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}W(e,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=At().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()),D(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function qu(t,e,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(t==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(t==="POST"){W(e,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(),D(),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),J(Ne(c,l),r);let d=null;a==="styleguide"&&(d=Dr(s,r)),D(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){W(e,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);ys(l)&&Ko(l),D(),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 Zu(t,e){p(e,200,Xu)}function jy(t){let e=[],n=[],s=t.split(`
2691
- `),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(Fy);if(l)for(let c of l)e.includes(c.toLowerCase())||e.push(c.toLowerCase())}if(i){let l=Du.exec(a);if(Du.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:e.slice(0,6),fonts:n.slice(0,4)}}function Dr(t,e){let{colors:n,fonts:s}=jy(e);if(n.length===0&&s.length===0)return null;t.brandAssets||(t.brandAssets={});let o=t.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=Xu.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]))}t.brandAssets.brandKit=o;let i=Ne(t.themePath,".vibespot");return Ie(i),J(Ne(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function Qu(t,e,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(t==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(t==="POST"){W(e,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"&&Dy.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),J(Ne(a,"brand-kit.json"),JSON.stringify(r,null,2)),D(),p(n,200,{ok:!0,brandKit:r})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Ne(s.themePath,".vibespot","brand-kit.json");ys(o)&&Ko(o),D(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Lu(t,e,n){if(!t)return;t.brandAssets||(t.brandAssets={}),t.brandAssets[e]=n,t.updatedAt=Date.now();let s=e==="themeContext"?"theme-context.md":`${e}.md`,o=Ne(t.themePath,".vibespot");Ie(o),J(Ne(o,s),n)}async function Ju(t,e,n){if(e==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(fs(),gs));return m(n||t.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(wn(),$r)),{loadConfig:o}=await Promise.resolve().then(()=>(Q(),pa)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(es(),vo)),d=c();if(!d||d.length<50)return null;if(e==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(Fr(),Or));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(Bo(),Jo));return u(d,t.brandAssets?.themeContext,r,a,l)}function em(t,e){let n=C();if(!n){p(e,404,{error:"No active session"});return}W(t,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 Promise.allSettled(c.map(g=>Ju(n,g,r))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Lu(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=Dr(n,u.styleguide)),D(),p(e,200,{ok:!0,type:"all",extracted:u,brandKit:m});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(e,400,{error:`Invalid type: ${i}`});return}let a=await Ju(n,i,r);if(!a){p(e,200,{ok:!1,type:i,error:"No content to extract from"});return}Lu(n,i,a);let l=null;i==="styleguide"&&(l=Dr(n,a)),D(),p(e,200,{ok:!0,type:i,content:a,brandKit:l})}catch(o){p(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}function tm(t,e){let n=C();if(!n){p(e,404,{error:"No active session"});return}W(t,s=>{(async()=>{try{let{source:o,themeName:i,localPath:r}=JSON.parse(s),a;if(o==="hubspot"){if(!i){p(e,400,{error:"themeName is required for HubSpot import"});return}let u=Fe();if(!u){p(e,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(e,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(()=>(Hs(),Ea));await b(u,m,f),a=f}else if(o==="local"){if(!r){p(e,400,{error:"localPath is required for local import"});return}if(!ys(r)){p(e,400,{error:`Path not found: ${r}`});return}a=r}else{p(e,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(fs(),gs)),c=await l(a);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ne(n.themePath,".vibespot");Ie(d),J(Ne(d,"styleguide.md"),c),D(),p(e,200,{ok:!0,styleguide:c,source:a})}catch(o){p(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}var Oy,Xu,Fy,Du,Dy,nm=R(()=>{"use strict";y();ze();de();Q();Jn();we();ne();Oy=process.platform==="win32"?{shell:!0}:{};Xu=[{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"}];Fy=/#[0-9a-fA-F]{6}\b/g,Du=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;Dy=/^#[0-9a-fA-F]{6}$/});import{join as Ly}from"path";function sm(t,e){let n=C();if(!n){p(e,404,{error:"No active session"});return}p(e,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function om(t,e,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(t==="GET"){let o=Se();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(t==="DELETE"){Ve(e,n,o=>{o.deleteEntirely?wl(o.moduleName):Cl(o.moduleName),D(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function im(t,e){let n=C();if(!n){p(e,404,{error:"No active session"});return}W(t,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(e,400,{error:"Invalid shared type"});return}let c=Ce();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),et(),D(),ke(),p(e,200,{ok:!0});return}let{moduleName:i,fileType:r,content:a}=o;if(!i||!r){p(e,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(e,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(e,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:p(e,400,{error:`Invalid fileType: ${r}`});return}n.updatedAt=Date.now(),et(),D(),ke(),p(e,200,{ok:!0})}catch(o){p(e,400,{error:String(o)})}})}function rm(t,e){Ve(t,e,n=>{Array.isArray(n.order)?(Rt(n.order),D(),p(e,200,{ok:!0})):p(e,400,{error:"order must be an array"})})}async function am(t){let e=C();if(!e){p(t,404,{error:"No active session"});return}try{ke();let n=Qs(e.themePath),s=No(`hs cms upload "${e.themePath}" "${e.themeName}"`,"Uploading to HubSpot",{cwd:Ly(e.themePath,".."),timeout:18e4});p(t,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(t,500,{error:String(n)})}}function lm(t,e){W(t,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);kl(s,o,i),D(),p(e,200,{ok:!0})}catch(s){p(e,400,{error:String(s)})}})}function cm(t,e){W(t,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(e,400,{error:"url is required"});return}let o=$a(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2690
+ `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=Xt("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 ku(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 Tu(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}ui(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 Au(e,t){W(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);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 $u(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=Ro(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 hs,Cy,pu,gu,ky,_u=R(()=>{"use strict";y();ze();Q();we();Wo();Ht();Gt();ne();Oo();hs={data:{},ts:0},Cy=600*1e3,pu={"claude-code":[{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-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-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"}]},gu=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,ky=gu});function Eu(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}mi(s.trim(),(o||"").trim());let i=O();(!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 Mu(e,t){let n=lt(),s=En();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Iu(e,t){try{Ms(),O().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 Pu=R(()=>{"use strict";y();ze();Q();xt()});import{existsSync as My,rmSync as Iy}from"fs";import{join as Py}from"path";function Ru(e,t,n){if(e==="GET"){let s=C(),o=gn().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);Ol(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 Nu(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=po(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 Ou(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=Py(st,s);if(!My(o)){p(t,404,{error:"Theme not found on disk"});return}Iy(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Fu(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=Fl(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 ju(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=jl(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 Du=R(()=>{"use strict";y();ze();we();Wo()});import{existsSync as ys,readFileSync as Ry,rmSync as Ko}from"fs";import{join as Ne,basename as Ny}from"path";import{execFileSync as Oy}from"child_process";function Hu(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=At();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 Gu(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!ys(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=Ne(n,".."),i=Ny(n);try{let r=`${s}.zip`,a=Ne(o,r);ys(a)&&Ko(a),Oy("zip",["-r",r,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...Fy});let l=Ry(a);Ko(a),e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${r}"`,"Content-Length":l.length}),e.end(l)}catch(r){M.error("download-zip","Failed to create zip archive",r),p(e,500,{error:"Failed to create zip archive"})}}function Uu(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=Tt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&ln(s.themePath,s.themeName),D(),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(!Il(i,!!r)){p(n,404,{error:"Template not found"});return}D(),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 Wu(e,t){W(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!Kn(s)){p(t,404,{error:"Template not found"});return}D();let i=C();p(t,200,{ok:!0,modules:Se().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Ku(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(!Ml(s,o.trim())){p(t,404,{error:"Template not found"});return}D(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Vu(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(!El(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}D(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function zu(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=_l(s,o);if(!i){p(t,404,{error:"Template not found"});return}D(),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 Yu(e){let t=At();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function qu(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=At().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()),D(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function Xu(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(),D(),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),J(Ne(c,l),r);let d=null;a==="styleguide"&&(d=Dr(s,r)),D(),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=Ne(s.themePath,".vibespot",a);ys(l)&&Ko(l),D(),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 Qu(e,t){p(t,200,Zu)}function Dy(e){let t=[],n=[],s=e.split(`
2691
+ `),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(jy);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Lu.exec(a);if(Lu.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 Dr(e,t){let{colors:n,fonts:s}=Dy(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=Zu.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),J(Ne(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function em(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"&&Ly.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),J(Ne(a,"brand-kit.json"),JSON.stringify(r,null,2)),D(),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");ys(o)&&Ko(o),D(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Ju(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),J(Ne(o,s),n)}async function Bu(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(fs(),gs));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(wn(),$r)),{loadConfig:o}=await Promise.resolve().then(()=>(Q(),pa)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(es(),vo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(Fr(),Or));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(Bo(),Jo));return u(d,e.brandAssets?.themeContext,r,a,l)}function tm(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 Promise.allSettled(c.map(g=>Bu(n,g,r))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Ju(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=Dr(n,u.styleguide)),D(),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 Bu(n,i,r);if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Ju(n,i,a);let l=null;i==="styleguide"&&(l=Dr(n,a)),D(),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 nm(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=Fe();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(()=>(Hs(),Ma));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(!ys(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(()=>(fs(),gs)),c=await l(a);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ne(n.themePath,".vibespot");Ie(d),J(Ne(d,"styleguide.md"),c),D(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var Fy,Zu,jy,Lu,Ly,sm=R(()=>{"use strict";y();ze();de();Q();Jn();we();ne();Fy=process.platform==="win32"?{shell:!0}:{};Zu=[{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"}];jy=/#[0-9a-fA-F]{6}\b/g,Lu=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;Ly=/^#[0-9a-fA-F]{6}$/});import{join as Jy}from"path";function om(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 im(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=Se();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"){Ve(t,n,o=>{o.deleteEntirely?wl(o.moduleName):Cl(o.moduleName),D(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function rm(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=Ce();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),et(),D(),ke(),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(),et(),D(),ke(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function am(e,t){Ve(e,t,n=>{Array.isArray(n.order)?(Rt(n.order),D(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function lm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}try{ke();let n=Qs(t.themePath),s=No(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:Jy(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function cm(e,t){W(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);kl(s,o,i),D(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function dm(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=$a(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2692
2692
  `),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.
2693
2693
 
2694
2694
  Source analysis found ${o.components.length} components:
@@ -2698,19 +2698,19 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
2698
2698
  Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
2699
2699
  Interactions: ${o.interactions.join(", ")}
2700
2700
 
2701
- 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(e,200,r)}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}function dm(t,e){let n=C();if(!n){p(e,404,{error:"No active session"});return}if(!Qe()){p(e,200,{available:!1,commits:[]});return}let o=new URL(t.url||"/","http://localhost").searchParams.get("templateId"),i=o?hl(n.themePath,o,50):fl(n.themePath,50);p(e,200,{available:!0,commits:i,filtered:!!o})}function um(t,e){W(t,n=>{try{let s=C();if(!s){p(e,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(e,400,{error:"Commit hash is required"});return}if(tt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let r=s.templates.find(c=>c.id===i);if(!r){p(e,404,{error:"Template not found"});return}let a=r.moduleOrder.map(c=>`modules/${c}.module`);r.templateFile&&a.push(r.templateFile);let l=bl(s.themePath,i,o,a);if(!l.success){p(e,500,{error:l.error||"Rollback failed"});return}zl()}else{let r=yl(s.themePath,o);if(!r.success){p(e,500,{error:r.error||"Rollback failed"});return}Vl()}D(),p(e,200,{ok:!0,modules:Se().map(r=>r.moduleName)})}catch(s){p(e,500,{error:s instanceof Error?s.message:String(s)})}})}var mm=R(()=>{"use strict";y();ze();we();eo();Oo();Bs();dn()});import{writeFileSync as Jy,mkdirSync as gm}from"fs";import{join as Vo}from"path";import{randomUUID as By}from"crypto";function fm(t){let e=t.match(Hy);if(!e)return null;let n=e[1],s=e[2]?decodeURIComponent(e[2].replace(/-/g," ")):void 0,o;try{let r=new URL(t).searchParams.get("node-id");r&&(o=r.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function Yo(t,e){let n=await fetch(`${Uy}${t}`,{headers:{"X-Figma-Token":e}});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 Jr(t,e){for(let n=0;;n++)try{return await t()}catch(s){if(!(s.status===429)||n>=pm.length)throw s;let r=pm[n];E.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${r}s`),e&&e(`Figma rate limited \u2014 retrying in ${r}s...`),await new Promise(a=>setTimeout(a,r*1e3))}}function Qt(t,e,n=0){if(e(t,n),t.children)for(let s of t.children)Qt(s,e,n+1)}function hm(t,e){if(t.id===e)return t;if(t.children)for(let n of t.children){let s=hm(n,e);if(s)return s}return null}function Gy(t,e){if(e){let s=hm(t,e);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>Lr.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>Lr.has(o.type)):[]}let n=t.children?.[0];return n?.children?n.children.filter(s=>Lr.has(s.type)):[]}function zo(t){let e=Math.round(t.r*255),n=Math.round(t.g*255),s=Math.round(t.b*255);return`#${e.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}`}function Wy(t){let e=new Map;for(let n of t)Qt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=zo(o.color),r=e.get(i),a=s.type==="TEXT",l=a?"text":"fill";r?(r.occurrences++,a&&r.usage!=="text"&&(r.usage="text")):e.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=zo(o.color),r=e.get(i);r?r.occurrences++:e.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...e.values()].sort((n,s)=>s.occurrences-n.occurrences)}function Ky(t){let e=new Map;for(let n of t)Qt(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=e.get(u);m?m.occurrences++:e.set(u,{fontFamily:c,fontSize:i,fontWeight:r,lineHeight:a,letterSpacing:l,role:d,occurrences:1})});return[...e.values()].sort((n,s)=>s.fontSize-n.fontSize)}function Vy(t){let e=[],n=new Set;for(let s of t)Qt(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),e.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);e.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return e}function zy(t){let e=[],n=new Set;for(let s of t)Qt(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),e.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}`),e.push({type:"radius",cssValue:i,context:o.name}))}});return e}function Yy(t,e){let n=[];return Qt(t,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:e})}),n}function qy(t){let e=t.absoluteBoundingBox;return{name:t.name,type:t.type,nodeId:t.id,width:e?.width||0,height:e?.height||0,layoutMode:t.layoutMode==="NONE"?void 0:t.layoutMode,childCount:t.children?.length||0,characters:t.type==="TEXT"?t.characters:void 0}}function Xy(t){if(t.fills){for(let e of t.fills)if(e.type==="SOLID"&&e.color)return zo(e.color)}if(t.backgroundColor)return zo(t.backgroundColor)}function Zy(t){return t.map(e=>{let n=e.absoluteBoundingBox;return{name:e.name,nodeId:e.id,width:n?.width||0,height:n?.height||0,textContent:Yy(e,e.name),children:(e.children||[]).slice(0,20).map(qy),backgroundColor:Xy(e),layoutMode:e.layoutMode==="NONE"?void 0:e.layoutMode,itemSpacing:e.itemSpacing,paddingTop:e.paddingTop,paddingRight:e.paddingRight,paddingBottom:e.paddingBottom,paddingLeft:e.paddingLeft}})}function Qy(t){let e=[];for(let n of t)Qt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="IMAGE"&&o.imageRef){e.push({nodeId:s.id,name:s.name||"image"});break}}});return e}async function ym(t,e){let n=await fetch(t);if(!n.ok)throw new Error(`Failed to download image: ${n.status}`);let s=Buffer.from(await n.arrayBuffer());Jy(e,s)}async function eb(t,e,n,s,o){if(e.length===0)return new Map;gm(s,{recursive:!0});let r=e.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await Jr(()=>Yo(`/v1/images/${t}?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=Vo(s,`frame-${u}.png`);try{await ym(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 tb(t,e,n,s,o){if(e.length===0)return[];gm(s,{recursive:!0});let i=50,r=[];for(let a=0;a<e.length;a+=i){let l=e.slice(a,a+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${a+1}-${Math.min(a+i,e.length)} of ${e.length})...`);let d=await Jr(()=>Yo(`/v1/images/${t}?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()}-${By().slice(0,6)}.png`,f=Vo(s,h);try{await ym(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 bm(t,e,n,s,o){o&&o("Fetching Figma file...");let i=e?`/v1/files/${t}?ids=${e}&geometry=paths`:`/v1/files/${t}?geometry=paths`,r=await Jr(()=>Yo(i,n),o);E.info("figma",`Fetched file: ${r.name}`);let a=Gy(r.document,e);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:Wy(a),typography:Ky(a),spacing:Vy(a),effects:zy(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=Zy(a),d=Vo(s,".vibespot","figma-frames"),u=await eb(t,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=Qy(a),h=Vo(s,"assets"),f=await tb(t,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/${t}`,designTokens:l,sections:m,assets:f}}function Sm(t){let e=t.fileName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,30);return{fileName:t.fileName,fileUrl:t.fileUrl,sectionNames:t.sections.map(n=>n.name),sectionCount:t.sections.length,colorPalette:t.designTokens.colors.slice(0,10).map(n=>n.hex),fontFamilies:[...new Set(t.designTokens.typography.map(n=>n.fontFamily))],textBlockCount:t.sections.reduce((n,s)=>n+s.textContent.length,0),assetCount:t.assets.length,suggestedThemeName:e}}async function xm(t){return await Yo("/v1/me",t)}var Hy,Uy,pm,Lr,vm=R(()=>{"use strict";y();de();Hy=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;Uy="https://api.figma.com",pm=[10,20,40,60,120];Lr=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var $m={};Be($m,{getCachedExtraction:()=>Am,handleFigmaExtractRoute:()=>Hr,handleFigmaGenerateRoute:()=>Ur,handleFigmaTestTokenRoute:()=>Br});import{randomUUID as wm}from"crypto";import{existsSync as Cm,mkdirSync as km,writeFileSync as nb,copyFileSync as sb}from"fs";import{join as qo,basename as ob}from"path";function Tm(){let t=Date.now();for(let[e,n]of bs)n.expires<t&&bs.delete(e)}function Am(t){Tm();let e=bs.get(t);return e?(bs.delete(t),e.extraction):null}function Br(t,e){Ve(t,e,async n=>{let s=n.token||O().figmaToken;if(!s){p(e,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await xm(s);p(e,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);E.warn("figma",`Token test failed: ${i}`),p(e,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function Hr(t,e){Ve(t,e,async n=>{let s=n.url;if(!s){p(e,400,{error:"Missing 'url' field"});return}let o=n.token||O().figmaToken;if(!o){p(e,400,{error:"No Figma token configured. Add one in Settings."});return}let i=fm(s);if(!i){p(e,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=C()?.themePath||`/tmp/vibespot-figma-${wm().slice(0,8)}`;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{e.write(`data: ${JSON.stringify(c)}
2701
+ 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 um(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}if(!Qe()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?hl(n.themePath,o,50):fl(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function mm(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(tt("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=bl(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}zl()}else{let r=yl(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}Vl()}D(),p(t,200,{ok:!0,modules:Se().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var pm=R(()=>{"use strict";y();ze();we();eo();Oo();Bs();dn()});import{writeFileSync as By,mkdirSync as fm}from"fs";import{join as Vo}from"path";import{randomUUID as Hy}from"crypto";function hm(e){let t=e.match(Gy);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 Yo(e,t){let n=await fetch(`${Uy}${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 Jr(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=gm.length)throw s;let r=gm[n];M.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 Qt(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)Qt(s,t,n+1)}function ym(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=ym(n,t);if(s)return s}return null}function Wy(e,t){if(t){let s=ym(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>Lr.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>Lr.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>Lr.has(s.type)):[]}function zo(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 Ky(e){let t=new Map;for(let n of e)Qt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=zo(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=zo(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 Vy(e){let t=new Map;for(let n of e)Qt(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 zy(e){let t=[],n=new Set;for(let s of e)Qt(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 Yy(e){let t=[],n=new Set;for(let s of e)Qt(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 qy(e,t){let n=[];return Qt(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 Xy(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 Zy(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return zo(t.color)}if(e.backgroundColor)return zo(e.backgroundColor)}function Qy(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:qy(t,t.name),children:(t.children||[]).slice(0,20).map(Xy),backgroundColor:Zy(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 eb(e){let t=[];for(let n of e)Qt(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 bm(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());By(t,s)}async function tb(e,t,n,s,o){if(t.length===0)return new Map;fm(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await Jr(()=>Yo(`/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=Vo(s,`frame-${u}.png`);try{await bm(d,m),l.set(c,m),M.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){M.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function nb(e,t,n,s,o){if(t.length===0)return[];fm(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 Jr(()=>Yo(`/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()}-${Hy().slice(0,6)}.png`,f=Vo(s,h);try{await bm(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),M.info("figma",`Downloaded asset: ${h}`)}catch(b){M.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function Sm(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 Jr(()=>Yo(i,n),o);M.info("figma",`Fetched file: ${r.name}`);let a=Wy(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.");M.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:Ky(a),typography:Vy(a),spacing:zy(a),effects:Yy(a)};M.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=Qy(a),d=Vo(s,".vibespot","figma-frames"),u=await tb(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=eb(a),h=Vo(s,"assets"),f=await nb(e,g,n,h,o);return M.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 xm(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 vm(e){return await Yo("/v1/me",e)}var Gy,Uy,gm,Lr,wm=R(()=>{"use strict";y();de();Gy=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;Uy="https://api.figma.com",gm=[10,20,40,60,120];Lr=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var _m={};Be(_m,{getCachedExtraction:()=>$m,handleFigmaExtractRoute:()=>Hr,handleFigmaGenerateRoute:()=>Gr,handleFigmaTestTokenRoute:()=>Br});import{randomUUID as Cm}from"crypto";import{existsSync as km,mkdirSync as Tm,writeFileSync as sb,copyFileSync as ob}from"fs";import{join as qo,basename as ib}from"path";function Am(){let e=Date.now();for(let[t,n]of bs)n.expires<e&&bs.delete(t)}function $m(e){Am();let t=bs.get(e);return t?(bs.delete(e),t.extraction):null}function Br(e,t){Ve(e,t,async n=>{let s=n.token||O().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await vm(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);M.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function Hr(e,t){Ve(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||O().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=hm(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-${Cm().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)}
2702
2702
 
2703
- `)};try{let c=await bm(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=wm();Tm(),bs.set(d,{extraction:c,expires:Date.now()+ib});let u=Sm(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})}e.end()})}function rb(t){let{designTokens:e,fileName:n}=t,s=[`# Styleguide \u2014 ${n}`,""];if(e.colors.length>0){s.push("## Colors","");let o=[...e.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(e.typography.length>0){s.push("## Typography","");let o=[...new Set(e.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 e.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(e.spacing.length>0){s.push("## Spacing","");let o=[...new Set(e.spacing.map(i=>i.value))].sort((i,r)=>i-r);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let i of e.spacing)s.push(`- **${i.property}** (${i.context}): ${i.value}px`);s.push("")}if(e.effects.length>0){s.push("## Effects","");for(let o of e.effects)o.boxShadow&&s.push(`- **Box shadow:** \`${o.boxShadow}\``),o.borderRadius&&s.push(`- **Border radius:** ${o.borderRadius}px`);s.push("")}return s.join(`
2704
- `)}function Ur(t,e){Ve(t,e,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(e,400,{error:"Missing extractionId or themeName"});return}let r=Am(s);if(!r){p(e,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=C();if(!a){p(e,400,{error:"No active session. Create a theme first."});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{e.write(`data: ${JSON.stringify(c)}
2703
+ `)};try{let c=await Sm(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=Cm();Am(),bs.set(d,{extraction:c,expires:Date.now()+rb});let u=xm(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);M.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 ab(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(`
2704
+ `)}function Gr(e,t){Ve(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=$m(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)}
2705
2705
 
2706
- `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=rb(r),d=qo(a.themePath,".vibespot");if(Cm(d)||km(d,{recursive:!0}),nb(qo(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,D(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)Tt("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(D(),i&&r.assets.length>0){let f=qo(a.themePath,"assets");km(f,{recursive:!0});let b=0;for(let S of r.assets)if(Cm(S.localPath)){let x=qo(f,ob(S.localPath));try{sb(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 us(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"?De({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(De({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Rt(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?(De({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});qt(g,{steps:u,modules:m,stats:g.stats}),ke(),Gt(a.themePath,`Figma import: ${r.fileName}`);let h=Se().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})}e.end()})}var bs,ib,Gr=R(()=>{"use strict";y();ze();Q();de();vm();we();Wn();Ui();dn();wn();Nt();bs=new Map,ib=1800*1e3});import{readdirSync as Vr,statSync as ab}from"fs";import{join as q,relative as lb}from"path";function Tn(t){let e=q(t,_t);if(!v(e))return null;try{return JSON.parse(M(e))}catch{return null}}function Zo(t,e){let n=q(t,_t);J(n,JSON.stringify(e,null,2)+`
2707
- `)}function Ss(t){let e=[];if(!v(t))return e.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${t}`}),Wr(t,e,null);let n=Kr(q(t,"theme.json"));if(!n)return e.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."}),Wr(t,e,Tn(t));ub(t,n,e),mb(t,n,e),pb(t,e),fb(t,e),hb(t,e),yb(t,e);let s=Tn(t);return bb(s,e),Wr(t,e,s)}function Wr(t,e,n){let s=e.filter(r=>r.severity==="error").length,o=e.filter(r=>r.severity==="warning").length,i=e.filter(r=>r.severity==="info").length;return{themePath:t,passed:s===0,errorCount:s,warningCount:o,infoCount:i,findings:e,metadata:n}}function ub(t,e,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 cb)yt(e,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 db)(!(r in e)||typeof e[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=e.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.'}):(yt(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."}),yt(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."}),yt(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=e.preview_path;if(typeof i=="string"&&i.length>0){let r=Im(t,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 mb(t,e,n){let s=e.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Im(t,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 pb(t,e){let n=q(t,"modules");if(!v(n)){e.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=Vr(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=q(n,i);gb(t,r,i,e)}s===0&&e.push({severity:"warning",rule:"modules.empty",message:"Theme has no .module directories",fix:"Generate at least one module before submitting to Marketplace."})}function gb(t,e,n,s){let o=Kr(q(e,"meta.json")),i=ot(t,q(e,"meta.json"));o?(yt(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(e,"fields.json"),a=ot(t,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=Kr(r);Array.isArray(c)?Mm(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(e,"module.html");v(l)||s.push({severity:"error",rule:"module.html.missing",file:ot(t,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function Mm(t,e,n,s){for(let o of t){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)";yt(i,"label")||s.push({severity:"error",rule:"module.field.label.missing",file:n,message:`${e}.${r}: field is missing "label"`,fix:`Add a human-readable "label" to the "${r}" field in fields.json.`,autoFixable:!0}),!yt(i,"help_text")&&i.type!=="group"&&s.push({severity:"info",rule:"module.field.help_text.missing",file:n,message:`${e}.${r}: consider adding "help_text"`,fix:`Add a short "help_text" describing what "${r}" controls.`}),Array.isArray(i.children)&&Mm(i.children,e,n,s)}}function fb(t,e){let n=[],s=q(t,"css");Xo(s,".css").forEach(i=>{_m(i,n,t)});let o=q(t,"modules");if(v(o))for(let i of xs(o)){if(!i.endsWith(".module"))continue;let r=q(o,i);["module.css","module.html"].forEach(a=>{let l=q(r,a);v(l)&&_m(l,n,t)})}for(let i of n)e.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 _m(t,e,n){let s;try{s=M(t)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&e.push({file:ot(n,t),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&e.push({file:ot(n,t),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&e.push({file:ot(n,t),match:r[0]})}function hb(t,e){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(t,"css");Xo(o,".css").forEach(a=>s.push(a));let i=q(t,"js");Xo(i,".js").forEach(a=>s.push(a));let r=q(t,"modules");if(v(r))for(let a of xs(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=q(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&&e.push({severity:"error",rule:c.rule,file:ot(t,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function yb(t,e){let n=q(t,"modules");if(v(n))for(let s of xs(n)){if(!s.endsWith(".module"))continue;let o=q(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)||e.push({severity:"warning",rule:"a11y.img.alt-missing",file:ot(t,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)||e.push({severity:"info",rule:"a11y.semantics.missing",file:ot(t,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 bb(t,e){if(!t){e.push({severity:"warning",rule:"marketplace.json.missing",file:_t,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}t.category?Lt.includes(t.category)||e.push({severity:"warning",rule:"marketplace.json.category.unknown",file:_t,message:`marketplace.json category "${t.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${Lt.join(", ")}.`}):e.push({severity:"warning",rule:"marketplace.json.category.missing",file:_t,message:"marketplace.json has no category",fix:`Pick one of: ${Lt.join(", ")}.`}),(!t.description||t.description.trim().length<40)&&e.push({severity:"warning",rule:"marketplace.json.description.short",file:_t,message:"marketplace.json description is missing or short (<40 chars)",fix:"Provide a 1\u20132 sentence description of the theme for the Marketplace listing."}),t.supportUrl||e.push({severity:"warning",rule:"marketplace.json.supportUrl.missing",file:_t,message:"marketplace.json has no supportUrl",fix:"Add a public support URL where buyers can reach the publisher."});let n=t.features?.length??0;n<2?e.push({severity:"warning",rule:"marketplace.json.features.too_few",file:_t,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&&e.push({severity:"warning",rule:"marketplace.json.features.too_many",file:_t,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function Qo(t){let e=[],n=[],s=q(t,"modules");if(v(s))for(let i of xs(s)){if(!i.endsWith(".module"))continue;let r=q(s,i),a=i.replace(/\.module$/,""),l=q(r,"meta.json");if(v(l))try{let d=JSON.parse(M(l));yt(d,"label")||(d.label=Pm(a),J(l,JSON.stringify(d,null,2)+`
2708
- `),e.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=q(r,"fields.json");if(v(c))try{let d=JSON.parse(M(c));if(Array.isArray(d)){let u=Em(d);u>0&&(J(c,JSON.stringify(d,null,2)+`
2709
- `),e.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=Sb(t);for(let i of o)e.push(`${i}: stripped external CDN reference(s)`);return{applied:e,skipped:n}}function Sb(t){let e=[],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&&(J(c,u),e.push(ot(t,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&&(J(c,u),e.push(ot(t,c)))}Xo(q(t,"css"),".css").forEach(r);let l=q(t,"modules");if(v(l))for(let c of xs(l)){if(!c.endsWith(".module"))continue;let d=q(l,c),u=q(d,"module.css"),m=q(d,"module.html");v(u)&&r(u),v(m)&&a(m)}return e}function Em(t){let e=0;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;!yt(s,"label")&&yt(s,"name")&&(s.label=Pm(String(s.name)),e++),Array.isArray(s.children)&&(e+=Em(s.children))}return e}function Kr(t){if(!v(t))return null;try{let e=JSON.parse(M(t));return e&&typeof e=="object"?e:null}catch{return null}}function yt(t,e){let n=t[e];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Im(t,e){let n=e.replace(/^\.?\//,"");return q(t,n)}function ot(t,e){return lb(t,e).split("\\").join("/")}function xs(t){try{return Vr(t)}catch{return[]}}function Xo(t,e){if(!v(t))return[];try{let n=[];for(let s of Vr(t)){let o=q(t,s);ab(o).isFile()&&s.endsWith(e)&&n.push(o)}return n}catch{return[]}}function Pm(t){return t.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}var Lt,cb,db,_t,zr=R(()=>{"use strict";y();ne();Lt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],cb=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],db=["enable_domain_stylesheets","is_available_for_new_content"],_t="marketplace.json"});function Yr(t){let e=C();if(!e)return p(t,400,{error:"No active theme. Open or create a theme first."}),null;try{ke()}catch{}return e.themePath}function Rm(t,e){let n=Yr(e);if(!n)return;let s=Ss(n);p(e,200,{report:s,categories:Lt})}function Nm(t,e){let n=Yr(e);if(!n)return;let s=Qo(n),o=Ss(n);p(e,200,{fix:s,report:o})}function Om(t,e,n){let s=Yr(n);if(s){if(t==="GET"){p(n,200,{metadata:Tn(s),categories:Lt});return}if(t==="POST"){Ve(e,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};Zo(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Fm=R(()=>{"use strict";y();ze();we();zr()});function xb(t){let e=C();if(!e)return p(t,400,{error:"No active theme. Open or fetch a theme first."}),null;try{ke()}catch{}return e.themePath}function jm(t,e){let n=xb(e);if(!n)return;let s=ho(n);p(e,200,{report:s})}function Dm(t,e){let n=C();if(!n){p(e,400,{error:"No active theme. Open or fetch a theme first."});return}let s=fn(n.themePath),o=Yn(s);if(!o){p(e,200,{applied:!1,reason:"No tokens to apply."});return}if(!n.sharedCss||n.sharedCss.trim().length===0){n.sharedCss=o,n.updatedAt=Date.now(),D(),p(e,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=yo(n.themePath,n.themeName);i?p(e,200,{applied:!0,written:i,rootBlock:o}):p(e,200,{applied:!1,reason:"Theme already has shared CSS."})}var Lm=R(()=>{"use strict";y();ze();we();bo()});import{createServer as vb}from"http";import{readFileSync as Xr,existsSync as vs}from"fs";import{join as Et,extname as Bm}from"path";import{WebSocketServer as wb,WebSocket as Cb}from"ws";function Ee(t){ti&&ti.readyState===Cb.OPEN&&ti.send(JSON.stringify(t))}function ei(t){ni.push(t),Ee(t)}function Mt(){ni=[]}function qr(t,e){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;ei(o)}else ei(n);if(n.type==="agent_step")t.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=t[t.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?De({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(De({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Rt(n.moduleOrder),ei({type:"modules_updated",modules:Se().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(De({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),ei({type:"modules_updated",modules:Se().map(s=>s.moduleName)}),e.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&e.push({name:n.module,status:"failed"})}}function yn(){return Um}function si(t){let{port:e,uiDir:n}=t;Um=t.contentMode||"page";let s=vb((i,r)=>kb(i,r,n)),o=new wb({server:s});return o.on("connection",i=>Ab(i)),new Promise((i,r)=>{s.on("error",a=>{a.code==="EADDRINUSE"?s.listen(e+1,"0.0.0.0",()=>{i({port:e+1,close:()=>{s.close(),o.close()}})}):r(a)}),s.listen(e,"0.0.0.0",()=>{i({port:e,close:()=>{s.close(),o.close()}})})})}function kb(t,e,n){let s=new URL(t.url||"/",`http://${t.headers.host}`),o=t.method||"GET";if(e.setHeader("X-Content-Type-Options","nosniff"),e.setHeader("X-Frame-Options","DENY"),e.setHeader("X-XSS-Protection","1; mode=block"),e.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname.startsWith("/api/")){Tb(o,s.pathname,t,e);return}if(s.pathname==="/preview"){let i=Vi();e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",r=zi(i);e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){$b(s.pathname.slice(14),e);return}if(s.pathname==="/docs"){e.writeHead(301,{Location:"/docs/"}),e.end();return}if(s.pathname.startsWith("/docs/")){let i=s.pathname.slice(5)||"/index.html";Jm(i,Et(n,"docs"),t,e);return}Jm(s.pathname,n,t,e)}function Tb(t,e,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"),t==="OPTIONS"){s.writeHead(204),s.end();return}switch(e){case"/api/session":sm(t,s);break;case"/api/modules":om(t,n,s);break;case"/api/modules/reorder":rm(n,s);break;case"/api/modules/code":im(n,s);break;case"/api/upload":am(s);break;case"/api/upload-files":t==="POST"?wc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":lm(n,s);break;case"/api/import":cm(n,s);break;case"/api/setup":tu(s);break;case"/api/setup/create":nu(n,s);break;case"/api/setup/fetch":ou(n,s);break;case"/api/setup/open":iu(n,s);break;case"/api/setup/resume":ru(n,s);break;case"/api/setup/apikey":au(n,s);break;case"/api/setup/remote-themes":t==="GET"?lu(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":t==="GET"?su(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":t==="GET"?gu(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":t==="POST"?fu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":t==="POST"?hu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":t==="POST"?yu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":t==="POST"?bu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":t==="POST"?Su(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":t==="POST"?xu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":t==="POST"?vu(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":t==="POST"?wu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":t==="POST"?Cu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":t==="POST"?ku(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":t==="POST"?_u(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":t==="GET"?Mu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":t==="POST"?Eu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":t==="POST"?Tu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":t==="GET"?p(s,200,{changelog:la()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Pu(t,n,s);break;case"/api/themes/switch":t==="POST"?Ru(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":t==="POST"?Nu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":t==="POST"?Ou(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":t==="POST"?Fu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":t==="GET"?dm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":t==="POST"?um(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":t==="GET"?Bu(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Uu(t,n,s);break;case"/api/templates/activate":t==="POST"?Gu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":t==="POST"?Wu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":t==="POST"?Vu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":t==="POST"?Ku(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":t==="GET"?zu(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":qu(t,n,s);break;case"/api/brand-kit":Qu(t,n,s);break;case"/api/fonts":t==="GET"?Zu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":t==="POST"?em(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":t==="POST"?tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":t==="GET"?Hu(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":t==="POST"?Br(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":t==="POST"?Hr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":t==="POST"?Ur(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":t==="POST"?Pd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":t==="POST"?Rd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":t==="GET"?Nd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":t==="POST"?Od(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":t==="GET"?Rm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":t==="POST"?Nm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Om(t,n,s);break;case"/api/inverse/analyze":t==="GET"?jm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":t==="POST"?Dm(n,s):p(s,405,{error:"Method not allowed"});break;default:e.startsWith("/api/settings/job/")&&t==="GET"?Au(e,s):e.match(/^\/api\/templates\/[^/]+\/add-module$/)&&t==="POST"?Yu(e,n,s):p(s,404,{error:"Not found"})}}function Ab(t){t.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{t.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(Tr()){tt("user",o),D();try{t.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await kr(o,d=>{a+=d,t.send(JSON.stringify({type:"stream",content:d}))},i),c=jd(l||a);c.plan&&(Po(c.plan),t.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&t.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),tt("assistant",c.cleanedContent),D(),t.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),t.send(JSON.stringify({type:"generation_complete"}))}catch(a){t.send(JSON.stringify({type:"error",message:a instanceof Error?a.message:String(a)}))}break}tt("user",o),D();let r=Ar();r.needsPrompt&&t.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Mt();let l=[],c=[],d=await Eo(o,qr(l,c),i);qt(d,{steps:l,modules:c,stats:d.stats})}else wr(l=>{Ee({type:"parse_warning",message:l})}),await ds(o,l=>{Ee({type:"stream",content:l})},l=>{Ee({type:"stream_status",content:l})},i);let a=C();if(a){ke();let l=Ce(),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=_i(a.themePath,l.id,o,d)}else c=Gt(a.themePath,o);c&&Ee({type:"version_created",hash:c})}Ee({type:"generation_complete"});{let l=C();Ee({type:"modules_updated",modules:Se().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}))})}Mt();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Ee({type:"suggest_brand_extraction"})}}catch(a){Mt(),Ee({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){t.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:r}=await Promise.resolve().then(()=>(Gr(),$m)),a=r(o);if(!a){t.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(()=>(Jn(),_a)),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),pn(S,i),D()}Ee({type:"figma_import_started",fileName:a.fileName}),Mt();let c=[],d=[],u=await us(a,i,qr(c,d));qt(u,{steps:c,modules:d,stats:u.stats}),ke(),Gt(C().themePath,`Figma import: ${a.fileName}`),Ee({type:"generation_complete"});{let m=C();Ee({type:"modules_updated",modules:Se().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}))})}Mt()}catch(l){Mt(),Ee({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=C();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=O(),{engine:r,apiKey:a,model:l}=vn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(es(),vo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(Bo(),Jo)),m=await 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=Et(o.themePath,".vibespot");vs(f)||g(f,{recursive:!0}),h(Et(f,"theme-context.md"),m),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(fs(),gs)),b=await f(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=Et(o.themePath,".vibespot");vs(S)||g(S,{recursive:!0}),h(Et(S,"styleguide.md"),b),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}t.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){t.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=C();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}try{ke();let i=Qs(o.themePath);if(i.length>0&&t.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(O().hubspotUploadMode||"api")==="api"){let l=Fe();if(!l){t.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}t.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await to(l,o.themePath,o.themeName,{onFileStart:d=>{t.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2710
- `}))},onFileComplete:d=>{t.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
2711
- `}))},onFileError:(d,u)=>{t.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
2712
- `}))},onProgress:(d,u)=>{t.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=It();t.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:yn()}))}else{let d=Xs(c.errors);t.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2713
- `),errors:d}))}}else{let l=No(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:Et(o.themePath,".."),timeout:18e4});t.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{t.send(JSON.stringify({type:"upload_output",chunk:u}))};Jd(l,c);let d=setInterval(()=>{let u=Ro(l);if(!(!u||u.status==="running"))if(clearInterval(d),Bd(l,c),u.status==="completed"){let m=dt(),g=m.portalId?Rn(m.portalId):"na1";t.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:yn()}))}else{let m=Zs(u.output);t.send(JSON.stringify({type:"upload_failed",output:u.output,errors:m,exitCode:u.exitCode}))}},500)}}catch(i){t.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()){t.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.
2706
+ `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=ab(r),d=qo(a.themePath,".vibespot");if(km(d)||Tm(d,{recursive:!0}),sb(qo(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,D(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)Tt("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(D(),i&&r.assets.length>0){let f=qo(a.themePath,"assets");Tm(f,{recursive:!0});let b=0;for(let S of r.assets)if(km(S.localPath)){let x=qo(f,ib(S.localPath));try{ob(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 us(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"?De({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(De({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Rt(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?(De({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});qt(g,{steps:u,modules:m,stats:g.stats}),ke(),Ut(a.themePath,`Figma import: ${r.fileName}`);let h=Se().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);M.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var bs,rb,Ur=R(()=>{"use strict";y();ze();Q();de();wm();we();Wn();Gi();dn();wn();Nt();bs=new Map,rb=1800*1e3});import{readdirSync as Vr,statSync as lb}from"fs";import{join as q,relative as cb}from"path";function Tn(e){let t=q(e,_t);if(!w(t))return null;try{return JSON.parse(E(t))}catch{return null}}function Zo(e,t){let n=q(e,_t);J(n,JSON.stringify(t,null,2)+`
2707
+ `)}function Ss(e){let t=[];if(!w(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),Wr(e,t,null);let n=Kr(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."}),Wr(e,t,Tn(e));mb(e,n,t),pb(e,n,t),gb(e,t),hb(e,t),yb(e,t),bb(e,t);let s=Tn(e);return Sb(s,t),Wr(e,t,s)}function Wr(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 mb(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 db)yt(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 ub)(!(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.'}):(yt(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."}),yt(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."}),yt(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=Pm(e,i);w(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 pb(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Pm(e,s);if(!w(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 gb(e,t){let n=q(e,"modules");if(!w(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=Vr(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=q(n,i);fb(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 fb(e,t,n,s){let o=Kr(q(t,"meta.json")),i=ot(e,q(t,"meta.json"));o?(yt(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=ot(e,r);if(!w(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=Kr(r);Array.isArray(c)?Mm(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");w(l)||s.push({severity:"error",rule:"module.html.missing",file:ot(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function Mm(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)";yt(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}),!yt(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)&&Mm(i.children,t,n,s)}}function hb(e,t){let n=[],s=q(e,"css");Xo(s,".css").forEach(i=>{Em(i,n,e)});let o=q(e,"modules");if(w(o))for(let i of xs(o)){if(!i.endsWith(".module"))continue;let r=q(o,i);["module.css","module.html"].forEach(a=>{let l=q(r,a);w(l)&&Em(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 Em(e,t,n){let s;try{s=E(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:ot(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:ot(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:ot(n,e),match:r[0]})}function yb(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");Xo(o,".css").forEach(a=>s.push(a));let i=q(e,"js");Xo(i,".js").forEach(a=>s.push(a));let r=q(e,"modules");if(w(r))for(let a of xs(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=q(r,a,l);w(c)&&s.push(c)});for(let a of s){let l;try{l=E(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:ot(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function bb(e,t){let n=q(e,"modules");if(w(n))for(let s of xs(n)){if(!s.endsWith(".module"))continue;let o=q(n,s,"module.html");if(!w(o))continue;let i;try{i=E(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:ot(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:ot(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 Sb(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:_t,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?Lt.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:_t,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${Lt.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:_t,message:"marketplace.json has no category",fix:`Pick one of: ${Lt.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:_t,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:_t,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:_t,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:_t,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function Qo(e){let t=[],n=[],s=q(e,"modules");if(w(s))for(let i of xs(s)){if(!i.endsWith(".module"))continue;let r=q(s,i),a=i.replace(/\.module$/,""),l=q(r,"meta.json");if(w(l))try{let d=JSON.parse(E(l));yt(d,"label")||(d.label=Rm(a),J(l,JSON.stringify(d,null,2)+`
2708
+ `),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(w(c))try{let d=JSON.parse(E(c));if(Array.isArray(d)){let u=Im(d);u>0&&(J(c,JSON.stringify(d,null,2)+`
2709
+ `),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=xb(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function xb(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=E(c)}catch{return}let u=d.replace(n,"");u!==d&&(J(c,u),t.push(ot(e,c)))}function a(c){let d;try{d=E(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(J(c,u),t.push(ot(e,c)))}Xo(q(e,"css"),".css").forEach(r);let l=q(e,"modules");if(w(l))for(let c of xs(l)){if(!c.endsWith(".module"))continue;let d=q(l,c),u=q(d,"module.css"),m=q(d,"module.html");w(u)&&r(u),w(m)&&a(m)}return t}function Im(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!yt(s,"label")&&yt(s,"name")&&(s.label=Rm(String(s.name)),t++),Array.isArray(s.children)&&(t+=Im(s.children))}return t}function Kr(e){if(!w(e))return null;try{let t=JSON.parse(E(e));return t&&typeof t=="object"?t:null}catch{return null}}function yt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Pm(e,t){let n=t.replace(/^\.?\//,"");return q(e,n)}function ot(e,t){return cb(e,t).split("\\").join("/")}function xs(e){try{return Vr(e)}catch{return[]}}function Xo(e,t){if(!w(e))return[];try{let n=[];for(let s of Vr(e)){let o=q(e,s);lb(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Rm(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var Lt,db,ub,_t,zr=R(()=>{"use strict";y();ne();Lt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],db=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],ub=["enable_domain_stylesheets","is_available_for_new_content"],_t="marketplace.json"});function Yr(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{ke()}catch{}return t.themePath}function Nm(e,t){let n=Yr(t);if(!n)return;let s=Ss(n);p(t,200,{report:s,categories:Lt})}function Om(e,t){let n=Yr(t);if(!n)return;let s=Qo(n),o=Ss(n);p(t,200,{fix:s,report:o})}function Fm(e,t,n){let s=Yr(n);if(s){if(e==="GET"){p(n,200,{metadata:Tn(s),categories:Lt});return}if(e==="POST"){Ve(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};Zo(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var jm=R(()=>{"use strict";y();ze();we();zr()});function vb(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{ke()}catch{}return t.themePath}function Dm(e,t){let n=vb(t);if(!n)return;let s=ho(n);p(t,200,{report:s})}function Lm(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=Yn(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(),D(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=yo(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 Jm=R(()=>{"use strict";y();ze();we();bo()});import{createServer as wb}from"http";import{readFileSync as Xr,existsSync as vs}from"fs";import{join as Mt,extname as Hm}from"path";import{WebSocketServer as Cb,WebSocket as kb}from"ws";function Me(e){ti&&ti.readyState===kb.OPEN&&ti.send(JSON.stringify(e))}function ei(e){ni.push(e),Me(e)}function Et(){ni=[]}function qr(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;ei(o)}else ei(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"?De({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(De({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Rt(n.moduleOrder),ei({type:"modules_updated",modules:Se().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(De({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),ei({type:"modules_updated",modules:Se().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 yn(){return Um}function si(e){let{port:t,uiDir:n}=e;Um=e.contentMode||"page";let s=wb((i,r)=>Tb(i,r,n)),o=new Cb({server:s});return o.on("connection",i=>$b(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 Tb(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/")){Ab(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=Vi();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=zi(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){_b(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";Bm(i,Mt(n,"docs"),e,t);return}Bm(s.pathname,n,e,t)}function Ab(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":om(e,s);break;case"/api/modules":im(e,n,s);break;case"/api/modules/reorder":am(n,s);break;case"/api/modules/code":rm(n,s);break;case"/api/upload":lm(s);break;case"/api/upload-files":e==="POST"?wc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":cm(n,s);break;case"/api/import":dm(n,s);break;case"/api/setup":nu(s);break;case"/api/setup/create":su(n,s);break;case"/api/setup/fetch":iu(n,s);break;case"/api/setup/open":ru(n,s);break;case"/api/setup/resume":au(n,s);break;case"/api/setup/apikey":lu(n,s);break;case"/api/setup/remote-themes":e==="GET"?cu(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?ou(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?fu(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?hu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?yu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?bu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?Su(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?xu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?vu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?wu(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?Cu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?ku(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Tu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Eu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Mu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Iu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Au(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:la()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Ru(e,n,s);break;case"/api/themes/switch":e==="POST"?Nu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Ou(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Fu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?ju(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?um(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?mm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Hu(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Uu(e,n,s);break;case"/api/templates/activate":e==="POST"?Wu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?Ku(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?zu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?Vu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?Yu(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":Xu(e,n,s);break;case"/api/brand-kit":em(e,n,s);break;case"/api/fonts":e==="GET"?Qu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?nm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Gu(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?Br(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?Hr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?Gr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Rd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Nd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Od(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?Fd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?Nm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?Om(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Fm(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Dm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Lm(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?$u(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?qu(t,n,s):p(s,404,{error:"Not found"})}}function $b(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(Tr()){tt("user",o),D();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await kr(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=Dd(l||a);c.plan&&(Po(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})),tt("assistant",c.cleanedContent),D(),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}tt("user",o),D();let r=Ar();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Et();let l=[],c=[],d=await Mo(o,qr(l,c),i);qt(d,{steps:l,modules:c,stats:d.stats})}else wr(l=>{Me({type:"parse_warning",message:l})}),await ds(o,l=>{Me({type:"stream",content:l})},l=>{Me({type:"stream_status",content:l})},i);let a=C();if(a){ke();let l=Ce(),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=_i(a.themePath,l.id,o,d)}else c=Ut(a.themePath,o);c&&Me({type:"version_created",hash:c})}Me({type:"generation_complete"});{let l=C();Me({type:"modules_updated",modules:Se().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}))})}Et();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Me({type:"suggest_brand_extraction"})}}catch(a){Et(),Me({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(()=>(Ur(),_m)),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(()=>(Jn(),_a)),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),pn(S,i),D()}Me({type:"figma_import_started",fileName:a.fileName}),Et();let c=[],d=[],u=await us(a,i,qr(c,d));qt(u,{steps:c,modules:d,stats:u.stats}),ke(),Ut(C().themePath,`Figma import: ${a.fileName}`),Me({type:"generation_complete"});{let m=C();Me({type:"modules_updated",modules:Se().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}))})}Et()}catch(l){Et(),Me({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=O(),{engine:r,apiKey:a,model:l}=vn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(es(),vo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(Bo(),Jo)),m=await 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=Mt(o.themePath,".vibespot");vs(f)||g(f,{recursive:!0}),h(Mt(f,"theme-context.md"),m),D(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(fs(),gs)),b=await f(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=Mt(o.themePath,".vibespot");vs(S)||g(S,{recursive:!0}),h(Mt(S,"styleguide.md"),b),D(),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{ke();let i=Qs(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(O().hubspotUploadMode||"api")==="api"){let l=Fe();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 to(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2710
+ `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
2711
+ `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
2712
+ `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=It();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:yn()}))}else{let d=Xs(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2713
+ `),errors:d}))}}else{let l=No(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:Mt(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}))};Bd(l,c);let d=setInterval(()=>{let u=Ro(l);if(!(!u||u.status==="running"))if(clearInterval(d),Hd(l,c),u.status==="completed"){let m=dt(),g=m.portalId?Rn(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:yn()}))}else{let m=Zs(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.
2714
2714
 
2715
2715
  IMPORTANT: Be verbose in your response. For each error:
2716
2716
  1. State exactly which file has the problem and what the error is
@@ -2723,9 +2723,9 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
2723
2723
  After fixing all errors, summarize the changes you made.
2724
2724
 
2725
2725
  Upload log:
2726
- ${o}`;tt("user",i),D(),t.send(JSON.stringify({type:"upload_fix_started"}));try{await ds(i,a=>{t.send(JSON.stringify({type:"stream",content:a})),t.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=C();if(r){ke();let a=Gt(r.themePath,"AI fix: upload errors");a&&t.send(JSON.stringify({type:"version_created",hash:a}))}t.send(JSON.stringify({type:"upload_fix_complete"}));{let a=C();t.send(JSON.stringify({type:"modules_updated",modules:Se().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){t.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":t.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=C();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.brandAssets?.plan;if(!i||!i.trim()){t.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.";tt("user",r),D();try{Mt();let a=[],l=[],c=await Eo(r,qr(a,l));qt(c,{steps:a,modules:l,stats:c.stats});let d=C();if(d){ke();let u=Ce(),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=_i(d.themePath,u.id,"Approved plan: implementation",g)}else m=Gt(d.themePath,"Approved plan: implementation");m&&Ee({type:"version_created",hash:m})}Ee({type:"generation_complete"});{let u=C();Ee({type:"modules_updated",modules:Se().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}))})}Mt()}catch(a){Mt(),Ee({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{_r(),Y({planMode:!1}),t.send(JSON.stringify({type:"plan_discarded"}));break}default:t.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),ti=t;let e=C();if(e){let n=O(),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=Ft(),i=Ce();if(t.send(JSON.stringify({type:"init",sessionId:e.id,themeName:e.themeName,modules:Se().map(r=>r.moduleName),messageCount:e.messages.length,messages:e.messages,gitAvailable:Qe(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",updatedAt:e.updatedAt,templateId:i?.id||null,pageType:i?.pageType||null,templates:(e.templates||[]).map(r=>({id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length})),planMode:!!n.planMode,plan:e.brandAssets?.plan||"",isGenerating:o})),o&&ni.length>0)for(let r of ni)t.send(JSON.stringify(r))}else t.send(JSON.stringify({type:"needs_setup"}))}function $b(t,e){let n=C();if(!n){e.writeHead(404,{"Content-Type":"text/plain"}),e.end("No session");return}let s=Et(n.themePath,"assets",t);if(!vs(s)){e.writeHead(404,{"Content-Type":"text/plain"}),e.end("Asset not found");return}let o=Bm(s),i=Hm[o]||"application/octet-stream",r=Xr(s);e.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),e.end(r)}function Jm(t,e,n,s){let i=Et(e,t==="/"?"/index.html":t);if(!vs(i)){let c=Et(e,"index.html");if(vs(c)){let d=Xr(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=Bm(i),a=Hm[r]||"application/octet-stream",l=r===".html";try{let c=Xr(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 Hm,ti,ni,Um,ts=R(()=>{"use strict";y();we();dn();es();wn();Fd();Dd();Q();Ht();eo();Oo();Ai();ze();ne();Wo();$u();Iu();ju();nm();mm();ir();Gr();Fm();Lm();Hm={".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"},ti=null,ni=[];Um="page"});y();y();import{Command as Jb}from"commander";y();y();at();ne();function Te(){let t=_.vibes,e=_.accent,n=_.muted,s=[`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B ")}${e("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${e(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\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")} ${_.dim(`v${sn()}`)}`),console.log()}y();Ht();xt();Jt();Q();Ut();Ye();at();async function Ls(){await me("Checking your environment");let t=En();t.found||(z("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Ns(t.version)||(z(`Node.js ${t.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),G(`Node.js v${t.version}`);let e=In();e.found||(z("Git not found. Install it from https://git-scm.com"),process.exit(1)),G(`Git ${e.version}`);let n=O(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Fe(),S=It();if(b)o=S?.portalId||"",i=S?.portalName||"",G(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{ee("No HubSpot account connected"),await ut(`You need a Personal Access Key to deploy themes.
2726
+ ${o}`;tt("user",i),D(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await ds(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){ke();let a=Ut(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:Se().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.";tt("user",r),D();try{Et();let a=[],l=[],c=await Mo(r,qr(a,l));qt(c,{steps:a,modules:l,stats:c.stats});let d=C();if(d){ke();let u=Ce(),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=_i(d.themePath,u.id,"Approved plan: implementation",g)}else m=Ut(d.themePath,"Approved plan: implementation");m&&Me({type:"version_created",hash:m})}Me({type:"generation_complete"});{let u=C();Me({type:"modules_updated",modules:Se().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}))})}Et()}catch(a){Et(),Me({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{_r(),Y({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),ti=e;let t=C();if(t){let n=O(),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=Ft(),i=Ce();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:Se().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:Qe(),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})),o&&ni.length>0)for(let r of ni)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function _b(e,t){let n=C();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=Mt(n.themePath,"assets",e);if(!vs(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Hm(s),i=Gm[o]||"application/octet-stream",r=Xr(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Bm(e,t,n,s){let i=Mt(t,e==="/"?"/index.html":e);if(!vs(i)){let c=Mt(t,"index.html");if(vs(c)){let d=Xr(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=Hm(i),a=Gm[r]||"application/octet-stream",l=r===".html";try{let c=Xr(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 Gm,ti,ni,Um,ts=R(()=>{"use strict";y();we();dn();es();wn();jd();Ld();Q();Ht();eo();Oo();Ai();ze();ne();Wo();_u();Pu();Du();sm();pm();ir();Ur();jm();Jm();Gm={".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"},ti=null,ni=[];Um="page"});y();y();import{Command as Bb}from"commander";y();y();at();ne();function Te(){let e=_.vibes,t=_.accent,n=_.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")} ${_.dim(`v${sn()}`)}`),console.log()}y();Ht();xt();Jt();Q();Gt();Ye();at();async function Ls(){await me("Checking your environment");let e=Mn();e.found||(z("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Ns(e.version)||(z(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),U(`Node.js v${e.version}`);let t=In();t.found||(z("Git not found. Install it from https://git-scm.com"),process.exit(1)),U(`Git ${t.version}`);let n=O(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Fe(),S=It();if(b)o=S?.portalId||"",i=S?.portalName||"",U(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{ee("No HubSpot account connected"),await ut(`You need a Personal Access Key to deploy themes.
2727
2727
  Create one at: https://app.hubspot.com/l/personal-access-key
2728
- Make sure the Content scope is enabled.`,"HubSpot connection required");let x=await be({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:P=>P.trim()?void 0:"Key is required"}),w=await Pe();w.start("Validating key...");try{let P=await js(x);An(x,P.portalId,P.portalName,P.dataCenter),b=x,o=P.portalId,i=P.portalName,w.stop(`Connected to ${P.portalName} (${P.portalId})`)}catch(P){w.stop("Validation failed"),z(`Invalid key: ${P instanceof Error?P.message:String(P)}`),process.exit(1)}}}else{let b=ct();if(b.found)G(`HubSpot CLI v${b.version}`);else{ee("HubSpot CLI not found"),await Ae({message:"Install HubSpot CLI globally?"})||(z("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let w=await Pe();w.start("Installing HubSpot CLI..."),te("npm install -g @hubspot/cli").success||(w.stop("Failed"),z("Try: npm install -g @hubspot/cli"),process.exit(1)),b=ct(),w.stop(`HubSpot CLI v${b.version} installed`)}let S=dt();if(S.authenticated)G(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{ee("HubSpot not authenticated"),await Ae({message:"Run `hs init` now?"})||(z("Run `hs init` manually."),process.exit(1));let w=await Pe();w.start("Waiting for HubSpot authentication..."),da("hs init")||(w.stop("Authentication failed"),process.exit(1)),S=dt(),w.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,i=S.portalName}let r=Pn(),a=Nn(),l=On(),c=ha(),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"},u=lt(),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 wt({message:"Choose your AI engine:",options:h});else if(await ut(`You need an AI coding assistant to power the conversion.
2728
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let x=await be({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:I=>I.trim()?void 0:"Key is required"}),v=await Pe();v.start("Validating key...");try{let I=await js(x);An(x,I.portalId,I.portalName,I.dataCenter),b=x,o=I.portalId,i=I.portalName,v.stop(`Connected to ${I.portalName} (${I.portalId})`)}catch(I){v.stop("Validation failed"),z(`Invalid key: ${I instanceof Error?I.message:String(I)}`),process.exit(1)}}}else{let b=ct();if(b.found)U(`HubSpot CLI v${b.version}`);else{ee("HubSpot CLI not found"),await Ae({message:"Install HubSpot CLI globally?"})||(z("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let v=await Pe();v.start("Installing HubSpot CLI..."),te("npm install -g @hubspot/cli").success||(v.stop("Failed"),z("Try: npm install -g @hubspot/cli"),process.exit(1)),b=ct(),v.stop(`HubSpot CLI v${b.version} installed`)}let S=dt();if(S.authenticated)U(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{ee("HubSpot not authenticated"),await Ae({message:"Run `hs init` now?"})||(z("Run `hs init` manually."),process.exit(1));let v=await Pe();v.start("Waiting for HubSpot authentication..."),da("hs init")||(v.stop("Authentication failed"),process.exit(1)),S=dt(),v.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,i=S.portalName}let r=Pn(),a=Nn(),l=On(),c=ha(),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=lt(),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,U(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await wt({message:"Choose your AI engine:",options:h});else if(await ut(`You need an AI coding assistant to power the conversion.
2729
2729
 
2730
2730
  ${_.bold("Option 1:")} Install Claude Code ${_.muted("(recommended)")}
2731
2731
  https://claude.ai/code
@@ -2738,12 +2738,12 @@ ${_.bold("Option 3:")} Install OpenAI Codex
2738
2738
 
2739
2739
  ${_.bold("Option 4:")} Set an Anthropic API key
2740
2740
  export ANTHROPIC_API_KEY=sk-ant-...
2741
- (get one at https://console.anthropic.com)`,"AI engine required"),m=await wt({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 be({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 wt({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 pe("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}Bs();y();Jt();ne();Ye();at();Q();Jn();Hs();import{join as Hn}from"path";async function Us(){await me("HubSpot Theme Setup");let t=await wt({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"}]}),e,n,s=Hn(process.cwd(),"workspace");if(Ie(s),t==="fetch"){e=await be({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=Hn(s,e);let l=await Pe();l.start("Fetching theme from HubSpot...");let c=O(),d=Fe();if(c.hubspotUploadMode==="cli"||!d)te(`hs cms fetch "${e}" "${n}"`).success||(l.stop("Fetch failed"),z(`Could not fetch theme "${e}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await Bn(d,e,n)}catch(u){l.stop("Fetch failed"),z(`Could not fetch theme "${e}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${_.dim(n)}`)}else{e=await be({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=Hn(s,e);let l=await Pe();l.start("Creating theme...");try{Ln(n,e)}catch(c){l.stop("Creation failed"),z(`Could not create theme "${e}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${_.dim(n)}`)}await me("Checking theme compatibility");let o=Hn(n,"templates/layouts/base.html");v(o)||(z(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),G("base.html found");let i=M(o),r=!1;if(i.includes("template_css"))G("template_css support");else{ee("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2741
+ (get one at https://console.anthropic.com)`,"AI engine required"),m=await wt({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 be({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 wt({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 pe("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}Bs();y();Jt();ne();Ye();at();Q();Jn();Hs();import{join as Hn}from"path";async function Gs(){await me("HubSpot Theme Setup");let e=await wt({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=Hn(process.cwd(),"workspace");if(Ie(s),e==="fetch"){t=await be({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=Hn(s,t);let l=await Pe();l.start("Fetching theme from HubSpot...");let c=O(),d=Fe();if(c.hubspotUploadMode==="cli"||!d)te(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),z(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await Bn(d,t,n)}catch(u){l.stop("Fetch failed"),z(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${_.dim(n)}`)}else{t=await be({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=Hn(s,t);let l=await Pe();l.start("Creating theme...");try{Ln(n,t)}catch(c){l.stop("Creation failed"),z(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${_.dim(n)}`)}await me("Checking theme compatibility");let o=Hn(n,"templates/layouts/base.html");w(o)||(z(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),U("base.html found");let i=E(o),r=!1;if(i.includes("template_css"))U("template_css support");else{ee("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2742
2742
  `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
2743
2743
  `,l);i=i.slice(0,c)+`
2744
2744
  {% if template_css %}
2745
2745
  {{ require_css(get_asset_url(template_css)) }}
2746
- {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))G("template_js support");else{ee("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2746
+ {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))U("template_js support");else{ee("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2747
2747
  `,l),d=i.indexOf(`
2748
2748
  `,c+1),u=`
2749
2749
  {% if template_js %}
@@ -2751,17 +2751,17 @@ ${_.bold("Option 4:")} Set an Anthropic API key
2751
2751
  {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
2752
2752
  `)+1;i=i.slice(0,i.indexOf(`
2753
2753
  `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
2754
- `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await Pe();l.start("Patching base.html..."),J(o,i),l.stop("base.html patched with template_css/template_js support")}let a=Hn(n,".hsignore");if(v(a)){let l=M(a);l.includes("docs/")||(J(a,l+`
2754
+ `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await Pe();l.start("Patching base.html..."),J(o,i),l.stop("base.html patched with template_css/template_js support")}let a=Hn(n,".hsignore");if(w(a)){let l=E(a);l.includes("docs/")||(J(a,l+`
2755
2755
  docs/
2756
- `),G("Added docs/ to .hsignore"))}else J(a,`docs/
2756
+ `),U("Added docs/ to .hsignore"))}else J(a,`docs/
2757
2757
  *.md
2758
2758
  node_modules/
2759
2759
  .git
2760
- `),G("Created .hsignore");return await pe("Theme ready!"),{themePath:n,themeName:e}}y();import{join as qe}from"path";import{readdirSync as Gn,rmSync as Ba}from"fs";y();Ue();ne();import{spawn as Pp}from"child_process";import{join as Z,basename as Rp}from"path";import{readdirSync as mt,statSync as La,writeFileSync as Np}from"fs";var Op=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"]),Gs=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(e){this.model=e}async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||fe();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(Z(s,"css")),c=this.listDir(Z(s,"js")),d=this.listDir(Z(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,w)=>{let P={...process.env};delete P.CLAUDECODE;let F=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&F.push("--model",this.model);let H=Pp("claude",F,{cwd:s,stdio:["pipe","pipe","pipe"],env:P,shell:!0});H.stdout.on("data",L=>{m+=L.toString()}),H.stderr.on("data",L=>{g+=L.toString()}),H.on("error",L=>w(new Error(`Claude Code failed to start: ${L.message}`))),H.on("close",L=>{L!==0?w(new Error(`Claude Code exited with code ${L}.
2760
+ `),U("Created .hsignore");return await pe("Theme ready!"),{themePath:n,themeName:t}}y();import{join as qe}from"path";import{readdirSync as Un,rmSync as Ba}from"fs";y();Ge();ne();import{spawn as Rp}from"child_process";import{join as Z,basename as Np}from"path";import{readdirSync as mt,statSync as La,writeFileSync as Op}from"fs";var Fp=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"]),Us=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||fe();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(Z(s,"css")),c=this.listDir(Z(s,"js")),d=this.listDir(Z(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,v)=>{let I={...process.env};delete I.CLAUDECODE;let F=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&F.push("--model",this.model);let H=Rp("claude",F,{cwd:s,stdio:["pipe","pipe","pipe"],env:I,shell:!0});H.stdout.on("data",L=>{m+=L.toString()}),H.stderr.on("data",L=>{g+=L.toString()}),H.on("error",L=>v(new Error(`Claude Code failed to start: ${L.message}`))),H.on("close",L=>{L!==0?v(new Error(`Claude Code exited with code ${L}.
2761
2761
  `+(g?`Stderr: ${g.slice(0,500)}
2762
- `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):x()}),H.stdin.on("error",()=>{}),H.stdin.write(u),H.stdin.end(),setTimeout(()=>{H.kill(),w(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let f=Z(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)+`
2762
+ `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):x()}),H.stdin.on("error",()=>{}),H.stdin.write(u),H.stdin.end(),setTimeout(()=>{H.kill(),v(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let f=Z(s,"..","vibespot-conversion.log");try{let v=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
2763
2763
  ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
2764
- `);Np(f,w,"utf-8"),o("status",`Log written to ${Rp(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)",w=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
2764
+ `);Op(f,v,"utf-8"),o("status",`Log written to ${Np(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)",v=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
2765
2765
 
2766
2766
  This usually means the model described the conversion instead of using Write tool to create files.
2767
2767
 
@@ -2770,23 +2770,23 @@ Possible causes:
2770
2770
  - Claude Code hit a rate limit or API error
2771
2771
  - The source directory was not accessible
2772
2772
 
2773
- Source: ${e.sourceDir}
2773
+ Source: ${t.sourceDir}
2774
2774
  Theme: ${s}
2775
- `+(w?`
2775
+ `+(v?`
2776
2776
  Stderr:
2777
- ${w}
2777
+ ${v}
2778
2778
  `:"")+`
2779
2779
  Claude output:
2780
- ${x}`)}return b}reportProgress(e,n,s,o,i,r){let a=0,l=this.listDir(Z(e,"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(Z(e,"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(e,i));let d=this.listModules(e);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(Z(e,"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(e,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
2780
+ ${x}`)}return b}reportProgress(t,n,s,o,i,r){let a=0,l=this.listDir(Z(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(Z(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(Z(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.
2781
2781
 
2782
- SOURCE DIRECTORY: ${e}
2782
+ SOURCE DIRECTORY: ${t}
2783
2783
  THEME DIRECTORY: ${n}
2784
2784
 
2785
2785
  IMPORTANT \u2014 YOU MUST CREATE REAL FILES:
2786
2786
  You have access to Write, Edit, Read, Glob, Grep, and Bash tools. You MUST use the Write tool to create each file. Do NOT just describe or list what files should be created \u2014 actually call the Write tool for every single file. If you do not call Write, no files will be created and the conversion will fail.
2787
2787
 
2788
2788
  STEP-BY-STEP PROCESS:
2789
- 1. Use Glob to find all .tsx/.jsx files in ${e}/src/
2789
+ 1. Use Glob to find all .tsx/.jsx files in ${t}/src/
2790
2790
  2. Use Read to read each component file and understand the page structure
2791
2791
  3. Use Write to create a shared CSS file at ${n}/css/<name>-theme.css
2792
2792
  - Include CSS custom properties, design system variables, utility classes
@@ -2823,13 +2823,13 @@ HUBSPOT CMS RULES:
2823
2823
  ${je()}
2824
2824
 
2825
2825
  CONVERSION GUIDE:
2826
- ${s}`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Z(e,"css");if(v(s)){for(let a of mt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(Z(s,a));break}}let o=Z(e,"js");if(v(o)){for(let a of mt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(Z(o,a));break}}let i=Z(e,"templates");if(v(i)){for(let a of mt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=M(Z(i,a));break}if(!n.template){for(let a of mt(i))if(a.endsWith(".html")&&!Op.has(a)&&!a.startsWith("system")){let l=M(Z(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of mt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(Z(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=Z(e,"modules");if(v(r))for(let a of mt(r)){if(!a.endsWith(".module"))continue;let l=Z(r,a);if(!La(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Z(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=Z(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=Z(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=Z(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=Z(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(e){let n=Z(e,"modules");return v(n)?new Set(mt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(e){return v(e)?new Set(mt(e)):new Set}detectExpectedModules(e,n){let s=Z(e,"templates");if(!v(s))return 0;for(let o of mt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=M(Z(s,o));if(i.includes("dnd_area")){let r=i.match(/dnd_module/g);return r?r.length:0}}catch{}return 0}countSourceComponents(e){let n=Z(e,"src");return v(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(e){let n=0;for(let s of mt(e)){let o=Z(e,s);try{La(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();Ue();ne();import Fp from"@anthropic-ai/sdk";import{join as re,basename as jp}from"path";import{readdirSync as Ja}from"fs";var Ws=class{client;model="claude-sonnet-4-6";constructor(e){this.client=new Fp({apiKey:e||process.env.ANTHROPIC_API_KEY})}async convert(e){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=e,r=Na(o),a=jp(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,Fa(c,d,l)),m=re(s,"css",`${l}-theme.css`);J(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,ja(g,h,l)),b=re(s,"js",`${l}-animations.js`);J(b,f),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let S=this.findComponents(n),x=[];for(let H=0;H<S.length;H++){let L=S[H],V=L.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${V}.module (${H+1}/${S.length})...`);let B=M(L.path),N=await this.complete(r,Oa(B,V,`See css/${l}-theme.css`));try{let T=JSON.parse(N),I={moduleName:V,fieldsJson:typeof T.fieldsJson=="string"?T.fieldsJson:JSON.stringify(T.fieldsJson,null,2),metaJson:typeof T.metaJson=="string"?T.metaJson:JSON.stringify(T.metaJson,null,2),moduleHtml:T.moduleHtml||"",moduleCss:T.moduleCss||"",moduleJs:T.moduleJs||void 0},k=re(s,"modules",`${V}.module`);Ie(k),J(re(k,"fields.json"),I.fieldsJson),J(re(k,"meta.json"),I.metaJson),J(re(k,"module.html"),I.moduleHtml),J(re(k,"module.css"),I.moduleCss),I.moduleJs&&J(re(k,"module.js"),I.moduleJs),x.push(I),i("module-done",`${V}.module (${this.countFiles(I)} files)`)}catch{i("module-error",`Failed to parse ${V} \u2014 skipping`)}}i("template","Creating page template...");let w=x.map(H=>H.moduleName),P=await this.complete(r,Da(w,a,l)),F=re(s,"templates",`lp-${l}.html`);return J(F,P),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:P,modules:x}}async complete(e,n){return(await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:e,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]})).content.find(i=>i.type==="text")?.text||""}findAndReadCSS(e){let n=[re(e,"src/index.css"),re(e,"src/globals.css"),re(e,"src/app/globals.css"),re(e,"app/globals.css")];for(let s of n)if(v(s))return M(s);return""}findAndReadTailwind(e){let n=[re(e,"tailwind.config.ts"),re(e,"tailwind.config.js"),re(e,"tailwind.config.mjs")];for(let s of n)if(v(s))return M(s);return""}findAndReadHooks(e){let n=re(e,"src/hooks");if(!v(n))return"";try{return Ja(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2827
- ${M(re(n,s))}`).join(`
2826
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Z(t,"css");if(w(s)){for(let a of mt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=E(Z(s,a));break}}let o=Z(t,"js");if(w(o)){for(let a of mt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=E(Z(o,a));break}}let i=Z(t,"templates");if(w(i)){for(let a of mt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=E(Z(i,a));break}if(!n.template){for(let a of mt(i))if(a.endsWith(".html")&&!Fp.has(a)&&!a.startsWith("system")){let l=E(Z(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of mt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=E(Z(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=Z(t,"modules");if(w(r))for(let a of mt(r)){if(!a.endsWith(".module"))continue;let l=Z(r,a);if(!La(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Z(l,"fields.json");w(d)&&(c.fieldsJson=E(d));let u=Z(l,"meta.json");w(u)&&(c.metaJson=E(u));let m=Z(l,"module.html");w(m)&&(c.moduleHtml=E(m));let g=Z(l,"module.css");w(g)&&(c.moduleCss=E(g));let h=Z(l,"module.js");w(h)&&(c.moduleJs=E(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=Z(t,"modules");return w(n)?new Set(mt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return w(t)?new Set(mt(t)):new Set}detectExpectedModules(t,n){let s=Z(t,"templates");if(!w(s))return 0;for(let o of mt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=E(Z(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=Z(t,"src");return w(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of mt(t)){let o=Z(t,s);try{La(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();Ge();ne();import jp from"@anthropic-ai/sdk";import{join as re,basename as Dp}from"path";import{readdirSync as Ja}from"fs";var Ws=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new jp({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=Na(o),a=Dp(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,Fa(c,d,l)),m=re(s,"css",`${l}-theme.css`);J(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,ja(g,h,l)),b=re(s,"js",`${l}-animations.js`);J(b,f),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let S=this.findComponents(n),x=[];for(let H=0;H<S.length;H++){let L=S[H],V=L.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${V}.module (${H+1}/${S.length})...`);let B=E(L.path),N=await this.complete(r,Oa(B,V,`See css/${l}-theme.css`));try{let T=JSON.parse(N),P={moduleName:V,fieldsJson:typeof T.fieldsJson=="string"?T.fieldsJson:JSON.stringify(T.fieldsJson,null,2),metaJson:typeof T.metaJson=="string"?T.metaJson:JSON.stringify(T.metaJson,null,2),moduleHtml:T.moduleHtml||"",moduleCss:T.moduleCss||"",moduleJs:T.moduleJs||void 0},k=re(s,"modules",`${V}.module`);Ie(k),J(re(k,"fields.json"),P.fieldsJson),J(re(k,"meta.json"),P.metaJson),J(re(k,"module.html"),P.moduleHtml),J(re(k,"module.css"),P.moduleCss),P.moduleJs&&J(re(k,"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 v=x.map(H=>H.moduleName),I=await this.complete(r,Da(v,a,l)),F=re(s,"templates",`lp-${l}.html`);return J(F,I),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:I,modules:x}}async complete(t,n){return(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}]})).content.find(i=>i.type==="text")?.text||""}findAndReadCSS(t){let n=[re(t,"src/index.css"),re(t,"src/globals.css"),re(t,"src/app/globals.css"),re(t,"app/globals.css")];for(let s of n)if(w(s))return E(s);return""}findAndReadTailwind(t){let n=[re(t,"tailwind.config.ts"),re(t,"tailwind.config.js"),re(t,"tailwind.config.mjs")];for(let s of n)if(w(s))return E(s);return""}findAndReadHooks(t){let n=re(t,"src/hooks");if(!w(n))return"";try{return Ja(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2827
+ ${E(re(n,s))}`).join(`
2828
2828
 
2829
- `)}catch{return""}}findInteractiveComponents(e){let n=this.findComponents(e),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}
2829
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=E(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
2830
2830
  ${i}`)}return s.join(`
2831
2831
 
2832
- `)}findComponents(e){let n=[re(e,"src/components/landing"),re(e,"src/components/sections"),re(e,"src/components")];for(let s of n)if(v(s))try{return Ja(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:re(s,o)}))}catch{continue}return[]}countFiles(e){let n=3;return e.moduleCss&&n++,e.moduleJs&&n++,n}};y();Ue();ne();import{spawn as Dp}from"child_process";import{join as Ge}from"path";import{readdirSync as Ks,statSync as Lp}from"fs";var Vs=class{async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||fe(),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=Dp("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(e,n,s){return`Read the conversion guide below, then convert the React landing page at ${e} into native HubSpot CMS modules for the theme at ${n}.
2832
+ `)}findComponents(t){let n=[re(t,"src/components/landing"),re(t,"src/components/sections"),re(t,"src/components")];for(let s of n)if(w(s))try{return Ja(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:re(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();Ge();ne();import{spawn as Lp}from"child_process";import{join as Ue}from"path";import{readdirSync as Ks,statSync as Jp}from"fs";var Vs=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||fe(),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=Lp("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}.
2833
2833
 
2834
2834
  INSTRUCTIONS:
2835
2835
  1. Analyze all .tsx/.jsx components in the React source
@@ -2844,7 +2844,7 @@ CONVERSION GUIDE:
2844
2844
  ${s}
2845
2845
 
2846
2846
  Do NOT run hs upload \u2014 I will handle that separately.
2847
- Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ge(e,"css");if(v(s)){for(let a of Ks(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(Ge(s,a));break}}let o=Ge(e,"js");if(v(o)){for(let a of Ks(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(Ge(o,a));break}}let i=Ge(e,"templates");if(v(i)){for(let a of Ks(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(Ge(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ge(e,"modules");if(v(r))for(let a of Ks(r)){if(!a.endsWith(".module"))continue;let l=Ge(r,a);if(!Lp(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ge(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=Ge(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=Ge(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=Ge(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=Ge(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ue();ne();import{spawn as Jp}from"child_process";import{join as We}from"path";import{readdirSync as zs,statSync as Bp}from"fs";var Ys=class{async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||fe(),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=Jp("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(e,n,s){return`Read the conversion guide below, then convert the React landing page at ${e} into native HubSpot CMS modules for the theme at ${n}.
2847
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ue(t,"css");if(w(s)){for(let a of Ks(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=E(Ue(s,a));break}}let o=Ue(t,"js");if(w(o)){for(let a of Ks(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=E(Ue(o,a));break}}let i=Ue(t,"templates");if(w(i)){for(let a of Ks(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=E(Ue(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ue(t,"modules");if(w(r))for(let a of Ks(r)){if(!a.endsWith(".module"))continue;let l=Ue(r,a);if(!Jp(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ue(l,"fields.json");w(d)&&(c.fieldsJson=E(d));let u=Ue(l,"meta.json");w(u)&&(c.metaJson=E(u));let m=Ue(l,"module.html");w(m)&&(c.moduleHtml=E(m));let g=Ue(l,"module.css");w(g)&&(c.moduleCss=E(g));let h=Ue(l,"module.js");w(h)&&(c.moduleJs=E(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ge();ne();import{spawn as Bp}from"child_process";import{join as We}from"path";import{readdirSync as zs,statSync as Hp}from"fs";var Ys=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||fe(),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=Bp("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}.
2848
2848
 
2849
2849
  INSTRUCTIONS:
2850
2850
  1. Analyze all .tsx/.jsx components in the React source
@@ -2859,15 +2859,15 @@ CONVERSION GUIDE:
2859
2859
  ${s}
2860
2860
 
2861
2861
  Do NOT run hs upload \u2014 I will handle that separately.
2862
- Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=We(e,"css");if(v(s)){for(let a of zs(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(We(s,a));break}}let o=We(e,"js");if(v(o)){for(let a of zs(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(We(o,a));break}}let i=We(e,"templates");if(v(i)){for(let a of zs(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(We(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=We(e,"modules");if(v(r))for(let a of zs(r)){if(!a.endsWith(".module"))continue;let l=We(r,a);if(!Bp(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=We(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=We(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=We(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=We(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=We(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ue();ne();Ye();function Hp(t,e){switch(t){case"claude-code":return new Gs(e);case"gemini-cli":return new Vs;case"codex-cli":return new Ys;case"api":return new Ws}}async function qs(t){await me("Converting React to HubSpot Modules"),await ut(`AI will now analyze your React code and create
2863
- HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let e=Hp(t.aiEngine,t.model),n=fe(),s=await Pe();s.start("Starting AI conversion...");let o=Date.now(),i=await e.convert({sourceDir:t.sourceDir,themePath:t.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=Up(t.themePath);for(let h of a)G(`Auto-fixed: ${h}`);let l=Gp(t.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(`
2862
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=We(t,"css");if(w(s)){for(let a of zs(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=E(We(s,a));break}}let o=We(t,"js");if(w(o)){for(let a of zs(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=E(We(o,a));break}}let i=We(t,"templates");if(w(i)){for(let a of zs(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=E(We(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=We(t,"modules");if(w(r))for(let a of zs(r)){if(!a.endsWith(".module"))continue;let l=We(r,a);if(!Hp(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=We(l,"fields.json");w(d)&&(c.fieldsJson=E(d));let u=We(l,"meta.json");w(u)&&(c.metaJson=E(u));let m=We(l,"module.html");w(m)&&(c.moduleHtml=E(m));let g=We(l,"module.css");w(g)&&(c.moduleCss=E(g));let h=We(l,"module.js");w(h)&&(c.moduleJs=E(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ge();ne();Ye();function Gp(e,t){switch(e){case"claude-code":return new Us(t);case"gemini-cli":return new Vs;case"codex-cli":return new Ys;case"api":return new Ws}}async function qs(e){await me("Converting React to HubSpot Modules"),await ut(`AI will now analyze your React code and create
2863
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=Gp(e.aiEngine,e.model),n=fe(),s=await Pe();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"?U(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=Up(e.themePath);for(let h of a)U(`Auto-fixed: ${h}`);let l=Wp(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(`
2864
2864
  ${d}/${l.length} checks passed`),await ut(c.join(`
2865
2865
  `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(z(`${u.length} critical issue(s) \u2014 upload will likely fail:
2866
2866
  `+u.map(f=>` - ${f.label}`).join(`
2867
2867
  `)),!await Ae({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&ee(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2868
2868
  `+m.map(h=>` - ${h.label}`).join(`
2869
- `));let g=qe(t.themePath,"..","vibespot-conversion.log");return v(g)&&(await Ae({message:"Keep conversion log file for debugging?",initialValue:!1})?G(`Log saved: ${g}`):Ba(g)),await pe("Files ready for upload!"),i}function Up(t){let e=[];Wp(t),Kp(t);let n=qe(t,"modules");if(v(n))for(let o of Gn(n)){if(!o.endsWith(".module"))continue;let i=qe(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,e.push(`${r}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(a)&&(a=a.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,e.push(`${r}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(a),u=!1;Ha(d)&&(u=!0,e.push(`${r}: fixed choice field format`)),Ua(d)&&(u=!0,e.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2870
- `,l=!0)}catch{e.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&J(i,a);let c=qe(n,o,"module.html");if(v(c)){let d=M(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),J(c,d),e.push(`${r}: now() \u2192 local_dt`))}}let s=qe(t,"templates");if(v(s))for(let o of Gn(s)){if(!o.endsWith(".html"))continue;let i=qe(s,o),r=M(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(Ba(i),e.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return e}function Ha(t){let e=!1;for(let n of t){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}),e=!0),Array.isArray(s.children)&&Ha(s.children)&&(e=!0)}return e}function Ua(t){let e=!1;for(let n of t){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},e=!0}}Array.isArray(s.children)&&Ua(s.children)&&(e=!0)}return e}function Gp(t,e){let n=[],s=e.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of e.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=e.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let r=e.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=e.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:e.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:e.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:e.template.length>0&&e.template.includes("dnd_area"),critical:!0});let c=qe(t,"templates"),d=!1;if(v(c))for(let u of Gn(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=M(qe(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 Wp(t){let e=qe(t,"templates");if(v(e))for(let n of Gn(e)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=qe(e,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+=`
2869
+ `));let g=qe(e.themePath,"..","vibespot-conversion.log");return w(g)&&(await Ae({message:"Keep conversion log file for debugging?",initialValue:!1})?U(`Log saved: ${g}`):Ba(g)),await pe("Files ready for upload!"),i}function Up(e){let t=[];Kp(e),Vp(e);let n=qe(e,"modules");if(w(n))for(let o of Un(n)){if(!o.endsWith(".module"))continue;let i=qe(n,o,"fields.json");if(!w(i))continue;let r=o.replace(".module",""),a=E(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;Ha(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),Ga(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2870
+ `,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&J(i,a);let c=qe(n,o,"module.html");if(w(c)){let d=E(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),J(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=qe(e,"templates");if(w(s))for(let o of Un(s)){if(!o.endsWith(".html"))continue;let i=qe(s,o),r=E(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(Ba(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Ha(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)&&Ha(s.children)&&(t=!0)}return t}function Ga(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)&&Ga(s.children)&&(t=!0)}return t}function Wp(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=qe(e,"templates"),d=!1;if(w(c))for(let u of Un(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=E(qe(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 Kp(e){let t=qe(e,"templates");if(w(t))for(let n of Un(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=qe(t,n),o=E(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+=`
2871
2871
  templateType: page`),r||(c+=`
2872
2872
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
2873
2873
  label: ${a}`),o=c+o.slice(l)}else o=`<!--
@@ -2875,11 +2875,11 @@ ${d}/${l.length} checks passed`),await ut(c.join(`
2875
2875
  isAvailableForNewContent: true
2876
2876
  label: ${a}
2877
2877
  -->
2878
- `+o;J(s,o),G(`Template "${n}" \u2014 annotations verified`)}}function Kp(t){let e=qe(t,"modules");if(v(e))for(let n of Gn(e)){if(!n.endsWith(".module"))continue;let s=qe(e,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&&J(s,JSON.stringify(o,null,2)+`
2879
- `)}catch{}}}y();Jt();Ye();eo();Q();Ai();import{join as nl,basename as ng}from"path";function sg(t){return(t.match(/^Uploaded file /gm)||[]).length}async function cn(t){await me("Uploading to HubSpot");let e=ng(t)||t,n=O(),s=Fe(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await Pe(),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 to(s,t,e,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Xs(m.errors)}else{let m=te(`hs cms upload "${t}" "${e}"`,{cwd:nl(t,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2880
- `);c=sg(g),d=m.success,d||(l=Zs(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await pe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(z("Upload failed with unknown error."),c>0&&(ee(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2881
- You can check your HubSpot Design Manager to verify.`),await Ae({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Ae({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?Ga(t,m)?(G(`Auto-fixed: ${m.message}`),u=!0):ee(`Could not auto-fix: ${m.message}`):z(m.message);if(!(u&&a<r)){if(c>0&&(ee(`${c} files uploaded successfully despite errors.
2882
- The theme may work \u2014 check HubSpot Design Manager.`),await Ae({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await bi(s,`${e}/modules`)}catch{}else te(`hs cms delete "${e}/modules"`,{cwd:nl(t,"..")});i.stop("Cleaned up modules, retrying...")}}}return z("Upload failed after multiple attempts."),!1}y();Ye();at();Ht();ne();import{execFileSync as $i}from"child_process";import{rmSync as og}from"fs";import{basename as sl}from"path";async function ol(t){let{portalId:e,sourceDir:n,themePath:s,wasCloned:o}=t;await me("You're all set!");let r=Rn(e)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await ut(`Your React page has been converted and uploaded to HubSpot.
2878
+ `+o;J(s,o),U(`Template "${n}" \u2014 annotations verified`)}}function Vp(e){let t=qe(e,"modules");if(w(t))for(let n of Un(t)){if(!n.endsWith(".module"))continue;let s=qe(t,n,"meta.json");if(w(s))try{let o=JSON.parse(E(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&&J(s,JSON.stringify(o,null,2)+`
2879
+ `)}catch{}}}y();Jt();Ye();eo();Q();Ai();import{join as nl,basename as sg}from"path";function og(e){return(e.match(/^Uploaded file /gm)||[]).length}async function cn(e){await me("Uploading to HubSpot");let t=sg(e)||e,n=O(),s=Fe(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await Pe(),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 to(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Xs(m.errors)}else{let m=te(`hs cms upload "${e}" "${t}"`,{cwd:nl(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2880
+ `);c=og(g),d=m.success,d||(l=Zs(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await pe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(z("Upload failed with unknown error."),c>0&&(ee(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2881
+ You can check your HubSpot Design Manager to verify.`),await Ae({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Ae({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?Ua(e,m)?(U(`Auto-fixed: ${m.message}`),u=!0):ee(`Could not auto-fix: ${m.message}`):z(m.message);if(!(u&&a<r)){if(c>0&&(ee(`${c} files uploaded successfully despite errors.
2882
+ The theme may work \u2014 check HubSpot Design Manager.`),await Ae({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 te(`hs cms delete "${t}/modules"`,{cwd:nl(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return z("Upload failed after multiple attempts."),!1}y();Ye();at();Ht();ne();import{execFileSync as $i}from"child_process";import{rmSync as ig}from"fs";import{basename as sl}from"path";async function ol(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await me("You're all set!");let r=Rn(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await ut(`Your React page has been converted and uploaded to HubSpot.
2883
2883
  The theme and modules are now in your account, but you still
2884
2884
  need to ${_.bold("create a new landing page")} that uses them.
2885
2885
 
@@ -2891,15 +2891,15 @@ Next steps:
2891
2891
  ${_.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
2892
2892
  ${_.bold("5.")} Click each section to edit text, images, and colors
2893
2893
  ${_.bold("6.")} Upload images via File Manager ${_.muted("(Settings \u2192 Files)")}
2894
- ${_.bold("7.")} Preview and publish!`,"What's next"),await Ae({message:"Open HubSpot Landing Pages in your browser?"})){let c=e?`https://${r}/page-ui/${e}/management/pages/landing`:`https://${r}`;try{let d=process.platform;d==="darwin"?$i("open",[c],{stdio:"ignore"}):d==="win32"?$i("cmd",["/c","start","",c],{stdio:"ignore"}):$i("xdg-open",[c],{stdio:"ignore"}),G("Opening HubSpot Landing Pages...")}catch{j(`Open this URL in your browser: ${_.info(c)}`)}}let l=[];if(o&&v(n)&&l.push({path:n,label:`Cloned source (${sl(n)})`}),v(s)&&l.push({path:s,label:`Theme directory (${sl(s)})`}),l.length>0&&await Ae({message:"Clean up local working directories?"}))for(let d of l)try{og(d.path,{recursive:!0,force:!0}),G(`Removed ${d.label}`)}catch{ee(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await pe(`Thanks for using hub${_.vibes("Vibes")}! ${_.vibes("~")}`)}Q();async function il(){Te();let t=await Ls(),e=await Js();Y({lastSourcePath:e.sourceDir});let n=await Us();Y({lastThemePath:n.themePath}),await qs({aiEngine:t.aiEngine,model:t.model,sourceDir:e.sourceDir,themePath:n.themePath}),await cn(n.themePath),await ol({portalId:t.portalId,sourceDir:e.sourceDir,themePath:n.themePath,wasCloned:e.wasCloned})}y();async function rl(){Te(),await Ls()}y();Bs();Q();Ye();async function al(){Te();let t=O();t.aiEngine||(z("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let e=await Js(),n=await Us();await qs({aiEngine:t.aiEngine,sourceDir:e.sourceDir,themePath:n.themePath})}y();Q();Ye();async function ll(){Te();let t=O();if(t.lastThemePath)if(await Ae({message:`Upload from ${t.lastThemePath}?`}))await cn(t.lastThemePath);else{let n=await be({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await cn(n)}else{let e=await be({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await cn(e)}}y();Ht();Q();Ye();at();async function cl(){Te(),await me("Environment Diagnostics");let t=0,e=En();e.found?Ns(e.version)?G(`Node.js v${e.version}`):(ee(`Node.js v${e.version} \u2014 too old (need 18+)`),j(" Update at https://nodejs.org"),t++):(z("Node.js \u2014 not installed"),j(" Install from https://nodejs.org"),t++);let n=In();n.found?G(`Git ${n.version}`):(z("Git \u2014 not installed"),j(" Install from https://git-scm.com"),t++);let s=ct();if(!s.found)ee("HubSpot CLI \u2014 not installed (only needed for deployment)"),j(" Install: npm install -g @hubspot/cli");else if(!ya(s.version))ee(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),j(" Update: npm install -g @hubspot/cli@latest"),t++;else{G(`HubSpot CLI v${s.version}`);let m=dt();m.authenticated?G(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(ee("HubSpot \u2014 not authenticated"),j(" Run: hs init"))}let o=Pn();o.found?G(`Claude Code ${o.version} at ${o.path}`):j(_.muted("Claude Code \u2014 not installed"));let i=Nn();i.found?G(`Gemini CLI ${i.version} at ${i.path}`):j(_.muted("Gemini CLI \u2014 not installed"));let r=On();r.found?G(`OpenAI Codex ${r.version} at ${r.path}`):j(_.muted("OpenAI Codex \u2014 not installed"));let a=O(),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"):j(_.muted("Anthropic API key \u2014 not set")),c?G("OpenAI API key configured"):j(_.muted("OpenAI API key \u2014 not set")),d?G("Google AI API key configured"):j(_.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&&j(_.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(ee("No AI engine available"),j(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),j(" Or install: Claude Code \u2014 https://claude.ai/code"),j(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),j(" Codex CLI \u2014 https://github.com/openai/codex"),t++),console.log(),t===0?await pe("Everything looks good!"):await pe(_.warn(`${t} issue${t>1?"s":""} found \u2014 see above`))}y();ts();we();import{dirname as _b,join as oi}from"path";import{existsSync as Mb}from"fs";import{fileURLToPath as Eb}from"url";import{execFileSync as Zr}from"child_process";import ii from"chalk";var Gm=_b(Eb(import.meta.url)),Ib=4200;async function Wm(){let t=ii.hex("#e8613a"),e=ii.dim;console.log(""),console.log(t(" v vibeSpot")),console.log(e(` Starting...
2895
- `));let n=Pb();n||(console.error(ii.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await si({port:Ib,uiDir:n}),i=`http://localhost:${s}`;console.log(t(` v ${i}`)),console.log(e(` Press Ctrl+C to stop
2896
- `));try{process.platform==="darwin"?Zr("open",[i],{stdio:"ignore"}):process.platform==="win32"?Zr("cmd",["/c","start","",i],{stdio:"ignore"}):Zr("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(e(`
2897
- Saving session...`)),D(),o(),console.log(e(` Goodbye!
2898
- `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(ii.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Pb(){let t=[oi(Gm,"../../ui"),oi(Gm,"../ui"),oi(process.cwd(),"ui")];for(let e of t)if(Mb(oi(e,"index.html")))return e;return null}y();import{resolve as Km}from"path";import{existsSync as Qr}from"fs";at();Ye();Q();zr();async function Vm(t={}){let e=await Ym(t.path);if(t.fix){let o=Qo(e);if(o.applied.length>0){G(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)j(` ${i}`)}else j(_.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)ee(i)}let n=Ss(e);if(t.json){process.stdout.write(JSON.stringify(n,null,2)+`
2899
- `),n.passed||process.exit(1);return}Te(),await me("Marketplace check");let s=`${n.errorCount} error${ta(n.errorCount)}, ${n.warningCount} warning${ta(n.warningCount)}, ${n.infoCount} note${ta(n.infoCount)}`;n.passed?G(`Theme passes Marketplace checks (${s}).`):z(`Theme is not yet ready: ${s}.`),ea("Errors",n.findings.filter(o=>o.severity==="error")),ea("Warnings",n.findings.filter(o=>o.severity==="warning")),ea("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(j(""),j(`Tip: run ${_.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await pe("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function zm(t={}){let e=await Ym(t.path);Te(),await me("Marketplace listing details");let n=Tn(e)??{},s=await wt({message:"Category",options:Lt.map(u=>({value:u,label:u}))}),o=await be({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 be({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 be({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 be({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 wt({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};Zo(e,d),G("Saved marketplace.json"),await pe(`Run ${_.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function Ym(t){if(t){let o=Km(t);if(!Qr(o))throw new Error(`Theme not found: ${o}`);return o}let e=O();if(e.lastThemePath&&Qr(e.lastThemePath))return e.lastThemePath;Te();let n=await be({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Km(n);if(!Qr(s))throw new Error(`Theme not found: ${s}`);return s}function ea(t,e){if(e.length!==0){j(""),j(_.heading(t));for(let n of e){let s=n.file?_.muted(`[${n.file}] `):"",o=n.severity==="error"?_.error("\u2717"):n.severity==="warning"?_.warn("!"):_.muted("\xB7");j(` ${o} ${s}${n.message}`),n.fix&&j(` ${_.muted("\u2192 "+n.fix)}`)}}}function ta(t){return t===1?"":"s"}y();import{resolve as qm}from"path";import{existsSync as na}from"fs";import{basename as Rb}from"path";at();Ye();Q();bo();async function Xm(t={}){let e=await Nb(t.path),n=Rb(e);if(t.applyTokens){let i=yo(e,n);i?G(`Wrote design tokens to ${i}`):j(_.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(t.snapshot){let i=Li(e);t.json||G(`Wrote imported theme snapshot to ${i}`)}let s=ho(e);t.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
2900
- `),process.exit(0)),Te(),await me("Inverse pipeline analyzer");let o=s.summary;if(j(`${_.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){j(""),j(_.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?_.muted(` (${i.varName})`):"";j(` ${i.value} ${_.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){j(""),j(_.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))j(` ${i}`)}if(s.graph.templates.length>0){j(""),j(_.heading("Template \u2192 modules"));for(let i of s.graph.templates)j(` ${i.id}: ${i.modules.length===0?_.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){j(""),j(_.heading("Orphan modules"));for(let i of s.graph.orphanModules)j(` ${i}`)}if(s.roundTripDiff.hasSnapshot){j(""),j(_.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)j(` ${_.muted("No changes from imported snapshot.")}`);else{j(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))j(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&j(` ${_.muted(`...and ${i.files.length-12} more`)}`)}}sa("Errors",s.findings.filter(i=>i.severity==="error")),sa("Warnings",s.findings.filter(i=>i.severity==="warning")),sa("Notes",s.findings.filter(i=>i.severity==="info")),!t.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(j(""),j(`Tip: run ${_.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await pe("Analysis complete."),process.exit(0)}async function Nb(t){if(t){let o=qm(t);if(!na(o))throw new Error(`Theme not found: ${o}`);return o}let e=O();if(e.lastThemePath&&na(e.lastThemePath))return e.lastThemePath;Te();let n=await be({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=qm(n);if(!na(s))throw new Error(`Theme not found: ${s}`);return s}function sa(t,e){if(e.length!==0){j(""),j(_.heading(t));for(let n of e){let s=n.file?_.muted(`[${n.file}] `):"",o=n.severity==="error"?_.error("\u2717"):n.severity==="warning"?_.warn("!"):_.muted("\xB7");j(` ${o} ${s}${n.message}`),n.fix&&j(` ${_.muted("\u2192 "+n.fix)}`)}}}y();ts();we();import{dirname as Ob,join as ri}from"path";import{existsSync as Fb}from"fs";import{fileURLToPath as jb}from"url";import{execFileSync as oa}from"child_process";import ai from"chalk";var Zm=Ob(jb(import.meta.url)),Db=4200;async function Qm(){let t=ai.hex("#e8613a"),e=ai.dim;console.log(""),console.log(t(" v vibeSpot \u2014 Email Mode")),console.log(e(` Starting...
2901
- `));let n=Lb();n||(console.error(ai.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await si({port:Db,uiDir:n,contentMode:"email"}),i=`http://localhost:${s}`;console.log(t(` v ${i}`)),console.log(e(` Email template mode \u2014 Press Ctrl+C to stop
2902
- `));try{process.platform==="darwin"?oa("open",[i],{stdio:"ignore"}):process.platform==="win32"?oa("cmd",["/c","start","",i],{stdio:"ignore"}):oa("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(e(`
2903
- Saving session...`)),D(),o(),console.log(e(` Goodbye!
2904
- `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(ai.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Lb(){let t=[ri(Zm,"../../ui"),ri(Zm,"../ui"),ri(process.cwd(),"ui")];for(let e of t)if(Fb(ri(e,"index.html")))return e;return null}ne();function ep(){let t=new Jb;t.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(sn()).action(Wm),t.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(il),t.command("init").description("Check and install required tools").action(rl),t.command("convert").description("Convert a React project to HubSpot modules").action(al),t.command("upload").description("Upload theme to HubSpot").action(ll),t.command("doctor").description("Diagnose environment issues").action(cl);let e=t.command("marketplace").description("Prepare a theme for HubSpot Marketplace submission");return e.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=>Vm(n)),e.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>zm(n)),t.command("email").description("Launch email template generation mode").action(Qm),t.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=>Xm(n)),t}var Bb=ep();Bb.parseAsync(process.argv).catch(t=>{console.error(t),process.exit(1)});
2894
+ ${_.bold("7.")} Preview and publish!`,"What's next"),await Ae({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"?$i("open",[c],{stdio:"ignore"}):d==="win32"?$i("cmd",["/c","start","",c],{stdio:"ignore"}):$i("xdg-open",[c],{stdio:"ignore"}),U("Opening HubSpot Landing Pages...")}catch{j(`Open this URL in your browser: ${_.info(c)}`)}}let l=[];if(o&&w(n)&&l.push({path:n,label:`Cloned source (${sl(n)})`}),w(s)&&l.push({path:s,label:`Theme directory (${sl(s)})`}),l.length>0&&await Ae({message:"Clean up local working directories?"}))for(let d of l)try{ig(d.path,{recursive:!0,force:!0}),U(`Removed ${d.label}`)}catch{ee(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await pe(`Thanks for using hub${_.vibes("Vibes")}! ${_.vibes("~")}`)}Q();async function il(){Te();let e=await Ls(),t=await Js();Y({lastSourcePath:t.sourceDir});let n=await Gs();Y({lastThemePath:n.themePath}),await qs({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await cn(n.themePath),await ol({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function rl(){Te(),await Ls()}y();Bs();Q();Ye();async function al(){Te();let e=O();e.aiEngine||(z("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await Js(),n=await Gs();await qs({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();Q();Ye();async function ll(){Te();let e=O();if(e.lastThemePath)if(await Ae({message:`Upload from ${e.lastThemePath}?`}))await cn(e.lastThemePath);else{let n=await be({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await cn(n)}else{let t=await be({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await cn(t)}}y();Ht();Q();Ye();at();async function cl(){Te(),await me("Environment Diagnostics");let e=0,t=Mn();t.found?Ns(t.version)?U(`Node.js v${t.version}`):(ee(`Node.js v${t.version} \u2014 too old (need 18+)`),j(" Update at https://nodejs.org"),e++):(z("Node.js \u2014 not installed"),j(" Install from https://nodejs.org"),e++);let n=In();n.found?U(`Git ${n.version}`):(z("Git \u2014 not installed"),j(" Install from https://git-scm.com"),e++);let s=ct();if(!s.found)ee("HubSpot CLI \u2014 not installed (only needed for deployment)"),j(" Install: npm install -g @hubspot/cli");else if(!ya(s.version))ee(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),j(" Update: npm install -g @hubspot/cli@latest"),e++;else{U(`HubSpot CLI v${s.version}`);let m=dt();m.authenticated?U(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(ee("HubSpot \u2014 not authenticated"),j(" Run: hs init"))}let o=Pn();o.found?U(`Claude Code ${o.version} at ${o.path}`):j(_.muted("Claude Code \u2014 not installed"));let i=Nn();i.found?U(`Gemini CLI ${i.version} at ${i.path}`):j(_.muted("Gemini CLI \u2014 not installed"));let r=On();r.found?U(`OpenAI Codex ${r.version} at ${r.path}`):j(_.muted("OpenAI Codex \u2014 not installed"));let a=O(),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?U("Anthropic API key configured"):j(_.muted("Anthropic API key \u2014 not set")),c?U("OpenAI API key configured"):j(_.muted("OpenAI API key \u2014 not set")),d?U("Google AI API key configured"):j(_.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&&U(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&j(_.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(ee("No AI engine available"),j(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),j(" Or install: Claude Code \u2014 https://claude.ai/code"),j(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),j(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await pe("Everything looks good!"):await pe(_.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}y();ts();we();import{dirname as Eb,join as oi}from"path";import{existsSync as Mb}from"fs";import{fileURLToPath as Ib}from"url";import{execFileSync as Zr}from"child_process";import ii from"chalk";var Wm=Eb(Ib(import.meta.url)),Pb=4200;async function Km(){let e=ii.hex("#e8613a"),t=ii.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
2895
+ `));let n=Rb();n||(console.error(ii.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||Pb;try{let{port:o,close:i}=await si({port:s,uiDir:n}),r=`http://localhost:${o}`;if(console.log(e(` v ${r}`)),console.log(t(` Press Ctrl+C to stop
2896
+ `)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?Zr("open",[r],{stdio:"ignore"}):process.platform==="win32"?Zr("cmd",["/c","start","",r],{stdio:"ignore"}):Zr("xdg-open",[r],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
2897
+ Saving session...`)),D(),i(),console.log(t(` Goodbye!
2898
+ `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(ii.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function Rb(){let e=[oi(Wm,"../../ui"),oi(Wm,"../ui"),oi(process.cwd(),"ui")];for(let t of e)if(Mb(oi(t,"index.html")))return t;return null}y();import{resolve as Vm}from"path";import{existsSync as Qr}from"fs";at();Ye();Q();zr();async function zm(e={}){let t=await qm(e.path);if(e.fix){let o=Qo(t);if(o.applied.length>0){U(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)j(` ${i}`)}else j(_.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)ee(i)}let n=Ss(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
2899
+ `),n.passed||process.exit(1);return}Te(),await me("Marketplace check");let s=`${n.errorCount} error${ta(n.errorCount)}, ${n.warningCount} warning${ta(n.warningCount)}, ${n.infoCount} note${ta(n.infoCount)}`;n.passed?U(`Theme passes Marketplace checks (${s}).`):z(`Theme is not yet ready: ${s}.`),ea("Errors",n.findings.filter(o=>o.severity==="error")),ea("Warnings",n.findings.filter(o=>o.severity==="warning")),ea("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(j(""),j(`Tip: run ${_.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await pe("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function Ym(e={}){let t=await qm(e.path);Te(),await me("Marketplace listing details");let n=Tn(t)??{},s=await wt({message:"Category",options:Lt.map(u=>({value:u,label:u}))}),o=await be({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 be({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 be({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 be({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 wt({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};Zo(t,d),U("Saved marketplace.json"),await pe(`Run ${_.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function qm(e){if(e){let o=Vm(e);if(!Qr(o))throw new Error(`Theme not found: ${o}`);return o}let t=O();if(t.lastThemePath&&Qr(t.lastThemePath))return t.lastThemePath;Te();let n=await be({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Vm(n);if(!Qr(s))throw new Error(`Theme not found: ${s}`);return s}function ea(e,t){if(t.length!==0){j(""),j(_.heading(e));for(let n of t){let s=n.file?_.muted(`[${n.file}] `):"",o=n.severity==="error"?_.error("\u2717"):n.severity==="warning"?_.warn("!"):_.muted("\xB7");j(` ${o} ${s}${n.message}`),n.fix&&j(` ${_.muted("\u2192 "+n.fix)}`)}}}function ta(e){return e===1?"":"s"}y();import{resolve as Xm}from"path";import{existsSync as na}from"fs";import{basename as Nb}from"path";at();Ye();Q();bo();async function Zm(e={}){let t=await Ob(e.path),n=Nb(t);if(e.applyTokens){let i=yo(t,n);i?U(`Wrote design tokens to ${i}`):j(_.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=Li(t);e.json||U(`Wrote imported theme snapshot to ${i}`)}let s=ho(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
2900
+ `),process.exit(0)),Te(),await me("Inverse pipeline analyzer");let o=s.summary;if(j(`${_.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){j(""),j(_.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?_.muted(` (${i.varName})`):"";j(` ${i.value} ${_.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){j(""),j(_.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))j(` ${i}`)}if(s.graph.templates.length>0){j(""),j(_.heading("Template \u2192 modules"));for(let i of s.graph.templates)j(` ${i.id}: ${i.modules.length===0?_.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){j(""),j(_.heading("Orphan modules"));for(let i of s.graph.orphanModules)j(` ${i}`)}if(s.roundTripDiff.hasSnapshot){j(""),j(_.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)j(` ${_.muted("No changes from imported snapshot.")}`);else{j(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))j(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&j(` ${_.muted(`...and ${i.files.length-12} more`)}`)}}sa("Errors",s.findings.filter(i=>i.severity==="error")),sa("Warnings",s.findings.filter(i=>i.severity==="warning")),sa("Notes",s.findings.filter(i=>i.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(j(""),j(`Tip: run ${_.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await pe("Analysis complete."),process.exit(0)}async function Ob(e){if(e){let o=Xm(e);if(!na(o))throw new Error(`Theme not found: ${o}`);return o}let t=O();if(t.lastThemePath&&na(t.lastThemePath))return t.lastThemePath;Te();let n=await be({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Xm(n);if(!na(s))throw new Error(`Theme not found: ${s}`);return s}function sa(e,t){if(t.length!==0){j(""),j(_.heading(e));for(let n of t){let s=n.file?_.muted(`[${n.file}] `):"",o=n.severity==="error"?_.error("\u2717"):n.severity==="warning"?_.warn("!"):_.muted("\xB7");j(` ${o} ${s}${n.message}`),n.fix&&j(` ${_.muted("\u2192 "+n.fix)}`)}}}y();ts();we();import{dirname as Fb,join as ri}from"path";import{existsSync as jb}from"fs";import{fileURLToPath as Db}from"url";import{execFileSync as oa}from"child_process";import ai from"chalk";var Qm=Fb(Db(import.meta.url)),Lb=4200;async function ep(){let e=ai.hex("#e8613a"),t=ai.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
2901
+ `));let n=Jb();n||(console.error(ai.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await si({port:Lb,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
2902
+ `));try{process.platform==="darwin"?oa("open",[i],{stdio:"ignore"}):process.platform==="win32"?oa("cmd",["/c","start","",i],{stdio:"ignore"}):oa("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
2903
+ Saving session...`)),D(),o(),console.log(t(` Goodbye!
2904
+ `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(ai.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Jb(){let e=[ri(Qm,"../../ui"),ri(Qm,"../ui"),ri(process.cwd(),"ui")];for(let t of e)if(jb(ri(t,"index.html")))return t;return null}ne();function tp(){let e=new Bb;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(sn()).action(Km),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(il),e.command("init").description("Check and install required tools").action(rl),e.command("convert").description("Convert a React project to HubSpot modules").action(al),e.command("upload").description("Upload theme to HubSpot").action(ll),e.command("doctor").description("Diagnose environment issues").action(cl);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=>zm(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>Ym(n)),e.command("email").description("Launch email template generation mode").action(ep),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=>Zm(n)),e}var Hb=tp();Hb.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
2905
2905
  //# sourceMappingURL=index.js.map