vibespot 1.5.1 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- var rp=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var Be=(e,t)=>{for(var n in t)rp(e,n,{get:t[n],enumerable:!0})};import zb from"path";import{fileURLToPath as qb}from"url";var h=R(()=>{"use strict"});import en from"chalk";function St(e){return ca?en:en.hex(e)}var rt,ca,_,at=R(()=>{"use strict";h();rt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ca=!!process.env.NO_COLOR;_={accent:St(rt.accent),accentBright:St(rt.accentBright),success:St(rt.success),info:St(rt.info),warn:St(rt.warn),error:St(rt.error),muted:St(rt.muted),vibes:St(rt.vibes),heading:ca?en.bold:en.bold.hex(rt.accent),command:St(rt.accentBright),dim:en.dim,bold:en.bold}});import{readFileSync as ci,writeFileSync as ap,mkdirSync as da,existsSync as Ts}from"fs";import{dirname as ua,join as vt}from"path";import{fileURLToPath as lp}from"url";function E(e){return ci(e,"utf-8")}function J(e,t){da(ua(e),{recursive:!0}),ap(e,t,"utf-8")}function w(e){return Ts(e)}function Ie(e){da(e,{recursive:!0})}function As(e){let t=[vt(nn,"../../assets",e),vt(nn,"../assets",e),vt(process.cwd(),"assets",e)];for(let n of t)if(Ts(n))return n;throw new Error(`Asset not found: ${e}`)}function sn(){if(tn)return tn;let e=[vt(nn,"../../package.json"),vt(nn,"../package.json"),vt(process.cwd(),"package.json")];for(let t of e)if(Ts(t))try{let n=JSON.parse(ci(t,"utf-8"));if(n.name==="vibespot"&&n.version)return tn=n.version,tn}catch{}return tn="dev",tn}function ma(){if(ks)return ks;let e=[vt(nn,"../../CHANGELOG.md"),vt(nn,"../CHANGELOG.md"),vt(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Ts(t))try{return ks=ci(t,"utf-8"),ks}catch{}return""}var nn,tn,ks,se=R(()=>{"use strict";h();nn=ua(lp(import.meta.url));tn="";ks=""});import{execSync as pa,execFileSync as cp}from"child_process";function ne(e,t={}){try{return{stdout:pa(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:cp("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 ga(e,t={}){try{return pa(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var Bt=R(()=>{"use strict";h()});var ya={};Be(ya,{addHubSpotAccount:()=>$n,getActiveHubSpotAccount:()=>Pt,getApiKeyForEngine:()=>Pe,getConfigDir:()=>mp,getHubSpotPak:()=>Fe,isCliToolEnabled:()=>_n,loadConfig:()=>O,maskApiKey:()=>_s,removeHubSpotAccount:()=>di,saveConfig:()=>z,setActiveHubSpotAccount:()=>ui,setCliToolEnabled:()=>mi});import{join as fa}from"path";import{homedir as dp}from"os";import{chmodSync as up}from"fs";function O(){let e={};if(w($s))try{e=JSON.parse(E($s)),e.aiEngine==="api"&&(e.aiEngine="anthropic-api")}catch{e={}}return process.env.VIBESPOT_AI_ENGINE&&!e.aiEngine&&(e.aiEngine=process.env.VIBESPOT_AI_ENGINE),process.env.ANTHROPIC_API_KEY&&!e.anthropicApiKey&&(e.anthropicApiKey=process.env.ANTHROPIC_API_KEY),process.env.OPENAI_API_KEY&&!e.openaiApiKey&&(e.openaiApiKey=process.env.OPENAI_API_KEY),(process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)&&!e.geminiApiKey&&(e.geminiApiKey=process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY),process.env.LANGDOCK_API_KEY&&!e.langdockApiKey&&(e.langdockApiKey=process.env.LANGDOCK_API_KEY),process.env.LANGDOCK_BASE_URL&&!e.langdockBaseUrl&&(e.langdockBaseUrl=process.env.LANGDOCK_BASE_URL),process.env.LANGDOCK_PROVIDER&&!e.langdockProvider&&(e.langdockProvider=process.env.LANGDOCK_PROVIDER),process.env.FIGMA_TOKEN&&!e.figmaToken&&(e.figmaToken=process.env.FIGMA_TOKEN),process.env.VIBESPOT_AGENTIC_MODE!==void 0&&e.agenticMode===void 0&&(e.agenticMode=process.env.VIBESPOT_AGENTIC_MODE==="true"),e}function Pe(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 z(e){let n={...O(),...e};if(J($s,JSON.stringify(n,null,2)),process.platform!=="win32")try{up($s,384)}catch{}}function mp(){return ha}function Pt(){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 $n(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),z({hubspotAccounts:i,activeHubSpotAccount:t})}function di(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),z(s)}function ui(e){z({activeHubSpotAccount:e})}function Fe(){return Pt()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function _n(e){return O().enabledCLITools?.includes(e)??!1}function mi(e,t){let n=O(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),z({enabledCLITools:[...s]})}var ha,$s,ee=R(()=>{"use strict";h();se();ha=fa(dp(),".vibespot"),$s=fa(ha,"config.json")});var fi={};Be(fi,{OAUTH_EXTRA_HEADERS:()=>En,OAUTH_SYSTEM_PREFIX:()=>rn,clearOAuthTokens:()=>Is,getOAuthTokenInfo:()=>Mn,getValidAccessToken:()=>gi,hasValidOAuthToken:()=>lt,saveInitialToken:()=>pi});import{join as pp}from"path";import{homedir as gp}from"os";import{chmodSync as fp,unlinkSync as hp}from"fs";function Ms(){if(!w(on))return null;try{return JSON.parse(E(on))}catch{return null}}function ba(e){if(J(on,JSON.stringify(e,null,2)),process.platform!=="win32")try{fp(on,384)}catch{}}async function vp(e){let t=await fetch(bp,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:yp})});if(!t.ok)throw Is(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();ba({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function pi(e,t=""){ba({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function lt(){let e=Ms();return e?e.expires_at>Date.now():!1}async function gi(){let e=Ms();if(!e)return null;if(e.expires_at-Date.now()>Sp)return e.access_token;if(e.refresh_token){Es||(Es=vp(e.refresh_token).finally(()=>{Es=null}));try{await Es}catch{return null}return Ms()?.access_token??null}return e.access_token}function Mn(){let e=Ms();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function Is(){if(w(on))try{hp(on)}catch{}}var yp,bp,on,Sp,En,rn,Es,xt=R(()=>{"use strict";h();se();yp="9d1c250a-e61b-44d9-88ed-5944d1962f5e",bp="https://console.anthropic.com/v1/oauth/token",on=pp(gp(),".vibespot","claude-oauth.json"),Sp=300*1e3,En={"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.";Es=null});import{join as Ps}from"path";import{homedir as Rs}from"os";import{readFileSync as Sa,existsSync as Ns,readdirSync as xp}from"fs";function In(){let e=ne("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:ne(`${Ht} node`).stdout}}function Pn(){let e=ne("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:ne(`${Ht} git`).stdout}}function ct(){let e=ne("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:ne(`${Ht} hs`).stdout}}function Rn(){let e=ne("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Ps(Rs(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Ns(t)){let o=xp(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:ne(`${Ht} claude`).stdout,authenticated:n,authDetail:s}}function Nn(e){try{let t=Ps(Rs(),".hscli","config.yml");if(!Ns(t))return"na1";let n=Sa(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=ne("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 On(){let e=ne("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Ps(Rs(),".config","gcloud","application_default_credentials.json"),n=Ns(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:ne(`${Ht} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function Fn(){let e=ne("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=Ps(Rs(),".codex","auth.json");Ns(i)&&(n=Sa(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:ne(`${Ht} codex`).stdout,authenticated:s,authDetail:o}}function yi(){let e=ne("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
3
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:ne(`${Ht} gh`).stdout}}function bi(){let e=ne("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 va(){return!!process.env.ANTHROPIC_API_KEY}function Os(e){return parseInt(e.split(".")[0],10)>=18}function xa(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function wp(){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=Pt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function Fs(){let e=O(),t=In(),n=Pn(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let x=ct(),v=x.found?dt():{authenticated:!1,portalName:"",portalId:"",accounts:[]},I=v.portalId?Nn(v.portalId):"na1";o={...x,...v,dataCenter:I,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...wp()};let i=yi(),r=i.found?bi():{authenticated:!1,username:""},a={authenticated:lt(),expiresAt:Mn()?.expiresAt},l=e.enabledCLITools||[],c=_n("claude-code")?Rn():{...hi,name:"Claude Code"},d=_n("gemini-cli")?On():{...hi,name:"Gemini CLI"},u=_n("codex-cli")?Fn():{...hi,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"),y=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"),y.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:y,gemini:f,langdock:b},activeEngine:e.aiEngine||null,availableEngines:S,enabledCLITools:l}}var Ht,hi,Gt=R(()=>{"use strict";h();Bt();ee();xt();Ht=process.platform==="win32"?"where":"which";hi={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as Cp}from"fs";import{basename as kp}from"path";async function Ca(e){let t=wa.get(e);if(t&&t.expiresAt-Date.now()>$p)return t;let n=await fetch(`${wt}/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 wa.set(e,o),o}async function an(e){let{accessToken:t}=await Ca(e);return{Authorization:`Bearer ${t}`}}function js(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function _p(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Ep(e){return new Promise(t=>setTimeout(t,e))}async function jn(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 Dn(e,t,n=Tp){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=Ap*Math.pow(2,s);await Ep(i);continue}return o}return fetch(e,t)}async function Ds(e){let t=await Ca(e),n=`${wt}/account-info/v3/details`,s=await Dn(n,{headers:await an(e)});if(!s.ok){let a=await jn(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:_p(e)}}async function ka(e,t,n){let s=Cp(n),o=kp(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${wt}/cms/v3/source-code/published/content/${js(t)}`,l=await Dn(a,{method:"PUT",headers:await an(e),body:i});if(!l.ok){let c=await jn(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function Si(e,t){let n=`${wt}/cms/v3/source-code/published/content/${js(t)}`,s=await Dn(n,{method:"DELETE",headers:await an(e)});if(!s.ok&&s.status!==404){let o=await jn(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Ta(e,t){let n=`${wt}/cms/v3/source-code/published/content/${js(t)}`,s=await Dn(n,{method:"GET",headers:await an(e)});if(!s.ok){let i=await jn(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Ls(e,t){let n=`${wt}/cms/v3/source-code/published/metadata/${js(t)}`,s=await Dn(n,{method:"GET",headers:await an(e)});if(s.status===404)return null;if(!s.ok){let o=await jn(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Aa(e){let t=await an(e),n=[`${wt}/cms/v3/source-code/published/metadata`,`${wt}/cms/v3/source-code/published/metadata/`,`${wt}/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 wt,Tp,Ap,$p,wa,Ut=R(()=>{"use strict";h();wt="https://api.hubapi.com",Tp=3,Ap=1e3,$p=300*1e3,wa=new Map});import*as oe from"@clack/prompts";function vi(e){oe.isCancel(e)&&(oe.cancel(_.muted("Operation cancelled.")),process.exit(0))}async function me(e){oe.intro(_.heading(e))}async function pe(e){oe.outro(_.success(e))}async function ut(e,t){oe.note(e,t?_.heading(t):void 0)}async function be(e){let t=await oe.text({message:_.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return vi(t),t}async function Ae(e){let t=await oe.confirm({message:_.accent(e.message),initialValue:e.initialValue??!0});return vi(t),t}async function Ct(e){let t=await oe.select({message:_.accent(e.message),options:e.options});return vi(t),t}async function Re(){let e=oe.spinner();return{start:t=>e.start(_.muted(t)),stop:t=>e.stop(_.success(t)),message:t=>e.message(_.muted(t))}}function j(e){oe.log.info(e)}function H(e){oe.log.success(_.success(e))}function te(e){oe.log.warn(_.warn(e))}function V(e){oe.log.error(_.error(e))}var Ye=R(()=>{"use strict";h();at()});import{readdirSync as xi,statSync as Mp}from"fs";import{join as ge,basename as wi,extname as Ip}from"path";function $a(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 _a(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(!Mp(r).isFile())continue;let l=Ip(i);if(![".tsx",".jsx"].includes(l))continue;let c=wi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=E(r),u=Pp(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function Pp(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 Ea(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 Ma(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 Ia(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!$a(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=wi(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=_a(t),o=w(ge(t,"tailwind.config.ts"))||w(ge(t,"tailwind.config.js")),{varCount:i,fonts:r}=Ea(t),a=Ma(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function Bs(){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:y=>{if(!y.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){$a(e)||(V("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let y=wi(e.replace(/\.git$/,""))||"react-source";if(t=ge(process.cwd(),"workspace",y),w(t))H(`Using existing clone: ${_.dim(t)}`);else{let f=await Re();f.start("Cloning repository..."),X(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${_.dim(t)}`)}}else t=e,w(t)||(V(`Directory not found: ${t}`),process.exit(1)),H(`Using local source: ${_.dim(t)}`);let s=await Re();s.start("Analyzing project structure...");let o=_a(t),i=w(ge(t,"tailwind.config.ts"))||w(ge(t,"tailwind.config.js")),{varCount:r,fonts:a}=Ea(t),l=Ma(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(te("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((y,f)=>` ${_.dim(`${f+1}.`)} ${_.bold(y.name)} ${_.muted(`\u2014 ${y.description}`)}`).join(`
4
- `),d=i?`Tailwind + custom CSS (${r} variables)`:`Custom CSS (${r} variables)`,u=a.length>0?a.join(", "):"System fonts",m=l.join(", ");return await ut(`${c}
1
+ var tg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{for(var n in t)tg(e,n,{get:t[n],enumerable:!0})};import mv from"path";import{fileURLToPath as gv}from"url";var y=N(()=>{"use strict"});import pn from"chalk";function Tt(e){return ja?pn:pn.hex(e)}var pt,ja,I,gt=N(()=>{"use strict";y();pt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ja=!!process.env.NO_COLOR;I={accent:Tt(pt.accent),accentBright:Tt(pt.accentBright),success:Tt(pt.success),info:Tt(pt.info),warn:Tt(pt.warn),error:Tt(pt.error),muted:Tt(pt.muted),vibes:Tt(pt.vibes),heading:ja?pn.bold:pn.bold.hex(pt.accent),command:Tt(pt.accentBright),dim:pn.dim,bold:pn.bold}});import{readFileSync as Ei,writeFileSync as ng,mkdirSync as La,existsSync as Us}from"fs";import{dirname as Ja,join as At}from"path";import{fileURLToPath as sg}from"url";function P(e){return Ei(e,"utf-8")}function J(e,t){La(Ja(e),{recursive:!0}),ng(e,t,"utf-8")}function x(e){return Us(e)}function Re(e){La(e,{recursive:!0})}function hn(e){let t=[At(fn,"../../assets",e),At(fn,"../assets",e),At(process.cwd(),"assets",e)];for(let n of t)if(Us(n))return n;throw new Error(`Asset not found: ${e}`)}function yn(){if(gn)return gn;let e=[At(fn,"../../package.json"),At(fn,"../package.json"),At(process.cwd(),"package.json")];for(let t of e)if(Us(t))try{let n=JSON.parse(Ei(t,"utf-8"));if(n.name==="vibespot"&&n.version)return gn=n.version,gn}catch{}return gn="dev",gn}function Ba(){if(Hs)return Hs;let e=[At(fn,"../../CHANGELOG.md"),At(fn,"../CHANGELOG.md"),At(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Us(t))try{return Hs=Ei(t,"utf-8"),Hs}catch{}return""}var fn,gn,Hs,oe=N(()=>{"use strict";y();fn=Ja(sg(import.meta.url));gn="";Hs=""});import{execSync as Ha,execFileSync as og}from"child_process";function ie(e,t={}){try{return{stdout:Ha(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Z(e,t={}){try{return{stdout:og("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 Ua(e,t={}){try{return Ha(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var qt=N(()=>{"use strict";y()});var Ka={};Ge(Ka,{addHubSpotAccount:()=>Yn,getActiveHubSpotAccount:()=>Lt,getApiKeyForEngine:()=>Fe,getConfigDir:()=>ag,getHubSpotPak:()=>Le,isCliToolEnabled:()=>st,loadConfig:()=>R,maskApiKey:()=>Ws,removeHubSpotAccount:()=>Mi,saveConfig:()=>Y,setActiveHubSpotAccount:()=>Ii,setCliToolEnabled:()=>Pi});import{join as Ga}from"path";import{homedir as ig}from"os";import{chmodSync as rg}from"fs";function R(){let e={};if(x(Gs))try{e=JSON.parse(P(Gs)),e.aiEngine==="api"&&(e.aiEngine="anthropic-api")}catch{e={}}return process.env.VIBESPOT_AI_ENGINE&&!e.aiEngine&&(e.aiEngine=process.env.VIBESPOT_AI_ENGINE),process.env.ANTHROPIC_API_KEY&&!e.anthropicApiKey&&(e.anthropicApiKey=process.env.ANTHROPIC_API_KEY),process.env.OPENAI_API_KEY&&!e.openaiApiKey&&(e.openaiApiKey=process.env.OPENAI_API_KEY),(process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)&&!e.geminiApiKey&&(e.geminiApiKey=process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY),process.env.LANGDOCK_API_KEY&&!e.langdockApiKey&&(e.langdockApiKey=process.env.LANGDOCK_API_KEY),process.env.LANGDOCK_BASE_URL&&!e.langdockBaseUrl&&(e.langdockBaseUrl=process.env.LANGDOCK_BASE_URL),process.env.LANGDOCK_PROVIDER&&!e.langdockProvider&&(e.langdockProvider=process.env.LANGDOCK_PROVIDER),process.env.FIGMA_TOKEN&&!e.figmaToken&&(e.figmaToken=process.env.FIGMA_TOKEN),process.env.VIBESPOT_AGENTIC_MODE!==void 0&&e.agenticMode===void 0&&(e.agenticMode=process.env.VIBESPOT_AGENTIC_MODE==="true"),process.env.LANGFUSE_PUBLIC_KEY&&!e.langfusePublicKey&&(e.langfusePublicKey=process.env.LANGFUSE_PUBLIC_KEY),process.env.LANGFUSE_SECRET_KEY&&!e.langfuseSecretKey&&(e.langfuseSecretKey=process.env.LANGFUSE_SECRET_KEY),process.env.LANGFUSE_BASE_URL&&!e.langfuseBaseUrl&&(e.langfuseBaseUrl=process.env.LANGFUSE_BASE_URL),process.env.LANGFUSE_ENABLED!==void 0&&e.langfuseEnabled===void 0&&(e.langfuseEnabled=process.env.LANGFUSE_ENABLED==="true"),e}function Fe(e,t){let n=t||R();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;case"langdock-api":return n.langdockApiKey||process.env.LANGDOCK_API_KEY;default:return}}function Ws(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function Y(e){let n={...R(),...e};if(J(Gs,JSON.stringify(n,null,2)),process.platform!=="win32")try{rg(Gs,384)}catch{}}function ag(){return Wa}function Lt(){let e=R();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function Yn(e,t,n,s){let i=R().hubspotAccounts||[],r=i.findIndex(l=>l.portalId===t),a={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};r>=0?i[r]=a:i.push(a),Y({hubspotAccounts:i,activeHubSpotAccount:t})}function Mi(e){let t=R(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),Y(s)}function Ii(e){Y({activeHubSpotAccount:e})}function Le(){return Lt()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function st(e){return R().enabledCLITools?.includes(e)??!1}function Pi(e,t){let n=R(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),Y({enabledCLITools:[...s]})}var Wa,Gs,ee=N(()=>{"use strict";y();oe();Wa=Ga(ig(),".vibespot"),Gs=Ga(Wa,"config.json")});var Oi={};Ge(Oi,{OAUTH_EXTRA_HEADERS:()=>qn,OAUTH_SYSTEM_PREFIX:()=>Sn,clearOAuthTokens:()=>zs,getOAuthTokenInfo:()=>Xt,getValidAccessToken:()=>Ri,hasValidOAuthToken:()=>Ze,saveInitialToken:()=>Ni});import{join as lg}from"path";import{homedir as cg}from"os";import{chmodSync as dg,unlinkSync as ug}from"fs";function Vs(){if(!x(bn))return null;try{return JSON.parse(P(bn))}catch{return null}}function Va(e){if(J(bn,JSON.stringify(e,null,2)),process.platform!=="win32")try{dg(bn,384)}catch{}}async function fg(e){let t=await fetch(pg,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:mg})});if(!t.ok)throw zs(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Va({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Ni(e,t=""){Va({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Ze(){let e=Vs();return e?e.expires_at>Date.now():!1}async function Ri(){let e=Vs();if(!e)return null;if(e.expires_at-Date.now()>gg)return e.access_token;if(e.refresh_token){Ks||(Ks=fg(e.refresh_token).finally(()=>{Ks=null}));try{await Ks}catch{return null}return Vs()?.access_token??null}return e.access_token}function Xt(){let e=Vs();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function zs(){if(x(bn))try{ug(bn)}catch{}}var mg,pg,bn,gg,qn,Sn,Ks,_t=N(()=>{"use strict";y();oe();mg="9d1c250a-e61b-44d9-88ed-5944d1962f5e",pg="https://console.anthropic.com/v1/oauth/token",bn=lg(cg(),".vibespot","claude-oauth.json"),gg=300*1e3,qn={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},Sn="You are Claude Code, Anthropic's official CLI for Claude.";Ks=null});import{join as Ys}from"path";import{homedir as qs}from"os";import{readFileSync as za,existsSync as Xs,readdirSync as hg}from"fs";function Xn(){let e=ie("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:ie(`${Zt} node`).stdout}}function Zn(){let e=ie("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:ie(`${Zt} git`).stdout}}function ft(){let e=ie("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:ie(`${Zt} hs`).stdout}}function wn(){let e=ie("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Ys(qs(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Xs(t)){let o=hg(t);(o.some(r=>r.includes("credentials")||r.includes("auth")||r.includes("token")||r===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:ie(`${Zt} claude`).stdout,authenticated:n,authDetail:s}}function Qn(e){try{let t=Ys(qs(),".hscli","config.yml");if(!Xs(t))return"na1";let n=za(t,"utf-8"),s=n.indexOf(`accountId: ${e}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let r=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!r)return"na1";if(r[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function ht(){let e=ie("hs accounts list",{timeout:Ya});if(!e.success||!e.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let t=[],n="",s="",o=e.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=e.stdout.split(`
2
+ `);for(let r of i){let a=r.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(a&&!/Account ID/i.test(r)&&!/^-+$/.test(r.trim())&&!/^Name\s/i.test(r.trim())){let l=a[1].trim(),c=a[2].trim(),d=a[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Cn(){let e=ie("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Ys(qs(),".config","gcloud","application_default_credentials.json"),n=Xs(t),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:e.stdout,path:ie(`${Zt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function kn(){let e=ie("codex --version");if(!e.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=!!process.env.OPENAI_API_KEY,n=!1;try{let i=Ys(qs(),".codex","auth.json");Xs(i)&&(n=za(i,"utf-8").length>10)}catch{}let s=t||n,o=n?"Authenticated (OAuth)":t?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:e.stdout,path:ie(`${Zt} codex`).stdout,authenticated:s,authDetail:o}}function Zs(){let e=ie("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
3
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:ie(`${Zt} gh`).stdout}}function Qs(){let e=ie("gh auth status 2>&1",{timeout:Ya});if(!e.success&&!e.stdout)return{authenticated:!1,username:""};let t=e.stdout||e.stderr||"",n=t.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=t.match(/account\s+(\S+)/);return s&&t.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:t.includes("Logged in"),username:""}}function qa(){return!!process.env.ANTHROPIC_API_KEY}function eo(e){return parseInt(e.split(".")[0],10)>=18}function Xa(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function yg(){let e=R(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Lt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function vn(e,...t){if(e)return{configured:!0,masked:Ws(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:Ws(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function Fi(e){return{anthropic:vn(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:vn(e.openaiApiKey,"OPENAI_API_KEY"),gemini:vn(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:vn(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:vn(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:vn(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function Di(e){let t=[];return e.claudeCode&&t.push("claude-code"),e.claudeOAuth&&t.push("claude-oauth"),e.apiKeys.anthropic.configured&&t.push("anthropic-api"),e.apiKeys.openai.configured&&t.push("openai-api"),e.geminiCli&&t.push("gemini-cli"),e.apiKeys.gemini.configured&&t.push("gemini-api"),e.codexCli&&t.push("codex-cli"),e.apiKeys.langdock.configured&&t.push("langdock-api"),t}function ji(e,t){if(e==="cli"){if(!t)return{name:"HubSpot CLI",found:!1,version:"",path:"",authenticated:!1,portalName:"",portalId:"",dataCenter:"na1",accounts:[],uploadMode:"cli"};let n=ft(),s=n.found?ht():{authenticated:!1,portalName:"",portalId:"",accounts:[]},o=s.portalId?Qn(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...yg()}}function Za(){let e=R(),t=e.hubspotUploadMode||"api",n=Fi(e),s={authenticated:Ze(),expiresAt:Xt()?.expiresAt},o=r=>({name:r,found:!1,version:"",path:"",authenticated:!1,authDetail:"Not scanned"}),i=r=>({name:r,found:!1,version:"",path:""});return{tools:{node:i("Node.js"),git:i("Git"),hubspot:ji(t,!1),github:{...i("GitHub CLI"),authenticated:!1,username:""},claudeCode:o("Claude Code"),claudeOAuth:s,geminiCli:o("Gemini CLI"),codexCli:o("OpenAI Codex CLI")},apiKeys:n,activeEngine:e.aiEngine||null,availableEngines:Di({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:st("claude-code"),geminiCli:st("gemini-cli"),codexCli:st("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function Qa(){let e=R(),t=Fi(e),n={authenticated:Ze(),expiresAt:Xt()?.expiresAt},s=st("claude-code")?wn():{...xn,name:"Claude Code"},o=st("gemini-cli")?Cn():{...xn,name:"Gemini CLI"},i=st("codex-cli")?kn():{...xn,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:i,claudeOAuth:n,availableEngines:Di({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:i.found&&i.authenticated})}}function el(){let t=R().hubspotUploadMode||"api",n=Zs(),s=n.found?Qs():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:ji(t,!0)}}function to(){let e=R(),t=e.hubspotUploadMode||"api",n=Xn(),s=Zn(),o=ji(t,!0),i=Zs(),r=i.found?Qs():{authenticated:!1,username:""},a={authenticated:Ze(),expiresAt:Xt()?.expiresAt},l=st("claude-code")?wn():{...xn,name:"Claude Code"},c=st("gemini-cli")?Cn():{...xn,name:"Gemini CLI"},d=st("codex-cli")?kn():{...xn,name:"OpenAI Codex CLI"},u=Fi(e);return{tools:{node:n,git:s,hubspot:o,github:{...i,...r},claudeCode:l,claudeOAuth:a,geminiCli:c,codexCli:d},apiKeys:u,activeEngine:e.aiEngine||null,availableEngines:Di({apiKeys:u,claudeOAuth:a.authenticated,claudeCode:l.found&&l.authenticated,geminiCli:c.found&&c.authenticated,codexCli:d.found&&d.authenticated}),enabledCLITools:e.enabledCLITools||[],scanned:!0}}var Zt,Ya,xn,Qt=N(()=>{"use strict";y();qt();ee();_t();Zt=process.platform==="win32"?"where":"which",Ya=4e3;xn={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as bg}from"fs";import{basename as Sg}from"path";async function nl(e){let t=tl.get(e);if(t&&t.expiresAt-Date.now()>wg)return t;let n=await fetch(`${$t}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:e})});if(!n.ok){let i=await n.text().catch(()=>"");throw new Error(n.status===401||n.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${n.status}): ${i.slice(0,200)}`)}let s=await n.json(),o={accessToken:s.oauthAccessToken,expiresAt:s.expiresAtMillis,hubId:s.hubId,hubName:s.hubName||""};return tl.set(e,o),o}async function Tn(e){let{accessToken:t}=await nl(e);return{Authorization:`Bearer ${t}`}}function no(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function Cg(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function kg(e){return new Promise(t=>setTimeout(t,e))}async function es(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 ts(e,t,n=vg){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=xg*Math.pow(2,s);await kg(i);continue}return o}return fetch(e,t)}async function so(e){let t=await nl(e),n=`${$t}/account-info/v3/details`,s=await ts(n,{headers:await Tn(e)});if(!s.ok){let a=await es(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:Cg(e)}}async function sl(e,t,n){let s=bg(n),o=Sg(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${$t}/cms/v3/source-code/published/content/${no(t)}`,l=await ts(a,{method:"PUT",headers:await Tn(e),body:i});if(!l.ok){let c=await es(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function Li(e,t){let n=`${$t}/cms/v3/source-code/published/content/${no(t)}`,s=await ts(n,{method:"DELETE",headers:await Tn(e)});if(!s.ok&&s.status!==404){let o=await es(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function ol(e,t){let n=`${$t}/cms/v3/source-code/published/content/${no(t)}`,s=await ts(n,{method:"GET",headers:await Tn(e)});if(!s.ok){let i=await es(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function oo(e,t){let n=`${$t}/cms/v3/source-code/published/metadata/${no(t)}`,s=await ts(n,{method:"GET",headers:await Tn(e)});if(s.status===404)return null;if(!s.ok){let o=await es(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function il(e){let t=await Tn(e),n=[`${$t}/cms/v3/source-code/published/metadata`,`${$t}/cms/v3/source-code/published/metadata/`,`${$t}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let i=await o.json(),r=i.children||i.objects||(Array.isArray(i)?i:null);if(r&&r.length>0)return r.filter(a=>a.folder)}}catch{}return[]}var $t,vg,xg,wg,tl,en=N(()=>{"use strict";y();$t="https://api.hubapi.com",vg=3,xg=1e3,wg=300*1e3,tl=new Map});import*as ae from"@clack/prompts";function Ji(e){ae.isCancel(e)&&(ae.cancel(I.muted("Operation cancelled.")),process.exit(0))}async function ge(e){ae.intro(I.heading(e))}async function fe(e){ae.outro(I.success(e))}async function yt(e,t){ae.note(e,t?I.heading(t):void 0)}async function Se(e){let t=await ae.text({message:I.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return Ji(t),t}async function Me(e){let t=await ae.confirm({message:I.accent(e.message),initialValue:e.initialValue??!0});return Ji(t),t}async function Et(e){let t=await ae.select({message:I.accent(e.message),options:e.options});return Ji(t),t}async function De(){let e=ae.spinner();return{start:t=>e.start(I.muted(t)),stop:t=>e.stop(I.success(t)),message:t=>e.message(I.muted(t))}}function D(e){ae.log.info(e)}function G(e){ae.log.success(I.success(e))}function se(e){ae.log.warn(I.warn(e))}function V(e){ae.log.error(I.error(e))}var Qe=N(()=>{"use strict";y();gt()});import{readdirSync as Bi,statSync as Tg}from"fs";import{join as he,basename as Hi,extname as Ag}from"path";function rl(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 al(e){let t=[],n=[he(e,"src/components/landing"),he(e,"src/components/sections"),he(e,"src/components"),he(e,"src/pages"),he(e,"app/components"),he(e,"components")];for(let s of n)if(x(s))try{let o=Bi(s);for(let i of o){let r=he(s,i);if(!Tg(r).isFile())continue;let l=Ag(i);if(![".tsx",".jsx"].includes(l))continue;let c=Hi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=P(r),u=_g(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function _g(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 ll(e){let t=[he(e,"src/index.css"),he(e,"src/globals.css"),he(e,"src/app/globals.css"),he(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!x(o))continue;let i=P(o),r=i.match(/--[\w-]+:/g);r&&(n+=r.length);let a=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(a)for(let c of a){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function cl(e){let t=[],n=he(e,"src/hooks");if(x(n))try{let o=Bi(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=he(e,"src/components/landing");if(x(s))try{let o=Bi(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=P(he(s,i));/carousel|embla|swiper/i.test(r)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(r)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(r)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(r)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function dl(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!rl(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=Hi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",l),!x(t)){let c=Z(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!x(t))throw new Error(`Directory not found: ${t}`);let s=al(t),o=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:i,fonts:r}=ll(t),a=cl(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function ro(){await ge("Source Project");let e=await Se({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){rl(e)||(V("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let h=Hi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",h),x(t))G(`Using existing clone: ${I.dim(t)}`);else{let f=await De();f.start("Cloning repository..."),Z(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${I.dim(t)}`)}}else t=e,x(t)||(V(`Directory not found: ${t}`),process.exit(1)),G(`Using local source: ${I.dim(t)}`);let s=await De();s.start("Analyzing project structure...");let o=al(t),i=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:r,fonts:a}=ll(t),l=cl(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(se("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${I.dim(`${f+1}.`)} ${I.bold(h.name)} ${I.muted(`\u2014 ${h.description}`)}`).join(`
4
+ `),d=i?`Tailwind + custom CSS (${r} variables)`:`Custom CSS (${r} variables)`,u=a.length>0?a.join(", "):"System fonts",m=l.join(", ");return await yt(`${c}
5
5
 
6
6
  CSS: ${d}
7
7
  JS: ${m}
8
- Font: ${u}`,`${o.length} components detected`),await Ae({message:"Does this look right?"})||(V("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 Hs=R(()=>{"use strict";h();Bt();se();Ye();at()});var Pa={};Be(Pa,{addEmailTemplateToTheme:()=>ln,createThemeScaffold:()=>Jn});import{mkdirSync as kt,writeFileSync as Ln}from"fs";import{join as He}from"path";function Jn(e,t){kt(e,{recursive:!0}),kt(He(e,"templates"),{recursive:!0}),kt(He(e,"modules"),{recursive:!0}),kt(He(e,"css"),{recursive:!0}),kt(He(e,"js"),{recursive:!0}),kt(He(e,"images"),{recursive:!0}),kt(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"}};Ln(He(e,"theme.json"),JSON.stringify(n,null,2)+`
9
- `),Ln(He(e,"fields.json"),`[]
8
+ Font: ${u}`,`${o.length} components detected`),await Me({message:"Does this look right?"})||(V("Please adjust your source directory and try again."),process.exit(0)),await fe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var ao=N(()=>{"use strict";y();qt();oe();Qe();gt()});var ul={};Ge(ul,{addEmailTemplateToTheme:()=>An,createThemeScaffold:()=>ss});import{mkdirSync as Mt,writeFileSync as ns}from"fs";import{join as We}from"path";function ss(e,t){Mt(e,{recursive:!0}),Mt(We(e,"templates"),{recursive:!0}),Mt(We(e,"modules"),{recursive:!0}),Mt(We(e,"css"),{recursive:!0}),Mt(We(e,"js"),{recursive:!0}),Mt(We(e,"images"),{recursive:!0}),Mt(We(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};ns(We(e,"theme.json"),JSON.stringify(n,null,2)+`
9
+ `),ns(We(e,"fields.json"),`[]
10
10
  `);let s=`<!--
11
11
  templateType: page
12
12
  isAvailableForNewContent: false
@@ -22,7 +22,7 @@ var rp=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var Be=(e,t)=>{f
22
22
  %}
23
23
  {% end_dnd_area %}
24
24
  {% endblock body %}
25
- `;Ln(He(e,"templates","home.html"),s);let o=`<!--
25
+ `;ns(We(e,"templates","home.html"),s);let o=`<!--
26
26
  templateType: none
27
27
  isAvailableForNewContent: false
28
28
  label: Base Layout
@@ -45,7 +45,7 @@ var rp=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var Be=(e,t)=>{f
45
45
  {{ standard_footer_includes }}
46
46
  </body>
47
47
  </html>
48
- `;kt(He(e,"templates","layouts"),{recursive:!0}),Ln(He(e,"templates","layouts","base.html"),o)}function ln(e,t){let n=`<!--
48
+ `;Mt(We(e,"templates","layouts"),{recursive:!0}),ns(We(e,"templates","layouts","base.html"),o)}function An(e,t){let n=`<!--
49
49
  templateType: email
50
50
  isAvailableForNewContent: true
51
51
  label: ${t} Email Template
@@ -84,8 +84,8 @@ var rp=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var Be=(e,t)=>{f
84
84
  {{ standard_footer_includes }}
85
85
  </body>
86
86
  </html>
87
- `;kt(He(e,"templates"),{recursive:!0}),Ln(He(e,"templates","email.html"),n)}var Bn=R(()=>{"use strict";h()});var Na={};Be(Na,{fetchTheme:()=>Hn});import{mkdirSync as Ra,writeFileSync as Rp}from"fs";import{join as Np,dirname as Op}from"path";async function Ci(e,t){let n=await Ls(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 Ci(e,a));else{let l=i;l.folder?s.push(...await Ci(e,l.path||a)):s.push(l.path||a)}}return s}async function Fp(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 Hn(e,t,n,s={}){let o=s.concurrency??5,i=await Ci(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);Ra(n,{recursive:!0}),await Fp(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=Np(n,a);Ra(Op(l),{recursive:!0});let c=await Ta(e,r);Rp(l,c),s.onFile?.(a)})}var Gs=R(()=>{"use strict";h();Ut()});function Rt(e){let t=Oa.get(e);if(t!==void 0)return t;try{t=E(As(e))}catch{t=""}return Oa.set(e,t),t}function fe(){return Rt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function Un(){return Rt("design-guide.md")}function ki(){return Rt("content-guide.md")}function je(){return Rt("hubspot-rules.md")}function Ti(){return Rt("humanify-guide.md")}function Fa(){return Rt("email-rules.md")}function ja(){return Rt("blog-rules.md")}function Ai(e){let t=Rt("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 Da(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
87
+ `;Mt(We(e,"templates"),{recursive:!0}),ns(We(e,"templates","email.html"),n)}var os=N(()=>{"use strict";y()});var pl={};Ge(pl,{fetchTheme:()=>is});import{mkdirSync as ml,writeFileSync as $g}from"fs";import{join as Eg,dirname as Mg}from"path";async function Ui(e,t){let n=await oo(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 Ui(e,a));else{let l=i;l.folder?s.push(...await Ui(e,l.path||a)):s.push(l.path||a)}}return s}async function Ig(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 is(e,t,n,s={}){let o=s.concurrency??5,i=await Ui(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);ml(n,{recursive:!0}),await Ig(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=Eg(n,a);ml(Mg(l),{recursive:!0});let c=await ol(e,r);$g(l,c),s.onFile?.(a)})}var lo=N(()=>{"use strict";y();en()});function Jt(e){let t=gl.get(e);if(t!==void 0)return t;try{t=P(hn(e))}catch{t=""}return gl.set(e,t),t}function ye(){return Jt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function as(){return Jt("design-guide.md")}function Gi(){return Jt("content-guide.md")}function Je(){return Jt("hubspot-rules.md")}function Wi(){return Jt("humanify-guide.md")}function fl(){return Jt("email-rules.md")}function hl(){return Jt("blog-rules.md")}function Ki(e){let t=Jt("page-types.md");if(!t)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[e];if(!s)return"";let o=t.indexOf(s);if(o<0)return"";let i=t.indexOf(`
88
+ ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function yl(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:
@@ -102,10 +102,10 @@ Follow the conversion guide below EXACTLY. Key rules:
102
102
  - Convert React hooks to vanilla JS (no React, no npm packages)
103
103
 
104
104
  ## HubSpot CMS Rules
105
- ${je()}
105
+ ${Je()}
106
106
 
107
107
  ## Conversion Guide
108
- ${e}`}function La(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
108
+ ${e}`}function bl(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
109
109
 
110
110
  Return a JSON object with these keys:
111
111
  - fieldsJson: complete fields.json content (as JSON string)
@@ -120,7 +120,7 @@ ${n}
120
120
  React component source:
121
121
  ${e}
122
122
 
123
- Return ONLY valid JSON, no markdown fences.`}function Ja(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
123
+ Return ONLY valid JSON, no markdown fences.`}function Sl(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
124
124
 
125
125
  Extract the design system from the source CSS and Tailwind config below.
126
126
  Use the class prefix ".${n}-" for all custom classes.
@@ -144,7 +144,7 @@ ${e}
144
144
  Tailwind config:
145
145
  ${t}
146
146
 
147
- Return ONLY the CSS content, no markdown fences.`}function Ba(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
147
+ Return ONLY the CSS content, no markdown fences.`}function vl(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
148
148
 
149
149
  Convert the React hooks and interactive components below to plain JavaScript.
150
150
  Use the class prefix "${n}-" to match the CSS.
@@ -162,7 +162,7 @@ ${e}
162
162
  Interactive component sources:
163
163
  ${t}
164
164
 
165
- Return ONLY the JavaScript content, no markdown fences.`}function Ha(e,t,n){return`Create a HubSpot page template that assembles these modules:
165
+ Return ONLY the JavaScript content, no markdown fences.`}function xl(e,t,n){return`Create a HubSpot page template that assembles these modules:
166
166
 
167
167
  ${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
168
168
  `)}
@@ -177,29 +177,29 @@ Template requirements:
177
177
  - Each module in its own dnd_section with padding zeroed and full_width=true
178
178
  - dnd_area label: "${t} Landing Page"
179
179
 
180
- Return ONLY the template HTML content, no markdown fences.`}var Oa,Ge=R(()=>{"use strict";h();se();Oa=new Map});import{join as le}from"path";import{readdirSync as Qe,rmSync as Zp}from"fs";function Zs(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 Qs(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 eo(e){let t=[];return Ya(e)&&t.push("textarea \u2192 text"),qa(e)&&t.push("name \u2192 item_name"),Xa(e)&&t.push("now() \u2192 local_dt"),Za(e)&&t.push("Removed HubDB templates"),Qa(e)&&t.push("Fixed link field defaults"),el(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),Qp(e)&&t.push("Stripped CDN @import statements"),nl(e)&&t.push('dnd_area \u2192 "main" in email templates'),sl(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function za(e,t){return t.message.includes("textarea")?Ya(e):t.message.includes("reserved field name")?qa(e):t.message.includes("now()")?Xa(e):t.message.includes("HubDB")?Za(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?Qa(e):t.message.includes("invalid format")&&t.message.includes("color")?el(e):t.message.includes("dnd")||t.message.includes("Dnd area")?nl(e):t.message.includes("dnd_area_stylesheet")?sl(e):!1}function Ya(e){let t=!1,n=le(e,"modules");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".module"))continue;let o=le(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 qa(e){let t=!1,n=le(e,"modules");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".module"))continue;let o=le(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 Xa(e){let t=!1,n=le(e,"modules");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".module"))continue;let o=le(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=le(e,"templates");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".html"))continue;let o=le(n,s),i=E(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Zp(o),t=!0)}return t}function Qa(e){let t=!1,n=le(e,"modules");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".module"))continue;let o=le(n,s,"fields.json");if(w(o))try{let i=JSON.parse(E(o));ol(i)&&(J(o,JSON.stringify(i,null,2)+`
181
- `),t=!0)}catch{}}return t}function Qp(e){let t=!1,n=le(e,"css");if(w(n))for(let o of Qe(n)){if(!o.endsWith(".css"))continue;let i=le(n,o),r=E(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(J(i,a),t=!0)}let s=le(e,"modules");if(w(s))for(let o of Qe(s)){if(!o.endsWith(".module"))continue;let i=le(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 Qe(s)){if(!o.endsWith(".module"))continue;let i=le(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 el(e){let t=!1,n=le(e,"modules");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".module"))continue;let o=le(n,s,"fields.json");if(w(o))try{let i=JSON.parse(E(o));tl(i)&&(J(o,JSON.stringify(i,null,2)+`
182
- `),t=!0)}catch{}}return t}function tl(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"&&!eg(i)){let r=tg(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&tl(s.children)&&(t=!0)}return t}function eg(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function tg(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 nl(e){let t=!1,n=le(e,"templates");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".html"))continue;let o=le(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 sl(e){let t=!1,n=le(e,"templates");if(!w(n))return!1;for(let s of Qe(n)){if(!s.endsWith(".html"))continue;let o=le(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 ol(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&ol(s.children)&&(t=!0)}return t}var to=R(()=>{"use strict";h();se()});import{readdirSync as ng}from"fs";import{join as sg,relative as og}from"path";function il(e){let t=[];for(let n of ng(e,{withFileTypes:!0})){if(ig.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=sg(e,n.name);n.isDirectory()?t.push(...il(s)):n.isFile()&&t.push(s)}return t}async function rg(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 no(e,t,n,s={}){let o=s.concurrency??5,i=il(t),r=i.length,a=0,l=0,c=[];return await rg(i,o,async d=>{let u=og(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await ka(e,m,d);if(g.success)a++,s.onFileComplete?.(u);else{l++;let y={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(y),s.onFileError?.(u,y)}s.onProgress?.(a+l,r)}),{success:l===0,uploaded:a,failed:l,total:r,errors:c}}var ig,$i=R(()=>{"use strict";h();Ut();Ut();ig=new Set([".git","node_modules",".vibespot",".DS_Store"])});var gl=R(()=>{"use strict";h()});import{existsSync as Tt,writeFileSync as dg,mkdirSync as ug}from"fs";import{join as pt}from"path";function hl(e){return/^[0-9a-f]{4,40}$/i.test(e)}function yl(e){return Number.isInteger(e)&&e>0&&e<1e3}function et(){return so!==null||(so=X(["--version"]).success),so}function oo(e){if(!et())return!1;if(Tt(pt(e,".git")))return fl(e),!0;let t=X(["init"],{cwd:e});return t.success?(mg(e),fl(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 fl(e){let t=pt(e,".vibespot");Tt(t)||ug(t,{recursive:!0})}function mg(e){let t=pt(e,".gitignore");dg(t,[".vibespot/","node_modules/",""].join(`
184
- `),"utf-8")}function Wt(e,t){if(!et()||!Tt(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 Ei(e,t,n,s){if(!et()||!Tt(pt(e,".git")))return null;for(let u of s){let m=pt(e,u);Tt(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 bl(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 Sl(e,t=50){if(!et())return[];if(!Tt(pt(e,".git")))return[];if(!yl(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()?[]:bl(n.stdout)}function vl(e,t,n=50){if(!et())return[];if(!Tt(pt(e,".git")))return[];if(!yl(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()?[]:bl(o.stdout)}function xl(e,t){if(!et())return{success:!1,error:"Git not available"};if(!Tt(pt(e,".git")))return{success:!1,error:"Not a git repo"};if(!hl(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 wl(e,t,n,s){if(!et())return{success:!1,error:"Git not available"};if(!Tt(pt(e,".git")))return{success:!1,error:"Not a git repo"};if(!hl(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 so,dn=R(()=>{"use strict";h();Bt();so=null});import{appendFileSync as pg,mkdirSync as gg,readdirSync as fg,unlinkSync as hg}from"fs";import{join as Ri}from"path";import{homedir as yg}from"os";function Sg(){if(!Ii)try{gg(io,{recursive:!0}),Ii=!0}catch{}}function vg(){if(!Pi){Pi=!0;try{let e=Date.now()-bg*864e5;for(let t of fg(io)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{hg(Ri(io,t))}catch{}}}catch{}}}function xg(){let t=new Date().toISOString().slice(0,10);return Ri(io,`vibespot-${t}.log`)}function wg(){return new Date().toISOString().slice(11,23)}function Mi(e,t){if(Sg(),!!Ii){Pi||vg();try{pg(xg(),`${wg()} ${e} ${t}
186
- `)}catch{}}}var io,bg,Ii,Pi,M,ce=R(()=>{"use strict";h();io=Ri(yg(),".vibespot","logs"),bg=7,Ii=!1,Pi=!1;M={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),Mi("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),Mi("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),Mi("ERROR",o)}}});import{readFileSync as Cg,existsSync as kl,writeFileSync as kg,mkdirSync as Tg,rmSync as Ag}from"fs";import{join as ro}from"path";function Kt(e){let t=k();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 tt(){let e=k();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=At("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 nt(e,t,n){let s=k();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),tt(),_g()}function Tl(e){let t=k();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),D())}function Cl(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function $g(e,t){let n=Cl(e),s=Cl(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=k();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=>$g(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(),tt()}}function Nt(e){let t=k();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),tt())}function Al(e){let t=k();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=ro(t.themePath,"modules",`${e}.module`);kl(n)&&Ag(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),tt()}}function $l(e){let t=k();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),tt())}function _l(e,t,n){let s=k();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);Il(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),tt()}catch{}}function Se(){let e=k();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 _g(){let e=k();if(e)try{let t=ro(e.themePath,".vibespot");Tg(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};kg(ro(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function El(e){let t=ro(e,".vibespot","chat.json");if(!kl(t))return[];try{let n=JSON.parse(Cg(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Ml(e){let t=k();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=At(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&&Vn(e.pages[0].templateId),t.updatedAt=Date.now()}}function Il(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&&Il(i.children,s.slice(1).join("."),n))}var Kn=R(()=>{"use strict";h();zn();Ot();ce()});import{existsSync as ao,rmSync as lo}from"fs";import{join as un}from"path";function co(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=k();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function Vn(e){let t=k();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,Kt(n),t.updatedAt=Date.now(),!0):!1}function At(e,t,n){let s=k();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,Kt(l),s.updatedAt=Date.now(),l}function Pl(e,t){let n=k();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,Kt(l),n.updatedAt=Date.now(),l}function Rl(e){let t=k();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 Nl(e,t){let n=k();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 Ol(e,t=!1){let n=k();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(ao(a)&&lo(a,{force:!0}),o.pageType==="blog_post"){let l=un(i,`${o.id}-listing.html`);ao(l)&&lo(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`);ao(c)&&lo(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?Vn(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");ao(r)&&lo(r,{force:!0})}return n.updatedAt=Date.now(),!0}function $t(){let e=k();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 Ot=R(()=>{"use strict";h();zn();Kn()});import{readFileSync as gt,readdirSync as Di,existsSync as $e,writeFileSync as Yn,mkdirSync as uo,rmSync as Ni,renameSync as Oi,cpSync as Eg}from"fs";import{join as de,dirname as Fl}from"path";import{homedir as Mg}from"os";function mo(){if(mn)return mn;try{return $e(Fi)?(mn=JSON.parse(gt(Fi,"utf-8")),mn):ji()}catch{return ji()}}function po(e){mn=e;try{uo(re,{recursive:!0}),Yn(Fi,JSON.stringify(e),"utf-8")}catch{}}function ji(){if(!$e(re))return[];let e=[];for(let t of Di(re).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(gt(de(re,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,po(e),e}function jl(e){let t=mo(),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),po(t)}function Ig(e){let t=mo().filter(n=>n.id!==e);po(t)}function Pg(e){let t=mo().filter(n=>n.themeName!==e);po(t)}function k(){return Le}function Dl(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function pn(e,t,n={}){let s={id:Dl(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Le=s,oo(e),s}function D(){if(!Le)return;uo(re,{recursive:!0});let e=de(re,`${Le.id}.json`);Yn(e,JSON.stringify(Le,null,2),"utf-8"),jl(Le)}function go(e){let t=de(re,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=""),co(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(re)?mo():[]}function Ll(e,t=!1){let n=de(re,e+".json"),s="";if(t)try{let o=JSON.parse(gt(n,"utf-8"));s=o.themeName||"",o.themePath&&$e(o.themePath)&&Ni(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(gt(n,"utf-8")).themeName||""}catch{}try{$e(n)&&Ni(n)}catch{}if(s&&$e(re)){for(let o of Di(re).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(gt(de(re,o),"utf-8")).themeName===s&&Ni(de(re,o))}catch{}Pg(s)}else Ig(e);Le?.id===e&&(Le=null)}function Jl(e,t){let n=de(re,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=de(Fl(i),t);if($e(i)){if($e(r))return{ok:!1,error:"A project with that name already exists"};try{Oi(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=de(r,"css",`${o}-theme.css`),l=de(r,"css",`${t}-theme.css`);if($e(a))try{Oi(a,l)}catch{}let c=de(r,"js",`${o}-animations.js`),d=de(r,"js",`${t}-animations.js`);if($e(c))try{Oi(c,d)}catch{}let u=de(r,"theme.json");if($e(u))try{let m=JSON.parse(gt(u,"utf-8"));m.label=t,m.name=t,Yn(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if($e(re))for(let a of Di(re).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(gt(de(re,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),Yn(de(re,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Le&&Le.themeName===o&&(Le.themeName=t,Le.themePath=r,Le.updatedAt=Date.now()),ji(),{ok:!0}}function Bl(e){let t=de(re,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=Fl(n.themePath),i=`${s}-copy`,r=1;for(;$e(de(o,i));)r++,i=`${s}-copy-${r}`;let a=de(o,i);if($e(n.themePath))try{Eg(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else uo(a,{recursive:!0});let l=Dl(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return uo(re,{recursive:!0}),Yn(de(re,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),jl(c),{ok:!0,newName:i,newSessionId:l}}var re,Fi,mn,Le,zn=R(()=>{"use strict";h();dn();Ot();re=de(Mg(),".vibespot","sessions"),Fi=de(re,"_index.json"),mn=null;Le=null});import{readFileSync as Rg,readdirSync as Ul,statSync as Li}from"fs";import{createHash as Ng}from"crypto";import{join as he,relative as Og}from"path";function yo(e){let t=[];if(!w(e))return af(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=fn(e),s=nf(e),o=of(e),i=rf(e),r=Jg(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 qn(e){let t=[];for(let[n,s]of Object.entries(e.cssVariables))t.push(` ${n}: ${s};`);return Object.keys(e.cssVariables).length===0&&(e.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;t.push(` --color-${o}: ${n.value};`)}),e.fontFamilies[0]&&t.push(` --font-family-base: ${e.fontFamilies[0]};`),e.fontFamilies[1]&&t.push(` --font-family-heading: ${e.fontFamilies[1]};`)),t.length===0?"":`:root {
180
+ Return ONLY the template HTML content, no markdown fences.`}var gl,Ke=N(()=>{"use strict";y();oe();gl=new Map});import{appendFileSync as Fg,mkdirSync as Dg,readdirSync as jg,unlinkSync as Lg}from"fs";import{join as qi}from"path";import{homedir as Jg}from"os";function Hg(){if(!zi)try{Dg(mo,{recursive:!0}),zi=!0}catch{}}function Ug(){if(!Yi){Yi=!0;try{let e=Date.now()-Bg*864e5;for(let t of jg(mo)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{Lg(qi(mo,t))}catch{}}}catch{}}}function Gg(){let t=new Date().toISOString().slice(0,10);return qi(mo,`vibespot-${t}.log`)}function Wg(){return new Date().toISOString().slice(11,23)}function Vi(e,t){if(Hg(),!!zi){Yi||Ug();try{Fg(Gg(),`${Wg()} ${e} ${t}
181
+ `)}catch{}}}var mo,Bg,zi,Yi,E,le=N(()=>{"use strict";y();mo=qi(Jg(),".vibespot","logs"),Bg=7,zi=!1,Yi=!1;E={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),Vi("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),Vi("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),Vi("ERROR",o)}}});function Vg(e){let t=(e||"").toLowerCase();return Kg.find(n=>t.includes(n.match))}function ls(e,t){let n=Vg(e);if(!n)return;let s=n.cacheReadPerM??n.inputPerM*.1,o=n.cacheWritePerM??n.inputPerM*1.25,i=(t.inputTokens??0)*n.inputPerM,r=(t.outputTokens??0)*n.outputPerM,a=(t.cacheReadTokens??0)*s,l=(t.cacheCreationTokens??0)*o,c={total:(i+r+a+l)/1e6};return t.inputTokens!=null&&(c.input=i/1e6),t.outputTokens!=null&&(c.output=r/1e6),t.cacheReadTokens&&(c.cache_read_input_tokens=a/1e6),t.cacheCreationTokens&&(c.cache_creation_input_tokens=l/1e6),c}function et(e){if(e)return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_input_tokens??void 0,cacheCreationTokens:e.cache_creation_input_tokens??void 0}}function _n(e){if(!e)return;let t=e.prompt_tokens_details?.cached_tokens??0,n=e.prompt_tokens;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.completion_tokens,totalTokens:e.total_tokens,cacheReadTokens:t||void 0}}function $n(e){if(!e)return;let t=e.cachedContentTokenCount??0,n=e.promptTokenCount;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.candidatesTokenCount,totalTokens:e.totalTokenCount,cacheReadTokens:t||void 0}}function Cl(e){let t={};return e.inputTokens!=null&&(t.input=e.inputTokens),e.outputTokens!=null&&(t.output=e.outputTokens),e.cacheReadTokens&&(t.cache_read_input_tokens=e.cacheReadTokens),e.cacheCreationTokens&&(t.cache_creation_input_tokens=e.cacheCreationTokens),e.totalTokens!=null&&(t.total=e.totalTokens),t}var Kg,tn=N(()=>{"use strict";y();Kg=[{match:"claude-opus-4",inputPerM:15,outputPerM:75},{match:"claude-sonnet-4",inputPerM:3,outputPerM:15},{match:"claude-haiku-4",inputPerM:1,outputPerM:5},{match:"claude-3-7-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-haiku",inputPerM:.8,outputPerM:4},{match:"claude-3-opus",inputPerM:15,outputPerM:75},{match:"gpt-5.5",inputPerM:5,outputPerM:30},{match:"gpt-5.4",inputPerM:2.5,outputPerM:15},{match:"gpt-5.3",inputPerM:1.75,outputPerM:14},{match:"gpt-4o-mini",inputPerM:.15,outputPerM:.6},{match:"gpt-4o",inputPerM:2.5,outputPerM:10},{match:"gpt-4.1-nano",inputPerM:.1,outputPerM:.4},{match:"gpt-4.1-mini",inputPerM:.4,outputPerM:1.6},{match:"gpt-4.1",inputPerM:2,outputPerM:8},{match:"gemini-2.5-pro",inputPerM:1.25,outputPerM:10},{match:"gemini-2.5-flash",inputPerM:.3,outputPerM:2.5},{match:"gemini-2.0-flash",inputPerM:.1,outputPerM:.4},{match:"gemini-1.5-pro",inputPerM:1.25,outputPerM:5},{match:"gemini-1.5-flash",inputPerM:.075,outputPerM:.3}]});import{AsyncLocalStorage as zg}from"async_hooks";function Yg(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function qg(e){return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,cacheReadTokens:e.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens,totalTokens:e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens,costUsd:e.costUsd,calls:e.calls,costComplete:e.unpricedCalls===0}}async function Xi(e){let t=Yg();return{result:await kl.run(t,e),cost:qg(t)}}function Tl(e,t){if(!t)return;let n=kl.getStore();if(!n)return;n.inputTokens+=t.inputTokens??0,n.outputTokens+=t.outputTokens??0,n.cacheReadTokens+=t.cacheReadTokens??0,n.cacheCreationTokens+=t.cacheCreationTokens??0,n.calls+=1;let s=ls(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}var kl,Zi=N(()=>{"use strict";y();tn();kl=new zg});import{randomUUID as Bt}from"crypto";import{AsyncLocalStorage as Xg}from"async_hooks";function _l(){let e=R(),t=e.langfusePublicKey||process.env.LANGFUSE_PUBLIC_KEY,n=e.langfuseSecretKey||process.env.LANGFUSE_SECRET_KEY;if(!(e.langfuseEnabled===!0||process.env.LANGFUSE_ENABLED==="true")||!t||!n)return null;let o=(e.langfuseBaseUrl||process.env.LANGFUSE_BASE_URL||Zg).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function Qi(){return _l()!==null}function go(e){if(typeof e=="string")return e.length>En?e.slice(0,En)+`\u2026[+${e.length-En} chars]`:e;try{let t=JSON.stringify(e);if(t&&t.length>En)return t.slice(0,En)+`\u2026[+${t.length-En} chars]`}catch{return"[unserializable]"}return e}async function tt(e,t){if(!Qi())return t();let n=Bt();nn.push({id:Bt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},...e.userId?{userId:e.userId}:{},...e.input!==void 0?{input:go(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await po.run({traceId:n,sessionId:e.sessionId},t)}finally{await $l()}}async function te(e,t,n){let s=po.getStore();if(!Qi()||!s?.traceId)return t();let o=Bt(),i=s.spanId,r=new Date,a,l;try{return await po.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{nn.push({id:Bt(),type:"span-create",timestamp:new Date().toISOString(),body:{id:o,traceId:s.traceId,name:e,startTime:r.toISOString(),endTime:new Date().toISOString(),...i?{parentObservationId:i}:{},...n?.input!==void 0?{input:go(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function Qg(e){if(Qi())try{let t=po.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Bt(),o=!0,nn.push({id:Bt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let i=e.usage?Cl(e.usage):void 0,r=e.usage?ls(e.model,e.usage):void 0;nn.push({id:Bt(),type:"generation-create",timestamp:new Date().toISOString(),body:{id:Bt(),traceId:n,...s?{parentObservationId:s}:{},name:e.name,model:e.model,startTime:(e.startTime??new Date).toISOString(),endTime:(e.endTime??new Date).toISOString(),...e.input!==void 0?{input:go(e.input)}:{},...e.output!==void 0?{output:go(e.output)}:{},...i?{usageDetails:i}:{},...r?{costDetails:r}:{},...e.level?{level:e.level}:{},...e.statusMessage?{statusMessage:e.statusMessage}:{},metadata:{...e.engine?{engine:e.engine}:{},...e.metadata??{}}}}),o&&await $l()}catch(t){E.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function St(e){let{engine:t,model:n,name:s,usage:o,startTime:i,endTime:r}=e,a=r.getTime()-i.getTime(),l=o?ls(n,o):void 0;if(o&&E.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),Al.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:i,endTime:r,durationMs:a};for(let d of Al)try{d(c)}catch{}}Tl(n,o),Qg({name:s,model:n,engine:t,input:e.input,output:e.output,usage:o,startTime:i,endTime:r,level:e.level,statusMessage:e.statusMessage,metadata:e.metadata})}async function $l(){let e=_l();if(!e||nn.length===0)return;let t=nn;nn=[];try{let n=Buffer.from(`${e.publicKey}:${e.secretKey}`).toString("base64"),s=await fetch(`${e.baseUrl}/api/public/ingestion`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Basic ${n}`},body:JSON.stringify({batch:t})});if(!s.ok&&s.status!==207){let o=await s.text().catch(()=>"");E.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else E.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){E.warn("langfuse",`ingestion failed: ${n.message}`)}}var Zg,En,po,nn,Al,Be=N(()=>{"use strict";y();ee();le();tn();Zi();Zg="https://cloud.langfuse.com",En=24e3,po=new Xg,nn=[],Al=new Set});import{join as me}from"path";import{readdirSync as it,rmSync as mf}from"fs";function xo(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 wo(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 Co(e){let t=[];return Rl(e)&&t.push("textarea \u2192 text"),Ol(e)&&t.push("name \u2192 item_name"),Fl(e)&&t.push("now() \u2192 local_dt"),Dl(e)&&t.push("Removed HubDB templates"),jl(e)&&t.push("Fixed link field defaults"),Ll(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),pf(e)&&t.push("Stripped CDN @import statements"),Bl(e)&&t.push('dnd_area \u2192 "main" in email templates'),Hl(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function Nl(e,t){return t.message.includes("textarea")?Rl(e):t.message.includes("reserved field name")?Ol(e):t.message.includes("now()")?Fl(e):t.message.includes("HubDB")?Dl(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?jl(e):t.message.includes("invalid format")&&t.message.includes("color")?Ll(e):t.message.includes("dnd")||t.message.includes("Dnd area")?Bl(e):t.message.includes("dnd_area_stylesheet")?Hl(e):!1}function Rl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),J(o,i),t=!0)}return t}function Ol(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),J(o,i),t=!0)}return t}function Fl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"module.html");if(!x(o))continue;let i=P(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),J(o,i),t=!0)}return t}function Dl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(mf(o),t=!0)}return t}function jl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));Ul(i)&&(J(o,JSON.stringify(i,null,2)+`
182
+ `),t=!0)}catch{}}return t}function pf(e){let t=!1,n=me(e,"css");if(x(n))for(let o of it(n)){if(!o.endsWith(".css"))continue;let i=me(n,o),r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(J(i,a),t=!0)}let s=me(e,"modules");if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.css");if(!x(i))continue;let r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(J(i,a),t=!0)}if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.html");if(!x(i))continue;let r=P(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(J(i,a),t=!0)}return t}function Ll(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));Jl(i)&&(J(o,JSON.stringify(i,null,2)+`
183
+ `),t=!0)}catch{}}return t}function Jl(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"&&!gf(i)){let r=ff(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&Jl(s.children)&&(t=!0)}return t}function gf(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function ff(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 Bl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i))continue;let r=i.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');r!==i&&(J(o,r),t=!0)}return t}function Hl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i)||i.includes("dnd_area_stylesheet"))continue;let r=i.replace(/(\{\{\s*standard_header_includes\s*\}\})/,`$1
184
+ {{ dnd_area_stylesheet }}`);r!==i&&(J(o,r),t=!0)}return t}function Ul(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="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)&&Ul(s.children)&&(t=!0)}return t}var ko=N(()=>{"use strict";y();oe()});import{readdirSync as hf}from"fs";import{join as yf,relative as bf}from"path";function Gl(e){let t=[];for(let n of hf(e,{withFileTypes:!0})){if(Sf.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=yf(e,n.name);n.isDirectory()?t.push(...Gl(s)):n.isFile()&&t.push(s)}return t}async function vf(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=Gl(t),r=i.length,a=0,l=0,c=[];return await vf(i,o,async d=>{let u=bf(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await sl(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 Sf,er=N(()=>{"use strict";y();en();en();Sf=new Set([".git","node_modules",".vibespot",".DS_Store"])});var Ql=N(()=>{"use strict";y()});import{existsSync as It,writeFileSync as kf,mkdirSync as Tf}from"fs";import{join as vt}from"path";function tc(e){return/^[0-9a-f]{4,40}$/i.test(e)}function nc(e){return Number.isInteger(e)&&e>0&&e<1e3}function rt(){return Ao!==null||(Ao=Z(["--version"]).success),Ao}function _o(e){if(!rt())return!1;if(It(vt(e,".git")))return ec(e),!0;let t=Z(["init"],{cwd:e});return t.success?(Af(e),ec(e),Z(["add","-A"],{cwd:e}),Z(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function ec(e){let t=vt(e,".vibespot");It(t)||Tf(t,{recursive:!0})}function Af(e){let t=vt(e,".gitignore");kf(t,[".vibespot/","node_modules/",""].join(`
185
+ `),"utf-8")}function sn(e,t){if(!rt()||!It(vt(e,".git"))||(Z(["add","-A"],{cwd:e}),Z(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=Z(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=Z(["rev-parse","--short","HEAD"],{cwd:e});return i.success?i.stdout:null}function nr(e,t,n,s){if(!rt()||!It(vt(e,".git")))return null;for(let u of s){let m=vt(e,u);It(m)&&Z(["add","--",u],{cwd:e})}if(Z(["diff","--cached","--quiet"],{cwd:e}).success)return null;let i=`[${t}] `,r=72-i.length,a=n.length>r?n.slice(0,r-3)+"...":n,l=i+a,c=Z(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=Z(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function sc(e){let t=[],n=null;for(let s of e.split(`
186
+ `)){let o=s.trimEnd();if(o.startsWith("COMMIT|")){n&&t.push(n);let i=o.slice(7).split("|");if(i.length<4){n=null;continue}let r=parseInt(i[3],10)*1e3;n={hash:i[0],fullHash:i[1],message:i[2],timestamp:r,date:new Date(r).toISOString(),changedFiles:[],changedModules:[]}}else o&&n&&n.changedFiles.push(o)}n&&t.push(n);for(let s of t){if(!s.changedFiles)continue;let o=new Set;for(let i of s.changedFiles){let r=i.match(/^modules\/([^/]+)\.module(?:\/|$)/);r&&o.add(r[1])}s.changedModules=[...o]}return t}function oc(e,t=50){if(!rt())return[];if(!It(vt(e,".git")))return[];if(!nc(t))return[];let n=Z(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:sc(n.stdout)}function ic(e,t,n=50){if(!rt())return[];if(!It(vt(e,".git")))return[];if(!nc(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=Z(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:sc(o.stdout)}function rc(e,t){if(!rt())return{success:!1,error:"Git not available"};if(!It(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!tc(t))return{success:!1,error:"Invalid commit hash"};let n=Z(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=Z(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=Z(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return Z(["commit","-m",r],{cwd:e}),{success:!0}}function ac(e,t,n,s){if(!rt())return{success:!1,error:"Git not available"};if(!It(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!tc(n))return{success:!1,error:"Invalid commit hash"};let o=Z(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=Z(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)Z(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};Z(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return Z(["commit","-m",c],{cwd:e}),{success:!0}}var Ao,In=N(()=>{"use strict";y();qt();Ao=null});import{readFileSync as _f,existsSync as cc,writeFileSync as $f,mkdirSync as Ef,rmSync as Mf}from"fs";import{join as $o}from"path";function on(e){let t=C();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e.plan)}function at(){let e=C();if(!e)return;let t=ke();if(!t){if(e.modules.length===0)return;let n={modules:e.modules,moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,template:e.template,messages:e.messages,plan:e.brandAssets?.plan};t=Pt("landing_page",`${e.themeName} Landing Page`),e.activeTemplateId=t.id,e.modules=n.modules,e.moduleOrder=n.moduleOrder,e.sharedCss=n.sharedCss,e.sharedJs=n.sharedJs,e.template=n.template,e.messages=n.messages,e.brandAssets&&(e.brandAssets.plan=n.plan)}t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.plan=e.brandAssets?.plan}function lt(e,t,n){let s=C();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),at(),Pf()}function dc(e){let t=C();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),j())}function uc(e){let t=C();if(!t)return;if(e.calls===0)return t.costTotal;let n=t.costTotal??{costUsd:0,totalTokens:0,generations:0,costComplete:!0},s={costUsd:n.costUsd+e.costUsd,totalTokens:n.totalTokens+e.totalTokens,generations:n.generations+1,costComplete:n.costComplete&&e.costComplete};return t.costTotal=s,t.updatedAt=Date.now(),s}function lc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function If(e,t){let n=lc(e),s=lc(t);if(n===s)return!0;if(n.length<4||s.length<4)return!1;let o=n.length<=s.length?n:s,i=n.length<=s.length?s:n;return i.includes(o)?o.length/i.length>=.8:!1}function He(e){let t=C();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let i=t.modules.find(r=>If(r.moduleName,n.moduleName));i&&E.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${i.moduleName}" \u2014 adding as a new module. This usually indicates the Module Planner re-named an existing module. Check the prompt's "preserve existing names" rule.`),t.modules.push(n),t.moduleOrder.some(r=>r.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),at()}}function Ht(e){let t=C();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),at())}function mc(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=$o(t.themePath,"modules",`${e}.module`);cc(n)&&Mf(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),at()}}function pc(e){let t=C();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),at())}function gc(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);yc(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),at()}catch{}}function ve(){let e=C();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Pf(){let e=C();if(e)try{let t=$o(e.themePath,".vibespot");Ef(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};$f($o(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function fc(e){let t=$o(e,".vibespot","chat.json");if(!cc(t))return[];try{let n=JSON.parse(_f(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function hc(e){let t=C();if(t){for(let n of t.templates)n.sharedCss=e.sharedCss,n.sharedJs=e.sharedJs;t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs;for(let n of e.pages){let s=e.pageLabels.get(n.pageId),o=s?.label||n.pageId,i=s?.pageType||"website_page",r=t.templates.find(a=>a.id===n.templateId);r||(r=Pt(i,o),r.id=n.templateId,r.templateFile=`templates/${n.templateId}.html`),r.modules=n.modules,r.moduleOrder=n.moduleOrder,r.sharedCss=e.sharedCss,r.sharedJs=e.sharedJs}e.pages.length>0&&us(e.pages[0].templateId),t.updatedAt=Date.now()}}function yc(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&&yc(i.children,s.slice(1).join("."),n))}var ds=N(()=>{"use strict";y();ms();Ut();le()});import{existsSync as Eo,rmSync as Mo}from"fs";import{join as Pn}from"path";function Io(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function ke(){let e=C();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function us(e){let t=C();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,on(n),t.updatedAt=Date.now(),!0):!1}function Pt(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=n==="email",a=`${i?"email":e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:t,pageType:e,contentMode:n,templateFile:i?"templates/email.html":e==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,on(l),s.updatedAt=Date.now(),l}function bc(e,t){let n=C();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:a,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${a}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[],plan:s.plan};return n.templates.push(l),n.activeTemplateId=a,on(l),n.updatedAt=Date.now(),l}function Sc(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 vc(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 xc(e,t=!1){let n=C();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Pn(n.themePath,"templates"),r=`${o.id}.html`,a=Pn(i,r);if(Eo(a)&&Mo(a,{force:!0}),o.pageType==="blog_post"){let l=Pn(i,`${o.id}-listing.html`);Eo(l)&&Mo(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let a of n.templates)for(let l of a.modules)i.add(l.moduleName);for(let a of n.modules)i.add(a.moduleName);let r=o.modules.map(a=>a.moduleName).filter(a=>!i.has(a));if(n.themePath&&r.length>0){let a=Pn(n.themePath,"modules");for(let l of r){let c=Pn(a,`${l}.module`);Eo(c)&&Mo(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?us(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[],n.brandAssets&&delete n.brandAssets.plan)),o.plan&&n.themePath&&!n.templates.some(r=>!!r.plan)){let r=Pn(n.themePath,".vibespot","plan.md");Eo(r)&&Mo(r,{force:!0})}return n.updatedAt=Date.now(),!0}function Nt(){let e=C();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of e.modules)t.has(n.moduleName)||t.set(n.moduleName,{module:n,usedIn:[]});return Array.from(t.values())}var Ut=N(()=>{"use strict";y();ms();ds()});import{readFileSync as xt,readdirSync as ar,existsSync as Ie,writeFileSync as ps,mkdirSync as Po,rmSync as sr,renameSync as or,cpSync as Nf}from"fs";import{join as pe,dirname as wc}from"path";import{homedir as Rf}from"os";function No(){if(Nn)return Nn;try{return Ie(ir)?(Nn=JSON.parse(xt(ir,"utf-8")),Nn):rr()}catch{return rr()}}function Ro(e){Nn=e;try{Po(de,{recursive:!0}),ps(ir,JSON.stringify(e),"utf-8")}catch{}}function rr(){if(!Ie(de))return[];let e=[];for(let t of ar(de).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(xt(pe(de,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length,pageCount:s.filter(o=>o.contentMode!=="email").length,emailCount:s.filter(o=>o.contentMode==="email").length,hasBrandAssets:!!(n.brandAssets&&(n.brandAssets.styleguide||n.brandAssets.brandvoice||n.brandAssets.brandKit)),isImported:!!n.isImported})}catch{}return Nn=e,Ro(e),e}function Cc(e){let t=No(),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),Ro(t)}function Of(e){let t=No().filter(n=>n.id!==e);Ro(t)}function Ff(e){let t=No().filter(n=>n.themeName!==e);Ro(t)}function C(){return Ue}function kc(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Rn(e,t,n={}){let s={id:kc(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Ue=s,_o(e),s}function j(){if(!Ue)return;Po(de,{recursive:!0});let e=pe(de,`${Ue.id}.json`);ps(e,JSON.stringify(Ue,null,2),"utf-8"),Cc(Ue)}function Oo(e){let t=pe(de,e+".json");if(!Ie(t))return null;try{let n=JSON.parse(xt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Io(n),n.brandAssets?.plan&&n.templates?.length>0){let s=n.templates.find(o=>o.id===n.activeTemplateId)||n.templates[0];s.plan||(s.plan=n.brandAssets.plan)}return Ue=n,n}catch{return null}}function On(){return Ie(de)?No():[]}function Tc(e,t=!1){let n=pe(de,e+".json"),s="";if(t)try{let o=JSON.parse(xt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ie(o.themePath)&&sr(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(xt(n,"utf-8")).themeName||""}catch{}try{Ie(n)&&sr(n)}catch{}if(s&&Ie(de)){for(let o of ar(de).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(xt(pe(de,o),"utf-8")).themeName===s&&sr(pe(de,o))}catch{}Ff(s)}else Of(e);Ue?.id===e&&(Ue=null)}function Ac(e,t){let n=pe(de,e+".json");if(!Ie(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(xt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,r=pe(wc(i),t);if(Ie(i)){if(Ie(r))return{ok:!1,error:"A project with that name already exists"};try{or(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=pe(r,"css",`${o}-theme.css`),l=pe(r,"css",`${t}-theme.css`);if(Ie(a))try{or(a,l)}catch{}let c=pe(r,"js",`${o}-animations.js`),d=pe(r,"js",`${t}-animations.js`);if(Ie(c))try{or(c,d)}catch{}let u=pe(r,"theme.json");if(Ie(u))try{let m=JSON.parse(xt(u,"utf-8"));m.label=t,m.name=t,ps(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ie(de))for(let a of ar(de).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(xt(pe(de,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),ps(pe(de,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Ue&&Ue.themeName===o&&(Ue.themeName=t,Ue.themePath=r,Ue.updatedAt=Date.now()),rr(),{ok:!0}}function _c(e){let t=pe(de,e+".json");if(!Ie(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(xt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=wc(n.themePath),i=`${s}-copy`,r=1;for(;Ie(pe(o,i));)r++,i=`${s}-copy-${r}`;let a=pe(o,i);if(Ie(n.themePath))try{Nf(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else Po(a,{recursive:!0});let l=kc(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return Po(de,{recursive:!0}),ps(pe(de,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Cc(c),{ok:!0,newName:i,newSessionId:l}}var de,ir,Nn,Ue,ms=N(()=>{"use strict";y();In();Ut();de=pe(Rf(),".vibespot","sessions"),ir=pe(de,"_index.json"),Nn=null;Ue=null});import{readFileSync as Df,readdirSync as Mc,statSync as lr}from"fs";import{createHash as jf}from"crypto";import{join as be,relative as Lf}from"path";function jo(e){let t=[];if(!x(e))return dh(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=Fn(e),s=rh(e),o=lh(e),i=ch(e),r=Gf(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 gs(e){let t=[];for(let[n,s]of Object.entries(e.cssVariables))t.push(` ${n}: ${s};`);return Object.keys(e.cssVariables).length===0&&(e.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;t.push(` --color-${o}: ${n.value};`)}),e.fontFamilies[0]&&t.push(` --font-family-base: ${e.fontFamilies[0]};`),e.fontFamilies[1]&&t.push(` --font-family-heading: ${e.fontFamilies[1]};`)),t.length===0?"":`:root {
187
187
  ${t.join(`
188
188
  `)}
189
189
  }
190
- `}function bo(e,t){let n=he(e,"css");if(w(n))try{for(let r of Ul(n))if(r.endsWith("-theme.css"))return null}catch{}let s=fn(e),o=qn(s);if(!o)return null;let i=he(n,`${t}-theme.css`);return J(i,o),i}function Xn(e){return he(e,Fg)}function Dg(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:Vl(e)}}function Ji(e,t){let n=Dg(e,t),s=Xn(e);return J(s,JSON.stringify(n,null,2)+`
191
- `),s}function Wl(e){let t=Xn(e);return w(t)?null:Ji(e)}function Lg(e){let t=Xn(e);if(!w(t))return null;try{let n=JSON.parse(E(t));return cf(n)?n:null}catch{return null}}function Jg(e){let t=Xn(e),n=Lg(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=Vl(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:ho(d.text),afterLines:ho(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:ho(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:ho(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=tf(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,y=new RegExp(Yg.source,"g");for(;(g=y.exec(m))!==null;){let f=g[1],b=new RegExp(qg.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 L=Hl(I[0]);o.set(L,x)}}}for(let f of[Bg,Hg,Gg]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let x=Hl(S[0]);x&&s.set(x,(s.get(x)??0)+1)}}fo(m,Ug,i,Zg),fo(m,Wg,r,f=>f.trim()),Xg(m,a),fo(m,Vg,l,f=>f.trim()),fo(m,zg,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!ef(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 fo(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 Xg(e,t){let n=new RegExp(Kg.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 Hl(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 ef(e){return Qg.has(e)}function tf(e){let t=[],n=he(e,"css");if(w(n))for(let o of Ft(n))o.endsWith(".css")&&t.push(he(n,o));let s=he(e,"modules");if(w(s))for(let o of Ft(s)){if(!o.endsWith(".module"))continue;let i=he(s,o,"module.css");w(i)&&t.push(i)}return t}function nf(e){let t=he(e,"modules"),n=he(e,"templates"),s=new Set,o=new Map;if(w(t))for(let c of Ft(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 Ft(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=he(n,c),u;try{u=Li(d)}catch{continue}if(!u.isFile())continue;let m;try{m=E(d)}catch{continue}let g=Bi(m);for(let f of g){let b=r.get(f)??new Set;b.add(c),r.set(f,b)}let y=c.replace(/\.html$/,"");i.push({id:y,file:`templates/${c}`,modules:df(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 Bi(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 of(e){let t=[],n=he(e,"modules");if(!w(n))return t;for(let s of Ft(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)&&Kl(r,o,t,0)}return t}function Kl(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&&!sf.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)&&Kl(i.children,t,n,s+1)}}function rf(e){let t=[],n=he(e,"modules");if(w(n))for(let i of Ft(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=he(n,i,"module.html");w(a)&&Gl(a,e,r,t);let l=he(n,i,"module.js");if(w(l))try{E(l).trim().length>0&&t.push({file:Hi(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 Ft(s)){if(!i.endsWith(".html"))continue;let r=he(s,i);if(!w(r))continue;let a;try{a=Li(r)}catch{continue}a.isFile()&&Gl(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 Gl(e,t,n,s){let o;try{o=E(e)}catch{return}let i=Hi(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 af(e,t){let n={hasSnapshot:!1,snapshotPath:Xn(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 Vl(e){let t=[];function n(s){for(let o of Ft(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=he(s,o),r;try{r=Li(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=Hi(e,i),l=Rg(i),c={path:a,sha256:Ng("sha256").update(l).digest("hex"),size:l.length};lf(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function lf(e){let t=e.lastIndexOf(".");return t<0?!1:jg.has(e.slice(t).toLowerCase())}function cf(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 ho(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Ft(e){try{return Ul(e)}catch{return[]}}function Hi(e,t){return Og(e,t).split("\\").join("/")}function df(e){return[...new Set(e)]}var Fg,jg,Bg,Hg,Gg,Ug,Wg,Kg,Vg,zg,Yg,qg,Qg,sf,So=R(()=>{"use strict";h();se();Fg=".vibespot/import-snapshot.json",jg=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);Bg=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Hg=/\brgba?\([^)]+\)/g,Gg=/\bhsla?\([^)]+\)/g,Ug=/font-family\s*:\s*([^;}\n]+)/g,Wg=/font-size\s*:\s*([^;}\n]+)/g,Kg=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,Vg=/border-radius\s*:\s*([^;}\n]+)/g,zg=/box-shadow\s*:\s*([^;}\n]+)/g,Yg=/:root\s*\{([\s\S]*?)\}/g,qg=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;Qg=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);sf=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 Gi,readdirSync as Qn,existsSync as ve,writeFileSync as Ke,mkdirSync as Zn,rmSync as zl}from"fs";import{join as B}from"path";function xe(e){try{return Gi(e,"utf-8")}catch{return""}}function ql(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 uf(e,t){let n=xe(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=Bi(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function mf(e,t,n,s,o){if(!ve(e))return[];let i=[],r=Qn(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=B(e,a),c=uf(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 vo(e){let t=k();if(!t)return;let n=El(e);n.length>0&&t.messages.length===0&&(t.messages=n),oo(e),Wl(e);let s=B(e,"modules");if(!ve(s))return;let o=Qn(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let x=B(s,S.name),v=S.name.replace(/\.module$/,""),I={moduleName:v,fieldsJson:xe(B(x,"fields.json")),metaJson:xe(B(x,"meta.json")),moduleHtml:xe(B(x,"module.html")),moduleCss:xe(B(x,"module.css")),moduleJs:xe(B(x,"module.js"))||void 0};I.fieldsJson&&I.moduleHtml&&(t.modules.push(I),t.moduleOrder.push(v))}let i=B(e,"css"),r=B(e,"js"),a="",l="";if(ve(i)){let S=Qn(i).filter(x=>x.endsWith("-theme.css"));S.length>0&&(a=xe(B(i,S[0])),t.sharedCss=a)}if(ve(r)){let S=Qn(r).filter(x=>x.endsWith("-animations.js"));S.length>0&&(l=xe(B(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=fn(e),x=qn(S);x&&(t.sharedCss=x,a=x)}let c=B(e,".vibespot","styleguide.md"),d=B(e,".vibespot","brandvoice.md"),u=B(e,".vibespot","theme-context.md"),m=B(e,".vibespot","plan.md"),g=B(e,".vibespot","brand-kit.json");if((ve(c)||ve(d)||ve(u)||ve(m)||ve(g))&&(t.brandAssets||(t.brandAssets={}),ve(c)&&(t.brandAssets.styleguide=xe(c)),ve(d)&&(t.brandAssets.brandvoice=xe(d)),ve(u)&&(t.brandAssets.themeContext=xe(u)),ve(m)&&(t.brandAssets.plan=xe(m)),ve(g)))try{t.brandAssets.brandKit=JSON.parse(xe(g))}catch{}let y=B(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=mf(y,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}Kt(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),co(t)}function ke(){let e=k();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=B(t,"modules");Zn(s,{recursive:!0});for(let l of n.values())Zn(B(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=B(s,`${l.moduleName}.module`);Ke(B(c,"fields.json"),l.fieldsJson,"utf-8"),Ke(B(c,"meta.json"),l.metaJson,"utf-8"),Ke(B(c,"module.html"),l.moduleHtml,"utf-8"),Ke(B(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ke(B(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=B(t,"css");Zn(l,{recursive:!0}),Ke(B(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=B(t,"js");Zn(l,{recursive:!0}),Ke(B(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=B(t,"templates");Zn(o,{recursive:!0});let i=B(o,"home.html");(e.templates.length>0||e.modules.length>0)&&ve(i)&&zl(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=hf(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ke(B(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||ff(l),d=Yl(c,l.label,l.pageType),u=`${l.id}.html`;Ke(B(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(yf(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||bf(),c=Yl(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ke(B(o,d),c,"utf-8"),a.add(d)}try{for(let l of Qn(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&zl(B(o,l),{force:!0})}catch{}pf(),gf()}function Xl(){let e=k();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",vo(e.themePath),e.updatedAt=Date.now(),tt())}function Zl(){let e=k();if(!e)return;let t=Ce();if(!t)return;let n=e.themePath,s=B(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=B(s,`${o}.module`);if(!ve(i))continue;let r={moduleName:o,fieldsJson:xe(B(i,"fields.json")),metaJson:xe(B(i,"meta.json")),moduleHtml:xe(B(i,"module.html")),moduleCss:xe(B(i,"module.css")),moduleJs:xe(B(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=B(n,t.templateFile);ve(o)&&(t.template=xe(o))}Kt(t),e.updatedAt=Date.now()}function pf(){let e=k();if(!e)return;let t=B(e.themePath,"templates","layouts","base.html");if(ve(t))try{let n=Gi(t,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
190
+ `}function Lo(e,t){let n=be(e,"css");if(x(n))try{for(let r of Mc(n))if(r.endsWith("-theme.css"))return null}catch{}let s=Fn(e),o=gs(s);if(!o)return null;let i=be(n,`${t}-theme.css`);return J(i,o),i}function fs(e){return be(e,Jf)}function Hf(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:Nc(e)}}function cr(e,t){let n=Hf(e,t),s=fs(e);return J(s,JSON.stringify(n,null,2)+`
191
+ `),s}function Ic(e){let t=fs(e);return x(t)?null:cr(e)}function Uf(e){let t=fs(e);if(!x(t))return null;try{let n=JSON.parse(P(t));return mh(n)?n:null}catch{return null}}function Gf(e){let t=fs(e),n=Uf(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=Nc(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:Do(d.text),afterLines:Do(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:Do(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:Do(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=ih(e),n={},s=new Map,o=new Map,i=new Set,r=new Set,a=new Set,l=new Set,c=new Set;for(let u of t){let m;try{m=P(u)}catch{continue}let g,h=new RegExp(Qf.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(eh.source,"g"),S;for(;(S=b.exec(f))!==null;){let v=S[1].trim(),w=S[2].trim();n[v]||(n[v]=w);let M=w.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if(M){let L=$c(M[0]);o.set(L,v)}}}for(let f of[Wf,Kf,Vf]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let v=$c(S[0]);v&&s.set(v,(s.get(v)??0)+1)}}Fo(m,zf,i,nh),Fo(m,Yf,r,f=>f.trim()),th(m,a),Fo(m,Xf,l,f=>f.trim()),Fo(m,Zf,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!oh(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 Fo(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 th(e,t){let n=new RegExp(qf.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 nh(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function $c(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 oh(e){return sh.has(e)}function ih(e){let t=[],n=be(e,"css");if(x(n))for(let o of Gt(n))o.endsWith(".css")&&t.push(be(n,o));let s=be(e,"modules");if(x(s))for(let o of Gt(s)){if(!o.endsWith(".module"))continue;let i=be(s,o,"module.css");x(i)&&t.push(i)}return t}function rh(e){let t=be(e,"modules"),n=be(e,"templates"),s=new Set,o=new Map;if(x(t))for(let c of Gt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,x(be(t,c,"module.js")))}let i=[],r=new Map;if(x(n))for(let c of Gt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=be(n,c),u;try{u=lr(d)}catch{continue}if(!u.isFile())continue;let m;try{m=P(d)}catch{continue}let g=dr(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:ph(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 dr(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 lh(e){let t=[],n=be(e,"modules");if(!x(n))return t;for(let s of Gt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=be(n,s,"fields.json");if(!x(i))continue;let r;try{r=JSON.parse(P(i))}catch{continue}Array.isArray(r)&&Pc(r,o,t,0)}return t}function Pc(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&&!ah.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)&&Pc(i.children,t,n,s+1)}}function ch(e){let t=[],n=be(e,"modules");if(x(n))for(let i of Gt(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=be(n,i,"module.html");x(a)&&Ec(a,e,r,t);let l=be(n,i,"module.js");if(x(l))try{P(l).trim().length>0&&t.push({file:ur(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=be(e,"templates");if(x(s))for(let i of Gt(s)){if(!i.endsWith(".html"))continue;let r=be(s,i);if(!x(r))continue;let a;try{a=lr(r)}catch{continue}a.isFile()&&Ec(r,e,i,t)}let o=be(e,"import_modules.json");return x(o)&&t.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),t}function Ec(e,t,n,s){let o;try{o=P(e)}catch{return}let i=ur(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 dh(e,t){let n={hasSnapshot:!1,snapshotPath:fs(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 Nc(e){let t=[];function n(s){for(let o of Gt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=be(s,o),r;try{r=lr(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=ur(e,i),l=Df(i),c={path:a,sha256:jf("sha256").update(l).digest("hex"),size:l.length};uh(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function uh(e){let t=e.lastIndexOf(".");return t<0?!1:Bf.has(e.slice(t).toLowerCase())}function mh(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 Do(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Gt(e){try{return Mc(e)}catch{return[]}}function ur(e,t){return Lf(e,t).split("\\").join("/")}function ph(e){return[...new Set(e)]}var Jf,Bf,Wf,Kf,Vf,zf,Yf,qf,Xf,Zf,Qf,eh,sh,ah,Jo=N(()=>{"use strict";y();oe();Jf=".vibespot/import-snapshot.json",Bf=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);Wf=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Kf=/\brgba?\([^)]+\)/g,Vf=/\bhsla?\([^)]+\)/g,zf=/font-family\s*:\s*([^;}\n]+)/g,Yf=/font-size\s*:\s*([^;}\n]+)/g,qf=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,Xf=/border-radius\s*:\s*([^;}\n]+)/g,Zf=/box-shadow\s*:\s*([^;}\n]+)/g,Qf=/:root\s*\{([\s\S]*?)\}/g,eh=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;sh=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);ah=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 mr,readdirSync as ys,existsSync as xe,writeFileSync as Ye,mkdirSync as hs,rmSync as Rc}from"fs";import{join as U}from"path";function we(e){try{return mr(e,"utf-8")}catch{return""}}function Fc(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 gh(e,t){let n=we(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o=/templateType:\s*email\b/i.test(n),i="landing_page",r;o?(i="module_only",r="email"):s.startsWith("bp-")?i="blog_post":s.startsWith("wp-")?i="website_page":s.startsWith("mo-")&&(i="module_only");let a=s,l=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);l&&(a=l[1].trim());let c=dr(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function fh(e,t,n,s,o){if(!xe(e))return[];let i=[],r=ys(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=U(e,a),c=gh(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 Bo(e){let t=C();if(!t)return;let n=fc(e);n.length>0&&t.messages.length===0&&(t.messages=n),_o(e),Ic(e);let s=U(e,"modules");if(!xe(s))return;let o=ys(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let v=U(s,S.name),w=S.name.replace(/\.module$/,""),M={moduleName:w,fieldsJson:we(U(v,"fields.json")),metaJson:we(U(v,"meta.json")),moduleHtml:we(U(v,"module.html")),moduleCss:we(U(v,"module.css")),moduleJs:we(U(v,"module.js"))||void 0};M.fieldsJson&&M.moduleHtml&&(t.modules.push(M),t.moduleOrder.push(w))}let i=U(e,"css"),r=U(e,"js"),a="",l="";if(xe(i)){let S=ys(i).filter(v=>v.endsWith("-theme.css"));S.length>0&&(a=we(U(i,S[0])),t.sharedCss=a)}if(xe(r)){let S=ys(r).filter(v=>v.endsWith("-animations.js"));S.length>0&&(l=we(U(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=Fn(e),v=gs(S);v&&(t.sharedCss=v,a=v)}let c=U(e,".vibespot","styleguide.md"),d=U(e,".vibespot","brandvoice.md"),u=U(e,".vibespot","theme-context.md"),m=U(e,".vibespot","plan.md"),g=U(e,".vibespot","brand-kit.json");if((xe(c)||xe(d)||xe(u)||xe(m)||xe(g))&&(t.brandAssets||(t.brandAssets={}),xe(c)&&(t.brandAssets.styleguide=we(c)),xe(d)&&(t.brandAssets.brandvoice=we(d)),xe(u)&&(t.brandAssets.themeContext=we(u)),xe(m)&&(t.brandAssets.plan=we(m)),xe(g)))try{t.brandAssets.brandKit=JSON.parse(we(g))}catch{}let h=U(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=fh(h,f,a,l,t.messages);if(b.length>0){t.templates=b,t.activeTemplateId=b[0].id,t.brandAssets?.plan&&!b[0].plan&&(b[0].plan=t.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let v=new Set(t.moduleOrder),w=S.filter(M=>v.has(M));for(let M of t.moduleOrder)w.includes(M)||w.push(M);t.moduleOrder=w}on(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),Io(t)}function Te(){let e=C();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=U(t,"modules");hs(s,{recursive:!0});for(let l of n.values())hs(U(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=U(s,`${l.moduleName}.module`);Ye(U(c,"fields.json"),l.fieldsJson,"utf-8"),Ye(U(c,"meta.json"),l.metaJson,"utf-8"),Ye(U(c,"module.html"),l.moduleHtml,"utf-8"),Ye(U(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ye(U(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=U(t,"css");hs(l,{recursive:!0}),Ye(U(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=U(t,"js");hs(l,{recursive:!0}),Ye(U(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=U(t,"templates");hs(o,{recursive:!0});let i=U(o,"home.html");(e.templates.length>0||e.modules.length>0)&&xe(i)&&Rc(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=Sh(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ye(U(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||bh(l),d=Oc(c,l.label,l.pageType),u=`${l.id}.html`;Ye(U(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(vh(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||xh(),c=Oc(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ye(U(o,d),c,"utf-8"),a.add(d)}try{for(let l of ys(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&Rc(U(o,l),{force:!0})}catch{}hh(),yh()}function Dc(){let e=C();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",Bo(e.themePath),e.updatedAt=Date.now(),at())}function jc(){let e=C();if(!e)return;let t=ke();if(!t)return;let n=e.themePath,s=U(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=U(s,`${o}.module`);if(!xe(i))continue;let r={moduleName:o,fieldsJson:we(U(i,"fields.json")),metaJson:we(U(i,"meta.json")),moduleHtml:we(U(i,"module.html")),moduleCss:we(U(i,"module.css")),moduleJs:we(U(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=U(n,t.templateFile);xe(o)&&(t.template=we(o))}on(t),e.updatedAt=Date.now()}function hh(){let e=C();if(!e)return;let t=U(e.themePath,"templates","layouts","base.html");if(xe(t))try{let n=mr(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(t,n,"utf-8")}catch{}}function gf(){let e=k();if(!e)return;let t=B(e.themePath,"theme.json");if(ve(t))try{let n=JSON.parse(Gi(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ke(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Yl(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
197
+ {{ standard_footer_includes }}`),Ye(t,n,"utf-8")}catch{}}function yh(){let e=C();if(!e)return;let t=U(e.themePath,"theme.json");if(xe(t))try{let n=JSON.parse(mr(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ye(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Oc(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
198
198
  templateType: ${n==="blog_post"?"blog_post":"page"}
199
199
  isAvailableForNewContent: true
200
200
  label: "${t}"
201
201
  -->
202
- `+e}function ff(e){if(e.modules.length===0)return"";let n=k().themeName,o=ql(e).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
202
+ `+e}function bh(e){if(e.modules.length===0)return"";let n=C().themeName,o=Fc(e).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
203
203
  {% dnd_module path="../modules/${r.moduleName}.module" %}
204
204
  {% end_dnd_module %}
205
205
  {% end_dnd_section %}`).join(`
@@ -230,7 +230,7 @@ ${o}
230
230
 
231
231
  {% block footer %}
232
232
  {% endblock footer %}
233
- `}function hf(e){let n=ql(e).map(s=>` {% dnd_section %}
233
+ `}function Sh(e){let n=Fc(e).map(s=>` {% dnd_section %}
234
234
  {% dnd_module path="../modules/${s.moduleName}.module" %}
235
235
  {% end_dnd_module %}
236
236
  {% end_dnd_section %}`).join(`
@@ -277,7 +277,7 @@ ${n}
277
277
  {{ standard_footer_includes }}
278
278
  </body>
279
279
  </html>
280
- `}function yf(e,t){let n=`<!--
280
+ `}function vh(e,t){let n=`<!--
281
281
  templateType: blog_listing
282
282
  isAvailableForNewContent: true
283
283
  label: "${t.label} - Listing"
@@ -302,7 +302,7 @@ ${n}
302
302
  {% endif %}
303
303
  </div>
304
304
  {% endblock body %}
305
- `;Ke(B(e,`${t.id}-listing.html`),n,"utf-8")}function bf(){let e=k();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 %}
305
+ `;Ye(U(e,`${t.id}-listing.html`),n,"utf-8")}function xh(){let e=C();if(!e||e.modules.length===0)return"";let t=e.themeName,s=ve().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
306
306
  {% dnd_module path="../modules/${o.moduleName}.module" %}
307
307
  {% end_dnd_module %}
308
308
  {% end_dnd_section %}`).join(`
@@ -333,7 +333,7 @@ ${s}
333
333
 
334
334
  {% block footer %}
335
335
  {% endblock footer %}
336
- `}var Ui=R(()=>{"use strict";h();zn();Kn();Ot();dn();So()});var Ql=R(()=>{"use strict";h();gl();zn();Kn();Ui();Ot()});var we=R(()=>{"use strict";h();Ql()});function es(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]=es(n.children):t[n.name]=n.default??"";return t}function xo(e,t){let n=e;return n=$f(n),n=sc(n,t),n=oc(n,t),n=ic(n,t),n=Ef(n),n}function Ki(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
336
+ `}var pr=N(()=>{"use strict";y();ms();ds();Ut();In();Jo()});var Lc=N(()=>{"use strict";y();Ql();ms();ds();pr();Ut()});var Ce=N(()=>{"use strict";y();Lc()});function rn(e){let t={};for(let n of e)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?t[n.name]=n.default:n.type==="group"&&n.children?t[n.name]=rn(n.children):t[n.name]=n.default??"";return t}function jn(e,t){let n=e;return n=Mh(n),n=Uc(n,t),n=Gc(n,t),n=Wc(n,t),n=Ph(n),n}function hr(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
337
337
  `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
338
338
  `),s=e.renderedModules.join(`
339
339
  `);return`<!DOCTYPE html>
@@ -380,11 +380,11 @@ document.querySelectorAll('img').forEach(function(img){
380
380
  });
381
381
  </script>
382
382
  </body>
383
- </html>`}function $f(e){return e=e.replace(Sf,""),e=e.replace(vf,""),e=e.replace(xf,""),ec.lastIndex=0,e=e.replace(ec,(t,n)=>`/theme-assets/${n}`),tc.lastIndex=0,e=e.replace(tc,""),e=e.replace(wf,""),e=e.replace(Cf,""),e=e.replace(kf,""),e=e.replace(Tf,""),e=e.replace(Af,""),e}function sc(e,t){let n=e,s=0;for(;s<30;){s++;let o=_f(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Mf(r,t),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let y={...t,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},f=sc(a,y);return f=oc(f,y),f=ic(f,y),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function _f(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 oc(e,t){let n=e,s=0;for(;Wi.test(n)&&s<50;)s++,n=n.replace(Wi,(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}),Wi.lastIndex=0;return n}function ic(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Vt(t,r);for(let c=1;c<i.length;c++)a=ac(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 Ef(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Mf(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=nc(n[1],t),i=nc(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=Vt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Vt(t,e)}function nc(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Vt(t,o);for(let r=1;r<s.length;r++)i=ac(i,s[r].trim());return Number(i)||0}function Vt(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=Vt(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=Vt(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=Vt(t,n);return rc(o)}function rc(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function ac(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 rc(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 Sf,vf,xf,ec,tc,wf,Cf,kf,Tf,Af,Wi,lc=R(()=>{"use strict";h();Sf=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,vf=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,xf=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,ec=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,tc=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,wf=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Cf=/\{%[-\s]*module\b.*?%\}/gs,kf=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Tf=/\{#.*?#\}/gs,Af=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Wi=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var wo={};Be(wo,{buildModulePreviewHtml:()=>Yi,buildPreviewHtml:()=>zi});function If(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 Pf(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 Vi(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 zi(){let e=k();if(!e)return cc();let t=Se(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return cc();if(If(t))return Rf(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:es(u)}}catch{d={module:{}}}let m=Vi(c.moduleHtml,u),g=xo(m,d),y=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${y}" data-module="${c.moduleName}">${g}</div>`),r.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let a=Pf(e.sharedCss);for(let c of n)if(!r.has(c)){let d=c.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module vibespot-module--pending" id="${d}" data-module="${c}">
383
+ </html>`}function Mh(e){return e=e.replace(wh,""),e=e.replace(Ch,""),e=e.replace(kh,""),Jc.lastIndex=0,e=e.replace(Jc,(t,n)=>`/theme-assets/${n}`),Bc.lastIndex=0,e=e.replace(Bc,""),e=e.replace(Th,""),e=e.replace(Ah,""),e=e.replace(_h,""),e=e.replace($h,""),e=e.replace(Eh,""),e}function Uc(e,t){let n=e,s=0;for(;s<30;){s++;let o=Ih(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Nh(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=Uc(a,h);return f=Gc(f,h),f=Wc(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Ih(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 Gc(e,t){let n=e,s=0;for(;gr.test(n)&&s<50;)s++,n=n.replace(gr,(o,i,r)=>{let a=r.split(/\{%[-\s]*else\s*-?%\}/),l=a[0],c=a[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(Dn(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(Dn(m,t))return g}return c}return Dn(i,t)?l:c}),gr.lastIndex=0;return n}function Wc(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Rh(t,r);for(let c=1;c<i.length;c++)a=Vc(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 Ph(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Nh(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Hc(n[1],t),i=Hc(n[2],t),r=[];for(let a=o;a<i;a++)r.push(a);return r}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=Wt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Wt(t,e)}function Hc(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Wt(t,o);for(let r=1;r<s.length;r++)i=Vc(i,s[r].trim());return Number(i)||0}function Wt(e,t){let n=t.split("."),s=e;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function Rh(e,t){let n=t.match(/^(.+?)\s*([*/])\s*([\d.]+)$/);if(n){let s=Wt(e,n[1].trim());if(s==null||s==="")return"";let o=Number(s);if(Number.isNaN(o))return"";let i=Number(n[3]);return n[2]==="/"?i===0?"":o/i:o*i}return Wt(e,t)}function Dn(e,t){let n=e.trim();if(n.startsWith("not "))return!Dn(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Dn(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Dn(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=Wt(t,s[1].trim()),r=s[2],a=s[3].trim();switch(typeof a=="string"&&a.startsWith('"')&&a.endsWith('"')||typeof a=="string"&&a.startsWith("'")&&a.endsWith("'")?a=a.slice(1,-1):isNaN(Number(a))?a=Wt(t,a):a=Number(a),r){case"==":return i==a;case"!=":return i!=a;case">":return Number(i)>Number(a);case"<":return Number(i)<Number(a);case">=":return Number(i)>=Number(a);case"<=":return Number(i)<=Number(a)}}let o=Wt(t,n);return Kc(o)}function Kc(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function Vc(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 Kc(e)?e:i??"";case"length":return Array.isArray(e)?e.length:n.length;case"join":return Array.isArray(e)?e.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));case"convert_rgb":{let r=fr(e);return r?Fh(r):""}default:return e}}function fr(e){if(e==null)return null;if(typeof e=="string"){let t=e.match(/#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})(?![0-9a-fA-F])/);return t?Oh(t[1]):null}if(typeof e=="object"){let t=e;if(typeof t.color=="string")return fr(t.color);if(typeof t.hex=="string")return fr(t.hex)}return null}function Oh(e){let t=e.toLowerCase();return t.length===3?t.split("").map(n=>n+n).join(""):t}function Fh(e){let t=parseInt(e.slice(0,2),16),n=parseInt(e.slice(2,4),16),s=parseInt(e.slice(4,6),16);return`${t}, ${n}, ${s}`}var wh,Ch,kh,Jc,Bc,Th,Ah,_h,$h,Eh,gr,yr=N(()=>{"use strict";y();wh=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Ch=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,kh=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,Jc=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Bc=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Th=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Ah=/\{%[-\s]*module\b.*?%\}/gs,_h=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,$h=/\{#.*?#\}/gs,Eh=/\{\{[-\s]*content\.\w+.*?\}\}/gs,gr=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Ho={};Ge(Ho,{buildModulePreviewHtml:()=>vr,buildPreviewHtml:()=>Sr});function Dh(e){if(Ln()==="email")return!0;for(let t of e)try{let n=JSON.parse(t.metaJson);if(Array.isArray(n.host_template_types)&&n.host_template_types.includes("EMAIL"))return!0}catch{}return!1}function jh(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 br(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 Sr(){let e=C();if(!e)return zc();let t=ve(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return zc();if(Dh(t))return Lh(t,n);let s=[],o=[],i=[],r=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d,u=[];try{let f=JSON.parse(c.fieldsJson);u=Array.isArray(f)?f:[],d={module:rn(u)}}catch{d={module:{}}}let m=br(c.moduleHtml,u),g=jn(m,d),h=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${h}" data-module="${c.moduleName}">${g}</div>`),r.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let a=jh(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 Ki({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function cc(){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 hr({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function zc(){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 Yi(e){let t=k();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:es(o)}}catch{s={module:{}}}let i=Vi(n.moduleHtml,o),r=xo(i,s);return Ki({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 Rf(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:es(a)}}catch{r={module:{}}}let l=Vi(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}">
438
+ </html>`}function vr(e){let t=C();if(!t)return"";let n;for(let a of t.templates)if(n=a.modules.find(l=>l.moduleName===e),n)break;if(n||(n=t.modules.find(a=>a.moduleName===e)),!n)return"";let s,o=[];try{let a=JSON.parse(n.fieldsJson);o=Array.isArray(a)?a:[],s={module:rn(o)}}catch{s={module:{}}}let i=br(n.moduleHtml,o),r=jn(i,s);return hr({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 Lh(e,t){let n=[],s=new Set;for(let i of e){let r,a=[];try{let u=JSON.parse(i.fieldsJson);a=Array.isArray(u)?u:[],r={module:rn(a)}}catch{r={module:{}}}let l=br(i.moduleHtml,a),c=jn(l,r),d=i.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module" id="${d}" data-module="${i.moduleName}">${c}</div>`),s.add(i.moduleName)}for(let i of t)if(!s.has(i)){let r=i.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module vibespot-module--pending" id="${r}" data-module="${i}">
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,8 +485,8 @@ document.addEventListener('click', function(e) {
485
485
  });
486
486
  </script>
487
487
  </body>
488
- </html>`}var ts=R(()=>{"use strict";h();lc();we();ns()});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 ss(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 qi(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 dc(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=>qi(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=>qi(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=ss(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=>qi(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 Co=R(()=>{"use strict";h();we();ce()});function bn(){let e=k();return e?{pageType:Ce()?.pageType,brandAssets:e.brandAssets}:{}}function uc(e,t,n=!1,s,o){let r=[{type:"text",text:Of(t,n)}];if(n){let l=`## HubSpot CMS Rules
489
- ${je()}
488
+ </html>`}var bs=N(()=>{"use strict";y();yr();Ce();Ss()});function ct(e){try{return JSON.parse(e)}catch{}let t=e,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(t)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let r=parseInt(i[1],10);if(r<=n)return null;n=r;let a=Math.max(0,r-5),c=t.slice(a,r+1).lastIndexOf('"');if(c===-1)return null;let d=a+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function vs(e){let t=e.indexOf('"modules"');if(t===-1)return null;let n=e.indexOf("[",t);if(n===-1)return null;let s=-1,o=0,i=!1,r=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(r){r=!1;continue}if(u==="\\"){r=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=e.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ct(c)}function xr(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 Yc(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{E.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ct(s[1]);if(!i||typeof i!="object")throw E.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let r=i;r.modules&&Array.isArray(r.modules)&&(He({modules:r.modules.map(a=>xr(a)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(i){E.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let r=ct(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(He({modules:a.modules.map(l=>xr(l)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(r){E.warn("parse","Failed to parse JSON module block",{error:r instanceof Error?r.message:String(r)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){E.info("parse","Detected truncated response (odd fence count), attempting salvage");let r=e.lastIndexOf("```"),a=e.slice(r+3);a=a.replace(/^[\w-]*\s*\n?/,"");let l=vs(a);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(E.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),He({modules:c.modules.map(d=>xr(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){E.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),r=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(i||r){let a=i?"Module changes could not be applied \u2014 the AI response contained invalid JSON. Try sending your request again.":"The AI described modules but did not include the required structured data. Try sending your request again.";E.warn("parse",a),t&&t(a)}}}var Uo=N(()=>{"use strict";y();Ce();le()});function Jn(){let e=C();return e?{pageType:ke()?.pageType,brandAssets:e.brandAssets}:{}}function qc(e,t,n=!1,s,o){let r=[{type:"text",text:Bh(t,n)}];if(n){let l=`## HubSpot CMS Rules
489
+ ${Je()}
490
490
 
491
491
  ## Conversion Guide Reference
492
492
  ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
@@ -512,22 +512,22 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
512
512
  This makes elements appear after 3 seconds if JS never adds the .visible class. Once JS runs normally and adds .visible, the animation is cancelled.
513
513
 
514
514
  ## Design Guide
515
- ${Un()}
515
+ ${as()}
516
516
 
517
517
  ## Content & Copywriting Guide
518
- ${ki()}
518
+ ${Gi()}
519
519
 
520
520
  ## HubSpot CMS Rules
521
- ${je()}
521
+ ${Je()}
522
522
 
523
523
  ## Conversion Guide Reference
524
- ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=Nf(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 Nf(e,t){let n=[];if(e){let s=Ai(e);s&&n.push(`## Page Type Context
524
+ ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=Jh(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 Jh(e,t){let n=[];if(e){let s=Ki(e);s&&n.push(`## Page Type Context
525
525
  ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
526
526
  ${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
527
- ${t.brandvoice}`),t?.humanify!==!1){let s=Ti();s&&n.push(`## Anti-AI Copy Rules (Humanify)
527
+ ${t.brandvoice}`),t?.humanify!==!1){let s=Wi();s&&n.push(`## Anti-AI Copy Rules (Humanify)
528
528
  ${s}`)}return n.join(`
529
529
 
530
- `)}function Of(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
530
+ `)}function Bh(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
531
531
 
532
532
  ## Your Role
533
533
  You generate native HubSpot CMS modules directly from user descriptions. Every module you create is immediately compatible with HubSpot's drag-and-drop page editor.
@@ -606,7 +606,7 @@ The current template's modules are listed in page order in the user message. Thi
606
606
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
607
607
  - **Remove**: When the user asks to remove a section, omit it from the output.
608
608
  - **Preserve**: Always include ALL modules you want to keep (modified + unchanged) in your output. Modules omitted from the output will be removed from the page.
609
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function os(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
609
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function xs(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
610
610
 
611
611
  ## Your Role
612
612
  You generate native HubSpot CMS modules directly from user descriptions. Every module you create is immediately compatible with HubSpot's drag-and-drop page editor.
@@ -685,7 +685,7 @@ The current template's modules are listed in page order in the user message. Thi
685
685
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
686
686
  - **Remove**: When the user asks to remove a section, omit it from the output.
687
687
  - **Preserve**: Always include ALL modules you want to keep (modified + unchanged) in your output. Modules omitted from the output will be removed from the page.
688
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,r=s?Ai(s):"",a=r?`
688
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,r=s?Ki(s):"",a=r?`
689
689
 
690
690
  ## Page Type Context
691
691
  ${r}`:"",l="";if(o?.styleguide&&(l+=`
@@ -694,13 +694,13 @@ ${r}`:"",l="";if(o?.styleguide&&(l+=`
694
694
  ${o.styleguide}`),o?.brandvoice&&(l+=`
695
695
 
696
696
  ## Brand Voice
697
- ${o.brandvoice}`),o?.humanify!==!1){let d=Ti();d&&(l+=`
697
+ ${o.brandvoice}`),o?.humanify!==!1){let d=Wi();d&&(l+=`
698
698
 
699
699
  ## Anti-AI Copy Rules (Humanify)
700
700
  ${d}`)}let c="\n\n## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory.";return n?i+a+l+`
701
701
 
702
702
  ## HubSpot CMS Rules
703
- ${je()}
703
+ ${Je()}
704
704
 
705
705
  ## Conversion Guide Reference
706
706
  ${e}`+c:i+a+l+`
@@ -728,16 +728,16 @@ 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
+ ${as()}
732
732
 
733
733
  ## Content & Copywriting Guide
734
- ${ki()}
734
+ ${Gi()}
735
735
 
736
736
  ## HubSpot CMS Rules
737
- ${je()}
737
+ ${Je()}
738
738
 
739
739
  ## Conversion Guide Reference
740
- ${e}`+c}function is(){let e=k(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
740
+ ${e}`+c}function ws(){let e=C(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
741
741
 
742
742
  ## Page Narrative (module sequence)
743
743
  `),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
@@ -774,13 +774,13 @@ ${e.sharedCss}
774
774
  \`\`\`js
775
775
  ${e.sharedJs}
776
776
  \`\`\`
777
- `)}let o=$t(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
777
+ `)}let o=Nt(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
778
778
 
779
779
  ## Available modules in this theme (reusable)
780
780
  `);for(let a of r)t.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
781
781
  `);t.push(`
782
782
  The user can ask to reuse any of these modules by name.
783
- `)}return t.join("")}function Xi(e,t){let n=k(),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=is(),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 wr(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=ws(),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"):
@@ -794,72 +794,55 @@ ${i}`),r&&(a+=r),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON
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?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 mc=R(()=>{"use strict";h();Ge();we()});import{spawn as pc}from"child_process";async function gc(){return Zi||(Zi=(await import("@anthropic-ai/sdk")).default),Zi}function fc(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.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 Xc=N(()=>{"use strict";y();Ke();Ce()});import{spawn as Zc}from"child_process";async function Qc(){return Cr||(Cr=(await import("@anthropic-ai/sdk")).default),Cr}function ed(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
798
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 t.join("")}async function hc(e,t,n,s,o,i,r){for(let a=0;;a++)try{let l="",c=0,d=i||(()=>{});d(Ne[0]);let u=setInterval(()=>{c++,d(Ne[Math.min(c,Ne.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 y=g.delta.text;l+=y,o(y)}}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>=Qi.length)throw l;let m=Qi[a];M.warn("ai-engine",`Rate limited (429), attempt ${a+1}/${Qi.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 yc(e,t,n){let s=fe(),i=k().modules.length>0,r=Xi(e,n),a=bn(),l=uc(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function er(e,t,n,s,o,i,r,a,l){let c=await gc(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:m}=yc(e,n,a);M.info("anthropic","API call",{model:s,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:u.length}),await hc(d,m,u,s,o,i,r)}async function bc(e,t,n,s,o,i,r){let a=await gi();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await gc(),c=new l({authToken:a,defaultHeaders:En}),{messages:d,systemBlocks:u}=yc(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 hc(c,m,d,n,s,o,i)}async function tr(e,t,n,s,o,i,r,a,l){let c=fe(),d=k().modules.length>0,u=Xi(e,a),m=bn(),g=u.map(F=>typeof F.content=="string"?F:{role:F.role,content:F.content.map(K=>K.type==="text"?{type:"text",text:K.text}:{type:"image_url",image_url:{url:`data:${K.source.media_type};base64,${K.source.data}`}})}),f=await fetch(l||"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:os(c,n,d,m.pageType,m.brandAssets)},...g]})});if(!f.ok){let F=await f.text();throw new Error(`API error (${f.status}): ${F}`)}let b=0,S=i||(()=>{});S(Ne[0]);let x=setInterval(()=>{b++,S(Ne[Math.min(b,Ne.length-1)])},6e3),v="",I=f.body.getReader(),L=new TextDecoder,G="";try{for(;;){let{done:F,value:K}=await I.read();if(F)break;G+=L.decode(K,{stream:!0});let q=G.split(`
803
- `);G=q.pop()||"";for(let N of q){if(!N.startsWith("data: "))continue;let C=N.slice(6).trim();if(C==="[DONE]")break;try{let T=JSON.parse(C).choices?.[0]?.delta?.content;T&&(v+=T,o(T))}catch{}}}}finally{clearInterval(x)}r&&r(v)}async function nr(e,t,n,s,o,i,r,a,l){let c=fe(),d=k(),u=d.modules.length>0,m=is(),g=bn(),y=[];for(let C of d.messages.slice(-20))y.push({role:C.role==="assistant"?"model":"user",parts:[{text:C.content}]});let f=m?`${e}
802
+ ${n.extractedText}`);return t.join("")}async function td(e,t,n,s,o,i,r,a="anthropic-api"){for(let l=0;;l++){let c=new Date;try{let d="",u=0,m=i||(()=>{});m(je[0]);let g=setInterval(()=>{u++,m(je[Math.min(u,je.length-1)])},6e3),h=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});try{for await(let b of h)if(b.type==="content_block_delta"&&b.delta.type==="text_delta"){let S=b.delta.text;d+=S,o(S)}}finally{clearInterval(g)}let f;try{f=et((await h.finalMessage()).usage)}catch{}St({engine:a,model:s,name:"vibe-chat",input:{system:t,messages:n},output:d,usage:f,startTime:c,endTime:new Date}),r&&r(d);return}catch(d){let u=d.status,m=d.error?.type;if(!(u===429||m==="rate_limit_error"||d instanceof Error&&d.message.includes("429"))||l>=kr.length)throw d;let h=kr[l];E.warn("ai-engine",`Rate limited (429), attempt ${l+1}/${kr.length} \u2014 waiting ${h}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${h}s...`),await new Promise(f=>setTimeout(f,h*1e3)),i&&i("Retrying...")}}}function nd(e,t,n){let s=ye(),i=C().modules.length>0,r=wr(e,n),a=Jn(),l=qc(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function Tr(e,t,n,s,o,i,r,a,l){let c=await Qc(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:m}=nd(e,n,a);E.info("anthropic","API call",{model:s,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:u.length}),await td(d,m,u,s,o,i,r)}async function sd(e,t,n,s,o,i,r){let a=await Ri();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await Qc(),c=new l({authToken:a,defaultHeaders:qn}),{messages:d,systemBlocks:u}=nd(e,t,r),m=[{type:"text",text:Sn},...u];E.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await td(c,m,d,n,s,o,i,"claude-oauth")}async function Ar(e,t,n,s,o,i,r,a,l){let c=ye(),d=C().modules.length>0,u=wr(e,a),m=Jn(),g=u.map(k=>typeof k.content=="string"?k:{role:k.role,content:k.content.map(T=>T.type==="text"?{type:"text",text:T.text}:{type:"image_url",image_url:{url:`data:${T.source.media_type};base64,${T.source.data}`}})}),h=xs(c,n,d,m.pageType,m.brandAssets),f=l||"https://api.openai.com/v1/chat/completions",b=!/\/mistral(\/|$|\?)/.test(f),S=new Date,v=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,...b?{stream_options:{include_usage:!0}}:{},messages:[{role:"system",content:h},...g]})});if(!v.ok){let k=await v.text();throw new Error(`API error (${v.status}): ${k}`)}let w=0,M=i||(()=>{});M(je[0]);let L=setInterval(()=>{w++,M(je[Math.min(w,je.length-1)])},6e3),H="",B,K=v.body.getReader(),X=new TextDecoder,O="";try{for(;;){let{done:k,value:T}=await K.read();if(k)break;O+=X.decode(T,{stream:!0});let $=O.split(`
803
+ `);O=$.pop()||"";for(let F of $){if(!F.startsWith("data: "))continue;let re=F.slice(6).trim();if(re==="[DONE]")break;try{let _e=JSON.parse(re),z=_e.choices?.[0]?.delta?.content;z&&(H+=z,o(z)),_e.usage&&(B=_e.usage)}catch{}}}}finally{clearInterval(L)}St({engine:"openai-api",model:s,name:"vibe-chat",input:{system:h,messages:g},output:H,usage:_n(B),startTime:S,endTime:new Date}),r&&r(H)}async function _r(e,t,n,s,o,i,r,a,l){let c=ye(),d=C(),u=d.modules.length>0,m=ws(),g=Jn(),h=[];for(let F of d.messages.slice(-20))h.push({role:F.role==="assistant"?"model":"user",parts:[{text:F.content}]});let f=m?`${e}
804
804
 
805
805
  ---
806
- ${m}`:e;if(r?.length)for(let C of r)C.type==="document"&&C.extractedText&&(f+=`
806
+ ${m}`:e;if(r?.length)for(let F of r)F.type==="document"&&F.extractedText&&(f+=`
807
807
 
808
808
  ---
809
- [Attached document: ${C.originalName}]
810
- ${C.extractedText}`),C.type==="image"&&C.usage==="asset"&&C.assetPath&&(f+=`
809
+ [Attached document: ${F.originalName}]
810
+ ${F.extractedText}`),F.type==="image"&&F.usage==="asset"&&F.assetPath&&(f+=`
811
811
 
812
- [Uploaded image: ${C.originalName} \u2192 available as get_asset_url("${C.assetPath}")]`);let b=[];if(r?.length)for(let C of r)C.type==="image"&&C.base64&&b.push({inlineData:{mimeType:C.mimeType,data:C.base64}});b.push({text:f}),y.push({role:"user",parts:b});let x=a||`https://generativelanguage.googleapis.com/v1beta/models/${l||"gemini-2.5-flash"}:streamGenerateContent?alt=sse&key=${t}`,v=await fetch(x,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:os(c,n,u,g.pageType,g.brandAssets)}]},contents:y,generationConfig:{maxOutputTokens:48e3}})});if(!v.ok){let C=await v.text();throw new Error(`Gemini API error (${v.status}): ${C}`)}let I=0,L=o||(()=>{});L(Ne[0]);let G=setInterval(()=>{I++,L(Ne[Math.min(I,Ne.length-1)])},6e3),F="",K=v.body.getReader(),q=new TextDecoder,N="";try{for(;;){let{done:C,value:P}=await K.read();if(C)break;N+=q.decode(P,{stream:!0});let T=N.split(`
813
- `);N=T.pop()||"";for(let W of T){if(!W.startsWith("data: "))continue;let ue=W.slice(6).trim();try{let Q=JSON.parse(ue).candidates?.[0]?.content?.parts?.[0]?.text;Q&&(F+=Q,s(Q))}catch{}}}}finally{clearInterval(G)}i&&i(F)}function sr(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=pc("claude",e,{stdio:["pipe","pipe","pipe"],env:r}),l="",c="",d="",u=!1,m=null,g=v=>{u||(u=!0,v())},y=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 L=I.text;l+=L,n.onChunk&&n.onChunk(L)}else if(I.type==="tool_use"){let L=I;L.name&&n.onToolUse&&n.onToolUse(L.name,L.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 L=d.slice(0,I).trim();if(d=d.slice(I+1),!!L)try{y(JSON.parse(L))}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{y(JSON.parse(d.trim()))}catch{}d=""}g(()=>{v!==0||m&&m.is_error?i(new Error(`claude exited with code ${v}.
812
+ [Uploaded image: ${F.originalName} \u2192 available as get_asset_url("${F.assetPath}")]`);let b=[];if(r?.length)for(let F of r)F.type==="image"&&F.base64&&b.push({inlineData:{mimeType:F.mimeType,data:F.base64}});b.push({text:f}),h.push({role:"user",parts:b});let S=l||"gemini-2.5-flash",v=a||`https://generativelanguage.googleapis.com/v1beta/models/${S}:streamGenerateContent?alt=sse&key=${t}`,w=xs(c,n,u,g.pageType,g.brandAssets),M=new Date,L=await fetch(v,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:w}]},contents:h,generationConfig:{maxOutputTokens:48e3}})});if(!L.ok){let F=await L.text();throw new Error(`Gemini API error (${L.status}): ${F}`)}let H=0,B=o||(()=>{});B(je[0]);let K=setInterval(()=>{H++,B(je[Math.min(H,je.length-1)])},6e3),X="",O,k=L.body.getReader(),T=new TextDecoder,$="";try{for(;;){let{done:F,value:re}=await k.read();if(F)break;$+=T.decode(re,{stream:!0});let _e=$.split(`
813
+ `);$=_e.pop()||"";for(let z of _e){if(!z.startsWith("data: "))continue;let ue=z.slice(6).trim();try{let ne=JSON.parse(ue),$e=ne.candidates?.[0]?.content?.parts?.[0]?.text;$e&&(X+=$e,s($e)),ne.usageMetadata&&(O=ne.usageMetadata)}catch{}}}}finally{clearInterval(K)}St({engine:"gemini-api",model:S,name:"vibe-chat",input:{system:w,contents:h},output:X,usage:$n(O),startTime:M,endTime:new Date}),i&&i(X)}function $r(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=Zc("claude",e,{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 M of w.message.content)if(M.type==="text"&&typeof M.text=="string"){let L=M.text;l+=L,n.onChunk&&n.onChunk(L)}else if(M.type==="tool_use"){let L=M;L.name&&n.onToolUse&&n.onToolUse(L.name,L.input)}}w.type==="result"&&(m=w,!l&&typeof w.result=="string"&&(l=w.result,n.onChunk&&n.onChunk(w.result))),n.onEvent&&n.onEvent(w)}catch{}};a.stdout.on("data",w=>{d+=w.toString();let M;for(;(M=d.indexOf(`
814
+ `))>=0;){let L=d.slice(0,M).trim();if(d=d.slice(M+1),!!L)try{h(JSON.parse(L))}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}.
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(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.
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),v=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 or(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=pc(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}.
818
+ `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(v))})}function Er(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=Zc(e,t,{stdio:["pipe","pipe","pipe"],env:a}),c="",d="",u=!1,m=S=>{u||(u=!0,S())};l.stdout.on("data",S=>{let v=S.toString();c+=v,s&&s(v)}),l.stderr.on("data",S=>{d+=S.toString()}),l.on("error",S=>m(()=>r(new Error(`${e} failed to start: ${S.message}`)))),l.on("close",S=>{m(()=>{S!==0?r(new Error(`${e} exited with code ${S}.
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 y=o||6e5,f=Math.round(y/6e4),b=setTimeout(()=>{l.kill(),m(()=>r(new Error(`${e} 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)}`)))},y);l.on("close",()=>clearTimeout(b))})}async function Sc(e,t,n,s,o,i){let r=fe(),a=O(),l=k().modules.length>0,c=bn(),d=os(r,t,l,c.pageType,c.brandAssets);d+=`
822
+ `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function od(e,t,n,s,o,i){let r=ye(),a=R(),l=C().modules.length>0,c=Jn(),d=xs(r,t,l,c.pageType,c.brandAssets);d+=`
823
823
 
824
824
  ## User Request
825
- `+e,d+=is(),d+=fc(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(Ne[0]);let y=setInterval(()=>{m++;let f=Ne[Math.min(m,Ne.length-1)];g(f)},6e3);try{let f=await sr(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(Ff(b,S))}});o&&o(f)}finally{clearInterval(y)}}function Ff(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 ir(e,t,n,s,o,i,r){let a=fe(),l=k().modules.length>0,c=bn(),d=os(a,n,l,c.pageType,c.brandAssets);d+=`
825
+ `+e,d+=ws(),d+=ed(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(je[0]);let h=setInterval(()=>{m++;let f=je[Math.min(m,je.length-1)];g(f)},6e3);try{let f=await $r(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(Hh(b,S))}});o&&o(f)}finally{clearInterval(h)}}function Hh(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 Mr(e,t,n,s,o,i,r){let a=ye(),l=C().modules.length>0,c=Jn(),d=xs(a,n,l,c.pageType,c.brandAssets);d+=`
826
826
 
827
827
  ## User Request
828
- `+t,d+=is(),d+=fc(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,y=o||(()=>{});y(Ne[0]);let f=setInterval(()=>{g++;let b=Ne[Math.min(g,Ne.length-1)];y(b)},6e3);try{let b=await or(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Zi,Ne,Qi,rr=R(()=>{"use strict";h();Ge();ee();xt();we();mc();ce();Zi=null;Ne=["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..."],Qi=[10,20,40,60,120]});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function U(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){U(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var ze=R(()=>{"use strict";h()});import{createWriteStream as jf,mkdirSync as vc,existsSync as ar,readFileSync as lr}from"fs";import{join as zt,extname as Df}from"path";import{randomUUID as Lf}from"crypto";import Jf from"busboy";function Uf(e,t){if(wc.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return Gf[n]??t}function Wf(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Kf(e,t){if(!ar(zt(e,t)))return t;let n=Df(t),s=t.slice(0,-n.length||void 0),o=1;for(;ar(zt(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function Vf(e){let t=(await import("pdf-parse")).default,n=lr(e);return(await t(n)).text}async function zf(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function Yf(e){return lr(e,"utf-8")}function Cc(e,t){let n=k();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=Jf({headers:e.headers,limits:{fileSize:Bf,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let y=Uf(m,g);if(!wc.has(y)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=xc.has(y),b=Wf(m),S=Lf(),x,v;f?(x=zt(n.themePath,"assets"),vc(x,{recursive:!0}),v=Kf(x,b)):(x=zt(n.themePath,".vibespot","uploads"),vc(x,{recursive:!0}),v=`${S}-${b}`);let I=zt(x,v),L=jf(I),G=0,F=!1;d.on("data",K=>{G+=K.length}),d.on("limit",()=>{F=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(L),a.push(new Promise(K=>{L.on("finish",()=>{if(!F){let q={id:S,filename:v,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:y,size:G,addedAt:new Date().toISOString()};o.push(q),Tl(q)}K()}),L.on("error",()=>{i.push(`Failed to write: ${m}`),K()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=zt(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await Vf(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await zf(d):c.extractedText=Yf(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 ko(e){let t=k();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=zt(t.themePath,"assets",s.filename);ar(i)&&(o.base64=lr(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 Bf,xc,Hf,wc,Gf,cr=R(()=>{"use strict";h();ze();we();ce();Bf=10*1024*1024,xc=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Hf=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),wc=new Set([...xc,...Hf]),Gf={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var Mc={};Be(Mc,{LANGDOCK_BASE_URLS:()=>rs,callAgent:()=>_e,callAgentAPI:()=>Ec,isAgenticCapable:()=>ls,isCLIEngine:()=>vn,resolveThinkingBudget:()=>Sn});async function To(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>=dr.length)throw s;let a=dr[n];M.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${dr.length} \u2014 waiting ${a}s`),t&&t(`Rate limited \u2014 retrying in ${a}s...`),await new Promise(l=>setTimeout(l,a*1e3)),t&&t("Retrying...")}}function as(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;for(let n of["fieldsJson","metaJson"])t[n]&&typeof t[n]=="object"&&(t[n]=JSON.stringify(t[n]))}return e}async function $c(){return ur||(ur=(await import("@anthropic-ai/sdk")).default),ur}async function kc(e,t,n,s,o,i){let r=await $c(),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 To(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:as(g.input)};return{type:"text",text:u.content.filter(g=>g.type==="text").map(g=>g.text).join("")}},n.onStatus)}return To(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 qf(e,t,n){let s=await $c(),o=new s({authToken:e,defaultHeaders:En}),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 To(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:as(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return To(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 mr(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"?mr(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=mr(t.items)),t}async function Tc(e,t,n,s){let o=[{role:"system",content:n.systemPrompt},...n.messages.map(d=>({role:d.role,content:typeof d.content=="string"?d.content:d.content.map(u=>({type:"text",text:u.text}))}))],i={model:t,max_tokens:n.maxTokens||16e3,messages:o};n.structuredOutput&&(i.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:mr(n.structuredOutput.schema)}});let a=await fetch(s||"https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(i)});if(!a.ok){let d=await a.text(),u=a.status;if(u===429){let m=new Error(`OpenAI rate limit: ${d}`);throw m.status=429,m}throw new Error(`OpenAI API error (${u}): ${d}`)}let c=(await a.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:as(JSON.parse(c))}}catch{return M.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}async function Ac(e,t,n,s){let o=t||"gemini-2.5-flash",i=n.messages.map(u=>({role:u.role==="assistant"?"model":"user",parts:typeof u.content=="string"?[{text:u.content}]:u.content.map(m=>({text:m.text}))})),r={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:i,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`,l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok){let u=await l.text(),m=l.status;if(m===429){let g=new Error(`Gemini rate limit: ${u}`);throw g.status=429,g}throw new Error(`Gemini API error (${m}): ${u}`)}let d=(await l.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:as(JSON.parse(d))}}catch{return M.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:d}}return{type:"text",text:d}}function Xf(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 Zf(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(`
828
+ `+t,d+=ws(),d+=ed(r),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;e==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,h=o||(()=>{});h(je[0]);let f=setInterval(()=>{g++;let b=je[Math.min(g,je.length-1)];h(b)},6e3);try{let b=await Er(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Cr,je,kr,Ir=N(()=>{"use strict";y();Ke();ee();_t();Ce();Xc();le();Be();tn();Cr=null;je=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],kr=[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 qe(e,t,n){W(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Xe=N(()=>{"use strict";y()});import{createWriteStream as Uh,mkdirSync as id,existsSync as Pr,readFileSync as Nr}from"fs";import{join as an,extname as Gh}from"path";import{randomUUID as Wh}from"crypto";import Kh from"busboy";function qh(e,t){if(ad.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return Yh[n]??t}function Xh(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Zh(e,t){if(!Pr(an(e,t)))return t;let n=Gh(t),s=t.slice(0,-n.length||void 0),o=1;for(;Pr(an(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function Qh(e){let t=(await import("pdf-parse")).default,n=Nr(e);return(await t(n)).text}async function ey(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function ty(e){return Nr(e,"utf-8")}function ld(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=Kh({headers:e.headers,limits:{fileSize:Vh,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=qh(m,g);if(!ad.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=rd.has(h),b=Xh(m),S=Wh(),v,w;f?(v=an(n.themePath,"assets"),id(v,{recursive:!0}),w=Zh(v,b)):(v=an(n.themePath,".vibespot","uploads"),id(v,{recursive:!0}),w=`${S}-${b}`);let M=an(v,w),L=Uh(M),H=0,B=!1;d.on("data",K=>{H+=K.length}),d.on("limit",()=>{B=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(L),a.push(new Promise(K=>{L.on("finish",()=>{if(!B){let X={id:S,filename:w,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:H,addedAt:new Date().toISOString()};o.push(X),dc(X)}K()}),L.on("error",()=>{i.push(`Failed to write: ${m}`),K()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=an(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await Qh(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await ey(d):c.extractedText=ty(d),E.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){E.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(r===0){p(t,400,{error:"No files uploaded"});return}p(t,200,{files:o.map(c=>({id:c.id,filename:c.filename,originalName:c.originalName,type:c.type,usage:c.usage,size:c.size})),errors:i.length>0?i:void 0})}),l.on("error",c=>{E.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Go(e){let t=C();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=an(t.themePath,"assets",s.filename);Pr(i)&&(o.base64=Nr(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 Vh,rd,zh,ad,Yh,Rr=N(()=>{"use strict";y();Xe();Ce();le();Vh=10*1024*1024,rd=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),zh=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),ad=new Set([...rd,...zh]),Yh={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var fd={};Ge(fd,{LANGDOCK_BASE_URLS:()=>Cs,callAgent:()=>Pe,callAgentAPI:()=>gd,isAgenticCapable:()=>Ts,isCLIEngine:()=>Hn,resolveThinkingBudget:()=>Bn});async function Wo(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>=Or.length)throw s;let a=Or[n];E.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${Or.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 ks(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 md(){return Fr||(Fr=(await import("@anthropic-ai/sdk")).default),Fr}async function cd(e,t,n,s,o,i){let r=await md(),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 Wo(async()=>{let u=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,tools:[d],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),m=et(u.usage);for(let h of u.content)if(h.type==="tool_use")return{type:"structured",data:ks(h.input),usage:m};return{type:"text",text:u.content.filter(h=>h.type==="text").map(h=>h.text).join(""),usage:m}},n.onStatus)}return Wo(async()=>{let d="",u=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let g of u)g.type==="content_block_delta"&&g.delta.type==="text_delta"&&(d+=g.delta.text,n.onChunk&&n.onChunk(g.delta.text));let m;try{m=et((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:m}},n.onStatus)}async function ny(e,t,n){let s=await md(),o=new s({authToken:e,defaultHeaders:qn}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:Sn},...n.systemBlocks]:r=[{type:"text",text:Sn},{type:"text",text:n.systemPrompt}],n.structuredOutput){let a={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Wo(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),c=et(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:ks(u.input),usage:c};return{type:"text",text:l.content.filter(u=>u.type==="text").map(u=>u.text).join(""),usage:c}},n.onStatus)}return Wo(async()=>{let a="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let d of l)d.type==="content_block_delta"&&d.delta.type==="text_delta"&&(a+=d.delta.text,n.onChunk&&n.onChunk(d.delta.text));let c;try{c=et((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus)}function Dr(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"?Dr(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Dr(t.items)),t}async function dd(e,t,n,s){let o=[{role:"system",content:n.systemPrompt},...n.messages.map(u=>({role:u.role,content:typeof u.content=="string"?u.content:u.content.map(m=>({type:"text",text:m.text}))}))],i={model:t,max_completion_tokens:n.maxTokens||16e3,messages:o};n.structuredOutput&&(i.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!1,schema:Dr(n.structuredOutput.schema)}});let a=await fetch(s||"https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(i)});if(!a.ok){let u=await a.text(),m=a.status;if(m===429){let g=new Error(`OpenAI rate limit: ${u}`);throw g.status=429,g}throw new Error(`OpenAI API error (${m}): ${u}`)}let l=await a.json(),c=l.choices?.[0]?.message?.content||"",d=_n(l.usage);if(n.structuredOutput)try{return{type:"structured",data:ks(JSON.parse(c)),usage:d}}catch{return E.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:c,usage:d}}return{type:"text",text:c,usage:d}}async function ud(e,t,n,s){let o=t||"gemini-2.5-flash",i=n.messages.map(m=>({role:m.role==="assistant"?"model":"user",parts:typeof m.content=="string"?[{text:m.content}]:m.content.map(g=>({text:g.text}))})),r={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:i,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`,l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok){let m=await l.text(),g=l.status;if(g===429){let h=new Error(`Gemini rate limit: ${m}`);throw h.status=429,h}throw new Error(`Gemini API error (${g}): ${m}`)}let c=await l.json(),d=c.candidates?.[0]?.content?.parts?.[0]?.text||"",u=$n(c.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:ks(JSON.parse(d)),usage:u}}catch{return E.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:d,usage:u}}return{type:"text",text:d,usage:u}}function sy(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 oy(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
829
  `);t.push(`
830
830
 
831
831
  ## ${s}
832
- ${o}`)}if(e.structuredOutput){let n=_c(e.structuredOutput.schema);t.push(`
832
+ ${o}`)}if(e.structuredOutput){let n=pd(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 t.join("")}function _c(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}": ${_c(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
839
- `)}function Qf(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=ss(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=ss(a);if(c&&typeof c=="object")return c}let r=ss(t);return r&&typeof r=="object"?r:null}async function eh(e,t,n){let{bin:s,args:o}=Xf(e,t,n),i=Zf(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await sr(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=th(c,d);n.onStatus(u)}})}else r=await or(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=Qf(r);return a?{type:"structured",data:as(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 th(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 Ec(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 kc(t,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(xt(),fi)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return qf(i,n,s)}case"openai-api":return Tc(t,n,s);case"gemini-api":return Ac(t,n,s);case"langdock-api":{let o=O(),i=o.langdockProvider||"anthropic",r=o.langdockBaseUrl;switch(i){case"openai":case"mistral":{let a=r||rs[i];return Tc(t,n,s,`${a}/v1/chat/completions`)}case"google":{let a=r||rs.google;return Ac(t,n,s,`${a}/v1beta/models/${n}:generateContent`)}default:{let a=r||rs.anthropic;return kc(t,n,s,void 0,void 0,a)}}}default:throw new Error(`Unsupported API engine: ${e}`)}}async function _e(e,t,n,s){return nh.has(e)?Ec(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}),eh(e,n,s))}function Sn(e){if(e==="langdock-api"){if((O().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")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 ls(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 vn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var rs,q0,dr,ur,nh,st=R(()=>{"use strict";h();rr();Co();ee();xt();ce();rs={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},q0=rs.anthropic,dr=[10,20,40,60,120];ur=null;nh=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});function Ic(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
- `)}`:"No modules yet (new page).",r=n.length>0?`
842
-
843
- Module library (reusable from other templates):
844
- ${n.map(c=>`- ${c.name} (used in: ${c.usedIn.join(", ")})`).join(`
845
- `)}`:"",a=s?`
846
-
847
- ## Product Context
848
- ${s}`:"",l=o?.pages&&o.pages.length>1?`
849
-
850
- ## Multi-Page Site Context
851
- This is a multi-page site. Currently editing: **${o.activePageLabel||"unknown"}**
852
- All pages:
853
- ${o.pages.map(c=>`- ${c.label} (${c.id}, ${c.moduleCount} modules)`).join(`
854
- `)}
838
+ ${n}`)}return t.join("")}function pd(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}": ${pd(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
839
+ `)}function iy(e){let t=e.trim(),n=ct(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let a=s[1].trim(),l=ct(a);if(l&&typeof l=="object")return l;let c=vs(a);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let a=t.slice(o,i+1),l=ct(a);if(l&&typeof l=="object")return l;let c=vs(a);if(c&&typeof c=="object")return c}let r=vs(t);return r&&typeof r=="object"?r:null}async function ry(e,t,n){let{bin:s,args:o}=sy(e,t,n),i=oy(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await $r(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=ay(c,d);n.onStatus(u)}})}else r=await Er(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=iy(r);return a?{type:"structured",data:ks(a)}:(E.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function ay(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 gd(e,t,n,s){E.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length});let o=new Date,i=await(async()=>{switch(e){case"anthropic-api":return cd(t,n,s);case"claude-oauth":{let{getValidAccessToken:r}=await Promise.resolve().then(()=>(_t(),Oi)),a=await r();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return ny(a,n,s)}case"openai-api":return dd(t,n,s);case"gemini-api":return ud(t,n,s);case"langdock-api":{let r=R(),a=r.langdockProvider||"anthropic",l=r.langdockBaseUrl;switch(a){case"openai":case"mistral":{let c=l||Cs[a];return dd(t,n,s,`${c}/v1/chat/completions`)}case"google":{let c=l||Cs.google;return ud(t,n,s,`${c}/v1beta/models/${n}:generateContent`)}default:{let c=l||Cs.anthropic;return cd(t,n,s,void 0,void 0,c)}}}default:throw new Error(`Unsupported API engine: ${e}`)}})();return cy(e,n,s,i,o,new Date),i}function cy(e,t,n,s,o,i){St({engine:e,model:t,name:n.structuredOutput?.name||"generation",input:{system:n.systemPrompt,messages:n.messages},output:s.type==="structured"?s.data:s.text,usage:s.usage,startTime:o,endTime:i,metadata:{structured:!!n.structuredOutput,systemPromptLength:n.systemPrompt.length}})}async function Pe(e,t,n,s){return ly.has(e)?gd(e,t,n,s):(E.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),ry(e,n,s))}function Bn(e){if(e==="langdock-api"){if((R().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=R();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Ts(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 Hn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Cs,Rk,Or,Fr,ly,dt=N(()=>{"use strict";y();Ir();Uo();ee();_t();le();tn();Be();Cs={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},Rk=Cs.anthropic,Or=[10,20,40,60,120];Fr=null;ly=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});var jr,hd=N(()=>{"use strict";y();jr={"intent-analyzer":{version:2,placeholders:["themeName","contextData"],template:`You are the Intent Analyzer for vibeSpot, a HubSpot CMS builder that generates pages, email templates, and blog templates.
855
840
 
856
- The user's message applies to the current page unless they reference another page by name or say "all pages" / "every page" / "the whole site".`:"";return`You are the Intent Analyzer for vibeSpot, a HubSpot CMS builder that generates pages, email templates, and blog templates.
841
+ Your job: classify the user's request, determine the content type (page, email, or blog), and plan which modules need work. You do NOT generate module code \u2014 you only plan. Think like a product strategist: read past the literal words to the outcome the user actually wants, then scope the smallest set of changes that delivers it.
857
842
 
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.
843
+ ## Theme: "{{themeName}}"
859
844
 
860
- ## Theme: "${e}"
861
-
862
- ${i}${r}${a}${l}
845
+ {{contextData}}
863
846
 
864
847
  ## Content Type Detection
865
848
 
@@ -885,10 +868,22 @@ If ambiguous, default to "page". The content type affects downstream pipeline be
885
868
  7. **style_change** \u2014 User wants design system changes that affect shared CSS/multiple modules (e.g., "change the color scheme to blue")
886
869
  8. **question** \u2014 User is asking a question, not requesting changes (e.g., "what modules do I have?"). Provide the answer directly.
887
870
 
871
+ ## Surface the brief (create / create_site)
872
+
873
+ When the intent is **create** or **create_site**, capture what you can infer about the brief so downstream stages design with intent instead of guessing. In \`themeContext\` (or the page \`purpose\` fields), note the inferred:
874
+ - **Audience** \u2014 who the page is for (e.g., "RevOps leaders at mid-market SaaS").
875
+ - **Primary goal / conversion** \u2014 the one action the page should drive (book demo, start trial, buy, subscribe, contact).
876
+ - **Tone** \u2014 how it should feel (authoritative, playful, premium, technical, warm).
877
+ Infer these from the user's words and the theme name; never invent specifics that contradict the request. A page with a clear audience + goal + tone converts far better than a generic one.
878
+
879
+ ## Plan a conversion-complete page (create, single page)
880
+
881
+ A landing page that only has a hero and a CTA underperforms. For a fresh **create**, lean toward a complete narrative arc so the Module Planner has the right scaffold: an attention-grabbing **hero**, **value/benefits**, **social proof** (logos, testimonials, or stats), an **objection-handler or how-it-works**, and a focused **final CTA**. Do not pad with filler \u2014 match section count to the brief \u2014 but do not ship a skeleton when the user asked for a real page.
882
+
888
883
  ## Multi-Page Site Rules (create_site only)
889
884
 
890
885
  When classifying as \`create_site\`:
891
- - Populate the \`pages\` array with one entry per page. Each page needs: id (kebab-case), label (human-readable), pageType ("landing_page" or "website_page"), purpose (1-sentence), slug (URL path without leading /).
886
+ - Populate the \`pages\` array with one entry per page. Each page needs: id (kebab-case), label (human-readable), pageType ("landing_page" or "website_page"), purpose (1-sentence, include audience + goal where inferable), slug (URL path without leading /).
892
887
  - Populate \`sharedModules\` with names of modules shared across all pages (typically ["site-header", "site-footer"]).
893
888
  - Always include at least a header and footer in sharedModules.
894
889
  - Page IDs should be descriptive: "wp-home", "wp-about", "wp-contact", etc.
@@ -898,8 +893,8 @@ When classifying as \`create_site\`:
898
893
 
899
894
  ## Key Rules
900
895
 
901
- - For **modify**: list only the modules that actually need changes in \`affectedModules\`. Everything else goes in \`unchangedModules\`.
902
- - For **add**: new modules go in \`newModules\` with a descriptive name, brief description, and position index (0-based).
896
+ - For **modify**: list only the modules that actually need changes in \`affectedModules\`. Everything else goes in \`unchangedModules\`. Be surgical \u2014 touching modules the user didn't ask about risks regressions and wastes generation.
897
+ - For **add**: new modules go in \`newModules\` with a descriptive name, brief description, and position index (0-based). Place the new module where it strengthens the page's flow, not just at the end, unless the user specifies.
903
898
  - For **reuse**: if the user references a module from the library, put it in \`reuseModules\` with the source template name. Reused modules are copied as-is \u2014 their structure (fields, HTML, CSS) MUST NOT change.
904
899
  - For **style_change**: set \`designSystemChanges: true\`. All modules become affected since they need the updated design system.
905
900
  - For **question**: set \`intent: "question"\` and provide the answer in the \`answer\` field. The pipeline will short-circuit.
@@ -925,88 +920,87 @@ CRITICAL: When the user corrects a misclassification (e.g., "I was referencing t
925
920
  If the user asks for multiple things (e.g., "make hero taller AND add testimonials"), capture ALL parts:
926
921
  - Affected existing modules in \`affectedModules\`
927
922
  - New modules in \`newModules\`
928
- - Set the broadest applicable intent (prefer "modify" + newModules over splitting)
929
-
930
- ## Content Type Detection
923
+ - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`},"design-system":{version:2,placeholders:["themeName"],template:`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
931
924
 
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 Pc,Rc=R(()=>{"use strict";h();Pc={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 Nc(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=Ic(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 y=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:y})}c.push({role:"user",content:e});let u=await _e(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Pc,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:sh(m)}),m}function sh(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 Oc=R(()=>{"use strict";h();st();Rc();ce()});function Ao(e,t){let n=[];n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
925
+ 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 \u2014 so the system has to be coherent, distinctive, and accessible, not a generic bootstrap clone.
933
926
 
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.
927
+ ## Theme: "{{themeName}}"
935
928
 
936
- ## Theme: "${e}"
929
+ ## Design Direction \u2014 decide FIRST
930
+ Before writing CSS, commit to a deliberate visual direction that fits the brand's audience, goal, and mood (premium SaaS, editorial media, warm local business, technical/developer, bold consumer, etc.). Then make every token serve that direction. A page reads as "designed" when its color, type, spacing, and depth all tell the same story \u2014 and as "templated" when they're arbitrary. Avoid the default purple-on-white startup look unless the brief calls for it. Aim for a memorable, modern aesthetic: confident color, real typographic hierarchy, generous whitespace, and subtle depth.
937
931
 
938
932
  ## Output Requirements
939
933
 
940
934
  ### cssVariables
941
935
  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
936
 
943
- **Colors** (at minimum):
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
-
958
- **Typography**:
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
-
966
- **Spacing**:
967
- - --${e}-space-xs through --${e}-space-xl, --${e}-space-section
968
- - --${e}-max-width: content max-width (1152-1280px)
969
-
970
- **Effects**:
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
937
+ **Colors** (at minimum). Build a deliberate palette, not random hex. Ensure text-on-background pairs meet **WCAG AA contrast (\u22654.5:1 for body, \u22653:1 for large text)** \u2014 this is non-negotiable for readability:
938
+ - --{{themeName}}-color-bg: page background
939
+ - --{{themeName}}-color-surface: card/section background
940
+ - --{{themeName}}-color-dark: dark section background
941
+ - --{{themeName}}-color-dark-surface: card bg inside dark sections
942
+ - --{{themeName}}-color-text: primary text color
943
+ - --{{themeName}}-color-text-inverse: text on dark backgrounds
944
+ - --{{themeName}}-color-text-muted: secondary/muted text (still AA against its background)
945
+ - --{{themeName}}-color-primary: primary brand color
946
+ - --{{themeName}}-color-primary-dark: darker variant for hover states
947
+ - --{{themeName}}-color-accent: accent/highlight color (use sparingly, for emphasis)
948
+ - --{{themeName}}-color-accent-light: light tint for pill/badge backgrounds
949
+ - --{{themeName}}-color-border: default border color
950
+ - --{{themeName}}-color-border-hover: border on hover
951
+
952
+ **Typography**. Use a consistent **modular scale** (e.g. ~1.25 ratio) so heading sizes feel related rather than arbitrary:
953
+ - --{{themeName}}-font-display: display/heading font stack (system fonts only)
954
+ - --{{themeName}}-font-body: body text font stack (system fonts only)
955
+ - --{{themeName}}-size-h1 through --{{themeName}}-size-h3: heading sizes using clamp() for fluid scaling
956
+ - --{{themeName}}-size-body, --{{themeName}}-size-lg, --{{themeName}}-size-small, --{{themeName}}-size-label
957
+ - --{{themeName}}-leading-tight, --{{themeName}}-leading-snug, --{{themeName}}-leading-body: line heights (tight for display, ~1.6 for body readability)
958
+ - --{{themeName}}-tracking-tight, --{{themeName}}-tracking-wide: letter spacing (tighten large display, widen labels/eyebrows)
959
+ - --{{themeName}}-weight-normal, --{{themeName}}-weight-medium, --{{themeName}}-weight-bold: weight scale for hierarchy
960
+
961
+ **Spacing**. Use a consistent **8pt-based scale** (4 / 8 / 16 / 24 / 40 / 64 \u2026) so rhythm is predictable:
962
+ - --{{themeName}}-space-xs through --{{themeName}}-space-xl, --{{themeName}}-space-section
963
+ - --{{themeName}}-max-width: content max-width (1152-1280px)
964
+
965
+ **Effects**. Use layered, soft shadows (not a single harsh drop) for real depth:
966
+ - --{{themeName}}-radius-sm, --{{themeName}}-radius-md, --{{themeName}}-radius-lg, --{{themeName}}-radius-full
967
+ - --{{themeName}}-shadow-card, --{{themeName}}-shadow-card-hover, --{{themeName}}-shadow-button
968
+ - --{{themeName}}-transition-fast, --{{themeName}}-transition-base, --{{themeName}}-transition-slow
969
+ - --{{themeName}}-ease: a refined easing curve (e.g. cubic-bezier(0.4, 0, 0.2, 1)) for tasteful motion
974
970
 
975
971
  ### sharedCss
976
972
  Complete CSS file content. MUST include:
977
973
  1. A \`:root {}\` block with ALL variables from cssVariables
978
- 2. Reset (box-sizing, margin, padding)
979
- 3. Body styles referencing your variables
980
- 4. Typography rules (h1-h6, p)
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)
974
+ 2. Reset (box-sizing, margin, padding) and \`scroll-behavior: smooth\` with \`@media (prefers-reduced-motion: reduce)\` disabling it
975
+ 3. Body styles referencing your variables (incl. \`-webkit-font-smoothing: antialiased\` and \`text-rendering: optimizeLegibility\`)
976
+ 4. Typography rules (h1-h6, p) using the modular scale, with sensible \`max-width\` on body copy (~65ch) for readability
977
+ 5. Layout utilities (.{{themeName}}-container, .{{themeName}}-section, .{{themeName}}-section--dark)
978
+ 6. Grid system (.{{themeName}}-grid, .{{themeName}}-grid--2/3/4 with responsive breakpoints)
979
+ 7. Card component (.{{themeName}}-card with hover lift using shadow + translateY)
980
+ 8. Button component (.{{themeName}}-btn, .{{themeName}}-btn--primary, .{{themeName}}-btn--secondary) with comfortable padding and a clear hover AND \`:focus-visible\` state
985
981
  CRITICAL: Re-declare color, text-decoration:none, and font-family on :hover/:focus \u2014 HubSpot overrides link hover styles
986
- 9. Pill/badge (.${e}-pill)
987
- 10. Decorative elements (at least one background treatment: grid pattern, noise, gradient orb)
988
- 11. Scroll animation CSS ([data-animate], [data-animate-stagger]) with 3s CSS-only fallback
989
- 12. Section label (.${e}-label) \u2014 uppercase, letter-spacing, accent color
990
- 13. Stat number styling
991
- 14. Responsive mobile styles (@media max-width: 767px)
982
+ 9. Pill/badge (.{{themeName}}-pill)
983
+ 10. Decorative elements (at least one tasteful background treatment: subtle grid pattern, soft noise/grain, gradient mesh/orb) \u2014 used to add depth, never to distract
984
+ 11. Scroll animation CSS ([data-animate], [data-animate-stagger]) with a 3s CSS-only fallback AND a \`@media (prefers-reduced-motion: reduce)\` block that shows content immediately
985
+ 12. Section label (.{{themeName}}-label) \u2014 uppercase, letter-spacing, accent color (the "eyebrow")
986
+ 13. Stat number styling (large, tight tracking, display font)
987
+ 14. Global \`:focus-visible\` outline using the accent color for keyboard accessibility
988
+ 15. Responsive mobile styles (@media max-width: 767px) \u2014 verify type, spacing, and grids all collapse gracefully
992
989
 
993
990
  ### sharedJs (optional)
994
- IntersectionObserver-based scroll animation JS. Wrap in IIFE.
991
+ IntersectionObserver-based scroll animation JS. Wrap in IIFE. Respect \`prefers-reduced-motion\` (skip animating when the user opts out). Keep it lightweight and dependency-free.
995
992
 
996
993
  ## CSS Rules \u2014 CRITICAL
997
- - All classes MUST use prefix "${e}-"
998
- - Use BEM naming: ${e}-module__element--modifier
994
+ - All classes MUST use prefix "{{themeName}}-"
995
+ - Use BEM naming: {{themeName}}-module__element--modifier
999
996
  - Use system font stacks ONLY (no Google Fonts @import, no external CDN)
1000
997
  - Every var() reference in CSS must have a matching declaration in :root
1001
998
  - No Tailwind, no Sass, no PostCSS
1002
999
  - Use clamp() for fluid typography sizing
1000
+ - Prefer CSS custom properties everywhere over hardcoded values, so modules stay consistent
1003
1001
 
1004
1002
  ## Font Strategy
1005
- Use system font stacks that approximate the desired aesthetic. Pick TWO stacks:
1006
- - Display: for headings
1007
- - Body: for text
1008
-
1009
- **Choose the pairing that best fits the content's mood** \u2014 don't default to the same one every time:
1003
+ Use system font stacks that approximate the desired aesthetic. Pick TWO stacks (Display for headings, Body for text) that fit the brand mood \u2014 and create real contrast between them. Don't default to the same pairing every time:
1010
1004
  | Style | Display Stack | Body Stack | Best for |
1011
1005
  |-------|--------------|------------|----------|
1012
1006
  | Editorial | Georgia, Cambria, "Times New Roman", serif | system-ui, -apple-system, "Segoe UI", sans-serif | Media, luxury, culture |
@@ -1016,10 +1010,189 @@ Use system font stacks that approximate the desired aesthetic. Pick TWO stacks:
1016
1010
  | Geometric | Futura, "Century Gothic", "Trebuchet MS", sans-serif | system-ui, sans-serif | Architecture, design, fashion |
1017
1011
  | Classic | "Book Antiqua", Palatino, "Palatino Linotype", serif | Georgia, "Times New Roman", serif | Law, finance, heritage |
1018
1012
  | Friendly | "Comic Sans MS", Chalkboard, cursive | "Trebuchet MS", system-ui, sans-serif | Kids, casual, fun brands |
1019
- | Contrast pair | Georgia, serif (display) | system-ui, sans-serif (body) | When you want serif/sans tension |`),n.push(`
1013
+ | Contrast pair | Georgia, serif (display) | system-ui, sans-serif (body) | When you want serif/sans tension |`},"module-planner":{version:2,placeholders:["themeName","cssSummary"],template:`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
1014
+
1015
+ 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. The quality of the finished page is decided here: a vague brief produces generic filler, a sharp brief produces copy that converts.
1016
+
1017
+ The Design System has already been created. Your module plans MUST reference the existing CSS classes and variables.
1018
+
1019
+ ## Theme: "{{themeName}}"
1020
+
1021
+ ## Available CSS Classes & Variables
1022
+ Reference these in your layoutNotes:
1023
+
1024
+ {{cssSummary}}
1025
+
1026
+ ## Plan the page as a persuasive narrative
1027
+ Order modules so the page argues its case: grab attention (hero) \u2192 establish relevance/pain \u2192 present the solution and its benefits \u2192 prove it (social proof, stats, testimonials) \u2192 handle objections (how-it-works, FAQ, comparison) \u2192 drive one clear action (final CTA). Vary the section types \u2014 don't stack three near-identical card grids. Match the section count to the brief; a focused 5-section page beats a padded 9-section one.
1028
+
1029
+ ## Output Rules
1030
+
1031
+ ### Module names \u2014 CRITICAL
1032
+ - **If the user message lists "Existing Modules to Re-plan", you MUST use those exact names verbatim** in \`modules[].name\` and in \`moduleOrder\`. Do not rename them. Do not retitle-case them. Do not "improve" them. The names are identifiers, not labels. Mismatched names create duplicate modules instead of regenerating existing ones.
1033
+ - **For genuinely new modules** (not in any existing-modules list): use kebab-case identifiers (e.g., \`hero\`, \`pricing-cards\`, \`final-cta\`). This matches the convention used by Plan Mode and Figma Import.
1034
+ - The \`description\` and \`contentBrief\` fields can be any text \u2014 they describe the module to humans, while \`name\` is the canonical identifier.
1035
+
1036
+ ### Content briefs \u2014 make them specific and benefit-led
1037
+ A strong \`contentBrief\` tells the developer exactly what to say, not just what kind of section it is. For each module include:
1038
+ - **Headline direction** \u2014 a benefit- or outcome-led angle (what the reader gets), not a feature label. Suggest an actual headline, not "Hero headline here".
1039
+ - **Supporting copy** \u2014 the key message, proof points, and the specific words/numbers to feature (real-sounding stats, concrete outcomes).
1040
+ - **CTA** \u2014 the exact action and button label where relevant ("Start free trial", "Book a 15-min demo").
1041
+ - **Conversion intent** \u2014 what this section must accomplish (build trust, remove a specific objection, create urgency).
1042
+ Apply proven structure where it fits: Problem\u2013Agitate\u2013Solution for the opening, social proof near decision points, objection-handling before the final CTA. Never write lorem ipsum or placeholder-y copy direction \u2014 write as if the brand's marketer wrote the brief.
1043
+
1044
+ ### Layout notes
1045
+ - Describe the visual layout using the available CSS classes above (e.g., "Use {{themeName}}-grid--3 for the card layout, {{themeName}}-section--dark for the background, {{themeName}}-label for the eyebrow").
1046
+ - Call out hierarchy and rhythm: what's the focal element, how much breathing room, where the eye should land first.
1047
+ - Note responsive intent (how it should stack on mobile) when it matters.
1048
+
1049
+ ### Module order
1050
+ - \`moduleOrder\`: list **all** modules' names in the order they should appear on the page, including:
1051
+ - the ones you just planned (in \`modules\`)
1052
+ - any "Existing Modules to Keep" the user listed (these are not in \`modules\`, but still belong in \`moduleOrder\`)`},"site-module-planner":{version:2,placeholders:["themeName","siteMap","sharedList","cssSummary","navHrefs","sharedModuleNamesCsv"],template:`You are the Site Module Planner for vibeSpot, a HubSpot CMS page builder.
1053
+
1054
+ 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. Think of the site as one story told across several pages \u2014 each page has a distinct job, but the voice, design language, and navigation stay consistent throughout.
1055
+
1056
+ ## Theme: "{{themeName}}"
1057
+
1058
+ ## Site Map
1059
+ {{siteMap}}
1060
+
1061
+ ## Shared Modules (appear on EVERY page)
1062
+ {{sharedList}}
1063
+
1064
+ Plan these shared modules ONCE. They will be automatically added to every page's template.
1065
+
1066
+ ## Available CSS Classes & Variables
1067
+ Reference these in your layoutNotes:
1068
+
1069
+ {{cssSummary}}
1070
+
1071
+ ## Shared Module Rules
1072
+
1073
+ ### site-header (Navigation)
1074
+ - Logo on the left, nav links center or right, CTA button far right
1075
+ - Nav links: one for each page in the site map. Use relative hrefs matching slugs:
1076
+ {{navHrefs}}
1077
+ - Active page link uses CSS class "{{themeName}}-nav__link--active"
1078
+ - Sticky with backdrop-blur, transitions on scroll
1079
+ - Mobile: hamburger menu with slide-in nav, fully keyboard-accessible
1080
+
1081
+ ### site-footer
1082
+ - Consistent across all pages
1083
+ - Brand name, link columns (include page links), contact info, social icons, copyright
1084
+ - Include navigation links matching the header
1085
+
1086
+ ## Per-Page Module Rules
1087
+ For each page, plan modules specific to that page's purpose. Do NOT include shared modules ({{sharedModuleNamesCsv}}) in per-page module lists or per-page moduleOrder \u2014 they are automatically prepended/appended.
1088
+
1089
+ Each page should have distinct content appropriate to its purpose, and each page should still earn its conversion (every page needs a clear next step, usually pointing toward the primary site goal). Aim for:
1090
+ - 4-8 unique modules per page (not counting shared modules)
1091
+ - A persuasive flow per page (attention \u2192 value \u2192 proof \u2192 action), not a flat list of sections
1092
+ - Specific, benefit-led content briefs (real headline/CTA direction, concrete proof points \u2014 never lorem ipsum)
1093
+ - Consistent use of design system classes across all pages so the site feels like one product
1094
+
1095
+ ## Cross-page coherence
1096
+ - Reuse the same component vocabulary (cards, labels, buttons, grids) across pages so they feel related.
1097
+ - Avoid repeating the exact same section on multiple pages \u2014 differentiate by purpose (e.g., home = overview, about = story/team, contact = form + details).
1098
+ - Keep tone and visual density consistent page to page.
1099
+
1100
+ ## Module Naming
1101
+ - Use kebab-case identifiers (e.g., "hero", "team-grid", "contact-form")
1102
+ - Page-specific modules that might conflict across pages should be prefixed with a short page identifier (e.g., "home-hero", "about-hero") unless the content is genuinely different enough that the name alone distinguishes it
1103
+ - Shared modules use the exact names from the shared modules list above
1104
+
1105
+ ## Output Structure
1106
+ Return a JSON object with:
1107
+ - \`sharedModules\`: array of shared module specs (planned once, used everywhere)
1108
+ - \`pages\`: array of per-page blueprints, each with:
1109
+ - \`pageId\`: matching the page ID from the site map
1110
+ - \`modules\`: array of module specs for that page only (excluding shared)
1111
+ - \`moduleOrder\`: ordered list of per-page module names only (excluding shared)
1112
+ - \`narrative\`: brief description of the overall site story/flow`},"module-developer":{version:2,placeholders:["themeName"],template:`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1113
+
1114
+ Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code. Build it to a senior front-end standard: clean semantic markup, polished responsive CSS that uses the theme's design system, and real, compelling default copy \u2014 what you ship is what the user sees in the live preview, so make it look finished, not like a wireframe.
1115
+
1116
+ ## Theme: "{{themeName}}"
1117
+
1118
+ ## Output Rules \u2014 CRITICAL
1119
+ You produce a single module with these fields:
1120
+ - **moduleName**: Exact module name (title-case, e.g., "Hero Banner")
1121
+ - **fieldsJson**: Valid JSON string \u2014 the module's fields.json content
1122
+ - **metaJson**: Valid JSON string \u2014 must include host_template_types: ["PAGE"], is_available_for_new_content: true
1123
+ - **moduleHtml**: HubL template ({{ module.field_name }} syntax)
1124
+ - **moduleCss**: Vanilla CSS (no Tailwind, no Sass, no CDN imports)
1125
+ - **moduleJs**: Optional vanilla JS wrapped in IIFE, or null
1126
+
1127
+ ## Content quality \u2014 write real copy, never lorem
1128
+ - Default field values must be specific, on-brief, benefit-led copy in the brand's voice \u2014 NEVER "Lorem ipsum", "Your headline here", "Section title", or placeholder filler. Write headlines that lead with the outcome, body copy that's concrete, CTAs that name the action ("Start free trial", "Book a demo").
1129
+ - Use real, plausible numbers in stats ("12,000+ teams", "3.2\xD7 faster") rather than "XX%".
1130
+ - Keep copy tight: punchy headlines, scannable body text, no waffle.
1131
+
1132
+ ## Design quality \u2014 make it look designed
1133
+ - Build a clear visual hierarchy (one focal element per section), generous whitespace, and consistent rhythm using the theme's spacing scale.
1134
+ - Use hover AND \`:focus-visible\` states on interactive elements; add tasteful transitions via the theme's transition/ease variables. Keep motion subtle.
1135
+ - Ensure the layout is fully responsive \u2014 verify it stacks cleanly at mobile widths (max-width: 767px).
1136
+ - Lean on the shared design system classes/variables shown below for consistency; only add module-specific CSS for what the shared system doesn't cover.
1137
+
1138
+ ## Accessibility
1139
+ - Use semantic HTML (\`section\`, \`header\`, \`nav\`, \`h1\`-\`h3\` in order, \`button\`/\`a\` correctly).
1140
+ - Every image needs meaningful \`alt\` text. Icons that are decorative get \`aria-hidden="true"\`.
1141
+ - Maintain readable contrast (the design system colors are AA-compliant \u2014 keep text on the intended backgrounds).
1142
+
1143
+ ## CSS Rules
1144
+ - All CSS classes must use prefix "{{themeName}}-"
1145
+ - Use BEM naming: {{themeName}}-moduleName__element--modifier
1146
+ - Reference the theme's CSS custom properties (shown below)
1147
+ - No CDN imports (@import url(), external <link> tags)
1148
+ - Use system font stacks \u2014 no Google Fonts
1149
+
1150
+ ## Field Rules
1151
+ - Use "type": "text" (NEVER "textarea" \u2014 it's deprecated)
1152
+ - NEVER use "name": "name" (reserved) \u2014 use "item_name" instead
1153
+ - NEVER use "name": "label" (reserved) \u2014 use "section_label" instead
1154
+ - NEVER put literal \\n in field defaults
1155
+ - Wrap style fields in a "styles" group with "tab": "STYLE"
1156
+ - Color fields: type "color", default { "color": "#hex", "opacity": 100 }
1157
+ - Link fields: type "link", default { "url": { "href": "#", "type": "EXTERNAL" }, "open_in_new_tab": false, "no_follow": false }
1158
+ - Image fields: type "image", default { "src": "https://placehold.co/800x600/1a1a2e/ffffff?text=Replace+in+HubSpot", "alt": "Placeholder", "width": 800, "height": 600 }
1159
+ - For repeater groups, use "occurrence": { "min": 0, "max": 100 }
1160
+
1161
+ ## Style fields MUST have complete defaults \u2014 CRITICAL
1162
+ Every style/color field you reference in CSS must ship a complete default value. If your CSS builds a color from a style field \u2014 e.g. \`rgba({{ module.styles.bg.color|convert_rgb }}, {{ module.styles.bg.opacity/100 }})\` \u2014 that field's default MUST include both a \`color\` hex AND \`opacity\`, or the rendered CSS becomes invalid (\`rgba(15, 17, 21, )\`) and the browser drops the declaration, leaving the section unstyled. Always give color fields a real default hex + opacity 100, and never reference a style field you didn't define with a default. Prefer the theme's CSS variables for anything that should match the design system.
1163
+
1164
+ ## Images & Assets
1165
+ - Use get_asset_url("{{themeName}}/assets/filename.ext") for uploaded assets
1166
+ - For placeholder images, use image fields with placehold.co defaults
1167
+ - Size placeholders appropriately (hero: 1920x800, cards: 600x400, icons: 200x200)
1168
+
1169
+ ## Navigation & Anchors
1170
+ - Add id attribute on module root element: id="module-name-lowercased"
1171
+ - For nav modules, use anchor links (#features, #pricing, etc.)
1172
+ - Include smooth scroll behavior in nav click handlers, and respect prefers-reduced-motion
1173
+
1174
+ ## metaJson Template
1175
+ { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`}}});function uy(){if(yd!==void 0)return yd;if(As!==void 0)return As;try{let e=JSON.parse(P(hn(dy)));As=e&&typeof e=="object"&&e.prompts?e:null}catch{As=null}return As}function my(e){let t=new Set;for(let n of e.matchAll(bd))t.add(n[1]);return[...t]}function py(e){let t=jr[e],n=uy()?.prompts?.[e];if(n&&n.version===t.version&&typeof n.template=="string"){let s=new Set(t.placeholders);if(my(n.template).every(o=>s.has(o)))return{id:e,version:n.version,source:"langfuse-bundled",template:n.template}}return{id:e,version:t.version,source:"local-fallback",template:t.template}}function gy(e,t,n){let s=new Set(jr[e].placeholders);return t.replace(bd,(o,i)=>s.has(i)?n[i]??"":o)}function Rt(e,t){return gy(e,py(e).template,t)}var dy,bd,As,yd,_s=N(()=>{"use strict";y();oe();hd();dy="prompts.bundle.json",bd=/\{\{\s*([a-zA-Z][\w]*)\s*\}\}/g});function Sd(e,t,n,s,o){let i=t.length>0?`Current template modules (in page order):
1176
+ ${t.map((d,u)=>`${u+1}. ${d}`).join(`
1177
+ `)}`:"No modules yet (new page).",r=n.length>0?`
1178
+
1179
+ Module library (reusable from other templates):
1180
+ ${n.map(d=>`- ${d.name} (used in: ${d.usedIn.join(", ")})`).join(`
1181
+ `)}`:"",a=s?`
1182
+
1183
+ ## Product Context
1184
+ ${s}`:"",l=o?.pages&&o.pages.length>1?`
1185
+
1186
+ ## Multi-Page Site Context
1187
+ This is a multi-page site. Currently editing: **${o.activePageLabel||"unknown"}**
1188
+ All pages:
1189
+ ${o.pages.map(d=>`- ${d.label} (${d.id}, ${d.moduleCount} modules)`).join(`
1190
+ `)}
1191
+
1192
+ The user's message applies to the current page unless they reference another page by name or say "all pages" / "every page" / "the whole site".`:"",c=`${i}${r}${a}${l}`;return Rt("intent-analyzer",{themeName:e,contextData:c})}var vd,xd=N(()=>{"use strict";y();_s();vd={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 wd(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=Sd(t.themeName,a,r,t.brandAssets?.themeContext,t.sitePages?{activePageLabel:t.activePageLabel,pages:t.sitePages}:void 0),c=[],d=t.messages.slice(-6);for(let g of d)if(g.role==="user"||g.role==="assistant"){let h=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:h})}c.push({role:"user",content:e});let u=await te("intent-analyzer",()=>Pe(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:vd,name:"pipeline_plan"},maxTokens:2e3}));if(u.type!=="structured"){E.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:a,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:g}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],t.contentMode==="email"?m.contentType="email":m.contentType=m.contentType==="email"?"email":"page",E.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:fy(m)}),m}function fy(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 Cd=N(()=>{"use strict";y();dt();xd();le();Be()});function Ko(e,t){let n=[];n.push(Rt("design-system",{themeName:e})),n.push(`
1020
1193
 
1021
1194
  ## Design Guide
1022
- ${Jc()}`),t?.styleguide&&n.push(`
1195
+ ${$d()}`),t?.styleguide&&n.push(`
1023
1196
 
1024
1197
  ## Brand Style Guide
1025
1198
  ${t.styleguide}`),t?.themeContext&&n.push(`
@@ -1035,11 +1208,11 @@ ${o.join(`
1035
1208
  ## No Brand Provided \u2014 Follow the Generation Recipe
1036
1209
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1037
1210
 
1038
- ${Lc()}`),n.join("")}function pr(e,t){let n=Ao(e),o=n.indexOf(`
1211
+ ${_d()}`),n.join("")}function Lr(e,t){let n=Ko(e),o=n.indexOf(`
1039
1212
 
1040
1213
  ## Design Guide
1041
1214
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Design Guide
1042
- ${Jc()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1215
+ ${$d()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1043
1216
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1044
1217
  ${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
1218
  The following brand identity values MUST be used. Do NOT substitute or override them:
@@ -1047,41 +1220,13 @@ ${d.join(`
1047
1220
  `)}`)}return!c&&!t?.styleguide&&l.push(`## No Brand Provided \u2014 Follow the Generation Recipe
1048
1221
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1049
1222
 
1050
- ${Lc()}`),l.length>0&&a.push({type:"text",text:l.join(`
1051
-
1052
- `)}),a}function oh(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 jc(e,t,n,s){let o=[],i=oh(t);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
1054
-
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
-
1057
- The Design System has already been created. Your module plans MUST reference the existing CSS classes and variables.
1058
-
1059
- ## Theme: "${e}"
1060
-
1061
- ## Available CSS Classes & Variables
1062
- Reference these in your layoutNotes:
1063
-
1064
- ${i}
1065
-
1066
- ## Output Rules
1067
-
1068
- ### Module names \u2014 CRITICAL
1069
- - **If the user message lists "Existing Modules to Re-plan", you MUST use those exact names verbatim** in \`modules[].name\` and in \`moduleOrder\`. Do not rename them. Do not retitle-case them. Do not "improve" them. The names are identifiers, not labels. Mismatched names create duplicate modules instead of regenerating existing ones.
1070
- - **For genuinely new modules** (not in any existing-modules list): use kebab-case identifiers (e.g., \`hero\`, \`pricing-cards\`, \`final-cta\`). This matches the convention used by Plan Mode and Figma Import.
1071
- - The \`description\` and \`contentBrief\` fields can be any text \u2014 they describe the module to humans, while \`name\` is the canonical identifier.
1223
+ ${_d()}`),l.length>0&&a.push({type:"text",text:l.join(`
1072
1224
 
1073
- ### Content & layout
1074
- - Content briefs: describe the actual copy/content each module needs (headlines, body text, CTAs, stats)
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 ${e}-grid--3 for card layout, ${e}-section--dark for background")
1077
-
1078
- ### Module order
1079
- - \`moduleOrder\`: list **all** modules' names in the order they should appear on the page, including:
1080
- - the ones you just planned (in \`modules\`)
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(`
1225
+ `)}),a}function hy(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(`
1226
+ `)}function Td(e,t,n,s){let o=[],i=hy(t);return o.push(Rt("module-planner",{themeName:e,cssSummary:i})),(!s||s.includes("content"))&&o.push(`
1082
1227
 
1083
1228
  ## Content & Copywriting Guide
1084
- ${ih()}`),n?.brandvoice&&o.push(`
1229
+ ${yy()}`),n?.brandvoice&&o.push(`
1085
1230
 
1086
1231
  ## Brand Voice
1087
1232
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1090,7 +1235,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1090
1235
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1091
1236
 
1092
1237
  ## Anti-AI Copy Rules
1093
- ${rh()}`),o.join("")}function Lc(){let e=Un(),t=Fc(e,"## 4. Color System","## 5."),n=Fc(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1238
+ ${by()}`),o.join("")}function _d(){let e=as(),t=kd(e,"## 4. Color System","## 5."),n=kd(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1094
1239
  Read the user's request carefully. What industry? What audience? What mood?
1095
1240
  Map it to ONE of these aesthetic directions \u2014 then commit fully:
1096
1241
 
@@ -1146,7 +1291,7 @@ Before finalizing, ask yourself:
1146
1291
 
1147
1292
  If any answer is "no," go bolder. The user wants personality, not safety.`),s.join(`
1148
1293
 
1149
- `)}function Fc(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
1294
+ `)}function kd(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 $d(){return`### Design Philosophy
1150
1295
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
1151
1296
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
1152
1297
 
@@ -1253,7 +1398,7 @@ Include these in shared CSS:
1253
1398
  | All animations same speed | Stagger with increasing delays |
1254
1399
  | Skip hover/focus states | Every interactive element needs feedback |
1255
1400
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
1256
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function ih(){return`### Mandatory Page Sections (generate all)
1401
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function yy(){return`### Mandatory Page Sections (generate all)
1257
1402
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
1258
1403
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
1259
1404
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -1341,7 +1486,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
1341
1486
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
1342
1487
  - Keep paragraphs to 2-3 sentences max
1343
1488
  - Aim for 6th-grade reading level
1344
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function rh(){return`### Banned Punctuation
1489
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function by(){return`### Banned Punctuation
1345
1490
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
1346
1491
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
1347
1492
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -1371,12 +1516,12 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
1371
1516
  - Use plain short words: use > utilize, start > commence, help > facilitate
1372
1517
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
1373
1518
  - 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 gr,Dc,Bc=R(()=>{"use strict";h();Ge();gr={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"]};Dc={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 fr(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?"":`
1519
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Jr,Ad,Ed=N(()=>{"use strict";y();Ke();_s();Jr={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"]};Ad={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 Br(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
1520
 
1376
1521
  ## Brand Kit \u2014 MANDATORY Design Constraints
1377
1522
  The following brand identity values MUST be used. Do NOT substitute or override them:
1378
1523
  ${t.join(`
1379
- `)}`}function $o(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1524
+ `)}`}function Vo(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1380
1525
 
1381
1526
  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
1527
 
@@ -1465,25 +1610,25 @@ Do NOT use: system-ui, -apple-system, Segoe UI, Inter, or any Google Fonts.
1465
1610
  - No external font imports`),n.push(`
1466
1611
 
1467
1612
  ## Email Design Guide
1468
- ${Gc()}`),t?.styleguide&&n.push(`
1613
+ ${Id()}`),t?.styleguide&&n.push(`
1469
1614
 
1470
1615
  ## Brand Style Guide
1471
1616
  ${t.styleguide}`),t?.themeContext&&n.push(`
1472
1617
 
1473
1618
  ## Product Context
1474
- ${t.themeContext}`);let s=fr(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
1619
+ ${t.themeContext}`);let s=Br(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
1475
1620
 
1476
1621
  ## 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 hr(e,t){let n=$o(e),o=n.indexOf(`
1622
+ 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 Hr(e,t){let n=Vo(e),o=n.indexOf(`
1478
1623
 
1479
1624
  ## Email Design Guide
1480
1625
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Email Design Guide
1481
- ${Gc()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1626
+ ${Id()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1482
1627
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1483
- ${t.themeContext}`);let c=fr(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1628
+ ${t.themeContext}`);let c=Br(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1484
1629
  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
1630
 
1486
- `)}),a}function Hc(e,t,n,s){let o=[],i=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
1631
+ `)}),a}function Md(e,t,n,s){let o=[],i=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
1487
1632
  `);o.push(`You are the Email Module Planner for vibeSpot, a HubSpot email template builder.
1488
1633
 
1489
1634
  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.
@@ -1542,7 +1687,7 @@ List all module names in display order (top to bottom)
1542
1687
  One sentence describing the email's purpose and flow`),(!s||s.includes("content"))&&o.push(`
1543
1688
 
1544
1689
  ## Email Content Guide
1545
- ${ah()}`),n?.brandvoice&&o.push(`
1690
+ ${Sy()}`),n?.brandvoice&&o.push(`
1546
1691
 
1547
1692
  ## Brand Voice
1548
1693
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1551,7 +1696,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1551
1696
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1552
1697
 
1553
1698
  ## Anti-AI Copy Rules
1554
- ${lh()}`);let r=fr(n?.brandKit);return r&&o.push(r),o.join("")}function Gc(){return`### Email Design Philosophy
1699
+ ${vy()}`);let r=Br(n?.brandKit);return r&&o.push(r),o.join("")}function Id(){return`### Email Design Philosophy
1555
1700
  Design for the inbox, not the browser. Email templates must look clean and professional in Gmail, Outlook, Apple Mail, and Yahoo Mail simultaneously.
1556
1701
 
1557
1702
  ### Color Strategy
@@ -1584,7 +1729,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1584
1729
  - Hero images: 600px wide, 2:1 to 3:1 aspect ratio
1585
1730
  - Always include alt text (images blocked by default in many clients)
1586
1731
  - Use display:block to prevent gaps in Outlook
1587
- - Product images: consistent sizing within a row`}function ah(){return`### Email Types and Structure
1732
+ - Product images: consistent sizing within a row`}function Sy(){return`### Email Types and Structure
1588
1733
 
1589
1734
  **Welcome / Onboarding Email**
1590
1735
  - Warm greeting with first-name personalization
@@ -1630,7 +1775,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1630
1775
  - One idea per paragraph, 2-3 sentences max
1631
1776
  - Use "you" more than "we"
1632
1777
  - Specific > vague: "saves 3 hours/week" beats "saves time"
1633
- - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function lh(){return`### Email-Specific Anti-AI Rules
1778
+ - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function vy(){return`### Email-Specific Anti-AI Rules
1634
1779
  - No em dashes (\u2014) in email copy. Period.
1635
1780
  - No "I hope this email finds you well"
1636
1781
  - No "In today's fast-paced world"
@@ -1639,159 +1784,61 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1639
1784
  - One exclamation mark per email maximum
1640
1785
  - Avoid tricolon structures ("Fast, reliable, secure")
1641
1786
  - 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 yr,Uc=R(()=>{"use strict";h();yr={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 Wc(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?$o(n.themeName,n.brandAssets):Ao(n.themeName,n.brandAssets),d=l?a?hr(n.themeName,n.brandAssets):pr(n.themeName,n.brandAssets):void 0,u=`## User Request
1787
+ - Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var Ur,Pd=N(()=>{"use strict";y();Ur={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 Nd(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?Vo(n.themeName,n.brandAssets):Ko(n.themeName,n.brandAssets),d=l?a?Hr(n.themeName,n.brandAssets):Lr(n.themeName,n.brandAssets):void 0,u=`## User Request
1643
1788
  ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1644
1789
 
1645
1790
  ## Current Shared CSS (update this)
1646
1791
  \`\`\`css
1647
1792
  ${n.sharedCss}
1648
- \`\`\``);let m=Sn(s),y=await _e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:a?yr:gr,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}}),f;y.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=y.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
- ${Object.entries(S).map(([L,G])=>` ${L.startsWith("--")?L:`--${L}`}: ${G};`).join(`
1793
+ \`\`\``);let m=Bn(s),g=a?Ur:Jr,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}})),f;h.type!=="structured"?(E.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,E.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1794
+ ${Object.entries(S).map(([L,H])=>` ${L.startsWith("--")?L:`--${L}`}: ${H};`).join(`
1650
1795
  `)}
1651
1796
  }
1652
1797
 
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 Kc(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?$o(n.themeName,n.brandAssets):Ao(n.themeName,n.brandAssets),d=l?a?hr(n.themeName,n.brandAssets):pr(n.themeName,n.brandAssets):void 0,u=`## User Request
1798
+ ${b}`));let v=Object.keys(S||{}).length,w=a?[`Email design tokens: ${f.aesthetic||"created"} | ${v} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${v} variables, ${b.length} chars CSS`];return r({type:"agent_decision",step:"designing",decision:w.join(`
1799
+ `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function Rd(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?Vo(n.themeName,n.brandAssets):Ko(n.themeName,n.brandAssets),d=l?a?Hr(n.themeName,n.brandAssets):Lr(n.themeName,n.brandAssets):void 0,u=`## User Request
1655
1800
  ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1656
1801
 
1657
1802
  ## Current Shared CSS (update this)
1658
1803
  \`\`\`css
1659
1804
  ${n.sharedCss}
1660
- \`\`\``);let m=Sn(s),y=await _e(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:a?yr:gr,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}}),f;y.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=y.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
- ${Object.entries(S).map(([T,W])=>` ${T.startsWith("--")?T:`--${T}`}: ${W};`).join(`
1805
+ \`\`\``);let m=Bn(s),g=a?Ur:Jr,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{}})),f;h.type!=="structured"?(E.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,E.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1806
+ ${Object.entries(S).map(([$,F])=>` ${$.startsWith("--")?$:`--${$}`}: ${F};`).join(`
1662
1807
  `)}
1663
1808
  }
1664
1809
 
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(W=>b.toLowerCase().includes(W.toLowerCase())),T=I.filter(W=>!P.includes(W));T.length>0&&x.push(`Note: ${T.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let L=Object.keys(S||{}).length,G=a?[`Email design tokens: ${f.aesthetic||"created"} | ${L} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${L} variables, ${b.length} chars CSS`,...x];r({type:"agent_decision",step:"designing",decision:G.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 F=a?Hc(n.themeName,S||{},n.brandAssets,t.guidesNeeded):jc(n.themeName,b,n.brandAssets,t.guidesNeeded),K=`## User Request
1810
+ ${b}`));let v=[],w=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,M=[...new Set((e.match(w)||[]).map(T=>T.trim()))];if(M.length>0){let T=M.filter(F=>b.toLowerCase().includes(F.toLowerCase())),$=M.filter(F=>!T.includes(F));$.length>0&&v.push(`Note: ${$.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let L=Object.keys(S||{}).length,H=a?[`Email design tokens: ${f.aesthetic||"created"} | ${L} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${L} variables, ${b.length} chars CSS`,...v];r({type:"agent_decision",step:"designing",decision:H.join(`
1811
+ `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let B=a?Md(n.themeName,S||{},n.brandAssets,t.guidesNeeded):Td(n.themeName,b,n.brandAssets,t.guidesNeeded),K=`## User Request
1667
1812
  ${e}`;if(t.newModules.length>0&&(K+=`
1668
1813
 
1669
1814
  ## Planned Modules
1670
- ${t.newModules.map((P,T)=>`${T+1}. **${P.name}** \u2014 ${P.description}`).join(`
1671
- `)}`),n.modules.length>0){let P=new Set(t.affectedModules),T=n.modules.filter(ue=>P.has(ue.moduleName)),W=n.modules.filter(ue=>!P.has(ue.moduleName));T.length>0&&(K+=`
1815
+ ${t.newModules.map((T,$)=>`${$+1}. **${T.name}** \u2014 ${T.description}`).join(`
1816
+ `)}`),n.modules.length>0){let T=new Set(t.affectedModules),$=n.modules.filter(re=>T.has(re.moduleName)),F=n.modules.filter(re=>!T.has(re.moduleName));$.length>0&&(K+=`
1672
1817
 
1673
1818
  ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1674
1819
  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.
1675
- `+T.map(ue=>`- \`${ue.moduleName}\``).join(`
1676
- `)),W.length>0&&(K+=`
1820
+ `+$.map(re=>`- \`${re.moduleName}\``).join(`
1821
+ `)),F.length>0&&(K+=`
1677
1822
 
1678
1823
  ## Existing Modules to Keep (do not re-plan)
1679
1824
  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
- `+W.map(ue=>`- \`${ue.moduleName}\``).join(`
1681
- `))}let q=await _e(s,o,i,{systemPrompt:F,messages:[{role:"user",content:K}],structuredOutput:{schema:Dc,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{}}),N,C={modules:t.newModules.map(P=>({name:P.name,description:P.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(P=>P.name),narrative:"Page generated from user request"};if(q.type!=="structured")M.warn("page-architect","Module planner: did not get structured output, using fallback"),N=C;else{let P=q.data;Array.isArray(P?.modules)&&P.modules.length>0?(N=P,N.moduleOrder=N.moduleOrder||N.modules.map(T=>T.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=C),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 Vc=R(()=>{"use strict";h();st();Bc();Uc();ce()});function ch(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 zc(e,t,n,s,o){let i=ch(s),r=t.map(c=>`- **${c.label}** (${c.pageType}, slug: "${c.slug}"): ${c.purpose}`).join(`
1683
- `),a=n.map(c=>`- **${c}**`).join(`
1684
- `),l=[];return l.push(`You are the Site Module Planner for vibeSpot, a HubSpot CMS page builder.
1685
-
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
-
1688
- ## Theme: "${e}"
1689
-
1690
- ## Site Map
1691
- ${r}
1692
-
1693
- ## Shared Modules (appear on EVERY page)
1694
- ${a}
1695
-
1696
- Plan these shared modules ONCE. They will be automatically added to every page's template.
1697
-
1698
- ## Available CSS Classes & Variables
1699
- Reference these in your layoutNotes:
1700
-
1701
- ${i}
1702
-
1703
- ## Shared Module Rules
1704
-
1705
- ### site-header (Navigation)
1706
- - Logo on the left, nav links center or right, CTA button far right
1707
- - Nav links: one for each page in the site map. Use relative hrefs matching slugs:
1708
- ${t.map(c=>` - "${c.label}" \u2192 href="/${c.slug}"`).join(`
1709
- `)}
1710
- - Active page link uses CSS class "${e}-nav__link--active"
1711
- - Sticky with backdrop-blur, transitions on scroll
1712
- - Mobile: hamburger menu with slide-in nav
1713
-
1714
- ### site-footer
1715
- - Consistent across all pages
1716
- - Brand name, link columns (include page links), contact info, social icons, copyright
1717
- - Include navigation links matching the header
1718
-
1719
- ## Per-Page Module Rules
1720
- For each page, plan modules specific to that page's purpose. Do NOT include shared modules (${n.join(", ")}) in per-page module lists or per-page moduleOrder \u2014 they are automatically prepended/appended.
1721
-
1722
- Each page should have distinct content appropriate to its purpose. Aim for:
1723
- - 4-8 unique modules per page (not counting shared modules)
1724
- - Content appropriate to the page's purpose
1725
- - Consistent use of design system classes across all pages
1726
-
1727
- ## Module Naming
1728
- - Use kebab-case identifiers (e.g., "hero", "team-grid", "contact-form")
1729
- - Page-specific modules that might conflict across pages should be prefixed with a short page identifier (e.g., "home-hero", "about-hero") unless the content is genuinely different enough that the name alone distinguishes it
1730
- - Shared modules use the exact names from the shared modules list above
1731
-
1732
- ## Output Structure
1733
- Return a JSON object with:
1734
- - \`sharedModules\`: array of shared module specs (planned once, used everywhere)
1735
- - \`pages\`: array of per-page blueprints, each with:
1736
- - \`pageId\`: matching the page ID from the site map
1737
- - \`modules\`: array of module specs for that page only (excluding shared)
1738
- - \`moduleOrder\`: ordered list of per-page module names only (excluding shared)
1739
- - \`narrative\`: brief description of the overall site story/flow`),o?.brandvoice&&l.push(`
1825
+ `+F.map(re=>`- \`${re.moduleName}\``).join(`
1826
+ `))}let X=await te("module-planner",()=>Pe(s,o,i,{systemPrompt:B,messages:[{role:"user",content:K}],structuredOutput:{schema:Ad,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{}})),O,k={modules:t.newModules.map(T=>({name:T.name,description:T.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(T=>T.name),narrative:"Page generated from user request"};if(X.type!=="structured")E.warn("page-architect","Module planner: did not get structured output, using fallback"),O=k;else{let T=X.data;Array.isArray(T?.modules)&&T.modules.length>0?(O=T,O.moduleOrder=O.moduleOrder||O.modules.map($=>$.name),O.narrative=O.narrative||"Page generated from user request"):(E.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:T?Object.keys(T):[]}),O=k),E.info("page-architect","Module plan",{moduleCount:O.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${O.narrative} | ${O.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:O.modules,moduleOrder:O.moduleOrder,narrative:O.narrative}}var Od=N(()=>{"use strict";y();dt();Ed();Pd();le();Be()});function xy(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(`
1827
+ `)}function Fd(e,t,n,s,o){let i=xy(s),r=t.map(d=>`- **${d.label}** (${d.pageType}, slug: "${d.slug}"): ${d.purpose}`).join(`
1828
+ `),a=n.map(d=>`- **${d}**`).join(`
1829
+ `),l=[],c=t.map(d=>` - "${d.label}" \u2192 href="/${d.slug}"`).join(`
1830
+ `);return l.push(Rt("site-module-planner",{themeName:e,siteMap:r,sharedList:a,cssSummary:i,navHrefs:c,sharedModuleNamesCsv:n.join(", ")})),o?.brandvoice&&l.push(`
1740
1831
 
1741
1832
  ## Brand Voice
1742
1833
  ${o.brandvoice}`),o?.themeContext&&l.push(`
1743
1834
 
1744
1835
  ## Product Context
1745
- ${o.themeContext}`),l.join("")}var Yc,qc=R(()=>{"use strict";h();Yc={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(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=zc(n.themeName,l,c,s,n.brandAssets),u=`## User Request
1836
+ ${o.themeContext}`),l.join("")}var Dd,jd=N(()=>{"use strict";y();_s();Dd={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 Jd(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=Fd(n.themeName,l,c,s,n.brandAssets),u=`## User Request
1746
1837
  ${e}
1747
1838
 
1748
1839
  ## Site Map
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:Yc,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"),Xc(t,c,s);let y=g.data;if(!Array.isArray(y?.pages)||!Array.isArray(y?.sharedModules))return M.warn("site-planner","Structured output missing expected fields",{keys:y?Object.keys(y):[]}),Xc(t,c,s);let f=y.sharedModules.map(x=>({name:x.name,description:x.description,contentBrief:x.contentBrief,layoutNotes:x.layoutNotes})),b=y.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:y.narrative||"Multi-page site generated from user request"}}function Xc(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";h();st();qc();ce()});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 br=R(()=>{"use strict";h()});function cs(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1751
-
1752
- Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code.
1753
-
1754
- ## Theme: "${e}"
1755
-
1756
- ## Output Rules \u2014 CRITICAL
1757
- You produce a single module with these fields:
1758
- - **moduleName**: Exact module name (title-case, e.g., "Hero Banner")
1759
- - **fieldsJson**: Valid JSON string \u2014 the module's fields.json content
1760
- - **metaJson**: Valid JSON string \u2014 must include host_template_types: ["PAGE"], is_available_for_new_content: true
1761
- - **moduleHtml**: HubL template ({{ module.field_name }} syntax)
1762
- - **moduleCss**: Vanilla CSS (no Tailwind, no Sass, no CDN imports)
1763
- - **moduleJs**: Optional vanilla JS wrapped in IIFE, or null
1764
-
1765
- ## CSS Rules
1766
- - All CSS classes must use prefix "${e}-"
1767
- - Use BEM naming: ${e}-moduleName__element--modifier
1768
- - Reference the theme's CSS custom properties (shown below)
1769
- - No CDN imports (@import url(), external <link> tags)
1770
- - Use system font stacks \u2014 no Google Fonts
1771
-
1772
- ## Field Rules
1773
- - Use "type": "text" (NEVER "textarea" \u2014 it's deprecated)
1774
- - NEVER use "name": "name" (reserved) \u2014 use "item_name" instead
1775
- - NEVER use "name": "label" (reserved) \u2014 use "section_label" instead
1776
- - NEVER put literal \\n in field defaults
1777
- - Wrap style fields in a "styles" group with "tab": "STYLE"
1778
- - Color fields: type "color", default { "color": "#hex", "opacity": 100 }
1779
- - Link fields: type "link", default { "url": { "href": "#", "type": "EXTERNAL" }, "open_in_new_tab": false, "no_follow": false }
1780
- - Image fields: type "image", default { "src": "https://placehold.co/800x600/1a1a2e/ffffff?text=Replace+in+HubSpot", "alt": "Placeholder", "width": 800, "height": 600 }
1781
- - For repeater groups, use "occurrence": { "min": 0, "max": 100 }
1782
-
1783
- ## Images & Assets
1784
- - Use get_asset_url("${e}/assets/filename.ext") for uploaded assets
1785
- - For placeholder images, use image fields with placehold.co defaults
1786
- - Size placeholders appropriately (hero: 1920x800, cards: 600x400, icons: 200x200)
1787
-
1788
- ## Navigation & Anchors
1789
- - Add id attribute on module root element: id="module-name-lowercased"
1790
- - For nav modules, use anchor links (#features, #pricing, etc.)
1791
- - Include smooth scroll behavior in nav click handlers
1792
-
1793
- ## metaJson Template
1794
- { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`),t&&o.push(`
1840
+ ${l.map(v=>`- ${v.label} (${v.slug}): ${v.purpose}`).join(`
1841
+ `)}`,m=Bn(o),g=await te("site-module-planner",()=>Pe(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:Dd,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"),Ld(t,c,s);let h=g.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return E.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),Ld(t,c,s);let f=h.sharedModules.map(v=>({name:v.name,description:v.description,contentBrief:v.contentBrief,layoutNotes:v.layoutNotes})),b=h.pages.map(v=>({pageId:v.pageId,modules:(v.modules||[]).map(w=>({name:w.name,description:w.description,contentBrief:w.contentBrief,layoutNotes:w.layoutNotes})),moduleOrder:v.moduleOrder||[]})),S=f.length+b.reduce((v,w)=>v+w.modules.length,0);return E.info("site-planner","Site plan complete",{pages:b.length,sharedModules:f.length,totalModules:S}),a({type:"agent_decision",step:"planning_site",decision:`${b.length} pages planned, ${f.length} shared modules, ${S} total modules`}),a({type:"site_blueprint_ready",pages:b.map(v=>{let w=l.find(M=>M.id===v.pageId);return{pageId:v.pageId,label:w?.label||v.pageId,moduleCount:v.modules.length}}),sharedModuleCount:f.length}),{designSystem:{cssVariables:{},sharedCss:s},pages:b,sharedModules:f,narrative:h.narrative||"Multi-page site generated from user request"}}function Ld(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 Bd=N(()=>{"use strict";y();dt();jd();le();Be()});function zo(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=N(()=>{"use strict";y()});function $s(e,t,n,s){let o=[];return o.push(Rt("module-developer",{themeName:e})),t&&o.push(`
1795
1842
 
1796
1843
  ## Theme Shared CSS (use these custom properties)
1797
1844
  \`\`\`css
@@ -1799,29 +1846,29 @@ ${t}
1799
1846
  \`\`\``),(!n||n.includes("hubspot_rules"))&&o.push(`
1800
1847
 
1801
1848
  ## HubSpot CMS Rules
1802
- ${je()}`),(!n||n.includes("conversion"))&&o.push(`
1849
+ ${Je()}`),(!n||n.includes("conversion"))&&o.push(`
1803
1850
 
1804
1851
  ## Conversion Guide
1805
- ${fe()}`),s?.themeContext&&o.push(`
1852
+ ${ye()}`),s?.themeContext&&o.push(`
1806
1853
 
1807
1854
  ## Product Context
1808
1855
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1809
1856
 
1810
1857
  ## Anti-AI Copy Rules
1811
- ${ed()}`),o.join("")}function Eo(e,t,n,s){let o=[],i=cs(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1858
+ ${Hd()}`),o.join("")}function Yo(e,t,n,s){let o=[],i=$s(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1812
1859
 
1813
1860
  ## Theme Shared CSS (use these custom properties)
1814
1861
  \`\`\`css
1815
1862
  ${t}
1816
1863
  \`\`\``),o.push({type:"text",text:i});let r=[];(!n||n.includes("hubspot_rules"))&&r.push(`## HubSpot CMS Rules
1817
- ${je()}`),(!n||n.includes("conversion"))&&r.push(`## Conversion Guide
1818
- ${fe()}`),r.length>0&&o.push({type:"text",text:r.join(`
1864
+ ${Je()}`),(!n||n.includes("conversion"))&&r.push(`## Conversion Guide
1865
+ ${ye()}`),r.length>0&&o.push({type:"text",text:r.join(`
1819
1866
 
1820
1867
  `),cache_control:{type:"ephemeral"}});let a=[];return s?.themeContext&&a.push(`## Product Context
1821
1868
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&a.push(`## Anti-AI Copy Rules
1822
- ${ed()}`),a.length>0&&o.push({type:"text",text:a.join(`
1869
+ ${Hd()}`),a.length>0&&o.push({type:"text",text:a.join(`
1823
1870
 
1824
- `)}),o}function ed(){return`### Banned Punctuation
1871
+ `)}),o}function Hd(){return`### Banned Punctuation
1825
1872
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1826
1873
  - **Semicolons**: Use periods instead in marketing copy.
1827
1874
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1860,7 +1907,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1860
1907
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1861
1908
  - Full names, specific roles (not "John D., CEO")
1862
1909
  - Never start with "This product is..." \u2014 start with the person's situation
1863
- - Vary length and voice across testimonials`}function td(e,t,n){let s=[];return s.push(`## User Request
1910
+ - Vary length and voice across testimonials`}function Ud(e,t,n){let s=[];return s.push(`## User Request
1864
1911
  ${e}`),s.push(`
1865
1912
 
1866
1913
  ## Module Specification
@@ -1887,7 +1934,7 @@ ${n.moduleCss}
1887
1934
  **module.js:**
1888
1935
  \`\`\`js
1889
1936
  ${n.moduleJs}
1890
- \`\`\``)),s.join("")}var ds,Sr=R(()=>{"use strict";h();Ge();ds={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 vr(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1937
+ \`\`\``)),s.join("")}var Es,Wr=N(()=>{"use strict";y();Ke();_s();Es={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 Kr(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1891
1938
 
1892
1939
  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
1940
 
@@ -2045,17 +2092,17 @@ Modules that serve as email footers MUST include:
2045
2092
  ${t.themeContext}`),t?.humanify!==!1&&n.push(`
2046
2093
 
2047
2094
  ## Anti-AI Copy Rules
2048
- ${sd()}`),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(`
2095
+ ${Wd()}`),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
2096
 
2050
2097
  ## Brand Kit \u2014 MANDATORY Design Constraints
2051
2098
  The following brand identity values MUST be used. Do NOT substitute or override them:
2052
2099
  ${s.join(`
2053
- `)}`)}return n.join("")}function nd(e,t){let n=[],s=vr(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=Fa()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2100
+ `)}`)}return n.join("")}function Gd(e,t){let n=[],s=Kr(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=fl()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2054
2101
  ${o}`,cache_control:{type:"ephemeral"}});let i=[];return t?.themeContext&&i.push(`## Product Context
2055
2102
  ${t.themeContext}`),t?.humanify!==!1&&i.push(`## Anti-AI Copy Rules
2056
- ${sd()}`),i.length>0&&n.push({type:"text",text:i.join(`
2103
+ ${Wd()}`),i.length>0&&n.push({type:"text",text:i.join(`
2057
2104
 
2058
- `)}),n}function sd(){return`### Banned Punctuation
2105
+ `)}),n}function Wd(){return`### Banned Punctuation
2059
2106
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2060
2107
  - **Semicolons**: Use periods instead.
2061
2108
  - **Exclamation marks**: One per email max. Zero ideal for B2B.
@@ -2074,7 +2121,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2074
2121
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2075
2122
  - Use plain words: use > utilize, start > commence, help > facilitate
2076
2123
  - Front-load the benefit in the first 5 words
2077
- - Email subject lines: specific, benefit-first, under 50 chars`}function od(e,t,n){let s=[];return s.push(`## User Request
2124
+ - Email subject lines: specific, benefit-first, under 50 chars`}function Kd(e,t,n){let s=[];return s.push(`## User Request
2078
2125
  ${e}`),s.push(`
2079
2126
 
2080
2127
  ## Email Module Specification
@@ -2094,7 +2141,7 @@ ${n.fieldsJson}
2094
2141
  **module.html:**
2095
2142
  \`\`\`html
2096
2143
  ${n.moduleHtml}
2097
- \`\`\``),s.join("")}var id,rd=R(()=>{"use strict";h();Ge();id={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 xr(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
2144
+ \`\`\``),s.join("")}var Vd,zd=N(()=>{"use strict";y();Ke();Vd={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 Vr(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
2098
2145
 
2099
2146
  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
2147
 
@@ -2279,22 +2326,22 @@ The blog post body module wraps \`{{ content.post_body }}\` with reading-optimiz
2279
2326
  ${s.themeContext}`),s?.humanify!==!1&&o.push(`
2280
2327
 
2281
2328
  ## Anti-AI Copy Rules
2282
- ${ld()}`);let i=[];if(n?.includes("conversion"))try{let r=fe();r&&i.push(`## Conversion Guide
2283
- ${r}`)}catch{}if(n?.includes("hubspot_rules"))try{let r=je();r&&i.push(`## HubSpot Rules
2329
+ ${qd()}`);let i=[];if(n?.includes("conversion"))try{let r=ye();r&&i.push(`## Conversion Guide
2330
+ ${r}`)}catch{}if(n?.includes("hubspot_rules"))try{let r=Je();r&&i.push(`## HubSpot Rules
2284
2331
  ${r}`)}catch{}return i.length>0&&o.push(`
2285
2332
 
2286
2333
  ${i.join(`
2287
2334
 
2288
- `)}`),o.join("")}function ad(e,t,n,s){let o=[],i=xr(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=ja()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2289
- ${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=fe();c&&a.push(`## Conversion Guide
2290
- ${c}`)}catch{}if(n?.includes("hubspot_rules"))try{let c=je();c&&a.push(`## HubSpot Rules
2335
+ `)}`),o.join("")}function Yd(e,t,n,s){let o=[],i=Vr(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=hl()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2336
+ ${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=ye();c&&a.push(`## Conversion Guide
2337
+ ${c}`)}catch{}if(n?.includes("hubspot_rules"))try{let c=Je();c&&a.push(`## HubSpot Rules
2291
2338
  ${c}`)}catch{}a.length>0&&o.push({type:"text",text:a.join(`
2292
2339
 
2293
2340
  `),cache_control:{type:"ephemeral"}});let l=[];return s?.themeContext&&l.push(`## Product Context
2294
2341
  ${s.themeContext}`),s?.humanify!==!1&&l.push(`## Anti-AI Copy Rules
2295
- ${ld()}`),l.length>0&&o.push({type:"text",text:l.join(`
2342
+ ${qd()}`),l.length>0&&o.push({type:"text",text:l.join(`
2296
2343
 
2297
- `)}),o}function ld(){return`### Banned Punctuation
2344
+ `)}),o}function qd(){return`### Banned Punctuation
2298
2345
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2299
2346
  - **Semicolons**: Use periods instead.
2300
2347
  - **Exclamation marks**: Maximum one per page. Zero ideal for B2B.
@@ -2313,7 +2360,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2313
2360
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2314
2361
  - Use plain words: use > utilize, start > commence, help > facilitate
2315
2362
  - Front-load the benefit in the first 5 words
2316
- - Blog headlines: specific, benefit-first, no clickbait`}function cd(e,t,n){let s=[];return s.push(`## User Request
2363
+ - Blog headlines: specific, benefit-first, no clickbait`}function Xd(e,t,n){let s=[];return s.push(`## User Request
2317
2364
  ${e}`),s.push(`
2318
2365
 
2319
2366
  ## Blog Module Specification
@@ -2338,17 +2385,17 @@ ${n.moduleHtml}
2338
2385
  **module.css:**
2339
2386
  \`\`\`css
2340
2387
  ${n.moduleCss}
2341
- \`\`\``),s.join("")}var dd,ud=R(()=>{"use strict";h();Ge();Ge();dd={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 us(e,t,n,s,o,i,r,a,l,c,d,u){let m=u==="email",g=u==="blog",y=m?"email module":g?"blog module":"module";l({type:"agent_step",step:"developing",label:`Generating ${t.length} ${y}${t.length===1?"":"s"}...`});let f=o==="anthropic-api"||o==="claude-oauth",b=m?vr(s,d):g?xr(s,n,c,d):cs(s,n,c,d),S=f?m?nd(s,d):g?ad(s,n,c,d):Eo(s,n,c,d):void 0,x=_o(a),v=t.length,I=m?id:g?dd:ds,L=t.map((F,K)=>x(async()=>{l({type:"module_progress",module:F.name,status:"generating",current:K+1,total:v});let q="";for(let N=0;N<2;N++)try{N>0&&(M.warn("module-developer",`${F.name}: retrying after failure (attempt ${N+1})`),l({type:"module_progress",module:F.name,status:"retrying",current:K+1,total:v}));let C=await md(e,F,b,o,i,r,0,S,m,I,g);return l({type:"module_progress",module:F.name,status:"complete",current:K+1,total:v,moduleFiles:C}),{moduleName:F.name,module:C}}catch(C){q=C instanceof Error?C.message:typeof C=="object"&&C!==null?JSON.stringify(C):String(C),M.error("module-developer",`Failed: ${F.name} (attempt ${N+1})`,{error:q})}return l({type:"module_progress",module:F.name,status:"failed",current:K+1,total:v}),{moduleName:F.name,error:q}}));return(await Promise.allSettled(L)).map(F=>F.status==="fulfilled"?F.value:{moduleName:"unknown",error:F.reason instanceof Error?F.reason.message:String(F.reason)})}async function md(e,t,n,s,o,i,r=0,a,l=!1,c=ds,d=!1){let u=l?od(e,t,t.existingCode):d?cd(e,t,t.existingCode):td(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}`),md(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,y=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:y,metaJson:f,moduleHtml:String(g.moduleHtml||""),moduleCss:l?"":String(g.moduleCss||""),moduleJs:l?void 0:g.moduleJs?String(g.moduleJs):void 0}}var pd=R(()=>{"use strict";h();st();br();Sr();rd();ud();ce()});function Yt(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=gd(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=gd(c.metaJson,c.moduleName,"metaJson",l,i,r);let d={};c.fieldsJson=uh(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=mh(c.moduleHtml,d),c.fieldsJson=ph(c.fieldsJson,c.moduleName,l),i?c=Ch(c,l):(c.moduleCss=gh(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=hh(c.moduleCss,c.moduleName,t,l),c.moduleHtml=yh(c.moduleHtml,c.moduleName,t,l),r&&(c=kh(c,l))),c.moduleHtml=Sh(c.moduleHtml,c.moduleName,l),c.metaJson=vh(c.metaJson,c.moduleName,l,i,r),o&&wh(c,o,l);let u=l.every(m=>m.autoFixed);return l.length>0&&M.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(m=>m.autoFixed).length,unfixed:l.filter(m=>!m.autoFixed).length}),{module:c,issues:l,valid:u}})}function gd(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 uh(e,t,n,s){let o=e;for(let[i,r]of dh)new RegExp(`"name"\\s*:\\s*"${i}"`,"g").test(o)&&(n.push({module:t,field:"fieldsJson",message:`"${i}" is a reserved field name \u2192 renamed to "${r}"`,autoFixed:!0}),o=o.replace(new RegExp(`"name"\\s*:\\s*"${i}"`,"g"),`"name": "${r}"`),s[i]=r);return o}function mh(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`module\\.${s}\\b`,"g"),`module.${o}`);return n}function ph(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 gh(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 fd(e){return fh.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function hh(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)&&!fd(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${bh(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 yh(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((y,f)=>f%2===1?y:y.split(/(\s+)/).map(b=>/^\s*$/.test(b)?b:b&&!b.startsWith(o)&&!fd(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 bh(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Sh(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,y=>y.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 y=u[1],f=!y.startsWith("end"),b=f?y:y.replace("end","");d.push({tag:y,isOpen:f,baseTag:b,start:u.index,end:u.index+u[0].length})}let m=[],g=[];for(let y=0;y<d.length;y++)if(d[y].isOpen)m.push(y);else{let f=-1;for(let b=m.length-1;b>=0;b--)if(d[m[b]].baseTag===d[y].baseTag){f=b;break}f!==-1?m.splice(f,1):g.push(y)}if(g.length>0){for(let y=g.length-1;y>=0;y--){let f=d[g[y]];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 y=m.map(b=>d[b].baseTag),f=y.reverse().map(b=>`{% end${b} %}`).join(`
2388
+ \`\`\``),s.join("")}var Zd,Qd=N(()=>{"use strict";y();Ke();Ke();Zd={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types 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 Ms(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?Kr(s,d):g?Vr(s,n,c,d):$s(s,n,c,d),S=f?m?Gd(s,d):g?Yd(s,n,c,d):Yo(s,n,c,d):void 0,v=zo(a),w=t.length,M=m?Vd:g?Zd:Es,L=t.map((B,K)=>v(async()=>{l({type:"module_progress",module:B.name,status:"generating",current:K+1,total:w});let X="";for(let O=0;O<2;O++)try{O>0&&(E.warn("module-developer",`${B.name}: retrying after failure (attempt ${O+1})`),l({type:"module_progress",module:B.name,status:"retrying",current:K+1,total:w}));let k=await eu(e,B,b,o,i,r,0,S,m,M,g);return l({type:"module_progress",module:B.name,status:"complete",current:K+1,total:w,moduleFiles:k}),{moduleName:B.name,module:k}}catch(k){X=k instanceof Error?k.message:typeof k=="object"&&k!==null?JSON.stringify(k):String(k),E.error("module-developer",`Failed: ${B.name} (attempt ${O+1})`,{error:X})}return l({type:"module_progress",module:B.name,status:"failed",current:K+1,total:w}),{moduleName:B.name,error:X}}));return(await Promise.allSettled(L)).map(B=>B.status==="fulfilled"?B.value:{moduleName:"unknown",error:B.reason instanceof Error?B.reason.message:String(B.reason)})}async function eu(e,t,n,s,o,i,r=0,a,l=!1,c=Es,d=!1){let u=l?Kd(e,t,t.existingCode):d?Xd(e,t,t.existingCode):Ud(e,t,t.existingCode),m=await Pe(s,o,i,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:u}],structuredOutput:{schema:c,name:"module_output"},maxTokens:16e3});if(m.type!=="structured"){if(r<2)return E.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),eu(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 tu=N(()=>{"use strict";y();dt();Gr();Wr();zd();Qd();le()});function ln(e,t,n,s,o){let i=s==="email",r=s==="blog";return n({type:"agent_step",step:"quality_check",label:i?"Email quality check...":r?"Blog quality check...":"Quality check..."}),e.map(a=>{let l=[],c={...a};c.fieldsJson=nu(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=nu(c.metaJson,c.moduleName,"metaJson",l,i,r);let d={};c.fieldsJson=Cy(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=ky(c.moduleHtml,d),c.fieldsJson=Ty(c.fieldsJson,c.moduleName,l),i?c=Fy(c,l):(c.moduleCss=Ay(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=$y(c.moduleCss,c.moduleName,t,l),c.moduleHtml=Ey(c.moduleHtml,c.moduleName,t,l),r&&(c=Dy(c,l))),c.moduleHtml=Iy(c.moduleHtml,c.moduleName,l),i||Py(c,l),c.metaJson=Ny(c.metaJson,c.moduleName,l,i,r),o&&Oy(c,o,l);let u=l.every(m=>m.autoFixed);return l.length>0&&E.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(m=>m.autoFixed).length,unfixed:l.filter(m=>!m.autoFixed).length}),{module:c,issues:l,valid:u}})}function nu(e,t,n,s,o=!1,i=!1){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0}):e):ct(e)===null?(s.push({module:t,field:n,message:`Invalid JSON in ${n} \u2014 reset to empty`,autoFixed:!0}),n==="fieldsJson"?"[]":JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0})):e}function Cy(e,t,n,s){let o=e;for(let[i,r]of wy)new RegExp(`"name"\\s*:\\s*"${i}"`,"g").test(o)&&(n.push({module:t,field:"fieldsJson",message:`"${i}" is a reserved field name \u2192 renamed to "${r}"`,autoFixed:!0}),o=o.replace(new RegExp(`"name"\\s*:\\s*"${i}"`,"g"),`"name": "${r}"`),s[i]=r);return o}function ky(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`module\\.${s}\\b`,"g"),`module.${o}`);return n}function Ty(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 Ay(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 ou(e){return _y.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function $y(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)&&!ou(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${My(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 Ey(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)&&!ou(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 My(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Iy(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
2389
  `);s=`${s}
2343
- ${f}`,n.push({module:t,field:"moduleHtml",message:`Added ${y.length} missing closing tag${y.length===1?"":"s"}: ${y.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 vh(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 hd(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 wh(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(xh))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 Ch(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 kh(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 dh,fh,xh,wr=R(()=>{"use strict";h();Co();ce();dh=[["name","item_name"],["label","section_label"],["body","body_text"]];fh=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);xh=/#[0-9a-fA-F]{6}\b/g});import{execSync as Th}from"child_process";async function yd(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(vn(n)){let C={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(C)try{Th(`command -v ${C}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${C}" to be installed and on your PATH.`)}}let d=await Nc(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 Ah(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 Kc(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 C=t.modules.find(P=>P.moduleName===N);C&&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:C})}}let b=[],S=[];if(f.length>0){let N=await us(e,f,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType);for(let C of N)C.module?b.push(C.module):S.push(C.moduleName)}let x=null;if(b.length>0){x=Yt(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit);let N=x.filter(P=>P.issues.some(T=>T.field==="fieldsJson"&&T.message.includes("reset to empty"))).map(P=>P.module.moduleName);if(N.length>0){let P=N.map(T=>f.find(W=>W.name===T)).filter(T=>T!=null);if(P.length>0){M.info("pipeline",`Retrying ${P.length} module(s) with broken fieldsJson: ${P.map(W=>W.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${P.length} module(s) with invalid fields JSON...`});let T=await us(e,P,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType);for(let W of T)if(W.module){let ue=b.findIndex(Xe=>Xe.moduleName===W.moduleName);ue>=0&&(b[ue]=W.module)}x=Yt(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit)}}b=x.map(P=>P.module);let C=x.reduce((P,T)=>P+T.issues.length,0);if(C>0){let P=x.reduce((W,ue)=>W+ue.issues.filter(Xe=>Xe.autoFixed).length,0);M.info("pipeline",`Quality check: ${C} issues, ${P} auto-fixed`);let T=x.flatMap(W=>W.issues).map(W=>`${W.autoFixed?"\u2713":"\u26A0"} ${W.module}: ${W.message}`).join(`
2344
- `);r({type:"agent_decision",step:"quality_check",decision:`${C} issues found, ${P} auto-fixed
2345
- ${T}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let v=_h(t,d,b,u,a),I=Eh(t,d,u,v);if(u?.moduleOrder?.length){let N=new Set(u.moduleOrder),C=v.filter(P=>!N.has(P.moduleName)).map(P=>P.moduleName);C.length>0&&r({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${C.length} module${C.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${C.join(", ")}`})}let L=Date.now()-l,G=b.length,F=d.unchangedModules.length,K=x?x.flatMap(N=>N.issues):[],q=Mh(d,G,F,S,L,u,K);return S.length>0?r({type:"pipeline_partial",succeeded:b.map(N=>N.moduleName),failed:S,durationMs:L}):r({type:"pipeline_complete",modulesGenerated:G,modulesUnchanged:F,durationMs:L,assistantMessage:q}),{modules:v,moduleOrder:I,sharedCss:m,sharedJs:g,assistantMessage:q,contentType:d.contentType,stats:{modulesGenerated:G,modulesUnchanged:F,modulesFailed:S.length,durationMs:L}}}async function Ah(e,t,n,s,o,i,r,a,l){let c=t.pages,d=t.sharedModules||["site-header","site-footer"],u=await Wc(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 y=await Zc(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 T of y.sharedModules)f.push({...T});for(let T of y.pages)for(let W of T.modules)f.push({name:W.name,description:W.description,contentBrief:W.contentBrief,layoutNotes:W.layoutNotes});let b=c.map(T=>`- "${T.label}" \u2192 /${T.slug}`).join(`
2346
- `);for(let T of f)(T.name.includes("header")||T.name.includes("nav"))&&(T.layoutNotes+=`
2390
+ ${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 su(e){if(!e)return[];let t=[],n=/\b(rgba?|hsla?)\(([^()]*)\)/gi,s;for(;(s=n.exec(e))!==null;){let o=s[2];(o.trim()===""||o.split(",").some(i=>i.trim()===""))&&t.push(s[0].trim())}return t}function Py(e,t){let n=ct(e.fieldsJson),s=Array.isArray(n)?rn(n):{},o=e.moduleHtml||"";try{o=jn(e.moduleHtml||"",{module:s})}catch{}let i=[...su(o),...su(e.moduleCss||"")];if(i.length===0)return;let r=i[0].length>60?i[0].slice(0,57)+"\u2026":i[0];t.push({module:e.moduleName,field:"moduleCss",message:`${i.length} invalid CSS color value${i.length===1?"":"s"} (e.g. \`${r}\`) \u2014 renders unstyled. A style field with no default is likely fed into rgba()/hsla().`,autoFixed:!1,code:"invalid-css"})}function Ny(e,t,n,s=!1,o=!1){let i=ct(e);if(!i||typeof i!="object")return e;let r=i,a=!1;if(r.host_template_types){if(s)r.host_template_types.includes("EMAIL")||(r.host_template_types=["EMAIL"],a=!0,n.push({module:t,field:"metaJson",message:'Fixed host_template_types to ["EMAIL"] for email module',autoFixed:!0}));else if(o){let l=r.host_template_types;l.includes("BLOG_POST")||l.includes("BLOG_LISTING")||(r.host_template_types=["BLOG_POST"],a=!0,n.push({module:t,field:"metaJson",message:"Fixed host_template_types to include blog type for blog module",autoFixed:!0}))}}else{let l=s?"EMAIL":o?"BLOG_POST":"PAGE";r.host_template_types=[l],a=!0}return r.is_available_for_new_content===void 0&&(r.is_available_for_new_content=!0,a=!0),a?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(r,null,2)):e}function iu(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 Oy(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(Ry))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 Fy(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 Dy(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 wy,_y,Ry,zr=N(()=>{"use strict";y();Uo();le();yr();wy=[["name","item_name"],["label","section_label"],["body","body_text"]];_y=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);Ry=/#[0-9a-fA-F]{6}\b/g});import{execSync as jy}from"child_process";async function ru(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(Hn(n)){let k={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(k)try{jy(`command -v ${k}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${k}" to be installed and on your PATH.`)}}let d=await wd(e,t,n,s,o,r,a);if(d.intent==="question"&&d.answer){let O=Date.now()-l;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:O,answer:d.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:O}}}if(d.intent==="create_site"&&d.pages&&d.pages.length>0)return Ly(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 Rd(e,d,t,n,s,o,r),d.contentType!=="email"&&(m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g),r({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let f=[];if(u)for(let O of u.modules)f.push({name:O.name,description:O.description,contentBrief:O.contentBrief,layoutNotes:O.layoutNotes});else{for(let O of d.newModules)f.push({name:O.name,description:O.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let O of d.affectedModules){let k=t.modules.find(T=>T.moduleName===O);k&&f.push({name:O,description:`Modify existing module: ${O}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:k})}}let b=[],S=[];if(f.length>0){let O=await te("module-development",()=>Ms(e,f,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:f.length}});for(let k of O)k.module?b.push(k.module):S.push(k.moduleName)}let v=null;if(b.length>0){v=ln(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit);let O=v.filter(T=>T.issues.some($=>$.field==="fieldsJson"&&$.message.includes("reset to empty"))).map(T=>T.module.moduleName);if(O.length>0){let T=O.map($=>f.find(F=>F.name===$)).filter($=>$!=null);if(T.length>0){E.info("pipeline",`Retrying ${T.length} module(s) with broken fieldsJson: ${T.map(F=>F.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${T.length} module(s) with invalid fields JSON...`});let $=await te("module-development-retry",()=>Ms(e,T,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:T.length}});for(let F of $)if(F.module){let re=b.findIndex(_e=>_e.moduleName===F.moduleName);re>=0&&(b[re]=F.module)}v=ln(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit)}}b=v.map(T=>T.module);let k=v.reduce((T,$)=>T+$.issues.length,0);if(k>0){let T=v.reduce((F,re)=>F+re.issues.filter(_e=>_e.autoFixed).length,0);E.info("pipeline",`Quality check: ${k} issues, ${T} auto-fixed`);let $=v.flatMap(F=>F.issues).map(F=>`${F.autoFixed?"\u2713":"\u26A0"} ${F.module}: ${F.message}`).join(`
2391
+ `);r({type:"agent_decision",step:"quality_check",decision:`${k} issues found, ${T} auto-fixed
2392
+ ${$}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let w=By(t,d,b,u,a),M=Hy(t,d,u,w);if(u?.moduleOrder?.length){let O=new Set(u.moduleOrder),k=w.filter(T=>!O.has(T.moduleName)).map(T=>T.moduleName);k.length>0&&r({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${k.length} module${k.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${k.join(", ")}`})}let L=Date.now()-l,H=b.length,B=d.unchangedModules.length,K=v?v.flatMap(O=>O.issues):[],X=Uy(d,H,B,S,L,u,K);return S.length>0?r({type:"pipeline_partial",succeeded:b.map(O=>O.moduleName),failed:S,durationMs:L}):r({type:"pipeline_complete",modulesGenerated:H,modulesUnchanged:B,durationMs:L,assistantMessage:X}),{modules:w,moduleOrder:M,sharedCss:m,sharedJs:g,assistantMessage:X,contentType:d.contentType,stats:{modulesGenerated:H,modulesUnchanged:B,modulesFailed:S.length,durationMs:L}}}async function Ly(e,t,n,s,o,i,r,a,l){let c=t.pages,d=t.sharedModules||["site-header","site-footer"],u=await Nd(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 Jd(e,t,n,m,s,o,i,a);a({type:"agent_step",step:"developing",label:`Generating modules for ${c.length} pages...`});let f=[];for(let $ of h.sharedModules)f.push({...$});for(let $ of h.pages)for(let F of $.modules)f.push({name:F.name,description:F.description,contentBrief:F.contentBrief,layoutNotes:F.layoutNotes});let b=c.map($=>`- "${$.label}" \u2192 /${$.slug}`).join(`
2393
+ `);for(let $ of f)($.name.includes("header")||$.name.includes("nav"))&&($.layoutNotes+=`
2347
2394
 
2348
2395
  ## Site Navigation
2349
2396
  This is a multi-page site. Include navigation links to all pages:
2350
2397
  ${b}
2351
- Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await us(e,f,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),x=[],v=[];for(let T of S)T.module?x.push(T.module):v.push(T.moduleName);let I=x,L=[];if(x.length>0){let T=Yt(x,n.themeName,a,t.contentType,n.brandAssets?.brandKit),W=T.filter(Q=>Q.issues.some(ye=>ye.field==="fieldsJson"&&ye.message.includes("reset to empty"))).map(Q=>Q.module.moduleName);if(W.length>0){let Q=W.map(ye=>f.find(ae=>ae.name===ye)).filter(ye=>ye!=null);if(Q.length>0){M.info("pipeline",`Retrying ${Q.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${Q.length} module(s) with invalid fields JSON...`});let ye=await us(e,Q,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType);for(let ae of ye)if(ae.module){let Je=x.findIndex(Cs=>Cs.moduleName===ae.moduleName);Je>=0&&(x[Je]=ae.module)}T=Yt(x,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}I=T.map(Q=>Q.module),L=T.flatMap(Q=>Q.issues);let ue=hd(I,c.map(Q=>Q.slug));L.push(...ue);let Xe=L.length;if(Xe>0){let Q=L.filter(ye=>ye.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${Xe} issues found, ${Q} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let G=new Map(I.map(T=>[T.moduleName,T])),F=y.sharedModules.map(T=>G.get(T.name)).filter(T=>!!T),K=new Map(c.map(T=>[T.id,T])),q=y.pages.map(T=>{let W=T.modules.map(ae=>G.get(ae.name)).filter(ae=>!!ae),ue=d.filter(ae=>ae.includes("header")||ae.includes("nav")),Xe=d.filter(ae=>ae.includes("footer")),Q=[...ue,...T.moduleOrder,...Xe],ye=K.get(T.pageId);return{pageId:T.pageId,templateId:T.pageId,label:ye?.label||T.pageId,pageType:ye?.pageType||"website_page",modules:[...F,...W],moduleOrder:Q}}),N=Date.now()-l,C=$h(c,x.length,v,N,y.narrative,L);return v.length>0?a({type:"pipeline_partial",succeeded:x.map(T=>T.moduleName),failed:v,durationMs:N}):a({type:"pipeline_complete",modulesGenerated:x.length,modulesUnchanged:0,durationMs:N,assistantMessage:C}),{modules:I,moduleOrder:I.map(T=>T.moduleName),sharedCss:m,sharedJs:g||"",assistantMessage:C,stats:{modulesGenerated:x.length,modulesUnchanged:0,modulesFailed:v.length,durationMs:N},multiPage:{pages:q,sharedModules:F,sharedCss:m,sharedJs:g||"",assistantMessage:C,stats:{pagesGenerated:c.length,modulesGenerated:x.length,modulesFailed:v.length,durationMs:N}}}}function $h(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(`
2398
+ Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await te("module-development",()=>Ms(e,f,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:f.length}}),v=[],w=[];for(let $ of S)$.module?v.push($.module):w.push($.moduleName);let M=v,L=[];if(v.length>0){let $=ln(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit),F=$.filter(z=>z.issues.some(ue=>ue.field==="fieldsJson"&&ue.message.includes("reset to empty"))).map(z=>z.module.moduleName);if(F.length>0){let z=F.map(ue=>f.find(ne=>ne.name===ue)).filter(ue=>ue!=null);if(z.length>0){E.info("pipeline",`Retrying ${z.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${z.length} module(s) with invalid fields JSON...`});let ue=await te("module-development-retry",()=>Ms(e,z,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:z.length}});for(let ne of ue)if(ne.module){let $e=v.findIndex(Bs=>Bs.moduleName===ne.moduleName);$e>=0&&(v[$e]=ne.module)}$=ln(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}M=$.map(z=>z.module),L=$.flatMap(z=>z.issues);let re=iu(M,c.map(z=>z.slug));L.push(...re);let _e=L.length;if(_e>0){let z=L.filter(ue=>ue.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${_e} issues found, ${z} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let H=new Map(M.map($=>[$.moduleName,$])),B=h.sharedModules.map($=>H.get($.name)).filter($=>!!$),K=new Map(c.map($=>[$.id,$])),X=h.pages.map($=>{let F=$.modules.map(ne=>H.get(ne.name)).filter(ne=>!!ne),re=d.filter(ne=>ne.includes("header")||ne.includes("nav")),_e=d.filter(ne=>ne.includes("footer")),z=[...re,...$.moduleOrder,..._e],ue=K.get($.pageId);return{pageId:$.pageId,templateId:$.pageId,label:ue?.label||$.pageId,pageType:ue?.pageType||"website_page",modules:[...B,...F],moduleOrder:z}}),O=Date.now()-l,k=Jy(c,v.length,w,O,h.narrative,L);return w.length>0?a({type:"pipeline_partial",succeeded:v.map($=>$.moduleName),failed:w,durationMs:O}):a({type:"pipeline_complete",modulesGenerated:v.length,modulesUnchanged:0,durationMs:O,assistantMessage:k}),{modules:M,moduleOrder:M.map($=>$.moduleName),sharedCss:m,sharedJs:g||"",assistantMessage:k,stats:{modulesGenerated:v.length,modulesUnchanged:0,modulesFailed:w.length,durationMs:O},multiPage:{pages:X,sharedModules:B,sharedCss:m,sharedJs:g||"",assistantMessage:k,stats:{pagesGenerated:c.length,modulesGenerated:v.length,modulesFailed:w.length,durationMs:O}}}}function Jy(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
2399
 
2353
2400
  **Pages:** ${e.map(d=>d.label).join(", ")}`),o&&a.push(`
2354
2401
 
@@ -2357,14 +2404,14 @@ ${o}`),n.length>0&&a.push(`
2357
2404
  **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
2405
 
2359
2406
  ${d.join(`
2360
- `)}`)}return a.join("")}function _h(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 Eh(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 Mh(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(`
2407
+ `)}`)}return a.join("")}function By(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 Hy(e,t,n,s){if(n?.moduleOrder?.length){let a=[...n.moduleOrder],l=new Set(a);for(let c of s)if(!l.has(c.moduleName)){let d=a.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?a.splice(d,0,c.moduleName):a.push(c.moduleName),l.add(c.moduleName),E.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return a}if(t.intent==="create")return s.map(a=>a.moduleName);let o=[...e.moduleOrder],i=[...t.newModules.map(a=>({name:a.name,position:a.position})),...(t.reuseModules||[]).map(a=>({name:a.name,position:a.position}))].sort((a,l)=>a.position-l.position);for(let a of i){let l=Math.min(a.position,o.length);o.splice(l,0,a.name)}let r=new Set(s.map(a=>a.moduleName));return o.filter(a=>r.has(a))}function Uy(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
2408
 
2362
2409
  ${i.narrative}`),s.length>0&&l.push(`
2363
2410
 
2364
2411
  **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
2412
 
2366
2413
  ${u.join(`
2367
- `)}`)}return l.join("")}var bd=R(()=>{"use strict";h();st();Oc();Vc();Qc();pd();wr();ce();st()});var Cd={};Be(Cd,{runFigmaConversion:()=>Ih});import{basename as xd}from"path";async function Ih(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}=Ph(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}=Nh(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 y=n==="anthropic-api"||n==="claude-oauth",f=cs(t,d,["hubspot_rules","conversion"],a),b=y?Eo(t,d,["hubspot_rules","conversion"],a):void 0,S=_o(i),x=m.length,v=m.map((T,W)=>{let ue=e.sections[W];return S(async()=>{r({type:"module_progress",module:T.name,status:"generating",current:W+1,total:x});let Xe=jh(ue,T,e.assets,t,l!==!1),Q="";for(let ye=0;ye<2;ye++)try{ye>0&&(M.warn("figma-pipeline",`${T.name}: retrying (attempt ${ye+1})`),r({type:"module_progress",module:T.name,status:"retrying",current:W+1,total:x}));let ae=await _e(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:Xe}],structuredOutput:{schema:ds,name:"module_output"},maxTokens:16e3});if(ae.type!=="structured")throw new Error("No structured output returned");let Je=ae.data,Cs={moduleName:T.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:T.name,status:"complete",current:W+1,total:x,moduleFiles:Cs}),{moduleName:T.name,module:Cs}}catch(ae){Q=ae instanceof Error?ae.message:String(ae),M.error("figma-pipeline",`Failed: ${T.name} (attempt ${ye+1}): ${Q}`)}return r({type:"module_progress",module:T.name,status:"failed",current:W+1,total:x}),{moduleName:T.name,error:Q}})}),L=(await Promise.allSettled(v)).map(T=>T.status==="fulfilled"?T.value:{moduleName:"unknown",error:String(T.reason)}),G=L.filter(T=>T.module).map(T=>T.module),F=L.filter(T=>T.error).map(T=>T.moduleName),q=Yt(G,t,r).map(T=>T.module),N=Date.now()-c,C=Math.round(N/1e3),P=`Imported ${q.length} modules from Figma design "${e.fileName}" in ${C}s.`;return F.length>0?r({type:"pipeline_partial",succeeded:q.map(T=>T.moduleName),failed:F,durationMs:N}):r({type:"pipeline_complete",modulesGenerated:q.length,modulesUnchanged:0,durationMs:N,assistantMessage:P}),{modules:q,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:P,stats:{modulesGenerated:q.length,modulesUnchanged:0,modulesFailed:F.length,durationMs:N}}}function Mo(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 Ph(e,t){let n=[],s=t,o=[...e.colors].sort((C,P)=>P.occurrences-C.occurrences),i=o.filter(C=>C.usage==="background"||C.usage==="fill"),r=o.filter(C=>C.usage==="text"),a=i[0]||o[0],l=a?Mo(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(C=>Mo(C.hex).l>.7):o.find(C=>Mo(C.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(C=>!d.has(C.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(C=>!d.has(C.hex)).slice(0,6).forEach((C,P)=>n.push(` --${s}-color-${P+1}: ${C.hex}`)),a){let C=Mo(a.hex).l;n.push(` --${s}-color-surface: ${l?Sd(a.hex,.05):vd(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?Sd(a.hex,.15):vd(a.hex,.12)}`)}let g=e.typography.filter(C=>C.role==="heading"||C.role==="subheading"),y=e.typography.filter(C=>C.role==="body"||C.role==="label"||C.role==="caption"),f=g[0]?.fontFamily||y[0]?.fontFamily||"system-ui",b=y[0]?.fontFamily||f;n.push(` --${s}-font-display: "${f}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let S=g.sort((C,P)=>P.fontSize-C.fontSize);S[0]&&n.push(` --${s}-size-h1: ${S[0].fontSize}px`),S[1]&&n.push(` --${s}-size-h2: ${S[1].fontSize}px`),S[2]&&n.push(` --${s}-size-h3: ${S[2].fontSize}px`);let x=y.sort((C,P)=>P.occurrences-C.occurrences)[0];x&&n.push(` --${s}-size-body: ${x.fontSize}px`);let v=[...new Set(e.spacing.map(C=>C.value))].sort((C,P)=>C-P),I=["xs","sm","md","lg","xl","2xl","section"];v.slice(0,I.length).forEach((C,P)=>{n.push(` --${s}-space-${I[P]}: ${C}px`)});let L=e.effects.filter(C=>C.type==="shadow"),G=e.effects.filter(C=>C.type==="radius");L[0]&&n.push(` --${s}-shadow: ${L[0].cssValue}`),G.sort((C,P)=>parseFloat(C.cssValue)-parseFloat(P.cssValue)),G[0]&&n.push(` --${s}-radius: ${G[0].cssValue}`),G[1]&&n.push(` --${s}-radius-lg: ${G[1].cssValue}`);let F=`:root {
2414
+ `)}`)}return l.join("")}var au=N(()=>{"use strict";y();dt();Cd();Od();Bd();tu();zr();le();Be();dt()});var mu={};Ge(mu,{runFigmaConversion:()=>Gy});import{basename as du}from"path";async function Gy(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}=Wy(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}=Vy(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=$s(t,d,["hubspot_rules","conversion"],a),b=h?Yo(t,d,["hubspot_rules","conversion"],a):void 0,S=zo(i),v=m.length,M=(await te("module-development",()=>{let T=m.map(($,F)=>{let re=e.sections[F];return S(async()=>{r({type:"module_progress",module:$.name,status:"generating",current:F+1,total:v});let _e=qy(re,$,e.assets,t,l!==!1),z="";for(let ue=0;ue<2;ue++)try{ue>0&&(E.warn("figma-pipeline",`${$.name}: retrying (attempt ${ue+1})`),r({type:"module_progress",module:$.name,status:"retrying",current:F+1,total:v}));let ne=await Pe(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:_e}],structuredOutput:{schema:Es,name:"module_output"},maxTokens:16e3});if(ne.type!=="structured")throw new Error("No structured output returned");let $e=ne.data,Bs={moduleName:$.name,fieldsJson:typeof $e.fieldsJson=="string"?$e.fieldsJson:JSON.stringify($e.fieldsJson,null,2),metaJson:typeof $e.metaJson=="string"?$e.metaJson:JSON.stringify($e.metaJson,null,2),moduleHtml:String($e.moduleHtml||""),moduleCss:String($e.moduleCss||""),moduleJs:$e.moduleJs?String($e.moduleJs):void 0};return r({type:"module_progress",module:$.name,status:"complete",current:F+1,total:v,moduleFiles:Bs}),{moduleName:$.name,module:Bs}}catch(ne){z=ne instanceof Error?ne.message:String(ne),E.error("figma-pipeline",`Failed: ${$.name} (attempt ${ue+1}): ${z}`)}return r({type:"module_progress",module:$.name,status:"failed",current:F+1,total:v}),{moduleName:$.name,error:z}})});return Promise.allSettled(T)},{metadata:{moduleCount:v}})).map(T=>T.status==="fulfilled"?T.value:{moduleName:"unknown",error:String(T.reason)}),L=M.filter(T=>T.module).map(T=>T.module),H=M.filter(T=>T.error).map(T=>T.moduleName),K=ln(L,t,r).map(T=>T.module),X=Date.now()-c,O=Math.round(X/1e3),k=`Imported ${K.length} modules from Figma design "${e.fileName}" in ${O}s.`;return H.length>0?r({type:"pipeline_partial",succeeded:K.map(T=>T.moduleName),failed:H,durationMs:X}):r({type:"pipeline_complete",modulesGenerated:K.length,modulesUnchanged:0,durationMs:X,assistantMessage:k}),{modules:K,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:k,stats:{modulesGenerated:K.length,modulesUnchanged:0,modulesFailed:H.length,durationMs:X}}}function qo(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 Wy(e,t){let n=[],s=t,o=[...e.colors].sort((k,T)=>T.occurrences-k.occurrences),i=o.filter(k=>k.usage==="background"||k.usage==="fill"),r=o.filter(k=>k.usage==="text"),a=i[0]||o[0],l=a?qo(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(k=>qo(k.hex).l>.7):o.find(k=>qo(k.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(k=>!d.has(k.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(k=>!d.has(k.hex)).slice(0,6).forEach((k,T)=>n.push(` --${s}-color-${T+1}: ${k.hex}`)),a){let k=qo(a.hex).l;n.push(` --${s}-color-surface: ${l?lu(a.hex,.05):cu(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?lu(a.hex,.15):cu(a.hex,.12)}`)}let g=e.typography.filter(k=>k.role==="heading"||k.role==="subheading"),h=e.typography.filter(k=>k.role==="body"||k.role==="label"||k.role==="caption"),f=g[0]?.fontFamily||h[0]?.fontFamily||"system-ui",b=h[0]?.fontFamily||f;n.push(` --${s}-font-display: "${f}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let S=g.sort((k,T)=>T.fontSize-k.fontSize);S[0]&&n.push(` --${s}-size-h1: ${S[0].fontSize}px`),S[1]&&n.push(` --${s}-size-h2: ${S[1].fontSize}px`),S[2]&&n.push(` --${s}-size-h3: ${S[2].fontSize}px`);let v=h.sort((k,T)=>T.occurrences-k.occurrences)[0];v&&n.push(` --${s}-size-body: ${v.fontSize}px`);let w=[...new Set(e.spacing.map(k=>k.value))].sort((k,T)=>k-T),M=["xs","sm","md","lg","xl","2xl","section"];w.slice(0,M.length).forEach((k,T)=>{n.push(` --${s}-space-${M[T]}: ${k}px`)});let L=e.effects.filter(k=>k.type==="shadow"),H=e.effects.filter(k=>k.type==="radius");L[0]&&n.push(` --${s}-shadow: ${L[0].cssValue}`),H.sort((k,T)=>parseFloat(k.cssValue)-parseFloat(T.cssValue)),H[0]&&n.push(` --${s}-radius: ${H[0].cssValue}`),H[1]&&n.push(` --${s}-radius-lg: ${H[1].cssValue}`);let B=`:root {
2368
2415
  ${n.join(`;
2369
2416
  `)};
2370
2417
  }`,K=`
@@ -2451,7 +2498,7 @@ body {
2451
2498
  h1 { font-size: 2rem; }
2452
2499
  h2 { font-size: 1.5rem; }
2453
2500
  h3 { font-size: 1.25rem; }
2454
- }`;return{sharedCss:F+`
2501
+ }`;return{sharedCss:B+`
2455
2502
  `+K,sharedJs:`(function() {
2456
2503
  var observer = new IntersectionObserver(function(entries) {
2457
2504
  entries.forEach(function(entry) {
@@ -2462,11 +2509,11 @@ body {
2462
2509
  });
2463
2510
  }, { threshold: 0.1 });
2464
2511
  document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
2465
- })();`}}function Sd(e,t){return wd(e,t)}function vd(e,t){return wd(e,-t)}function wd(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 Rh(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Nh(e,t,n){let s=new Set,o=[];for(let i of e){let r=Rh(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=Oh(i.textContent),l=Fh(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 Oh(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 Fh(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(`
2512
+ })();`}}function lu(e,t){return uu(e,t)}function cu(e,t){return uu(e,-t)}function uu(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 Ky(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Vy(e,t,n){let s=new Set,o=[];for(let i of e){let r=Ky(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=zy(i.textContent),l=Yy(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 zy(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(`
2513
+ `)}function Yy(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
2514
  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=xd(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2469
- `)}function jh(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
2515
+ Available image assets:`);for(let o of t){let i=du(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2516
+ `)}function qy(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
2470
2517
 
2471
2518
  TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
2472
2519
  - Use the EXACT text content from the design as field default values
@@ -2491,12 +2538,12 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
2491
2538
  ### 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
2539
  ### 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
2540
  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=xd(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2541
+ ### 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=du(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2495
2542
  ### 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
2543
  ## Module Specification
2497
2544
  - **Name**: ${t.name}
2498
2545
  - **Description**: ${t.description}`),i.join(`
2499
- `)}var kd=R(()=>{"use strict";h();st();br();Sr();wr();ce()});var Td={};Be(Td,{buildPlanModePrompt:()=>Dh});function Dh(e,t,n,s,o){let i=Lh(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
2546
+ `)}var pu=N(()=>{"use strict";y();dt();Gr();Wr();zr();le();Be()});var gu={};Ge(gu,{buildPlanModePrompt:()=>Xy});function Xy(e,t,n,s,o){let i=Zy(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
2500
2547
 
2501
2548
  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
2549
 
@@ -2565,15 +2612,15 @@ Drive toward filling these gaps in priority order:
2565
2612
  The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
2566
2613
 
2567
2614
  \`\`\`
2568
- ${Cr(t.styleguide,1500)}
2615
+ ${Yr(t.styleguide,1500)}
2569
2616
  \`\`\``),t?.brandvoice&&r.push(`## Available brand voice
2570
2617
 
2571
2618
  \`\`\`
2572
- ${Cr(t.brandvoice,1e3)}
2619
+ ${Yr(t.brandvoice,1e3)}
2573
2620
  \`\`\``),t?.themeContext&&r.push(`## Theme context
2574
2621
 
2575
2622
  \`\`\`
2576
- ${Cr(t.themeContext,1e3)}
2623
+ ${Yr(t.themeContext,1e3)}
2577
2624
  \`\`\``),n.length>0&&r.push(`## Existing modules in this theme
2578
2625
 
2579
2626
  These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
@@ -2594,13 +2641,13 @@ ${t.plan}
2594
2641
 
2595
2642
  ${i}`),r.join(`
2596
2643
 
2597
- `)}function Lh(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:
2644
+ `)}function Zy(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
2645
  - Briefly acknowledge the template and that you'll work from this structure (1\u20132 sentences in chat).
2599
2646
  - 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
2647
  - 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
2648
  - 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?").`: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 Cr(e,t){return e.length<=t?e:e.slice(0,t)+`
2603
- ... [truncated]`}var Ad=R(()=>{"use strict";h()});var Ir={};Be(Ir,{applyPipelineResult:()=>qt,handleAgenticGenerate:()=>Io,handleFigmaImport:()=>ps,handleGenerate:()=>Jh,handleGenerateStream:()=>ms,handlePlanModeStream:()=>_r,isGenerating:()=>jt,isPlanModeActive:()=>Er,resolveAgenticEngine:()=>xn,setParseWarningCallback:()=>Ar,shouldUseAgenticMode:()=>Mr});import{execSync as kr}from"child_process";function Ar(e){Tr=e}function jt(){return _t!==null}function ht(e){if(_t){let t=k();if(!t||t.id!==_t){M.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}nt("assistant",e),dc(e,Tr||void 0),D()}async function ms(e,t,n,s){let o=k();if(!o)throw new Error("No active session");_t=o.id;let r=s?.length?ko(s):void 0;try{let a=O(),l=a.aiEngine||$r();switch(l){case"anthropic-api":case"api":{let c=Pe("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await er(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,ht,r);break}case"claude-oauth":{await bc(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,ht,r);break}case"openai-api":{let c=Pe("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await tr(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,ht,r);break}case"gemini-api":{let c=Pe("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await nr(e,c,o.themeName,t,n,ht,r);break}case"claude-code":await Sc(e,o.themeName,t,n,ht,r);break;case"gemini-cli":await ir("gemini",e,o.themeName,t,n,ht,r);break;case"codex-cli":await ir("codex",e,o.themeName,t,n,ht,r);break;case"langdock-api":{let c=Pe("langdock-api",a);if(!c)throw new Error("Langdock API key not configured. Open Settings to add one.");let d=a.langdockProvider||"anthropic",u={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},m=a.langdockBaseUrl||u[d],g=a.langdockApiModel;switch(d){case"openai":case"mistral":await tr(e,c,o.themeName,g||"gpt-4.1",t,n,ht,r,`${m}/v1/chat/completions`);break;case"google":await nr(e,c,o.themeName,t,n,ht,r,`${m}/v1beta/models/${g||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,g);break;default:await er(e,c,o.themeName,g||"claude-sonnet-4-6",t,n,ht,r,m);break}break}default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{_t=null,Tr=null}}function $r(){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 kr("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return kr("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return kr("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 ms(e,n=>{t+=n}),t}function $d(){let e=k(),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 xn(e){let t=e.aiEngine||$r();if(!ls(t))throw new Error("Agentic pipeline is not available for this engine.");if(vn(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=Pe(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=e.geminiApiModel||"gemini-2.5-pro";break;case"langdock-api":{let o={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-flash",mistral:"mistral-large-latest"};s=e.langdockApiModel||o[e.langdockProvider||"anthropic"];break}case"claude-code":s=e.claudeCodeModel||"";break;case"codex-cli":s=e.codexCliModel||"";break;case"gemini-cli":s=e.geminiCliModel||"";break;default:s=""}return{engine:t,apiKey:n,model:s}}async function Io(e,t,n){let s=k();if(!s)throw new Error("No active session");let o=s.id;_t=o;try{let i=O(),{engine:r,apiKey:a,model:l}=xn(i),c=i.agenticConcurrency||20,d=$d(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
2649
+ - 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 Yr(e,t){return e.length<=t?e:e.slice(0,t)+`
2650
+ ... [truncated]`}var fu=N(()=>{"use strict";y()});var sa={};Ge(sa,{applyPipelineResult:()=>cn,handleAgenticGenerate:()=>Xo,handleFigmaImport:()=>Ps,handleGenerate:()=>Qy,handleGenerateStream:()=>Is,handlePlanModeStream:()=>ea,isGenerating:()=>Kt,isPlanModeActive:()=>ta,resolveAgenticEngine:()=>Un,setParseWarningCallback:()=>Zr,shouldUseAgenticMode:()=>na});import{execSync as qr}from"child_process";function Zr(e){Xr=e}function Kt(){return Ot!==null}function wt(e){if(Ot){let t=C();if(!t||t.id!==Ot){E.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}lt("assistant",e),Yc(e,Xr||void 0),j()}async function Is(e,t,n,s){let o=C();if(!o)throw new Error("No active session");Ot=o.id;let r=s?.length?Go(s):void 0;try{let a=R(),l=a.aiEngine||Qr();switch(l){case"anthropic-api":case"api":{let c=Fe("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await Tr(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,wt,r);break}case"claude-oauth":{await sd(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,wt,r);break}case"openai-api":{let c=Fe("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await Ar(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,wt,r);break}case"gemini-api":{let c=Fe("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await _r(e,c,o.themeName,t,n,wt,r);break}case"claude-code":await od(e,o.themeName,t,n,wt,r);break;case"gemini-cli":await Mr("gemini",e,o.themeName,t,n,wt,r);break;case"codex-cli":await Mr("codex",e,o.themeName,t,n,wt,r);break;case"langdock-api":{let c=Fe("langdock-api",a);if(!c)throw new Error("Langdock API key not configured. Open Settings to add one.");let d=a.langdockProvider||"anthropic",u={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},m=a.langdockBaseUrl||u[d],g=a.langdockApiModel;switch(d){case"openai":case"mistral":await Ar(e,c,o.themeName,g||"gpt-4.1",t,n,wt,r,`${m}/v1/chat/completions`);break;case"google":await _r(e,c,o.themeName,t,n,wt,r,`${m}/v1beta/models/${g||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,g);break;default:await Tr(e,c,o.themeName,g||"claude-sonnet-4-6",t,n,wt,r,m);break}break}default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{Ot=null,Xr=null}}function Qr(){let e=R();if(Ze())return"claude-oauth";if(e.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(e.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(e.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return qr("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return qr("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return qr("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Qy(e){let t="";return await Is(e,n=>{t+=n}),t}function hu(){let e=C(),t=ke(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder],o={modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,contentMode:t?.contentMode,brandAssets:e.brandAssets?{...e.brandAssets}:void 0};return e.templates.length>1&&(o.activePageLabel=t?.label,o.sitePages=e.templates.map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))),o}function Un(e){let t=e.aiEngine||Qr();if(!Ts(t))throw new Error("Agentic pipeline is not available for this engine.");if(Hn(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Ze())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=Fe(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=e.geminiApiModel||"gemini-2.5-pro";break;case"langdock-api":{let o={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-flash",mistral:"mistral-large-latest"};s=e.langdockApiModel||o[e.langdockProvider||"anthropic"];break}case"claude-code":s=e.claudeCodeModel||"";break;case"codex-cli":s=e.codexCliModel||"";break;case"gemini-cli":s=e.geminiCliModel||"";break;default:s=""}return{engine:t,apiKey:n,model:s}}async function Xo(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=s.id;Ot=o;try{let i=R(),{engine:r,apiKey:a,model:l}=Un(i),c=i.agenticConcurrency||20,d=hu(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
2604
2651
 
2605
2652
  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
2653
 
@@ -2610,39 +2657,39 @@ ${u}
2610
2657
 
2611
2658
  ## User message
2612
2659
 
2613
- ${e}`);let g=n?.length?ko(n):void 0;if(g?.length)for(let v of g)v.type==="document"&&v.extractedText&&(m+=`
2660
+ ${e}`);let g=n?.length?Go(n):void 0;if(g?.length)for(let M of g)M.type==="document"&&M.extractedText&&(m+=`
2614
2661
 
2615
2662
  ---
2616
- [Attached document: ${v.originalName}]
2617
- ${v.extractedText}`),v.type==="image"&&v.usage==="asset"&&v.assetPath&&(m+=`
2663
+ [Attached document: ${M.originalName}]
2664
+ ${M.extractedText}`),M.type==="image"&&M.usage==="asset"&&M.assetPath&&(m+=`
2618
2665
 
2619
- [Uploaded image: ${v.originalName} \u2192 available as get_asset_url("${v.assetPath}")]`);let y=$t(),f=new Set(d.modules.map(v=>v.moduleName)),b=y.filter(v=>!f.has(v.module.moduleName)).map(v=>({name:v.module.moduleName,usedIn:v.usedIn})),S=await yd(m,d,r,a,l,c,t,b),x=k();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 ps(e,t,n,s){let o=k();if(!o)throw new Error("No active session");let i=o.id;_t=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(kd(),Cd)),a=O(),{engine:l,apiKey:c,model:d}=xn(a),u=a.agenticConcurrency||20,m=$d(),g=await r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets),y=k();if(!y||y.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"});Ml({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}),Nt(e.moduleOrder),e.contentType==="email"){let o=Ce();o&&!o.contentMode&&(o.contentMode="email")}nt("assistant",e.assistantMessage,t),D()}async function _r(e,t,n){let s=k();if(!s)throw new Error("No active session");let o=O(),{engine:i,apiKey:r,model:a}=xn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(Ad(),Td)),Promise.resolve().then(()=>(st(),Mc))]),d=s.messages.filter(v=>v.role==="assistant").length,u=s.modules.map(v=>v.moduleName),m=$t(),g=new Set(u),y=m.filter(v=>!g.has(v.module.moduleName)).map(v=>({name:v.module.moduleName,usedIn:v.usedIn})),f=l(s.themeName,s.brandAssets,u,y,d),b=n?.length?ko(n):void 0,S=e;if(b?.length)for(let v of b)v.type==="document"&&v.extractedText&&(S+=`
2666
+ [Uploaded image: ${M.originalName} \u2192 available as get_asset_url("${M.assetPath}")]`);let h=Nt(),f=new Set(d.modules.map(M=>M.moduleName)),b=h.filter(M=>!f.has(M.module.moduleName)).map(M=>({name:M.module.moduleName,usedIn:M.usedIn})),{result:S,cost:v}=await Xi(()=>tt({name:"agent_pipeline",sessionId:d.themeName,input:e,metadata:{engine:r,model:l,concurrency:c},tags:["vibespot","agentic-pipeline"]},()=>ru(m,d,r,a,l,c,t,b)));S.cost=v;let w=C();if(!w||w.id!==o)throw E.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return S}finally{Ot=null}}async function Ps(e,t,n,s){let o=C();if(!o)throw new Error("No active session");let i=o.id;Ot=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(pu(),mu)),a=R(),{engine:l,apiKey:c,model:d}=Un(a),u=a.agenticConcurrency||20,m=hu(),{result:g,cost:h}=await Xi(()=>tt({name:"figma_import",sessionId:t,input:{fileName:e.fileName,sections:e.sections.length},metadata:{engine:l,model:d,concurrency:u},tags:["vibespot","figma-import"]},()=>r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets)));g.cost=h;let f=C();if(!f||f.id!==i)throw E.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{Ot=null}}function cn(e,t){let n=e.multiPage;if(n&&n.pages.length>0){let s=new Map;for(let o of n.pages)s.set(o.pageId,{label:o.label||o.pageId,pageType:o.pageType||"website_page"});hc({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(He({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Ht(e.moduleOrder),e.contentType==="email"){let o=ke();o&&!o.contentMode&&(o.contentMode="email")}t?.cost&&uc(t.cost),lt("assistant",e.assistantMessage,t),j()}async function ea(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=R(),{engine:i,apiKey:r,model:a}=Un(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(fu(),gu)),Promise.resolve().then(()=>(dt(),fd))]),d=s.messages.filter(w=>w.role==="assistant").length,u=s.modules.map(w=>w.moduleName),m=Nt(),g=new Set(u),h=m.filter(w=>!g.has(w.module.moduleName)).map(w=>({name:w.module.moduleName,usedIn:w.usedIn})),f=l(s.themeName,s.brandAssets,u,h,d),b=n?.length?Go(n):void 0,S=e;if(b?.length)for(let w of b)w.type==="document"&&w.extractedText&&(S+=`
2620
2667
 
2621
2668
  ---
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 Er(){return!!O().planMode}function Mr(){let e=O(),t=e.aiEngine||$r();return ls(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 Tr,_t,wn=R(()=>{"use strict";h();ee();we();Co();ce();rr();xt();cr();bd();Tr=null;_t=null});import{readFileSync as Bh,readdirSync as Hh,existsSync as Gh}from"fs";import{dirname as Uh,join as Po}from"path";import{fileURLToPath as Wh}from"url";function Vh(e){let t=e.match(Kh);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 zh(e){let t=Vh(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 Yh(){let e=[Po(_d,"../../assets/plan-templates"),Po(_d,"../assets/plan-templates"),Po(process.cwd(),"assets/plan-templates")];for(let t of e)if(Gh(t))return t;return null}function Ed(){if(Dt)return Dt;let e=Yh();if(!e)return Dt=[],Dt;let t=[],n=[];try{n=Hh(e)}catch{return Dt=[],Dt}for(let s of n)if(s.endsWith(".md"))try{let o=Bh(Po(e,s),"utf-8"),i=zh(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),Dt=t,Dt}function Md(e){return Ed().find(t=>t.id===e)??null}function Id(){return Ed().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 _d,Kh,Dt,Pd=R(()=>{"use strict";h();_d=Uh(Wh(import.meta.url)),Kh=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;Dt=null});import{existsSync as Rd,mkdirSync as qh,writeFileSync as Xh,rmSync as Zh}from"fs";import{join as Nd}from"path";function Od(e){return Nd(e,".vibespot",Qh)}function Ro(e){let t=k();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=Ce();n&&(n.plan=e);try{let s=Nd(t.themePath,".vibespot");Rd(s)||qh(s,{recursive:!0}),Xh(Od(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 Pr(){let e=k();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=Ce();t&&delete t.plan;try{let n=Od(e.themePath);Rd(n)&&Zh(n)}catch(n){M.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}D()}function Fd(e,t){Ve(e,t,n=>{if(!k()){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}Ro(o),p(t,200,{ok:!0,plan:o})})}function jd(e,t){Ve(e,t,()=>{Pr(),z({planMode:!1}),p(t,200,{ok:!0})})}function Dd(e,t){p(t,200,{templates:Id()})}function Ld(e,t){Ve(e,t,n=>{if(!k()){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=Md(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}Ro(i.body),z({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var Qh,Jd=R(()=>{"use strict";h();ze();we();Ot();ee();ce();Pd();Qh="plan.md"});function Bd(e){let t,n,s;for(Rr.lastIndex=0;(s=Rr.exec(e))!==null;)t=s[1].trim();let o;for(Nr.lastIndex=0;(o=Nr.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(Rr,"").replace(Nr,"").replace(/\n{3,}/g,`
2669
+ [Attached document: ${w.originalName}]
2670
+ ${w.extractedText}`);let v=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return v.type==="text"?v.text:JSON.stringify(v.data)}function ta(){return!!R().planMode}function na(){let e=R(),t=e.aiEngine||Qr();return Ts(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 Xr,Ot,Gn=N(()=>{"use strict";y();ee();Ce();Uo();le();Zi();Ir();_t();Rr();au();Be();Xr=null;Ot=null});import{readFileSync as eb,readdirSync as tb,existsSync as nb}from"fs";import{dirname as sb,join as Zo}from"path";import{fileURLToPath as ob}from"url";function rb(e){let t=e.match(ib);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 ab(e){let t=rb(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()+`
2671
+ `}}function lb(){let e=[Zo(yu,"../../assets/plan-templates"),Zo(yu,"../assets/plan-templates"),Zo(process.cwd(),"assets/plan-templates")];for(let t of e)if(nb(t))return t;return null}function bu(){if(Vt)return Vt;let e=lb();if(!e)return Vt=[],Vt;let t=[],n=[];try{n=tb(e)}catch{return Vt=[],Vt}for(let s of n)if(s.endsWith(".md"))try{let o=eb(Zo(e,s),"utf-8"),i=ab(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),Vt=t,Vt}function Su(e){return bu().find(t=>t.id===e)??null}function vu(){return bu().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 yu,ib,Vt,xu=N(()=>{"use strict";y();yu=sb(ob(import.meta.url)),ib=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;Vt=null});import{existsSync as wu,mkdirSync as cb,writeFileSync as db,rmSync as ub}from"fs";import{join as Cu}from"path";function ku(e){return Cu(e,".vibespot",mb)}function Qo(e){let t=C();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=ke();n&&(n.plan=e);try{let s=Cu(t.themePath,".vibespot");wu(s)||cb(s,{recursive:!0}),db(ku(t.themePath),e,"utf-8")}catch(s){E.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return j(),e}function oa(){let e=C();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=ke();t&&delete t.plan;try{let n=ku(e.themePath);wu(n)&&ub(n)}catch(n){E.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}j()}function Tu(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(t,400,{error:"Plan content cannot be empty"});return}Qo(o),p(t,200,{ok:!0,plan:o})})}function Au(e,t){qe(e,t,()=>{oa(),Y({planMode:!1}),p(t,200,{ok:!0})})}function _u(e,t){p(t,200,{templates:vu()})}function $u(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.templateId=="string"?n.templateId.trim():"";if(!o){p(t,400,{error:"templateId is required"});return}let i=Su(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}Qo(i.body),Y({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var mb,Eu=N(()=>{"use strict";y();Xe();Ce();Ut();ee();le();xu();mb="plan.md"});function Mu(e){let t,n,s;for(ia.lastIndex=0;(s=ia.exec(e))!==null;)t=s[1].trim();let o;for(ra.lastIndex=0;(o=ra.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(ia,"").replace(ra,"").replace(/\n{3,}/g,`
2625
2672
 
2626
- `).trim(),plan:t,choices:n}}var Rr,Nr,Hd=R(()=>{"use strict";h();Rr=/```vibespot-plan\s*\n([\s\S]*?)```/g,Nr=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as Or}from"child_process";function Gd(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+=`
2673
+ `).trim(),plan:t,choices:n}}var ia,ra,Iu=N(()=>{"use strict";y();ia=/```vibespot-plan\s*\n([\s\S]*?)```/g,ra=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as aa}from"child_process";function Pu(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
2674
  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 gs(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};Lt.set(o,i);let r=Or(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()),Gd(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};Lt.set(s,o);let i=e.split(" "),r=Or(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Gd(r,o,n?.timeout),s}function No(e){return Lt.get(e)}function ey(){let e=Date.now()-18e5;for(let[t,n]of Lt)n.completedAt&&n.completedAt<e&&Lt.delete(t)}function Oo(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};Lt.set(s,o);let i=e.split(" "),r=Or(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+=`
2675
+ Process timed out`,t.completedAt=Date.now())},n||3e5)}function Ns(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};zt.set(o,i);let r=aa(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()),Pu(r,i,s?.timeout),o}function dn(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};zt.set(s,o);let i=e.split(" "),r=aa(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Pu(r,o,n?.timeout),s}function ei(e){return zt.get(e)}function pb(){let e=Date.now()-18e5;for(let[t,n]of zt)n.completedAt&&n.completedAt<e&&zt.delete(t)}function ti(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};zt.set(s,o);let i=e.split(" "),r=aa(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
2676
  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 Ud(e,t){let n=Lt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Wd(e,t){let n=Lt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var Lt,Fo=R(()=>{"use strict";h();Lt=new Map;setInterval(ey,600*1e3)});import{readFileSync as ty,readdirSync as ny,existsSync as sy}from"fs";import{dirname as oy,join as jo}from"path";import{fileURLToPath as iy}from"url";function ry(){let e=[jo(Kd,"../../starters"),jo(Kd,"../starters"),jo(process.cwd(),"starters")];for(let t of e)if(sy(t))return t;return null}function Vd(){if(Cn!==null)return Cn;let e=ry();if(!e)return Cn=[],Cn;let t=[];for(let n of ny(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(ty(jo(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 zd(){return Vd().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function Fr(e){return Vd().find(t=>t.id===e)||null}var Kd,Cn,Yd=R(()=>{"use strict";h();Kd=oy(iy(import.meta.url)),Cn=null});var hs={};Be(hs,{collectThemeFiles:()=>Xd,extractDesignContext:()=>uy});import{existsSync as Do,readdirSync as Lo,readFileSync as ay}from"fs";import{join as yt}from"path";import{spawn as ly}from"child_process";async function qd(){return jr||(jr=(await import("@anthropic-ai/sdk")).default),jr}function fs(e){try{return ay(e,"utf-8")}catch{return""}}function Xd(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2677
+ Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Nu(e,t){let n=zt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Ru(e,t){let n=zt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var zt,ni=N(()=>{"use strict";y();zt=new Map;setInterval(pb,600*1e3)});import{readFileSync as gb,readdirSync as fb,existsSync as hb}from"fs";import{dirname as yb,join as si}from"path";import{fileURLToPath as bb}from"url";function Sb(){let e=[si(Ou,"../../starters"),si(Ou,"../starters"),si(process.cwd(),"starters")];for(let t of e)if(hb(t))return t;return null}function Fu(){if(Wn!==null)return Wn;let e=Sb();if(!e)return Wn=[],Wn;let t=[];for(let n of fb(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(gb(si(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 Wn=t,Wn}function Du(){return Fu().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function la(e){return Fu().find(t=>t.id===e)||null}var Ou,Wn,ju=N(()=>{"use strict";y();Ou=yb(bb(import.meta.url)),Wn=null});var Os={};Ge(Os,{collectThemeFiles:()=>Ju,extractDesignContext:()=>kb});import{existsSync as oi,readdirSync as ii,readFileSync as vb}from"fs";import{join as Ct}from"path";import{spawn as xb}from"child_process";async function Lu(){return ca||(ca=(await import("@anthropic-ai/sdk")).default),ca}function Rs(e){try{return vb(e,"utf-8")}catch{return""}}function Ju(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2631
2678
  ### ${a}
2632
2679
  \`\`\`
2633
2680
  ${l}
2634
2681
  \`\`\`
2635
- `;return n+c.length>cy?!1:(t.push(c),n+=c.length,!0)}let o=fs(yt(e,"theme.json"));o&&s("theme.json",o);let i=yt(e,"css");if(Do(i)){for(let a of Lo(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,fs(yt(i,a))))break}let r=yt(e,"modules");if(Do(r))for(let a of Lo(r).filter(l=>l.endsWith(".module"))){let l=yt(r,a),c=fs(yt(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(Do(r))for(let a of Lo(r).filter(l=>l.endsWith(".module"))){let l=yt(r,a),c=fs(yt(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(Do(r))for(let a of Lo(r).filter(l=>l.endsWith(".module"))){let l=yt(r,a),c=fs(yt(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function dy(){if(!Jo)try{Jo=E(As("extraction-prompt.md"))}catch{Jo=""}return Jo}function Dr(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=ly(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 uy(e,t){t?.({status:"Collecting theme files..."});let n=Xd(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=dy();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=Pe("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await qd();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(),fi)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await qd();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=Pe("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=Pe("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}
2682
+ `;return n+c.length>wb?!1:(t.push(c),n+=c.length,!0)}let o=Rs(Ct(e,"theme.json"));o&&s("theme.json",o);let i=Ct(e,"css");if(oi(i)){for(let a of ii(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,Rs(Ct(i,a))))break}let r=Ct(e,"modules");if(oi(r))for(let a of ii(r).filter(l=>l.endsWith(".module"))){let l=Ct(r,a),c=Rs(Ct(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(oi(r))for(let a of ii(r).filter(l=>l.endsWith(".module"))){let l=Ct(r,a),c=Rs(Ct(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(oi(r))for(let a of ii(r).filter(l=>l.endsWith(".module"))){let l=Ct(r,a),c=Rs(Ct(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function Cb(){if(!ri)try{ri=P(hn("extraction-prompt.md"))}catch{ri=""}return ri}function da(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=xb(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 kb(e,t){t?.({status:"Collecting theme files..."});let n=Ju(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=Cb();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:
2683
+ ${n}`;t?.({status:"Analyzing design patterns..."});let i=R(),r=i.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(r){case"anthropic-api":case"api":{let u=Fe("anthropic-api");if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");let m=await Lu(),g=new m({apiKey:u});d=i.anthropicApiModel||"claude-sonnet-4-6";let h=await g.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=h.content.map(f=>f.type==="text"?f.text:"").join(""),c=et(h.usage);break}case"claude-oauth":{let{getValidAccessToken:u,OAUTH_EXTRA_HEADERS:m,OAUTH_SYSTEM_PREFIX:g}=await Promise.resolve().then(()=>(_t(),Oi)),h=await u();if(!h)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let f=await Lu(),b=new f({authToken:h,defaultHeaders:m});d=i.anthropicApiModel||"claude-sonnet-4-6";let S=await b.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:g},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=S.content.map(v=>v.type==="text"?v.text:"").join(""),c=et(S.usage);break}case"openai-api":{let u=Fe("openai-api");if(!u)throw new Error("OpenAI API key not configured. Open Settings to add one.");d=i.openaiApiModel||"gpt-4o";let m=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`},body:JSON.stringify({model:d,max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!m.ok)throw new Error(`OpenAI API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.choices?.[0]?.message?.content||"",c=_n(g.usage);break}case"gemini-api":{let u=Fe("gemini-api");if(!u)throw new Error("Gemini API key not configured. Open Settings to add one.");d=i.geminiApiModel||"gemini-2.5-flash";let m=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${d}:generateContent?key=${u}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!m.ok)throw new Error(`Gemini API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.candidates?.[0]?.content?.parts?.map(h=>h.text).join("")||"",c=$n(g.usageMetadata);break}case"claude-code":{let u=`${s}
2637
2684
 
2638
2685
  ## User Request
2639
- ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),a=await Dr("claude",c,l);break}case"gemini-cli":{let l=`${s}
2686
+ ${o}`,m=["--print"];i.claudeCodeModel&&m.push("--model",i.claudeCodeModel),a=await da("claude",m,u);break}case"gemini-cli":{let u=`${s}
2640
2687
 
2641
2688
  ## User Request
2642
- ${o}`;a=await Dr("gemini",[],l);break}case"codex-cli":{let l=`${s}
2689
+ ${o}`;a=await da("gemini",[],u);break}case"codex-cli":{let u=`${s}
2643
2690
 
2644
2691
  ## User Request
2645
- ${o}`;a=await Dr("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 jr,cy,Jo,ys=R(()=>{"use strict";h();se();ee();jr=null;cy=8e4;Jo=""});var Lr={};Be(Lr,{extractBrandvoice:()=>my});async function my(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.
2692
+ ${o}`;a=await da("codex",[],u);break}default:throw new Error(`Unknown AI engine: ${r}. Open Settings to configure one.`)}if(!a.trim())throw new Error("AI returned empty response.");return d&&St({engine:r,model:d,name:"styleguide-extraction",input:{system:s,messages:[{role:"user",content:o}]},output:a,usage:c,startTime:l,endTime:new Date}),t?.({status:"Design extraction complete."}),a}var ca,wb,ri,Fs=N(()=>{"use strict";y();oe();ee();Be();tn();ca=null;wb=8e4;ri=""});var ua={};Ge(ua,{extractBrandvoice:()=>Tb});async function Tb(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
2693
 
2647
2694
  Return a markdown document with these sections (skip any section where the content provides no signal):
2648
2695
 
@@ -2662,7 +2709,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
2662
2709
  ## Dos and Don'ts
2663
2710
  3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
2664
2711
 
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 Jr=R(()=>{"use strict";h();st();ce()});var Bo={};Be(Bo,{extractThemeContext:()=>py});async function py(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.
2712
+ Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Pe(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),r=i.type==="text"?i.text:JSON.stringify(i.data);return!r||r.trim().length<20?null:(E.info("brandvoice-extractor",`Extracted brand voice (${r.length} chars)`),r.trim())}catch(i){let r=i instanceof Error?i.message:String(i);return E.warn("brandvoice-extractor",`Brand voice extraction failed: ${r}`),null}}var ma=N(()=>{"use strict";y();dt();le()});var ai={};Ge(ai,{extractThemeContext:()=>Ab});async function Ab(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
2713
 
2667
2714
  Return a markdown document with these sections (skip any section where the content provides no information):
2668
2715
 
@@ -2684,11 +2731,11 @@ Specific terms, product names, or branded language used consistently.
2684
2731
  Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
2685
2732
 
2686
2733
  Existing product context (update if the new content adds info, keep what's still accurate):
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 Ho=R(()=>{"use strict";h();st();ce()});import{join as Zd}from"path";function gy(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function fy(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=Zd(e.themePath,".vibespot");Ie(o),J(Zd(o,s),n)}async function Qd(e,t){let n=gy(e),s={attempted:[],extracted:[],skipped:[],errors:[]};if(n.length===0)return s;let o=hy(t)?t:{...await yy(e),...t??{}};n.includes("styleguide")&&await Br(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 Br(e,"brandvoice",s,()=>o.extractBrandvoice(e,r)),n.includes("themeContext")&&await Br(e,"themeContext",s,()=>o.extractThemeContext(e,r)),s}async function Br(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}fy(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 hy(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function yy(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(ys(),hs)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(ts(),wo)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(wn(),Ir)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(Jr(),Lr)),{extractThemeContext:i}=await Promise.resolve().then(()=>(Ho(),Bo)),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 eu=R(()=>{"use strict";h();se();ee();ce()});import{existsSync as kn,readdirSync as tu,rmSync as by,writeFileSync as Zt,mkdirSync as Go}from"fs";import{join as Ee,basename as Sy}from"path";import{homedir as vy}from"os";import{execFileSync as su}from"child_process";function Wo(){if(Uo&&Date.now()-Uo.ts<xy)return Uo.data;let e=[];if(kn(ot))try{for(let t of tu(ot,{withFileTypes:!0}))if(t.isDirectory()){let n=Ee(ot,t.name,"theme.json");if(kn(n)){let s=0,o=Ee(ot,t.name,"modules");if(kn(o))try{s=tu(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return Uo={data:e,ts:Date.now()},e}function iu(e){let t=k(),n=Fs(),s=!1;try{su("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...ou}),s=!0}catch{}let o=gn().sort((r,a)=>a.updatedAt-r.updatedAt),i=Wo();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 ru(e,t){U(e,n=>{try{if(jt()){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(ot,r);if(Ie(ot),kn(a)&&by(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!Fr(o)){p(t,400,{error:`Starter template "${o}" not found`});return}Jn(a,r),pn(a,r),o&&typeof o=="string"?(wy(a,r,o),ke()):i==="email"&&(At("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 wy(e,t,n){let s=Fr(n);if(!s)return;let o=k();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");Go(d,{recursive:!0});for(let u of s.modules){let m=Ee(d,`${u.moduleName}.module`);Go(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");Go(u,{recursive:!0}),Zt(Ee(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Ee(e,"js");Go(u,{recursive:!0}),Zt(Ee(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function au(e){p(e,200,{starters:zd()})}function lu(e,t){U(e,n=>{try{if(jt()){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(ot,a);Ie(ot),r.hubspotUploadMode==="cli"||!i?(async()=>{su("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...ou});let c=await nu(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)})}):Hn(i,o,l).then(async()=>{let c=await nu(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 nu(e,t){pn(e,t,{isImported:!0}),vo(e),D();let n=k(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await Qd(n),D()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function cu(e,t){U(e,n=>{try{if(jt()){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(ot,s)),!kn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Sy(o);pn(o,i),vo(o),D(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:k()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function du(e,t){U(e,n=>{try{if(jt()){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=go(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 uu(e,t){U(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}z({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function mu(e){let t=Fe();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Aa(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 Ls(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=Wo(),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 ou,ot,Uo,xy,Ko=R(()=>{"use strict";h();ze();ee();Bn();Gs();Ut();we();Ot();wn();Gt();ee();se();Yd();ns();eu();ou=process.platform==="win32"?{shell:!0}:{},ot=Ee(vy(),"vibespot-themes"),Uo=null,xy=5e3});import{existsSync as Cy,readFileSync as ky,appendFileSync as Ty}from"fs";import{join as pu}from"path";import{homedir as gu}from"os";function _y(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 Ey(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 My(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 hu(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:_y(n)}))}async function Iy(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 Py(){if(Date.now()-Tn.ts<Ay&&Object.keys(Tn.data).length>0)return Tn.data;let e=O(),t={...yu},n=[],s=Pe("anthropic-api",e);s&&n.push(Ey(s).then(a=>{a.length&&(t["anthropic-api"]=a,t["claude-oauth"]=a)}).catch(()=>{}));let o=Pe("openai-api",e);o&&n.push(My(o).then(a=>{if(!a.length)return;let l=hu(a,bu);l.length&&(t["openai-api"]=l);let c=hu(a,$y);c.length&&(t["codex-cli"]=c)}).catch(()=>{}));let i=Pe("gemini-api",e);i&&n.push(Iy(i).then(a=>{a.length&&(t["gemini-api"]=a,t["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n);let r=e.langdockProvider||"anthropic";return t["langdock-api"]=fu[r]||fu.anthropic,Tn.data=t,Tn.ts=Date.now(),t}function Su(e){let t=Fs(),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,langdockProvider:n.langdockProvider||"anthropic",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=Wo().length,r=sn();Py().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:yu,sessionCount:o,localThemeCount:i})})}function vu(e,t){U(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}z(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function xu(e,t){U(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}z(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}z(i);let r=null;if(!O().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(z({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 wu(e,t){U(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 Cu(e,t){U(e,n=>{try{let s=JSON.parse(n||"{}"),o=O(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){Ds(s.personalAccessKey).then(r=>{$n(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=gs("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 ku(e,t){U(e,n=>{try{let s=JSON.parse(n||"{}");if(!yi().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=bi();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=gs("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 Tu(e,t){U(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((O().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){di(s),p(t,200,{ok:!0});return}if(s){ui(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=gs("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=gs("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 Au(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 $u(e,t){U(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,z({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")?pu(gu(),".zshrc"):pu(gu(),".bashrc");try{(Cy(l)?ky(l,"utf-8"):"").includes("OPENAI_API_KEY")||Ty(l,`
2734
+ ${t}`:""}`;try{let a=await Pe(n,s,o,{systemPrompt:r,messages:[{role:"user",content:e}],maxTokens:1e3}),l=a.type==="text"?a.text:JSON.stringify(a.data);return!l||l.trim().length<20?null:(E.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return E.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var li=N(()=>{"use strict";y();dt();le()});import{join as Bu}from"path";function _b(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function $b(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=Bu(e.themePath,".vibespot");Re(o),J(Bu(o,s),n)}async function Hu(e,t){let n=_b(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:tt({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>Eb(e,t,n,s))}async function Eb(e,t,n,s){let o=Mb(t)?t:{...await Ib(e),...t??{}};n.includes("styleguide")&&await pa(e,"styleguide",s,()=>te("extract-styleguide",()=>o.extractStyleguide(e)));let i=n.filter(a=>a==="brandvoice"||a==="themeContext");if(i.length===0)return s;let r="";try{r=o.buildPreviewHtml()}catch(a){let l=a instanceof Error?a.message:String(a);for(let c of i)s.skipped.push(c),s.errors.push({asset:c,message:`Could not render preview HTML: ${l}`});return s}if(!r||r.length<50){for(let a of i)s.skipped.push(a);return s}return n.includes("brandvoice")&&await pa(e,"brandvoice",s,()=>te("extract-brandvoice",()=>o.extractBrandvoice(e,r))),n.includes("themeContext")&&await pa(e,"themeContext",s,()=>te("extract-theme-context",()=>o.extractThemeContext(e,r))),s}async function pa(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}$b(e,t,o),n.extracted.push(t)}catch(o){let i=o instanceof Error?o.message:String(o);n.skipped.push(t),n.errors.push({asset:t,message:i}),E.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function Mb(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function Ib(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(Fs(),Os)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(bs(),Ho)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Gn(),sa)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(ma(),ua)),{extractThemeContext:i}=await Promise.resolve().then(()=>(li(),ai)),r=R();return{extractStyleguide:()=>t(e.themePath),buildPreviewHtml:n,extractBrandvoice:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return o(l,c,d,u)},extractThemeContext:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return i(l,a.brandAssets?.themeContext,c,d,u)}}}var Uu=N(()=>{"use strict";y();oe();ee();le();Be()});import{existsSync as Kn,readdirSync as Gu,rmSync as Pb,writeFileSync as un,mkdirSync as ci}from"fs";import{join as Ne,basename as Nb}from"path";import{homedir as Rb}from"os";import{execFileSync as Ku}from"child_process";function ui(){if(di&&Date.now()-di.ts<Ob)return di.data;let e=[];if(Kn(ut))try{for(let t of Gu(ut,{withFileTypes:!0}))if(t.isDirectory()){let n=Ne(ut,t.name,"theme.json");if(Kn(n)){let s=0,o=Ne(ut,t.name,"modules");if(Kn(o))try{s=Gu(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return di={data:e,ts:Date.now()},e}function zu(e){let t=C(),n=to(),s=!1;try{Ku("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Vu}),s=!0}catch{}let o=On().sort((r,a)=>a.updatedAt-r.updatedAt),i=ui();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length,isImported:!!t.isImported}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i,contentMode:Ln()})}function Yu(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s,starterId:o,assetType:i}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let r=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!r){p(t,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Ne(ut,r);if(Re(ut),Kn(a)&&Pb(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!la(o)){p(t,400,{error:`Starter template "${o}" not found`});return}ss(a,r),Rn(a,r),o&&typeof o=="string"?(Fb(a,r,o),Te()):i==="email"&&(Pt("module_only","Email","email"),An(a,r)),j(),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 Fb(e,t,n){let s=la(n);if(!s)return;let o=C();if(!o)return;let i=s.contentType==="email",r=s.modules.map(u=>({...u})),a=[...s.moduleOrder],l=i?`email-${t}`:`lp-${t}`,c={id:l,label:`${s.name}`,pageType:i?"module_only":"landing_page",contentMode:i?"email":void 0,templateFile:i?"templates/email.html":`templates/${l}.html`,modules:r,moduleOrder:a,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};i&&An(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Ne(e,"modules");ci(d,{recursive:!0});for(let u of s.modules){let m=Ne(d,`${u.moduleName}.module`);ci(m,{recursive:!0}),un(Ne(m,"fields.json"),u.fieldsJson,"utf-8"),un(Ne(m,"meta.json"),u.metaJson,"utf-8"),un(Ne(m,"module.html"),u.moduleHtml,"utf-8"),un(Ne(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&un(Ne(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Ne(e,"css");ci(u,{recursive:!0}),un(Ne(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Ne(e,"js");ci(u,{recursive:!0}),un(Ne(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function qu(e){p(e,200,{starters:Du()})}function Xu(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Le(),r=R(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Ne(ut,a);Re(ut),r.hubspotUploadMode==="cli"||!i?(async()=>{Ku("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Vu});let c=await Wu(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)})}):is(i,o,l).then(async()=>{let c=await Wu(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 Wu(e,t){Rn(e,t,{isImported:!0}),Bo(e),j();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await Hu(n),j()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function Zu(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme path is required"});return}let o=s;if(Kn(o)||(o=Ne(ut,s)),!Kn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Nb(o);Rn(o,i),Bo(o),j(),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 Qu(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Session ID is required"});return}let o=Oo(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 em(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 tm(e){let t=Le();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await il(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 oo(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=ui(),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 Vu,ut,di,Ob,mi=N(()=>{"use strict";y();Xe();ee();os();lo();en();Ce();Ut();Gn();Qt();ee();oe();ju();Ss();Uu();Vu=process.platform==="win32"?{shell:!0}:{},ut=Ne(Rb(),"vibespot-themes"),di=null,Ob=5e3});import{existsSync as Db,readFileSync as jb,appendFileSync as Lb}from"fs";import{join as nm}from"path";import{homedir as sm}from"os";function Hb(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 fa(e,t={},n=lm){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function Ub(e){let t=await fa("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 Gb(e){let t=await fa("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function im(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:Hb(n)}))}async function Wb(e){let t=await fa(`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 Kb(e=!1){if(!e&&Date.now()-Vn.ts<Jb&&Object.keys(Vn.data).length>0)return Vn.data;let t=R(),n={...ga},s=[],o=Fe("anthropic-api",t);o&&s.push(Ub(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c)}).catch(()=>{}));let i=Fe("openai-api",t);i&&s.push(Gb(i).then(c=>{if(!c.length)return;let d=im(c,am);d.length&&(n["openai-api"]=d);let u=im(c,Bb);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let r=Fe("gemini-api",t);r&&s.push(Wb(r).then(c=>{c.length&&(n["gemini-api"]=c,n["gemini-cli"]=c)}).catch(()=>{}));let a=!1;await Promise.race([Promise.all(s).then(()=>{a=!0}),new Promise(c=>setTimeout(c,lm+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=om[l]||om.anthropic,a&&(Vn.data=n,Vn.ts=Date.now()),n}function cm(e){let t=Za(),n=R(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,codexCliModel:n.codexCliModel||null,geminiCliModel:n.geminiCliModel||null,geminiApiModel:n.geminiApiModel||null,langdockApiModel:n.langdockApiModel||null,langdockBaseUrl:n.langdockBaseUrl||null,langdockProvider:n.langdockProvider||"anthropic",hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(o=>({portalId:o.portalId,portalName:o.portalName,dataCenter:o.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null,langfuseEnabled:n.langfuseEnabled,langfuseBaseUrl:n.langfuseBaseUrl||null};p(e,200,{version:yn(),environment:t,config:s,models:ga,sessionCount:On().length,localThemeCount:ui().length})}function dm(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");Kb(n).then(s=>p(t,200,{models:s})).catch(()=>p(t,200,{models:ga}))}function um(e,t){let n=new URL(e.url||"/","http://localhost"),s=n.searchParams.get("group")||"all",o=s==="ai"||s==="platform"?s:"all",i=n.searchParams.get("refresh")==="1",r=rm[o];if(!i&&Date.now()-r.ts<Vb&&Object.keys(r.data).length>0){p(t,200,{...r.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=Qa();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:el()};else{let l=to();a={tools:l.tools,availableEngines:l.availableEngines}}rm[o]={data:a,ts:Date.now()},p(t,200,{...a,group:o,cached:!1})}function mm(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 pm(e,t){W(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"langdock":l.langdockApiKey="";break;case"figma":l.figmaToken="";break;case"langfuse-public":l.langfusePublicKey="";break;case"langfuse-secret":l.langfuseSecretKey="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"langdock":i.langdockApiKey=o;break;case"figma":i.figmaToken=o;break;case"langfuse-public":i.langfusePublicKey=o;break;case"langfuse-secret":i.langfuseSecretKey=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(i);let r=null;if(!R().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(Y({aiEngine:c}),r=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function gm(e,t){W(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let r=dn(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function fm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}"),o=R(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){so(s.personalAccessKey).then(r=>{Yn(s.personalAccessKey,r.portalId,r.portalName,r.dataCenter),p(t,200,{ok:!0,portalName:r.portalName,portalId:r.portalId,dataCenter:r.dataCenter})}).catch(r=>{p(t,400,{error:r instanceof Error?r.message:String(r)})});return}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=Ns("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:a});return}if(i==="api"){let r=o.hubspotAccounts||[];if(r.length>0&&!s.force){let a=r.find(l=>l.portalId===o.activeHubSpotAccount)||r[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ht();if(a.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function hm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}");if(!Zs().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=Qs();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=Ns("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=dn("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:r,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function ym(e,t){W(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((R().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Mi(s),p(t,200,{ok:!0});return}if(s){Ii(s),p(t,200,{ok:!0});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=Ns("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=Ns("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 bm(e){let t=dn("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function Sm(e,t){W(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=dn("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=dn("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,Y({openaiApiKey:i}),process.platform!=="win32"){let r=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(r){let a=`export OPENAI_API_KEY="${r}"`,l=process.env.SHELL?.includes("zsh")?nm(sm(),".zshrc"):nm(sm(),".bashrc");try{(Db(l)?jb(l,"utf-8"):"").includes("OPENAI_API_KEY")||Lb(l,`
2688
2735
  # Added by vibeSpot
2689
2736
  ${a}
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 _u(e,t){U(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}z({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Eu(e,t){U(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}mi(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 Mu(e,t){U(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){p(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(i.langdockProvider){let r={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};i.langdockApiModel=r[i.langdockProvider]||"",Tn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}z(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Iu(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=No(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 Tn,Ay,yu,fu,bu,$y,Pu=R(()=>{"use strict";h();ze();ee();we();Ko();Gt();Ut();se();Fo();Tn={data:{},ts:0},Ay=600*1e3,yu={"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"}]},fu={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],openai:[{id:"gpt-4.1",label:"GPT-4.1 (default)"},{id:"gpt-4.1-mini",label:"GPT-4.1 Mini"},{id:"gpt-4.1-nano",label:"GPT-4.1 Nano"},{id:"gpt-4o",label:"GPT-4o"},{id:"o3-mini",label:"o3 Mini"}],google:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],mistral:[{id:"mistral-large-latest",label:"Mistral Large (default)"},{id:"mistral-medium-latest",label:"Mistral Medium"},{id:"mistral-small-latest",label:"Mistral Small"},{id:"codestral-latest",label:"Codestral"},{id:"pixtral-large-latest",label:"Pixtral Large"}]},bu=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,$y=bu});function Ru(e,t){U(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}pi(s.trim(),(o||"").trim());let i=O();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&z({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Nu(e,t){let n=lt(),s=Mn();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Ou(e,t){try{Is(),O().aiEngine==="claude-oauth"&&z({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var Fu=R(()=>{"use strict";h();ze();ee();xt()});import{existsSync as Ry,rmSync as Ny}from"fs";import{join as Oy}from"path";function ju(e,t,n){if(e==="GET"){let s=k(),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"){U(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Ll(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 Du(e,t){U(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=go(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 Lu(e,t){U(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=Oy(ot,s);if(!Ry(o)){p(t,404,{error:"Theme not found on disk"});return}Ny(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Ju(e,t){U(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=Jl(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 Bu(e,t){U(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=Bl(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 Hu=R(()=>{"use strict";h();ze();we();Ko()});import{existsSync as bs,readFileSync as Fy,rmSync as Vo}from"fs";import{join as Oe,basename as jy}from"path";import{execFileSync as Dy}from"child_process";function Ku(e){let t=k();if(!t){p(e,404,{error:"No active session"});return}let n=$t();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 Vu(e){let t=k();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!bs(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=Oe(n,".."),i=jy(n);try{let r=`${s}.zip`,a=Oe(o,r);bs(a)&&Vo(a),Dy("zip",["-r",r,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...Ly});let l=Fy(a);Vo(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 zu(e,t,n){let s=k();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"){U(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=At(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"){U(t,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Ol(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 Yu(e,t){U(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!Vn(s)){p(t,404,{error:"Template not found"});return}D();let i=k();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 qu(e,t){U(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(!Nl(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 Xu(e,t){U(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(!Rl(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){U(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=Pl(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 Qu(e){let t=$t();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function em(e,t,n){let s=k();if(!s){p(n,404,{error:"No active session"});return}U(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=$t().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 tm(e,t,n){let s=k();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"){U(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=Oe(s.themePath,".vibespot");Ie(c),J(Oe(c,l),r);let d=null;a==="styleguide"&&(d=Hr(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"){U(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let r=i;s.brandAssets&&delete s.brandAssets[r],s.updatedAt=Date.now();let a=r==="themeContext"?"theme-context.md":`${r}.md`,l=Oe(s.themePath,".vibespot",a);bs(l)&&Vo(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 sm(e,t){p(t,200,nm)}function By(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=Gu.exec(a);if(Gu.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 Hr(e,t){let{colors:n,fonts:s}=By(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=nm.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=r(s[0])),s[1]?o.fonts.body=r(s[1]):s[0]&&(o.fonts.body=r(s[0]))}e.brandAssets.brandKit=o;let i=Oe(e.themePath,".vibespot");return Ie(i),J(Oe(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function om(e,t,n){let s=k();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){U(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"&&Hy.test(i.colors[c])&&(l[c]=i.colors[c]);Object.keys(l).length>0&&(r.colors=l)}if(i.fonts&&typeof i.fonts=="object"){let l={};for(let c of["heading","body"])typeof i.fonts[c]=="string"&&i.fonts[c].trim()&&(l[c]=i.fonts[c].trim());Object.keys(l).length>0&&(r.fonts=l)}typeof i.logoUrl=="string"&&i.logoUrl.trim()&&(r.logoUrl=i.logoUrl.trim()),s.brandAssets.brandKit=r,s.updatedAt=Date.now();let a=Oe(s.themePath,".vibespot");Ie(a),J(Oe(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=Oe(s.themePath,".vibespot","brand-kit.json");bs(o)&&Vo(o),D(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Uu(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Oe(e.themePath,".vibespot");Ie(o),J(Oe(o,s),n)}async function Wu(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(ys(),hs));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(wn(),Ir)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),ya)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ts(),wo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(Jr(),Lr));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(Ho(),Bo));return u(d,e.brandAssets?.themeContext,r,a,l)}function im(e,t){let n=k();if(!n){p(t,404,{error:"No active session"});return}U(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=>Wu(n,g,r))),u={};for(let g=0;g<c.length;g++){let y=d[g],f=y.status==="fulfilled"?y.value:null;f&&Uu(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=Hr(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 Wu(n,i,r);if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Uu(n,i,a);let l=null;i==="styleguide"&&(l=Hr(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 rm(e,t){let n=k();if(!n){p(t,404,{error:"No active session"});return}U(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:y}=await import("os"),f=Oe(y(),"vibespot-themes",".references",g);Ie(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(Gs(),Na));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(!bs(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(()=>(ys(),hs)),c=await l(a);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Oe(n.themePath,".vibespot");Ie(d),J(Oe(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 Ly,nm,Jy,Gu,Hy,am=R(()=>{"use strict";h();ze();ce();ee();Bn();we();se();Ly=process.platform==="win32"?{shell:!0}:{};nm=[{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,Gu=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;Hy=/^#[0-9a-fA-F]{6}$/});import{join as Gy}from"path";function lm(e,t){let n=k();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 cm(e,t,n){let s=k();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?Al(o.moduleName):$l(o.moduleName),D(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function dm(e,t){let n=k();if(!n){p(t,404,{error:"No active session"});return}U(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(),tt(),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(),tt(),D(),ke(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function um(e,t){Ve(e,t,n=>{Array.isArray(n.order)?(Nt(n.order),D(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function mm(e){let t=k();if(!t){p(e,404,{error:"No active session"});return}try{ke();let n=eo(t.themePath),s=Oo(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:Gy(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function pm(e,t){U(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);_l(s,o,i),D(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function gm(e,t){U(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=Ia(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2737
+ `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=dn("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:p(t,400,{error:`Unknown CLI: ${s}`})}}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function vm(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 xm(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}Pi(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 wm(e,t){W(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider","langfuseEnabled","langfuseBaseUrl"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langfuseEnabled!==void 0&&typeof s.langfuseEnabled!="boolean"){p(t,400,{error:"langfuseEnabled must be a boolean"});return}if(s.langfuseBaseUrl!==void 0&&typeof s.langfuseBaseUrl!="string"){p(t,400,{error:"langfuseBaseUrl must be a string"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){p(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(i.langdockProvider){let r={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};i.langdockApiModel=r[i.langdockProvider]||"",Vn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}Y(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Cm(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=ei(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 Vn,Jb,ga,om,am,Bb,lm,Vb,rm,km=N(()=>{"use strict";y();Xe();ee();Ce();mi();Qt();en();oe();ni();Vn={data:{},ts:0},Jb=600*1e3,ga={"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"}]},om={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],openai:[{id:"gpt-4.1",label:"GPT-4.1 (default)"},{id:"gpt-4.1-mini",label:"GPT-4.1 Mini"},{id:"gpt-4.1-nano",label:"GPT-4.1 Nano"},{id:"gpt-4o",label:"GPT-4o"},{id:"o3-mini",label:"o3 Mini"}],google:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],mistral:[{id:"mistral-large-latest",label:"Mistral Large (default)"},{id:"mistral-medium-latest",label:"Mistral Medium"},{id:"mistral-small-latest",label:"Mistral Small"},{id:"codestral-latest",label:"Codestral"},{id:"pixtral-large-latest",label:"Pixtral Large"}]},am=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,Bb=am;lm=2500;Vb=60*1e3,rm={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}}});function Tm(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}Ni(s.trim(),(o||"").trim());let i=R();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&Y({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Am(e,t){let n=Ze(),s=Xt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function _m(e,t){try{zs(),R().aiEngine==="claude-oauth"&&Y({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var $m=N(()=>{"use strict";y();Xe();ee();_t()});import{existsSync as zb,rmSync as Yb}from"fs";import{join as qb}from"path";function Em(e,t,n){if(e==="GET"){let s=C(),o=On().sort((i,r)=>r.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName,isImported:!!s.isImported}:null,sessions:o});return}if(e==="DELETE"){W(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Tc(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 Mm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=Oo(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 Im(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=qb(ut,s);if(!zb(o)){p(t,404,{error:"Theme not found on disk"});return}Yb(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Pm(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=Ac(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 Nm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=_c(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 Rm=N(()=>{"use strict";y();Xe();Ce();mi()});import{existsSync as pi,readFileSync as Xb,readdirSync as Zb,rmSync as Lm}from"fs";import{join as Oe,basename as Qb,relative as eS,sep as tS}from"path";import nS from"jszip";function Jm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=Nt();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.contentMode==="email"?"email":s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1,hasBrandKit:!!t.brandAssets?.brandKit&&Object.keys(t.brandAssets.brandKit).length>0,brandKit:t.brandAssets?.brandKit||null}})}function Bm(e,t=[]){for(let n of Zb(e,{withFileTypes:!0}))if(n.isDirectory()){if(sS.has(n.name))continue;Bm(Oe(e,n.name),t)}else n.isFile()&&t.push(Oe(e,n.name));return t}async function Hm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!pi(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=Qb(n);try{let i=new nS;for(let a of Bm(n)){let l=Oe(o,eS(n,a)).split(tS).join("/");i.file(l,Xb(a))}let r=await i.generateAsync({type:"nodebuffer",compression:"DEFLATE",compressionOptions:{level:6}});e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${s}.zip"`,"Content-Length":r.length}),e.end(r)}catch(i){E.error("download-zip","Failed to create zip archive",i),p(e,500,{error:"Failed to create zip archive"})}}function Um(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.contentMode==="email"?"email":o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){W(t,o=>{try{let{pageType:i,label:r}=JSON.parse(o);if(!i||!r){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only","email"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=i==="email",d=Pt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&An(s.themePath,s.themeName),j(),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(!xc(i,!!r)){p(n,404,{error:"Template not found"});return}j(),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 Gm(e,t){W(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!us(s)){p(t,404,{error:"Template not found"});return}j();let i=C();p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Wm(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(!vc(s,o.trim())){p(t,404,{error:"Template not found"});return}j(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Km(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(!Sc(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}j(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Vm(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=bc(s,o);if(!i){p(t,404,{error:"Template not found"});return}j(),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 zm(e){let t=Nt();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Ym(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}W(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=Nt().find(d=>d.module.moduleName===i);if(!a){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...a.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function qm(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(),j(),p(n,200,{ok:!0});return}if(!r){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let a=i,l=a==="themeContext"?"theme-context.md":`${a}.md`;s.brandAssets[a]=r,s.updatedAt=Date.now();let c=Oe(s.themePath,".vibespot");Re(c),J(Oe(c,l),r);let d=null;a==="styleguide"&&(d=ha(s,r)),j(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let r=i;s.brandAssets&&delete s.brandAssets[r],s.updatedAt=Date.now();let a=r==="themeContext"?"theme-context.md":`${r}.md`,l=Oe(s.themePath,".vibespot",a);pi(l)&&Lm(l),j(),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 Zm(e,t){p(t,200,Xm)}function iS(e){let t=[],n=[],s=e.split(`
2738
+ `),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(oS);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Om.exec(a);if(Om.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 ha(e,t){let{colors:n,fonts:s}=iS(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=Xm.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=r(s[0])),s[1]?o.fonts.body=r(s[1]):s[0]&&(o.fonts.body=r(s[0]))}e.brandAssets.brandKit=o;let i=Oe(e.themePath,".vibespot");return Re(i),J(Oe(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function Qm(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"&&rS.test(i.colors[c])&&(l[c]=i.colors[c]);Object.keys(l).length>0&&(r.colors=l)}if(i.fonts&&typeof i.fonts=="object"){let l={};for(let c of["heading","body"])typeof i.fonts[c]=="string"&&i.fonts[c].trim()&&(l[c]=i.fonts[c].trim());Object.keys(l).length>0&&(r.fonts=l)}typeof i.logoUrl=="string"&&i.logoUrl.trim()&&(r.logoUrl=i.logoUrl.trim()),s.brandAssets.brandKit=r,s.updatedAt=Date.now();let a=Oe(s.themePath,".vibespot");Re(a),J(Oe(a,"brand-kit.json"),JSON.stringify(r,null,2)),j(),p(n,200,{ok:!0,brandKit:r})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Oe(s.themePath,".vibespot","brand-kit.json");pi(o)&&Lm(o),j(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Fm(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Oe(e.themePath,".vibespot");Re(o),J(Oe(o,s),n)}function Dm(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function jm(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Fs(),Os));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Gn(),sa)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),Ka)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(bs(),Ho)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(ma(),ua));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(li(),ai));return u(d,e.brandAssets?.themeContext,r,a,l)}function ep(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",r=o.sourcePath;if(i==="all"){let c=["styleguide","brandvoice","themeContext"],d=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>te(Dm(g),()=>jm(n,g,r))))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Fm(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=ha(n,u.styleguide)),j(),p(t,200,{ok:!0,type:"all",extracted:u,brandKit:m});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let a=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:i},tags:["vibespot","brand-extract"]},()=>te(Dm(i),()=>jm(n,i,r)));if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Fm(n,i,a);let l=null;i==="styleguide"&&(l=ha(n,a)),j(),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 tp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:r}=JSON.parse(s),a;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Le();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),f=Oe(h(),"vibespot-themes",".references",g);Re(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(lo(),pl));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(!pi(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(),Os)),c=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Oe(n.themePath,".vibespot");Re(d),J(Oe(d,"styleguide.md"),c),j(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var sS,Xm,oS,Om,rS,np=N(()=>{"use strict";y();Xe();le();Be();ee();os();Ce();oe();sS=new Set([".git",".vibespot","node_modules"]);Xm=[{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"}];oS=/#[0-9a-fA-F]{6}\b/g,Om=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;rS=/^#[0-9a-fA-F]{6}$/});import{join as aS}from"path";function sp(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 op(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=ve();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){qe(t,n,o=>{o.deleteEntirely?mc(o.moduleName):pc(o.moduleName),j(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function ip(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=ke();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),at(),j(),Te(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:r,content:a}=o;if(!i||!r){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(r){case"html":l.moduleHtml=a;break;case"css":l.moduleCss=a;break;case"js":l.moduleJs=a||void 0;break;case"fields":try{JSON.parse(a)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:p(t,400,{error:`Invalid fileType: ${r}`});return}n.updatedAt=Date.now(),at(),j(),Te(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function rp(e,t){qe(e,t,n=>{Array.isArray(n.order)?(Ht(n.order),j(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function ap(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}try{Te();let n=Co(t.themePath),s=ti(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:aS(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function lp(e,t){W(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);gc(s,o,i),j(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function cp(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=dl(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2692
2739
  `),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
2740
 
2694
2741
  Source analysis found ${o.components.length} components:
@@ -2698,19 +2745,19 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
2698
2745
  Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
2699
2746
  Interactions: ${o.interactions.join(", ")}
2700
2747
 
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 fm(e,t){let n=k();if(!n){p(t,404,{error:"No active session"});return}if(!et()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?vl(n.themePath,o,50):Sl(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function hm(e,t){U(e,n=>{try{let s=k();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(nt("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=wl(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}Zl()}else{let r=xl(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}Xl()}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 ym=R(()=>{"use strict";h();ze();we();to();Fo();Hs();dn()});import{writeFileSync as Uy,mkdirSync as Sm}from"fs";import{join as zo}from"path";import{randomUUID as Wy}from"crypto";function vm(e){let t=e.match(Ky);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 qo(e,t){let n=await fetch(`${Vy}${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 Ur(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=bm.length)throw s;let r=bm[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 xm(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=xm(n,t);if(s)return s}return null}function zy(e,t){if(t){let s=xm(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>Gr.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>Gr.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>Gr.has(s.type)):[]}function Yo(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 Yy(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=Yo(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=Yo(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 qy(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 Xy(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 Zy(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 eb(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 tb(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Yo(t.color)}if(e.backgroundColor)return Yo(e.backgroundColor)}function nb(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(eb),backgroundColor:tb(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 sb(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 wm(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());Uy(t,s)}async function ob(e,t,n,s,o){if(t.length===0)return new Map;Sm(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await Ur(()=>qo(`/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=zo(s,`frame-${u}.png`);try{await wm(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 ib(e,t,n,s,o){if(t.length===0)return[];Sm(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 Ur(()=>qo(`/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 y=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${Wy().slice(0,6)}.png`,f=zo(s,y);try{await wm(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),M.info("figma",`Downloaded asset: ${y}`)}catch(b){M.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function Cm(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 Ur(()=>qo(i,n),o);M.info("figma",`Fetched file: ${r.name}`);let a=zy(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:Yy(a),typography:qy(a),spacing:Xy(a),effects:Zy(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=nb(a),d=zo(s,".vibespot","figma-frames"),u=await ob(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=sb(a),y=zo(s,"assets"),f=await ib(e,g,n,y,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 km(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 Tm(e){return await qo("/v1/me",e)}var Ky,Vy,bm,Gr,Am=R(()=>{"use strict";h();ce();Ky=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;Vy="https://api.figma.com",bm=[10,20,40,60,120];Gr=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var Pm={};Be(Pm,{getCachedExtraction:()=>Im,handleFigmaExtractRoute:()=>Kr,handleFigmaGenerateRoute:()=>Vr,handleFigmaTestTokenRoute:()=>Wr});import{randomUUID as $m}from"crypto";import{existsSync as _m,mkdirSync as Em,writeFileSync as rb,copyFileSync as ab}from"fs";import{join as Xo,basename as lb}from"path";function Mm(){let e=Date.now();for(let[t,n]of Ss)n.expires<e&&Ss.delete(t)}function Im(e){Mm();let t=Ss.get(e);return t?(Ss.delete(e),t.extraction):null}function Wr(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 Tm(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 Kr(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=vm(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=k()?.themePath||`/tmp/vibespot-figma-${$m().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)}
2748
+ 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 dp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}if(!rt()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?ic(n.themePath,o,50):oc(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function up(e,t){W(e,n=>{try{let s=C();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(lt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let r=s.templates.find(c=>c.id===i);if(!r){p(t,404,{error:"Template not found"});return}let a=r.moduleOrder.map(c=>`modules/${c}.module`);r.templateFile&&a.push(r.templateFile);let l=ac(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}jc()}else{let r=rc(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}Dc()}j(),p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var mp=N(()=>{"use strict";y();Xe();Ce();ko();ni();ao();In()});import{writeFileSync as lS,mkdirSync as gp}from"fs";import{join as gi}from"path";import{randomUUID as cS}from"crypto";function fp(e){let t=e.match(dS);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 hi(e,t){let n=await fetch(`${uS}${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 ba(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=pp.length)throw s;let r=pp[n];E.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${r}s`),t&&t(`Figma rate limited \u2014 retrying in ${r}s...`),await new Promise(a=>setTimeout(a,r*1e3))}}function mn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)mn(s,t,n+1)}function hp(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=hp(n,t);if(s)return s}return null}function mS(e,t){if(t){let s=hp(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>ya.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>ya.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>ya.has(s.type)):[]}function fi(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 pS(e){let t=new Map;for(let n of e)mn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=fi(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=fi(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 gS(e){let t=new Map;for(let n of e)mn(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,r=o.fontWeight||400,a=o.lineHeightPx?Math.round(o.lineHeightPx/i*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";i>=32?d="heading":i>=20?d="subheading":i<=12?d="caption":r>=600&&i<=14&&(d="label");let u=`${c}-${i}-${r}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:r,lineHeight:a,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function fS(e){let t=[],n=new Set;for(let s of e)mn(s,o=>{if(!o.layoutMode||o.layoutMode==="NONE")return;if(o.itemSpacing&&o.itemSpacing>0){let c=`gap-${o.itemSpacing}-${o.name}`;n.has(c)||(n.add(c),t.push({context:`${o.name} gap`,value:o.itemSpacing,type:"gap"}))}let i=o.paddingTop||0,r=o.paddingRight||0,a=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||r>0||a>0||l>0){let c=`pad-${i}-${r}-${a}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===a&&l===r&&i===l?i:Math.max(i,r,a,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function hS(e){let t=[],n=new Set;for(let s of e)mn(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r,g:a,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(r*255)},${Math.round(a*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let i=`${o.cornerRadius}px`;n.has(`radius-${i}`)||(n.add(`radius-${i}`),t.push({type:"radius",cssValue:i,context:o.name}))}});return t}function yS(e,t){let n=[];return mn(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,r="body";o>=32?r="headline":o>=20?r="subheadline":o<=12?r="caption":i>=600&&o<=16&&(r="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(r="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:r,sectionName:t})}),n}function bS(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 SS(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return fi(t.color)}if(e.backgroundColor)return fi(e.backgroundColor)}function vS(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:yS(t,t.name),children:(t.children||[]).slice(0,20).map(bS),backgroundColor:SS(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 xS(e){let t=[];for(let n of e)mn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="IMAGE"&&o.imageRef){t.push({nodeId:s.id,name:s.name||"image"});break}}});return t}async function yp(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());lS(t,s)}async function wS(e,t,n,s,o){if(t.length===0)return new Map;gp(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await ba(()=>hi(`/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=gi(s,`frame-${u}.png`);try{await yp(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 CS(e,t,n,s,o){if(t.length===0)return[];gp(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 ba(()=>hi(`/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()}-${cS().slice(0,6)}.png`,f=gi(s,h);try{await yp(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 bp(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 ba(()=>hi(i,n),o);E.info("figma",`Fetched file: ${r.name}`);let a=mS(r.document,t);if(a.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");E.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:pS(a),typography:gS(a),spacing:fS(a),effects:hS(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=vS(a),d=gi(s,".vibespot","figma-frames"),u=await wS(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=xS(a),h=gi(s,"assets"),f=await CS(e,g,n,h,o);return E.info("figma",`Extraction complete: ${m.length} sections, ${f.length} assets`),{fileName:r.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:f}}function Sp(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 vp(e){return await hi("/v1/me",e)}var dS,uS,pp,ya,xp=N(()=>{"use strict";y();le();dS=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;uS="https://api.figma.com",pp=[10,20,40,60,120];ya=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var _p={};Ge(_p,{getCachedExtraction:()=>Ap,handleFigmaExtractRoute:()=>va,handleFigmaGenerateRoute:()=>xa,handleFigmaTestTokenRoute:()=>Sa});import{randomUUID as wp}from"crypto";import{existsSync as Cp,mkdirSync as kp,writeFileSync as kS,copyFileSync as TS}from"fs";import{join as yi,basename as AS}from"path";function Tp(){let e=Date.now();for(let[t,n]of Ds)n.expires<e&&Ds.delete(t)}function Ap(e){Tp();let t=Ds.get(e);return t?(Ds.delete(e),t.extraction):null}function Sa(e,t){qe(e,t,async n=>{let s=n.token||R().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await vp(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);E.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function va(e,t){qe(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||R().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=fp(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-${wp().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
2749
 
2703
- `)};try{let c=await Cm(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=$m();Mm(),Ss.set(d,{extraction:c,expires:Date.now()+cb});let u=km(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 db(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 Vr(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=Im(s);if(!r){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=k();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)}
2750
+ `)};try{let c=await bp(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=wp();Tp(),Ds.set(d,{extraction:c,expires:Date.now()+_S});let u=Sp(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);E.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function $S(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(`
2751
+ `)}function xa(e,t){qe(e,t,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(t,400,{error:"Missing extractionId or themeName"});return}let r=Ap(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
2752
 
2706
- `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=db(r),d=Xo(a.themePath,".vibespot");if(_m(d)||Em(d,{recursive:!0}),rb(Xo(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,D(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)At("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=Xo(a.themePath,"assets");Em(f,{recursive:!0});let b=0;for(let S of r.assets)if(_m(S.localPath)){let x=Xo(f,lb(S.localPath));try{ab(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 ps(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}),Nt(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(),Wt(a.themePath,`Figma import: ${r.fileName}`);let y=Se().map(f=>f.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${y.length} modules generated`}),l({type:"complete",ok:!0,modules:y})}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 Ss,cb,zr=R(()=>{"use strict";h();ze();ee();ce();Am();we();Kn();Ui();dn();wn();Ot();Ss=new Map,cb=1800*1e3});import{readdirSync as Xr,statSync as ub}from"fs";import{join as Y,relative as mb}from"path";function An(e){let t=Y(e,Et);if(!w(t))return null;try{return JSON.parse(E(t))}catch{return null}}function Qo(e,t){let n=Y(e,Et);J(n,JSON.stringify(t,null,2)+`
2707
- `)}function vs(e){let t=[];if(!w(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),Yr(e,t,null);let n=qr(Y(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."}),Yr(e,t,An(e));fb(e,n,t),hb(e,n,t),yb(e,t),Sb(e,t),vb(e,t),xb(e,t);let s=An(e);return wb(s,t),Yr(e,t,s)}function Yr(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 fb(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 pb)bt(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 gb)(!(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.'}):(bt(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."}),bt(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."}),bt(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=Fm(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 hb(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Fm(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 yb(e,t){let n=Y(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=Xr(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=Y(n,i);bb(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 bb(e,t,n,s){let o=qr(Y(t,"meta.json")),i=it(e,Y(t,"meta.json"));o?(bt(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=Y(t,"fields.json"),a=it(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=qr(r);Array.isArray(c)?Nm(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=Y(t,"module.html");w(l)||s.push({severity:"error",rule:"module.html.missing",file:it(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function Nm(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)";bt(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}),!bt(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)&&Nm(i.children,t,n,s)}}function Sb(e,t){let n=[],s=Y(e,"css");Zo(s,".css").forEach(i=>{Rm(i,n,e)});let o=Y(e,"modules");if(w(o))for(let i of xs(o)){if(!i.endsWith(".module"))continue;let r=Y(o,i);["module.css","module.html"].forEach(a=>{let l=Y(r,a);w(l)&&Rm(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 Rm(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:it(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:it(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:it(n,e),match:r[0]})}function vb(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=Y(e,"css");Zo(o,".css").forEach(a=>s.push(a));let i=Y(e,"js");Zo(i,".js").forEach(a=>s.push(a));let r=Y(e,"modules");if(w(r))for(let a of xs(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=Y(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:it(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function xb(e,t){let n=Y(e,"modules");if(w(n))for(let s of xs(n)){if(!s.endsWith(".module"))continue;let o=Y(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:it(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:it(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 wb(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Et,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?Jt.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Et,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${Jt.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Et,message:"marketplace.json has no category",fix:`Pick one of: ${Jt.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Et,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:Et,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:Et,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:Et,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function ei(e){let t=[],n=[],s=Y(e,"modules");if(w(s))for(let i of xs(s)){if(!i.endsWith(".module"))continue;let r=Y(s,i),a=i.replace(/\.module$/,""),l=Y(r,"meta.json");if(w(l))try{let d=JSON.parse(E(l));bt(d,"label")||(d.label=jm(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=Y(r,"fields.json");if(w(c))try{let d=JSON.parse(E(c));if(Array.isArray(d)){let u=Om(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=Cb(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function Cb(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(it(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(it(e,c)))}Zo(Y(e,"css"),".css").forEach(r);let l=Y(e,"modules");if(w(l))for(let c of xs(l)){if(!c.endsWith(".module"))continue;let d=Y(l,c),u=Y(d,"module.css"),m=Y(d,"module.html");w(u)&&r(u),w(m)&&a(m)}return t}function Om(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!bt(s,"label")&&bt(s,"name")&&(s.label=jm(String(s.name)),t++),Array.isArray(s.children)&&(t+=Om(s.children))}return t}function qr(e){if(!w(e))return null;try{let t=JSON.parse(E(e));return t&&typeof t=="object"?t:null}catch{return null}}function bt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Fm(e,t){let n=t.replace(/^\.?\//,"");return Y(e,n)}function it(e,t){return mb(e,t).split("\\").join("/")}function xs(e){try{return Xr(e)}catch{return[]}}function Zo(e,t){if(!w(e))return[];try{let n=[];for(let s of Xr(e)){let o=Y(e,s);ub(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function jm(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var Jt,pb,gb,Et,Zr=R(()=>{"use strict";h();se();Jt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],pb=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],gb=["enable_domain_stylesheets","is_available_for_new_content"],Et="marketplace.json"});function Qr(e){let t=k();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{ke()}catch{}return t.themePath}function Dm(e,t){let n=Qr(t);if(!n)return;let s=vs(n);p(t,200,{report:s,categories:Jt})}function Lm(e,t){let n=Qr(t);if(!n)return;let s=ei(n),o=vs(n);p(t,200,{fix:s,report:o})}function Jm(e,t,n){let s=Qr(n);if(s){if(e==="GET"){p(n,200,{metadata:An(s),categories:Jt});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};Qo(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Bm=R(()=>{"use strict";h();ze();we();Zr()});function kb(e){let t=k();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{ke()}catch{}return t.themePath}function Hm(e,t){let n=kb(t);if(!n)return;let s=yo(n);p(t,200,{report:s})}function Gm(e,t){let n=k();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=fn(n.themePath),o=qn(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=bo(n.themePath,n.themeName);i?p(t,200,{applied:!0,written:i,rootBlock:o}):p(t,200,{applied:!1,reason:"Theme already has shared CSS."})}var Um=R(()=>{"use strict";h();ze();we();So()});import{createServer as Tb}from"http";import{readFileSync as ta,existsSync as ws}from"fs";import{join as It,extname as Km}from"path";import{WebSocketServer as Ab,WebSocket as $b}from"ws";function Me(e){ni&&ni.readyState===$b.OPEN&&ni.send(JSON.stringify(e))}function ti(e){si.push(e),Me(e)}function Mt(){si=[]}function ea(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;ti(o)}else ti(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}),Nt(n.moduleOrder),ti({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}]}),ti({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 zm}function oi(e){let{port:t,uiDir:n}=e;zm=e.contentMode||"page";let s=Tb((i,r)=>_b(i,r,n)),o=new Ab({server:s});return o.on("connection",i=>Mb(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 _b(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/")){Eb(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=zi();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=Yi(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){Ib(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";Wm(i,It(n,"docs"),e,t);return}Wm(s.pathname,n,e,t)}function Eb(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":lm(e,s);break;case"/api/modules":cm(e,n,s);break;case"/api/modules/reorder":um(n,s);break;case"/api/modules/code":dm(n,s);break;case"/api/upload":mm(s);break;case"/api/upload-files":e==="POST"?Cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":pm(n,s);break;case"/api/import":gm(n,s);break;case"/api/setup":iu(s);break;case"/api/setup/create":ru(n,s);break;case"/api/setup/fetch":lu(n,s);break;case"/api/setup/open":cu(n,s);break;case"/api/setup/resume":du(n,s);break;case"/api/setup/apikey":uu(n,s);break;case"/api/setup/remote-themes":e==="GET"?mu(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?au(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?Su(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?vu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?xu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?wu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?Cu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?ku(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?Tu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Au(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?$u(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?_u(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Eu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Ru(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Nu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Ou(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Mu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:ma()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":ju(e,n,s);break;case"/api/themes/switch":e==="POST"?Du(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Lu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Ju(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?Bu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?hm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Ku(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":zu(e,n,s);break;case"/api/templates/activate":e==="POST"?Yu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?qu(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"?Xu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?Qu(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":tm(e,n,s);break;case"/api/brand-kit":om(e,n,s);break;case"/api/fonts":e==="GET"?sm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?im(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?rm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Vu(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?Wr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?Kr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?Vr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Fd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?jd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Dd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?Ld(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?Dm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?Lm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Jm(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Hm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Gm(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?Iu(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?em(t,n,s):p(s,404,{error:"Not found"})}}function Mb(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(Er()){nt("user",o),D();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await _r(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=Bd(l||a);c.plan&&(Ro(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})),nt("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}nt("user",o),D();let r=Mr();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Mt();let l=[],c=[],d=await Io(o,ea(l,c),i);qt(d,{steps:l,modules:c,stats:d.stats})}else Ar(l=>{Me({type:"parse_warning",message:l})}),await ms(o,l=>{Me({type:"stream",content:l})},l=>{Me({type:"stream_status",content:l})},i);let a=k();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=Ei(a.themePath,l.id,o,d)}else c=Wt(a.themePath,o);c&&Me({type:"version_created",hash:c})}Me({type:"generation_complete"});{let l=k();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}))})}Mt();{let l=k();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Me({type:"suggest_brand_extraction"})}}catch(a){Mt(),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(()=>(zr(),Pm)),a=r(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=k();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:y}=await import("fs"),{createThemeScaffold:f}=await Promise.resolve().then(()=>(Bn(),Pa)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!y(b)){let{mkdirSync:x}=await import("fs");x(b,{recursive:!0})}y(S)||f(S,i),pn(S,i),D()}Me({type:"figma_import_started",fileName:a.fileName}),Mt();let c=[],d=[],u=await ps(a,i,ea(c,d));qt(u,{steps:c,modules:d,stats:u.stats}),ke(),Wt(k().themePath,`Figma import: ${a.fileName}`),Me({type:"generation_complete"});{let m=k();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}))})}Mt()}catch(l){Mt(),Me({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=k();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=O(),{engine:r,apiKey:a,model:l}=xn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ts(),wo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(Ho(),Bo)),m=await u(d,o.brandAssets?.themeContext,r,a,l),{mkdirSync:g,writeFileSync:y}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let f=It(o.themePath,".vibespot");ws(f)||g(f,{recursive:!0}),y(It(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(()=>(ys(),hs)),b=await f(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=It(o.themePath,".vibespot");ws(S)||g(S,{recursive:!0}),y(It(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=k();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{ke();let i=eo(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 no(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2753
+ `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=$S(r),d=yi(a.themePath,".vibespot");if(Cp(d)||kp(d,{recursive:!0}),kS(yi(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,j(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)Pt("landing_page","Landing Page");else{a.modules=[],a.moduleOrder=[],a.sharedCss="",a.sharedJs="";let f=a.templates.find(b=>b.id===a.activeTemplateId);f&&(f.modules=[],f.moduleOrder=[],f.sharedCss="",f.sharedJs="")}if(j(),i&&r.assets.length>0){let f=yi(a.themePath,"assets");kp(f,{recursive:!0});let b=0;for(let S of r.assets)if(Cp(S.localPath)){let v=yi(f,AS(S.localPath));try{TS(S.localPath,v),S.localPath=v,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],g=await Ps(r,o,f=>{if(f.type==="agent_step")u.push({step:f.step,label:f.label}),l({type:"progress",message:`${f.label}...`});else if(f.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(f.decision)),l({type:"progress",message:` ${f.decision}`})}else f.type==="design_system_ready"?He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Ht(f.moduleOrder),l({type:"progress",message:`Planned ${f.moduleOrder.length} modules`})):f.type==="module_progress"&&(f.status==="generating"?l({type:"progress",message:`Generating module: ${f.module}`}):f.status==="complete"&&f.moduleFiles?(He({modules:[{moduleName:f.module,fieldsJson:f.moduleFiles.fieldsJson,metaJson:f.moduleFiles.metaJson,moduleHtml:f.moduleFiles.moduleHtml,moduleCss:f.moduleFiles.moduleCss,moduleJs:f.moduleFiles.moduleJs}]}),m.push({name:f.module,status:"complete"}),l({type:"progress",message:`Module complete: ${f.module}`})):f.status==="failed"&&(m.push({name:f.module,status:"failed"}),l({type:"progress",message:`Module failed: ${f.module}`})))},{useAssets:i});cn(g,{steps:u,modules:m,stats:g.stats}),Te(),sn(a.themePath,`Figma import: ${r.fileName}`);let h=ve().map(f=>f.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${h.length} modules generated`}),l({type:"complete",ok:!0,modules:h})}catch(c){let d=c instanceof Error?c.message:String(c);E.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Ds,_S,wa=N(()=>{"use strict";y();Xe();ee();le();xp();Ce();ds();pr();In();Gn();Ut();Ds=new Map,_S=1800*1e3});import{readdirSync as Ta,statSync as ES}from"fs";import{join as q,relative as MS}from"path";function zn(e){let t=q(e,Ft);if(!x(t))return null;try{return JSON.parse(P(t))}catch{return null}}function Si(e,t){let n=q(e,Ft);J(n,JSON.stringify(t,null,2)+`
2754
+ `)}function js(e){let t=[];if(!x(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),Ca(e,t,null);let n=ka(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."}),Ca(e,t,zn(e));NS(e,n,t),RS(e,n,t),OS(e,t),DS(e,t),jS(e,t),LS(e,t);let s=zn(e);return JS(s,t),Ca(e,t,s)}function Ca(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 NS(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 IS)kt(t,r)||n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json is missing required field "${r}"`,fix:s[r]??`Add a "${r}" entry to theme.json.`});for(let r of PS)(!(r in t)||typeof t[r]!="boolean")&&n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json must declare boolean "${r}"`,fix:`Add "${r}": true (or false) to theme.json.`});let o=t.author;!o||typeof o!="object"?n.push({severity:"error",rule:"theme.json.author.missing",file:"theme.json",message:'theme.json is missing required "author" block',fix:'Add { "author": { "name": "...", "email": "...", "url": "..." } } to theme.json.'}):(kt(o,"name")||n.push({severity:"error",rule:"theme.json.author.name.missing",file:"theme.json",message:"theme.json author.name is missing",fix:"Provide a publisher name in theme.json author.name."}),kt(o,"email")||n.push({severity:"error",rule:"theme.json.author.email.missing",file:"theme.json",message:"theme.json author.email is missing",fix:"Provide a contact email in theme.json author.email."}),kt(o,"url")||n.push({severity:"error",rule:"theme.json.author.url.missing",file:"theme.json",message:"theme.json author.url is missing",fix:"Add a public URL for the publisher (homepage or support page)."}));let i=t.preview_path;if(typeof i=="string"&&i.length>0){let r=Ip(e,i);x(r)||n.push({severity:"error",rule:"theme.json.preview_path.invalid",file:"theme.json",message:`preview_path "${i}" does not point to an existing file`,fix:"Update preview_path to a real template, e.g. ./templates/home.html."})}}function RS(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Ip(e,s);if(!x(o)){n.push({severity:"error",rule:"theme.json.screenshot.missing",file:"theme.json",message:`Screenshot not found at ${s}`,fix:"Place a 1500\xD71000 PNG at the screenshot_path declared in theme.json."});return}/\.(png|jpg|jpeg)$/i.test(s)||n.push({severity:"warning",rule:"theme.json.screenshot.format",file:s,message:"Screenshot should be a PNG or JPG",fix:"Re-export the screenshot as PNG (1500\xD71000) or JPG."})}function OS(e,t){let n=q(e,"modules");if(!x(n)){t.push({severity:"warning",rule:"modules.empty",message:"Theme has no modules/ directory",fix:"Generate at least one module before submitting to Marketplace."});return}let s=0,o=[];try{o=Ta(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=q(n,i);FS(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 FS(e,t,n,s){let o=ka(q(t,"meta.json")),i=mt(e,q(t,"meta.json"));o?(kt(o,"label")||s.push({severity:"error",rule:"module.meta.label.missing",file:i,message:`${n}: meta.json is missing "label"`,fix:`Add a "label" entry to the module's meta.json.`,autoFixable:!0}),o.is_available_for_new_content===!1&&s.push({severity:"info",rule:"module.meta.unavailable",file:i,message:`${n}: is_available_for_new_content=false (won\u2019t be selectable in HubSpot UI)`})):s.push({severity:"error",rule:"module.meta.missing",file:i,message:`${n}: meta.json is missing or invalid`,fix:"Recreate the module so meta.json is generated."});let r=q(t,"fields.json"),a=mt(e,r);if(!x(r))s.push({severity:"warning",rule:"module.fields.missing",file:a,message:`${n}: fields.json is missing`,fix:"Add a fields.json (an empty array [] is acceptable for static modules)."});else{let c=ka(r);Array.isArray(c)?Ep(c,n,a,s):s.push({severity:"warning",rule:"module.fields.invalid",file:a,message:`${n}: fields.json is not a JSON array`})}let l=q(t,"module.html");x(l)||s.push({severity:"error",rule:"module.html.missing",file:mt(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function Ep(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)";kt(i,"label")||s.push({severity:"error",rule:"module.field.label.missing",file:n,message:`${t}.${r}: field is missing "label"`,fix:`Add a human-readable "label" to the "${r}" field in fields.json.`,autoFixable:!0}),!kt(i,"help_text")&&i.type!=="group"&&s.push({severity:"info",rule:"module.field.help_text.missing",file:n,message:`${t}.${r}: consider adding "help_text"`,fix:`Add a short "help_text" describing what "${r}" controls.`}),Array.isArray(i.children)&&Ep(i.children,t,n,s)}}function DS(e,t){let n=[],s=q(e,"css");bi(s,".css").forEach(i=>{$p(i,n,e)});let o=q(e,"modules");if(x(o))for(let i of Ls(o)){if(!i.endsWith(".module"))continue;let r=q(o,i);["module.css","module.html"].forEach(a=>{let l=q(r,a);x(l)&&$p(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 $p(e,t,n){let s;try{s=P(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:mt(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:mt(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:mt(n,e),match:r[0]})}function jS(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");bi(o,".css").forEach(a=>s.push(a));let i=q(e,"js");bi(i,".js").forEach(a=>s.push(a));let r=q(e,"modules");if(x(r))for(let a of Ls(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=q(r,a,l);x(c)&&s.push(c)});for(let a of s){let l;try{l=P(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:mt(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function LS(e,t){let n=q(e,"modules");if(x(n))for(let s of Ls(n)){if(!s.endsWith(".module"))continue;let o=q(n,s,"module.html");if(!x(o))continue;let i;try{i=P(o)}catch{continue}let r=/<img\b([^>]*)>/gi,a;for(;a=r.exec(i);){let c=a[1];/\balt\s*=/.test(c)||t.push({severity:"warning",rule:"a11y.img.alt-missing",file:mt(e,o),message:`${s}: <img> without alt attribute`,fix:'Add an alt attribute (alt="" is fine for purely decorative images).'})}/<(section|article|header|footer|main|nav|aside|h[1-6])\b/i.test(i)||t.push({severity:"info",rule:"a11y.semantics.missing",file:mt(e,o),message:`${s}: module.html has no semantic landmarks (section/article/header/etc.)`,fix:"Wrap the module's main content in a <section> with a heading."})}}function JS(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Ft,message:"marketplace.json sidecar not found",fix:"Run `vibespot marketplace edit` (CLI) or open the Marketplace panel in the editor to fill in listing details."});return}e.category?Yt.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Ft,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${Yt.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Ft,message:"marketplace.json has no category",fix:`Pick one of: ${Yt.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Ft,message:"marketplace.json description is missing or short (<40 chars)",fix:"Provide a 1\u20132 sentence description of the theme for the Marketplace listing."}),e.supportUrl||t.push({severity:"warning",rule:"marketplace.json.supportUrl.missing",file:Ft,message:"marketplace.json has no supportUrl",fix:"Add a public support URL where buyers can reach the publisher."});let n=e.features?.length??0;n<2?t.push({severity:"warning",rule:"marketplace.json.features.too_few",file:Ft,message:`marketplace.json needs at least 2 features (has ${n})`,fix:"Add 2\u20135 short bullet points highlighting what the theme does well."}):n>5&&t.push({severity:"warning",rule:"marketplace.json.features.too_many",file:Ft,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function vi(e){let t=[],n=[],s=q(e,"modules");if(x(s))for(let i of Ls(s)){if(!i.endsWith(".module"))continue;let r=q(s,i),a=i.replace(/\.module$/,""),l=q(r,"meta.json");if(x(l))try{let d=JSON.parse(P(l));kt(d,"label")||(d.label=Pp(a),J(l,JSON.stringify(d,null,2)+`
2755
+ `),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=q(r,"fields.json");if(x(c))try{let d=JSON.parse(P(c));if(Array.isArray(d)){let u=Mp(d);u>0&&(J(c,JSON.stringify(d,null,2)+`
2756
+ `),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=BS(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function BS(e){let t=[],n=/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,s=/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,o=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*><\/script>/gi,i=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*\/>/gi;function r(c){let d;try{d=P(c)}catch{return}let u=d.replace(n,"");u!==d&&(J(c,u),t.push(mt(e,c)))}function a(c){let d;try{d=P(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(J(c,u),t.push(mt(e,c)))}bi(q(e,"css"),".css").forEach(r);let l=q(e,"modules");if(x(l))for(let c of Ls(l)){if(!c.endsWith(".module"))continue;let d=q(l,c),u=q(d,"module.css"),m=q(d,"module.html");x(u)&&r(u),x(m)&&a(m)}return t}function Mp(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!kt(s,"label")&&kt(s,"name")&&(s.label=Pp(String(s.name)),t++),Array.isArray(s.children)&&(t+=Mp(s.children))}return t}function ka(e){if(!x(e))return null;try{let t=JSON.parse(P(e));return t&&typeof t=="object"?t:null}catch{return null}}function kt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Ip(e,t){let n=t.replace(/^\.?\//,"");return q(e,n)}function mt(e,t){return MS(e,t).split("\\").join("/")}function Ls(e){try{return Ta(e)}catch{return[]}}function bi(e,t){if(!x(e))return[];try{let n=[];for(let s of Ta(e)){let o=q(e,s);ES(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Pp(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var Yt,IS,PS,Ft,Aa=N(()=>{"use strict";y();oe();Yt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],IS=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],PS=["enable_domain_stylesheets","is_available_for_new_content"],Ft="marketplace.json"});function _a(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Te()}catch{}return t.themePath}function Np(e,t){let n=_a(t);if(!n)return;let s=js(n);p(t,200,{report:s,categories:Yt})}function Rp(e,t){let n=_a(t);if(!n)return;let s=vi(n),o=js(n);p(t,200,{fix:s,report:o})}function Op(e,t,n){let s=_a(n);if(s){if(e==="GET"){p(n,200,{metadata:zn(s),categories:Yt});return}if(e==="POST"){qe(t,n,o=>{let i={category:typeof o.category=="string"?o.category:void 0,description:typeof o.description=="string"?o.description:void 0,features:Array.isArray(o.features)?o.features.filter(r=>typeof r=="string"&&r.trim().length>0):void 0,supportUrl:typeof o.supportUrl=="string"?o.supportUrl:void 0,documentationUrl:typeof o.documentationUrl=="string"?o.documentationUrl:void 0,pricingTier:o.pricingTier==="free"||o.pricingTier==="paid"?o.pricingTier:void 0,tags:Array.isArray(o.tags)?o.tags.filter(r=>typeof r=="string"):void 0};Si(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Fp=N(()=>{"use strict";y();Xe();Ce();Aa()});function HS(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Te()}catch{}return t.themePath}function Dp(e,t){let n=HS(t);if(!n)return;let s=jo(n);p(t,200,{report:s})}function jp(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=gs(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(),j(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=Lo(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 Lp=N(()=>{"use strict";y();Xe();Ce();Jo()});import{createServer as US}from"http";import{readFileSync as Ma,existsSync as Js}from"fs";import{join as jt,extname as Bp}from"path";import{WebSocketServer as GS,WebSocket as WS}from"ws";function Ae(e){wi&&wi.readyState===WS.OPEN&&wi.send(JSON.stringify(e))}function xi(e){Ci.push(e),Ae(e)}function Dt(){Ci=[]}function $a(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;xi(o)}else xi(n);if(n.type==="agent_step")e.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=e[e.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Ht(n.moduleOrder),xi({type:"modules_updated",modules:ve().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(He({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),xi({type:"modules_updated",modules:ve().map(s=>s.moduleName)}),t.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&t.push({name:n.module,status:"failed"})}}function Ea(e){let t=e.cost;if(!t||t.calls===0)return;let n=C();Ae({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}function Ln(){return Up}function ki(e){let{port:t,uiDir:n}=e;Up=e.contentMode||"page";let s=US((i,r)=>KS(i,r,n)),o=new GS({server:s});return o.on("connection",i=>zS(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 KS(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/")){VS(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=Sr();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=vr(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){YS(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";Jp(i,jt(n,"docs"),e,t);return}Jp(s.pathname,n,e,t)}function VS(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":sp(e,s);break;case"/api/modules":op(e,n,s);break;case"/api/modules/reorder":rp(n,s);break;case"/api/modules/code":ip(n,s);break;case"/api/upload":ap(s);break;case"/api/upload-files":e==="POST"?ld(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":lp(n,s);break;case"/api/import":cp(n,s);break;case"/api/setup":zu(s);break;case"/api/setup/create":Yu(n,s);break;case"/api/setup/fetch":Xu(n,s);break;case"/api/setup/open":Zu(n,s);break;case"/api/setup/resume":Qu(n,s);break;case"/api/setup/apikey":em(n,s);break;case"/api/setup/remote-themes":e==="GET"?tm(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?qu(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?cm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/models":e==="GET"?dm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/tools":e==="GET"?um(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?mm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?pm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?gm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?hm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?ym(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?bm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?Sm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?vm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?xm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Am(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?_m(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?wm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Ba()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Em(e,n,s);break;case"/api/themes/switch":e==="POST"?Mm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Im(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Pm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?Nm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?dp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?up(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Jm(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Um(e,n,s);break;case"/api/templates/activate":e==="POST"?Gm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?Wm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?Vm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?Km(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?zm(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":qm(e,n,s);break;case"/api/brand-kit":Qm(e,n,s);break;case"/api/fonts":e==="GET"?Zm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?ep(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?tp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Hm(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?Sa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?va(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?xa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Tu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Au(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?_u(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?$u(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?Np(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?Rp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Op(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Dp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?jp(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?Cm(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?Ym(t,n,s):p(s,404,{error:"Not found"})}}function zS(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(ta()){lt("user",o),j();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await ea(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=Mu(l||a);c.plan&&(Qo(c.plan),e.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&e.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),lt("assistant",c.cleanedContent),j(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(a){e.send(JSON.stringify({type:"error",message:a instanceof Error?a.message:String(a)}))}break}lt("user",o),j();let r=na();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Dt();let l=[],c=[],d=await Xo(o,$a(l,c),i);cn(d,{steps:l,modules:c,stats:d.stats,cost:d.cost}),Ea(d)}else Zr(l=>{Ae({type:"parse_warning",message:l})}),await Is(o,l=>{Ae({type:"stream",content:l})},l=>{Ae({type:"stream_status",content:l})},i);let a=C();if(a){Te();let l=ke(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${a.themeName}-theme.css`),l.sharedJs&&d.push(`js/${a.themeName}-animations.js`),c=nr(a.themePath,l.id,o,d)}else c=sn(a.themePath,o);c&&Ae({type:"version_created",hash:c})}Ae({type:"generation_complete"});{let l=C();Ae({type:"modules_updated",modules:ve().map(c=>c.moduleName),templateId:l?.activeTemplateId||null,templates:(l?.templates||[]).map(c=>({id:c.id,label:c.label,pageType:c.pageType,moduleCount:c.modules.length}))})}Dt();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Ae({type:"suggest_brand_extraction"})}}catch(a){Dt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:r}=await Promise.resolve().then(()=>(wa(),_p)),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(()=>(os(),ul)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!h(b)){let{mkdirSync:v}=await import("fs");v(b,{recursive:!0})}h(S)||f(S,i),Rn(S,i),j()}Ae({type:"figma_import_started",fileName:a.fileName}),Dt();let c=[],d=[],u=await Ps(a,i,$a(c,d));cn(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),Ea(u),Te(),sn(C().themePath,`Figma import: ${a.fileName}`),Ae({type:"generation_complete"});{let m=C();Ae({type:"modules_updated",modules:ve().map(g=>g.moduleName),templateId:m?.activeTemplateId||null,templates:(m?.templates||[]).map(g=>({id:g.id,label:g.label,pageType:g.pageType,moduleCount:g.modules.length}))})}Dt()}catch(l){Dt(),Ae({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=R(),{engine:r,apiKey:a,model:l}=Un(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(bs(),Ho)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(li(),ai)),m=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>te("extract-theme-context",()=>u(d,o.brandAssets?.themeContext,r,a,l))),{mkdirSync:g,writeFileSync:h}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let f=jt(o.themePath,".vibespot");Js(f)||g(f,{recursive:!0}),h(jt(f,"theme-context.md"),m),j(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(Fs(),Os)),b=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>f(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=jt(o.themePath,".vibespot");Js(S)||g(S,{recursive:!0}),h(jt(S,"styleguide.md"),b),j(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Te();let i=Co(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(R().hubspotUploadMode||"api")==="api"){let l=Le();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await To(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2710
2757
  `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
2711
2758
  `}))},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=Pt();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=Zs(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=Oo(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:It(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}))};Ud(l,c);let d=setInterval(()=>{let u=No(l);if(!(!u||u.status==="running"))if(clearInterval(d),Wd(l,c),u.status==="completed"){let m=dt(),g=m.portalId?Nn(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=Qs(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.
2759
+ `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Lt();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:Ln()}))}else{let d=xo(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2760
+ `),errors:d}))}}else{let l=ti(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:jt(o.themePath,".."),timeout:18e4});e.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{e.send(JSON.stringify({type:"upload_output",chunk:u}))};Nu(l,c);let d=setInterval(()=>{let u=ei(l);if(!(!u||u.status==="running"))if(clearInterval(d),Ru(l,c),u.status==="completed"){let m=ht(),g=m.portalId?Qn(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:Ln()}))}else{let m=wo(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
2761
 
2715
2762
  IMPORTANT: Be verbose in your response. For each error:
2716
2763
  1. State exactly which file has the problem and what the error is
@@ -2723,27 +2770,27 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
2723
2770
  After fixing all errors, summarize the changes you made.
2724
2771
 
2725
2772
  Upload log:
2726
- ${o}`;nt("user",i),D(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await ms(i,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=k();if(r){ke();let a=Wt(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=k();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=k();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}z({planMode:!1});let r="Implement the approved plan.";nt("user",r),D();try{Mt();let a=[],l=[],c=await Io(r,ea(a,l));qt(c,{steps:a,modules:l,stats:c.stats});let d=k();if(d){ke();let u=Ce(),m=null;if(u){let g=u.moduleOrder.map(y=>`modules/${y}.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=Ei(d.themePath,u.id,"Approved plan: implementation",g)}else m=Wt(d.themePath,"Approved plan: implementation");m&&Me({type:"version_created",hash:m})}Me({type:"generation_complete"});{let u=k();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}))})}Mt()}catch(a){Mt(),Me({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{Pr(),z({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),ni=e;let t=k();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=jt(),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:et(),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&&si.length>0)for(let r of si)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function Ib(e,t){let n=k();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=It(n.themePath,"assets",e);if(!ws(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Km(s),i=Vm[o]||"application/octet-stream",r=ta(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Wm(e,t,n,s){let i=It(t,e==="/"?"/index.html":e);if(!ws(i)){let c=It(t,"index.html");if(ws(c)){let d=ta(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=Km(i),a=Vm[r]||"application/octet-stream",l=r===".html";try{let c=ta(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 Vm,ni,si,zm,ns=R(()=>{"use strict";h();we();dn();ts();wn();Jd();Hd();ee();Gt();to();Fo();$i();ze();se();Ko();Pu();Fu();Hu();am();ym();cr();zr();Bm();Um();Vm={".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"},ni=null,si=[];zm="page"});h();h();import{Command as Ub}from"commander";h();h();at();se();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()}h();Gt();xt();Bt();ee();Ut();Ye();at();async function Js(){await me("Checking your environment");let e=In();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Os(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),H(`Node.js v${e.version}`);let t=Pn();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),H(`Git ${t.version}`);let n=O(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Fe(),S=Pt();if(b)o=S?.portalId||"",i=S?.portalName||"",H(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{te("No HubSpot account connected"),await ut(`You need a Personal Access Key to deploy themes.
2773
+ ${o}`;lt("user",i),j(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await Is(i,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=C();if(r){Te();let a=sn(r.themePath,"AI fix: upload errors");a&&e.send(JSON.stringify({type:"version_created",hash:a}))}e.send(JSON.stringify({type:"upload_fix_complete"}));{let a=C();e.send(JSON.stringify({type:"modules_updated",modules:ve().map(l=>l.moduleName),templateId:a?.activeTemplateId||null,templates:(a?.templates||[]).map(l=>({id:l.id,label:l.label,pageType:l.pageType,moduleCount:l.modules.length}))}))}}catch(r){e.send(JSON.stringify({type:"upload_failed",output:r instanceof Error?r.message:String(r),errors:[{file:"AI fix",message:r instanceof Error?r.message:String(r),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.brandAssets?.plan;if(!i||!i.trim()){e.send(JSON.stringify({type:"error",message:"No plan to approve. Send a chat message first."}));break}Y({planMode:!1});let r="Implement the approved plan.";lt("user",r),j();try{Dt();let a=[],l=[],c=await Xo(r,$a(a,l));cn(c,{steps:a,modules:l,stats:c.stats,cost:c.cost}),Ea(c);let d=C();if(d){Te();let u=ke(),m=null;if(u){let g=u.moduleOrder.map(h=>`modules/${h}.module`);u.templateFile&&g.push(u.templateFile),u.sharedCss&&g.push(`css/${d.themeName}-theme.css`),u.sharedJs&&g.push(`js/${d.themeName}-animations.js`),m=nr(d.themePath,u.id,"Approved plan: implementation",g)}else m=sn(d.themePath,"Approved plan: implementation");m&&Ae({type:"version_created",hash:m})}Ae({type:"generation_complete"});{let u=C();Ae({type:"modules_updated",modules:ve().map(m=>m.moduleName),templateId:u?.activeTemplateId||null,templates:(u?.templates||[]).map(m=>({id:m.id,label:m.label,pageType:m.pageType,moduleCount:m.modules.length}))})}Dt()}catch(a){Dt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{oa(),Y({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),wi=e;let t=C();if(t){let n=R(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Kt(),i=ke();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:ve().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:rt(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",updatedAt:t.updatedAt,templateId:i?.id||null,pageType:i?.pageType||null,templates:(t.templates||[]).map(r=>({id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||"",isGenerating:o,costTotal:t.costTotal||null})),o&&Ci.length>0)for(let r of Ci)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function YS(e,t){let n=C();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=jt(n.themePath,"assets",e);if(!Js(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Bp(s),i=Hp[o]||"application/octet-stream",r=Ma(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Jp(e,t,n,s){let i=jt(t,e==="/"?"/index.html":e);if(!Js(i)){let c=jt(t,"index.html");if(Js(c)){let d=Ma(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=Bp(i),a=Hp[r]||"application/octet-stream",l=r===".html";try{let c=Ma(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 Hp,wi,Ci,Up,Ss=N(()=>{"use strict";y();Ce();In();bs();Gn();Eu();Iu();ee();Qt();ko();ni();er();Xe();oe();Be();mi();km();$m();Rm();np();mp();Rr();wa();Fp();Lp();Hp={".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"},wi=null,Ci=[];Up="page"});y();y();import{Command as lv}from"commander";y();y();gt();oe();function Ee(){let e=I.vibes,t=I.accent,n=I.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${I.dim(`v${yn()}`)}`),console.log()}y();Qt();_t();qt();ee();en();Qe();gt();async function io(){await ge("Checking your environment");let e=Xn();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),eo(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),G(`Node.js v${e.version}`);let t=Zn();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),G(`Git ${t.version}`);let n=R(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Le(),S=Lt();if(b)o=S?.portalId||"",i=S?.portalName||"",G(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{se("No HubSpot account connected"),await yt(`You need a Personal Access Key to deploy themes.
2727
2774
  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:I=>I.trim()?void 0:"Key is required"}),v=await Re();v.start("Validating key...");try{let I=await Ds(x);$n(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"),V(`Invalid key: ${I instanceof Error?I.message:String(I)}`),process.exit(1)}}}else{let b=ct();if(b.found)H(`HubSpot CLI v${b.version}`);else{te("HubSpot CLI not found"),await Ae({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let v=await Re();v.start("Installing HubSpot CLI..."),ne("npm install -g @hubspot/cli").success||(v.stop("Failed"),V("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)H(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{te("HubSpot not authenticated"),await Ae({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let v=await Re();v.start("Waiting for HubSpot authentication..."),ga("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=Rn(),a=On(),l=Fn(),c=va(),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,y=[];if(r.found&&y.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&y.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&y.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&y.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&y.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&y.sort((b,S)=>b.value===g?-1:S.value===g?1:0),y.length===1)m=y[0].value,H(`AI engine: ${d[m]} (auto-detected)`);else if(y.length>1)m=await Ct({message:"Choose your AI engine:",options:y});else if(await ut(`You need an AI coding assistant to power the conversion.
2775
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let v=await Se({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:M=>M.trim()?void 0:"Key is required"}),w=await De();w.start("Validating key...");try{let M=await so(v);Yn(v,M.portalId,M.portalName,M.dataCenter),b=v,o=M.portalId,i=M.portalName,w.stop(`Connected to ${M.portalName} (${M.portalId})`)}catch(M){w.stop("Validation failed"),V(`Invalid key: ${M instanceof Error?M.message:String(M)}`),process.exit(1)}}}else{let b=ft();if(b.found)G(`HubSpot CLI v${b.version}`);else{se("HubSpot CLI not found"),await Me({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let w=await De();w.start("Installing HubSpot CLI..."),ie("npm install -g @hubspot/cli").success||(w.stop("Failed"),V("Try: npm install -g @hubspot/cli"),process.exit(1)),b=ft(),w.stop(`HubSpot CLI v${b.version} installed`)}let S=ht();if(S.authenticated)G(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{se("HubSpot not authenticated"),await Me({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let w=await De();w.start("Waiting for HubSpot authentication..."),Ua("hs init")||(w.stop("Authentication failed"),process.exit(1)),S=ht(),w.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,i=S.portalName}let r=wn(),a=Cn(),l=kn(),c=qa(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex","langdock-api":"Langdock (EU)"},u=Ze(),m,g=n.aiEngine,h=[];if(r.found&&h.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&h.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&h.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&h.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&h.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&h.sort((b,S)=>b.value===g?-1:S.value===g?1:0),h.length===1)m=h[0].value,G(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await Et({message:"Choose your AI engine:",options:h});else if(await yt(`You need an AI coding assistant to power the conversion.
2729
2776
 
2730
- ${_.bold("Option 1:")} Install Claude Code ${_.muted("(recommended)")}
2777
+ ${I.bold("Option 1:")} Install Claude Code ${I.muted("(recommended)")}
2731
2778
  https://claude.ai/code
2732
2779
 
2733
- ${_.bold("Option 2:")} Install Gemini CLI
2780
+ ${I.bold("Option 2:")} Install Gemini CLI
2734
2781
  https://github.com/google-gemini/gemini-cli
2735
2782
 
2736
- ${_.bold("Option 3:")} Install OpenAI Codex
2783
+ ${I.bold("Option 3:")} Install OpenAI Codex
2737
2784
  https://github.com/openai/codex
2738
2785
 
2739
- ${_.bold("Option 4:")} Set an Anthropic API key
2786
+ ${I.bold("Option 4:")} Set an Anthropic API key
2740
2787
  export ANTHROPIC_API_KEY=sk-ant-...
2741
- (get one at https://console.anthropic.com)`,"AI engine required"),m=await Ct({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,z({anthropicApiKey:b})}let f;return m==="claude-code"&&(f=await Ct({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"}]})),z({aiEngine:m}),await pe("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}Hs();h();Bt();se();Ye();at();ee();Bn();Gs();import{join as Gn}from"path";async function Us(){await me("HubSpot Theme Setup");let e=await Ct({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=Gn(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=Gn(s,t);let l=await Re();l.start("Fetching theme from HubSpot...");let c=O(),d=Fe();if(c.hubspotUploadMode==="cli"||!d)ne(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),V(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await Hn(d,t,n)}catch(u){l.stop("Fetch failed"),V(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${_.dim(n)}`)}else{t=await be({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=Gn(s,t);let l=await Re();l.start("Creating theme...");try{Jn(n,t)}catch(c){l.stop("Creation failed"),V(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${_.dim(n)}`)}await me("Checking theme compatibility");let o=Gn(n,"templates/layouts/base.html");w(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),H("base.html found");let i=E(o),r=!1;if(i.includes("template_css"))H("template_css support");else{te("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2788
+ (get one at https://console.anthropic.com)`,"AI engine required"),m=await Et({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),m==="api"){let b=await Se({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:S=>S.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,Y({anthropicApiKey:b})}let f;return m==="claude-code"&&(f=await Et({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),Y({aiEngine:m}),await fe("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}ao();y();qt();oe();Qe();gt();ee();os();lo();import{join as rs}from"path";async function co(){await ge("HubSpot Theme Setup");let e=await Et({message:"Do you have an existing HubSpot theme?",options:[{value:"fetch",label:"Fetch my existing theme from HubSpot",hint:"downloads your current theme"},{value:"create",label:"Start fresh (HubSpot Boilerplate)",hint:"creates a new starter theme"}]}),t,n,s=rs(process.cwd(),"workspace");if(Re(s),e==="fetch"){t=await Se({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=rs(s,t);let l=await De();l.start("Fetching theme from HubSpot...");let c=R(),d=Le();if(c.hubspotUploadMode==="cli"||!d)ie(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),V(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await is(d,t,n)}catch(u){l.stop("Fetch failed"),V(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${I.dim(n)}`)}else{t=await Se({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=rs(s,t);let l=await De();l.start("Creating theme...");try{ss(n,t)}catch(c){l.stop("Creation failed"),V(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${I.dim(n)}`)}await ge("Checking theme compatibility");let o=rs(n,"templates/layouts/base.html");x(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),G("base.html found");let i=P(o),r=!1;if(i.includes("template_css"))G("template_css support");else{se("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2742
2789
  `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
2743
2790
  `,l);i=i.slice(0,c)+`
2744
2791
  {% if template_css %}
2745
2792
  {{ require_css(get_asset_url(template_css)) }}
2746
- {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))H("template_js support");else{te("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2793
+ {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))G("template_js support");else{se("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2747
2794
  `,l),d=i.indexOf(`
2748
2795
  `,c+1),u=`
2749
2796
  {% if template_js %}
@@ -2751,17 +2798,17 @@ ${_.bold("Option 4:")} Set an Anthropic API key
2751
2798
  {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
2752
2799
  `)+1;i=i.slice(0,i.indexOf(`
2753
2800
  `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
2754
- `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await Re();l.start("Patching base.html..."),J(o,i),l.stop("base.html patched with template_css/template_js support")}let a=Gn(n,".hsignore");if(w(a)){let l=E(a);l.includes("docs/")||(J(a,l+`
2801
+ `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await De();l.start("Patching base.html..."),J(o,i),l.stop("base.html patched with template_css/template_js support")}let a=rs(n,".hsignore");if(x(a)){let l=P(a);l.includes("docs/")||(J(a,l+`
2755
2802
  docs/
2756
- `),H("Added docs/ to .hsignore"))}else J(a,`docs/
2803
+ `),G("Added docs/ to .hsignore"))}else J(a,`docs/
2757
2804
  *.md
2758
2805
  node_modules/
2759
2806
  .git
2760
- `),H("Created .hsignore");return await pe("Theme ready!"),{themePath:n,themeName:t}}h();import{join as qe}from"path";import{readdirSync as Wn,rmSync as Wa}from"fs";h();Ge();se();import{spawn as jp}from"child_process";import{join as Z,basename as Dp}from"path";import{readdirSync as mt,statSync as Ga,writeFileSync as Lp}from"fs";var Jp=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"]),Ws=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="",y=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((x,v)=>{let I={...process.env};delete I.CLAUDECODE;let L=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&L.push("--model",this.model);let G=jp("claude",L,{cwd:s,stdio:["pipe","pipe","pipe"],env:I,shell:!0});G.stdout.on("data",F=>{m+=F.toString()}),G.stderr.on("data",F=>{g+=F.toString()}),G.on("error",F=>v(new Error(`Claude Code failed to start: ${F.message}`))),G.on("close",F=>{F!==0?v(new Error(`Claude Code exited with code ${F}.
2807
+ `),G("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}y();import{join as nt}from"path";import{readdirSync as cs,rmSync as Ml}from"fs";y();Ke();oe();import{spawn as Pg}from"child_process";import{join as Q,basename as Ng}from"path";import{readdirSync as bt,statSync as wl,writeFileSync as Rg}from"fs";var Og=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"]),uo=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(t){this.model=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(Q(s,"css")),c=this.listDir(Q(s,"js")),d=this.listDir(Q(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${r} source components found)...`);let m="",g="",h=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((v,w)=>{let M={...process.env};delete M.CLAUDECODE;let L=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&L.push("--model",this.model);let H=Pg("claude",L,{cwd:s,stdio:["pipe","pipe","pipe"],env:M,shell:!0});H.stdout.on("data",B=>{m+=B.toString()}),H.stderr.on("data",B=>{g+=B.toString()}),H.on("error",B=>w(new Error(`Claude Code failed to start: ${B.message}`))),H.on("close",B=>{B!==0?w(new Error(`Claude Code exited with code ${B}.
2761
2808
  `+(g?`Stderr: ${g.slice(0,500)}
2762
- `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):x()}),G.stdin.on("error",()=>{}),G.stdin.write(u),G.stdin.end(),setTimeout(()=>{G.kill(),v(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(y)}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)+`
2809
+ `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):v()}),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=Q(s,"..","vibespot-conversion.log");try{let w=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
2763
2810
  ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
2764
- `);Lp(f,v,"utf-8"),o("status",`Log written to ${Dp(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.
2811
+ `);Rg(f,w,"utf-8"),o("status",`Log written to ${Ng(f)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(v=>!a.has(v.moduleName+".module")).length===0){let v=m.slice(0,1500)||"(no output)",w=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
2765
2812
 
2766
2813
  This usually means the model described the conversion instead of using Write tool to create files.
2767
2814
 
@@ -2772,12 +2819,12 @@ Possible causes:
2772
2819
 
2773
2820
  Source: ${t.sourceDir}
2774
2821
  Theme: ${s}
2775
- `+(v?`
2822
+ `+(w?`
2776
2823
  Stderr:
2777
- ${v}
2824
+ ${w}
2778
2825
  `:"")+`
2779
2826
  Claude output:
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 y=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;r("created",`Module ${y}: ${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.
2827
+ ${v}`)}return b}reportProgress(t,n,s,o,i,r){let a=0,l=this.listDir(Q(t,"css"));for(let m of l){if(s.has(m)||!m.endsWith(".css"))continue;let g=`css:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared CSS (${m})`),a++)}let c=this.listDir(Q(t,"js"));for(let m of c){if(o.has(m)||!m.endsWith(".js"))continue;let g=`js:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared JS (${m})`),a++)}this.expectedModules===0&&(this.expectedModules=this.detectExpectedModules(t,i));let d=this.listModules(t);for(let m of d){if(n.has(m))continue;let g=`module:${m}`;if(!this.reported.has(g)){this.reported.add(g),this.moduleCount++;let h=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;r("created",`Module ${h}: ${m.replace(".module","")}`),a++}}let u=this.listDir(Q(t,"templates"));for(let m of u){if(i.has(m)||!m.endsWith(".html"))continue;let g=`template:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Page template (${m})`),a++)}if(a===0)if(this.moduleCount>0){let m=this.expectedModules>0?`/${this.expectedModules}`:"";r("status",`${this.moduleCount}${m} modules created, conversion continuing...`)}else this.reported.size>0?r("status","Shared assets created, building modules..."):r("status","Claude Code is analyzing source files...")}buildFullPrompt(t,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
2781
2828
 
2782
2829
  SOURCE DIRECTORY: ${t}
2783
2830
  THEME DIRECTORY: ${n}
@@ -2820,16 +2867,16 @@ CSS QUALITY: The converted page must visually match the original React page. Eve
2820
2867
  Do NOT run hs upload \u2014 I will handle that separately.
2821
2868
 
2822
2869
  HUBSPOT CMS RULES:
2823
- ${je()}
2870
+ ${Je()}
2824
2871
 
2825
2872
  CONVERSION GUIDE:
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")&&!Jp.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(!Ga(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 y=Z(l,"module.js");w(y)&&(c.moduleJs=E(y)),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{Ga(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}};h();Ge();se();import Bp from"@anthropic-ai/sdk";import{join as ie,basename as Hp}from"path";import{readdirSync as Ua}from"fs";var Ks=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new Bp({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=Da(o),a=Hp(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,Ja(c,d,l)),m=ie(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),y=this.findInteractiveComponents(n),f=await this.complete(r,Ba(g,y,l)),b=ie(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 G=0;G<S.length;G++){let F=S[G],K=F.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${K}.module (${G+1}/${S.length})...`);let q=E(F.path),N=await this.complete(r,La(q,K,`See css/${l}-theme.css`));try{let C=JSON.parse(N),P={moduleName:K,fieldsJson:typeof C.fieldsJson=="string"?C.fieldsJson:JSON.stringify(C.fieldsJson,null,2),metaJson:typeof C.metaJson=="string"?C.metaJson:JSON.stringify(C.metaJson,null,2),moduleHtml:C.moduleHtml||"",moduleCss:C.moduleCss||"",moduleJs:C.moduleJs||void 0},T=ie(s,"modules",`${K}.module`);Ie(T),J(ie(T,"fields.json"),P.fieldsJson),J(ie(T,"meta.json"),P.metaJson),J(ie(T,"module.html"),P.moduleHtml),J(ie(T,"module.css"),P.moduleCss),P.moduleJs&&J(ie(T,"module.js"),P.moduleJs),x.push(P),i("module-done",`${K}.module (${this.countFiles(P)} files)`)}catch{i("module-error",`Failed to parse ${K} \u2014 skipping`)}}i("template","Creating page template...");let v=x.map(G=>G.moduleName),I=await this.complete(r,Ha(v,a,l)),L=ie(s,"templates",`lp-${l}.html`);return J(L,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=[ie(t,"src/index.css"),ie(t,"src/globals.css"),ie(t,"src/app/globals.css"),ie(t,"app/globals.css")];for(let s of n)if(w(s))return E(s);return""}findAndReadTailwind(t){let n=[ie(t,"tailwind.config.ts"),ie(t,"tailwind.config.js"),ie(t,"tailwind.config.mjs")];for(let s of n)if(w(s))return E(s);return""}findAndReadHooks(t){let n=ie(t,"src/hooks");if(!w(n))return"";try{return Ua(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2827
- ${E(ie(n,s))}`).join(`
2873
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Q(t,"css");if(x(s)){for(let a of bt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Q(s,a));break}}let o=Q(t,"js");if(x(o)){for(let a of bt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Q(o,a));break}}let i=Q(t,"templates");if(x(i)){for(let a of bt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=P(Q(i,a));break}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!Og.has(a)&&!a.startsWith("system")){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=Q(t,"modules");if(x(r))for(let a of bt(r)){if(!a.endsWith(".module"))continue;let l=Q(r,a);if(!wl(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Q(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Q(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Q(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Q(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Q(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=Q(t,"modules");return x(n)?new Set(bt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return x(t)?new Set(bt(t)):new Set}detectExpectedModules(t,n){let s=Q(t,"templates");if(!x(s))return 0;for(let o of bt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=P(Q(s,o));if(i.includes("dnd_area")){let r=i.match(/dnd_module/g);return r?r.length:0}}catch{}return 0}countSourceComponents(t){let n=Q(t,"src");return x(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of bt(t)){let o=Q(t,s);try{wl(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};y();Ke();oe();Be();tn();import ef from"@anthropic-ai/sdk";import{join as ce,basename as tf}from"path";import{readdirSync as El}from"fs";var fo=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new ef({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=yl(o),a=tf(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,Sl(c,d,l)),m=ce(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,vl(g,h,l)),b=ce(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),v=[];for(let H=0;H<S.length;H++){let B=S[H],K=B.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${K}.module (${H+1}/${S.length})...`);let X=P(B.path),O=await this.complete(r,bl(X,K,`See css/${l}-theme.css`));try{let k=JSON.parse(O),T={moduleName:K,fieldsJson:typeof k.fieldsJson=="string"?k.fieldsJson:JSON.stringify(k.fieldsJson,null,2),metaJson:typeof k.metaJson=="string"?k.metaJson:JSON.stringify(k.metaJson,null,2),moduleHtml:k.moduleHtml||"",moduleCss:k.moduleCss||"",moduleJs:k.moduleJs||void 0},$=ce(s,"modules",`${K}.module`);Re($),J(ce($,"fields.json"),T.fieldsJson),J(ce($,"meta.json"),T.metaJson),J(ce($,"module.html"),T.moduleHtml),J(ce($,"module.css"),T.moduleCss),T.moduleJs&&J(ce($,"module.js"),T.moduleJs),v.push(T),i("module-done",`${K}.module (${this.countFiles(T)} files)`)}catch{i("module-error",`Failed to parse ${K} \u2014 skipping`)}}i("template","Creating page template...");let w=v.map(H=>H.moduleName),M=await this.complete(r,xl(w,a,l)),L=ce(s,"templates",`lp-${l}.html`);return J(L,M),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:M,modules:v}}async complete(t,n){let s=new Date,o=await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]}),r=o.content.find(a=>a.type==="text")?.text||"";return St({engine:"anthropic-api",model:this.model,name:"react-conversion",input:{system:t,messages:[{role:"user",content:n}]},output:r,usage:et(o.usage),startTime:s,endTime:new Date}),r}findAndReadCSS(t){let n=[ce(t,"src/index.css"),ce(t,"src/globals.css"),ce(t,"src/app/globals.css"),ce(t,"app/globals.css")];for(let s of n)if(x(s))return P(s);return""}findAndReadTailwind(t){let n=[ce(t,"tailwind.config.ts"),ce(t,"tailwind.config.js"),ce(t,"tailwind.config.mjs")];for(let s of n)if(x(s))return P(s);return""}findAndReadHooks(t){let n=ce(t,"src/hooks");if(!x(n))return"";try{return El(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2874
+ ${P(ce(n,s))}`).join(`
2828
2875
 
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}
2876
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=P(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
2830
2877
  ${i}`)}return s.join(`
2831
2878
 
2832
- `)}findComponents(t){let n=[ie(t,"src/components/landing"),ie(t,"src/components/sections"),ie(t,"src/components")];for(let s of n)if(w(s))try{return Ua(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:ie(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};h();Ge();se();import{spawn as Gp}from"child_process";import{join as Ue}from"path";import{readdirSync as Vs,statSync as Up}from"fs";var zs=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=Gp("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}.
2879
+ `)}findComponents(t){let n=[ce(t,"src/components/landing"),ce(t,"src/components/sections"),ce(t,"src/components")];for(let s of n)if(x(s))try{return El(s).filter(o=>(o.endsWith(".tsx")||o.endsWith(".jsx"))&&!o.startsWith("ui")&&o!=="index.tsx"&&o!=="index.jsx").map(o=>({name:o.replace(/\.(tsx|jsx)$/,""),path:ce(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();Ke();oe();import{spawn as nf}from"child_process";import{join as Ve}from"path";import{readdirSync as ho,statSync as sf}from"fs";var yo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((a,l)=>{let c=nf("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
2880
 
2834
2881
  INSTRUCTIONS:
2835
2882
  1. Analyze all .tsx/.jsx components in the React source
@@ -2844,7 +2891,7 @@ CONVERSION GUIDE:
2844
2891
  ${s}
2845
2892
 
2846
2893
  Do NOT run hs upload \u2014 I will handle that separately.
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 Vs(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 Vs(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 Vs(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 Vs(r)){if(!a.endsWith(".module"))continue;let l=Ue(r,a);if(!Up(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 y=Ue(l,"module.js");w(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};h();Ge();se();import{spawn as Wp}from"child_process";import{join as We}from"path";import{readdirSync as Ys,statSync as Kp}from"fs";var qs=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=Wp("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}.
2894
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ve(t,"css");if(x(s)){for(let a of ho(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Ve(s,a));break}}let o=Ve(t,"js");if(x(o)){for(let a of ho(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Ve(o,a));break}}let i=Ve(t,"templates");if(x(i)){for(let a of ho(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Ve(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ve(t,"modules");if(x(r))for(let a of ho(r)){if(!a.endsWith(".module"))continue;let l=Ve(r,a);if(!sf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ve(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Ve(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Ve(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Ve(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Ve(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ke();oe();import{spawn as of}from"child_process";import{join as ze}from"path";import{readdirSync as bo,statSync as rf}from"fs";var So=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((a,l)=>{let c=of("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
2895
 
2849
2896
  INSTRUCTIONS:
2850
2897
  1. Analyze all .tsx/.jsx components in the React source
@@ -2859,15 +2906,15 @@ CONVERSION GUIDE:
2859
2906
  ${s}
2860
2907
 
2861
2908
  Do NOT run hs upload \u2014 I will handle that separately.
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 Ys(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 Ys(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 Ys(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 Ys(r)){if(!a.endsWith(".module"))continue;let l=We(r,a);if(!Kp(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 y=We(l,"module.js");w(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ge();se();Ye();function Vp(e,t){switch(e){case"claude-code":return new Ws(t);case"gemini-cli":return new zs;case"codex-cli":return new qs;case"api":return new Ks}}async function Xs(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=Vp(e.aiEngine,e.model),n=fe(),s=await Re();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(y,f)=>{y==="created"?H(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=zp(e.themePath);for(let y of a)H(`Auto-fixed: ${y}`);let l=Yp(e.themePath,i),c=[];for(let y of l){let f=y.passed?"\u2705":"\u274C",b=y.passed?"":y.critical?" (CRITICAL)":" (cosmetic)";c.push(`${f} ${y.label}${b}`)}let d=l.filter(y=>y.passed).length;c.push(`
2864
- ${d}/${l.length} checks passed`),await ut(c.join(`
2865
- `),"Conversion Checklist");let u=l.filter(y=>!y.passed&&y.critical),m=l.filter(y=>!y.passed&&!y.critical);if(u.length>0){if(V(`${u.length} critical issue(s) \u2014 upload will likely fail:
2909
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ze(t,"css");if(x(s)){for(let a of bo(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(ze(s,a));break}}let o=ze(t,"js");if(x(o)){for(let a of bo(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(ze(o,a));break}}let i=ze(t,"templates");if(x(i)){for(let a of bo(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(ze(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=ze(t,"modules");if(x(r))for(let a of bo(r)){if(!a.endsWith(".module"))continue;let l=ze(r,a);if(!rf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=ze(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=ze(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=ze(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=ze(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=ze(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ke();oe();Qe();function af(e,t){switch(e){case"claude-code":return new uo(t);case"gemini-cli":return new yo;case"codex-cli":return new So;case"api":return new fo}}async function vo(e){await ge("Converting React to HubSpot Modules"),await yt(`AI will now analyze your React code and create
2910
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=af(e.aiEngine,e.model),n=ye(),s=await De();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(h,f)=>{h==="created"?G(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=lf(e.themePath);for(let h of a)G(`Auto-fixed: ${h}`);let l=cf(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(`
2911
+ ${d}/${l.length} checks passed`),await yt(c.join(`
2912
+ `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(V(`${u.length} critical issue(s) \u2014 upload will likely fail:
2866
2913
  `+u.map(f=>` - ${f.label}`).join(`
2867
- `)),!await Ae({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&te(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2868
- `+m.map(y=>` - ${y.label}`).join(`
2869
- `));let g=qe(e.themePath,"..","vibespot-conversion.log");return w(g)&&(await Ae({message:"Keep conversion log file for debugging?",initialValue:!1})?H(`Log saved: ${g}`):Wa(g)),await pe("Files ready for upload!"),i}function zp(e){let t=[];qp(e),Xp(e);let n=qe(e,"modules");if(w(n))for(let o of Wn(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;Ka(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),Va(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 Wn(s)){if(!o.endsWith(".html"))continue;let i=qe(s,o),r=E(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(Wa(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Ka(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)&&Ka(s.children)&&(t=!0)}return t}function Va(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)&&Va(s.children)&&(t=!0)}return t}function Yp(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 Wn(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 qp(e){let t=qe(e,"templates");if(w(t))for(let n of Wn(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+=`
2914
+ `)),!await Me({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&se(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2915
+ `+m.map(h=>` - ${h.label}`).join(`
2916
+ `));let g=nt(e.themePath,"..","vibespot-conversion.log");return x(g)&&(await Me({message:"Keep conversion log file for debugging?",initialValue:!1})?G(`Log saved: ${g}`):Ml(g)),await fe("Files ready for upload!"),i}function lf(e){let t=[];df(e),uf(e);let n=nt(e,"modules");if(x(n))for(let o of cs(n)){if(!o.endsWith(".module"))continue;let i=nt(n,o,"fields.json");if(!x(i))continue;let r=o.replace(".module",""),a=P(i),l=!1;a.includes('"textarea"')&&(a=a.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${r}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(a)&&(a=a.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${r}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(a),u=!1;Il(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),Pl(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2917
+ `,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&J(i,a);let c=nt(n,o,"module.html");if(x(c)){let d=P(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),J(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=nt(e,"templates");if(x(s))for(let o of cs(s)){if(!o.endsWith(".html"))continue;let i=nt(s,o),r=P(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(Ml(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Il(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)&&Il(s.children)&&(t=!0)}return t}function Pl(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)&&Pl(s.children)&&(t=!0)}return t}function cf(e,t){let n=[],s=t.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of t.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let r=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),a=r.length===0;n.push({label:a?"module.css created for each module":`module.css missing for: ${r.join(", ")}`,passed:s>0&&a,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=nt(e,"templates"),d=!1;if(x(c))for(let u of cs(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=P(nt(c,u));if(m.includes("dnd_area")&&/templateType\s*:\s*page/i.test(m)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function df(e){let t=nt(e,"templates");if(x(t))for(let n of cs(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=nt(t,n),o=P(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),r=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&r)continue;let a=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);i||(c+=`
2871
2918
  templateType: page`),r||(c+=`
2872
2919
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
2873
2920
  label: ${a}`),o=c+o.slice(l)}else o=`<!--
@@ -2875,31 +2922,31 @@ ${d}/${l.length} checks passed`),await ut(c.join(`
2875
2922
  isAvailableForNewContent: true
2876
2923
  label: ${a}
2877
2924
  -->
2878
- `+o;J(s,o),H(`Template "${n}" \u2014 annotations verified`)}}function Xp(e){let t=qe(e,"modules");if(w(t))for(let n of Wn(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{}}}h();Bt();Ye();to();ee();$i();import{join as rl,basename as ag}from"path";function lg(e){return(e.match(/^Uploaded file /gm)||[]).length}async function cn(e){await me("Uploading to HubSpot");let t=ag(e)||e,n=O(),s=Fe(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await Re(),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 no(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Zs(m.errors)}else{let m=ne(`hs cms upload "${e}" "${t}"`,{cwd:rl(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2880
- `);c=lg(g),d=m.success,d||(l=Qs(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(V("Upload failed with unknown error."),c>0&&(te(`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?za(e,m)?(H(`Auto-fixed: ${m.message}`),u=!0):te(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&a<r)){if(c>0&&(te(`${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 Si(s,`${t}/modules`)}catch{}else ne(`hs cms delete "${t}/modules"`,{cwd:rl(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}h();Ye();at();Gt();se();import{execFileSync as _i}from"child_process";import{rmSync as cg}from"fs";import{basename as al}from"path";async function ll(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await me("You're all set!");let r=Nn(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await ut(`Your React page has been converted and uploaded to HubSpot.
2925
+ `+o;J(s,o),G(`Template "${n}" \u2014 annotations verified`)}}function uf(e){let t=nt(e,"modules");if(x(t))for(let n of cs(t)){if(!n.endsWith(".module"))continue;let s=nt(t,n,"meta.json");if(x(s))try{let o=JSON.parse(P(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&J(s,JSON.stringify(o,null,2)+`
2926
+ `)}catch{}}}y();qt();Qe();ko();ee();er();import{join as Wl,basename as xf}from"path";function wf(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Mn(e){await ge("Uploading to HubSpot");let t=xf(e)||e,n=R(),s=Le(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await De(),r=3;for(let a=1;a<=r;a++){i.start(a===1?"Uploading theme...":`Retrying upload (attempt ${a}/${r})...`);let l=[],c=0,d=!1;if(o){let m=await To(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=xo(m.errors)}else{let m=ie(`hs cms upload "${e}" "${t}"`,{cwd:Wl(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2927
+ `);c=wf(g),d=m.success,d||(l=wo(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await fe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(V("Upload failed with unknown error."),c>0&&(se(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2928
+ You can check your HubSpot Design Manager to verify.`),await Me({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Me({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?Nl(e,m)?(G(`Auto-fixed: ${m.message}`),u=!0):se(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&a<r)){if(c>0&&(se(`${c} files uploaded successfully despite errors.
2929
+ The theme may work \u2014 check HubSpot Design Manager.`),await Me({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await Li(s,`${t}/modules`)}catch{}else ie(`hs cms delete "${t}/modules"`,{cwd:Wl(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}y();Qe();gt();Qt();oe();import{execFileSync as tr}from"child_process";import{rmSync as Cf}from"fs";import{basename as Kl}from"path";async function Vl(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ge("You're all set!");let r=Qn(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await yt(`Your React page has been converted and uploaded to HubSpot.
2883
2930
  The theme and modules are now in your account, but you still
2884
- need to ${_.bold("create a new landing page")} that uses them.
2931
+ need to ${I.bold("create a new landing page")} that uses them.
2885
2932
 
2886
2933
  Next steps:
2887
2934
 
2888
- ${_.bold("1.")} Go to HubSpot ${_.muted("\u2192")} Content ${_.muted("\u2192")} Landing Pages ${_.muted("\u2192")} Create
2889
- ${_.bold("2.")} Choose your uploaded theme from the theme picker
2890
- ${_.bold("3.")} Select the landing page template that was just created
2891
- ${_.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
2892
- ${_.bold("5.")} Click each section to edit text, images, and colors
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=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"}),H("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 (${al(n)})`}),w(s)&&l.push({path:s,label:`Theme directory (${al(s)})`}),l.length>0&&await Ae({message:"Clean up local working directories?"}))for(let d of l)try{cg(d.path,{recursive:!0,force:!0}),H(`Removed ${d.label}`)}catch{te(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await pe(`Thanks for using hub${_.vibes("Vibes")}! ${_.vibes("~")}`)}ee();async function cl(){Te();let e=await Js(),t=await Bs();z({lastSourcePath:t.sourceDir});let n=await Us();z({lastThemePath:n.themePath}),await Xs({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await cn(n.themePath),await ll({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}h();async function dl(){Te(),await Js()}h();Hs();ee();Ye();async function ul(){Te();let e=O();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await Bs(),n=await Us();await Xs({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}h();ee();Ye();async function ml(){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)}}h();Gt();ee();Ye();at();async function pl(){Te(),await me("Environment Diagnostics");let e=0,t=In();t.found?Os(t.version)?H(`Node.js v${t.version}`):(te(`Node.js v${t.version} \u2014 too old (need 18+)`),j(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),j(" Install from https://nodejs.org"),e++);let n=Pn();n.found?H(`Git ${n.version}`):(V("Git \u2014 not installed"),j(" Install from https://git-scm.com"),e++);let s=ct();if(!s.found)te("HubSpot CLI \u2014 not installed (only needed for deployment)"),j(" Install: npm install -g @hubspot/cli");else if(!xa(s.version))te(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),j(" Update: npm install -g @hubspot/cli@latest"),e++;else{H(`HubSpot CLI v${s.version}`);let m=dt();m.authenticated?H(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(te("HubSpot \u2014 not authenticated"),j(" Run: hs init"))}let o=Rn();o.found?H(`Claude Code ${o.version} at ${o.path}`):j(_.muted("Claude Code \u2014 not installed"));let i=On();i.found?H(`Gemini CLI ${i.version} at ${i.path}`):j(_.muted("Gemini CLI \u2014 not installed"));let r=Fn();r.found?H(`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?H("Anthropic API key configured"):j(_.muted("Anthropic API key \u2014 not set")),c?H("OpenAI API key configured"):j(_.muted("OpenAI API key \u2014 not set")),d?H("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&&H(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&j(_.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(te("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`))}h();ns();we();import{dirname as Pb,join as ii}from"path";import{existsSync as Rb}from"fs";import{fileURLToPath as Nb}from"url";import{execFileSync as na}from"child_process";import ri from"chalk";var Ym=Pb(Nb(import.meta.url)),Ob=4200;async function qm(){let e=ri.hex("#e8613a"),t=ri.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
2895
- `));let n=Fb();n||(console.error(ri.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||Ob;try{let{port:o,close:i}=await oi({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"?na("open",[r],{stdio:"ignore"}):process.platform==="win32"?na("cmd",["/c","start","",r],{stdio:"ignore"}):na("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(ri.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function Fb(){let e=[ii(Ym,"../../ui"),ii(Ym,"../ui"),ii(process.cwd(),"ui")];for(let t of e)if(Rb(ii(t,"index.html")))return t;return null}h();import{resolve as Xm}from"path";import{existsSync as sa}from"fs";at();Ye();ee();Zr();async function Zm(e={}){let t=await ep(e.path);if(e.fix){let o=ei(t);if(o.applied.length>0){H(`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)te(i)}let n=vs(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${ia(n.errorCount)}, ${n.warningCount} warning${ia(n.warningCount)}, ${n.infoCount} note${ia(n.infoCount)}`;n.passed?H(`Theme passes Marketplace checks (${s}).`):V(`Theme is not yet ready: ${s}.`),oa("Errors",n.findings.filter(o=>o.severity==="error")),oa("Warnings",n.findings.filter(o=>o.severity==="warning")),oa("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 Qm(e={}){let t=await ep(e.path);Te(),await me("Marketplace listing details");let n=An(t)??{},s=await Ct({message:"Category",options:Jt.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 Ct({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};Qo(t,d),H("Saved marketplace.json"),await pe(`Run ${_.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function ep(e){if(e){let o=Xm(e);if(!sa(o))throw new Error(`Theme not found: ${o}`);return o}let t=O();if(t.lastThemePath&&sa(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=Xm(n);if(!sa(s))throw new Error(`Theme not found: ${s}`);return s}function oa(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 ia(e){return e===1?"":"s"}h();import{resolve as tp}from"path";import{existsSync as ra}from"fs";import{basename as jb}from"path";at();Ye();ee();So();async function np(e={}){let t=await Db(e.path),n=jb(t);if(e.applyTokens){let i=bo(t,n);i?H(`Wrote design tokens to ${i}`):j(_.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=Ji(t);e.json||H(`Wrote imported theme snapshot to ${i}`)}let s=yo(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`)}`)}}aa("Errors",s.findings.filter(i=>i.severity==="error")),aa("Warnings",s.findings.filter(i=>i.severity==="warning")),aa("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 Db(e){if(e){let o=tp(e);if(!ra(o))throw new Error(`Theme not found: ${o}`);return o}let t=O();if(t.lastThemePath&&ra(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=tp(n);if(!ra(s))throw new Error(`Theme not found: ${s}`);return s}function aa(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)}`)}}}h();ns();we();import{dirname as Lb,join as ai}from"path";import{existsSync as Jb}from"fs";import{fileURLToPath as Bb}from"url";import{execFileSync as la}from"child_process";import li from"chalk";var sp=Lb(Bb(import.meta.url)),Hb=4200;async function op(){let e=li.hex("#e8613a"),t=li.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
2901
- `));let n=Gb();n||(console.error(li.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await oi({port:Hb,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"?la("open",[i],{stdio:"ignore"}):process.platform==="win32"?la("cmd",["/c","start","",i],{stdio:"ignore"}):la("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(li.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Gb(){let e=[ai(sp,"../../ui"),ai(sp,"../ui"),ai(process.cwd(),"ui")];for(let t of e)if(Jb(ai(t,"index.html")))return t;return null}se();function ip(){let e=new Ub;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(sn()).action(qm),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(cl),e.command("init").description("Check and install required tools").action(dl),e.command("convert").description("Convert a React project to HubSpot modules").action(ul),e.command("upload").description("Upload theme to HubSpot").action(ml),e.command("doctor").description("Diagnose environment issues").action(pl);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=>Qm(n)),e.command("email").description("Launch email template generation mode").action(op),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=>np(n)),e}var Wb=ip();Wb.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
2935
+ ${I.bold("1.")} Go to HubSpot ${I.muted("\u2192")} Content ${I.muted("\u2192")} Landing Pages ${I.muted("\u2192")} Create
2936
+ ${I.bold("2.")} Choose your uploaded theme from the theme picker
2937
+ ${I.bold("3.")} Select the landing page template that was just created
2938
+ ${I.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
2939
+ ${I.bold("5.")} Click each section to edit text, images, and colors
2940
+ ${I.bold("6.")} Upload images via File Manager ${I.muted("(Settings \u2192 Files)")}
2941
+ ${I.bold("7.")} Preview and publish!`,"What's next"),await Me({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${r}/page-ui/${t}/management/pages/landing`:`https://${r}`;try{let d=process.platform;d==="darwin"?tr("open",[c],{stdio:"ignore"}):d==="win32"?tr("cmd",["/c","start","",c],{stdio:"ignore"}):tr("xdg-open",[c],{stdio:"ignore"}),G("Opening HubSpot Landing Pages...")}catch{D(`Open this URL in your browser: ${I.info(c)}`)}}let l=[];if(o&&x(n)&&l.push({path:n,label:`Cloned source (${Kl(n)})`}),x(s)&&l.push({path:s,label:`Theme directory (${Kl(s)})`}),l.length>0&&await Me({message:"Clean up local working directories?"}))for(let d of l)try{Cf(d.path,{recursive:!0,force:!0}),G(`Removed ${d.label}`)}catch{se(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await fe(`Thanks for using hub${I.vibes("Vibes")}! ${I.vibes("~")}`)}ee();async function zl(){Ee();let e=await io(),t=await ro();Y({lastSourcePath:t.sourceDir});let n=await co();Y({lastThemePath:n.themePath}),await vo({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Mn(n.themePath),await Vl({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function Yl(){Ee(),await io()}y();ao();ee();Qe();async function ql(){Ee();let e=R();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await ro(),n=await co();await vo({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();ee();Qe();async function Xl(){Ee();let e=R();if(e.lastThemePath)if(await Me({message:`Upload from ${e.lastThemePath}?`}))await Mn(e.lastThemePath);else{let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Mn(n)}else{let t=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Mn(t)}}y();Qt();ee();Qe();gt();async function Zl(){Ee(),await ge("Environment Diagnostics");let e=0,t=Xn();t.found?eo(t.version)?G(`Node.js v${t.version}`):(se(`Node.js v${t.version} \u2014 too old (need 18+)`),D(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),D(" Install from https://nodejs.org"),e++);let n=Zn();n.found?G(`Git ${n.version}`):(V("Git \u2014 not installed"),D(" Install from https://git-scm.com"),e++);let s=ft();if(!s.found)se("HubSpot CLI \u2014 not installed (only needed for deployment)"),D(" Install: npm install -g @hubspot/cli");else if(!Xa(s.version))se(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),D(" Update: npm install -g @hubspot/cli@latest"),e++;else{G(`HubSpot CLI v${s.version}`);let m=ht();m.authenticated?G(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(se("HubSpot \u2014 not authenticated"),D(" Run: hs init"))}let o=wn();o.found?G(`Claude Code ${o.version} at ${o.path}`):D(I.muted("Claude Code \u2014 not installed"));let i=Cn();i.found?G(`Gemini CLI ${i.version} at ${i.path}`):D(I.muted("Gemini CLI \u2014 not installed"));let r=kn();r.found?G(`OpenAI Codex ${r.version} at ${r.path}`):D(I.muted("OpenAI Codex \u2014 not installed"));let a=R(),l=!!(a.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(a.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(a.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?G("Anthropic API key configured"):D(I.muted("Anthropic API key \u2014 not set")),c?G("OpenAI API key configured"):D(I.muted("OpenAI API key \u2014 not set")),d?G("Google AI API key configured"):D(I.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};a.aiEngine&&G(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&D(I.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(se("No AI engine available"),D(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),D(" Or install: Claude Code \u2014 https://claude.ai/code"),D(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),D(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await fe("Everything looks good!"):await fe(I.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}y();Ss();Ce();import{dirname as qS,join as Ti}from"path";import{existsSync as XS}from"fs";import{fileURLToPath as ZS}from"url";import{execFileSync as Ia}from"child_process";import Ai from"chalk";var Gp=qS(ZS(import.meta.url)),QS=4200;async function Wp(){let e=Ai.hex("#e8613a"),t=Ai.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
2942
+ `));let n=ev();n||(console.error(Ai.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||QS;try{let{port:o,close:i}=await ki({port:s,uiDir:n}),r=`http://localhost:${o}`;if(console.log(e(` v ${r}`)),console.log(t(` Press Ctrl+C to stop
2943
+ `)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?Ia("open",[r],{stdio:"ignore"}):process.platform==="win32"?Ia("cmd",["/c","start","",r],{stdio:"ignore"}):Ia("xdg-open",[r],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
2944
+ Saving session...`)),j(),i(),console.log(t(` Goodbye!
2945
+ `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(Ai.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function ev(){let e=[Ti(Gp,"../../ui"),Ti(Gp,"../ui"),Ti(process.cwd(),"ui")];for(let t of e)if(XS(Ti(t,"index.html")))return t;return null}y();import{resolve as Kp}from"path";import{existsSync as Pa}from"fs";gt();Qe();ee();Aa();async function Vp(e={}){let t=await Yp(e.path);if(e.fix){let o=vi(t);if(o.applied.length>0){G(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)D(` ${i}`)}else D(I.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)se(i)}let n=js(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
2946
+ `),n.passed||process.exit(1);return}Ee(),await ge("Marketplace check");let s=`${n.errorCount} error${Ra(n.errorCount)}, ${n.warningCount} warning${Ra(n.warningCount)}, ${n.infoCount} note${Ra(n.infoCount)}`;n.passed?G(`Theme passes Marketplace checks (${s}).`):V(`Theme is not yet ready: ${s}.`),Na("Errors",n.findings.filter(o=>o.severity==="error")),Na("Warnings",n.findings.filter(o=>o.severity==="warning")),Na("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(D(""),D(`Tip: run ${I.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await fe("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function zp(e={}){let t=await Yp(e.path);Ee(),await ge("Marketplace listing details");let n=zn(t)??{},s=await Et({message:"Category",options:Yt.map(u=>({value:u,label:u}))}),o=await Se({message:"Description (1\u20132 sentences shown on the listing)",placeholder:"A clean, fast SaaS landing page theme...",defaultValue:n.description??"",validate:u=>u.trim().length<40?"Aim for at least 40 characters.":void 0}),r=(await Se({message:"Key features (comma-separated, 2\u20135 items)",placeholder:"Hero, Pricing, Testimonials, Footer",defaultValue:(n.features??[]).join(", "),validate:u=>{let m=u.split(",").map(g=>g.trim()).filter(Boolean).length;if(m<2)return"Provide at least 2 features.";if(m>5)return"Provide at most 5 features."}})).split(",").map(u=>u.trim()).filter(Boolean),a=await Se({message:"Public support URL",placeholder:"https://example.com/support",defaultValue:n.supportUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),l=await Se({message:"Documentation URL (optional)",placeholder:"https://example.com/docs",defaultValue:n.documentationUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),c=await Et({message:"Pricing tier",options:[{value:"free",label:"Free"},{value:"paid",label:"Paid"}]}),d={category:s,description:o.trim(),features:r,supportUrl:a.trim()||void 0,documentationUrl:l.trim()||void 0,pricingTier:c,tags:n.tags};Si(t,d),G("Saved marketplace.json"),await fe(`Run ${I.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function Yp(e){if(e){let o=Kp(e);if(!Pa(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&Pa(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Kp(n);if(!Pa(s))throw new Error(`Theme not found: ${s}`);return s}function Na(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}function Ra(e){return e===1?"":"s"}y();import{resolve as qp}from"path";import{existsSync as Oa}from"fs";import{basename as tv}from"path";gt();Qe();ee();Jo();async function Xp(e={}){let t=await nv(e.path),n=tv(t);if(e.applyTokens){let i=Lo(t,n);i?G(`Wrote design tokens to ${i}`):D(I.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=cr(t);e.json||G(`Wrote imported theme snapshot to ${i}`)}let s=jo(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
2947
+ `),process.exit(0)),Ee(),await ge("Inverse pipeline analyzer");let o=s.summary;if(D(`${I.heading("Summary")} ${o.moduleCount} module(s), ${o.templateCount} template(s), ${o.orphanCount} orphan, ${o.paletteSize} colour(s), ${o.cssVarCount} CSS var(s), ${o.customMacroCount} macro(s)`),s.designTokens.palette.length>0){D(""),D(I.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?I.muted(` (${i.varName})`):"";D(` ${i.value} ${I.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){D(""),D(I.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))D(` ${i}`)}if(s.graph.templates.length>0){D(""),D(I.heading("Template \u2192 modules"));for(let i of s.graph.templates)D(` ${i.id}: ${i.modules.length===0?I.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){D(""),D(I.heading("Orphan modules"));for(let i of s.graph.orphanModules)D(` ${i}`)}if(s.roundTripDiff.hasSnapshot){D(""),D(I.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)D(` ${I.muted("No changes from imported snapshot.")}`);else{D(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))D(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&D(` ${I.muted(`...and ${i.files.length-12} more`)}`)}}Fa("Errors",s.findings.filter(i=>i.severity==="error")),Fa("Warnings",s.findings.filter(i=>i.severity==="warning")),Fa("Notes",s.findings.filter(i=>i.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(D(""),D(`Tip: run ${I.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await fe("Analysis complete."),process.exit(0)}async function nv(e){if(e){let o=qp(e);if(!Oa(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&Oa(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=qp(n);if(!Oa(s))throw new Error(`Theme not found: ${s}`);return s}function Fa(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}y();Ss();Ce();import{dirname as sv,join as _i}from"path";import{existsSync as ov}from"fs";import{fileURLToPath as iv}from"url";import{execFileSync as Da}from"child_process";import $i from"chalk";var Zp=sv(iv(import.meta.url)),rv=4200;async function Qp(){let e=$i.hex("#e8613a"),t=$i.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
2948
+ `));let n=av();n||(console.error($i.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await ki({port:rv,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
2949
+ `));try{process.platform==="darwin"?Da("open",[i],{stdio:"ignore"}):process.platform==="win32"?Da("cmd",["/c","start","",i],{stdio:"ignore"}):Da("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
2950
+ Saving session...`)),j(),o(),console.log(t(` Goodbye!
2951
+ `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error($i.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function av(){let e=[_i(Zp,"../../ui"),_i(Zp,"../ui"),_i(process.cwd(),"ui")];for(let t of e)if(ov(_i(t,"index.html")))return t;return null}oe();function eg(){let e=new lv;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(yn()).action(Wp),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(zl),e.command("init").description("Check and install required tools").action(Yl),e.command("convert").description("Convert a React project to HubSpot modules").action(ql),e.command("upload").description("Upload theme to HubSpot").action(Xl),e.command("doctor").description("Diagnose environment issues").action(Zl);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=>Vp(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>zp(n)),e.command("email").description("Launch email template generation mode").action(Qp),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=>Xp(n)),e}var cv=eg();cv.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
2905
2952
  //# sourceMappingURL=index.js.map