vibespot 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- var Vc=Object.defineProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var ke=(e,t)=>{for(var n in t)Vc(e,n,{get:t[n],enumerable:!0})};import Qp from"path";import{fileURLToPath as tg}from"url";var f=L(()=>{"use strict"});import{readFileSync as Xs,writeFileSync as Kc,mkdirSync as Pi,existsSync as Rn}from"fs";import{dirname as zc,join as et}from"path";function E(e){return Xs(e,"utf-8")}function G(e,t){Pi(zc(e),{recursive:!0}),Kc(e,t,"utf-8")}function k(e){return Rn(e)}function Te(e){Pi(e,{recursive:!0})}function Fn(e){let t=[et(import.meta.dirname,"../../assets",e),et(import.meta.dirname,"../assets",e),et(process.cwd(),"assets",e)];for(let n of t)if(Rn(n))return n;throw new Error(`Asset not found: ${e}`)}function Nt(){if(_t)return _t;let e=[et(import.meta.dirname,"../../package.json"),et(import.meta.dirname,"../package.json"),et(process.cwd(),"package.json")];for(let t of e)if(Rn(t))try{let n=JSON.parse(Xs(t,"utf-8"));if(n.name==="vibespot"&&n.version)return _t=n.version,_t}catch{}return _t="dev",_t}function Mi(){if(On)return On;let e=[et(import.meta.dirname,"../../CHANGELOG.md"),et(import.meta.dirname,"../CHANGELOG.md"),et(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Rn(t))try{return On=Xs(t,"utf-8"),On}catch{}return""}var _t,On,te=L(()=>{"use strict";f();_t="";On=""});import{execSync as Oi}from"child_process";function J(e,t={}){try{return{stdout:Oi(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 Ri(e,t={}){try{return Oi(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var ht=L(()=>{"use strict";f()});var ji={};ke(ji,{addHubSpotAccount:()=>qt,getActiveHubSpotAccount:()=>ut,getApiKeyForEngine:()=>be,getConfigDir:()=>Xc,getHubSpotPak:()=>Se,isCliToolEnabled:()=>Xt,loadConfig:()=>P,maskApiKey:()=>jn,removeHubSpotAccount:()=>Zs,saveConfig:()=>W,setActiveHubSpotAccount:()=>Qs,setCliToolEnabled:()=>eo});import{join as Fi}from"path";import{homedir as Yc}from"os";import{chmodSync as qc}from"fs";function P(){if(!k(Jn))return{};try{let e=JSON.parse(E(Jn));return e.aiEngine==="api"&&(e.aiEngine="anthropic-api"),e}catch{return{}}}function be(e,t){let n=t||P();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;default:return}}function jn(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function W(e){let n={...P(),...e};if(G(Jn,JSON.stringify(n,null,2)),process.platform!=="win32")try{qc(Jn,384)}catch{}}function Xc(){return Ji}function ut(){let e=P();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 qt(e,t,n,s){let i=P().hubspotAccounts||[],a=i.findIndex(l=>l.portalId===t),r={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};a>=0?i[a]=r:i.push(r),W({hubspotAccounts:i,activeHubSpotAccount:t})}function Zs(e){let t=P(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),W(s)}function Qs(e){W({activeHubSpotAccount:e})}function Se(){return ut()?.personalAccessKey||null}function Xt(e){return P().enabledCLITools?.includes(e)??!1}function eo(e,t){let n=P(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),W({enabledCLITools:[...s]})}var Ji,Jn,Q=L(()=>{"use strict";f();te();Ji=Fi(Yc(),".vibespot"),Jn=Fi(Ji,"config.json")});var so={};ke(so,{OAUTH_EXTRA_HEADERS:()=>Zt,OAUTH_SYSTEM_PREFIX:()=>Mt,clearOAuthTokens:()=>Ln,getOAuthTokenInfo:()=>Qt,getValidAccessToken:()=>no,hasValidOAuthToken:()=>Le,saveInitialToken:()=>to});import{join as Zc}from"path";import{homedir as Qc}from"os";import{chmodSync as ed,unlinkSync as td}from"fs";function Hn(){if(!k(Pt))return null;try{return JSON.parse(E(Pt))}catch{return null}}function Di(e){if(G(Pt,JSON.stringify(e,null,2)),process.platform!=="win32")try{ed(Pt,384)}catch{}}async function id(e){let t=await fetch(sd,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:nd})});if(!t.ok)throw Ln(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Di({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function to(e,t=""){Di({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Le(){let e=Hn();return e?e.expires_at>Date.now():!1}async function no(){let e=Hn();if(!e)return null;if(e.expires_at-Date.now()>od)return e.access_token;if(e.refresh_token){Dn||(Dn=id(e.refresh_token).finally(()=>{Dn=null}));try{await Dn}catch{return null}return Hn()?.access_token??null}return e.access_token}function Qt(){let e=Hn();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function Ln(){if(k(Pt))try{td(Pt)}catch{}}var nd,sd,Pt,od,Zt,Mt,Dn,tt=L(()=>{"use strict";f();te();nd="9d1c250a-e61b-44d9-88ed-5944d1962f5e",sd="https://console.anthropic.com/v1/oauth/token",Pt=Zc(Qc(),".vibespot","claude-oauth.json"),od=300*1e3,Zt={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},Mt="You are Claude Code, Anthropic's official CLI for Claude.";Dn=null});import{readFileSync as ld}from"fs";import{basename as cd}from"path";async function Gi(e){let t=Ui.get(e);if(t&&t.expiresAt-Date.now()>md)return t;let n=await fetch(`${nt}/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 Ui.set(e,o),o}async function Ot(e){let{accessToken:t}=await Gi(e);return{Authorization:`Bearer ${t}`}}function Kn(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function pd(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function gd(e){return new Promise(t=>setTimeout(t,e))}async function an(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 a=i.errors[0];o=a.message||JSON.stringify(a)}}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 ln(e,t,n=dd){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=ud*Math.pow(2,s);await gd(i);continue}return o}return fetch(e,t)}async function zn(e){let t=await Gi(e),n=`${nt}/account-info/v3/details`,s=await ln(n,{headers:await Ot(e)});if(!s.ok){let r=await an(s);throw new Error(`Failed to get account info: ${r.message}`)}let o=await s.json(),i=String(o.portalId||t.hubId||""),a=t.hubName||o.uiDomain||i;return{portalId:i,portalName:a,dataCenter:pd(e)}}async function Wi(e,t,n){let s=ld(n),o=cd(n),i=new FormData,a=new Blob([s]);i.append("file",a,o);let r=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,l=await ln(r,{method:"PUT",headers:await Ot(e),body:i});if(!l.ok){let c=await an(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function ao(e,t){let n=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,s=await ln(n,{method:"DELETE",headers:await Ot(e)});if(!s.ok&&s.status!==404){let o=await an(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Vi(e,t){let n=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,s=await ln(n,{method:"GET",headers:await Ot(e)});if(!s.ok){let i=await an(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Yn(e,t){let n=`${nt}/cms/v3/source-code/published/metadata/${Kn(t)}`,s=await ln(n,{method:"GET",headers:await Ot(e)});if(s.status===404)return null;if(!s.ok){let o=await an(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Ki(e){let t=await Ot(e),n=[`${nt}/cms/v3/source-code/published/metadata`,`${nt}/cms/v3/source-code/published/metadata/`,`${nt}/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(),a=i.children||i.objects||(Array.isArray(i)?i:null);if(a&&a.length>0)return a.filter(r=>r.folder)}}catch{}return[]}var nt,dd,ud,md,Ui,bt=L(()=>{"use strict";f();nt="https://api.hubapi.com",dd=3,ud=1e3,md=300*1e3,Ui=new Map});var Zi={};ke(Zi,{createThemeScaffold:()=>cn});import{mkdirSync as mt,writeFileSync as Zn}from"fs";import{join as Pe}from"path";function cn(e,t){mt(e,{recursive:!0}),mt(Pe(e,"templates"),{recursive:!0}),mt(Pe(e,"modules"),{recursive:!0}),mt(Pe(e,"css"),{recursive:!0}),mt(Pe(e,"js"),{recursive:!0}),mt(Pe(e,"images"),{recursive:!0}),mt(Pe(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"}};Zn(Pe(e,"theme.json"),JSON.stringify(n,null,2)+`
2
- `),Zn(Pe(e,"fields.json"),`[]
1
+ var $u=Object.defineProperty;var G=(e,t)=>()=>(e&&(t=e(e=0)),t);var _e=(e,t)=>{for(var n in t)$u(e,n,{get:t[n],enumerable:!0})};import Zh from"path";import{fileURLToPath as ey}from"url";var g=G(()=>{"use strict"});import{readFileSync as jo,writeFileSync as Iu,mkdirSync as Mr,existsSync as ns}from"fs";import{dirname as Rr,join as at}from"path";import{fileURLToPath as Eu}from"url";function T(e){return jo(e,"utf-8")}function L(e,t){Mr(Rr(e),{recursive:!0}),Iu(e,t,"utf-8")}function b(e){return ns(e)}function Ae(e){Mr(e,{recursive:!0})}function ss(e){let t=[at(Wt,"../../assets",e),at(Wt,"../assets",e),at(process.cwd(),"assets",e)];for(let n of t)if(ns(n))return n;throw new Error(`Asset not found: ${e}`)}function Vt(){if(Gt)return Gt;let e=[at(Wt,"../../package.json"),at(Wt,"../package.json"),at(process.cwd(),"package.json")];for(let t of e)if(ns(t))try{let n=JSON.parse(jo(t,"utf-8"));if(n.name==="vibespot"&&n.version)return Gt=n.version,Gt}catch{}return Gt="dev",Gt}function _r(){if(ts)return ts;let e=[at(Wt,"../../CHANGELOG.md"),at(Wt,"../CHANGELOG.md"),at(process.cwd(),"CHANGELOG.md")];for(let t of e)if(ns(t))try{return ts=jo(t,"utf-8"),ts}catch{}return""}var Wt,Gt,ts,Q=G(()=>{"use strict";g();Wt=Rr(Eu(import.meta.url));Gt="";ts=""});import{execSync as Pr}from"child_process";function D(e,t={}){try{return{stdout:Pr(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 Nr(e,t={}){try{return Pr(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var Et=G(()=>{"use strict";g()});var jr={};_e(jr,{addHubSpotAccount:()=>fn,getActiveHubSpotAccount:()=>xt,getApiKeyForEngine:()=>Te,getConfigDir:()=>_u,getHubSpotPak:()=>$e,isCliToolEnabled:()=>gn,loadConfig:()=>R,maskApiKey:()=>is,removeHubSpotAccount:()=>Do,saveConfig:()=>V,setActiveHubSpotAccount:()=>Jo,setCliToolEnabled:()=>Lo});import{join as Or}from"path";import{homedir as Mu}from"os";import{chmodSync as Ru}from"fs";function R(){if(!b(os))return{};try{let e=JSON.parse(T(os));return e.aiEngine==="api"&&(e.aiEngine="anthropic-api"),e}catch{return{}}}function Te(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;default:return}}function is(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function V(e){let n={...R(),...e};if(L(os,JSON.stringify(n,null,2)),process.platform!=="win32")try{Ru(os,384)}catch{}}function _u(){return Fr}function xt(){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 fn(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),V({hubspotAccounts:i,activeHubSpotAccount:t})}function Do(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),V(s)}function Jo(e){V({activeHubSpotAccount:e})}function $e(){return xt()?.personalAccessKey||null}function gn(e){return R().enabledCLITools?.includes(e)??!1}function Lo(e,t){let n=R(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),V({enabledCLITools:[...s]})}var Fr,os,X=G(()=>{"use strict";g();Q();Fr=Or(Mu(),".vibespot"),os=Or(Fr,"config.json")});var Uo={};_e(Uo,{OAUTH_EXTRA_HEADERS:()=>hn,OAUTH_SYSTEM_PREFIX:()=>Kt,clearOAuthTokens:()=>ls,getOAuthTokenInfo:()=>yn,getValidAccessToken:()=>Bo,hasValidOAuthToken:()=>Ye,saveInitialToken:()=>Ho});import{join as Pu}from"path";import{homedir as Nu}from"os";import{chmodSync as Ou,unlinkSync as Fu}from"fs";function as(){if(!b(zt))return null;try{return JSON.parse(T(zt))}catch{return null}}function Dr(e){if(L(zt,JSON.stringify(e,null,2)),process.platform!=="win32")try{Ou(zt,384)}catch{}}async function Lu(e){let t=await fetch(Du,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:ju})});if(!t.ok)throw ls(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Dr({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Ho(e,t=""){Dr({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Ye(){let e=as();return e?e.expires_at>Date.now():!1}async function Bo(){let e=as();if(!e)return null;if(e.expires_at-Date.now()>Ju)return e.access_token;if(e.refresh_token){rs||(rs=Lu(e.refresh_token).finally(()=>{rs=null}));try{await rs}catch{return null}return as()?.access_token??null}return e.access_token}function yn(){let e=as();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function ls(){if(b(zt))try{Fu(zt)}catch{}}var ju,Du,zt,Ju,hn,Kt,rs,lt=G(()=>{"use strict";g();Q();ju="9d1c250a-e61b-44d9-88ed-5944d1962f5e",Du="https://console.anthropic.com/v1/oauth/token",zt=Pu(Nu(),".vibespot","claude-oauth.json"),Ju=300*1e3,hn={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},Kt="You are Claude Code, Anthropic's official CLI for Claude.";rs=null});import{readFileSync as Uu}from"fs";import{basename as Gu}from"path";async function Ur(e){let t=Br.get(e);if(t&&t.expiresAt-Date.now()>zu)return t;let n=await fetch(`${ct}/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 Br.set(e,o),o}async function Yt(e){let{accessToken:t}=await Ur(e);return{Authorization:`Bearer ${t}`}}function fs(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function Ku(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Yu(e){return new Promise(t=>setTimeout(t,e))}async function kn(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 An(e,t,n=Wu){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=Vu*Math.pow(2,s);await Yu(i);continue}return o}return fetch(e,t)}async function gs(e){let t=await Ur(e),n=`${ct}/account-info/v3/details`,s=await An(n,{headers:await Yt(e)});if(!s.ok){let a=await kn(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:Ku(e)}}async function Gr(e,t,n){let s=Uu(n),o=Gu(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${ct}/cms/v3/source-code/published/content/${fs(t)}`,l=await An(a,{method:"PUT",headers:await Yt(e),body:i});if(!l.ok){let c=await kn(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function zo(e,t){let n=`${ct}/cms/v3/source-code/published/content/${fs(t)}`,s=await An(n,{method:"DELETE",headers:await Yt(e)});if(!s.ok&&s.status!==404){let o=await kn(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Wr(e,t){let n=`${ct}/cms/v3/source-code/published/content/${fs(t)}`,s=await An(n,{method:"GET",headers:await Yt(e)});if(!s.ok){let i=await kn(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function hs(e,t){let n=`${ct}/cms/v3/source-code/published/metadata/${fs(t)}`,s=await An(n,{method:"GET",headers:await Yt(e)});if(s.status===404)return null;if(!s.ok){let o=await kn(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Vr(e){let t=await Yt(e),n=[`${ct}/cms/v3/source-code/published/metadata`,`${ct}/cms/v3/source-code/published/metadata/`,`${ct}/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 ct,Wu,Vu,zu,Br,Rt=G(()=>{"use strict";g();ct="https://api.hubapi.com",Wu=3,Vu=1e3,zu=300*1e3,Br=new Map});var Xr={};_e(Xr,{createThemeScaffold:()=>Tn});import{mkdirSync as vt,writeFileSync as Ss}from"fs";import{join as Le}from"path";function Tn(e,t){vt(e,{recursive:!0}),vt(Le(e,"templates"),{recursive:!0}),vt(Le(e,"modules"),{recursive:!0}),vt(Le(e,"css"),{recursive:!0}),vt(Le(e,"js"),{recursive:!0}),vt(Le(e,"images"),{recursive:!0}),vt(Le(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};Ss(Le(e,"theme.json"),JSON.stringify(n,null,2)+`
2
+ `),Ss(Le(e,"fields.json"),`[]
3
3
  `);let s=`<!--
4
4
  templateType: page
5
5
  isAvailableForNewContent: false
@@ -15,7 +15,7 @@ var Vc=Object.defineProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var ke=(e,t)=>{f
15
15
  %}
16
16
  {% end_dnd_area %}
17
17
  {% endblock body %}
18
- `;Zn(Pe(e,"templates","home.html"),s);let o=`<!--
18
+ `;Ss(Le(e,"templates","home.html"),s);let o=`<!--
19
19
  templateType: none
20
20
  isAvailableForNewContent: false
21
21
  label: Base Layout
@@ -38,8 +38,8 @@ var Vc=Object.defineProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var ke=(e,t)=>{f
38
38
  {{ standard_footer_includes }}
39
39
  </body>
40
40
  </html>
41
- `;mt(Pe(e,"templates","layouts"),{recursive:!0}),Zn(Pe(e,"templates","layouts","base.html"),o)}var Qn=L(()=>{"use strict";f()});var er={};ke(er,{fetchTheme:()=>dn});import{mkdirSync as Qi,writeFileSync as bd}from"fs";import{join as Sd,dirname as xd}from"path";async function mo(e,t){let n=await Yn(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let i of o){let a=typeof i=="string"?i:i.name;if(!a)continue;let r=`${t}/${a}`;if(typeof i=="string")s.push(...await mo(e,r));else{let l=i;l.folder?s.push(...await mo(e,l.path||r)):s.push(l.path||r)}}return s}async function vd(e,t,n){let s=0;async function o(){for(;s<e.length;){let a=s++;await n(e[a])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function dn(e,t,n,s={}){let o=s.concurrency??5,i=await mo(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);Qi(n,{recursive:!0}),await vd(i,o,async a=>{let r=a.startsWith(t+"/")?a.slice(t.length+1):a,l=Sd(n,r);Qi(xd(l),{recursive:!0});let c=await Vi(e,a);bd(l,c),s.onFile?.(r)})}var es=L(()=>{"use strict";f();bt()});function Ft(e){let t=tr.get(e);if(t!==void 0)return t;try{t=E(Fn(e))}catch{t=""}return tr.set(e,t),t}function ce(){return Ft("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function po(){return Ft("design-guide.md")}function go(){return Ft("content-guide.md")}function Me(){return Ft("hubspot-rules.md")}function fo(){return Ft("humanify-guide.md")}function ho(e){let t=Ft("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(`
42
- ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function nr(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
41
+ `;vt(Le(e,"templates","layouts"),{recursive:!0}),Ss(Le(e,"templates","layouts","base.html"),o)}var xs=G(()=>{"use strict";g()});var Qr={};_e(Qr,{fetchTheme:()=>$n});import{mkdirSync as Zr,writeFileSync as Qu}from"fs";import{join as em,dirname as tm}from"path";async function Xo(e,t){let n=await hs(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 Xo(e,a));else{let l=i;l.folder?s.push(...await Xo(e,l.path||a)):s.push(l.path||a)}}return s}async function nm(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 $n(e,t,n,s={}){let o=s.concurrency??5,i=await Xo(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);Zr(n,{recursive:!0}),await nm(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=em(n,a);Zr(tm(l),{recursive:!0});let c=await Wr(e,r);Qu(l,c),s.onFile?.(a)})}var vs=G(()=>{"use strict";g();Rt()});function qt(e){let t=ea.get(e);if(t!==void 0)return t;try{t=T(ss(e))}catch{t=""}return ea.set(e,t),t}function ge(){return qt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function Zo(){return qt("design-guide.md")}function Qo(){return qt("content-guide.md")}function He(){return qt("hubspot-rules.md")}function ei(){return qt("humanify-guide.md")}function ti(e){let t=qt("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(`
42
+ ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function ta(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
43
43
 
44
44
  ## Rules
45
45
  Follow the conversion guide below EXACTLY. Key rules:
@@ -56,10 +56,10 @@ Follow the conversion guide below EXACTLY. Key rules:
56
56
  - Convert React hooks to vanilla JS (no React, no npm packages)
57
57
 
58
58
  ## HubSpot CMS Rules
59
- ${Me()}
59
+ ${He()}
60
60
 
61
61
  ## Conversion Guide
62
- ${e}`}function sr(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
62
+ ${e}`}function na(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
63
63
 
64
64
  Return a JSON object with these keys:
65
65
  - fieldsJson: complete fields.json content (as JSON string)
@@ -74,7 +74,7 @@ ${n}
74
74
  React component source:
75
75
  ${e}
76
76
 
77
- Return ONLY valid JSON, no markdown fences.`}function or(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
77
+ Return ONLY valid JSON, no markdown fences.`}function sa(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
78
78
 
79
79
  Extract the design system from the source CSS and Tailwind config below.
80
80
  Use the class prefix ".${n}-" for all custom classes.
@@ -98,7 +98,7 @@ ${e}
98
98
  Tailwind config:
99
99
  ${t}
100
100
 
101
- Return ONLY the CSS content, no markdown fences.`}function ir(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
101
+ Return ONLY the CSS content, no markdown fences.`}function oa(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
102
102
 
103
103
  Convert the React hooks and interactive components below to plain JavaScript.
104
104
  Use the class prefix "${n}-" to match the CSS.
@@ -116,7 +116,7 @@ ${e}
116
116
  Interactive component sources:
117
117
  ${t}
118
118
 
119
- Return ONLY the JavaScript content, no markdown fences.`}function rr(e,t,n){return`Create a HubSpot page template that assembles these modules:
119
+ Return ONLY the JavaScript content, no markdown fences.`}function ia(e,t,n){return`Create a HubSpot page template that assembles these modules:
120
120
 
121
121
  ${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
122
122
  `)}
@@ -131,23 +131,27 @@ Template requirements:
131
131
  - Each module in its own dnd_section with padding zeroed and full_width=true
132
132
  - dnd_area label: "${t} Landing Page"
133
133
 
134
- Return ONLY the template HTML content, no markdown fences.`}var tr,ot=L(()=>{"use strict";f();te();tr=new Map});var _r=L(()=>{"use strict";f()});import{existsSync as rt,writeFileSync as Yd,mkdirSync as qd}from"fs";import{join as Ve}from"path";function Pr(e){return/^[0-9a-f]{4,40}$/i.test(e)}function Oe(){return ps!==null||(ps=J("git --version").success),ps}function gs(e){if(!Oe())return!1;if(rt(Ve(e,".git")))return Nr(e),!0;let t=J("git init",{cwd:e});return t.success?(Xd(e),Nr(e),J("git add -A",{cwd:e}),J('git commit -m "Initial theme"',{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Nr(e){let t=Ve(e,".vibespot");rt(t)||qd(t,{recursive:!0})}function Xd(e){let t=Ve(e,".gitignore");Yd(t,[".vibespot/","node_modules/",""].join(`
135
- `),"utf-8")}function St(e,t){if(!Oe()||!rt(Ve(e,".git"))||(J("git add -A",{cwd:e}),J("git diff --cached --quiet",{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=J(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=J("git rev-parse --short HEAD",{cwd:e});return i.success?i.stdout:null}function bo(e,t,n,s){if(!Oe()||!rt(Ve(e,".git")))return null;for(let u of s){let m=Ve(e,u);rt(m)&&J(`git add "${u}"`,{cwd:e})}if(J("git diff --cached --quiet",{cwd:e}).success)return null;let i=`[${t}] `,a=72-i.length,r=n.length>a?n.slice(0,a-3)+"...":n,l=i+r,c=J(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=J("git rev-parse --short HEAD",{cwd:e});return d.success?d.stdout:null}function Mr(e,t=50){if(!Oe())return[];if(!rt(Ve(e,".git")))return[];let n=J(`git log --pretty=format:"%h|%H|%s|%at" -n ${t}`,{cwd:e});if(!n.success||!n.stdout.trim())return[];let s=[];for(let o of n.stdout.split(`
136
- `)){let i=o.split("|");if(i.length<4)continue;let a=parseInt(i[3],10)*1e3;s.push({hash:i[0],fullHash:i[1],message:i[2],timestamp:a,date:new Date(a).toISOString()})}return s}function Or(e,t,n=50){if(!Oe())return[];if(!rt(Ve(e,".git")))return[];let s=t.replace(/[[\]\\]/g,"\\$&"),o=J(`git log --grep="\\[${s}\\]" --pretty=format:"%h|%H|%s|%at" -n ${n}`,{cwd:e});if(!o.success||!o.stdout.trim())return[];let i=[];for(let a of o.stdout.split(`
137
- `)){let r=a.split("|");if(r.length<4)continue;let l=parseInt(r[3],10)*1e3;i.push({hash:r[0],fullHash:r[1],message:r[2],timestamp:l,date:new Date(l).toISOString()})}return i}function Rr(e,t){if(!Oe())return{success:!1,error:"Git not available"};if(!rt(Ve(e,".git")))return{success:!1,error:"Not a git repo"};if(!Pr(t))return{success:!1,error:"Invalid commit hash"};let n=J(`git cat-file -t ${t}`,{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=J(`git log --format="%s" -1 ${t}`,{cwd:e}),o=s.success?s.stdout:t,i=J(`git checkout ${t} -- .`,{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let a=`Rollback to: ${o}`.slice(0,72);return J(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}function Fr(e,t,n,s){if(!Oe())return{success:!1,error:"Git not available"};if(!rt(Ve(e,".git")))return{success:!1,error:"Not a git repo"};if(!Pr(n))return{success:!1,error:"Invalid commit hash"};let o=J(`git cat-file -t ${n}`,{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=J(`git log --format="%s" -1 ${n}`,{cwd:e}),a=i.success?i.stdout:n,r=0;for(let d of s)J(`git checkout ${n} -- "${d}"`,{cwd:e}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};J("git add -A",{cwd:e});let c=`${`[${t}] `}Rollback to: ${a}`.slice(0,72);return J(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}var ps,jt=L(()=>{"use strict";f();ht();ps=null});import{appendFileSync as Zd,mkdirSync as Qd,readdirSync as eu,unlinkSync as tu}from"fs";import{join as wo}from"path";import{homedir as nu}from"os";function ou(){if(!xo)try{Qd(fs,{recursive:!0}),xo=!0}catch{}}function iu(){if(!vo){vo=!0;try{let e=Date.now()-su*864e5;for(let t of eu(fs)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{tu(wo(fs,t))}catch{}}}catch{}}}function ru(){let t=new Date().toISOString().slice(0,10);return wo(fs,`vibespot-${t}.log`)}function au(){return new Date().toISOString().slice(11,23)}function So(e,t){if(ou(),!!xo){vo||iu();try{Zd(ru(),`${au()} ${e} ${t}
138
- `)}catch{}}}var fs,su,xo,vo,A,ie=L(()=>{"use strict";f();fs=wo(nu(),".vibespot","logs"),su=7,xo=!1,vo=!1;A={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),So("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),So("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),So("ERROR",o)}}});import{readFileSync as lu,existsSync as jr,writeFileSync as cu,mkdirSync as du,rmSync as uu}from"fs";import{join as hs}from"path";function xt(e){let t=v();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)}function pt(){let e=v();if(!e)return;let t=xe();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)}function Re(e,t,n){let s=v();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),pt(),pu()}function Dr(e){let t=v();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),j())}function Jr(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function mu(e,t){let n=Jr(e),s=Jr(t);return n===s?!0:n.length<4||s.length<4?!1:n.includes(s)||s.includes(n)}function oe(e){let t=v();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(a=>mu(a.moduleName,n.moduleName));i&&A.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(a=>a.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),pt()}}function Ke(e){let t=v();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),pt())}function Hr(e){let t=v();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=hs(t.themePath,"modules",`${e}.module`);jr(n)&&uu(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),pt()}}function Lr(e){let t=v();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),pt())}function Br(e,t,n){let s=v();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);Gr(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),pt()}catch{}}function X(){let e=v();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 pu(){let e=v();if(e)try{let t=hs(e.themePath,".vibespot");du(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};cu(hs(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Ur(e){let t=hs(e,".vibespot","chat.json");if(!jr(t))return[];try{let n=JSON.parse(lu(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Gr(e,t,n){let s=t.split("."),o=s[0],i=e.find(a=>a.name===o);i&&(s.length===1?i.default=n:i.children&&Gr(i.children,s.slice(1).join("."),n))}var pn=L(()=>{"use strict";f();gn();Dt();ie()});import{existsSync as Co,rmSync as ko}from"fs";import{join as fn}from"path";function ys(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 xe(){let e=v();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function Ao(e){let t=v();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,xt(n),t.updatedAt=Date.now(),!0):!1}function bs(e,t){let n=v();if(!n)throw new Error("No active session");let s=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${s}`,a={id:i,label:t,pageType:e,templateFile:e==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(a),n.activeTemplateId=i,xt(a),n.updatedAt=Date.now(),a}function Wr(e,t){let n=v();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,""),r=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:r,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${r}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[]};return n.templates.push(l),n.activeTemplateId=r,xt(l),n.updatedAt=Date.now(),l}function Vr(e,t){let n=v();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 Kr(e,t=!1){let n=v();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=fn(n.themePath,"templates"),a=`${o.id}.html`,r=fn(i,a);if(Co(r)&&ko(r,{force:!0}),o.pageType==="blog_post"){let l=fn(i,`${o.id}-listing.html`);Co(l)&&ko(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let r of n.templates)for(let l of r.modules)i.add(l.moduleName);for(let r of n.modules)i.add(r.moduleName);let a=o.modules.map(r=>r.moduleName).filter(r=>!i.has(r));if(n.themePath&&a.length>0){let r=fn(n.themePath,"modules");for(let l of a){let c=fn(r,`${l}.module`);Co(c)&&ko(c,{recursive:!0,force:!0})}}}return n.activeTemplateId===e&&(n.templates.length>0?Ao(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[])),n.updatedAt=Date.now(),!0}function at(){let e=v();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]})}return Array.from(t.values())}var Dt=L(()=>{"use strict";f();gn();pn()});import{readFileSync as lt,readdirSync as _o,existsSync as ve,writeFileSync as Ss,mkdirSync as zr,rmSync as $o,renameSync as To}from"fs";import{join as ue,dirname as gu}from"path";import{homedir as fu}from"os";function xs(){if(Ht)return Ht;try{return ve(Io)?(Ht=JSON.parse(lt(Io,"utf-8")),Ht):Eo()}catch{return Eo()}}function vs(e){Ht=e;try{zr(re,{recursive:!0}),Ss(Io,JSON.stringify(e),"utf-8")}catch{}}function Eo(){if(!ve(re))return[];let e=[];for(let t of _o(re).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(lt(ue(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})}catch{}return Ht=e,vs(e),e}function hu(e){let t=xs(),n=e.templates||[],s={id:e.id,themeName:e.themeName,updatedAt:e.updatedAt,moduleCount:n.reduce((i,a)=>i+(a.modules?.length||0),0),templateCount:n.length},o=t.findIndex(i=>i.id===e.id);o>=0?t[o]=s:t.push(s),vs(t)}function yu(e){let t=xs().filter(n=>n.id!==e);vs(t)}function bu(e){let t=xs().filter(n=>n.themeName!==e);vs(t)}function v(){return we}function Su(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function vt(e,t){let n={id:Su(),themePath:e,themeName:t,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return we=n,gs(e),n}function j(){if(!we)return;zr(re,{recursive:!0});let e=ue(re,`${we.id}.json`);Ss(e,JSON.stringify(we,null,2),"utf-8"),hu(we)}function ws(e){let t=ue(re,e+".json");if(!ve(t))return null;try{let n=JSON.parse(lt(t,"utf-8"));return n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),ys(n),we=n,n}catch{return null}}function Lt(){return ve(re)?xs():[]}function Yr(e,t=!1){let n=ue(re,e+".json"),s="";if(t)try{let o=JSON.parse(lt(n,"utf-8"));s=o.themeName||"",o.themePath&&ve(o.themePath)&&$o(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(lt(n,"utf-8")).themeName||""}catch{}try{ve(n)&&$o(n)}catch{}if(s&&ve(re)){for(let o of _o(re).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(lt(ue(re,o),"utf-8")).themeName===s&&$o(ue(re,o))}catch{}bu(s)}else yu(e);we?.id===e&&(we=null)}function qr(e,t){let n=ue(re,e+".json");if(!ve(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(lt(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,a=ue(gu(i),t);if(ve(i)){if(ve(a))return{ok:!1,error:"A project with that name already exists"};try{To(i,a)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let r=ue(a,"css",`${o}-theme.css`),l=ue(a,"css",`${t}-theme.css`);if(ve(r))try{To(r,l)}catch{}let c=ue(a,"js",`${o}-animations.js`),d=ue(a,"js",`${t}-animations.js`);if(ve(c))try{To(c,d)}catch{}let u=ue(a,"theme.json");if(ve(u))try{let m=JSON.parse(lt(u,"utf-8"));m.label=t,m.name=t,Ss(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(ve(re))for(let r of _o(re).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(lt(ue(re,r),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=a,l.updatedAt=Date.now(),Ss(ue(re,r),JSON.stringify(l,null,2),"utf-8"))}catch{}return we&&we.themeName===o&&(we.themeName=t,we.themePath=a,we.updatedAt=Date.now()),Eo(),{ok:!0}}var re,Io,Ht,we,gn=L(()=>{"use strict";f();jt();Dt();re=ue(fu(),".vibespot","sessions"),Io=ue(re,"_index.json"),Ht=null;we=null});import{readFileSync as No,readdirSync as yn,existsSync as me,writeFileSync as Ee,mkdirSync as hn,rmSync as Xr}from"fs";import{join as D}from"path";function ae(e){try{return No(e,"utf-8")}catch{return""}}function xu(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 vu(e,t){let n=ae(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o="landing_page";s.startsWith("bp-")?o="blog_post":s.startsWith("wp-")?o="website_page":s.startsWith("mo-")&&(o="module_only");let i=s,a=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);a&&(i=a[1].trim());let r=/dnd_module\s+path=["']\.\.\/modules\/(.+?)\.module["']/g,l=[],c;for(;(c=r.exec(n))!==null;)l.push(c[1]);return{id:s,label:i,pageType:o,moduleNames:l,templateContent:n,filename:t}}function wu(e,t,n,s,o){if(!me(e))return[];let i=[],a=yn(e).filter(r=>r.endsWith(".html")&&r!=="home.html");for(let r of a){let l=D(e,r),c=vu(l,r);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,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:n,sharedJs:s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function bn(e){let t=v();if(!t)return;let n=Ur(e);n.length>0&&t.messages.length===0&&(t.messages=n),gs(e);let s=D(e,"modules");if(!me(s))return;let o=yn(s,{withFileTypes:!0});for(let b of o){if(!b.isDirectory()||!b.name.endsWith(".module"))continue;let x=D(s,b.name),w=b.name.replace(/\.module$/,""),S={moduleName:w,fieldsJson:ae(D(x,"fields.json")),metaJson:ae(D(x,"meta.json")),moduleHtml:ae(D(x,"module.html")),moduleCss:ae(D(x,"module.css")),moduleJs:ae(D(x,"module.js"))||void 0};S.fieldsJson&&S.moduleHtml&&(t.modules.push(S),t.moduleOrder.push(w))}let i=D(e,"css"),a=D(e,"js"),r="",l="";if(me(i)){let b=yn(i).filter(x=>x.endsWith("-theme.css"));b.length>0&&(r=ae(D(i,b[0])),t.sharedCss=r)}if(me(a)){let b=yn(a).filter(x=>x.endsWith("-animations.js"));b.length>0&&(l=ae(D(a,b[0])),t.sharedJs=l)}let c=D(e,".vibespot","styleguide.md"),d=D(e,".vibespot","brandvoice.md"),u=D(e,".vibespot","theme-context.md"),m=D(e,".vibespot","plan.md");(me(c)||me(d)||me(u)||me(m))&&(t.brandAssets||(t.brandAssets={}),me(c)&&(t.brandAssets.styleguide=ae(c)),me(d)&&(t.brandAssets.brandvoice=ae(d)),me(u)&&(t.brandAssets.themeContext=ae(u)),me(m)&&(t.brandAssets.plan=ae(m)));let g=D(e,"templates"),y=new Map(t.modules.map(b=>[b.moduleName,b])),h=wu(g,y,r,l,t.messages);if(h.length>0){t.templates=h,t.activeTemplateId=h[0].id;let b=h[0].moduleOrder;if(b.length>0){let x=new Set(t.moduleOrder),w=b.filter(S=>x.has(S));for(let S of t.moduleOrder)w.includes(S)||w.push(S);t.moduleOrder=w}xt(h[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),ys(t)}function _e(){let e=v();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=D(t,"modules");hn(s,{recursive:!0});for(let l of n.values())hn(D(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=D(s,`${l.moduleName}.module`);Ee(D(c,"fields.json"),l.fieldsJson,"utf-8"),Ee(D(c,"meta.json"),l.metaJson,"utf-8"),Ee(D(c,"module.html"),l.moduleHtml,"utf-8"),Ee(D(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ee(D(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=D(t,"css");hn(l,{recursive:!0}),Ee(D(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=D(t,"js");hn(l,{recursive:!0}),Ee(D(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=D(t,"templates");hn(o,{recursive:!0});let i=D(o,"home.html");(e.templates.length>0||e.modules.length>0)&&me(i)&&Xr(i,{force:!0});let r=new Set;if(e.templates.length>0)for(let l of e.templates){if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||Au(l),d=Zr(c,l.label,l.pageType),u=`${l.id}.html`;Ee(D(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&($u(o,l),r.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||Tu(),c=Zr(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ee(D(o,d),c,"utf-8"),r.add(d)}try{for(let l of yn(o))l.startsWith("lp-")&&l.endsWith(".html")&&!r.has(l)&&Xr(D(o,l),{force:!0})}catch{}Cu(),ku()}function Qr(){let e=v();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",bn(e.themePath),e.updatedAt=Date.now(),pt())}function ea(){let e=v();if(!e)return;let t=xe();if(!t)return;let n=e.themePath,s=D(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=D(s,`${o}.module`);if(!me(i))continue;let a={moduleName:o,fieldsJson:ae(D(i,"fields.json")),metaJson:ae(D(i,"meta.json")),moduleHtml:ae(D(i,"module.html")),moduleCss:ae(D(i,"module.css")),moduleJs:ae(D(i,"module.js"))||void 0};a.fieldsJson&&a.moduleHtml&&t.modules.push(a)}if(t.templateFile){let o=D(n,t.templateFile);me(o)&&(t.template=ae(o))}xt(t),e.updatedAt=Date.now()}function Cu(){let e=v();if(!e)return;let t=D(e.themePath,"templates","layouts","base.html");if(me(t))try{let n=No(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+`
134
+ Return ONLY the template HTML content, no markdown fences.`}var ea,ut=G(()=>{"use strict";g();Q();ea=new Map});var Ea=G(()=>{"use strict";g()});import{existsSync as pt,writeFileSync as Mm,mkdirSync as Rm}from"fs";import{join as et}from"path";function Ra(e){return/^[0-9a-f]{4,40}$/i.test(e)}function Be(){return Ns!==null||(Ns=D("git --version").success),Ns}function Os(e){if(!Be())return!1;if(pt(et(e,".git")))return Ma(e),!0;let t=D("git init",{cwd:e});return t.success?(_m(e),Ma(e),D("git add -A",{cwd:e}),D('git commit -m "Initial theme"',{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Ma(e){let t=et(e,".vibespot");pt(t)||Rm(t,{recursive:!0})}function _m(e){let t=et(e,".gitignore");Mm(t,[".vibespot/","node_modules/",""].join(`
135
+ `),"utf-8")}function _t(e,t){if(!Be()||!pt(et(e,".git"))||(D("git add -A",{cwd:e}),D("git diff --cached --quiet",{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=D(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=D("git rev-parse --short HEAD",{cwd:e});return i.success?i.stdout:null}function si(e,t,n,s){if(!Be()||!pt(et(e,".git")))return null;for(let u of s){let m=et(e,u);pt(m)&&D(`git add "${u}"`,{cwd:e})}if(D("git 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=D(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=D("git rev-parse --short HEAD",{cwd:e});return d.success?d.stdout:null}function _a(e){let t=[],n=null;for(let s of e.split(`
136
+ `)){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 Pa(e,t=50){if(!Be())return[];if(!pt(et(e,".git")))return[];let n=D(`git log --name-only --pretty=format:"COMMIT|%h|%H|%s|%at" -n ${t}`,{cwd:e});return!n.success||!n.stdout.trim()?[]:_a(n.stdout)}function Na(e,t,n=50){if(!Be())return[];if(!pt(et(e,".git")))return[];let s=t.replace(/[[\]\\]/g,"\\$&"),o=D(`git log --grep="\\[${s}\\]" --name-only --pretty=format:"COMMIT|%h|%H|%s|%at" -n ${n}`,{cwd:e});return!o.success||!o.stdout.trim()?[]:_a(o.stdout)}function Oa(e,t){if(!Be())return{success:!1,error:"Git not available"};if(!pt(et(e,".git")))return{success:!1,error:"Not a git repo"};if(!Ra(t))return{success:!1,error:"Invalid commit hash"};let n=D(`git cat-file -t ${t}`,{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=D(`git log --format="%s" -1 ${t}`,{cwd:e}),o=s.success?s.stdout:t,i=D(`git checkout ${t} -- .`,{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return D(`git commit -m "${r.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}function Fa(e,t,n,s){if(!Be())return{success:!1,error:"Git not available"};if(!pt(et(e,".git")))return{success:!1,error:"Not a git repo"};if(!Ra(n))return{success:!1,error:"Invalid commit hash"};let o=D(`git cat-file -t ${n}`,{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=D(`git log --format="%s" -1 ${n}`,{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)D(`git checkout ${n} -- "${d}"`,{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};D("git add -A",{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return D(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}var Ns,Zt=G(()=>{"use strict";g();Et();Ns=null});import{appendFileSync as Pm,mkdirSync as Nm,readdirSync as Om,unlinkSync as Fm}from"fs";import{join as ai}from"path";import{homedir as jm}from"os";function Jm(){if(!ii)try{Nm(Fs,{recursive:!0}),ii=!0}catch{}}function Lm(){if(!ri){ri=!0;try{let e=Date.now()-Dm*864e5;for(let t of Om(Fs)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{Fm(ai(Fs,t))}catch{}}}catch{}}}function Hm(){let t=new Date().toISOString().slice(0,10);return ai(Fs,`vibespot-${t}.log`)}function Bm(){return new Date().toISOString().slice(11,23)}function oi(e,t){if(Jm(),!!ii){ri||Lm();try{Pm(Hm(),`${Bm()} ${e} ${t}
137
+ `)}catch{}}}var Fs,Dm,ii,ri,E,re=G(()=>{"use strict";g();Fs=ai(jm(),".vibespot","logs"),Dm=7,ii=!1,ri=!1;E={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),oi("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),oi("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),oi("ERROR",o)}}});import{readFileSync as Um,existsSync as Da,writeFileSync as Gm,mkdirSync as Wm,rmSync as Vm}from"fs";import{join as js}from"path";function Pt(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 Ue(){let e=C();if(!e)return;let t=ye();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.plan=e.brandAssets?.plan)}function Ge(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(),Ue(),Km()}function Ja(e){let t=C();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),J())}function ja(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function zm(e,t){let n=ja(e),s=ja(t);return n===s?!0:n.length<4||s.length<4?!1:n.includes(s)||s.includes(n)}function Ie(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=>zm(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(),Ue()}}function wt(e){let t=C();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),Ue())}function La(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=js(t.themePath,"modules",`${e}.module`);Da(n)&&Vm(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),Ue()}}function Ha(e){let t=C();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),Ue())}function Ba(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);Ga(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),Ue()}catch{}}function ce(){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 Km(){let e=C();if(e)try{let t=js(e.themePath,".vibespot");Wm(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};Gm(js(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Ua(e){let t=js(e,".vibespot","chat.json");if(!Da(t))return[];try{let n=JSON.parse(Um(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Ga(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&&Ga(i.children,s.slice(1).join("."),n))}var Mn=G(()=>{"use strict";g();Rn();Nt();re()});import{existsSync as Ds,rmSync as Js}from"fs";import{join as Qt}from"path";function Ls(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 ye(){let e=C();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function li(e){let t=C();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,Pt(n),t.updatedAt=Date.now(),!0):!1}function Hs(e,t){let n=C();if(!n)throw new Error("No active session");let s=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${s}`,r={id:i,label:t,pageType:e,templateFile:e==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(r),n.activeTemplateId=i,Pt(r),n.updatedAt=Date.now(),r}function Wa(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,Pt(l),n.updatedAt=Date.now(),l}function Va(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 za(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=Qt(n.themePath,"templates"),r=`${o.id}.html`,a=Qt(i,r);if(Ds(a)&&Js(a,{force:!0}),o.pageType==="blog_post"){let l=Qt(i,`${o.id}-listing.html`);Ds(l)&&Js(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=Qt(n.themePath,"modules");for(let l of r){let c=Qt(a,`${l}.module`);Ds(c)&&Js(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?li(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=Qt(n.themePath,".vibespot","plan.md");Ds(r)&&Js(r,{force:!0})}return n.updatedAt=Date.now(),!0}function ft(){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]})}return Array.from(t.values())}var Nt=G(()=>{"use strict";g();Rn();Mn()});import{readFileSync as gt,readdirSync as pi,existsSync as Ee,writeFileSync as Bs,mkdirSync as Ka,rmSync as ci,renameSync as di}from"fs";import{join as be,dirname as Ym}from"path";import{homedir as qm}from"os";function Us(){if(en)return en;try{return Ee(ui)?(en=JSON.parse(gt(ui,"utf-8")),en):mi()}catch{return mi()}}function Gs(e){en=e;try{Ka(de,{recursive:!0}),Bs(ui,JSON.stringify(e),"utf-8")}catch{}}function mi(){if(!Ee(de))return[];let e=[];for(let t of pi(de).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(gt(be(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,isImported:!!n.isImported})}catch{}return en=e,Gs(e),e}function Xm(e){let t=Us(),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,isImported:!!e.isImported},o=t.findIndex(i=>i.id===e.id);o>=0?t[o]=s:t.push(s),Gs(t)}function Zm(e){let t=Us().filter(n=>n.id!==e);Gs(t)}function Qm(e){let t=Us().filter(n=>n.themeName!==e);Gs(t)}function C(){return Me}function ep(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function tn(e,t,n={}){let s={id:ep(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Me=s,Os(e),s}function J(){if(!Me)return;Ka(de,{recursive:!0});let e=be(de,`${Me.id}.json`);Bs(e,JSON.stringify(Me,null,2),"utf-8"),Xm(Me)}function Ws(e){let t=be(de,e+".json");if(!Ee(t))return null;try{let n=JSON.parse(gt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Ls(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 Me=n,n}catch{return null}}function nn(){return Ee(de)?Us():[]}function Ya(e,t=!1){let n=be(de,e+".json"),s="";if(t)try{let o=JSON.parse(gt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ee(o.themePath)&&ci(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(gt(n,"utf-8")).themeName||""}catch{}try{Ee(n)&&ci(n)}catch{}if(s&&Ee(de)){for(let o of pi(de).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(gt(be(de,o),"utf-8")).themeName===s&&ci(be(de,o))}catch{}Qm(s)}else Zm(e);Me?.id===e&&(Me=null)}function qa(e,t){let n=be(de,e+".json");if(!Ee(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=be(Ym(i),t);if(Ee(i)){if(Ee(r))return{ok:!1,error:"A project with that name already exists"};try{di(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=be(r,"css",`${o}-theme.css`),l=be(r,"css",`${t}-theme.css`);if(Ee(a))try{di(a,l)}catch{}let c=be(r,"js",`${o}-animations.js`),d=be(r,"js",`${t}-animations.js`);if(Ee(c))try{di(c,d)}catch{}let u=be(r,"theme.json");if(Ee(u))try{let m=JSON.parse(gt(u,"utf-8"));m.label=t,m.name=t,Bs(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ee(de))for(let a of pi(de).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(gt(be(de,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),Bs(be(de,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Me&&Me.themeName===o&&(Me.themeName=t,Me.themePath=r,Me.updatedAt=Date.now()),mi(),{ok:!0}}var de,ui,en,Me,Rn=G(()=>{"use strict";g();Zt();Nt();de=be(qm(),".vibespot","sessions"),ui=be(de,"_index.json"),en=null;Me=null});import{readFileSync as tp,readdirSync as Qa,statSync as fi}from"fs";import{createHash as np}from"crypto";import{join as ae,relative as sp}from"path";function Ks(e){let t=[];if(!b(e))return Ip(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=sn(e),s=kp(e),o=Tp(e),i=$p(e),r=lp(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 _n(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 {
138
+ ${t.join(`
139
+ `)}
140
+ }
141
+ `}function Ys(e,t){let n=ae(e,"css");if(b(n))try{for(let r of Qa(n))if(r.endsWith("-theme.css"))return null}catch{}let s=sn(e),o=_n(s);if(!o)return null;let i=ae(n,`${t}-theme.css`);return L(i,o),i}function Pn(e){return ae(e,op)}function rp(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:nl(e)}}function gi(e,t){let n=rp(e,t),s=Pn(e);return L(s,JSON.stringify(n,null,2)+`
142
+ `),s}function el(e){let t=Pn(e);return b(t)?null:gi(e)}function ap(e){let t=Pn(e);if(!b(t))return null;try{let n=JSON.parse(T(t));return Mp(n)?n:null}catch{return null}}function lp(e){let t=Pn(e),n=ap(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=nl(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:zs(d.text),afterLines:zs(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:zs(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:zs(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 sn(e){let t=Cp(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=T(u)}catch{continue}let f,y=new RegExp(yp.source,"g");for(;(f=y.exec(m))!==null;){let h=f[1],S=new RegExp(bp.source,"g"),x;for(;(x=S.exec(h))!==null;){let w=x[1].trim(),v=x[2].trim();n[w]||(n[w]=v);let N=v.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if(N){let O=Xa(N[0]);o.set(O,w)}}}for(let h of[cp,dp,up]){let S=new RegExp(h.source,"g"),x;for(;(x=S.exec(m))!==null;){let w=Xa(x[0]);w&&s.set(w,(s.get(w)??0)+1)}}Vs(m,mp,i,xp),Vs(m,pp,r,h=>h.trim()),Sp(m,a),Vs(m,gp,l,h=>h.trim()),Vs(m,hp,c,h=>h.trim())}let d=[...s.entries()].filter(([u])=>!wp(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 Vs(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 Sp(e,t){let n=new RegExp(fp.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 xp(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function Xa(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 wp(e){return vp.has(e)}function Cp(e){let t=[],n=ae(e,"css");if(b(n))for(let o of Ct(n))o.endsWith(".css")&&t.push(ae(n,o));let s=ae(e,"modules");if(b(s))for(let o of Ct(s)){if(!o.endsWith(".module"))continue;let i=ae(s,o,"module.css");b(i)&&t.push(i)}return t}function kp(e){let t=ae(e,"modules"),n=ae(e,"templates"),s=new Set,o=new Map;if(b(t))for(let c of Ct(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,b(ae(t,c,"module.js")))}let i=[],r=new Map;if(b(n))for(let c of Ct(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=ae(n,c),u;try{u=fi(d)}catch{continue}if(!u.isFile())continue;let m;try{m=T(d)}catch{continue}let f=hi(m);for(let h of f){let S=r.get(h)??new Set;S.add(c),r.set(h,S)}let y=c.replace(/\.html$/,"");i.push({id:y,file:`templates/${c}`,modules:Rp(f)})}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 hi(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 Tp(e){let t=[],n=ae(e,"modules");if(!b(n))return t;for(let s of Ct(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=ae(n,s,"fields.json");if(!b(i))continue;let r;try{r=JSON.parse(T(i))}catch{continue}Array.isArray(r)&&tl(r,o,t,0)}return t}function tl(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&&!Ap.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)&&tl(i.children,t,n,s+1)}}function $p(e){let t=[],n=ae(e,"modules");if(b(n))for(let i of Ct(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=ae(n,i,"module.html");b(a)&&Za(a,e,r,t);let l=ae(n,i,"module.js");if(b(l))try{T(l).trim().length>0&&t.push({file:yi(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=ae(e,"templates");if(b(s))for(let i of Ct(s)){if(!i.endsWith(".html"))continue;let r=ae(s,i);if(!b(r))continue;let a;try{a=fi(r)}catch{continue}a.isFile()&&Za(r,e,i,t)}let o=ae(e,"import_modules.json");return b(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 Za(e,t,n,s){let o;try{o=T(e)}catch{return}let i=yi(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 Ip(e,t){let n={hasSnapshot:!1,snapshotPath:Pn(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 nl(e){let t=[];function n(s){for(let o of Ct(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=ae(s,o),r;try{r=fi(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=yi(e,i),l=tp(i),c={path:a,sha256:np("sha256").update(l).digest("hex"),size:l.length};Ep(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function Ep(e){let t=e.lastIndexOf(".");return t<0?!1:ip.has(e.slice(t).toLowerCase())}function Mp(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 zs(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Ct(e){try{return Qa(e)}catch{return[]}}function yi(e,t){return sp(e,t).split("\\").join("/")}function Rp(e){return[...new Set(e)]}var op,ip,cp,dp,up,mp,pp,fp,gp,hp,yp,bp,vp,Ap,qs=G(()=>{"use strict";g();Q();op=".vibespot/import-snapshot.json",ip=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);cp=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,dp=/\brgba?\([^)]+\)/g,up=/\bhsla?\([^)]+\)/g,mp=/font-family\s*:\s*([^;}\n]+)/g,pp=/font-size\s*:\s*([^;}\n]+)/g,fp=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,gp=/border-radius\s*:\s*([^;}\n]+)/g,hp=/box-shadow\s*:\s*([^;}\n]+)/g,yp=/:root\s*\{([\s\S]*?)\}/g,bp=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;vp=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);Ap=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 bi,readdirSync as On,existsSync as Se,writeFileSync as De,mkdirSync as Nn,rmSync as sl}from"fs";import{join as B}from"path";function ue(e){try{return bi(e,"utf-8")}catch{return""}}function _p(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 Pp(e,t){let n=ue(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o="landing_page";s.startsWith("bp-")?o="blog_post":s.startsWith("wp-")?o="website_page":s.startsWith("mo-")&&(o="module_only");let i=s,r=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);r&&(i=r[1].trim());let a=hi(n);return{id:s,label:i,pageType:o,moduleNames:a,templateContent:n,filename:t}}function Np(e,t,n,s,o){if(!Se(e))return[];let i=[],r=On(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=B(e,a),c=Pp(l,a);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let f=t.get(m);f&&(d.push(f),u.push(m))}i.push({id:c.id,label:c.label,pageType:c.pageType,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:n,sharedJs:s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function Xs(e){let t=C();if(!t)return;let n=Ua(e);n.length>0&&t.messages.length===0&&(t.messages=n),Os(e),el(e);let s=B(e,"modules");if(!Se(s))return;let o=On(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let x=B(s,S.name),w=S.name.replace(/\.module$/,""),v={moduleName:w,fieldsJson:ue(B(x,"fields.json")),metaJson:ue(B(x,"meta.json")),moduleHtml:ue(B(x,"module.html")),moduleCss:ue(B(x,"module.css")),moduleJs:ue(B(x,"module.js"))||void 0};v.fieldsJson&&v.moduleHtml&&(t.modules.push(v),t.moduleOrder.push(w))}let i=B(e,"css"),r=B(e,"js"),a="",l="";if(Se(i)){let S=On(i).filter(x=>x.endsWith("-theme.css"));S.length>0&&(a=ue(B(i,S[0])),t.sharedCss=a)}if(Se(r)){let S=On(r).filter(x=>x.endsWith("-animations.js"));S.length>0&&(l=ue(B(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=sn(e),x=_n(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");(Se(c)||Se(d)||Se(u)||Se(m))&&(t.brandAssets||(t.brandAssets={}),Se(c)&&(t.brandAssets.styleguide=ue(c)),Se(d)&&(t.brandAssets.brandvoice=ue(d)),Se(u)&&(t.brandAssets.themeContext=ue(u)),Se(m)&&(t.brandAssets.plan=ue(m)));let f=B(e,"templates"),y=new Map(t.modules.map(S=>[S.moduleName,S])),h=Np(f,y,a,l,t.messages);if(h.length>0){t.templates=h,t.activeTemplateId=h[0].id,t.brandAssets?.plan&&!h[0].plan&&(h[0].plan=t.brandAssets.plan);let S=h[0].moduleOrder;if(S.length>0){let x=new Set(t.moduleOrder),w=S.filter(v=>x.has(v));for(let v of t.moduleOrder)w.includes(v)||w.push(v);t.moduleOrder=w}Pt(h[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),Ls(t)}function we(){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=B(t,"modules");Nn(s,{recursive:!0});for(let l of n.values())Nn(B(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=B(s,`${l.moduleName}.module`);De(B(c,"fields.json"),l.fieldsJson,"utf-8"),De(B(c,"meta.json"),l.metaJson,"utf-8"),De(B(c,"module.html"),l.moduleHtml,"utf-8"),De(B(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&De(B(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=B(t,"css");Nn(l,{recursive:!0}),De(B(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=B(t,"js");Nn(l,{recursive:!0}),De(B(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=B(t,"templates");Nn(o,{recursive:!0});let i=B(o,"home.html");(e.templates.length>0||e.modules.length>0)&&Se(i)&&sl(i,{force:!0});let a=new Set;if(e.templates.length>0)for(let l of e.templates){if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||jp(l),d=ol(c,l.label,l.pageType),u=`${l.id}.html`;De(B(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(Dp(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||Jp(),c=ol(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;De(B(o,d),c,"utf-8"),a.add(d)}try{for(let l of On(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&sl(B(o,l),{force:!0})}catch{}Op(),Fp()}function il(){let e=C();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",Xs(e.themePath),e.updatedAt=Date.now(),Ue())}function rl(){let e=C();if(!e)return;let t=ye();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(!Se(i))continue;let r={moduleName:o,fieldsJson:ue(B(i,"fields.json")),metaJson:ue(B(i,"meta.json")),moduleHtml:ue(B(i,"module.html")),moduleCss:ue(B(i,"module.css")),moduleJs:ue(B(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=B(n,t.templateFile);Se(o)&&(t.template=ue(o))}Pt(t),e.updatedAt=Date.now()}function Op(){let e=C();if(!e)return;let t=B(e.themePath,"templates","layouts","base.html");if(Se(t))try{let n=bi(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+`
139
143
  {% if template_js %}
140
144
  {{ require_js(get_asset_url(template_js)) }}
141
145
  {% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
142
146
  {{ require_js(get_asset_url(template_js)) }}
143
147
  {% endif %}
144
- {{ standard_footer_includes }}`),Ee(t,n,"utf-8")}catch{}}function ku(){let e=v();if(!e)return;let t=D(e.themePath,"theme.json");if(me(t))try{let n=JSON.parse(No(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ee(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Zr(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
148
+ {{ standard_footer_includes }}`),De(t,n,"utf-8")}catch{}}function Fp(){let e=C();if(!e)return;let t=B(e.themePath,"theme.json");if(Se(t))try{let n=JSON.parse(bi(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,De(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function ol(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
145
149
  templateType: ${n==="blog_post"?"blog_post":"page"}
146
150
  isAvailableForNewContent: true
147
151
  label: "${t}"
148
152
  -->
149
- `+e}function Au(e){if(e.modules.length===0)return"";let n=v().themeName,o=xu(e).map(a=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
150
- {% dnd_module path="../modules/${a.moduleName}.module" %}
153
+ `+e}function jp(e){if(e.modules.length===0)return"";let n=C().themeName,o=_p(e).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
154
+ {% dnd_module path="../modules/${r.moduleName}.module" %}
151
155
  {% end_dnd_module %}
152
156
  {% end_dnd_section %}`).join(`
153
157
 
@@ -177,7 +181,7 @@ ${o}
177
181
 
178
182
  {% block footer %}
179
183
  {% endblock footer %}
180
- `}function $u(e,t){let n=`<!--
184
+ `}function Dp(e,t){let n=`<!--
181
185
  templateType: blog_listing
182
186
  isAvailableForNewContent: true
183
187
  label: "${t.label} - Listing"
@@ -202,7 +206,7 @@ ${o}
202
206
  {% endif %}
203
207
  </div>
204
208
  {% endblock body %}
205
- `;Ee(D(e,`${t.id}-listing.html`),n,"utf-8")}function Tu(){let e=v();if(!e||e.modules.length===0)return"";let t=e.themeName,s=X().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
209
+ `;De(B(e,`${t.id}-listing.html`),n,"utf-8")}function Jp(){let e=C();if(!e||e.modules.length===0)return"";let t=e.themeName,s=ce().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
206
210
  {% dnd_module path="../modules/${o.moduleName}.module" %}
207
211
  {% end_dnd_module %}
208
212
  {% end_dnd_section %}`).join(`
@@ -233,7 +237,7 @@ ${s}
233
237
 
234
238
  {% block footer %}
235
239
  {% endblock footer %}
236
- `}var Po=L(()=>{"use strict";f();gn();pn();Dt();jt()});var ta=L(()=>{"use strict";f();_r();gn();pn();Po();Dt()});var pe=L(()=>{"use strict";f();ta()});function Cs(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]=Cs(n.children):t[n.name]=n.default??"";return t}function Oo(e,t){let n=e;return n=Fu(n),n=ia(n,t),n=ra(n,t),n=aa(n,t),n=ju(n),n}function Ro(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
240
+ `}var Si=G(()=>{"use strict";g();Rn();Mn();Nt();Zt();qs()});var al=G(()=>{"use strict";g();Ea();Rn();Mn();Si();Nt()});var me=G(()=>{"use strict";g();al()});function Zs(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]=Zs(n.children):t[n.name]=n.default??"";return t}function vi(e,t){let n=e;return n=Kp(n),n=ul(n,t),n=ml(n,t),n=pl(n,t),n=qp(n),n}function wi(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
237
241
  `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
238
242
  `),s=e.renderedModules.join(`
239
243
  `);return`<!DOCTYPE html>
@@ -280,11 +284,11 @@ document.querySelectorAll('img').forEach(function(img){
280
284
  });
281
285
  </script>
282
286
  </body>
283
- </html>`}function Fu(e){return e=e.replace(Iu,""),e=e.replace(Eu,""),e=e.replace(_u,""),na.lastIndex=0,e=e.replace(na,(t,n)=>`/theme-assets/${n}`),sa.lastIndex=0,e=e.replace(sa,""),e=e.replace(Nu,""),e=e.replace(Pu,""),e=e.replace(Mu,""),e=e.replace(Ou,""),e=e.replace(Ru,""),e}function ia(e,t){let n=e,s=0;for(;s<30;){s++;let o=Ju(n);if(!o)break;let{varName:i,iterExpr:a,body:r,start:l,end:c}=o,d=Du(a,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}},h=ia(r,y);return h=ra(h,y),h=aa(h,y),h}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Ju(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],a=s.index+s[0].length;n.lastIndex=a;let r=1,l;for(;(l=n.exec(e))!==null;)if(l[1].startsWith("for"))r++;else if(r--,r===0){let c=e.slice(a,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function ra(e,t){let n=e,s=0;for(;Mo.test(n)&&s<50;)s++,n=n.replace(Mo,(o,i,a)=>{let r=a.split(/\{%[-\s]*else\s*-?%\}/),l=r[0],c=r[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(Bt(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(Bt(m,t))return g}return c}return Bt(i,t)?l:c}),Mo.lastIndex=0;return n}function aa(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),a=i[0].trim(),r=wt(t,a);for(let c=1;c<i.length;c++)r=ca(r,i[c].trim());if(r==null)return"";if(typeof r=="object")return JSON.stringify(r);let l=String(r);return l=l.replace(/\\n/g," ").replace(/\n/g," "),l})}function ju(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Du(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=oa(n[1],t),i=oa(n[2],t),a=[];for(let r=o;r<i;r++)a.push(r);return a}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 oa(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 a=1;a<s.length;a++)i=ca(i,s[a].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 Bt(e,t){let n=e.trim();if(n.startsWith("not "))return!Bt(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Bt(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Bt(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=wt(t,s[1].trim()),a=s[2],r=s[3].trim();switch(typeof r=="string"&&r.startsWith('"')&&r.endsWith('"')||typeof r=="string"&&r.startsWith("'")&&r.endsWith("'")?r=r.slice(1,-1):isNaN(Number(r))?r=wt(t,r):r=Number(r),a){case"==":return i==r;case"!=":return i!=r;case">":return Number(i)>Number(r);case"<":return Number(i)<Number(r);case">=":return Number(i)>=Number(r);case"<=":return Number(i)<=Number(r)}}let o=wt(t,n);return la(o)}function la(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function ca(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 a=parseInt(i,10);return n.length>a?n.slice(0,a)+"...":n}return n;case"default":return la(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 Iu,Eu,_u,na,sa,Nu,Pu,Mu,Ou,Ru,Mo,da=L(()=>{"use strict";f();Iu=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Eu=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,_u=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,na=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,sa=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Nu=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Pu=/\{%[-\s]*module\b.*?%\}/gs,Mu=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Ou=/\{#.*?#\}/gs,Ru=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Mo=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var jo={};ke(jo,{buildModulePreviewHtml:()=>Jo,buildPreviewHtml:()=>Fo});function Hu(e){if(!e)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let t=(r,l)=>{for(let c of r){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"),a=t(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:a}}function Fo(){let e=v();if(!e)return ua();let t=X(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return ua();let s=[],o=[],i=[],a=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d;try{let g=JSON.parse(c.fieldsJson);d={module:Cs(g)}}catch{d={module:{}}}let u=Oo(c.moduleHtml,d),m=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${m}" data-module="${c.moduleName}">${u}</div>`),a.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let r=Hu(e.sharedCss);for(let c of n)if(!a.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}">
287
+ </html>`}function Kp(e){return e=e.replace(Lp,""),e=e.replace(Hp,""),e=e.replace(Bp,""),ll.lastIndex=0,e=e.replace(ll,(t,n)=>`/theme-assets/${n}`),cl.lastIndex=0,e=e.replace(cl,""),e=e.replace(Up,""),e=e.replace(Gp,""),e=e.replace(Wp,""),e=e.replace(Vp,""),e=e.replace(zp,""),e}function ul(e,t){let n=e,s=0;for(;s<30;){s++;let o=Yp(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Xp(r,t),u="";Array.isArray(d)&&(u=d.map((m,f)=>{let y={...t,[i]:m,loop:{index:f+1,index0:f,first:f===0,last:f===d.length-1,length:d.length}},h=ul(a,y);return h=ml(h,y),h=pl(h,y),h}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Yp(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 ml(e,t){let n=e,s=0;for(;xi.test(n)&&s<50;)s++,n=n.replace(xi,(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(on(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],f=d[u+1]||"";if(on(m,t))return f}return c}return on(i,t)?l:c}),xi.lastIndex=0;return n}function pl(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Ot(t,r);for(let c=1;c<i.length;c++)a=gl(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 qp(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Xp(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=dl(n[1],t),i=dl(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=Ot(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Ot(t,e)}function dl(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Ot(t,o);for(let r=1;r<s.length;r++)i=gl(i,s[r].trim());return Number(i)||0}function Ot(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 on(e,t){let n=e.trim();if(n.startsWith("not "))return!on(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>on(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>on(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=Ot(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=Ot(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=Ot(t,n);return fl(o)}function fl(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function gl(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 fl(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 Lp,Hp,Bp,ll,cl,Up,Gp,Wp,Vp,zp,xi,hl=G(()=>{"use strict";g();Lp=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Hp=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,Bp=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,ll=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,cl=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Up=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Gp=/\{%[-\s]*module\b.*?%\}/gs,Wp=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Vp=/\{#.*?#\}/gs,zp=/\{\{[-\s]*content\.\w+.*?\}\}/gs,xi=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Qs={};_e(Qs,{buildModulePreviewHtml:()=>ki,buildPreviewHtml:()=>Ci});function Zp(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 Ci(){let e=C();if(!e)return yl();let t=ce(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return yl();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;try{let f=JSON.parse(c.fieldsJson);d={module:Zs(f)}}catch{d={module:{}}}let u=vi(c.moduleHtml,d),m=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${m}" data-module="${c.moduleName}">${u}</div>`),r.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let a=Zp(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}">
284
288
  <div class="vibespot-placeholder">
285
289
  <div class="vibespot-placeholder__name">${c}</div>
286
290
  </div>
287
- </div>`)}let l=`body{background:${r.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${r.surface};border:1px dashed ${r.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${r.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return Ro({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function ua(){return`<!DOCTYPE html>
291
+ </div>`)}let l=`body{background:${a.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${a.surface};border:1px dashed ${a.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${a.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return wi({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function yl(){return`<!DOCTYPE html>
288
292
  <html lang="en">
289
293
  <head>
290
294
  <meta charset="utf-8">
@@ -335,11 +339,11 @@ document.querySelectorAll('img').forEach(function(img){
335
339
  <div class="welcome__sub">Build Something Great</div>
336
340
  </div>
337
341
  </body>
338
- </html>`}function Jo(e){let t=v();if(!t)return"";let n;for(let i of t.templates)if(n=i.modules.find(a=>a.moduleName===e),n)break;if(n||(n=t.modules.find(i=>i.moduleName===e)),!n)return"";let s;try{let i=JSON.parse(n.fieldsJson);s={module:Cs(i)}}catch{s={module:{}}}let o=Oo(n.moduleHtml,s);return Ro({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${o}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}var ks=L(()=>{"use strict";f();da();pe()});function ze(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 a=parseInt(i[1],10);if(a<=n)return null;n=a;let r=Math.max(0,a-5),c=t.slice(r,a+1).lastIndexOf('"');if(c===-1)return null;let d=r+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function Sn(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,a=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(a){a=!1;continue}if(u==="\\"){a=!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 ze(c)}function Do(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 ma(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{A.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ze(s[1]);if(!i||typeof i!="object")throw A.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let a=i;a.modules&&Array.isArray(a.modules)&&(oe({modules:a.modules.map(r=>Do(r)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(i){A.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 a=ze(s[1]);if(!a||typeof a!="object")throw new Error("Invalid JSON after repair");let r=a;r.modules&&Array.isArray(r.modules)&&(oe({modules:r.modules.map(l=>Do(l)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(a){A.warn("parse","Failed to parse JSON module block",{error:a instanceof Error?a.message:String(a)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){A.info("parse","Detected truncated response (odd fence count), attempting salvage");let a=e.lastIndexOf("```"),r=e.slice(a+3);r=r.replace(/^[\w-]*\s*\n?/,"");let l=Sn(r);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(A.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),oe({modules:c.modules.map(d=>Do(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){A.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"'),a=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(i||a){let r=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.";A.warn("parse",r),t&&t(r)}}}var As=L(()=>{"use strict";f();pe();ie()});function Ut(){let e=v();return e?{pageType:xe()?.pageType,brandAssets:e.brandAssets}:{}}function pa(e,t,n=!1,s,o){let a=[{type:"text",text:Bu(t,n)}];if(n){let l=`## HubSpot CMS Rules
339
- ${Me()}
342
+ </html>`}function ki(e){let t=C();if(!t)return"";let n;for(let i of t.templates)if(n=i.modules.find(r=>r.moduleName===e),n)break;if(n||(n=t.modules.find(i=>i.moduleName===e)),!n)return"";let s;try{let i=JSON.parse(n.fieldsJson);s={module:Zs(i)}}catch{s={module:{}}}let o=vi(n.moduleHtml,s);return wi({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${o}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}var Fn=G(()=>{"use strict";g();hl();me()});function tt(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 jn(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 tt(c)}function Ai(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 bl(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=tt(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)&&(Ie({modules:r.modules.map(a=>Ai(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=tt(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(Ie({modules:a.modules.map(l=>Ai(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=jn(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}),Ie({modules:c.modules.map(d=>Ai(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 eo=G(()=>{"use strict";g();me();re()});function rn(){let e=C();return e?{pageType:ye()?.pageType,brandAssets:e.brandAssets}:{}}function Sl(e,t,n=!1,s,o){let r=[{type:"text",text:ef(t,n)}];if(n){let l=`## HubSpot CMS Rules
343
+ ${He()}
340
344
 
341
345
  ## Conversion Guide Reference
342
- ${e}`;a.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
346
+ ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
343
347
  - Use modern, clean design with proper spacing and typography
344
348
  - Include responsive CSS (mobile breakpoint at 767px)
345
349
  - Add scroll animation classes where appropriate
@@ -362,22 +366,22 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
362
366
  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.
363
367
 
364
368
  ## Design Guide
365
- ${po()}
369
+ ${Zo()}
366
370
 
367
371
  ## Content & Copywriting Guide
368
- ${go()}
372
+ ${Qo()}
369
373
 
370
374
  ## HubSpot CMS Rules
371
- ${Me()}
375
+ ${He()}
372
376
 
373
377
  ## Conversion Guide Reference
374
- ${e}`;a.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let r=Lu(s,o);return r&&a.push({type:"text",text:r}),a.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."}),a}function Lu(e,t){let n=[];if(e){let s=ho(e);s&&n.push(`## Page Type Context
378
+ ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=Qp(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 Qp(e,t){let n=[];if(e){let s=ti(e);s&&n.push(`## Page Type Context
375
379
  ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
376
380
  ${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
377
- ${t.brandvoice}`),t?.humanify!==!1){let s=fo();s&&n.push(`## Anti-AI Copy Rules (Humanify)
381
+ ${t.brandvoice}`),t?.humanify!==!1){let s=ei();s&&n.push(`## Anti-AI Copy Rules (Humanify)
378
382
  ${s}`)}return n.join(`
379
383
 
380
- `)}function Bu(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
384
+ `)}function ef(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
381
385
 
382
386
  ## Your Role
383
387
  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.
@@ -456,7 +460,7 @@ The current template's modules are listed in page order in the user message. Thi
456
460
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
457
461
  - **Remove**: When the user asks to remove a section, omit it from the output.
458
462
  - **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.
459
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function xn(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
463
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function Dn(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
460
464
 
461
465
  ## Your Role
462
466
  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.
@@ -535,25 +539,25 @@ The current template's modules are listed in page order in the user message. Thi
535
539
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
536
540
  - **Remove**: When the user asks to remove a section, omit it from the output.
537
541
  - **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.
538
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,a=s?ho(s):"",r=a?`
542
+ - **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?ti(s):"",a=r?`
539
543
 
540
544
  ## Page Type Context
541
- ${a}`:"",l="";if(o?.styleguide&&(l+=`
545
+ ${r}`:"",l="";if(o?.styleguide&&(l+=`
542
546
 
543
547
  ## Brand Style Guide
544
548
  ${o.styleguide}`),o?.brandvoice&&(l+=`
545
549
 
546
550
  ## Brand Voice
547
- ${o.brandvoice}`),o?.humanify!==!1){let d=fo();d&&(l+=`
551
+ ${o.brandvoice}`),o?.humanify!==!1){let d=ei();d&&(l+=`
548
552
 
549
553
  ## Anti-AI Copy Rules (Humanify)
550
- ${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+r+l+`
554
+ ${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+`
551
555
 
552
556
  ## HubSpot CMS Rules
553
- ${Me()}
557
+ ${He()}
554
558
 
555
559
  ## Conversion Guide Reference
556
- ${e}`+c:i+r+l+`
560
+ ${e}`+c:i+a+l+`
557
561
 
558
562
  ## Design Quality
559
563
  - Use modern, clean design with proper spacing and typography
@@ -578,26 +582,26 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
578
582
  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.
579
583
 
580
584
  ## Design Guide
581
- ${po()}
585
+ ${Zo()}
582
586
 
583
587
  ## Content & Copywriting Guide
584
- ${go()}
588
+ ${Qo()}
585
589
 
586
590
  ## HubSpot CMS Rules
587
- ${Me()}
591
+ ${He()}
588
592
 
589
593
  ## Conversion Guide Reference
590
- ${e}`+c}function vn(){let e=v(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
594
+ ${e}`+c}function Jn(){let e=C(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
591
595
 
592
596
  ## Page Narrative (module sequence)
593
597
  `),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
594
- `);for(let r=0;r<s;r++)t.push(`${r+1}. ${n[r].moduleName}
598
+ `);for(let a=0;a<s;a++)t.push(`${a+1}. ${n[a].moduleName}
595
599
  `);t.push(`
596
600
  When the user asks to modify this page, decide whether to MODIFY existing modules, ADD new ones at the right narrative position, REARRANGE the sequence, or REMOVE sections. Always include ALL modules you want to keep in your output.
597
601
  `),t.push(`
598
602
  ## Current Module State
599
- `);for(let r=0;r<s;r++){let l=n[r];t.push(`
600
- ### ${r+1}/${s}: ${l.moduleName}.module
603
+ `);for(let a=0;a<s;a++){let l=n[a];t.push(`
604
+ ### ${a+1}/${s}: ${l.moduleName}.module
601
605
  `),t.push(`**fields.json:**
602
606
  \`\`\`json
603
607
  ${l.fieldsJson}
@@ -624,75 +628,75 @@ ${e.sharedCss}
624
628
  \`\`\`js
625
629
  ${e.sharedJs}
626
630
  \`\`\`
627
- `)}let o=at(),i=new Set(e.modules.map(r=>r.moduleName)),a=o.filter(r=>!i.has(r.module.moduleName));if(a.length>0){t.push(`
631
+ `)}let o=ft(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
628
632
 
629
633
  ## Available modules in this theme (reusable)
630
- `);for(let r of a)t.push(`- ${r.module.moduleName} (used in: ${r.usedIn.join(", ")})
634
+ `);for(let a of r)t.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
631
635
  `);t.push(`
632
636
  The user can ask to reuse any of these modules by name.
633
- `)}return t.join("")}function Ho(e,t){let n=v(),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=vn(),a="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(a=`
637
+ `)}return t.join("")}function Ti(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=Jn(),r="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(r=`
634
638
 
635
639
  ## Available Theme Assets
636
640
  These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
637
641
  ${d.map(u=>`- ${u.filename} (${u.originalName}) \u2192 get_asset_url("${n.themeName}/assets/${u.filename}")`).join(`
638
- `)}`)}let r=e;i&&(r+=`
642
+ `)}`)}let a=e;i&&(a+=`
639
643
 
640
644
  ---
641
- ${i}`),a&&(r+=a),r+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let l=t&&t.length>0;if(l)for(let d of t)d.type==="document"&&d.extractedText&&(r+=`
645
+ ${i}`),r&&(a+=r),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let l=t&&t.length>0;if(l)for(let d of t)d.type==="document"&&d.extractedText&&(a+=`
642
646
 
643
647
  ---
644
648
  [Attached document: ${d.originalName}]
645
- ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(r+=`
649
+ ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(a+=`
646
650
 
647
- [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:r}),o.push({role:"user",content:d})}else o.push({role:"user",content:r});return o}var ga=L(()=>{"use strict";f();ot();pe()});import{spawn as fa}from"child_process";async function ha(){return Lo||(Lo=(await import("@anthropic-ai/sdk")).default),Lo}function ya(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
651
+ [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 xl=G(()=>{"use strict";g();ut();me()});import{spawn as vl}from"child_process";async function wl(){return $i||($i=(await import("@anthropic-ai/sdk")).default),$i}function Cl(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
648
652
  [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
649
653
 
650
654
  ---
651
655
  [Attached document: ${n.originalName}]
652
- ${n.extractedText}`);return t.join("")}async function ba(e,t,n,s,o,i,a){for(let r=0;;r++)try{let l="",c=0,d=i||(()=>{});d(ye[0]);let u=setInterval(()=>{c++,d(ye[Math.min(c,ye.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)}a&&a(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"))||r>=Bo.length)throw l;let m=Bo[r];A.warn("ai-engine",`Rate limited (429), attempt ${r+1}/${Bo.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 Sa(e,t,n){let s=ce(),i=v().modules.length>0,a=Ho(e,n),r=Ut(),l=pa(s,t,i,r.pageType,r.brandAssets);return{messages:a,systemBlocks:l,conversionGuide:s,editMode:i}}async function xa(e,t,n,s,o,i,a,r){let l=await ha(),c=new l({apiKey:t}),{messages:d,systemBlocks:u}=Sa(e,n,r);A.info("anthropic","API call",{model:s,systemBlockCount:u.length,cachedBlocks:u.filter(m=>m.cache_control).length,messageCount:d.length}),await ba(c,u,d,s,o,i,a)}async function va(e,t,n,s,o,i,a){let r=await no();if(!r)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await ha(),c=new l({authToken:r,defaultHeaders:Zt}),{messages:d,systemBlocks:u}=Sa(e,t,a),m=[{type:"text",text:Mt},...u];A.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await ba(c,m,d,n,s,o,i)}async function wa(e,t,n,s,o,i,a,r){let l=ce(),c=v().modules.length>0,d=Ho(e,r),u=Ut(),m=d.map(O=>typeof O.content=="string"?O:{role:O.role,content:O.content.map(R=>R.type==="text"?{type:"text",text:R.text}:{type:"image_url",image_url:{url:`data:${R.source.media_type};base64,${R.source.data}`}})}),g=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:xn(l,n,c,u.pageType,u.brandAssets)},...m]})});if(!g.ok){let O=await g.text();throw new Error(`OpenAI API error (${g.status}): ${O}`)}let y=0,h=i||(()=>{});h(ye[0]);let b=setInterval(()=>{y++,h(ye[Math.min(y,ye.length-1)])},6e3),x="",w=g.body.getReader(),S=new TextDecoder,M="";try{for(;;){let{done:O,value:R}=await w.read();if(O)break;M+=S.decode(R,{stream:!0});let H=M.split(`
653
- `);M=H.pop()||"";for(let z of H){if(!z.startsWith("data: "))continue;let _=z.slice(6).trim();if(_==="[DONE]")break;try{let C=JSON.parse(_).choices?.[0]?.delta?.content;C&&(x+=C,o(C))}catch{}}}}finally{clearInterval(b)}a&&a(x)}async function Ca(e,t,n,s,o,i,a){let r=ce(),l=v(),c=l.modules.length>0,d=vn(),u=Ut(),m=[];for(let _ of l.messages.slice(-20))m.push({role:_.role==="assistant"?"model":"user",parts:[{text:_.content}]});let g=d?`${e}
656
+ ${n.extractedText}`);return t.join("")}async function kl(e,t,n,s,o,i,r){for(let a=0;;a++)try{let l="",c=0,d=i||(()=>{});d(ke[0]);let u=setInterval(()=>{c++,d(ke[Math.min(c,ke.length-1)])},6e3);try{let m=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});for await(let f of m)if(f.type==="content_block_delta"&&f.delta.type==="text_delta"){let y=f.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>=Ii.length)throw l;let m=Ii[a];E.warn("ai-engine",`Rate limited (429), attempt ${a+1}/${Ii.length} \u2014 waiting ${m}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${m}s...`),await new Promise(f=>setTimeout(f,m*1e3)),i&&i("Retrying...")}}function Al(e,t,n){let s=ge(),i=C().modules.length>0,r=Ti(e,n),a=rn(),l=Sl(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function Tl(e,t,n,s,o,i,r,a){let l=await wl(),c=new l({apiKey:t}),{messages:d,systemBlocks:u}=Al(e,n,a);E.info("anthropic","API call",{model:s,systemBlockCount:u.length,cachedBlocks:u.filter(m=>m.cache_control).length,messageCount:d.length}),await kl(c,u,d,s,o,i,r)}async function $l(e,t,n,s,o,i,r){let a=await Bo();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await wl(),c=new l({authToken:a,defaultHeaders:hn}),{messages:d,systemBlocks:u}=Al(e,t,r),m=[{type:"text",text:Kt},...u];E.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(f=>f.cache_control).length,messageCount:d.length}),await kl(c,m,d,n,s,o,i)}async function Il(e,t,n,s,o,i,r,a){let l=ge(),c=C().modules.length>0,d=Ti(e,a),u=rn(),m=d.map(O=>typeof O.content=="string"?O:{role:O.role,content:O.content.map(F=>F.type==="text"?{type:"text",text:F.text}:{type:"image_url",image_url:{url:`data:${F.source.media_type};base64,${F.source.data}`}})}),f=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:Dn(l,n,c,u.pageType,u.brandAssets)},...m]})});if(!f.ok){let O=await f.text();throw new Error(`OpenAI API error (${f.status}): ${O}`)}let y=0,h=i||(()=>{});h(ke[0]);let S=setInterval(()=>{y++,h(ke[Math.min(y,ke.length-1)])},6e3),x="",w=f.body.getReader(),v=new TextDecoder,N="";try{for(;;){let{done:O,value:F}=await w.read();if(O)break;N+=v.decode(F,{stream:!0});let U=N.split(`
657
+ `);N=U.pop()||"";for(let q of U){if(!q.startsWith("data: "))continue;let _=q.slice(6).trim();if(_==="[DONE]")break;try{let k=JSON.parse(_).choices?.[0]?.delta?.content;k&&(x+=k,o(k))}catch{}}}}finally{clearInterval(S)}r&&r(x)}async function El(e,t,n,s,o,i,r){let a=ge(),l=C(),c=l.modules.length>0,d=Jn(),u=rn(),m=[];for(let _ of l.messages.slice(-20))m.push({role:_.role==="assistant"?"model":"user",parts:[{text:_.content}]});let f=d?`${e}
654
658
 
655
659
  ---
656
- ${d}`:e;if(a?.length)for(let _ of a)_.type==="document"&&_.extractedText&&(g+=`
660
+ ${d}`:e;if(r?.length)for(let _ of r)_.type==="document"&&_.extractedText&&(f+=`
657
661
 
658
662
  ---
659
663
  [Attached document: ${_.originalName}]
660
- ${_.extractedText}`),_.type==="image"&&_.usage==="asset"&&_.assetPath&&(g+=`
664
+ ${_.extractedText}`),_.type==="image"&&_.usage==="asset"&&_.assetPath&&(f+=`
661
665
 
662
- [Uploaded image: ${_.originalName} \u2192 available as get_asset_url("${_.assetPath}")]`);let y=[];if(a?.length)for(let _ of a)_.type==="image"&&_.base64&&y.push({inlineData:{mimeType:_.mimeType,data:_.base64}});y.push({text:g}),m.push({role:"user",parts:y});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${t}`,x=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:xn(r,n,c,u.pageType,u.brandAssets)}]},contents:m,generationConfig:{maxOutputTokens:48e3}})});if(!x.ok){let _=await x.text();throw new Error(`Gemini API error (${x.status}): ${_}`)}let w=0,S=o||(()=>{});S(ye[0]);let M=setInterval(()=>{w++,S(ye[Math.min(w,ye.length-1)])},6e3),O="",R=x.body.getReader(),H=new TextDecoder,z="";try{for(;;){let{done:_,value:F}=await R.read();if(_)break;z+=H.decode(F,{stream:!0});let C=z.split(`
663
- `);z=C.pop()||"";for(let I of C){if(!I.startsWith("data: "))continue;let Z=I.slice(6).trim();try{let ft=JSON.parse(Z).candidates?.[0]?.content?.parts?.[0]?.text;ft&&(O+=ft,s(ft))}catch{}}}}finally{clearInterval(M)}i&&i(O)}function Uo(e,t,n={},s){return new Promise((o,i)=>{let a={...process.env};delete a.CLAUDECODE;let r=fa("claude",e,{stdio:["pipe","pipe","pipe"],env:a}),l="",c="",d="",u=!1,m=null,g=S=>{u||(u=!0,S())},y=S=>{try{if(S.type==="assistant"&&S.message?.content){for(let M of S.message.content)if(M.type==="text"&&typeof M.text=="string"){let O=M.text;l+=O,n.onChunk&&n.onChunk(O)}else if(M.type==="tool_use"){let O=M;O.name&&n.onToolUse&&n.onToolUse(O.name,O.input)}}S.type==="result"&&(m=S,!l&&typeof S.result=="string"&&(l=S.result,n.onChunk&&n.onChunk(S.result))),n.onEvent&&n.onEvent(S)}catch{}};r.stdout.on("data",S=>{d+=S.toString();let M;for(;(M=d.indexOf(`
664
- `))>=0;){let O=d.slice(0,M).trim();if(d=d.slice(M+1),!!O)try{y(JSON.parse(O))}catch{}}}),r.stderr.on("data",S=>{c+=S.toString()}),r.on("error",S=>g(()=>i(new Error(`claude failed to start: ${S.message}`)))),r.on("close",S=>{if(d.trim()){try{y(JSON.parse(d.trim()))}catch{}d=""}g(()=>{S!==0||m&&m.is_error?i(new Error(`claude exited with code ${S}.
666
+ [Uploaded image: ${_.originalName} \u2192 available as get_asset_url("${_.assetPath}")]`);let y=[];if(r?.length)for(let _ of r)_.type==="image"&&_.base64&&y.push({inlineData:{mimeType:_.mimeType,data:_.base64}});y.push({text:f}),m.push({role:"user",parts:y});let S=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${t}`,x=await fetch(S,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:Dn(a,n,c,u.pageType,u.brandAssets)}]},contents:m,generationConfig:{maxOutputTokens:48e3}})});if(!x.ok){let _=await x.text();throw new Error(`Gemini API error (${x.status}): ${_}`)}let w=0,v=o||(()=>{});v(ke[0]);let N=setInterval(()=>{w++,v(ke[Math.min(w,ke.length-1)])},6e3),O="",F=x.body.getReader(),U=new TextDecoder,q="";try{for(;;){let{done:_,value:j}=await F.read();if(_)break;q+=U.decode(j,{stream:!0});let k=q.split(`
667
+ `);q=k.pop()||"";for(let M of k){if(!M.startsWith("data: "))continue;let te=M.slice(6).trim();try{let It=JSON.parse(te).candidates?.[0]?.content?.parts?.[0]?.text;It&&(O+=It,s(It))}catch{}}}}finally{clearInterval(N)}i&&i(O)}function Ei(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=vl("claude",e,{stdio:["pipe","pipe","pipe"],env:r}),l="",c="",d="",u=!1,m=null,f=v=>{u||(u=!0,v())},y=v=>{try{if(v.type==="assistant"&&v.message?.content){for(let N of v.message.content)if(N.type==="text"&&typeof N.text=="string"){let O=N.text;l+=O,n.onChunk&&n.onChunk(O)}else if(N.type==="tool_use"){let O=N;O.name&&n.onToolUse&&n.onToolUse(O.name,O.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 N;for(;(N=d.indexOf(`
668
+ `))>=0;){let O=d.slice(0,N).trim();if(d=d.slice(N+1),!!O)try{y(JSON.parse(O))}catch{}}}),a.stderr.on("data",v=>{c+=v.toString()}),a.on("error",v=>f(()=>i(new Error(`claude failed to start: ${v.message}`)))),a.on("close",v=>{if(d.trim()){try{y(JSON.parse(d.trim()))}catch{}d=""}f(()=>{v!==0||m&&m.is_error?i(new Error(`claude exited with code ${v}.
665
669
  `+(c?`Stderr: ${c.slice(0,500)}
666
- `:"")+(l?`Output: ${l.slice(0,500)}`:"No output"))):o(l)})}),r.stdin.on("error",()=>{}),r.stdin.write(t)?r.stdin.end():r.stdin.once("drain",()=>r.stdin.end());let b=s||6e5,x=Math.round(b/6e4),w=setTimeout(()=>{r.kill(),g(()=>i(new Error(`claude (stream-json) timed out after ${x} minutes.
670
+ `:"")+(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 S=s||6e5,x=Math.round(S/6e4),w=setTimeout(()=>{a.kill(),f(()=>i(new Error(`claude (stream-json) timed out after ${x} minutes.
667
671
  `+(c?`Stderr: ${c.slice(0,500)}
668
- `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);r.on("close",()=>clearTimeout(w))})}function Go(e,t,n,s,o){return new Promise((i,a)=>{let r={...process.env};delete r.CLAUDECODE;let l=fa(e,t,{stdio:["pipe","pipe","pipe"],env:r}),c="",d="",u=!1,m=x=>{u||(u=!0,x())};l.stdout.on("data",x=>{let w=x.toString();c+=w,s&&s(w)}),l.stderr.on("data",x=>{d+=x.toString()}),l.on("error",x=>m(()=>a(new Error(`${e} failed to start: ${x.message}`)))),l.on("close",x=>{m(()=>{x!==0?a(new Error(`${e} exited with code ${x}.
672
+ `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},S);a.on("close",()=>clearTimeout(w))})}function Mi(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=vl(e,t,{stdio:["pipe","pipe","pipe"],env:a}),c="",d="",u=!1,m=x=>{u||(u=!0,x())};l.stdout.on("data",x=>{let w=x.toString();c+=w,s&&s(w)}),l.stderr.on("data",x=>{d+=x.toString()}),l.on("error",x=>m(()=>r(new Error(`${e} failed to start: ${x.message}`)))),l.on("close",x=>{m(()=>{x!==0?r(new Error(`${e} exited with code ${x}.
669
673
  `+(d?`Stderr: ${d.slice(0,500)}
670
- `:"")+(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,h=Math.round(y/6e4),b=setTimeout(()=>{l.kill(),m(()=>a(new Error(`${e} timed out after ${h} minutes.
674
+ `:"")+(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,h=Math.round(y/6e4),S=setTimeout(()=>{l.kill(),m(()=>r(new Error(`${e} timed out after ${h} minutes.
671
675
  `+(d?`Stderr: ${d.slice(0,500)}
672
- `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},y);l.on("close",()=>clearTimeout(b))})}async function ka(e,t,n,s,o,i){let a=ce(),r=P(),l=v().modules.length>0,c=Ut(),d=xn(a,t,l,c.pageType,c.brandAssets);d+=`
676
+ `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},y);l.on("close",()=>clearTimeout(S))})}async function Ml(e,t,n,s,o,i){let r=ge(),a=R(),l=C().modules.length>0,c=rn(),d=Dn(r,t,l,c.pageType,c.brandAssets);d+=`
673
677
 
674
678
  ## User Request
675
- `+e,d+=vn(),d+=ya(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print"];r.claudeCodeModel&&u.push("--model",r.claudeCodeModel),r.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let m=0,g=s||(()=>{});g(ye[0]);let y=setInterval(()=>{m++;let h=ye[Math.min(m,ye.length-1)];g(h)},6e3);try{let h=await Uo(u,d,{onChunk:b=>n(b),onToolUse:(b,x)=>{g(Uu(b,x))}});o&&o(h)}finally{clearInterval(y)}}function Uu(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 Wo(e,t,n,s,o,i,a){let r=ce(),l=v().modules.length>0,c=Ut(),d=xn(r,n,l,c.pageType,c.brandAssets);d+=`
679
+ `+e,d+=Jn(),d+=Cl(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,f=s||(()=>{});f(ke[0]);let y=setInterval(()=>{m++;let h=ke[Math.min(m,ke.length-1)];f(h)},6e3);try{let h=await Ei(u,d,{onChunk:S=>n(S),onToolUse:(S,x)=>{f(tf(S,x))}});o&&o(h)}finally{clearInterval(y)}}function tf(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 Ri(e,t,n,s,o,i,r){let a=ge(),l=C().modules.length>0,c=rn(),d=Dn(a,n,l,c.pageType,c.brandAssets);d+=`
676
680
 
677
681
  ## User Request
678
- `+t,d+=vn(),d+=ya(a),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(ye[0]);let h=setInterval(()=>{g++;let b=ye[Math.min(g,ye.length-1)];y(b)},6e3);try{let b=await Go(u,m,d,x=>{s(x)});i&&i(b)}finally{clearInterval(h)}}var Lo,ye,Bo,Vo=L(()=>{"use strict";f();ot();Q();tt();pe();ga();ie();Lo=null;ye=["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..."],Bo=[10,20,40,60,120]});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function B(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function Ye(e,t,n){B(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Fe=L(()=>{"use strict";f()});import{createWriteStream as Gu,mkdirSync as Aa,existsSync as Ko,readFileSync as zo}from"fs";import{join as Ct,extname as Wu}from"path";import{randomUUID as Vu}from"crypto";import Ku from"busboy";function Xu(e,t){if(Ta.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return qu[n]??t}function Zu(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Qu(e,t){if(!Ko(Ct(e,t)))return t;let n=Wu(t),s=t.slice(0,-n.length||void 0),o=1;for(;Ko(Ct(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function em(e){let t=(await import("pdf-parse")).default,n=zo(e);return(await t(n)).text}async function tm(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function nm(e){return zo(e,"utf-8")}function Ia(e,t){let n=v();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=[],a=0,r=[],l=Ku({headers:e.headers,limits:{fileSize:zu,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;a++;let y=Xu(m,g);if(!Ta.has(y)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let h=$a.has(y),b=Zu(m),x=Vu(),w,S;h?(w=Ct(n.themePath,"assets"),Aa(w,{recursive:!0}),S=Qu(w,b)):(w=Ct(n.themePath,".vibespot","uploads"),Aa(w,{recursive:!0}),S=`${x}-${b}`);let M=Ct(w,S),O=Gu(M),R=0,H=!1;d.on("data",z=>{R+=z.length}),d.on("limit",()=>{H=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(O),r.push(new Promise(z=>{O.on("finish",()=>{if(!H){let _={id:x,filename:S,originalName:m,type:h?"image":"document",usage:h?"asset":"context",mimeType:y,size:R,addedAt:new Date().toISOString()};o.push(_),Dr(_)}z()}),O.on("error",()=>{i.push(`Failed to write: ${m}`),z()})}))}),l.on("finish",async()=>{await Promise.all(r);for(let c of o)if(c.type==="document"){let d=Ct(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await em(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await tm(d):c.extractedText=nm(d),A.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){A.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(a===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=>{A.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function $s(e){let t=v();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=Ct(t.themePath,"assets",s.filename);Ko(i)&&(o.base64=zo(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 zu,$a,Yu,Ta,qu,Yo=L(()=>{"use strict";f();Fe();pe();ie();zu=10*1024*1024,$a=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Yu=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),Ta=new Set([...$a,...Yu]),qu={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var Pa={};ke(Pa,{callAgent:()=>Ce,callAgentAPI:()=>Na,isAgenticCapable:()=>Cn,isCLIEngine:()=>Gt,resolveThinkingBudget:()=>Qo});async function Ts(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>=qo.length)throw s;let r=qo[n];A.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${qo.length} \u2014 waiting ${r}s`),t&&t(`Rate limited \u2014 retrying in ${r}s...`),await new Promise(l=>setTimeout(l,r*1e3)),t&&t("Retrying...")}}function wn(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 Ea(){return Xo||(Xo=(await import("@anthropic-ai/sdk")).default),Xo}async function sm(e,t,n,s,o){let i=await Ea(),a=new i({apiKey:e,...s?{defaultHeaders:s}:{}}),r=n.messages,l=n.systemPrompt;if(n.systemBlocks?l=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(l=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let c={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Ts(async()=>{let d=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:r,tools:[c],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for(let m of d.content)if(m.type==="tool_use")return{type:"structured",data:wn(m.input)};return{type:"text",text:d.content.filter(m=>m.type==="text").map(m=>m.text).join("")}},n.onStatus)}return Ts(async()=>{let c="",d=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:r,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let u of d)u.type==="content_block_delta"&&u.delta.type==="text_delta"&&(c+=u.delta.text,n.onChunk&&n.onChunk(u.delta.text));return{type:"text",text:c}},n.onStatus)}async function om(e,t,n){let s=await Ea(),o=new s({authToken:e,defaultHeaders:Zt}),i=n.messages,a;if(n.systemBlocks?a=[{type:"text",text:Mt},...n.systemBlocks]:a=[{type:"text",text:Mt},{type:"text",text:n.systemPrompt}],n.structuredOutput){let r={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 Ts(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:a,messages:i,tools:[r],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:wn(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return Ts(async()=>{let r="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:a,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"&&(r+=c.delta.text,n.onChunk&&n.onChunk(c.delta.text));return{type:"text",text:r}},n.onStatus)}function Zo(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"?Zo(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Zo(t.items)),t}async function im(e,t,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:t,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:Zo(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let r=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:wn(JSON.parse(r))}}catch{return A.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:r}}return{type:"text",text:r}}async function rm(e,t,n){let s=t||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${e}`,r=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!r.ok){let d=await r.text(),u=r.status;if(u===429){let m=new Error(`Gemini rate limit: ${d}`);throw m.status=429,m}throw new Error(`Gemini API error (${u}): ${d}`)}let c=(await r.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:wn(JSON.parse(c))}}catch{return A.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function am(e,t){switch(e){case"claude-code":{let n=P(),s=["--print"];return n.claudeCodeModel&&s.push("--model",n.claudeCodeModel),t?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":return{bin:"gemini",args:[]};case"codex-cli":return{bin:"codex",args:["exec","--full-auto"]};default:throw new Error(`Not a CLI engine: ${e}`)}}function lm(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(`
682
+ `+t,d+=Jn(),d+=Cl(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 f=0,y=o||(()=>{});y(ke[0]);let h=setInterval(()=>{f++;let S=ke[Math.min(f,ke.length-1)];y(S)},6e3);try{let S=await Mi(u,m,d,x=>{s(x)});i&&i(S)}finally{clearInterval(h)}}var $i,ke,Ii,_i=G(()=>{"use strict";g();ut();X();lt();me();xl();re();$i=null;ke=["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..."],Ii=[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 Oe(e,t,n){W(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Fe=G(()=>{"use strict";g()});import{createWriteStream as nf,mkdirSync as Rl,existsSync as Pi,readFileSync as Ni}from"fs";import{join as Ft,extname as sf}from"path";import{randomUUID as of}from"crypto";import rf from"busboy";function df(e,t){if(Pl.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return cf[n]??t}function uf(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function mf(e,t){if(!Pi(Ft(e,t)))return t;let n=sf(t),s=t.slice(0,-n.length||void 0),o=1;for(;Pi(Ft(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function pf(e){let t=(await import("pdf-parse")).default,n=Ni(e);return(await t(n)).text}async function ff(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function gf(e){return Ni(e,"utf-8")}function Nl(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=rf({headers:e.headers,limits:{fileSize:af,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:f}=u;r++;let y=df(m,f);if(!Pl.has(y)){i.push(`Unsupported file type: ${m} (${f})`),d.resume();return}let h=_l.has(y),S=uf(m),x=of(),w,v;h?(w=Ft(n.themePath,"assets"),Rl(w,{recursive:!0}),v=mf(w,S)):(w=Ft(n.themePath,".vibespot","uploads"),Rl(w,{recursive:!0}),v=`${x}-${S}`);let N=Ft(w,v),O=nf(N),F=0,U=!1;d.on("data",q=>{F+=q.length}),d.on("limit",()=>{U=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(O),a.push(new Promise(q=>{O.on("finish",()=>{if(!U){let _={id:x,filename:v,originalName:m,type:h?"image":"document",usage:h?"asset":"context",mimeType:y,size:F,addedAt:new Date().toISOString()};o.push(_),Ja(_)}q()}),O.on("error",()=>{i.push(`Failed to write: ${m}`),q()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=Ft(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await pf(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await ff(d):c.extractedText=gf(d),E.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){E.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(r===0){p(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 to(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=Ft(t.themePath,"assets",s.filename);Pi(i)&&(o.base64=Ni(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 af,_l,lf,Pl,cf,Oi=G(()=>{"use strict";g();Fe();me();re();af=10*1024*1024,_l=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),lf=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),Pl=new Set([..._l,...lf]),cf={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var Dl={};_e(Dl,{callAgent:()=>Re,callAgentAPI:()=>jl,isAgenticCapable:()=>Hn,isCLIEngine:()=>an,resolveThinkingBudget:()=>Ji});async function no(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>=Fi.length)throw s;let a=Fi[n];E.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${Fi.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 Ln(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 Ol(){return ji||(ji=(await import("@anthropic-ai/sdk")).default),ji}async function hf(e,t,n,s,o){let i=await Ol(),r=new i({apiKey:e,...s?{defaultHeaders:s}:{}}),a=n.messages,l=n.systemPrompt;if(n.systemBlocks?l=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(l=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let c={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return no(async()=>{let d=await r.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:a,tools:[c],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for(let m of d.content)if(m.type==="tool_use")return{type:"structured",data:Ln(m.input)};return{type:"text",text:d.content.filter(m=>m.type==="text").map(m=>m.text).join("")}},n.onStatus)}return no(async()=>{let c="",d=r.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:a,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let u of d)u.type==="content_block_delta"&&u.delta.type==="text_delta"&&(c+=u.delta.text,n.onChunk&&n.onChunk(u.delta.text));return{type:"text",text:c}},n.onStatus)}async function yf(e,t,n){let s=await Ol(),o=new s({authToken:e,defaultHeaders:hn}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:Kt},...n.systemBlocks]:r=[{type:"text",text:Kt},{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 no(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:Ln(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return no(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 Di(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"?Di(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Di(t.items)),t}async function bf(e,t,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:t,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:Di(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let a=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:Ln(JSON.parse(a))}}catch{return E.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:a}}return{type:"text",text:a}}async function Sf(e,t,n){let s=t||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},r=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${e}`,a=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!a.ok){let d=await a.text(),u=a.status;if(u===429){let m=new Error(`Gemini rate limit: ${d}`);throw m.status=429,m}throw new Error(`Gemini API error (${u}): ${d}`)}let c=(await a.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:Ln(JSON.parse(c))}}catch{return E.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function 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 vf(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(`
679
683
  `);t.push(`
680
684
 
681
685
  ## ${s}
682
- ${o}`)}if(e.structuredOutput){let n=_a(e.structuredOutput.schema);t.push(`
686
+ ${o}`)}if(e.structuredOutput){let n=Fl(e.structuredOutput.schema);t.push(`
683
687
 
684
688
  ## Output Format \u2014 CRITICAL
685
689
  Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
686
690
 
687
691
  The JSON must match this structure:
688
- ${n}`)}return t.join("")}function _a(e,t=0){let n=" ".repeat(t),s=e.properties,o=e.required||[];if(!s)return`${n}${JSON.stringify(e)}`;let i=["{"];for(let[a,r]of Object.entries(s)){let l=o.includes(a)?" (required)":"",c=r.type||"any",d=r.description?` \u2014 ${r.description}`:"",u=r.enum?` [${r.enum.join(", ")}]`:"";if(c==="array"&&r.items){let m=r.items.type||"object";i.push(`${n} "${a}": ${c}<${m}>${l}${d}${u}`)}else c==="object"&&r.properties?i.push(`${n} "${a}": ${_a(r,t+1)}${l}${d}`):i.push(`${n} "${a}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
689
- `)}function cm(e){let t=e.trim(),n=ze(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let r=s[1].trim(),l=ze(r);if(l&&typeof l=="object")return l;let c=Sn(r);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let r=t.slice(o,i+1),l=ze(r);if(l&&typeof l=="object")return l;let c=Sn(r);if(c&&typeof c=="object")return c}let a=Sn(t);return a&&typeof a=="object"?a:null}async function dm(e,t,n){let{bin:s,args:o}=am(e,n),i=lm(n),a;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];a=await Uo(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=um(c,d);n.onStatus(u)}})}else a=await Go(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:a};let r=cm(a);return r?{type:"structured",data:wn(r)}:(A.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:a.slice(0,500),outputLength:a.length}),{type:"text",text:a})}function um(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 Na(e,t,n,s){switch(A.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 sm(t,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(tt(),so)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return om(i,n,s)}case"openai-api":return im(t,n,s);case"gemini-api":return rm(t,n,s);default:throw new Error(`Unsupported API engine: ${e}`)}}async function Ce(e,t,n,s){return mm.has(e)?Na(e,t,n,s):(A.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),dm(e,n,s))}function Qo(e){if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=P();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Cn(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function Gt(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var qo,Xo,mm,qe=L(()=>{"use strict";f();Vo();As();Q();tt();ie();qo=[10,20,40,60,120];Xo=null;mm=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api"])});function Ma(e,t,n,s){let o=t.length>0?`Current template modules (in page order):
690
- ${t.map((r,l)=>`${l+1}. ${r}`).join(`
692
+ ${n}`)}return t.join("")}function Fl(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}": ${Fl(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
693
+ `)}function wf(e){let t=e.trim(),n=tt(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=tt(a);if(l&&typeof l=="object")return l;let c=jn(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=tt(a);if(l&&typeof l=="object")return l;let c=jn(a);if(c&&typeof c=="object")return c}let r=jn(t);return r&&typeof r=="object"?r:null}async function Cf(e,t,n){let{bin:s,args:o}=xf(e,t,n),i=vf(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Ei(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=kf(c,d);n.onStatus(u)}})}else r=await Mi(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=wf(r);return a?{type:"structured",data:Ln(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 kf(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 jl(e,t,n,s){switch(E.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 hf(t,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(lt(),Uo)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return yf(i,n,s)}case"openai-api":return bf(t,n,s);case"gemini-api":return Sf(t,n,s);default:throw new Error(`Unsupported API engine: ${e}`)}}async function Re(e,t,n,s){return Af.has(e)?jl(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}),Cf(e,n,s))}function Ji(e){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 Hn(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function an(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Fi,ji,Af,nt=G(()=>{"use strict";g();_i();eo();X();lt();re();Fi=[10,20,40,60,120];ji=null;Af=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api"])});function Jl(e,t,n,s){let o=t.length>0?`Current template modules (in page order):
694
+ ${t.map((a,l)=>`${l+1}. ${a}`).join(`
691
695
  `)}`:"No modules yet (new page).",i=n.length>0?`
692
696
 
693
697
  Module library (reusable from other templates):
694
- ${n.map(r=>`- ${r.name} (used in: ${r.usedIn.join(", ")})`).join(`
695
- `)}`:"",a=s?`
698
+ ${n.map(a=>`- ${a.name} (used in: ${a.usedIn.join(", ")})`).join(`
699
+ `)}`:"",r=s?`
696
700
 
697
701
  ## Product Context
698
702
  ${s}`:"";return`You are the Intent Analyzer for vibeSpot, a HubSpot CMS page builder.
@@ -701,7 +705,7 @@ Your job: classify the user's request and plan which modules need work. You do N
701
705
 
702
706
  ## Theme: "${e}"
703
707
 
704
- ${o}${i}${a}
708
+ ${o}${i}${r}
705
709
 
706
710
  ## Classification Rules
707
711
 
@@ -742,7 +746,7 @@ CRITICAL: When the user corrects a misclassification (e.g., "I was referencing t
742
746
  If the user asks for multiple things (e.g., "make hero taller AND add testimonials"), capture ALL parts:
743
747
  - Affected existing modules in \`affectedModules\`
744
748
  - New modules in \`newModules\`
745
- - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Oa,Ra=L(()=>{"use strict";f();Oa={type:"object",properties:{intent:{type:"string",enum:["create","modify","add","remove","rearrange","style_change","question"]},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'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function Fa(e,t,n,s,o,i,a){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let r=t.modules.map(g=>g.moduleName),l=Ma(t.themeName,r,a,t.brandAssets?.themeContext),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 Ce(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Oa,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){A.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:r,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||[],A.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:pm(m)}),m}function pm(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 Ja=L(()=>{"use strict";f();qe();Ra();ie()});function ei(e,t){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
749
+ - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Ll,Hl=G(()=>{"use strict";g();Ll={type:"object",properties:{intent:{type:"string",enum:["create","modify","add","remove","rearrange","style_change","question"]},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'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function Bl(e,t,n,s,o,i,r){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let a=t.modules.map(f=>f.moduleName),l=Jl(t.themeName,a,r,t.brandAssets?.themeContext),c=[],d=t.messages.slice(-6);for(let f of d)if(f.role==="user"||f.role==="assistant"){let y=f.role==="assistant"&&f.content.length>300?f.content.slice(0,300)+"...":f.content;c.push({role:f.role,content:y})}c.push({role:"user",content:e});let u=await Re(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Ll,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){E.warn("intent-analyzer","Did not get structured output, falling back");let f=t.modules.length===0;return{intent:f?"create":"modify",affectedModules:f?[]:a,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:f}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],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:Tf(m)}),m}function Tf(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 Ul=G(()=>{"use strict";g();nt();Hl();re()});function Li(e,t){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
746
750
 
747
751
  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.
748
752
 
@@ -829,22 +833,22 @@ Good system font stacks by style:
829
833
  | Geometric | Futura, "Century Gothic", "Trebuchet MS", sans-serif | system-ui, sans-serif |`),n.push(`
830
834
 
831
835
  ## Design Guide
832
- ${Ba()}`),t?.styleguide&&n.push(`
836
+ ${Kl()}`),t?.styleguide&&n.push(`
833
837
 
834
838
  ## Brand Style Guide
835
839
  ${t.styleguide}`),t?.themeContext&&n.push(`
836
840
 
837
841
  ## Product Context
838
- ${t.themeContext}`),n.join("")}function ja(e,t){let n=ei(e),o=n.indexOf(`
842
+ ${t.themeContext}`),n.join("")}function Gl(e,t){let n=Li(e),o=n.indexOf(`
839
843
 
840
844
  ## Design Guide
841
- `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),a=`## Design Guide
842
- ${Ba()}`,r=[{type:"text",text:i},{type:"text",text:a,cache_control:{type:"ephemeral"}}],l=[];return t?.styleguide&&l.push(`## Brand Style Guide
845
+ `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Design Guide
846
+ ${Kl()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];return t?.styleguide&&l.push(`## Brand Style Guide
843
847
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
844
- ${t.themeContext}`),l.length>0&&r.push({type:"text",text:l.join(`
848
+ ${t.themeContext}`),l.length>0&&a.push({type:"text",text:l.join(`
845
849
 
846
- `)}),r}function gm(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(`
847
- `)}function Ha(e,t,n,s){let o=[],i=gm(t);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
850
+ `)}),a}function $f(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(`
851
+ `)}function Vl(e,t,n,s){let o=[],i=$f(t);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
848
852
 
849
853
  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.
850
854
 
@@ -875,7 +879,7 @@ ${i}
875
879
  - any "Existing Modules to Keep" the user listed (these are not in \`modules\`, but still belong in \`moduleOrder\`)`),(!s||s.includes("content"))&&o.push(`
876
880
 
877
881
  ## Content & Copywriting Guide
878
- ${fm()}`),n?.brandvoice&&o.push(`
882
+ ${If()}`),n?.brandvoice&&o.push(`
879
883
 
880
884
  ## Brand Voice
881
885
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -884,7 +888,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
884
888
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
885
889
 
886
890
  ## Anti-AI Copy Rules
887
- ${hm()}`),o.join("")}function Ba(){return`### Design Philosophy
891
+ ${Ef()}`),o.join("")}function Kl(){return`### Design Philosophy
888
892
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
889
893
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
890
894
 
@@ -987,7 +991,7 @@ Include these in shared CSS:
987
991
  | All animations same speed | Stagger with increasing delays |
988
992
  | Skip hover/focus states | Every interactive element needs feedback |
989
993
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
990
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function fm(){return`### Mandatory Page Sections (generate all)
994
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function If(){return`### Mandatory Page Sections (generate all)
991
995
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
992
996
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
993
997
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -1075,7 +1079,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
1075
1079
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
1076
1080
  - Keep paragraphs to 2-3 sentences max
1077
1081
  - Aim for 6th-grade reading level
1078
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function hm(){return`### Banned Punctuation
1082
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function Ef(){return`### Banned Punctuation
1079
1083
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
1080
1084
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
1081
1085
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -1105,34 +1109,34 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
1105
1109
  - Use plain short words: use > utilize, start > commence, help > facilitate
1106
1110
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
1107
1111
  - Front-load the benefit in the first 5 words
1108
- - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Da,La,Ua=L(()=>{"use strict";f();Da={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"]};La={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"]}});async function Ga(e,t,n,s,o,i,a){a({type:"agent_step",step:"designing",label:"Creating design system..."});let r=s==="anthropic-api"||s==="claude-oauth",l=ei(n.themeName,n.brandAssets),c=r?ja(n.themeName,n.brandAssets):void 0,d=`## User Request
1112
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Wl,zl,Yl=G(()=>{"use strict";g();Wl={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"]};zl={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"]}});async function ql(e,t,n,s,o,i,r){r({type:"agent_step",step:"designing",label:"Creating design system..."});let a=s==="anthropic-api"||s==="claude-oauth",l=Li(n.themeName,n.brandAssets),c=a?Gl(n.themeName,n.brandAssets):void 0,d=`## User Request
1109
1113
  ${e}`;n.modules.length>0&&t.designSystemChanges&&(d+=`
1110
1114
 
1111
1115
  ## Current Shared CSS (update this)
1112
1116
  \`\`\`css
1113
1117
  ${n.sharedCss}
1114
- \`\`\``);let u=Qo(s),m=await Ce(s,o,i,{systemPrompt:l,systemBlocks:c,messages:[{role:"user",content:d}],structuredOutput:{schema:Da,name:"design_system"},maxTokens:16e3,...u>0?{thinkingBudgetTokens:u}:{}}),g;m.type!=="structured"?(A.warn("page-architect","Design system: did not get structured output, using fallback"),g={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(g=m.data,A.info("page-architect","Design system created",{aesthetic:g.aesthetic,varCount:Object.keys(g.cssVariables||{}).length,cssLength:g.sharedCss?.length||0}));let y=g.sharedCss||"",h=g.cssVariables;h&&typeof h=="object"&&Object.keys(h).length>0&&(y.includes(":root")||(y=`:root {
1115
- ${Object.entries(h).map(([F,C])=>` ${F.startsWith("--")?F:`--${F}`}: ${C};`).join(`
1118
+ \`\`\``);let u=Ji(s),m=await Re(s,o,i,{systemPrompt:l,systemBlocks:c,messages:[{role:"user",content:d}],structuredOutput:{schema:Wl,name:"design_system"},maxTokens:16e3,...u>0?{thinkingBudgetTokens:u}:{}}),f;m.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=m.data,E.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let y=f.sharedCss||"",h=f.cssVariables;h&&typeof h=="object"&&Object.keys(h).length>0&&(y.includes(":root")||(y=`:root {
1119
+ ${Object.entries(h).map(([j,k])=>` ${j.startsWith("--")?j:`--${j}`}: ${k};`).join(`
1116
1120
  `)}
1117
1121
  }
1118
1122
 
1119
- ${y}`));let b=[],x=/\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,w=[...new Set((e.match(x)||[]).map(_=>_.trim()))];if(w.length>0){let _=w.filter(C=>y.toLowerCase().includes(C.toLowerCase())),F=w.filter(C=>!_.includes(C));F.length>0&&b.push(`Note: ${F.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let S=[`Design system: ${g.aesthetic||"created"} | ${Object.keys(h||{}).length} variables, ${y.length} chars CSS`,...b];a({type:"agent_decision",step:"designing",decision:S.join(`
1120
- `)}),a({type:"design_system_ready",sharedCss:y,sharedJs:g.sharedJs||"",aesthetic:g.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let M=Ha(n.themeName,y,n.brandAssets,t.guidesNeeded),O=`## User Request
1123
+ ${y}`));let S=[],x=/\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,w=[...new Set((e.match(x)||[]).map(_=>_.trim()))];if(w.length>0){let _=w.filter(k=>y.toLowerCase().includes(k.toLowerCase())),j=w.filter(k=>!_.includes(k));j.length>0&&S.push(`Note: ${j.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let v=[`Design system: ${f.aesthetic||"created"} | ${Object.keys(h||{}).length} variables, ${y.length} chars CSS`,...S];r({type:"agent_decision",step:"designing",decision:v.join(`
1124
+ `)}),r({type:"design_system_ready",sharedCss:y,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let N=Vl(n.themeName,y,n.brandAssets,t.guidesNeeded),O=`## User Request
1121
1125
  ${e}`;if(t.newModules.length>0&&(O+=`
1122
1126
 
1123
1127
  ## Planned Modules
1124
- ${t.newModules.map((_,F)=>`${F+1}. **${_.name}** \u2014 ${_.description}`).join(`
1125
- `)}`),n.modules.length>0){let _=new Set(t.affectedModules),F=n.modules.filter(I=>_.has(I.moduleName)),C=n.modules.filter(I=>!_.has(I.moduleName));F.length>0&&(O+=`
1128
+ ${t.newModules.map((_,j)=>`${j+1}. **${_.name}** \u2014 ${_.description}`).join(`
1129
+ `)}`),n.modules.length>0){let _=new Set(t.affectedModules),j=n.modules.filter(M=>_.has(M.moduleName)),k=n.modules.filter(M=>!_.has(M.moduleName));j.length>0&&(O+=`
1126
1130
 
1127
1131
  ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1128
1132
  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.
1129
- `+F.map(I=>`- \`${I.moduleName}\``).join(`
1130
- `)),C.length>0&&(O+=`
1133
+ `+j.map(M=>`- \`${M.moduleName}\``).join(`
1134
+ `)),k.length>0&&(O+=`
1131
1135
 
1132
1136
  ## Existing Modules to Keep (do not re-plan)
1133
1137
  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).
1134
- `+C.map(I=>`- \`${I.moduleName}\``).join(`
1135
- `))}let R=await Ce(s,o,i,{systemPrompt:M,messages:[{role:"user",content:O}],structuredOutput:{schema:La,name:"module_plan"},maxTokens:8e3,...u>0?{thinkingBudgetTokens:u}:{}}),H,z={modules:t.newModules.map(_=>({name:_.name,description:_.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(_=>_.name),narrative:"Page generated from user request"};if(R.type!=="structured")A.warn("page-architect","Module planner: did not get structured output, using fallback"),H=z;else{let _=R.data;Array.isArray(_?.modules)&&_.modules.length>0?(H=_,H.moduleOrder=H.moduleOrder||H.modules.map(F=>F.name),H.narrative=H.narrative||"Page generated from user request"):(A.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:_?Object.keys(_):[]}),H=z),A.info("page-architect","Module plan",{moduleCount:H.modules.length})}return a({type:"agent_decision",step:"designing",decision:`Page: ${H.narrative} | ${H.modules.length} modules planned`}),{designSystem:{cssVariables:g.cssVariables||{},sharedCss:y,sharedJs:g.sharedJs},modules:H.modules,moduleOrder:H.moduleOrder,narrative:H.narrative}}var Wa=L(()=>{"use strict";f();qe();Ua();ie()});function Is(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 ti=L(()=>{"use strict";f()});function kn(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1138
+ `+k.map(M=>`- \`${M.moduleName}\``).join(`
1139
+ `))}let F=await Re(s,o,i,{systemPrompt:N,messages:[{role:"user",content:O}],structuredOutput:{schema:zl,name:"module_plan"},maxTokens:8e3,...u>0?{thinkingBudgetTokens:u}:{}}),U,q={modules:t.newModules.map(_=>({name:_.name,description:_.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(_=>_.name),narrative:"Page generated from user request"};if(F.type!=="structured")E.warn("page-architect","Module planner: did not get structured output, using fallback"),U=q;else{let _=F.data;Array.isArray(_?.modules)&&_.modules.length>0?(U=_,U.moduleOrder=U.moduleOrder||U.modules.map(j=>j.name),U.narrative=U.narrative||"Page generated from user request"):(E.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:_?Object.keys(_):[]}),U=q),E.info("page-architect","Module plan",{moduleCount:U.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${U.narrative} | ${U.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:y,sharedJs:f.sharedJs},modules:U.modules,moduleOrder:U.moduleOrder,narrative:U.narrative}}var Xl=G(()=>{"use strict";g();nt();Yl();re()});function so(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 Hi=G(()=>{"use strict";g()});function Bn(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1136
1140
 
1137
1141
  Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code.
1138
1142
 
@@ -1184,29 +1188,29 @@ ${t}
1184
1188
  \`\`\``),(!n||n.includes("hubspot_rules"))&&o.push(`
1185
1189
 
1186
1190
  ## HubSpot CMS Rules
1187
- ${Me()}`),(!n||n.includes("conversion"))&&o.push(`
1191
+ ${He()}`),(!n||n.includes("conversion"))&&o.push(`
1188
1192
 
1189
1193
  ## Conversion Guide
1190
- ${ce()}`),s?.themeContext&&o.push(`
1194
+ ${ge()}`),s?.themeContext&&o.push(`
1191
1195
 
1192
1196
  ## Product Context
1193
1197
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1194
1198
 
1195
1199
  ## Anti-AI Copy Rules
1196
- ${Va()}`),o.join("")}function Es(e,t,n,s){let o=[],i=kn(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1200
+ ${Zl()}`),o.join("")}function oo(e,t,n,s){let o=[],i=Bn(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1197
1201
 
1198
1202
  ## Theme Shared CSS (use these custom properties)
1199
1203
  \`\`\`css
1200
1204
  ${t}
1201
- \`\`\``),o.push({type:"text",text:i});let a=[];(!n||n.includes("hubspot_rules"))&&a.push(`## HubSpot CMS Rules
1202
- ${Me()}`),(!n||n.includes("conversion"))&&a.push(`## Conversion Guide
1203
- ${ce()}`),a.length>0&&o.push({type:"text",text:a.join(`
1205
+ \`\`\``),o.push({type:"text",text:i});let r=[];(!n||n.includes("hubspot_rules"))&&r.push(`## HubSpot CMS Rules
1206
+ ${He()}`),(!n||n.includes("conversion"))&&r.push(`## Conversion Guide
1207
+ ${ge()}`),r.length>0&&o.push({type:"text",text:r.join(`
1204
1208
 
1205
- `),cache_control:{type:"ephemeral"}});let r=[];return s?.themeContext&&r.push(`## Product Context
1206
- ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&r.push(`## Anti-AI Copy Rules
1207
- ${Va()}`),r.length>0&&o.push({type:"text",text:r.join(`
1209
+ `),cache_control:{type:"ephemeral"}});let a=[];return s?.themeContext&&a.push(`## Product Context
1210
+ ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&a.push(`## Anti-AI Copy Rules
1211
+ ${Zl()}`),a.length>0&&o.push({type:"text",text:a.join(`
1208
1212
 
1209
- `)}),o}function Va(){return`### Banned Punctuation
1213
+ `)}),o}function Zl(){return`### Banned Punctuation
1210
1214
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1211
1215
  - **Semicolons**: Use periods instead in marketing copy.
1212
1216
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1245,7 +1249,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1245
1249
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1246
1250
  - Full names, specific roles (not "John D., CEO")
1247
1251
  - Never start with "This product is..." \u2014 start with the person's situation
1248
- - Vary length and voice across testimonials`}function Ka(e,t,n){let s=[];return s.push(`## User Request
1252
+ - Vary length and voice across testimonials`}function Ql(e,t,n){let s=[];return s.push(`## User Request
1249
1253
  ${e}`),s.push(`
1250
1254
 
1251
1255
  ## Module Specification
@@ -1272,21 +1276,21 @@ ${n.moduleCss}
1272
1276
  **module.js:**
1273
1277
  \`\`\`js
1274
1278
  ${n.moduleJs}
1275
- \`\`\``)),s.join("")}var _s,ni=L(()=>{"use strict";f();ot();_s={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"]}});async function za(e,t,n,s,o,i,a,r,l,c,d){l({type:"agent_step",step:"developing",label:`Generating ${t.length} module${t.length===1?"":"s"}...`});let u=o==="anthropic-api"||o==="claude-oauth",m=kn(s,n,c,d),g=u?Es(s,n,c,d):void 0,y=Is(r),h=t.length,b=t.map((w,S)=>y(async()=>{l({type:"module_progress",module:w.name,status:"generating",current:S+1,total:h});let M="";for(let O=0;O<2;O++)try{O>0&&(A.warn("module-developer",`${w.name}: retrying after failure (attempt ${O+1})`),l({type:"module_progress",module:w.name,status:"retrying",current:S+1,total:h}));let R=await Ya(e,w,m,o,i,a,0,g);return l({type:"module_progress",module:w.name,status:"complete",current:S+1,total:h,moduleFiles:R}),{moduleName:w.name,module:R}}catch(R){M=R instanceof Error?R.message:typeof R=="object"&&R!==null?JSON.stringify(R):String(R),A.error("module-developer",`Failed: ${w.name} (attempt ${O+1})`,{error:M})}return l({type:"module_progress",module:w.name,status:"failed",current:S+1,total:h}),{moduleName:w.name,error:M}}));return(await Promise.allSettled(b)).map(w=>w.status==="fulfilled"?w.value:{moduleName:"unknown",error:w.reason instanceof Error?w.reason.message:String(w.reason)})}async function Ya(e,t,n,s,o,i,a=0,r){let l=Ka(e,t,t.existingCode),c=await Ce(s,o,i,{systemPrompt:n,systemBlocks:r,messages:[{role:"user",content:l}],structuredOutput:{schema:_s,name:"module_output"},maxTokens:16e3});if(c.type!=="structured"){if(a<2)return A.warn("module-developer",`${t.name}: no structured output, retry ${a+1}`),Ya(e,t,n,s,o,i,a+1,r);throw new Error(`Module "${t.name}" failed to produce structured output after ${a+1} attempts`)}let d=c.data,u=typeof d.fieldsJson=="string"?d.fieldsJson:JSON.stringify(d.fieldsJson,null,2),m=typeof d.metaJson=="string"?d.metaJson:JSON.stringify(d.metaJson,null,2);return{moduleName:t.name,fieldsJson:u,metaJson:m,moduleHtml:String(d.moduleHtml||""),moduleCss:String(d.moduleCss||""),moduleJs:d.moduleJs?String(d.moduleJs):void 0}}var qa=L(()=>{"use strict";f();qe();ti();ni();ie()});function Ns(e,t,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),e.map(s=>{let o=[],i={...s};i.fieldsJson=Xa(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=Xa(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=ym(i.fieldsJson,i.moduleName,o),i.fieldsJson=bm(i.fieldsJson,i.moduleName,o),i.moduleCss=Sm(i.moduleCss,i.moduleName,"moduleCss",o),i.moduleCss=vm(i.moduleCss,i.moduleName,t,o),i.moduleHtml=wm(i.moduleHtml,i.moduleName,t,o),i.moduleHtml=km(i.moduleHtml,i.moduleName,o),i.metaJson=Am(i.metaJson,i.moduleName,o);let a=o.every(r=>r.autoFixed);return o.length>0&&A.info("validator",`${i.moduleName}: ${o.length} issues`,{autoFixed:o.filter(r=>r.autoFixed).length,unfixed:o.filter(r=>!r.autoFixed).length}),{module:i,issues:o,valid:a}})}function Xa(e,t,n,s){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:["PAGE"],is_available_for_new_content:!0}):e):(ze(e)===null&&s.push({module:t,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),e)}function ym(e,t,n){let s=e;return/"name"\s*:\s*"name"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"name" is a reserved field name \u2192 renamed to "item_name"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"name"/g,'"name": "item_name"')),/"name"\s*:\s*"label"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"label" is a reserved field name \u2192 renamed to "section_label"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"label"/g,'"name": "section_label"')),s}function bm(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 Sm(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 Za(e){return xm.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function vm(e,t,n,s){if(!e)return e;let o=n+"-",i=/\.([a-zA-Z][\w-]*)/g,a=new Set,r;for(;(r=i.exec(e))!==null;){let c=r[1];!c.startsWith(o)&&!Za(c)&&a.add(c)}if(a.size<=3)return e;let l=e;for(let c of a){let d=new RegExp(`\\.${Cm(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==e&&s.push({module:t,field:"moduleCss",message:`${a.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function wm(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,a=!1,r=e.replace(i,(l,c)=>{let d=c.split(/\s+/),u=!1,m=d.map(g=>g&&!g.startsWith(o)&&!Za(g)&&/^[a-zA-Z][\w-]*$/.test(g)?(u=!0,o+g):g);return u?(a=!0,`class="${m.join(" ")}"`):l});return a&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),r}function Cm(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function km(e,t,n){if(!e)return e;let s=e,o=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,i=[],a;for(;(a=o.exec(s))!==null;){let c=a[1],d=!c.startsWith("end"),u=d?c:c.replace("end","");i.push({tag:c,isOpen:d,baseTag:u,start:a.index,end:a.index+a[0].length})}let r=[],l=[];for(let c=0;c<i.length;c++)if(i[c].isOpen)r.push(c);else{let d=-1;for(let u=r.length-1;u>=0;u--)if(i[r[u]].baseTag===i[c].baseTag){d=u;break}d!==-1?r.splice(d,1):l.push(c)}if(l.length>0){for(let c=l.length-1;c>=0;c--){let d=i[l[c]];s=s.slice(0,d.start)+`<!-- removed orphan {% ${d.tag} %} -->`+s.slice(d.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${l.length} orphan closing tag${l.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(r.length>0){let c=r.map(u=>i[u].baseTag),d=c.reverse().map(u=>`{% end${u} %}`).join(`
1279
+ \`\`\``)),s.join("")}var io,Bi=G(()=>{"use strict";g();ut();io={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"]}});async function ec(e,t,n,s,o,i,r,a,l,c,d){l({type:"agent_step",step:"developing",label:`Generating ${t.length} module${t.length===1?"":"s"}...`});let u=o==="anthropic-api"||o==="claude-oauth",m=Bn(s,n,c,d),f=u?oo(s,n,c,d):void 0,y=so(a),h=t.length,S=t.map((w,v)=>y(async()=>{l({type:"module_progress",module:w.name,status:"generating",current:v+1,total:h});let N="";for(let O=0;O<2;O++)try{O>0&&(E.warn("module-developer",`${w.name}: retrying after failure (attempt ${O+1})`),l({type:"module_progress",module:w.name,status:"retrying",current:v+1,total:h}));let F=await tc(e,w,m,o,i,r,0,f);return l({type:"module_progress",module:w.name,status:"complete",current:v+1,total:h,moduleFiles:F}),{moduleName:w.name,module:F}}catch(F){N=F instanceof Error?F.message:typeof F=="object"&&F!==null?JSON.stringify(F):String(F),E.error("module-developer",`Failed: ${w.name} (attempt ${O+1})`,{error:N})}return l({type:"module_progress",module:w.name,status:"failed",current:v+1,total:h}),{moduleName:w.name,error:N}}));return(await Promise.allSettled(S)).map(w=>w.status==="fulfilled"?w.value:{moduleName:"unknown",error:w.reason instanceof Error?w.reason.message:String(w.reason)})}async function tc(e,t,n,s,o,i,r=0,a){let l=Ql(e,t,t.existingCode),c=await Re(s,o,i,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:l}],structuredOutput:{schema:io,name:"module_output"},maxTokens:16e3});if(c.type!=="structured"){if(r<2)return E.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),tc(e,t,n,s,o,i,r+1,a);throw new Error(`Module "${t.name}" failed to produce structured output after ${r+1} attempts`)}let d=c.data,u=typeof d.fieldsJson=="string"?d.fieldsJson:JSON.stringify(d.fieldsJson,null,2),m=typeof d.metaJson=="string"?d.metaJson:JSON.stringify(d.metaJson,null,2);return{moduleName:t.name,fieldsJson:u,metaJson:m,moduleHtml:String(d.moduleHtml||""),moduleCss:String(d.moduleCss||""),moduleJs:d.moduleJs?String(d.moduleJs):void 0}}var nc=G(()=>{"use strict";g();nt();Hi();Bi();re()});function ro(e,t,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),e.map(s=>{let o=[],i={...s};i.fieldsJson=sc(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=sc(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=Mf(i.fieldsJson,i.moduleName,o),i.fieldsJson=Rf(i.fieldsJson,i.moduleName,o),i.moduleCss=_f(i.moduleCss,i.moduleName,"moduleCss",o),i.moduleCss=Nf(i.moduleCss,i.moduleName,t,o),i.moduleHtml=Of(i.moduleHtml,i.moduleName,t,o),i.moduleHtml=jf(i.moduleHtml,i.moduleName,o),i.metaJson=Df(i.metaJson,i.moduleName,o);let r=o.every(a=>a.autoFixed);return o.length>0&&E.info("validator",`${i.moduleName}: ${o.length} issues`,{autoFixed:o.filter(a=>a.autoFixed).length,unfixed:o.filter(a=>!a.autoFixed).length}),{module:i,issues:o,valid:r}})}function sc(e,t,n,s){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:["PAGE"],is_available_for_new_content:!0}):e):(tt(e)===null&&s.push({module:t,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),e)}function Mf(e,t,n){let s=e;return/"name"\s*:\s*"name"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"name" is a reserved field name \u2192 renamed to "item_name"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"name"/g,'"name": "item_name"')),/"name"\s*:\s*"label"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"label" is a reserved field name \u2192 renamed to "section_label"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"label"/g,'"name": "section_label"')),s}function Rf(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 _f(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 oc(e){return Pf.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Nf(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)&&!oc(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${Ff(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 Of(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,r=!1,a=e.replace(i,(l,c)=>{let d=c.split(/\s+/),u=!1,m=d.map(f=>f&&!f.startsWith(o)&&!oc(f)&&/^[a-zA-Z][\w-]*$/.test(f)?(u=!0,o+f):f);return u?(r=!0,`class="${m.join(" ")}"`):l});return r&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),a}function Ff(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function jf(e,t,n){if(!e)return e;let s=e,o=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,i=[],r;for(;(r=o.exec(s))!==null;){let c=r[1],d=!c.startsWith("end"),u=d?c:c.replace("end","");i.push({tag:c,isOpen:d,baseTag:u,start:r.index,end:r.index+r[0].length})}let a=[],l=[];for(let c=0;c<i.length;c++)if(i[c].isOpen)a.push(c);else{let d=-1;for(let u=a.length-1;u>=0;u--)if(i[a[u]].baseTag===i[c].baseTag){d=u;break}d!==-1?a.splice(d,1):l.push(c)}if(l.length>0){for(let c=l.length-1;c>=0;c--){let d=i[l[c]];s=s.slice(0,d.start)+`<!-- removed orphan {% ${d.tag} %} -->`+s.slice(d.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${l.length} orphan closing tag${l.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(a.length>0){let c=a.map(u=>i[u].baseTag),d=c.reverse().map(u=>`{% end${u} %}`).join(`
1276
1280
  `);s=`${s}
1277
- ${d}`,n.push({module:t,field:"moduleHtml",message:`Added ${c.length} missing closing tag${c.length===1?"":"s"}: ${c.map(u=>`{% end${u} %}`).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 Am(e,t,n){let s=ze(e);if(!s||typeof s!="object")return e;let o=s,i=!1;return o.host_template_types||(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content===void 0&&(o.is_available_for_new_content=!0,i=!0),i?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(o,null,2)):e}var xm,si=L(()=>{"use strict";f();As();ie();xm=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"])});import{execSync as $m}from"child_process";async function Qa(e,t,n,s,o,i,a,r){let l=Date.now(),c=i;if(Gt(n)){let C={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(C)try{$m(`command -v ${C}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${C}" to be installed and on your PATH.`)}}let d=await Fa(e,t,n,s,o,a,r);if(d.intent==="question"&&d.answer){let F=Date.now()-l;return a({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:F,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:F}}}let u=null,m=t.sharedCss,g=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Ga(e,d,t,n,s,o,a),m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g,a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let h=[];if(u)for(let F of u.modules)h.push({name:F.name,description:F.description,contentBrief:F.contentBrief,layoutNotes:F.layoutNotes});else{for(let F of d.newModules)h.push({name:F.name,description:F.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let F of d.affectedModules){let C=t.modules.find(I=>I.moduleName===F);C&&h.push({name:F,description:`Modify existing module: ${F}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:C})}}let b=[],x=[];if(h.length>0){let F=await za(e,h,m,t.themeName,n,s,o,c,a,d.guidesNeeded,t.brandAssets);for(let C of F)C.module?b.push(C.module):x.push(C.moduleName)}let w=null;if(b.length>0){w=Ns(b,t.themeName,a),b=w.map(C=>C.module);let F=w.reduce((C,I)=>C+I.issues.length,0);if(F>0){let C=w.reduce((Z,Mn)=>Z+Mn.issues.filter(ft=>ft.autoFixed).length,0);A.info("pipeline",`Quality check: ${F} issues, ${C} auto-fixed`);let I=w.flatMap(Z=>Z.issues).map(Z=>`${Z.autoFixed?"\u2713":"\u26A0"} ${Z.module}: ${Z.message}`).join(`
1278
- `);a({type:"agent_decision",step:"quality_check",decision:`${F} issues found, ${C} auto-fixed
1279
- ${I}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let S=Tm(t,d,b,u,r),M=Im(t,d,u,S);if(u?.moduleOrder?.length){let F=new Set(u.moduleOrder),C=S.filter(I=>!F.has(I.moduleName)).map(I=>I.moduleName);C.length>0&&a({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 O=Date.now()-l,R=b.length,H=d.unchangedModules.length,z=w?w.flatMap(F=>F.issues):[],_=Em(d,R,H,x,O,u,z);return x.length>0?a({type:"pipeline_partial",succeeded:b.map(F=>F.moduleName),failed:x,durationMs:O}):a({type:"pipeline_complete",modulesGenerated:R,modulesUnchanged:H,durationMs:O}),{modules:S,moduleOrder:M,sharedCss:m,sharedJs:g,assistantMessage:_,stats:{modulesGenerated:R,modulesUnchanged:H,modulesFailed:x.length,durationMs:O}}}function Tm(e,t,n,s,o){let i=[],a=new Set;for(let r of n)i.push(r),a.add(r.moduleName);for(let r of t.unchangedModules){if(a.has(r))continue;let l=e.modules.find(c=>c.moduleName===r);l&&(i.push(l),a.add(r))}if(t.reuseModules)for(let r of t.reuseModules){if(a.has(r.name))continue;let l=o.find(c=>c.name===r.name&&c.module);l&&l.module&&(i.push(l.module),a.add(r.name))}return i}function Im(e,t,n,s){if(n?.moduleOrder?.length){let r=[...n.moduleOrder],l=new Set(r);for(let c of s)if(!l.has(c.moduleName)){let d=r.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?r.splice(d,0,c.moduleName):r.push(c.moduleName),l.add(c.moduleName),A.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return r}if(t.intent==="create")return s.map(r=>r.moduleName);let o=[...e.moduleOrder],i=[...t.newModules.map(r=>({name:r.name,position:r.position})),...(t.reuseModules||[]).map(r=>({name:r.name,position:r.position}))].sort((r,l)=>r.position-l.position);for(let r of i){let l=Math.min(r.position,o.length);o.splice(l,0,r.name)}let a=new Set(s.map(r=>r.moduleName));return o.filter(r=>a.has(r))}function Em(e,t,n,s,o,i,a){let r=Math.round(o/1e3),l=[];if(e.intent==="create")l.push(`Created ${t} module${t===1?"":"s"} in ${r}s.`);else if(e.intent==="modify"||e.intent==="style_change")l.push(`Updated ${t} module${t===1?"":"s"} in ${r}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 ${r}s.`)}else e.intent==="remove"?l.push(`Removed modules in ${r}s.`):e.intent==="rearrange"&&l.push(`Rearranged modules in ${r}s.`);i?.narrative&&l.push(`
1281
+ ${d}`,n.push({module:t,field:"moduleHtml",message:`Added ${c.length} missing closing tag${c.length===1?"":"s"}: ${c.map(u=>`{% end${u} %}`).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 Df(e,t,n){let s=tt(e);if(!s||typeof s!="object")return e;let o=s,i=!1;return o.host_template_types||(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content===void 0&&(o.is_available_for_new_content=!0,i=!0),i?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(o,null,2)):e}var Pf,Ui=G(()=>{"use strict";g();eo();re();Pf=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"])});import{execSync as Jf}from"child_process";async function ic(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(an(n)){let k={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(k)try{Jf(`command -v ${k}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${k}" to be installed and on your PATH.`)}}let d=await Bl(e,t,n,s,o,r,a);if(d.intent==="question"&&d.answer){let j=Date.now()-l;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:j,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:j}}}let u=null,m=t.sharedCss,f=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await ql(e,d,t,n,s,o,r),m=u.designSystem.sharedCss||m,f=u.designSystem.sharedJs||f,r({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:f}));let h=[];if(u)for(let j of u.modules)h.push({name:j.name,description:j.description,contentBrief:j.contentBrief,layoutNotes:j.layoutNotes});else{for(let j of d.newModules)h.push({name:j.name,description:j.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let j of d.affectedModules){let k=t.modules.find(M=>M.moduleName===j);k&&h.push({name:j,description:`Modify existing module: ${j}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:k})}}let S=[],x=[];if(h.length>0){let j=await ec(e,h,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets);for(let k of j)k.module?S.push(k.module):x.push(k.moduleName)}let w=null;if(S.length>0){w=ro(S,t.themeName,r),S=w.map(k=>k.module);let j=w.reduce((k,M)=>k+M.issues.length,0);if(j>0){let k=w.reduce((te,es)=>te+es.issues.filter(It=>It.autoFixed).length,0);E.info("pipeline",`Quality check: ${j} issues, ${k} auto-fixed`);let M=w.flatMap(te=>te.issues).map(te=>`${te.autoFixed?"\u2713":"\u26A0"} ${te.module}: ${te.message}`).join(`
1282
+ `);r({type:"agent_decision",step:"quality_check",decision:`${j} issues found, ${k} auto-fixed
1283
+ ${M}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let v=Lf(t,d,S,u,a),N=Hf(t,d,u,v);if(u?.moduleOrder?.length){let j=new Set(u.moduleOrder),k=v.filter(M=>!j.has(M.moduleName)).map(M=>M.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 O=Date.now()-l,F=S.length,U=d.unchangedModules.length,q=w?w.flatMap(j=>j.issues):[],_=Bf(d,F,U,x,O,u,q);return x.length>0?r({type:"pipeline_partial",succeeded:S.map(j=>j.moduleName),failed:x,durationMs:O}):r({type:"pipeline_complete",modulesGenerated:F,modulesUnchanged:U,durationMs:O}),{modules:v,moduleOrder:N,sharedCss:m,sharedJs:f,assistantMessage:_,stats:{modulesGenerated:F,modulesUnchanged:U,modulesFailed:x.length,durationMs:O}}}function Lf(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 Hf(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 Bf(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(`
1280
1284
 
1281
1285
  ${i.narrative}`),s.length>0&&l.push(`
1282
1286
 
1283
- **Failed:** ${s.join(", ")}. You can retry these individually.`);let c=a.filter(u=>!u.autoFixed),d=a.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(`
1287
+ **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(`
1284
1288
 
1285
1289
  ${u.join(`
1286
- `)}`)}return l.join("")}var el=L(()=>{"use strict";f();qe();Ja();Wa();qa();si();ie();qe()});var il={};ke(il,{runFigmaConversion:()=>_m});import{basename as sl}from"path";async function _m(e,t,n,s,o,i,a,r,l){let c=Date.now();a({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=Nm(e.designTokens,t);a({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),a({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}=Mm(e.sections,e.assets,t);a({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),a({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${g.join(", ")}`}),a({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let y=n==="anthropic-api"||n==="claude-oauth",h=kn(t,d,["hubspot_rules","conversion"],r),b=y?Es(t,d,["hubspot_rules","conversion"],r):void 0,x=Is(i),w=m.length,S=m.map((I,Z)=>{let Mn=e.sections[Z];return x(async()=>{a({type:"module_progress",module:I.name,status:"generating",current:Z+1,total:w});let ft=Fm(Mn,I,e.assets,t,l!==!1),qs="";for(let Yt=0;Yt<2;Yt++)try{Yt>0&&(A.warn("figma-pipeline",`${I.name}: retrying (attempt ${Yt+1})`),a({type:"module_progress",module:I.name,status:"retrying",current:Z+1,total:w}));let It=await Ce(n,s,o,{systemPrompt:h,systemBlocks:b,messages:[{role:"user",content:ft}],structuredOutput:{schema:_s,name:"module_output"},maxTokens:16e3});if(It.type!=="structured")throw new Error("No structured output returned");let je=It.data,_i={moduleName:I.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 a({type:"module_progress",module:I.name,status:"complete",current:Z+1,total:w,moduleFiles:_i}),{moduleName:I.name,module:_i}}catch(It){qs=It instanceof Error?It.message:String(It),A.error("figma-pipeline",`Failed: ${I.name} (attempt ${Yt+1}): ${qs}`)}return a({type:"module_progress",module:I.name,status:"failed",current:Z+1,total:w}),{moduleName:I.name,error:qs}})}),O=(await Promise.allSettled(S)).map(I=>I.status==="fulfilled"?I.value:{moduleName:"unknown",error:String(I.reason)}),R=O.filter(I=>I.module).map(I=>I.module),H=O.filter(I=>I.error).map(I=>I.moduleName),_=Ns(R,t,a).map(I=>I.module),F=Date.now()-c,C=Math.round(F/1e3);return H.length>0?a({type:"pipeline_partial",succeeded:_.map(I=>I.moduleName),failed:H,durationMs:F}):a({type:"pipeline_complete",modulesGenerated:_.length,modulesUnchanged:0,durationMs:F}),{modules:_,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:`Imported ${_.length} modules from Figma design "${e.fileName}" in ${C}s.`,stats:{modulesGenerated:_.length,modulesUnchanged:0,modulesFailed:H.length,durationMs:F}}}function Ps(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),a=(o+i)/2;if(o===i)return{h:0,s:0,l:a};let r=o-i,l=a>.5?r/(2-o-i):r/(o+i),c=0;return o===t?c=((n-s)/r+(n<s?6:0))/6:o===n?c=((s-t)/r+2)/6:c=((t-n)/r+4)/6,{h:c*360,s:l,l:a}}function Nm(e,t){let n=[],s=t,o=[...e.colors].sort((C,I)=>I.occurrences-C.occurrences),i=o.filter(C=>C.usage==="background"||C.usage==="fill"),a=o.filter(C=>C.usage==="text"),r=i[0]||o[0],l=r?Ps(r.hex).l<.4:!1;r&&n.push(` --${s}-color-bg: ${r.hex}`);let c=a[0]||(l?o.find(C=>Ps(C.hex).l>.7):o.find(C=>Ps(C.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([r?.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,I)=>n.push(` --${s}-color-${I+1}: ${C.hex}`)),r){let C=Ps(r.hex).l;n.push(` --${s}-color-surface: ${l?tl(r.hex,.05):nl(r.hex,.03)}`),n.push(` --${s}-color-border: ${l?tl(r.hex,.15):nl(r.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"),h=g[0]?.fontFamily||y[0]?.fontFamily||"system-ui",b=y[0]?.fontFamily||h;n.push(` --${s}-font-display: "${h}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let x=g.sort((C,I)=>I.fontSize-C.fontSize);x[0]&&n.push(` --${s}-size-h1: ${x[0].fontSize}px`),x[1]&&n.push(` --${s}-size-h2: ${x[1].fontSize}px`),x[2]&&n.push(` --${s}-size-h3: ${x[2].fontSize}px`);let w=y.sort((C,I)=>I.occurrences-C.occurrences)[0];w&&n.push(` --${s}-size-body: ${w.fontSize}px`);let S=[...new Set(e.spacing.map(C=>C.value))].sort((C,I)=>C-I),M=["xs","sm","md","lg","xl","2xl","section"];S.slice(0,M.length).forEach((C,I)=>{n.push(` --${s}-space-${M[I]}: ${C}px`)});let O=e.effects.filter(C=>C.type==="shadow"),R=e.effects.filter(C=>C.type==="radius");O[0]&&n.push(` --${s}-shadow: ${O[0].cssValue}`),R.sort((C,I)=>parseFloat(C.cssValue)-parseFloat(I.cssValue)),R[0]&&n.push(` --${s}-radius: ${R[0].cssValue}`),R[1]&&n.push(` --${s}-radius-lg: ${R[1].cssValue}`);let H=`:root {
1290
+ `)}`)}return l.join("")}var rc=G(()=>{"use strict";g();nt();Ul();Xl();nc();Ui();re();nt()});var uc={};_e(uc,{runFigmaConversion:()=>Uf});import{basename as cc}from"path";async function Uf(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}=Gf(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:f}=Vf(e.sections,e.assets,t);r({type:"blueprint_ready",moduleOrder:f,sharedCss:d,sharedJs:u}),r({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${f.join(", ")}`}),r({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let y=n==="anthropic-api"||n==="claude-oauth",h=Bn(t,d,["hubspot_rules","conversion"],a),S=y?oo(t,d,["hubspot_rules","conversion"],a):void 0,x=so(i),w=m.length,v=m.map((M,te)=>{let es=e.sections[te];return x(async()=>{r({type:"module_progress",module:M.name,status:"generating",current:te+1,total:w});let It=Yf(es,M,e.assets,t,l!==!1),Fo="";for(let pn=0;pn<2;pn++)try{pn>0&&(E.warn("figma-pipeline",`${M.name}: retrying (attempt ${pn+1})`),r({type:"module_progress",module:M.name,status:"retrying",current:te+1,total:w}));let Bt=await Re(n,s,o,{systemPrompt:h,systemBlocks:S,messages:[{role:"user",content:It}],structuredOutput:{schema:io,name:"module_output"},maxTokens:16e3});if(Bt.type!=="structured")throw new Error("No structured output returned");let ze=Bt.data,Ir={moduleName:M.name,fieldsJson:typeof ze.fieldsJson=="string"?ze.fieldsJson:JSON.stringify(ze.fieldsJson,null,2),metaJson:typeof ze.metaJson=="string"?ze.metaJson:JSON.stringify(ze.metaJson,null,2),moduleHtml:String(ze.moduleHtml||""),moduleCss:String(ze.moduleCss||""),moduleJs:ze.moduleJs?String(ze.moduleJs):void 0};return r({type:"module_progress",module:M.name,status:"complete",current:te+1,total:w,moduleFiles:Ir}),{moduleName:M.name,module:Ir}}catch(Bt){Fo=Bt instanceof Error?Bt.message:String(Bt),E.error("figma-pipeline",`Failed: ${M.name} (attempt ${pn+1}): ${Fo}`)}return r({type:"module_progress",module:M.name,status:"failed",current:te+1,total:w}),{moduleName:M.name,error:Fo}})}),O=(await Promise.allSettled(v)).map(M=>M.status==="fulfilled"?M.value:{moduleName:"unknown",error:String(M.reason)}),F=O.filter(M=>M.module).map(M=>M.module),U=O.filter(M=>M.error).map(M=>M.moduleName),_=ro(F,t,r).map(M=>M.module),j=Date.now()-c,k=Math.round(j/1e3);return U.length>0?r({type:"pipeline_partial",succeeded:_.map(M=>M.moduleName),failed:U,durationMs:j}):r({type:"pipeline_complete",modulesGenerated:_.length,modulesUnchanged:0,durationMs:j}),{modules:_,moduleOrder:f,sharedCss:d,sharedJs:u,assistantMessage:`Imported ${_.length} modules from Figma design "${e.fileName}" in ${k}s.`,stats:{modulesGenerated:_.length,modulesUnchanged:0,modulesFailed:U.length,durationMs:j}}}function ao(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 Gf(e,t){let n=[],s=t,o=[...e.colors].sort((k,M)=>M.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?ao(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(k=>ao(k.hex).l>.7):o.find(k=>ao(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,M)=>n.push(` --${s}-color-${M+1}: ${k.hex}`)),a){let k=ao(a.hex).l;n.push(` --${s}-color-surface: ${l?ac(a.hex,.05):lc(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?ac(a.hex,.15):lc(a.hex,.12)}`)}let f=e.typography.filter(k=>k.role==="heading"||k.role==="subheading"),y=e.typography.filter(k=>k.role==="body"||k.role==="label"||k.role==="caption"),h=f[0]?.fontFamily||y[0]?.fontFamily||"system-ui",S=y[0]?.fontFamily||h;n.push(` --${s}-font-display: "${h}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${S}", system-ui, sans-serif`);let x=f.sort((k,M)=>M.fontSize-k.fontSize);x[0]&&n.push(` --${s}-size-h1: ${x[0].fontSize}px`),x[1]&&n.push(` --${s}-size-h2: ${x[1].fontSize}px`),x[2]&&n.push(` --${s}-size-h3: ${x[2].fontSize}px`);let w=y.sort((k,M)=>M.occurrences-k.occurrences)[0];w&&n.push(` --${s}-size-body: ${w.fontSize}px`);let v=[...new Set(e.spacing.map(k=>k.value))].sort((k,M)=>k-M),N=["xs","sm","md","lg","xl","2xl","section"];v.slice(0,N.length).forEach((k,M)=>{n.push(` --${s}-space-${N[M]}: ${k}px`)});let O=e.effects.filter(k=>k.type==="shadow"),F=e.effects.filter(k=>k.type==="radius");O[0]&&n.push(` --${s}-shadow: ${O[0].cssValue}`),F.sort((k,M)=>parseFloat(k.cssValue)-parseFloat(M.cssValue)),F[0]&&n.push(` --${s}-radius: ${F[0].cssValue}`),F[1]&&n.push(` --${s}-radius-lg: ${F[1].cssValue}`);let U=`:root {
1287
1291
  ${n.join(`;
1288
1292
  `)};
1289
- }`,z=`
1293
+ }`,q=`
1290
1294
  /* Reset */
1291
1295
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
1292
1296
 
@@ -1370,8 +1374,8 @@ body {
1370
1374
  h1 { font-size: 2rem; }
1371
1375
  h2 { font-size: 1.5rem; }
1372
1376
  h3 { font-size: 1.25rem; }
1373
- }`;return{sharedCss:H+`
1374
- `+z,sharedJs:`(function() {
1377
+ }`;return{sharedCss:U+`
1378
+ `+q,sharedJs:`(function() {
1375
1379
  var observer = new IntersectionObserver(function(entries) {
1376
1380
  entries.forEach(function(entry) {
1377
1381
  if (entry.isIntersecting) {
@@ -1381,11 +1385,11 @@ body {
1381
1385
  });
1382
1386
  }, { threshold: 0.1 });
1383
1387
  document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
1384
- })();`}}function tl(e,t){return ol(e,t)}function nl(e,t){return ol(e,-t)}function ol(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 Pm(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Mm(e,t,n){let s=new Set,o=[];for(let i of e){let a=Pm(i.name);if(s.has(a)){let d=2;for(;s.has(`${a}-${d}`);)d++;a=`${a}-${d}`}s.add(a);let r=Om(i.textContent),l=Rm(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:a,description:c,contentBrief:r,layoutNotes:l})}return{specs:o,moduleOrder:o.map(i=>i.name)}}function Om(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(`
1385
- `)}function Rm(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(`
1388
+ })();`}}function ac(e,t){return dc(e,t)}function lc(e,t){return dc(e,-t)}function dc(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 Wf(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Vf(e,t,n){let s=new Set,o=[];for(let i of e){let r=Wf(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=zf(i.textContent),l=Kf(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 zf(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(`
1389
+ `)}function Kf(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(`
1386
1390
  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(`
1387
- Available image assets:`);for(let o of t){let i=sl(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
1388
- `)}function Fm(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
1391
+ Available image assets:`);for(let o of t){let i=cc(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
1392
+ `)}function Yf(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
1389
1393
 
1390
1394
  TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
1391
1395
  - Use the EXACT text content from the design as field default values
@@ -1407,15 +1411,15 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
1407
1411
 
1408
1412
  ## Section: "${e.name}" (${e.width}x${e.height}px)`),e.backgroundColor&&i.push(`Background: ${e.backgroundColor}`),(e.layoutMode||e.itemSpacing||e.paddingTop)&&(i.push(`
1409
1413
  ### Layout`),e.layoutMode&&i.push(`Direction: ${e.layoutMode}`),e.itemSpacing&&i.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&i.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`)),e.textContent.length>0){i.push(`
1410
- ### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let a of e.textContent)i.push(`- **${a.role}** (${a.fontSize}px, weight ${a.fontWeight}): "${a.text}"`)}if(e.children.length>0){i.push(`
1411
- ### Structure (${e.children.length} children)`);for(let a of e.children){let r=`- ${a.type} "${a.name}" (${a.width}x${a.height})`;a.layoutMode&&(r+=` layout: ${a.layoutMode}`),a.childCount>0&&(r+=`, ${a.childCount} children`),a.characters&&(r+=`
1412
- text: "${a.characters.slice(0,100)}"`),i.push(r)}}if(n.length>0)if(o){i.push(`
1413
- ### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let a of n){let r=sl(a.localPath);i.push(`- \`get_asset_url("${s}/assets/${r}")\` \u2014 ${a.name}`)}}else{i.push(`
1414
- ### 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 a of n)i.push(`- "${a.name}" \u2014 create an image field for this`)}return i.push(`
1414
+ ### 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(`
1415
+ ### 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+=`
1416
+ text: "${r.characters.slice(0,100)}"`),i.push(a)}}if(n.length>0)if(o){i.push(`
1417
+ ### 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=cc(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
1418
+ ### 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(`
1415
1419
  ## Module Specification
1416
1420
  - **Name**: ${t.name}
1417
1421
  - **Description**: ${t.description}`),i.join(`
1418
- `)}var rl=L(()=>{"use strict";f();qe();ti();ni();si();ie()});var al={};ke(al,{buildPlanModePrompt:()=>Jm});function Jm(e,t,n,s,o){let i=jm(o,!!t?.plan),a=[];return a.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
1422
+ `)}var mc=G(()=>{"use strict";g();nt();Hi();Bi();Ui();re()});var pc={};_e(pc,{buildPlanModePrompt:()=>qf});function qf(e,t,n,s,o){let i=Xf(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
1419
1423
 
1420
1424
  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.
1421
1425
 
@@ -1479,42 +1483,47 @@ Drive toward filling these gaps in priority order:
1479
1483
  4. **Sections / modules** \u2014 high-level page structure (hero, features, testimonials, pricing, FAQ, footer, etc.)
1480
1484
  5. **Content** \u2014 actual copy, value props, social proof, key messages
1481
1485
  6. **Brand voice and visual style** \u2014 formal/casual, palette preferences, reference sites
1482
- 7. **Constraints** \u2014 must-haves, must-avoids, integrations needed`),t?.styleguide&&a.push(`## Available styleguide
1486
+ 7. **Constraints** \u2014 must-haves, must-avoids, integrations needed`),t?.styleguide&&r.push(`## Available styleguide
1483
1487
 
1484
1488
  The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
1485
1489
 
1486
1490
  \`\`\`
1487
- ${oi(t.styleguide,1500)}
1488
- \`\`\``),t?.brandvoice&&a.push(`## Available brand voice
1491
+ ${Gi(t.styleguide,1500)}
1492
+ \`\`\``),t?.brandvoice&&r.push(`## Available brand voice
1489
1493
 
1490
1494
  \`\`\`
1491
- ${oi(t.brandvoice,1e3)}
1492
- \`\`\``),t?.themeContext&&a.push(`## Theme context
1495
+ ${Gi(t.brandvoice,1e3)}
1496
+ \`\`\``),t?.themeContext&&r.push(`## Theme context
1493
1497
 
1494
1498
  \`\`\`
1495
- ${oi(t.themeContext,1e3)}
1496
- \`\`\``),n.length>0&&a.push(`## Existing modules in this theme
1499
+ ${Gi(t.themeContext,1e3)}
1500
+ \`\`\``),n.length>0&&r.push(`## Existing modules in this theme
1497
1501
 
1498
1502
  These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
1499
1503
 
1500
- ${n.map(r=>`- ${r}`).join(`
1501
- `)}`),s.length>0&&a.push(`## Module library (reusable across templates)
1504
+ ${n.map(a=>`- ${a}`).join(`
1505
+ `)}`),s.length>0&&r.push(`## Module library (reusable across templates)
1502
1506
 
1503
1507
  These modules exist in other templates and could be reused here. Reference them by name in the plan if appropriate.
1504
1508
 
1505
- ${s.map(r=>`- **${r.name}** (used in: ${r.usedIn.join(", ")})`).join(`
1506
- `)}`),t?.plan&&a.push(`## Current plan (continue refining)
1509
+ ${s.map(a=>`- **${a.name}** (used in: ${a.usedIn.join(", ")})`).join(`
1510
+ `)}`),t?.plan&&r.push(`## Current plan (continue refining)
1507
1511
 
1508
1512
  The plan in progress so far. Build on it \u2014 preserve what's there, only update sections that are changing based on the user's latest message.
1509
1513
 
1510
1514
  \`\`\`markdown
1511
1515
  ${t.plan}
1512
- \`\`\``),a.push(`## Phase guidance for this turn
1516
+ \`\`\``),r.push(`## Phase guidance for this turn
1513
1517
 
1514
- ${i}`),a.join(`
1518
+ ${i}`),r.join(`
1515
1519
 
1516
- `)}function jm(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<=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 oi(e,t){return e.length<=t?e:e.slice(0,t)+`
1517
- ... [truncated]`}var ll=L(()=>{"use strict";f()});var dl={};ke(dl,{applyPipelineResult:()=>At,handleAgenticGenerate:()=>Ms,handleFigmaImport:()=>$n,handleGenerate:()=>Dm,handleGenerateStream:()=>An,handlePlanModeStream:()=>ci,isGenerating:()=>Wt,isPlanModeActive:()=>di,resolveAgenticEngine:()=>Vt,setParseWarningCallback:()=>ai,shouldUseAgenticMode:()=>ui});import{execSync as ii}from"child_process";function ai(e){ri=e}function Wt(){return ct!==null}function kt(e){if(ct){let t=v();if(!t||t.id!==ct){A.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}Re("assistant",e),ma(e,ri||void 0),j()}async function An(e,t,n,s){let o=v();if(!o)throw new Error("No active session");ct=o.id;let a=s?.length?$s(s):void 0;try{let r=P(),l=r.aiEngine||li();switch(l){case"anthropic-api":case"api":{let c=be("anthropic-api",r);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await xa(e,c,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,kt,a);break}case"claude-oauth":{await va(e,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,kt,a);break}case"openai-api":{let c=be("openai-api",r);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await wa(e,c,o.themeName,r.openaiApiModel||"gpt-4o",t,n,kt,a);break}case"gemini-api":{let c=be("gemini-api",r);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await Ca(e,c,o.themeName,t,n,kt,a);break}case"claude-code":await ka(e,o.themeName,t,n,kt,a);break;case"gemini-cli":await Wo("gemini",e,o.themeName,t,n,kt,a);break;case"codex-cli":await Wo("codex",e,o.themeName,t,n,kt,a);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{ct=null,ri=null}}function li(){let e=P();if(Le())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 ii("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return ii("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return ii("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Dm(e){let t="";return await An(e,n=>{t+=n}),t}function cl(){let e=v(),t=xe(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder];return{modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,brandAssets:e.brandAssets?{...e.brandAssets}:void 0}}function Vt(e){let t=e.aiEngine||li();if(!Cn(t))throw new Error("Agentic pipeline is not available for this engine.");if(Gt(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Le())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=be(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-4o";break;case"gemini-api":s="gemini-2.5-flash";break;default:s=""}return{engine:t,apiKey:n,model:s}}async function Ms(e,t,n){let s=v();if(!s)throw new Error("No active session");let o=s.id;ct=o;try{let i=P(),{engine:a,apiKey:r,model:l}=Vt(i),c=i.agenticConcurrency||20,d=cl(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
1520
+ `)}function Xf(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:
1521
+ - Briefly acknowledge the template and that you'll work from this structure (1\u20132 sentences in chat).
1522
+ - 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.
1523
+ - 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.
1524
+ - 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.
1525
+ - 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 Gi(e,t){return e.length<=t?e:e.slice(0,t)+`
1526
+ ... [truncated]`}var fc=G(()=>{"use strict";g()});var Zi={};_e(Zi,{applyPipelineResult:()=>Dt,handleAgenticGenerate:()=>lo,handleFigmaImport:()=>Gn,handleGenerate:()=>Zf,handleGenerateStream:()=>Un,handlePlanModeStream:()=>Yi,isGenerating:()=>kt,isPlanModeActive:()=>qi,resolveAgenticEngine:()=>ln,setParseWarningCallback:()=>zi,shouldUseAgenticMode:()=>Xi});import{execSync as Wi}from"child_process";function zi(e){Vi=e}function kt(){return ht!==null}function jt(e){if(ht){let t=C();if(!t||t.id!==ht){E.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}Ge("assistant",e),bl(e,Vi||void 0),J()}async function Un(e,t,n,s){let o=C();if(!o)throw new Error("No active session");ht=o.id;let r=s?.length?to(s):void 0;try{let a=R(),l=a.aiEngine||Ki();switch(l){case"anthropic-api":case"api":{let c=Te("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await Tl(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,jt,r);break}case"claude-oauth":{await $l(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,jt,r);break}case"openai-api":{let c=Te("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await Il(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,jt,r);break}case"gemini-api":{let c=Te("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await El(e,c,o.themeName,t,n,jt,r);break}case"claude-code":await Ml(e,o.themeName,t,n,jt,r);break;case"gemini-cli":await Ri("gemini",e,o.themeName,t,n,jt,r);break;case"codex-cli":await Ri("codex",e,o.themeName,t,n,jt,r);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{ht=null,Vi=null}}function Ki(){let e=R();if(Ye())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 Wi("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return Wi("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return Wi("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Zf(e){let t="";return await Un(e,n=>{t+=n}),t}function gc(){let e=C(),t=ye(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder];return{modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,brandAssets:e.brandAssets?{...e.brandAssets}:void 0}}function ln(e){let t=e.aiEngine||Ki();if(!Hn(t))throw new Error("Agentic pipeline is not available for this engine.");if(an(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Ye())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=Te(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"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 lo(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=s.id;ht=o;try{let i=R(),{engine:r,apiKey:a,model:l}=ln(i),c=i.agenticConcurrency||20,d=gc(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
1518
1527
 
1519
1528
  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.
1520
1529
 
@@ -1524,32 +1533,32 @@ ${u}
1524
1533
 
1525
1534
  ## User message
1526
1535
 
1527
- ${e}`);let g=n?.length?$s(n):void 0;if(g?.length)for(let S of g)S.type==="document"&&S.extractedText&&(m+=`
1536
+ ${e}`);let f=n?.length?to(n):void 0;if(f?.length)for(let v of f)v.type==="document"&&v.extractedText&&(m+=`
1528
1537
 
1529
1538
  ---
1530
- [Attached document: ${S.originalName}]
1531
- ${S.extractedText}`),S.type==="image"&&S.usage==="asset"&&S.assetPath&&(m+=`
1539
+ [Attached document: ${v.originalName}]
1540
+ ${v.extractedText}`),v.type==="image"&&v.usage==="asset"&&v.assetPath&&(m+=`
1532
1541
 
1533
- [Uploaded image: ${S.originalName} \u2192 available as get_asset_url("${S.assetPath}")]`);let y=at(),h=new Set(d.modules.map(S=>S.moduleName)),b=y.filter(S=>!h.has(S.module.moduleName)).map(S=>({name:S.module.moduleName,usedIn:S.usedIn})),x=await Qa(m,d,a,r,l,c,t,b),w=v();if(!w||w.id!==o)throw A.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return x}finally{ct=null}}async function $n(e,t,n,s){let o=v();if(!o)throw new Error("No active session");let i=o.id;ct=i;try{let{runFigmaConversion:a}=await Promise.resolve().then(()=>(rl(),il)),r=P(),{engine:l,apiKey:c,model:d}=Vt(r),u=r.agenticConcurrency||20,m=cl(),g=await a(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets),y=v();if(!y||y.id!==i)throw A.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{ct=null}}function At(e,t){oe({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Ke(e.moduleOrder),Re("assistant",e.assistantMessage,t),j()}async function ci(e,t,n){let s=v();if(!s)throw new Error("No active session");let o=P(),{engine:i,apiKey:a,model:r}=Vt(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(ll(),al)),Promise.resolve().then(()=>(qe(),Pa))]),d=s.messages.filter(S=>S.role==="assistant").length,u=s.modules.map(S=>S.moduleName),m=at(),g=new Set(u),y=m.filter(S=>!g.has(S.module.moduleName)).map(S=>({name:S.module.moduleName,usedIn:S.usedIn})),h=l(s.themeName,s.brandAssets,u,y,d),b=n?.length?$s(n):void 0,x=e;if(b?.length)for(let S of b)S.type==="document"&&S.extractedText&&(x+=`
1542
+ [Uploaded image: ${v.originalName} \u2192 available as get_asset_url("${v.assetPath}")]`);let y=ft(),h=new Set(d.modules.map(v=>v.moduleName)),S=y.filter(v=>!h.has(v.module.moduleName)).map(v=>({name:v.module.moduleName,usedIn:v.usedIn})),x=await ic(m,d,r,a,l,c,t,S),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 x}finally{ht=null}}async function Gn(e,t,n,s){let o=C();if(!o)throw new Error("No active session");let i=o.id;ht=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(mc(),uc)),a=R(),{engine:l,apiKey:c,model:d}=ln(a),u=a.agenticConcurrency||20,m=gc(),f=await r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets),y=C();if(!y||y.id!==i)throw E.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return f}finally{ht=null}}function Dt(e,t){Ie({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),wt(e.moduleOrder),Ge("assistant",e.assistantMessage,t),J()}async function Yi(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=R(),{engine:i,apiKey:r,model:a}=ln(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(fc(),pc)),Promise.resolve().then(()=>(nt(),Dl))]),d=s.messages.filter(v=>v.role==="assistant").length,u=s.modules.map(v=>v.moduleName),m=ft(),f=new Set(u),y=m.filter(v=>!f.has(v.module.moduleName)).map(v=>({name:v.module.moduleName,usedIn:v.usedIn})),h=l(s.themeName,s.brandAssets,u,y,d),S=n?.length?to(n):void 0,x=e;if(S?.length)for(let v of S)v.type==="document"&&v.extractedText&&(x+=`
1534
1543
 
1535
1544
  ---
1536
- [Attached document: ${S.originalName}]
1537
- ${S.extractedText}`);let w=await c(i,a,r,{systemPrompt:h,messages:[{role:"user",content:x}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return w.type==="text"?w.text:JSON.stringify(w.data)}function di(){return!!P().planMode}function ui(){let e=P(),t=e.aiEngine||li();return Cn(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 ri,ct,Tn=L(()=>{"use strict";f();Q();pe();As();ie();Vo();tt();Yo();el();ri=null;ct=null});var Ls={};ke(Ls,{collectThemeFiles:()=>ec,extractDesignContext:()=>dp});import{existsSync as js,readdirSync as Ds,readFileSync as rp}from"fs";import{join as Xe}from"path";import{spawn as ap}from"child_process";async function Ql(){return yi||(yi=(await import("@anthropic-ai/sdk")).default),yi}function _n(e){try{return rp(e,"utf-8")}catch{return""}}function ec(e){let t=[],n=0;function s(r,l){if(!l.trim())return!0;let c=`
1538
- ### ${r}
1545
+ [Attached document: ${v.originalName}]
1546
+ ${v.extractedText}`);let w=await c(i,r,a,{systemPrompt:h,messages:[{role:"user",content:x}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return w.type==="text"?w.text:JSON.stringify(w.data)}function qi(){return!!R().planMode}function Xi(){let e=R(),t=e.aiEngine||Ki();return Hn(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 Vi,ht,cn=G(()=>{"use strict";g();X();me();eo();re();_i();lt();Oi();rc();Vi=null;ht=null});var zn={};_e(zn,{collectThemeFiles:()=>Oc,extractDesignContext:()=>Cg});import{existsSync as go,readdirSync as ho,readFileSync as Sg}from"fs";import{join as st}from"path";import{spawn as xg}from"child_process";async function Nc(){return or||(or=(await import("@anthropic-ai/sdk")).default),or}function Vn(e){try{return Sg(e,"utf-8")}catch{return""}}function Oc(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
1547
+ ### ${a}
1539
1548
  \`\`\`
1540
1549
  ${l}
1541
1550
  \`\`\`
1542
- `;return n+c.length>lp?!1:(t.push(c),n+=c.length,!0)}let o=_n(Xe(e,"theme.json"));o&&s("theme.json",o);let i=Xe(e,"css");if(js(i)){for(let r of Ds(i).filter(l=>l.endsWith(".css")))if(!s(`css/${r}`,_n(Xe(i,r))))break}let a=Xe(e,"modules");if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"module.css"));if(c&&!s(`modules/${r}/module.css`,c))break}if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"module.html"));if(c&&!s(`modules/${r}/module.html`,c))break}if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"fields.json"));if(c&&!s(`modules/${r}/fields.json`,c))break}return t.join("")}function cp(){if(!Hs)try{Hs=E(Fn("extraction-prompt.md"))}catch{Hs=""}return Hs}function bi(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let a=ap(e,t,{stdio:["pipe","pipe","pipe"],env:i,shell:!0}),r="",l="";a.stdout.on("data",c=>{r+=c.toString()}),a.stderr.on("data",c=>{l+=c.toString()}),a.on("error",c=>o(new Error(`${e} failed to start: ${c.message}`))),a.on("close",c=>{c===0||r.trim()?s(r.trim()):o(new Error(`${e} exited with code ${c}: ${l.trim()}`))}),a.stdin.write(n),a.stdin.end()})}async function dp(e,t){t?.({status:"Collecting theme files..."});let n=ec(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=cp();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:
1543
- ${n}`;t?.({status:"Analyzing design patterns..."});let i=P(),a=i.aiEngine||"anthropic-api",r="";switch(a){case"anthropic-api":case"api":{let l=be("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Ql();r=(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(()=>(tt(),so)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await Ql();r=(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(h=>h.type==="text"?h.text:"").join("");break}case"openai-api":{let l=be("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()}`);r=(await c.json()).choices?.[0]?.message?.content||"";break}case"gemini-api":{let l=be("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()}`);r=(await d.json()).candidates?.[0]?.content?.parts?.map(m=>m.text).join("")||"";break}case"claude-code":{let l=`${s}
1551
+ `;return n+c.length>vg?!1:(t.push(c),n+=c.length,!0)}let o=Vn(st(e,"theme.json"));o&&s("theme.json",o);let i=st(e,"css");if(go(i)){for(let a of ho(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,Vn(st(i,a))))break}let r=st(e,"modules");if(go(r))for(let a of ho(r).filter(l=>l.endsWith(".module"))){let l=st(r,a),c=Vn(st(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(go(r))for(let a of ho(r).filter(l=>l.endsWith(".module"))){let l=st(r,a),c=Vn(st(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(go(r))for(let a of ho(r).filter(l=>l.endsWith(".module"))){let l=st(r,a),c=Vn(st(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function wg(){if(!yo)try{yo=T(ss("extraction-prompt.md"))}catch{yo=""}return yo}function ir(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=xg(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 Cg(e,t){t?.({status:"Collecting theme files..."});let n=Oc(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=wg();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:
1552
+ ${n}`;t?.({status:"Analyzing design patterns..."});let i=R(),r=i.aiEngine||"anthropic-api",a="";switch(r){case"anthropic-api":case"api":{let l=Te("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Nc();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(()=>(lt(),Uo)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await Nc();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(h=>h.type==="text"?h.text:"").join("");break}case"openai-api":{let l=Te("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=Te("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}
1544
1553
 
1545
1554
  ## User Request
1546
- ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await bi("claude",c,l);break}case"gemini-cli":{let l=`${s}
1555
+ ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),a=await ir("claude",c,l);break}case"gemini-cli":{let l=`${s}
1547
1556
 
1548
1557
  ## User Request
1549
- ${o}`;r=await bi("gemini",[],l);break}case"codex-cli":{let l=`${s}
1558
+ ${o}`;a=await ir("gemini",[],l);break}case"codex-cli":{let l=`${s}
1550
1559
 
1551
1560
  ## User Request
1552
- ${o}`;r=await bi("codex",[],l);break}default:throw new Error(`Unknown AI engine: ${a}. Open Settings to configure one.`)}if(!r.trim())throw new Error("AI returned empty response.");return t?.({status:"Design extraction complete."}),r}var yi,lp,Hs,Bs=L(()=>{"use strict";f();te();Q();yi=null;lp=8e4;Hs=""});var tc={};ke(tc,{extractBrandvoice:()=>up});async function up(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.
1561
+ ${o}`;a=await ir("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 or,vg,yo,Kn=G(()=>{"use strict";g();Q();X();or=null;vg=8e4;yo=""});var rr={};_e(rr,{extractBrandvoice:()=>kg});async function kg(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.
1553
1562
 
1554
1563
  Return a markdown document with these sections (skip any section where the content provides no signal):
1555
1564
 
@@ -1569,7 +1578,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
1569
1578
  ## Dos and Don'ts
1570
1579
  3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
1571
1580
 
1572
- Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Ce(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),a=i.type==="text"?i.text:JSON.stringify(i.data);return!a||a.trim().length<20?null:(A.info("brandvoice-extractor",`Extracted brand voice (${a.length} chars)`),a.trim())}catch(i){let a=i instanceof Error?i.message:String(i);return A.warn("brandvoice-extractor",`Brand voice extraction failed: ${a}`),null}}var nc=L(()=>{"use strict";f();qe();ie()});var Si={};ke(Si,{extractThemeContext:()=>mp});async function mp(e,t,n,s,o){if(!e||e.length<50)return null;let a=`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.
1581
+ Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Re(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 ar=G(()=>{"use strict";g();nt();re()});var bo={};_e(bo,{extractThemeContext:()=>Ag});async function Ag(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.
1573
1582
 
1574
1583
  Return a markdown document with these sections (skip any section where the content provides no information):
1575
1584
 
@@ -1591,39 +1600,39 @@ Specific terms, product names, or branded language used consistently.
1591
1600
  Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
1592
1601
 
1593
1602
  Existing product context (update if the new content adds info, keep what's still accurate):
1594
- ${t}`:""}`;try{let r=await Ce(n,s,o,{systemPrompt:a,messages:[{role:"user",content:e}],maxTokens:1e3}),l=r.type==="text"?r.text:JSON.stringify(r.data);return!l||l.trim().length<20?null:(A.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(r){let l=r instanceof Error?r.message:String(r);return A.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var xi=L(()=>{"use strict";f();qe();ie()});import{writeFileSync as bp,mkdirSync as $c}from"fs";import{join as Gs}from"path";import{randomUUID as Sp}from"crypto";function Tc(e){let t=e.match(xp);if(!t)return null;let n=t[1],s=t[2]?decodeURIComponent(t[2].replace(/-/g," ")):void 0,o;try{let a=new URL(e).searchParams.get("node-id");a&&(o=a.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function Vs(e,t){let n=await fetch(`${vp}${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 Ci(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=Ac.length)throw s;let a=Ac[n];A.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${a}s`),t&&t(`Figma rate limited \u2014 retrying in ${a}s...`),await new Promise(r=>setTimeout(r,a*1e3))}}function Tt(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)Tt(s,t,n+1)}function Ic(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=Ic(n,t);if(s)return s}return null}function wp(e,t){if(t){let s=Ic(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>wi.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>wi.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>wi.has(s.type)):[]}function Ws(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 Cp(e){let t=new Map;for(let n of e)Tt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=Ws(o.color),a=t.get(i),r=s.type==="TEXT",l=r?"text":"fill";a?(a.occurrences++,r&&a.usage!=="text"&&(a.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=Ws(o.color),a=t.get(i);a?a.occurrences++:t.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function kp(e){let t=new Map;for(let n of e)Tt(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,a=o.fontWeight||400,r=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":a>=600&&i<=14&&(d="label");let u=`${c}-${i}-${a}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:a,lineHeight:r,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function Ap(e){let t=[],n=new Set;for(let s of e)Tt(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,a=o.paddingRight||0,r=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||a>0||r>0||l>0){let c=`pad-${i}-${a}-${r}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===r&&l===a&&i===l?i:Math.max(i,a,r,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function $p(e){let t=[],n=new Set;for(let s of e)Tt(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r:a,g:r,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(a*255)},${Math.round(r*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 Tp(e,t){let n=[];return Tt(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,a="body";o>=32?a="headline":o>=20?a="subheadline":o<=12?a="caption":i>=600&&o<=16&&(a="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(a="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:a,sectionName:t})}),n}function Ip(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 Ep(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Ws(t.color)}if(e.backgroundColor)return Ws(e.backgroundColor)}function _p(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:Tp(t,t.name),children:(t.children||[]).slice(0,20).map(Ip),backgroundColor:Ep(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 Np(e){let t=[];for(let n of e)Tt(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 Ec(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());bp(t,s)}async function Pp(e,t,n,s,o){if(t.length===0)return new Map;$c(s,{recursive:!0});let a=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let r=await Ci(()=>Vs(`/v1/images/${e}?ids=${a}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(r.images)){if(!d)continue;let u=c.replace(/:/g,"-"),m=Gs(s,`frame-${u}.png`);try{await Ec(d,m),l.set(c,m),A.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){A.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function Mp(e,t,n,s,o){if(t.length===0)return[];$c(s,{recursive:!0});let i=50,a=[];for(let r=0;r<t.length;r+=i){let l=t.slice(r,r+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${r+1}-${Math.min(r+i,t.length)} of ${t.length})...`);let d=await Ci(()=>Vs(`/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()}-${Sp().slice(0,6)}.png`,h=Gs(s,y);try{await Ec(m,h),a.push({name:u.name,localPath:h,nodeId:u.nodeId,format:"png"}),A.info("figma",`Downloaded asset: ${y}`)}catch(b){A.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return a}async function _c(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`,a=await Ci(()=>Vs(i,n),o);A.info("figma",`Fetched file: ${a.name}`);let r=wp(a.document,t);if(r.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");A.info("figma",`Found ${r.length} top-level frames`),o&&o(`Found ${r.length} sections. Extracting design tokens...`);let l={colors:Cp(r),typography:kp(r),spacing:Ap(r),effects:$p(r)};A.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=_p(r),d=Gs(s,".vibespot","figma-frames"),u=await Pp(e,r,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=Np(r),y=Gs(s,"assets"),h=await Mp(e,g,n,y,o);return A.info("figma",`Extraction complete: ${m.length} sections, ${h.length} assets`),{fileName:a.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:h}}function Nc(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 Pc(e){return await Vs("/v1/me",e)}var xp,vp,Ac,wi,Mc=L(()=>{"use strict";f();ie();xp=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;vp="https://api.figma.com",Ac=[10,20,40,60,120];wi=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var Dc={};ke(Dc,{getCachedExtraction:()=>jc,handleFigmaExtractRoute:()=>Ai,handleFigmaGenerateRoute:()=>$i,handleFigmaTestTokenRoute:()=>ki});import{randomUUID as Oc}from"crypto";import{existsSync as Rc,mkdirSync as Fc,writeFileSync as Op,copyFileSync as Rp}from"fs";import{join as Ks,basename as Fp}from"path";function Jc(){let e=Date.now();for(let[t,n]of Nn)n.expires<e&&Nn.delete(t)}function jc(e){Jc();let t=Nn.get(e);return t?(Nn.delete(e),t.extraction):null}function ki(e,t){Ye(e,t,async n=>{let s=n.token||P().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Pc(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);A.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function Ai(e,t){Ye(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||P().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=Tc(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let r=v()?.themePath||`/tmp/vibespot-figma-${Oc().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)}
1603
+ ${t}`:""}`;try{let a=await Re(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 So=G(()=>{"use strict";g();nt();re()});import{writeFileSync as Qg,mkdirSync as Gd}from"fs";import{join as ko}from"path";import{randomUUID as eh}from"crypto";function Wd(e){let t=e.match(th);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 To(e,t){let n=await fetch(`${nh}${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>=Ud.length)throw s;let r=Ud[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 Ht(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)Ht(s,t,n+1)}function Vd(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=Vd(n,t);if(s)return s}return null}function sh(e,t){if(t){let s=Vd(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>dr.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>dr.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>dr.has(s.type)):[]}function Ao(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 oh(e){let t=new Map;for(let n of e)Ht(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=Ao(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=Ao(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 ih(e){let t=new Map;for(let n of e)Ht(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 rh(e){let t=[],n=new Set;for(let s of e)Ht(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 ah(e){let t=[],n=new Set;for(let s of e)Ht(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 lh(e,t){let n=[];return Ht(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 ch(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 dh(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Ao(t.color)}if(e.backgroundColor)return Ao(e.backgroundColor)}function uh(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:lh(t,t.name),children:(t.children||[]).slice(0,20).map(ch),backgroundColor:dh(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 mh(e){let t=[];for(let n of e)Ht(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 zd(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());Qg(t,s)}async function ph(e,t,n,s,o){if(t.length===0)return new Map;Gd(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await ur(()=>To(`/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=ko(s,`frame-${u}.png`);try{await zd(d,m),l.set(c,m),E.info("figma",`Downloaded frame screenshot: ${m}`)}catch(f){E.warn("figma",`Failed to download frame ${c}: ${f}`)}}return l}async function fh(e,t,n,s,o){if(t.length===0)return[];Gd(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(()=>To(`/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()}-${eh().slice(0,6)}.png`,h=ko(s,y);try{await zd(m,h),r.push({name:u.name,localPath:h,nodeId:u.nodeId,format:"png"}),E.info("figma",`Downloaded asset: ${y}`)}catch(S){E.warn("figma",`Failed to download image ${u.name}: ${S}`)}}}return r}async function Kd(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(()=>To(i,n),o);E.info("figma",`Fetched file: ${r.name}`);let a=sh(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:oh(a),typography:ih(a),spacing:rh(a),effects:ah(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=uh(a),d=ko(s,".vibespot","figma-frames"),u=await ph(e,a,n,d,o),m=c.map(S=>({...S,frameImagePath:u.get(S.nodeId)||""}));o&&o("Extracting image assets...");let f=mh(a),y=ko(s,"assets"),h=await fh(e,f,n,y,o);return E.info("figma",`Extraction complete: ${m.length} sections, ${h.length} assets`),{fileName:r.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:h}}function Yd(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 qd(e){return await To("/v1/me",e)}var th,nh,Ud,dr,Xd=G(()=>{"use strict";g();re();th=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;nh="https://api.figma.com",Ud=[10,20,40,60,120];dr=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var su={};_e(su,{getCachedExtraction:()=>nu,handleFigmaExtractRoute:()=>pr,handleFigmaGenerateRoute:()=>fr,handleFigmaTestTokenRoute:()=>mr});import{randomUUID as Zd}from"crypto";import{existsSync as Qd,mkdirSync as eu,writeFileSync as gh,copyFileSync as hh}from"fs";import{join as $o,basename as yh}from"path";function tu(){let e=Date.now();for(let[t,n]of qn)n.expires<e&&qn.delete(t)}function nu(e){tu();let t=qn.get(e);return t?(qn.delete(e),t.extraction):null}function mr(e,t){Oe(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 qd(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 pr(e,t){Oe(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=Wd(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-${Zd().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)}
1595
1604
 
1596
- `)};try{let c=await _c(i.fileKey,i.nodeId,o,r,m=>l({type:"progress",message:m})),d=Oc();Jc(),Nn.set(d,{extraction:c,expires:Date.now()+Jp});let u=Nc(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);A.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 jp(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((r,l)=>l.count-r.count),i=o[0],a=o[1];i&&s.push(`- **Primary:** \`${i.hex}\` (${i.name||"dominant color"})`),a&&s.push(`- **Secondary:** \`${a.hex}\` (${a.name||"accent color"})`),s.push(""),s.push("### Full palette","");for(let r of o.slice(0,15)){let l=r.name?`${r.name}`:`${r.count}\xD7 used`;s.push(`- \`${r.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(a=>a.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let i=new Set;for(let a of t.typography){let r=`${a.role}-${a.fontSize}-${a.fontWeight}`;i.has(r)||(i.add(r),s.push(`| ${a.role} | ${a.fontFamily} | ${a.fontSize}px | ${a.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(i=>i.value))].sort((i,a)=>i-a);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(`
1597
- `)}function $i(e,t){Ye(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 a=jc(s);if(!a){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let r=v();if(!r){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)}
1605
+ `)};try{let c=await Kd(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=Zd();tu(),qn.set(d,{extraction:c,expires:Date.now()+bh});let u=Yd(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 Sh(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(`
1606
+ `)}function fr(e,t){Oe(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=nu(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)}
1598
1607
 
1599
- `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=jp(a),d=Ks(r.themePath,".vibespot");if(Rc(d)||Fc(d,{recursive:!0}),Op(Ks(d,"styleguide.md"),c),r.brandAssets||(r.brandAssets={}),r.brandAssets.styleguide=c,j(),l({type:"progress",message:"Styleguide saved."}),r.templates.length===0)bs("landing_page","Landing Page");else{r.modules=[],r.moduleOrder=[],r.sharedCss="",r.sharedJs="";let h=r.templates.find(b=>b.id===r.activeTemplateId);h&&(h.modules=[],h.moduleOrder=[],h.sharedCss="",h.sharedJs="")}if(j(),i&&a.assets.length>0){let h=Ks(r.themePath,"assets");Fc(h,{recursive:!0});let b=0;for(let x of a.assets)if(Rc(x.localPath)){let w=Ks(h,Fp(x.localPath));try{Rp(x.localPath,w),x.localPath=w,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 $n(a,o,h=>{if(h.type==="agent_step")u.push({step:h.step,label:h.label}),l({type:"progress",message:`${h.label}...`});else if(h.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(h.decision)),l({type:"progress",message:` ${h.decision}`})}else h.type==="design_system_ready"?oe({sharedCss:h.sharedCss,sharedJs:h.sharedJs}):h.type==="blueprint_ready"?(oe({sharedCss:h.sharedCss,sharedJs:h.sharedJs}),Ke(h.moduleOrder),l({type:"progress",message:`Planned ${h.moduleOrder.length} modules`})):h.type==="module_progress"&&(h.status==="generating"?l({type:"progress",message:`Generating module: ${h.module}`}):h.status==="complete"&&h.moduleFiles?(oe({modules:[{moduleName:h.module,fieldsJson:h.moduleFiles.fieldsJson,metaJson:h.moduleFiles.metaJson,moduleHtml:h.moduleFiles.moduleHtml,moduleCss:h.moduleFiles.moduleCss,moduleJs:h.moduleFiles.moduleJs}]}),m.push({name:h.module,status:"complete"}),l({type:"progress",message:`Module complete: ${h.module}`})):h.status==="failed"&&(m.push({name:h.module,status:"failed"}),l({type:"progress",message:`Module failed: ${h.module}`})))},{useAssets:i});At(g,{steps:u,modules:m,stats:g.stats}),_e(),St(r.themePath,`Figma import: ${a.fileName}`);let y=X().map(h=>h.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);A.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Nn,Jp,Ti=L(()=>{"use strict";f();Fe();Q();ie();Mc();pe();pn();Po();jt();Tn();Dt();Nn=new Map,Jp=1800*1e3});f();f();import{Command as Yp}from"commander";f();f();f();import Et from"chalk";var De={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Ni=!!process.env.NO_COLOR;function Qe(e){return Ni?Et:Et.hex(e)}var N={accent:Qe(De.accent),accentBright:Qe(De.accentBright),success:Qe(De.success),info:Qe(De.info),warn:Qe(De.warn),error:Qe(De.error),muted:Qe(De.muted),vibes:Qe(De.vibes),heading:Ni?Et.bold:Et.bold.hex(De.accent),command:Qe(De.accentBright),dim:Et.dim,bold:Et.bold};te();function He(){let e=N.vibes,t=N.accent,n=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")} ${N.dim(`v${Nt()}`)}`),console.log()}f();f();ht();Q();tt();import{join as Bn}from"path";import{homedir as Un}from"os";import{readFileSync as Hi,existsSync as Gn,readdirSync as rd}from"fs";var yt=process.platform==="win32"?"where":"which";function en(){let e=J("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:J(`${yt} node`).stdout}}function tn(){let e=J("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:J(`${yt} git`).stdout}}function Be(){let e=J("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:J(`${yt} hs`).stdout}}function nn(){let e=J("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Bn(Un(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Gn(t)){let o=rd(t);(o.some(a=>a.includes("credentials")||a.includes("auth")||a.includes("token")||a===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:J(`${yt} claude`).stdout,authenticated:n,authDetail:s}}function sn(e){try{let t=Bn(Un(),".hscli","config.yml");if(!Gn(t))return"na1";let n=Hi(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 a=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!a)return"na1";if(a[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function Ue(){let e=J("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(`
1600
- `);for(let a of i){let r=a.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(r&&!/Account ID/i.test(a)&&!/^-+$/.test(a.trim())&&!/^Name\s/i.test(a.trim())){let l=r[1].trim(),c=r[2].trim(),d=r[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=J("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Bn(Un(),".config","gcloud","application_default_credentials.json"),n=Gn(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:J(`${yt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function rn(){let e=J("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=Bn(Un(),".codex","auth.json");Gn(i)&&(n=Hi(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:J(`${yt} codex`).stdout,authenticated:s,authDetail:o}}function io(){let e=J("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
1601
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:J(`${yt} gh`).stdout}}function ro(){let e=J("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 Li(){return!!process.env.ANTHROPIC_API_KEY}function Wn(e){return parseInt(e.split(".")[0],10)>=18}function Bi(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function ad(){let e=P(),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=ut();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}var oo={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function Vn(){let e=P(),t=en(),n=tn(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let x=Be(),w=x.found?Ue():{authenticated:!1,portalName:"",portalId:"",accounts:[]},S=w.portalId?sn(w.portalId):"na1";o={...x,...w,dataCenter:S,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...ad()};let i=io(),a=i.found?ro():{authenticated:!1,username:""},r={authenticated:Le(),expiresAt:Qt()?.expiresAt},l=e.enabledCLITools||[],c=Xt("claude-code")?nn():{...oo,name:"Claude Code"},d=Xt("gemini-cli")?on():{...oo,name:"Gemini CLI"},u=Xt("codex-cli")?rn():{...oo,name:"OpenAI Codex CLI"};function m(x,...w){if(x)return{configured:!0,masked:jn(x),source:"config"};for(let S of w)if(process.env[S])return{configured:!0,masked:jn(process.env[S]),source:"env"};return{configured:!1,masked:"",source:null}}let g=m(e.anthropicApiKey,"ANTHROPIC_API_KEY"),y=m(e.openaiApiKey,"OPENAI_API_KEY"),h=m(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),b=[];return c.found&&c.authenticated&&b.push("claude-code"),r.authenticated&&b.push("claude-oauth"),g.configured&&b.push("anthropic-api"),y.configured&&b.push("openai-api"),d.found&&d.authenticated&&b.push("gemini-cli"),h.configured&&b.push("gemini-api"),u.found&&u.authenticated&&b.push("codex-cli"),{tools:{node:t,git:n,hubspot:o,github:{...i,...a},claudeCode:c,claudeOAuth:r,geminiCli:d,codexCli:u},apiKeys:{anthropic:g,openai:y,gemini:h},activeEngine:e.aiEngine||null,availableEngines:b,enabledCLITools:l}}tt();ht();Q();bt();f();import*as Y from"@clack/prompts";function lo(e){Y.isCancel(e)&&(Y.cancel(N.muted("Operation cancelled.")),process.exit(0))}async function ge(e){Y.intro(N.heading(e))}async function fe(e){Y.outro(N.success(e))}async function Ge(e,t){Y.note(e,t?N.heading(t):void 0)}async function Ne(e){let t=await Y.text({message:N.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return lo(t),t}async function le(e){let t=await Y.confirm({message:N.accent(e.message),initialValue:e.initialValue??!0});return lo(t),t}async function Rt(e){let t=await Y.select({message:N.accent(e.message),options:e.options});return lo(t),t}async function he(){let e=Y.spinner();return{start:t=>e.start(N.muted(t)),stop:t=>e.stop(N.success(t)),message:t=>e.message(N.muted(t))}}function ne(e){Y.log.info(e)}function U(e){Y.log.success(N.success(e))}function q(e){Y.log.warn(N.warn(e))}function V(e){Y.log.error(N.error(e))}async function qn(){await ge("Checking your environment");let e=en();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Wn(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),U(`Node.js v${e.version}`);let t=tn();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),U(`Git ${t.version}`);let n=P(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Se(),x=ut();if(b)o=x?.portalId||"",i=x?.portalName||"",U(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{q("No HubSpot account connected"),await Ge(`You need a Personal Access Key to deploy themes.
1608
+ `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=Sh(r),d=$o(a.themePath,".vibespot");if(Qd(d)||eu(d,{recursive:!0}),gh($o(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,J(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)Hs("landing_page","Landing Page");else{a.modules=[],a.moduleOrder=[],a.sharedCss="",a.sharedJs="";let h=a.templates.find(S=>S.id===a.activeTemplateId);h&&(h.modules=[],h.moduleOrder=[],h.sharedCss="",h.sharedJs="")}if(J(),i&&r.assets.length>0){let h=$o(a.themePath,"assets");eu(h,{recursive:!0});let S=0;for(let x of r.assets)if(Qd(x.localPath)){let w=$o(h,yh(x.localPath));try{hh(x.localPath,w),x.localPath=w,S++}catch{}}S>0&&l({type:"progress",message:`Copied ${S} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],f=await Gn(r,o,h=>{if(h.type==="agent_step")u.push({step:h.step,label:h.label}),l({type:"progress",message:`${h.label}...`});else if(h.type==="agent_decision"){let S=u[u.length-1];S&&(S.decisions||(S.decisions=[]),S.decisions.push(h.decision)),l({type:"progress",message:` ${h.decision}`})}else h.type==="design_system_ready"?Ie({sharedCss:h.sharedCss,sharedJs:h.sharedJs}):h.type==="blueprint_ready"?(Ie({sharedCss:h.sharedCss,sharedJs:h.sharedJs}),wt(h.moduleOrder),l({type:"progress",message:`Planned ${h.moduleOrder.length} modules`})):h.type==="module_progress"&&(h.status==="generating"?l({type:"progress",message:`Generating module: ${h.module}`}):h.status==="complete"&&h.moduleFiles?(Ie({modules:[{moduleName:h.module,fieldsJson:h.moduleFiles.fieldsJson,metaJson:h.moduleFiles.metaJson,moduleHtml:h.moduleFiles.moduleHtml,moduleCss:h.moduleFiles.moduleCss,moduleJs:h.moduleFiles.moduleJs}]}),m.push({name:h.module,status:"complete"}),l({type:"progress",message:`Module complete: ${h.module}`})):h.status==="failed"&&(m.push({name:h.module,status:"failed"}),l({type:"progress",message:`Module failed: ${h.module}`})))},{useAssets:i});Dt(f,{steps:u,modules:m,stats:f.stats}),we(),_t(a.themePath,`Figma import: ${r.fileName}`);let y=ce().map(h=>h.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);E.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var qn,bh,gr=G(()=>{"use strict";g();Fe();X();re();Xd();me();Mn();Si();Zt();cn();Nt();qn=new Map,bh=1800*1e3});g();g();import{Command as Kh}from"commander";g();g();g();import Ut from"chalk";var Ke={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Er=!!process.env.NO_COLOR;function rt(e){return Er?Ut:Ut.hex(e)}var A={accent:rt(Ke.accent),accentBright:rt(Ke.accentBright),success:rt(Ke.success),info:rt(Ke.info),warn:rt(Ke.warn),error:rt(Ke.error),muted:rt(Ke.muted),vibes:rt(Ke.vibes),heading:Er?Ut.bold:Ut.bold.hex(Ke.accent),command:rt(Ke.accentBright),dim:Ut.dim,bold:Ut.bold};Q();function pe(){let e=A.vibes,t=A.accent,n=A.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")} ${A.dim(`v${Vt()}`)}`),console.log()}g();g();Et();X();lt();import{join as cs}from"path";import{homedir as ds}from"os";import{readFileSync as Jr,existsSync as us,readdirSync as Hu}from"fs";var Mt=process.platform==="win32"?"where":"which";function bn(){let e=D("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:D(`${Mt} node`).stdout}}function Sn(){let e=D("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:D(`${Mt} git`).stdout}}function qe(){let e=D("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:D(`${Mt} hs`).stdout}}function xn(){let e=D("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=cs(ds(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(us(t)){let o=Hu(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:D(`${Mt} claude`).stdout,authenticated:n,authDetail:s}}function vn(e){try{let t=cs(ds(),".hscli","config.yml");if(!us(t))return"na1";let n=Jr(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 Xe(){let e=D("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(`
1609
+ `);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 wn(){let e=D("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=cs(ds(),".config","gcloud","application_default_credentials.json"),n=us(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:D(`${Mt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function Cn(){let e=D("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=cs(ds(),".codex","auth.json");us(i)&&(n=Jr(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:D(`${Mt} codex`).stdout,authenticated:s,authDetail:o}}function Wo(){let e=D("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
1610
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:D(`${Mt} gh`).stdout}}function Vo(){let e=D("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 Lr(){return!!process.env.ANTHROPIC_API_KEY}function ms(e){return parseInt(e.split(".")[0],10)>=18}function Hr(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function Bu(){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=xt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}var Go={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function ps(){let e=R(),t=bn(),n=Sn(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let x=qe(),w=x.found?Xe():{authenticated:!1,portalName:"",portalId:"",accounts:[]},v=w.portalId?vn(w.portalId):"na1";o={...x,...w,dataCenter:v,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...Bu()};let i=Wo(),r=i.found?Vo():{authenticated:!1,username:""},a={authenticated:Ye(),expiresAt:yn()?.expiresAt},l=e.enabledCLITools||[],c=gn("claude-code")?xn():{...Go,name:"Claude Code"},d=gn("gemini-cli")?wn():{...Go,name:"Gemini CLI"},u=gn("codex-cli")?Cn():{...Go,name:"OpenAI Codex CLI"};function m(x,...w){if(x)return{configured:!0,masked:is(x),source:"config"};for(let v of w)if(process.env[v])return{configured:!0,masked:is(process.env[v]),source:"env"};return{configured:!1,masked:"",source:null}}let f=m(e.anthropicApiKey,"ANTHROPIC_API_KEY"),y=m(e.openaiApiKey,"OPENAI_API_KEY"),h=m(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),S=[];return c.found&&c.authenticated&&S.push("claude-code"),a.authenticated&&S.push("claude-oauth"),f.configured&&S.push("anthropic-api"),y.configured&&S.push("openai-api"),d.found&&d.authenticated&&S.push("gemini-cli"),h.configured&&S.push("gemini-api"),u.found&&u.authenticated&&S.push("codex-cli"),{tools:{node:t,git:n,hubspot:o,github:{...i,...r},claudeCode:c,claudeOAuth:a,geminiCli:d,codexCli:u},apiKeys:{anthropic:f,openai:y,gemini:h},activeEngine:e.aiEngine||null,availableEngines:S,enabledCLITools:l}}lt();Et();X();Rt();g();import*as ee from"@clack/prompts";function Ko(e){ee.isCancel(e)&&(ee.cancel(A.muted("Operation cancelled.")),process.exit(0))}async function se(e){ee.intro(A.heading(e))}async function oe(e){ee.outro(A.success(e))}async function Ze(e,t){ee.note(e,t?A.heading(t):void 0)}async function le(e){let t=await ee.text({message:A.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return Ko(t),t}async function fe(e){let t=await ee.confirm({message:A.accent(e.message),initialValue:e.initialValue??!0});return Ko(t),t}async function dt(e){let t=await ee.select({message:A.accent(e.message),options:e.options});return Ko(t),t}async function Ce(){let e=ee.spinner();return{start:t=>e.start(A.muted(t)),stop:t=>e.stop(A.success(t)),message:t=>e.message(A.muted(t))}}function P(e){ee.log.info(e)}function H(e){ee.log.success(A.success(e))}function Z(e){ee.log.warn(A.warn(e))}function z(e){ee.log.error(A.error(e))}async function ys(){await se("Checking your environment");let e=bn();e.found||(z("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),ms(e.version)||(z(`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=Sn();t.found||(z("Git not found. Install it from https://git-scm.com"),process.exit(1)),H(`Git ${t.version}`);let n=R(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let S=$e(),x=xt();if(S)o=x?.portalId||"",i=x?.portalName||"",H(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{Z("No HubSpot account connected"),await Ze(`You need a Personal Access Key to deploy themes.
1602
1611
  Create one at: https://app.hubspot.com/l/personal-access-key
1603
- Make sure the Content scope is enabled.`,"HubSpot connection required");let w=await Ne({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:M=>M.trim()?void 0:"Key is required"}),S=await he();S.start("Validating key...");try{let M=await zn(w);qt(w,M.portalId,M.portalName,M.dataCenter),b=w,o=M.portalId,i=M.portalName,S.stop(`Connected to ${M.portalName} (${M.portalId})`)}catch(M){S.stop("Validation failed"),V(`Invalid key: ${M instanceof Error?M.message:String(M)}`),process.exit(1)}}}else{let b=Be();if(b.found)U(`HubSpot CLI v${b.version}`);else{q("HubSpot CLI not found"),await le({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let S=await he();S.start("Installing HubSpot CLI..."),J("npm install -g @hubspot/cli").success||(S.stop("Failed"),V("Try: npm install -g @hubspot/cli"),process.exit(1)),b=Be(),S.stop(`HubSpot CLI v${b.version} installed`)}let x=Ue();if(x.authenticated)U(`HubSpot portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`);else{q("HubSpot not authenticated"),await le({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let S=await he();S.start("Waiting for HubSpot authentication..."),Ri("hs init")||(S.stop("Authentication failed"),process.exit(1)),x=Ue(),S.stop(`Connected to portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`)}o=x.portalId,i=x.portalName}let a=nn(),r=on(),l=rn(),c=Li(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"},u=Le(),m,g=n.aiEngine,y=[];if(a.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"}),r.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,x)=>b.value===g?-1:x.value===g?1:0),y.length===1)m=y[0].value,U(`AI engine: ${d[m]} (auto-detected)`);else if(y.length>1)m=await Rt({message:"Choose your AI engine:",options:y});else if(await Ge(`You need an AI coding assistant to power the conversion.
1612
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let w=await le({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:N=>N.trim()?void 0:"Key is required"}),v=await Ce();v.start("Validating key...");try{let N=await gs(w);fn(w,N.portalId,N.portalName,N.dataCenter),S=w,o=N.portalId,i=N.portalName,v.stop(`Connected to ${N.portalName} (${N.portalId})`)}catch(N){v.stop("Validation failed"),z(`Invalid key: ${N instanceof Error?N.message:String(N)}`),process.exit(1)}}}else{let S=qe();if(S.found)H(`HubSpot CLI v${S.version}`);else{Z("HubSpot CLI not found"),await fe({message:"Install HubSpot CLI globally?"})||(z("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let v=await Ce();v.start("Installing HubSpot CLI..."),D("npm install -g @hubspot/cli").success||(v.stop("Failed"),z("Try: npm install -g @hubspot/cli"),process.exit(1)),S=qe(),v.stop(`HubSpot CLI v${S.version} installed`)}let x=Xe();if(x.authenticated)H(`HubSpot portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`);else{Z("HubSpot not authenticated"),await fe({message:"Run `hs init` now?"})||(z("Run `hs init` manually."),process.exit(1));let v=await Ce();v.start("Waiting for HubSpot authentication..."),Nr("hs init")||(v.stop("Authentication failed"),process.exit(1)),x=Xe(),v.stop(`Connected to portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`)}o=x.portalId,i=x.portalName}let r=xn(),a=wn(),l=Cn(),c=Lr(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"},u=Ye(),m,f=n.aiEngine,y=[];if(r.found&&y.push({value:"claude-code",label:"Claude Code",hint:f==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&y.push({value:"claude-oauth",label:"Claude (OAuth)",hint:f==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&y.push({value:"gemini-cli",label:"Gemini CLI",hint:f==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&y.push({value:"codex-cli",label:"OpenAI Codex",hint:f==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&y.push({value:"api",label:"Anthropic API",hint:f==="api"?"last used":"uses your API key"}),f&&y.sort((S,x)=>S.value===f?-1:x.value===f?1:0),y.length===1)m=y[0].value,H(`AI engine: ${d[m]} (auto-detected)`);else if(y.length>1)m=await dt({message:"Choose your AI engine:",options:y});else if(await Ze(`You need an AI coding assistant to power the conversion.
1604
1613
 
1605
- ${N.bold("Option 1:")} Install Claude Code ${N.muted("(recommended)")}
1614
+ ${A.bold("Option 1:")} Install Claude Code ${A.muted("(recommended)")}
1606
1615
  https://claude.ai/code
1607
1616
 
1608
- ${N.bold("Option 2:")} Install Gemini CLI
1617
+ ${A.bold("Option 2:")} Install Gemini CLI
1609
1618
  https://github.com/google-gemini/gemini-cli
1610
1619
 
1611
- ${N.bold("Option 3:")} Install OpenAI Codex
1620
+ ${A.bold("Option 3:")} Install OpenAI Codex
1612
1621
  https://github.com/openai/codex
1613
1622
 
1614
- ${N.bold("Option 4:")} Set an Anthropic API key
1623
+ ${A.bold("Option 4:")} Set an Anthropic API key
1615
1624
  export ANTHROPIC_API_KEY=sk-ant-...
1616
- (get one at https://console.anthropic.com)`,"AI engine required"),m=await Rt({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 Ne({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:x=>x.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,W({anthropicApiKey:b})}let h;return m==="claude-code"&&(h=await Rt({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"}]})),W({aiEngine:m}),await fe("Environment ready!"),{aiEngine:m,model:h,portalId:o,portalName:i}}f();ht();te();import{readdirSync as co,statSync as fd}from"fs";import{join as se,basename as uo,extname as hd}from"path";function zi(e){let t=[],n=[se(e,"src/components/landing"),se(e,"src/components/sections"),se(e,"src/components"),se(e,"src/pages"),se(e,"app/components"),se(e,"components")];for(let s of n)if(k(s))try{let o=co(s);for(let i of o){let a=se(s,i);if(!fd(a).isFile())continue;let l=hd(i);if(![".tsx",".jsx"].includes(l))continue;let c=uo(i,l);if(c.startsWith("ui")||c==="index")continue;let d=E(a),u=yd(c,d);t.push({name:c,path:a,description:u})}}catch{}return t}function yd(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 Yi(e){let t=[se(e,"src/index.css"),se(e,"src/globals.css"),se(e,"src/app/globals.css"),se(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!k(o))continue;let i=E(o),a=i.match(/--[\w-]+:/g);a&&(n+=a.length);let r=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(r)for(let c of r){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 qi(e){let t=[],n=se(e,"src/hooks");if(k(n))try{let o=co(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=se(e,"src/components/landing");if(k(s))try{let o=co(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let a=E(se(s,i));/carousel|embla|swiper/i.test(a)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(a)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(a)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(a)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function Xi(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let l=uo(e.replace(/\.git$/,""))||"react-source";if(t=se(process.cwd(),"workspace",l),!k(t)){let c=J(`git clone --depth 1 "${e}" "${t}"`);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!k(t))throw new Error(`Directory not found: ${t}`);let s=zi(t),o=k(se(t,"tailwind.config.ts"))||k(se(t,"tailwind.config.js")),{varCount:i,fonts:a}=Yi(t),r=qi(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:a,interactions:r}}async function Xn(){await ge("Source Project");let e=await Ne({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@")){n=!0;let y=uo(e.replace(/\.git$/,""))||"react-source";if(t=se(process.cwd(),"workspace",y),k(t))U(`Using existing clone: ${N.dim(t)}`);else{let h=await he();h.start("Cloning repository..."),J(`git clone --depth 1 "${e}" "${t}"`).success||(h.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),h.stop(`Cloned to ${N.dim(t)}`)}}else t=e,k(t)||(V(`Directory not found: ${t}`),process.exit(1)),U(`Using local source: ${N.dim(t)}`);let s=await he();s.start("Analyzing project structure...");let o=zi(t),i=k(se(t,"tailwind.config.ts"))||k(se(t,"tailwind.config.js")),{varCount:a,fonts:r}=Yi(t),l=qi(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(q("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((y,h)=>` ${N.dim(`${h+1}.`)} ${N.bold(y.name)} ${N.muted(`\u2014 ${y.description}`)}`).join(`
1617
- `),d=i?`Tailwind + custom CSS (${a} variables)`:`Custom CSS (${a} variables)`,u=r.length>0?r.join(", "):"System fonts",m=l.join(", ");return await Ge(`${c}
1625
+ (get one at https://console.anthropic.com)`,"AI engine required"),m=await dt({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 S=await le({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:x=>x.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=S,V({anthropicApiKey:S})}let h;return m==="claude-code"&&(h=await dt({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"}]})),V({aiEngine:m}),await oe("Environment ready!"),{aiEngine:m,model:h,portalId:o,portalName:i}}g();Et();Q();import{readdirSync as Yo,statSync as qu}from"fs";import{join as ie,basename as qo,extname as Xu}from"path";function zr(e){let t=[],n=[ie(e,"src/components/landing"),ie(e,"src/components/sections"),ie(e,"src/components"),ie(e,"src/pages"),ie(e,"app/components"),ie(e,"components")];for(let s of n)if(b(s))try{let o=Yo(s);for(let i of o){let r=ie(s,i);if(!qu(r).isFile())continue;let l=Xu(i);if(![".tsx",".jsx"].includes(l))continue;let c=qo(i,l);if(c.startsWith("ui")||c==="index")continue;let d=T(r),u=Zu(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function Zu(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 Kr(e){let t=[ie(e,"src/index.css"),ie(e,"src/globals.css"),ie(e,"src/app/globals.css"),ie(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!b(o))continue;let i=T(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 Yr(e){let t=[],n=ie(e,"src/hooks");if(b(n))try{let o=Yo(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=ie(e,"src/components/landing");if(b(s))try{let o=Yo(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=T(ie(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 qr(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let l=qo(e.replace(/\.git$/,""))||"react-source";if(t=ie(process.cwd(),"workspace",l),!b(t)){let c=D(`git clone --depth 1 "${e}" "${t}"`);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!b(t))throw new Error(`Directory not found: ${t}`);let s=zr(t),o=b(ie(t,"tailwind.config.ts"))||b(ie(t,"tailwind.config.js")),{varCount:i,fonts:r}=Kr(t),a=Yr(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function bs(){await se("Source Project");let e=await le({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@")){n=!0;let y=qo(e.replace(/\.git$/,""))||"react-source";if(t=ie(process.cwd(),"workspace",y),b(t))H(`Using existing clone: ${A.dim(t)}`);else{let h=await Ce();h.start("Cloning repository..."),D(`git clone --depth 1 "${e}" "${t}"`).success||(h.stop("Clone failed"),z(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),h.stop(`Cloned to ${A.dim(t)}`)}}else t=e,b(t)||(z(`Directory not found: ${t}`),process.exit(1)),H(`Using local source: ${A.dim(t)}`);let s=await Ce();s.start("Analyzing project structure...");let o=zr(t),i=b(ie(t,"tailwind.config.ts"))||b(ie(t,"tailwind.config.js")),{varCount:r,fonts:a}=Kr(t),l=Yr(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(Z("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((y,h)=>` ${A.dim(`${h+1}.`)} ${A.bold(y.name)} ${A.muted(`\u2014 ${y.description}`)}`).join(`
1626
+ `),d=i?`Tailwind + custom CSS (${r} variables)`:`Custom CSS (${r} variables)`,u=a.length>0?a.join(", "):"System fonts",m=l.join(", ");return await Ze(`${c}
1618
1627
 
1619
1628
  CSS: ${d}
1620
1629
  JS: ${m}
1621
- Font: ${u}`,`${o.length} components detected`),await le({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:a,fonts:r,interactions:l}}f();ht();te();import{join as un}from"path";Q();Qn();es();async function ts(){await ge("HubSpot Theme Setup");let e=await Rt({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=un(process.cwd(),"workspace");if(Te(s),e==="fetch"){t=await Ne({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=un(s,t);let l=await he();l.start("Fetching theme from HubSpot...");let c=P(),d=Se();if(c.hubspotUploadMode==="cli"||!d)J(`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 dn(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: ${N.dim(n)}`)}else{t=await Ne({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=un(s,t);let l=await he();l.start("Creating theme...");try{cn(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: ${N.dim(n)}`)}await ge("Checking theme compatibility");let o=un(n,"templates/layouts/base.html");k(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),U("base.html found");let i=E(o),a=!1;if(i.includes("template_css"))U("template_css support");else{q("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
1630
+ Font: ${u}`,`${o.length} components detected`),await fe({message:"Does this look right?"})||(z("Please adjust your source directory and try again."),process.exit(0)),await oe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}g();Et();Q();import{join as In}from"path";X();xs();vs();async function ws(){await se("HubSpot Theme Setup");let e=await dt({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=In(process.cwd(),"workspace");if(Ae(s),e==="fetch"){t=await le({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=In(s,t);let l=await Ce();l.start("Fetching theme from HubSpot...");let c=R(),d=$e();if(c.hubspotUploadMode==="cli"||!d)D(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),z(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await $n(d,t,n)}catch(u){l.stop("Fetch failed"),z(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${A.dim(n)}`)}else{t=await le({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=In(s,t);let l=await Ce();l.start("Creating theme...");try{Tn(n,t)}catch(c){l.stop("Creation failed"),z(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${A.dim(n)}`)}await se("Checking theme compatibility");let o=In(n,"templates/layouts/base.html");b(o)||(z(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),H("base.html found");let i=T(o),r=!1;if(i.includes("template_css"))H("template_css support");else{Z("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
1622
1631
  `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
1623
1632
  `,l);i=i.slice(0,c)+`
1624
1633
  {% if template_css %}
1625
1634
  {{ require_css(get_asset_url(template_css)) }}
1626
- {% endif %}`+i.slice(c),a=!0}}if(i.includes("template_js"))U("template_js support");else{q("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
1635
+ {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))H("template_js support");else{Z("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
1627
1636
  `,l),d=i.indexOf(`
1628
1637
  `,c+1),u=`
1629
1638
  {% if template_js %}
@@ -1631,17 +1640,17 @@ ${N.bold("Option 4:")} Set an Anthropic API key
1631
1640
  {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
1632
1641
  `)+1;i=i.slice(0,i.indexOf(`
1633
1642
  `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
1634
- `,i.indexOf("}}",l)+2)),a=!0}}if(a){let l=await he();l.start("Patching base.html..."),G(o,i),l.stop("base.html patched with template_css/template_js support")}let r=un(n,".hsignore");if(k(r)){let l=E(r);l.includes("docs/")||(G(r,l+`
1643
+ `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await Ce();l.start("Patching base.html..."),L(o,i),l.stop("base.html patched with template_css/template_js support")}let a=In(n,".hsignore");if(b(a)){let l=T(a);l.includes("docs/")||(L(a,l+`
1635
1644
  docs/
1636
- `),U("Added docs/ to .hsignore"))}else G(r,`docs/
1645
+ `),H("Added docs/ to .hsignore"))}else L(a,`docs/
1637
1646
  *.md
1638
1647
  node_modules/
1639
1648
  .git
1640
- `),U("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}f();import{join as Ie}from"path";import{readdirSync as mn,rmSync as cr}from"fs";f();ot();te();import{spawn as wd}from"child_process";import{join as K,basename as Cd}from"path";import{readdirSync as We,statSync as ar,writeFileSync as kd}from"fs";var Ad=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"]),ns=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||ce();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let a=this.countSourceComponents(n),r=this.listModules(s),l=this.listDir(K(s,"css")),c=this.listDir(K(s,"js")),d=this.listDir(K(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${a} source components found)...`);let m="",g="",y=setInterval(()=>{this.reportProgress(s,r,l,c,d,o)},3e3);try{await new Promise((w,S)=>{let M={...process.env};delete M.CLAUDECODE;let O=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&O.push("--model",this.model);let R=wd("claude",O,{cwd:s,stdio:["pipe","pipe","pipe"],env:M,shell:!0});R.stdout.on("data",H=>{m+=H.toString()}),R.stderr.on("data",H=>{g+=H.toString()}),R.on("error",H=>S(new Error(`Claude Code failed to start: ${H.message}`))),R.on("close",H=>{H!==0?S(new Error(`Claude Code exited with code ${H}.
1641
- `+(g?`Stderr: ${g.slice(0,500)}
1642
- `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):w()}),R.stdin.on("error",()=>{}),R.stdin.write(u),R.stdin.end(),setTimeout(()=>{R.kill(),S(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(y)}let h=K(s,"..","vibespot-conversion.log");try{let S=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
1643
- ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
1644
- `);kd(h,S,"utf-8"),o("status",`Log written to ${Cd(h)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(w=>!r.has(w.moduleName+".module")).length===0){let w=m.slice(0,1500)||"(no output)",S=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
1649
+ `),H("Created .hsignore");return await oe("Theme ready!"),{themePath:n,themeName:t}}g();import{join as je}from"path";import{readdirSync as En,rmSync as la}from"fs";g();ut();Q();import{spawn as sm}from"child_process";import{join as Y,basename as om}from"path";import{readdirSync as Qe,statSync as ra,writeFileSync as im}from"fs";var rm=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"]),Cs=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||ge();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(Y(s,"css")),c=this.listDir(Y(s,"js")),d=this.listDir(Y(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${r} source components found)...`);let m="",f="",y=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((w,v)=>{let N={...process.env};delete N.CLAUDECODE;let O=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&O.push("--model",this.model);let F=sm("claude",O,{cwd:s,stdio:["pipe","pipe","pipe"],env:N,shell:!0});F.stdout.on("data",U=>{m+=U.toString()}),F.stderr.on("data",U=>{f+=U.toString()}),F.on("error",U=>v(new Error(`Claude Code failed to start: ${U.message}`))),F.on("close",U=>{U!==0?v(new Error(`Claude Code exited with code ${U}.
1650
+ `+(f?`Stderr: ${f.slice(0,500)}
1651
+ `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):w()}),F.stdin.on("error",()=>{}),F.stdin.write(u),F.stdin.end(),setTimeout(()=>{F.kill(),v(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(y)}let h=Y(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)+`
1652
+ ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",f||"(empty)",""].join(`
1653
+ `);im(h,v,"utf-8"),o("status",`Log written to ${om(h)}`)}catch{}o("scan","Scanning generated files...");let S=this.scanGeneratedFiles(s);if(S.modules.filter(w=>!a.has(w.moduleName+".module")).length===0){let w=m.slice(0,1500)||"(no output)",v=f.slice(0,500);throw new Error(`Claude Code did not create any new module files.
1645
1654
 
1646
1655
  This usually means the model described the conversion instead of using Write tool to create files.
1647
1656
 
@@ -1652,12 +1661,12 @@ Possible causes:
1652
1661
 
1653
1662
  Source: ${t.sourceDir}
1654
1663
  Theme: ${s}
1655
- `+(S?`
1664
+ `+(v?`
1656
1665
  Stderr:
1657
- ${S}
1666
+ ${v}
1658
1667
  `:"")+`
1659
1668
  Claude output:
1660
- ${w}`)}return b}reportProgress(t,n,s,o,i,a){let r=0,l=this.listDir(K(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),a("created",`Shared CSS (${m})`),r++)}let c=this.listDir(K(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),a("created",`Shared JS (${m})`),r++)}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}]`;a("created",`Module ${y}: ${m.replace(".module","")}`),r++}}let u=this.listDir(K(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),a("created",`Page template (${m})`),r++)}if(r===0)if(this.moduleCount>0){let m=this.expectedModules>0?`/${this.expectedModules}`:"";a("status",`${this.moduleCount}${m} modules created, conversion continuing...`)}else this.reported.size>0?a("status","Shared assets created, building modules..."):a("status","Claude Code is analyzing source files...")}buildFullPrompt(t,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
1669
+ ${w}`)}return S}reportProgress(t,n,s,o,i,r){let a=0,l=this.listDir(Y(t,"css"));for(let m of l){if(s.has(m)||!m.endsWith(".css"))continue;let f=`css:${m}`;this.reported.has(f)||(this.reported.add(f),r("created",`Shared CSS (${m})`),a++)}let c=this.listDir(Y(t,"js"));for(let m of c){if(o.has(m)||!m.endsWith(".js"))continue;let f=`js:${m}`;this.reported.has(f)||(this.reported.add(f),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 f=`module:${m}`;if(!this.reported.has(f)){this.reported.add(f),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(Y(t,"templates"));for(let m of u){if(i.has(m)||!m.endsWith(".html"))continue;let f=`template:${m}`;this.reported.has(f)||(this.reported.add(f),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.
1661
1670
 
1662
1671
  SOURCE DIRECTORY: ${t}
1663
1672
  THEME DIRECTORY: ${n}
@@ -1700,16 +1709,16 @@ CSS QUALITY: The converted page must visually match the original React page. Eve
1700
1709
  Do NOT run hs upload \u2014 I will handle that separately.
1701
1710
 
1702
1711
  HUBSPOT CMS RULES:
1703
- ${Me()}
1712
+ ${He()}
1704
1713
 
1705
1714
  CONVERSION GUIDE:
1706
- ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=K(t,"css");if(k(s)){for(let r of We(s))if(r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=E(K(s,r));break}}let o=K(t,"js");if(k(o)){for(let r of We(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=E(K(o,r));break}}let i=K(t,"templates");if(k(i)){for(let r of We(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=E(K(i,r));break}if(!n.template){for(let r of We(i))if(r.endsWith(".html")&&!Ad.has(r)&&!r.startsWith("system")){let l=E(K(i,r));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let r of We(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=E(K(i,r));if(l.includes("dnd_area")){n.template=l;break}}}}let a=K(t,"modules");if(k(a))for(let r of We(a)){if(!r.endsWith(".module"))continue;let l=K(a,r);if(!ar(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=K(l,"fields.json");k(d)&&(c.fieldsJson=E(d));let u=K(l,"meta.json");k(u)&&(c.metaJson=E(u));let m=K(l,"module.html");k(m)&&(c.moduleHtml=E(m));let g=K(l,"module.css");k(g)&&(c.moduleCss=E(g));let y=K(l,"module.js");k(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=K(t,"modules");return k(n)?new Set(We(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return k(t)?new Set(We(t)):new Set}detectExpectedModules(t,n){let s=K(t,"templates");if(!k(s))return 0;for(let o of We(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=E(K(s,o));if(i.includes("dnd_area")){let a=i.match(/dnd_module/g);return a?a.length:0}}catch{}return 0}countSourceComponents(t){let n=K(t,"src");return k(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of We(t)){let o=K(t,s);try{ar(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}};f();ot();te();import $d from"@anthropic-ai/sdk";import{join as ee,basename as Td}from"path";import{readdirSync as lr}from"fs";var ss=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new $d({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,a=nr(o),r=Td(n)||"page",l=r.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(a,or(c,d,l)),m=ee(s,"css",`${l}-theme.css`);G(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),y=this.findInteractiveComponents(n),h=await this.complete(a,ir(g,y,l)),b=ee(s,"js",`${l}-animations.js`);G(b,h),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let x=this.findComponents(n),w=[];for(let R=0;R<x.length;R++){let H=x[R],z=H.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${z}.module (${R+1}/${x.length})...`);let _=E(H.path),F=await this.complete(a,sr(_,z,`See css/${l}-theme.css`));try{let C=JSON.parse(F),I={moduleName:z,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},Z=ee(s,"modules",`${z}.module`);Te(Z),G(ee(Z,"fields.json"),I.fieldsJson),G(ee(Z,"meta.json"),I.metaJson),G(ee(Z,"module.html"),I.moduleHtml),G(ee(Z,"module.css"),I.moduleCss),I.moduleJs&&G(ee(Z,"module.js"),I.moduleJs),w.push(I),i("module-done",`${z}.module (${this.countFiles(I)} files)`)}catch{i("module-error",`Failed to parse ${z} \u2014 skipping`)}}i("template","Creating page template...");let S=w.map(R=>R.moduleName),M=await this.complete(a,rr(S,r,l)),O=ee(s,"templates",`lp-${l}.html`);return G(O,M),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:h,template:M,modules:w}}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=[ee(t,"src/index.css"),ee(t,"src/globals.css"),ee(t,"src/app/globals.css"),ee(t,"app/globals.css")];for(let s of n)if(k(s))return E(s);return""}findAndReadTailwind(t){let n=[ee(t,"tailwind.config.ts"),ee(t,"tailwind.config.js"),ee(t,"tailwind.config.mjs")];for(let s of n)if(k(s))return E(s);return""}findAndReadHooks(t){let n=ee(t,"src/hooks");if(!k(n))return"";try{return lr(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
1707
- ${E(ee(n,s))}`).join(`
1715
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Y(t,"css");if(b(s)){for(let a of Qe(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=T(Y(s,a));break}}let o=Y(t,"js");if(b(o)){for(let a of Qe(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=T(Y(o,a));break}}let i=Y(t,"templates");if(b(i)){for(let a of Qe(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=T(Y(i,a));break}if(!n.template){for(let a of Qe(i))if(a.endsWith(".html")&&!rm.has(a)&&!a.startsWith("system")){let l=T(Y(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of Qe(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=T(Y(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=Y(t,"modules");if(b(r))for(let a of Qe(r)){if(!a.endsWith(".module"))continue;let l=Y(r,a);if(!ra(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Y(l,"fields.json");b(d)&&(c.fieldsJson=T(d));let u=Y(l,"meta.json");b(u)&&(c.metaJson=T(u));let m=Y(l,"module.html");b(m)&&(c.moduleHtml=T(m));let f=Y(l,"module.css");b(f)&&(c.moduleCss=T(f));let y=Y(l,"module.js");b(y)&&(c.moduleJs=T(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=Y(t,"modules");return b(n)?new Set(Qe(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return b(t)?new Set(Qe(t)):new Set}detectExpectedModules(t,n){let s=Y(t,"templates");if(!b(s))return 0;for(let o of Qe(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=T(Y(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=Y(t,"src");return b(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of Qe(t)){let o=Y(t,s);try{ra(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}};g();ut();Q();import am from"@anthropic-ai/sdk";import{join as ne,basename as lm}from"path";import{readdirSync as aa}from"fs";var ks=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new am({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=ta(o),a=lm(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,sa(c,d,l)),m=ne(s,"css",`${l}-theme.css`);L(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let f=this.findAndReadHooks(n),y=this.findInteractiveComponents(n),h=await this.complete(r,oa(f,y,l)),S=ne(s,"js",`${l}-animations.js`);L(S,h),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let x=this.findComponents(n),w=[];for(let F=0;F<x.length;F++){let U=x[F],q=U.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${q}.module (${F+1}/${x.length})...`);let _=T(U.path),j=await this.complete(r,na(_,q,`See css/${l}-theme.css`));try{let k=JSON.parse(j),M={moduleName:q,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},te=ne(s,"modules",`${q}.module`);Ae(te),L(ne(te,"fields.json"),M.fieldsJson),L(ne(te,"meta.json"),M.metaJson),L(ne(te,"module.html"),M.moduleHtml),L(ne(te,"module.css"),M.moduleCss),M.moduleJs&&L(ne(te,"module.js"),M.moduleJs),w.push(M),i("module-done",`${q}.module (${this.countFiles(M)} files)`)}catch{i("module-error",`Failed to parse ${q} \u2014 skipping`)}}i("template","Creating page template...");let v=w.map(F=>F.moduleName),N=await this.complete(r,ia(v,a,l)),O=ne(s,"templates",`lp-${l}.html`);return L(O,N),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:h,template:N,modules:w}}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=[ne(t,"src/index.css"),ne(t,"src/globals.css"),ne(t,"src/app/globals.css"),ne(t,"app/globals.css")];for(let s of n)if(b(s))return T(s);return""}findAndReadTailwind(t){let n=[ne(t,"tailwind.config.ts"),ne(t,"tailwind.config.js"),ne(t,"tailwind.config.mjs")];for(let s of n)if(b(s))return T(s);return""}findAndReadHooks(t){let n=ne(t,"src/hooks");if(!b(n))return"";try{return aa(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
1716
+ ${T(ne(n,s))}`).join(`
1708
1717
 
1709
- `)}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}
1718
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=T(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
1710
1719
  ${i}`)}return s.join(`
1711
1720
 
1712
- `)}findComponents(t){let n=[ee(t,"src/components/landing"),ee(t,"src/components/sections"),ee(t,"src/components")];for(let s of n)if(k(s))try{return lr(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:ee(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};f();ot();te();import{spawn as Id}from"child_process";import{join as Ae}from"path";import{readdirSync as os,statSync as Ed}from"fs";var is=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce(),a=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((r,l)=>{let c=Id("gemini",["-p",a],{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}`)):r()}),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}.
1721
+ `)}findComponents(t){let n=[ne(t,"src/components/landing"),ne(t,"src/components/sections"),ne(t,"src/components")];for(let s of n)if(b(s))try{return aa(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:ne(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};g();ut();Q();import{spawn as cm}from"child_process";import{join as Pe}from"path";import{readdirSync as As,statSync as dm}from"fs";var Ts=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ge(),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=cm("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}.
1713
1722
 
1714
1723
  INSTRUCTIONS:
1715
1724
  1. Analyze all .tsx/.jsx components in the React source
@@ -1724,7 +1733,7 @@ CONVERSION GUIDE:
1724
1733
  ${s}
1725
1734
 
1726
1735
  Do NOT run hs upload \u2014 I will handle that separately.
1727
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ae(t,"css");if(k(s)){for(let r of os(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=E(Ae(s,r));break}}let o=Ae(t,"js");if(k(o)){for(let r of os(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=E(Ae(o,r));break}}let i=Ae(t,"templates");if(k(i)){for(let r of os(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=E(Ae(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=Ae(t,"modules");if(k(a))for(let r of os(a)){if(!r.endsWith(".module"))continue;let l=Ae(a,r);if(!Ed(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ae(l,"fields.json");k(d)&&(c.fieldsJson=E(d));let u=Ae(l,"meta.json");k(u)&&(c.metaJson=E(u));let m=Ae(l,"module.html");k(m)&&(c.moduleHtml=E(m));let g=Ae(l,"module.css");k(g)&&(c.moduleCss=E(g));let y=Ae(l,"module.js");k(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};f();ot();te();import{spawn as _d}from"child_process";import{join as $e}from"path";import{readdirSync as rs,statSync as Nd}from"fs";var as=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce(),a=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((r,l)=>{let c=_d("codex",["exec","--full-auto",a],{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}`)):r()}),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}.
1736
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Pe(t,"css");if(b(s)){for(let a of As(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=T(Pe(s,a));break}}let o=Pe(t,"js");if(b(o)){for(let a of As(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=T(Pe(o,a));break}}let i=Pe(t,"templates");if(b(i)){for(let a of As(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=T(Pe(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Pe(t,"modules");if(b(r))for(let a of As(r)){if(!a.endsWith(".module"))continue;let l=Pe(r,a);if(!dm(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Pe(l,"fields.json");b(d)&&(c.fieldsJson=T(d));let u=Pe(l,"meta.json");b(u)&&(c.metaJson=T(u));let m=Pe(l,"module.html");b(m)&&(c.moduleHtml=T(m));let f=Pe(l,"module.css");b(f)&&(c.moduleCss=T(f));let y=Pe(l,"module.js");b(y)&&(c.moduleJs=T(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};g();ut();Q();import{spawn as um}from"child_process";import{join as Ne}from"path";import{readdirSync as $s,statSync as mm}from"fs";var Is=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ge(),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=um("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}.
1728
1737
 
1729
1738
  INSTRUCTIONS:
1730
1739
  1. Analyze all .tsx/.jsx components in the React source
@@ -1739,51 +1748,52 @@ CONVERSION GUIDE:
1739
1748
  ${s}
1740
1749
 
1741
1750
  Do NOT run hs upload \u2014 I will handle that separately.
1742
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=$e(t,"css");if(k(s)){for(let r of rs(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=E($e(s,r));break}}let o=$e(t,"js");if(k(o)){for(let r of rs(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=E($e(o,r));break}}let i=$e(t,"templates");if(k(i)){for(let r of rs(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=E($e(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=$e(t,"modules");if(k(a))for(let r of rs(a)){if(!r.endsWith(".module"))continue;let l=$e(a,r);if(!Nd(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=$e(l,"fields.json");k(d)&&(c.fieldsJson=E(d));let u=$e(l,"meta.json");k(u)&&(c.metaJson=E(u));let m=$e(l,"module.html");k(m)&&(c.moduleHtml=E(m));let g=$e(l,"module.css");k(g)&&(c.moduleCss=E(g));let y=$e(l,"module.js");k(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};ot();te();function Pd(e,t){switch(e){case"claude-code":return new ns(t);case"gemini-cli":return new is;case"codex-cli":return new as;case"api":return new ss}}async function ls(e){await ge("Converting React to HubSpot Modules"),await Ge(`AI will now analyze your React code and create
1743
- HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=Pd(e.aiEngine,e.model),n=ce(),s=await he();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(y,h)=>{y==="created"?U(h):s.message(h)}}),a=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${a}s)`);let r=Md(e.themePath);for(let y of r)U(`Auto-fixed: ${y}`);let l=Od(e.themePath,i),c=[];for(let y of l){let h=y.passed?"\u2705":"\u274C",b=y.passed?"":y.critical?" (CRITICAL)":" (cosmetic)";c.push(`${h} ${y.label}${b}`)}let d=l.filter(y=>y.passed).length;c.push(`
1744
- ${d}/${l.length} checks passed`),await Ge(c.join(`
1745
- `),"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:
1751
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ne(t,"css");if(b(s)){for(let a of $s(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=T(Ne(s,a));break}}let o=Ne(t,"js");if(b(o)){for(let a of $s(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=T(Ne(o,a));break}}let i=Ne(t,"templates");if(b(i)){for(let a of $s(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=T(Ne(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ne(t,"modules");if(b(r))for(let a of $s(r)){if(!a.endsWith(".module"))continue;let l=Ne(r,a);if(!mm(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ne(l,"fields.json");b(d)&&(c.fieldsJson=T(d));let u=Ne(l,"meta.json");b(u)&&(c.metaJson=T(u));let m=Ne(l,"module.html");b(m)&&(c.moduleHtml=T(m));let f=Ne(l,"module.css");b(f)&&(c.moduleCss=T(f));let y=Ne(l,"module.js");b(y)&&(c.moduleJs=T(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};ut();Q();function pm(e,t){switch(e){case"claude-code":return new Cs(t);case"gemini-cli":return new Ts;case"codex-cli":return new Is;case"api":return new ks}}async function Es(e){await se("Converting React to HubSpot Modules"),await Ze(`AI will now analyze your React code and create
1752
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=pm(e.aiEngine,e.model),n=ge(),s=await Ce();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(y,h)=>{y==="created"?H(h):s.message(h)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=fm(e.themePath);for(let y of a)H(`Auto-fixed: ${y}`);let l=gm(e.themePath,i),c=[];for(let y of l){let h=y.passed?"\u2705":"\u274C",S=y.passed?"":y.critical?" (CRITICAL)":" (cosmetic)";c.push(`${h} ${y.label}${S}`)}let d=l.filter(y=>y.passed).length;c.push(`
1753
+ ${d}/${l.length} checks passed`),await Ze(c.join(`
1754
+ `),"Conversion Checklist");let u=l.filter(y=>!y.passed&&y.critical),m=l.filter(y=>!y.passed&&!y.critical);if(u.length>0){if(z(`${u.length} critical issue(s) \u2014 upload will likely fail:
1746
1755
  `+u.map(h=>` - ${h.label}`).join(`
1747
- `)),!await le({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&q(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
1756
+ `)),!await fe({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&Z(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
1748
1757
  `+m.map(y=>` - ${y.label}`).join(`
1749
- `));let g=Ie(e.themePath,"..","vibespot-conversion.log");return k(g)&&(await le({message:"Keep conversion log file for debugging?",initialValue:!1})?U(`Log saved: ${g}`):cr(g)),await fe("Files ready for upload!"),i}function Md(e){let t=[];Rd(e),Fd(e);let n=Ie(e,"modules");if(k(n))for(let o of mn(n)){if(!o.endsWith(".module"))continue;let i=Ie(n,o,"fields.json");if(!k(i))continue;let a=o.replace(".module",""),r=E(i),l=!1;r.includes('"textarea"')&&(r=r.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${a}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(r)&&(r=r.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${a}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(r),u=!1;dr(d)&&(u=!0,t.push(`${a}: fixed choice field format`)),ur(d)&&(u=!0,t.push(`${a}: fixed link field default value`)),u&&(r=JSON.stringify(d,null,2)+`
1750
- `,l=!0)}catch{t.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&G(i,r);let c=Ie(n,o,"module.html");if(k(c)){let d=E(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),G(c,d),t.push(`${a}: now() \u2192 local_dt`))}}let s=Ie(e,"templates");if(k(s))for(let o of mn(s)){if(!o.endsWith(".html"))continue;let i=Ie(s,o),a=E(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(cr(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function dr(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 a=i.charAt(0).toUpperCase()+i.slice(1);return[i,a]}return i}),t=!0),Array.isArray(s.children)&&dr(s.children)&&(t=!0)}return t}function ur(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 a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&ur(s.children)&&(t=!0)}return t}function Od(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 a=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),r=a.length===0;n.push({label:r?"module.css created for each module":`module.css missing for: ${a.join(", ")}`,passed:s>0&&r,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=Ie(e,"templates"),d=!1;if(k(c))for(let u of mn(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=E(Ie(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 Rd(e){let t=Ie(e,"templates");if(k(t))for(let n of mn(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=Ie(t,n),o=E(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),a=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&a)continue;let r=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+=`
1751
- templateType: page`),a||(c+=`
1758
+ `));let f=je(e.themePath,"..","vibespot-conversion.log");return b(f)&&(await fe({message:"Keep conversion log file for debugging?",initialValue:!1})?H(`Log saved: ${f}`):la(f)),await oe("Files ready for upload!"),i}function fm(e){let t=[];hm(e),ym(e);let n=je(e,"modules");if(b(n))for(let o of En(n)){if(!o.endsWith(".module"))continue;let i=je(n,o,"fields.json");if(!b(i))continue;let r=o.replace(".module",""),a=T(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;ca(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),da(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
1759
+ `,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&L(i,a);let c=je(n,o,"module.html");if(b(c)){let d=T(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),L(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=je(e,"templates");if(b(s))for(let o of En(s)){if(!o.endsWith(".html"))continue;let i=je(s,o),r=T(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(la(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function ca(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)&&ca(s.children)&&(t=!0)}return t}function da(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)&&da(s.children)&&(t=!0)}return t}function gm(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=je(e,"templates"),d=!1;if(b(c))for(let u of En(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=T(je(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 hm(e){let t=je(e,"templates");if(b(t))for(let n of En(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=je(t,n),o=T(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+=`
1760
+ templateType: page`),r||(c+=`
1752
1761
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
1753
- label: ${r}`),o=c+o.slice(l)}else o=`<!--
1762
+ label: ${a}`),o=c+o.slice(l)}else o=`<!--
1754
1763
  templateType: page
1755
1764
  isAvailableForNewContent: true
1756
- label: ${r}
1765
+ label: ${a}
1757
1766
  -->
1758
- `+o;G(s,o),U(`Template "${n}" \u2014 annotations verified`)}}function Fd(e){let t=Ie(e,"modules");if(k(t))for(let n of mn(t)){if(!n.endsWith(".module"))continue;let s=Ie(t,n,"meta.json");if(k(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&&G(s,JSON.stringify(o,null,2)+`
1759
- `)}catch{}}}f();ht();import{join as wr,basename as Vd}from"path";f();te();import{join as de}from"path";import{readdirSync as it,rmSync as Jd}from"fs";function cs(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),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function ds(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}),t}function us(e){let t=[];return pr(e)&&t.push("textarea \u2192 text"),gr(e)&&t.push("name \u2192 item_name"),fr(e)&&t.push("now() \u2192 local_dt"),hr(e)&&t.push("Removed HubDB templates"),yr(e)&&t.push("Fixed link field defaults"),br(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),jd(e)&&t.push("Stripped CDN @import statements"),t}function mr(e,t){return t.message.includes("textarea")?pr(e):t.message.includes("reserved field name")?gr(e):t.message.includes("now()")?fr(e):t.message.includes("HubDB")?hr(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?yr(e):t.message.includes("invalid format")&&t.message.includes("color")?br(e):!1}function pr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(!k(o))continue;let i=E(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),G(o,i),t=!0)}return t}function gr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(!k(o))continue;let i=E(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),G(o,i),t=!0)}return t}function fr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"module.html");if(!k(o))continue;let i=E(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),G(o,i),t=!0)}return t}function hr(e){let t=!1,n=de(e,"templates");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=de(n,s),i=E(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Jd(o),t=!0)}return t}function yr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(k(o))try{let i=JSON.parse(E(o));xr(i)&&(G(o,JSON.stringify(i,null,2)+`
1760
- `),t=!0)}catch{}}return t}function jd(e){let t=!1,n=de(e,"css");if(k(n))for(let o of it(n)){if(!o.endsWith(".css"))continue;let i=de(n,o),a=E(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(G(i,r),t=!0)}let s=de(e,"modules");if(k(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=de(s,o,"module.css");if(!k(i))continue;let a=E(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(G(i,r),t=!0)}if(k(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=de(s,o,"module.html");if(!k(i))continue;let a=E(i),r=a.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");r!==a&&(G(i,r),t=!0)}return t}function br(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(k(o))try{let i=JSON.parse(E(o));Sr(i)&&(G(o,JSON.stringify(i,null,2)+`
1761
- `),t=!0)}catch{}}return t}function Sr(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"&&!Dd(i)){let a=Hd(i);a&&(o.color=a.hex,a.opacity!==void 0&&(o.opacity=a.opacity),t=!0)}}Array.isArray(s.children)&&Sr(s.children)&&(t=!0)}return t}function Dd(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function Hd(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])),a=Math.min(255,parseInt(n[2])),r=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}${r.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 xr(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 a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&xr(s.children)&&(t=!0)}return t}Q();f();bt();bt();import{readdirSync as Ld}from"fs";import{join as Bd,relative as Ud}from"path";var Gd=new Set([".git","node_modules",".vibespot",".DS_Store"]);function vr(e){let t=[];for(let n of Ld(e,{withFileTypes:!0})){if(Gd.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=Bd(e,n.name);n.isDirectory()?t.push(...vr(s)):n.isFile()&&t.push(s)}return t}async function Wd(e,t,n){let s=0;async function o(){for(;s<e.length;){let a=s++;await n(e[a])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function ms(e,t,n,s={}){let o=s.concurrency??5,i=vr(t),a=i.length,r=0,l=0,c=[];return await Wd(i,o,async d=>{let u=Ud(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await Wi(e,m,d);if(g.success)r++,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?.(r+l,a)}),{success:l===0,uploaded:r,failed:l,total:a,errors:c}}function Kd(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Jt(e){await ge("Uploading to HubSpot");let t=Vd(e)||e,n=P(),s=Se(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await he(),a=3;for(let r=1;r<=a;r++){i.start(r===1?"Uploading theme...":`Retrying upload (attempt ${r}/${a})...`);let l=[],c=0,d=!1;if(o){let m=await ms(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=cs(m.errors)}else{let m=J(`hs cms upload "${e}" "${t}"`,{cwd:wr(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
1762
- `);c=Kd(g),d=m.success,d||(l=ds(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&&(q(`Most files uploaded successfully. The theme may already be usable in HubSpot.
1763
- You can check your HubSpot Design Manager to verify.`),await le({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(r<a){if(!await le({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?mr(e,m)?(U(`Auto-fixed: ${m.message}`),u=!0):q(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&r<a)){if(c>0&&(q(`${c} files uploaded successfully despite errors.
1764
- The theme may work \u2014 check HubSpot Design Manager.`),await le({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await ao(s,`${t}/modules`)}catch{}else J(`hs cms delete "${t}/modules"`,{cwd:wr(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}f();import{execFileSync as yo}from"child_process";import{rmSync as zd}from"fs";import{basename as Cr}from"path";te();async function kr(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ge("You're all set!");let a=sn(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await Ge(`Your React page has been converted and uploaded to HubSpot.
1767
+ `+o;L(s,o),H(`Template "${n}" \u2014 annotations verified`)}}function ym(e){let t=je(e,"modules");if(b(t))for(let n of En(t)){if(!n.endsWith(".module"))continue;let s=je(t,n,"meta.json");if(b(s))try{let o=JSON.parse(T(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&&L(s,JSON.stringify(o,null,2)+`
1768
+ `)}catch{}}}g();Et();import{join as va,basename as $m}from"path";g();Q();import{join as he}from"path";import{readdirSync as mt,rmSync as bm}from"fs";function Ms(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),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function Rs(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}),t}function _s(e){let t=[];return ma(e)&&t.push("textarea \u2192 text"),pa(e)&&t.push("name \u2192 item_name"),fa(e)&&t.push("now() \u2192 local_dt"),ga(e)&&t.push("Removed HubDB templates"),ha(e)&&t.push("Fixed link field defaults"),ya(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),Sm(e)&&t.push("Stripped CDN @import statements"),t}function ua(e,t){return t.message.includes("textarea")?ma(e):t.message.includes("reserved field name")?pa(e):t.message.includes("now()")?fa(e):t.message.includes("HubDB")?ga(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?ha(e):t.message.includes("invalid format")&&t.message.includes("color")?ya(e):!1}function ma(e){let t=!1,n=he(e,"modules");if(!b(n))return!1;for(let s of mt(n)){if(!s.endsWith(".module"))continue;let o=he(n,s,"fields.json");if(!b(o))continue;let i=T(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),L(o,i),t=!0)}return t}function pa(e){let t=!1,n=he(e,"modules");if(!b(n))return!1;for(let s of mt(n)){if(!s.endsWith(".module"))continue;let o=he(n,s,"fields.json");if(!b(o))continue;let i=T(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),L(o,i),t=!0)}return t}function fa(e){let t=!1,n=he(e,"modules");if(!b(n))return!1;for(let s of mt(n)){if(!s.endsWith(".module"))continue;let o=he(n,s,"module.html");if(!b(o))continue;let i=T(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),L(o,i),t=!0)}return t}function ga(e){let t=!1,n=he(e,"templates");if(!b(n))return!1;for(let s of mt(n)){if(!s.endsWith(".html"))continue;let o=he(n,s),i=T(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(bm(o),t=!0)}return t}function ha(e){let t=!1,n=he(e,"modules");if(!b(n))return!1;for(let s of mt(n)){if(!s.endsWith(".module"))continue;let o=he(n,s,"fields.json");if(b(o))try{let i=JSON.parse(T(o));Sa(i)&&(L(o,JSON.stringify(i,null,2)+`
1769
+ `),t=!0)}catch{}}return t}function Sm(e){let t=!1,n=he(e,"css");if(b(n))for(let o of mt(n)){if(!o.endsWith(".css"))continue;let i=he(n,o),r=T(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(L(i,a),t=!0)}let s=he(e,"modules");if(b(s))for(let o of mt(s)){if(!o.endsWith(".module"))continue;let i=he(s,o,"module.css");if(!b(i))continue;let r=T(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(L(i,a),t=!0)}if(b(s))for(let o of mt(s)){if(!o.endsWith(".module"))continue;let i=he(s,o,"module.html");if(!b(i))continue;let r=T(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(L(i,a),t=!0)}return t}function ya(e){let t=!1,n=he(e,"modules");if(!b(n))return!1;for(let s of mt(n)){if(!s.endsWith(".module"))continue;let o=he(n,s,"fields.json");if(b(o))try{let i=JSON.parse(T(o));ba(i)&&(L(o,JSON.stringify(i,null,2)+`
1770
+ `),t=!0)}catch{}}return t}function ba(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"&&!xm(i)){let r=vm(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&ba(s.children)&&(t=!0)}return t}function xm(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function vm(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 Sa(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)&&Sa(s.children)&&(t=!0)}return t}X();g();Rt();Rt();import{readdirSync as wm}from"fs";import{join as Cm,relative as km}from"path";var Am=new Set([".git","node_modules",".vibespot",".DS_Store"]);function xa(e){let t=[];for(let n of wm(e,{withFileTypes:!0})){if(Am.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=Cm(e,n.name);n.isDirectory()?t.push(...xa(s)):n.isFile()&&t.push(s)}return t}async function Tm(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 Ps(e,t,n,s={}){let o=s.concurrency??5,i=xa(t),r=i.length,a=0,l=0,c=[];return await Tm(i,o,async d=>{let u=km(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let f=await Gr(e,m,d);if(f.success)a++,s.onFileComplete?.(u);else{l++;let y={file:u,status:f.error?.status||0,message:f.error?.message||"Unknown error",category:f.error?.category,detail:f.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}}function Im(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Xt(e){await se("Uploading to HubSpot");let t=$m(e)||e,n=R(),s=$e(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await Ce(),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 Ps(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Ms(m.errors)}else{let m=D(`hs cms upload "${e}" "${t}"`,{cwd:va(e,"..")}),f=[m.stdout,m.stderr].filter(Boolean).join(`
1771
+ `);c=Im(f),d=m.success,d||(l=Rs(f))}if(d)return i.stop(`All files uploaded! (${c} files)`),await oe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(z("Upload failed with unknown error."),c>0&&(Z(`Most files uploaded successfully. The theme may already be usable in HubSpot.
1772
+ You can check your HubSpot Design Manager to verify.`),await fe({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await fe({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?ua(e,m)?(H(`Auto-fixed: ${m.message}`),u=!0):Z(`Could not auto-fix: ${m.message}`):z(m.message);if(!(u&&a<r)){if(c>0&&(Z(`${c} files uploaded successfully despite errors.
1773
+ The theme may work \u2014 check HubSpot Design Manager.`),await fe({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await zo(s,`${t}/modules`)}catch{}else D(`hs cms delete "${t}/modules"`,{cwd:va(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return z("Upload failed after multiple attempts."),!1}g();import{execFileSync as ni}from"child_process";import{rmSync as Em}from"fs";import{basename as wa}from"path";Q();async function Ca(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await se("You're all set!");let r=vn(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await Ze(`Your React page has been converted and uploaded to HubSpot.
1765
1774
  The theme and modules are now in your account, but you still
1766
- need to ${N.bold("create a new landing page")} that uses them.
1775
+ need to ${A.bold("create a new landing page")} that uses them.
1767
1776
 
1768
1777
  Next steps:
1769
1778
 
1770
- ${N.bold("1.")} Go to HubSpot ${N.muted("\u2192")} Content ${N.muted("\u2192")} Landing Pages ${N.muted("\u2192")} Create
1771
- ${N.bold("2.")} Choose your uploaded theme from the theme picker
1772
- ${N.bold("3.")} Select the landing page template that was just created
1773
- ${N.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
1774
- ${N.bold("5.")} Click each section to edit text, images, and colors
1775
- ${N.bold("6.")} Upload images via File Manager ${N.muted("(Settings \u2192 Files)")}
1776
- ${N.bold("7.")} Preview and publish!`,"What's next"),await le({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${a}/page-ui/${t}/management/pages/landing`:`https://${a}`;try{let d=process.platform;d==="darwin"?yo("open",[c],{stdio:"ignore"}):d==="win32"?yo("cmd",["/c","start","",c],{stdio:"ignore"}):yo("xdg-open",[c],{stdio:"ignore"}),U("Opening HubSpot Landing Pages...")}catch{ne(`Open this URL in your browser: ${N.info(c)}`)}}let l=[];if(o&&k(n)&&l.push({path:n,label:`Cloned source (${Cr(n)})`}),k(s)&&l.push({path:s,label:`Theme directory (${Cr(s)})`}),l.length>0&&await le({message:"Clean up local working directories?"}))for(let d of l)try{zd(d.path,{recursive:!0,force:!0}),U(`Removed ${d.label}`)}catch{q(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await fe(`Thanks for using hub${N.vibes("Vibes")}! ${N.vibes("~")}`)}Q();async function Ar(){He();let e=await qn(),t=await Xn();W({lastSourcePath:t.sourceDir});let n=await ts();W({lastThemePath:n.themePath}),await ls({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Jt(n.themePath),await kr({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}f();async function $r(){He(),await qn()}f();Q();async function Tr(){He();let e=P();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await Xn(),n=await ts();await ls({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}f();Q();async function Ir(){He();let e=P();if(e.lastThemePath)if(await le({message:`Upload from ${e.lastThemePath}?`}))await Jt(e.lastThemePath);else{let n=await Ne({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Jt(n)}else{let t=await Ne({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Jt(t)}}f();Q();async function Er(){He(),await ge("Environment Diagnostics");let e=0,t=en();t.found?Wn(t.version)?U(`Node.js v${t.version}`):(q(`Node.js v${t.version} \u2014 too old (need 18+)`),ne(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),ne(" Install from https://nodejs.org"),e++);let n=tn();n.found?U(`Git ${n.version}`):(V("Git \u2014 not installed"),ne(" Install from https://git-scm.com"),e++);let s=Be();if(!s.found)q("HubSpot CLI \u2014 not installed (only needed for deployment)"),ne(" Install: npm install -g @hubspot/cli");else if(!Bi(s.version))q(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),ne(" Update: npm install -g @hubspot/cli@latest"),e++;else{U(`HubSpot CLI v${s.version}`);let m=Ue();m.authenticated?U(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(q("HubSpot \u2014 not authenticated"),ne(" Run: hs init"))}let o=nn();o.found?U(`Claude Code ${o.version} at ${o.path}`):ne(N.muted("Claude Code \u2014 not installed"));let i=on();i.found?U(`Gemini CLI ${i.version} at ${i.path}`):ne(N.muted("Gemini CLI \u2014 not installed"));let a=rn();a.found?U(`OpenAI Codex ${a.version} at ${a.path}`):ne(N.muted("OpenAI Codex \u2014 not installed"));let r=P(),l=!!(r.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(r.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(r.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?U("Anthropic API key configured"):ne(N.muted("Anthropic API key \u2014 not set")),c?U("OpenAI API key configured"):ne(N.muted("OpenAI API key \u2014 not set")),d?U("Google AI API key configured"):ne(N.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"};r.aiEngine&&U(`AI engine: ${u[r.aiEngine]||r.aiEngine}`),r.lastThemePath&&ne(N.muted(`Last theme: ${r.lastThemePath}`)),!o.found&&!i.found&&!a.found&&!l&&!c&&!d&&(q("No AI engine available"),ne(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),ne(" Or install: Claude Code \u2014 https://claude.ai/code"),ne(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),ne(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await fe("Everything looks good!"):await fe(N.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}f();import{join as zs}from"path";import{existsSync as Vp}from"fs";import{execFileSync as Ei}from"child_process";import Ys from"chalk";f();pe();jt();ks();Tn();import{createServer as Dp}from"http";import{readFileSync as Ii,existsSync as Pn}from"fs";import{join as dt,extname as Lc}from"path";import{createHash as Hp}from"crypto";import{WebSocketServer as Lp}from"ws";f();Fe();pe();Q();ie();import{existsSync as ul,mkdirSync as Hm,writeFileSync as Lm,rmSync as Bm}from"fs";import{join as ml}from"path";var Um="plan.md";function pl(e){return ml(e,".vibespot",Um)}function mi(e){let t=v();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;try{let n=ml(t.themePath,".vibespot");ul(n)||Hm(n,{recursive:!0}),Lm(pl(t.themePath),e,"utf-8")}catch(n){A.warn("plan",`Failed to write plan.md: ${n instanceof Error?n.message:String(n)}`)}return j(),e}function pi(){let e=v();if(e){e.brandAssets&&delete e.brandAssets.plan;try{let t=pl(e.themePath);ul(t)&&Bm(t)}catch(t){A.warn("plan",`Failed to remove plan.md: ${t instanceof Error?t.message:String(t)}`)}j()}}function gl(e,t){Ye(e,t,n=>{if(!v()){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}mi(o),p(t,200,{ok:!0,plan:o})})}function fl(e,t){Ye(e,t,()=>{pi(),W({planMode:!1}),p(t,200,{ok:!0})})}f();var gi=/```vibespot-plan\s*\n([\s\S]*?)```/g,fi=/```vibespot-choices\s*\n([\s\S]*?)```/g;function hl(e){let t,n,s;for(gi.lastIndex=0;(s=gi.exec(e))!==null;)t=s[1].trim();let o;for(fi.lastIndex=0;(o=fi.exec(e))!==null;)try{let a=JSON.parse(o[1].trim());a&&typeof a.question=="string"&&Array.isArray(a.options)&&a.options.every(r=>typeof r=="string")&&a.options.length>0&&(n={question:a.question,options:a.options})}catch{}return{cleanedContent:e.replace(gi,"").replace(fi,"").replace(/\n{3,}/g,`
1779
+ ${A.bold("1.")} Go to HubSpot ${A.muted("\u2192")} Content ${A.muted("\u2192")} Landing Pages ${A.muted("\u2192")} Create
1780
+ ${A.bold("2.")} Choose your uploaded theme from the theme picker
1781
+ ${A.bold("3.")} Select the landing page template that was just created
1782
+ ${A.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
1783
+ ${A.bold("5.")} Click each section to edit text, images, and colors
1784
+ ${A.bold("6.")} Upload images via File Manager ${A.muted("(Settings \u2192 Files)")}
1785
+ ${A.bold("7.")} Preview and publish!`,"What's next"),await fe({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"?ni("open",[c],{stdio:"ignore"}):d==="win32"?ni("cmd",["/c","start","",c],{stdio:"ignore"}):ni("xdg-open",[c],{stdio:"ignore"}),H("Opening HubSpot Landing Pages...")}catch{P(`Open this URL in your browser: ${A.info(c)}`)}}let l=[];if(o&&b(n)&&l.push({path:n,label:`Cloned source (${wa(n)})`}),b(s)&&l.push({path:s,label:`Theme directory (${wa(s)})`}),l.length>0&&await fe({message:"Clean up local working directories?"}))for(let d of l)try{Em(d.path,{recursive:!0,force:!0}),H(`Removed ${d.label}`)}catch{Z(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await oe(`Thanks for using hub${A.vibes("Vibes")}! ${A.vibes("~")}`)}X();async function ka(){pe();let e=await ys(),t=await bs();V({lastSourcePath:t.sourceDir});let n=await ws();V({lastThemePath:n.themePath}),await Es({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Xt(n.themePath),await Ca({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}g();async function Aa(){pe(),await ys()}g();X();async function Ta(){pe();let e=R();e.aiEngine||(z("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await bs(),n=await ws();await Es({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}g();X();async function $a(){pe();let e=R();if(e.lastThemePath)if(await fe({message:`Upload from ${e.lastThemePath}?`}))await Xt(e.lastThemePath);else{let n=await le({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Xt(n)}else{let t=await le({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Xt(t)}}g();X();async function Ia(){pe(),await se("Environment Diagnostics");let e=0,t=bn();t.found?ms(t.version)?H(`Node.js v${t.version}`):(Z(`Node.js v${t.version} \u2014 too old (need 18+)`),P(" Update at https://nodejs.org"),e++):(z("Node.js \u2014 not installed"),P(" Install from https://nodejs.org"),e++);let n=Sn();n.found?H(`Git ${n.version}`):(z("Git \u2014 not installed"),P(" Install from https://git-scm.com"),e++);let s=qe();if(!s.found)Z("HubSpot CLI \u2014 not installed (only needed for deployment)"),P(" Install: npm install -g @hubspot/cli");else if(!Hr(s.version))Z(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),P(" Update: npm install -g @hubspot/cli@latest"),e++;else{H(`HubSpot CLI v${s.version}`);let m=Xe();m.authenticated?H(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(Z("HubSpot \u2014 not authenticated"),P(" Run: hs init"))}let o=xn();o.found?H(`Claude Code ${o.version} at ${o.path}`):P(A.muted("Claude Code \u2014 not installed"));let i=wn();i.found?H(`Gemini CLI ${i.version} at ${i.path}`):P(A.muted("Gemini CLI \u2014 not installed"));let r=Cn();r.found?H(`OpenAI Codex ${r.version} at ${r.path}`):P(A.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?H("Anthropic API key configured"):P(A.muted("Anthropic API key \u2014 not set")),c?H("OpenAI API key configured"):P(A.muted("OpenAI API key \u2014 not set")),d?H("Google AI API key configured"):P(A.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&&P(A.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(Z("No AI engine available"),P(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),P(" Or install: Claude Code \u2014 https://claude.ai/code"),P(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),P(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await oe("Everything looks good!"):await oe(A.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}g();import{dirname as Hh,join as No}from"path";import{existsSync as Bh}from"fs";import{fileURLToPath as Uh}from"url";import{execFileSync as wr}from"child_process";import Oo from"chalk";g();me();Zt();Fn();cn();import{createServer as Nh}from"http";import{readFileSync as vr,existsSync as Qn}from"fs";import{join as St,extname as gu}from"path";import{WebSocketServer as Oh,WebSocket as Fh}from"ws";g();Fe();me();Nt();X();re();import{existsSync as xc,mkdirSync as lg,writeFileSync as cg,rmSync as dg}from"fs";import{join as vc}from"path";g();import{readFileSync as Qf,readdirSync as eg,existsSync as tg}from"fs";import{dirname as ng,join as co}from"path";import{fileURLToPath as sg}from"url";var hc=ng(sg(import.meta.url)),og=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;function ig(e){let t=e.match(og);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 rg(e){let t=ig(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;return{id:o,label:i,description:r,icon:n.icon||void 0,order:Number.isFinite(a)?a:9999,body:s.trimEnd()+`
1786
+ `}}var At=null;function ag(){let e=[co(hc,"../../assets/plan-templates"),co(hc,"../assets/plan-templates"),co(process.cwd(),"assets/plan-templates")];for(let t of e)if(tg(t))return t;return null}function yc(){if(At)return At;let e=ag();if(!e)return At=[],At;let t=[],n=[];try{n=eg(e)}catch{return At=[],At}for(let s of n)if(s.endsWith(".md"))try{let o=Qf(co(e,s),"utf-8"),i=rg(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),At=t,At}function bc(e){return yc().find(t=>t.id===e)??null}function Sc(){return yc().map(({id:e,label:t,description:n,icon:s,order:o})=>({id:e,label:t,description:n,icon:s,order:o}))}var ug="plan.md";function wc(e){return vc(e,".vibespot",ug)}function uo(e){let t=C();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=ye();n&&(n.plan=e);try{let s=vc(t.themePath,".vibespot");xc(s)||lg(s,{recursive:!0}),cg(wc(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 Qi(){let e=C();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=ye();t&&delete t.plan;try{let n=wc(e.themePath);xc(n)&&dg(n)}catch(n){E.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}J()}function Cc(e,t){Oe(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}uo(o),p(t,200,{ok:!0,plan:o})})}function kc(e,t){Oe(e,t,()=>{Qi(),V({planMode:!1}),p(t,200,{ok:!0})})}function Ac(e,t){p(t,200,{templates:Sc()})}function Tc(e,t){Oe(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=bc(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}uo(i.body),V({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}g();var er=/```vibespot-plan\s*\n([\s\S]*?)```/g,tr=/```vibespot-choices\s*\n([\s\S]*?)```/g;function $c(e){let t,n,s;for(er.lastIndex=0;(s=er.exec(e))!==null;)t=s[1].trim();let o;for(tr.lastIndex=0;(o=tr.exec(e))!==null;)try{let r=JSON.parse(o[1].trim());r&&typeof r.question=="string"&&Array.isArray(r.options)&&r.options.every(a=>typeof a=="string")&&r.options.length>0&&(n={question:r.question,options:r.options})}catch{}return{cleanedContent:e.replace(er,"").replace(tr,"").replace(/\n{3,}/g,`
1777
1787
 
1778
- `).trim(),plan:t,choices:n}}Q();f();import{spawn as hi}from"child_process";var gt=new Map;function yl(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+=`
1788
+ `).trim(),plan:t,choices:n}}X();g();import{spawn as nr}from"child_process";var Tt=new Map;function Ic(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+=`
1779
1789
  Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
1780
- Process timed out`,t.completedAt=Date.now())},n||3e5)}function In(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};gt.set(o,i);let a=hi(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&a.stdin&&(a.stdin.write(s.stdin),a.stdin.end()),yl(a,i,s?.timeout),o}function $t(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};gt.set(s,o);let i=e.split(" "),a=hi(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return yl(a,o,n?.timeout),s}function Os(e){return gt.get(e)}function Gm(){let e=Date.now()-18e5;for(let[t,n]of gt)n.completedAt&&n.completedAt<e&&gt.delete(t)}setInterval(Gm,600*1e3);function Rs(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};gt.set(s,o);let i=e.split(" "),a=hi(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),r=c=>{for(let d of o.listeners)try{d(c)}catch{}};a.stdout?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.stderr?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),a.on("error",c=>{o.status="failed",o.output+=`
1781
- Process error: ${c.message}`,o.completedAt=Date.now(),o.listeners.clear()});let l=n?.timeout||3e5;return setTimeout(()=>{o.status==="running"&&(a.kill(),o.status="failed",o.output+=`
1782
- Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function bl(e,t){let n=gt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Sl(e,t){let n=gt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}Fe();te();f();Fe();Q();Qn();es();bt();pe();Tn();import{existsSync as Kt,readdirSync as xl,rmSync as Wm}from"fs";import{join as zt,basename as Vm}from"path";import{homedir as Km}from"os";import{execFileSync as vl}from"child_process";Q();te();var wl=process.platform==="win32"?{shell:!0}:{},Je=zt(Km(),"vibespot-themes"),Fs=null,zm=5e3;function Js(){if(Fs&&Date.now()-Fs.ts<zm)return Fs.data;let e=[];if(Kt(Je))try{for(let t of xl(Je,{withFileTypes:!0}))if(t.isDirectory()){let n=zt(Je,t.name,"theme.json");if(Kt(n)){let s=0,o=zt(Je,t.name,"modules");if(Kt(o))try{s=xl(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return Fs={data:e,ts:Date.now()},e}function Cl(e){let t=v(),n=Vn(),s=!1;try{vl("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...wl}),s=!0}catch{}let o=Lt().sort((a,r)=>r.updatedAt-a.updatedAt).slice(0,10),i=Js();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i})}function kl(e,t){B(e,n=>{try{if(Wt()){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.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,""),i=zt(Je,o);Te(Je),Kt(i)&&Wm(i,{recursive:!0,force:!0}),cn(i,o),vt(i,o),j(),p(t,200,{ok:!0,themeName:o,themePath:i})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Al(e,t){B(e,n=>{try{if(Wt()){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=Se(),a=P(),r=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=zt(Je,r);Te(Je),a.hubspotUploadMode==="cli"||!i?(vl("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...wl}),vt(l,r),bn(l),j(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})):dn(i,o,l).then(()=>{vt(l,r),bn(l),j(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})}).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)})}})}function $l(e,t){B(e,n=>{try{if(Wt()){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(Kt(o)||(o=zt(Je,s)),!Kt(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Vm(o);vt(o,i),bn(o),j(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:v()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Tl(e,t){B(e,n=>{try{if(Wt()){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=ws(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 Il(e,t){B(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}W({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function El(e){let t=Se();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Ki(t);if(n.length===0){p(e,200,{themes:[]});return}let s=[],o=n.map(async r=>{let l=r.path||r.name;try{let c=await Yn(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:r.name,path:l})}catch{}});await Promise.all(o),s.sort((r,l)=>r.name.localeCompare(l.name));let i=Js(),a=new Set(i.map(r=>r.name));p(e,200,{themes:s.map(r=>({...r,existsLocally:a.has(r.name)}))})})().catch(n=>{p(e,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}f();Fe();Q();pe();import{existsSync as Ym,readFileSync as qm,appendFileSync as Xm}from"fs";import{join as _l}from"path";import{homedir as Nl}from"os";bt();te();var En={data:{},ts:0},Zm=600*1e3,Pl={"claude-code":[{id:"sonnet",label:"Claude Sonnet (default)"},{id:"opus",label:"Claude Opus"},{id:"haiku",label:"Claude Haiku"}],"codex-cli":[{id:"o4-mini",label:"o4 Mini (default)"},{id:"o3",label:"o3"},{id:"gpt-4o",label:"GPT-4o"}]};async function Qm(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 ep(e){let t=await fetch("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});if(!t.ok)return[];let n=await t.json(),s=/^(gpt-4o|gpt-4o-mini|o[1-4](-mini)?|o[1-4]-pro)$/;return n.data.filter(o=>s.test(o.id)).sort((o,i)=>o.id.localeCompare(i.id)).map(o=>({id:o.id,label:o.id}))}async function tp(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 np(){if(Date.now()-En.ts<Zm&&Object.keys(En.data).length>0)return En.data;let e=P(),t={...Pl},n=[],s=be("anthropic-api",e);s&&n.push(Qm(s).then(a=>{a.length&&(t["anthropic-api"]=a,t["claude-oauth"]=a)}).catch(()=>{}));let o=be("openai-api",e);o&&n.push(ep(o).then(a=>{a.length&&(t["openai-api"]=a)}).catch(()=>{}));let i=be("gemini-api",e);return i&&n.push(tp(i).then(a=>{a.length&&(t["gemini-api"]=a,t["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n),En.data=t,En.ts=Date.now(),t}function Ml(e){let t=Vn(),n=P(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(r=>({portalId:r.portalId,portalName:r.portalName,dataCenter:r.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=Lt().length,i=Js().length,a=Nt();np().then(r=>{p(e,200,{version:a,environment:t,config:s,models:r,sessionCount:o,localThemeCount:i})}).catch(()=>{p(e,200,{version:a,environment:t,config:s,models:Pl,sessionCount:o,localThemeCount:i})})}function Ol(e,t){B(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"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let a={aiEngine:s};if(o)switch(s){case"claude-code":a.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":a.anthropicApiModel=o;break;case"openai-api":a.openaiApiModel=o;break}W(a),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Rl(e,t){B(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"figma":l.figmaToken="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}W(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"figma":i.figmaToken=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}W(i);let a=null;if(!P().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(W({aiEngine:c}),a=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:a})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Fl(e,t){B(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 a=$t(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:a})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Jl(e,t){B(e,n=>{try{let s=JSON.parse(n||"{}"),o=P(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){zn(s.personalAccessKey).then(a=>{qt(s.personalAccessKey,a.portalId,a.portalName,a.dataCenter),p(t,200,{ok:!0,portalName:a.portalName,portalId:a.portalId,dataCenter:a.dataCenter})}).catch(a=>{p(t,400,{error:a instanceof Error?a.message:String(a)})});return}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=In("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:r});return}if(i==="api"){let a=o.hubspotAccounts||[];if(a.length>0&&!s.force){let r=a.find(l=>l.portalId===o.activeHubSpotAccount)||a[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=Ue();if(r.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.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 jl(e,t){B(e,n=>{try{let s=JSON.parse(n||"{}");if(!io().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=ro();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let r=In("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:r});return}let a=$t("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:a,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Dl(e,t){B(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((P().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Zs(s),p(t,200,{ok:!0});return}if(s){Qs(s),p(t,200,{ok:!0});return}}else{if(!Be().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=In("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=In("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 Hl(e){let t=$t("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function Ll(e,t){B(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=$t("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=$t("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,W({openaiApiKey:i}),process.platform!=="win32"){let a=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(a){let r=`export OPENAI_API_KEY="${a}"`,l=process.env.SHELL?.includes("zsh")?_l(Nl(),".zshrc"):_l(Nl(),".bashrc");try{(Ym(l)?qm(l,"utf-8"):"").includes("OPENAI_API_KEY")||Xm(l,`
1790
+ Process timed out`,t.completedAt=Date.now())},n||3e5)}function Wn(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};Tt.set(o,i);let r=nr(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()),Ic(r,i,s?.timeout),o}function Jt(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};Tt.set(s,o);let i=e.split(" "),r=nr(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Ic(r,o,n?.timeout),s}function mo(e){return Tt.get(e)}function mg(){let e=Date.now()-18e5;for(let[t,n]of Tt)n.completedAt&&n.completedAt<e&&Tt.delete(t)}setInterval(mg,600*1e3);function po(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};Tt.set(s,o);let i=e.split(" "),r=nr(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+=`
1791
+ 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+=`
1792
+ Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Ec(e,t){let n=Tt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Mc(e,t){let n=Tt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}Fe();Q();g();Fe();X();xs();vs();Rt();me();cn();import{existsSync as un,readdirSync as Dc,rmSync as Mg,writeFileSync as Lt,mkdirSync as xo}from"fs";import{join as xe,basename as Rg}from"path";import{homedir as _g}from"os";import{execFileSync as Lc}from"child_process";X();Q();g();import{readFileSync as pg,readdirSync as fg,existsSync as gg}from"fs";import{dirname as hg,join as fo}from"path";import{fileURLToPath as yg}from"url";var Rc=hg(yg(import.meta.url)),dn=null;function bg(){let e=[fo(Rc,"../../starters"),fo(Rc,"../starters"),fo(process.cwd(),"starters")];for(let t of e)if(gg(t))return t;return null}function _c(){if(dn!==null)return dn;let e=bg();if(!e)return dn=[],dn;let t=[];for(let n of fg(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(pg(fo(e,n),"utf-8"));t.push({id:s.id,name:s.name,description:s.description,category:s.category||"General",modules:s.modules||[],moduleOrder:s.moduleOrder||[],sharedCss:s.sharedCss||"",sharedJs:s.sharedJs||""})}catch{}return dn=t,dn}function Pc(){return _c().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,moduleCount:e.modules.length}))}function sr(e){return _c().find(t=>t.id===e)||null}g();Q();X();re();import{join as Fc}from"path";function Tg(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function $g(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=Fc(e.themePath,".vibespot");Ae(o),L(Fc(o,s),n)}async function jc(e,t){let n=Tg(e),s={attempted:[],extracted:[],skipped:[],errors:[]};if(n.length===0)return s;let o=Ig(t)?t:{...await Eg(e),...t??{}};n.includes("styleguide")&&await lr(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 lr(e,"brandvoice",s,()=>o.extractBrandvoice(e,r)),n.includes("themeContext")&&await lr(e,"themeContext",s,()=>o.extractThemeContext(e,r)),s}async function lr(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}$g(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 Ig(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function Eg(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(Kn(),zn)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(Fn(),Qs)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(cn(),Zi)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(ar(),rr)),{extractThemeContext:i}=await Promise.resolve().then(()=>(So(),bo)),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 Hc=process.platform==="win32"?{shell:!0}:{},We=xe(_g(),"vibespot-themes"),vo=null,Pg=5e3;function wo(){if(vo&&Date.now()-vo.ts<Pg)return vo.data;let e=[];if(un(We))try{for(let t of Dc(We,{withFileTypes:!0}))if(t.isDirectory()){let n=xe(We,t.name,"theme.json");if(un(n)){let s=0,o=xe(We,t.name,"modules");if(un(o))try{s=Dc(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return vo={data:e,ts:Date.now()},e}function Bc(e){let t=C(),n=ps(),s=!1;try{Lc("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Hc}),s=!0}catch{}let o=nn().sort((r,a)=>a.updatedAt-r.updatedAt).slice(0,10),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})}function Uc(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}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let i=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,""),r=xe(We,i);if(Ae(We),un(r)&&Mg(r,{recursive:!0,force:!0}),o&&typeof o=="string"&&!sr(o)){p(t,400,{error:`Starter template "${o}" not found`});return}Tn(r,i),tn(r,i),o&&typeof o=="string"&&Ng(r,i,o),J(),p(t,200,{ok:!0,themeName:i,themePath:r,starterId:o||void 0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Ng(e,t,n){let s=sr(n);if(!s)return;let o=C();if(!o)return;let i=s.modules.map(d=>({...d})),r=[...s.moduleOrder],a=`lp-${t}`,l={id:a,label:`${s.name}`,pageType:"landing_page",templateFile:`templates/${a}.html`,modules:i,moduleOrder:r,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};o.templates=[l],o.activeTemplateId=a,o.modules=i,o.moduleOrder=r,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let c=xe(e,"modules");xo(c,{recursive:!0});for(let d of s.modules){let u=xe(c,`${d.moduleName}.module`);xo(u,{recursive:!0}),Lt(xe(u,"fields.json"),d.fieldsJson,"utf-8"),Lt(xe(u,"meta.json"),d.metaJson,"utf-8"),Lt(xe(u,"module.html"),d.moduleHtml,"utf-8"),Lt(xe(u,"module.css"),d.moduleCss,"utf-8"),d.moduleJs&&Lt(xe(u,"module.js"),d.moduleJs,"utf-8")}if(s.sharedCss){let d=xe(e,"css");xo(d,{recursive:!0}),Lt(xe(d,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let d=xe(e,"js");xo(d,{recursive:!0}),Lt(xe(d,`${t}-animations.js`),s.sharedJs,"utf-8")}}function Gc(e){p(e,200,{starters:Pc()})}function Wc(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=$e(),r=R(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=xe(We,a);Ae(We),r.hubspotUploadMode==="cli"||!i?(async()=>{Lc("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Hc});let c=await Jc(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)})}):$n(i,o,l).then(async()=>{let c=await Jc(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 Jc(e,t){tn(e,t,{isImported:!0}),Xs(e),J();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await jc(n),J()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function Vc(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(un(o)||(o=xe(We,s)),!un(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Rg(o);tn(o,i),Xs(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 zc(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=Ws(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 Kc(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}V({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Yc(e){let t=$e();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Vr(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 hs(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)})})}g();Fe();X();me();import{existsSync as Og,readFileSync as Fg,appendFileSync as jg}from"fs";import{join as qc}from"path";import{homedir as Xc}from"os";Rt();Q();var Yn={data:{},ts:0},Dg=600*1e3,Qc={"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"}]},ed=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,Jg=ed;function Lg(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 Hg(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 Bg(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 Zc(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:Lg(n)}))}async function Ug(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 Gg(){if(Date.now()-Yn.ts<Dg&&Object.keys(Yn.data).length>0)return Yn.data;let e=R(),t={...Qc},n=[],s=Te("anthropic-api",e);s&&n.push(Hg(s).then(r=>{r.length&&(t["anthropic-api"]=r,t["claude-oauth"]=r)}).catch(()=>{}));let o=Te("openai-api",e);o&&n.push(Bg(o).then(r=>{if(!r.length)return;let a=Zc(r,ed);a.length&&(t["openai-api"]=a);let l=Zc(r,Jg);l.length&&(t["codex-cli"]=l)}).catch(()=>{}));let i=Te("gemini-api",e);return i&&n.push(Ug(i).then(r=>{r.length&&(t["gemini-api"]=r,t["gemini-cli"]=r)}).catch(()=>{})),await Promise.all(n),Yn.data=t,Yn.ts=Date.now(),t}function td(e){let t=ps(),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,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=nn().length,i=wo().length,r=Vt();Gg().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:Qc,sessionCount:o,localThemeCount:i})})}function nd(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"].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}V(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function sd(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"figma":l.figmaToken="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}V(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"figma":i.figmaToken=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}V(i);let r=null;if(!R().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(V({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 od(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=Jt(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 id(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}"),o=R(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){gs(s.personalAccessKey).then(r=>{fn(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(!qe().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=Wn("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(!qe().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=Xe();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 rd(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}");if(!Wo().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=Vo();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=Wn("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=Jt("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 ad(e,t){W(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((R().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Do(s),p(t,200,{ok:!0});return}if(s){Jo(s),p(t,200,{ok:!0});return}}else{if(!qe().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=Wn("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=Wn("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 ld(e){let t=Jt("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function cd(e,t){W(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=Jt("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=Jt("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,V({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")?qc(Xc(),".zshrc"):qc(Xc(),".bashrc");try{(Og(l)?Fg(l,"utf-8"):"").includes("OPENAI_API_KEY")||jg(l,`
1783
1793
  # Added by vibeSpot
1784
- ${r}
1785
- `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=$t("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 Bl(e,t){B(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}W({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ul(e,t){B(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}eo(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 Gl(e,t){B(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}let i={};for(let a of o)a in s&&(i[a]=s[a]);if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}W(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Wl(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=Os(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})}f();Fe();Q();tt();function Vl(e,t){B(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}to(s.trim(),(o||"").trim());let i=P();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&W({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Kl(e,t){let n=Le(),s=Qt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function zl(e,t){try{Ln(),P().aiEngine==="claude-oauth"&&W({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}f();Fe();pe();import{existsSync as sp,rmSync as op}from"fs";import{join as ip}from"path";function Yl(e,t,n){if(e==="GET"){let s=v(),o=Lt().sort((i,a)=>a.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName}:null,sessions:o});return}if(e==="DELETE"){B(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Yr(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 ql(e,t){B(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=ws(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 Xl(e,t){B(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=ip(Je,s);if(!sp(o)){p(t,404,{error:"Theme not found on disk"});return}op(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Zl(e,t){B(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 a=qr(s,i);a.ok?p(t,200,{ok:!0,newName:i}):p(t,400,{error:a.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}f();Fe();ie();Q();pe();te();import{existsSync as Us,readFileSync as pp,rmSync as vi}from"fs";import{join as Ze,basename as gp}from"path";import{execFileSync as fp}from"child_process";var hp=process.platform==="win32"?{shell:!0}:{};function ic(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}let n=at();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.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}})}function rc(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!Us(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=Ze(n,".."),i=gp(n);try{let a=`${s}.zip`,r=Ze(o,a);Us(r)&&vi(r),fp("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...hp});let l=pp(r);vi(r),e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${a}"`,"Content-Length":l.length}),e.end(l)}catch(a){A.error("download-zip","Failed to create zip archive",a),p(e,500,{error:"Failed to create zip archive"})}}function ac(e,t,n){let s=v();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.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){B(t,o=>{try{let{pageType:i,label:a}=JSON.parse(o);if(!i||!a){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=bs(i,a);j(),p(n,200,{ok:!0,template:{id:l.id,label:l.label,pageType:l.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){B(t,o=>{try{let{templateId:i,deleteModules:a}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Kr(i,!!a)){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 lc(e,t){B(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!Ao(s)){p(t,404,{error:"Template not found"});return}j();let i=v();p(t,200,{ok:!0,modules:X().map(a=>a.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function cc(e,t){B(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(!Vr(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 dc(e,t){B(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=Wr(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 uc(e){let t=at();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function mc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}B(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let r=at().find(d=>d.module.moduleName===i);if(!r){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...r.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 pc(e,t,n){let s=v();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"){B(t,o=>{try{let{type:i,content:a}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=a==="on",s.updatedAt=Date.now(),j(),p(n,200,{ok:!0});return}if(!a){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 r=i,l=r==="themeContext"?"theme-context.md":`${r}.md`;s.brandAssets[r]=a,s.updatedAt=Date.now();let c=Ze(s.themePath,".vibespot");Te(c),G(Ze(c,l),a),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){B(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 a=i;s.brandAssets&&delete s.brandAssets[a],s.updatedAt=Date.now();let r=a==="themeContext"?"theme-context.md":`${a}.md`,l=Ze(s.themePath,".vibespot",r);Us(l)&&vi(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 sc(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=Ze(e.themePath,".vibespot");Te(o),G(Ze(o,s),n)}async function oc(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Bs(),Ls));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Tn(),dl)),{loadConfig:o}=await Promise.resolve().then(()=>(Q(),ji)),i=o(),{engine:a,apiKey:r,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ks(),jo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(nc(),tc));return m(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(xi(),Si));return u(d,e.brandAssets?.themeContext,a,r,l)}function gc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",a=o.sourcePath;if(i==="all"){let l=["styleguide","brandvoice","themeContext"],c=await Promise.allSettled(l.map(u=>oc(n,u,a))),d={};for(let u=0;u<l.length;u++){let m=c[u],g=m.status==="fulfilled"?m.value:null;g&&sc(n,l[u],g),d[l[u]]=g}j(),p(t,200,{ok:!0,type:"all",extracted:d});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let r=await oc(n,i,a);if(!r){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}sc(n,i,r),j(),p(t,200,{ok:!0,type:i,content:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function fc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:a}=JSON.parse(s),r;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Se();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"),h=Ze(y(),"vibespot-themes",".references",g);Te(h);let{fetchTheme:b}=await Promise.resolve().then(()=>(es(),er));await b(u,m,h),r=h}else if(o==="local"){if(!a){p(t,400,{error:"localPath is required for local import"});return}if(!Us(a)){p(t,400,{error:`Path not found: ${a}`});return}r=a}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(Bs(),Ls)),c=await l(r);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ze(n.themePath,".vibespot");Te(d),G(Ze(d,"styleguide.md"),c),j(),p(t,200,{ok:!0,styleguide:c,source:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}f();Fe();pe();import{join as yp}from"path";jt();function hc(e,t){let n=v();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 yc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=X();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"){Ye(t,n,o=>{o.deleteEntirely?Hr(o.moduleName):Lr(o.moduleName),j(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function bc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(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=xe();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),j(),_e(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:a,content:r}=o;if(!i||!a){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(a){case"html":l.moduleHtml=r;break;case"css":l.moduleCss=r;break;case"js":l.moduleJs=r||void 0;break;case"fields":try{JSON.parse(r)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=r;break;default:p(t,400,{error:`Invalid fileType: ${a}`});return}n.updatedAt=Date.now(),j(),_e(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function Sc(e,t){Ye(e,t,n=>{Array.isArray(n.order)?(Ke(n.order),j(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function xc(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}try{_e();let n=us(t.themePath),s=Rs(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:yp(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function vc(e,t){B(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Br(s,o,i),j(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function wc(e,t){B(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=Xi(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
1786
- `),a={sourceDir:o.sourceDir,componentCount:o.components.length,components:o.components.map(r=>({name:r.name,description:r.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.
1794
+ ${a}
1795
+ `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=Jt("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 dd(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}V({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function ud(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}Lo(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 md(e,t){W(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}V(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function pd(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=mo(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})}g();Fe();X();lt();function fd(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}Ho(s.trim(),(o||"").trim());let i=R();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&V({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function gd(e,t){let n=Ye(),s=yn();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function hd(e,t){try{ls(),R().aiEngine==="claude-oauth"&&V({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}g();Fe();me();import{existsSync as Wg,rmSync as Vg}from"fs";import{join as zg}from"path";function yd(e,t,n){if(e==="GET"){let s=C(),o=nn().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);Ya(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 bd(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=Ws(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 Sd(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}let o=zg(We,s);if(!Wg(o)){p(t,404,{error:"Theme not found on disk"});return}Vg(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function xd(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=qa(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)})}})}g();Fe();re();X();me();Q();import{existsSync as Co,readFileSync as Kg,rmSync as cr}from"fs";import{join as ot,basename as Yg}from"path";import{execFileSync as qg}from"child_process";var Xg=process.platform==="win32"?{shell:!0}:{};function Cd(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=ft();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType: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}})}function kd(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!Co(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=ot(n,".."),i=Yg(n);try{let r=`${s}.zip`,a=ot(o,r);Co(a)&&cr(a),qg("zip",["-r",r,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...Xg});let l=Kg(a);cr(a),e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${r}"`,"Content-Length":l.length}),e.end(l)}catch(r){E.error("download-zip","Failed to create zip archive",r),p(e,500,{error:"Failed to create zip archive"})}}function Ad(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.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"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=Hs(i,r);J(),p(n,200,{ok:!0,template:{id:l.id,label:l.label,pageType:l.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(!za(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 Td(e,t){W(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!li(s)){p(t,404,{error:"Template not found"});return}J();let i=C();p(t,200,{ok:!0,modules:ce().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function $d(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(!Va(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 Id(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=Wa(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 Ed(e){let t=ft();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Md(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=ft().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 Rd(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=ot(s.themePath,".vibespot");Ae(c),L(ot(c,l),r),J(),p(n,200,{ok:!0})}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=ot(s.themePath,".vibespot",a);Co(l)&&cr(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 vd(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=ot(e.themePath,".vibespot");Ae(o),L(ot(o,s),n)}async function wd(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Kn(),zn));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(cn(),Zi)),{loadConfig:o}=await Promise.resolve().then(()=>(X(),jr)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Fn(),Qs)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(ar(),rr));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(So(),bo));return u(d,e.brandAssets?.themeContext,r,a,l)}function _d(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 l=["styleguide","brandvoice","themeContext"],c=await Promise.allSettled(l.map(u=>wd(n,u,r))),d={};for(let u=0;u<l.length;u++){let m=c[u],f=m.status==="fulfilled"?m.value:null;f&&vd(n,l[u],f),d[l[u]]=f}J(),p(t,200,{ok:!0,type:"all",extracted:d});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let a=await wd(n,i,r);if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}vd(n,i,a),J(),p(t,200,{ok:!0,type:i,content:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function Pd(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=$e();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 f=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:y}=await import("os"),h=ot(y(),"vibespot-themes",".references",f);Ae(h);let{fetchTheme:S}=await Promise.resolve().then(()=>(vs(),Qr));await S(u,m,h),a=h}else if(o==="local"){if(!r){p(t,400,{error:"localPath is required for local import"});return}if(!Co(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(()=>(Kn(),zn)),c=await l(a);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=ot(n.themePath,".vibespot");Ae(d),L(ot(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)})}})()})}g();Fe();me();import{join as Zg}from"path";Zt();function Nd(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 Od(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=ce();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"){Oe(t,n,o=>{o.deleteEntirely?La(o.moduleName):Ha(o.moduleName),J(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function Fd(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=ye();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),Ue(),J(),we(),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(),Ue(),J(),we(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function jd(e,t){Oe(e,t,n=>{Array.isArray(n.order)?(wt(n.order),J(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function Dd(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}try{we();let n=_s(t.themePath),s=po(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:Zg(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function Jd(e,t){W(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Ba(s,o,i),J(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function Ld(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=qr(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
1796
+ `),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.
1787
1797
 
1788
1798
  Source analysis found ${o.components.length} components:
1789
1799
  ${i}
@@ -1792,11 +1802,14 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
1792
1802
  Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
1793
1803
  Interactions: ${o.interactions.join(", ")}
1794
1804
 
1795
- 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,a)}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Cc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}if(!Oe()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?Or(n.themePath,o,50):Mr(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function kc(e,t){B(e,n=>{try{let s=v();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(Re("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let a=s.templates.find(c=>c.id===i);if(!a){p(t,404,{error:"Template not found"});return}let r=a.moduleOrder.map(c=>`modules/${c}.module`);a.templateFile&&r.push(a.templateFile);let l=Fr(s.themePath,i,o,r);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}ea()}else{let a=Rr(s.themePath,o);if(!a.success){p(t,500,{error:a.error||"Rollback failed"});return}Qr()}j(),p(t,200,{ok:!0,modules:X().map(a=>a.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}Yo();Ti();var Bc={".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"};function Uc(e){let{port:t,uiDir:n}=e,s=Dp((i,a)=>Bp(i,a,n)),o=new Lp({server:s});return o.on("connection",i=>Gp(i)),new Promise((i,a)=>{s.on("error",r=>{r.code==="EADDRINUSE"?s.listen(t+1,()=>{i({port:t+1,close:()=>{s.close(),o.close()}})}):a(r)}),s.listen(t,()=>{i({port:t,close:()=>{s.close(),o.close()}})})})}function Bp(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.startsWith("/api/")){Up(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=Fo();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")||"",a=Jo(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(a||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){Wp(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";Hc(i,dt(n,"docs"),e,t);return}Hc(s.pathname,n,e,t)}function Up(e,t,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1)(:\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":hc(e,s);break;case"/api/modules":yc(e,n,s);break;case"/api/modules/reorder":Sc(n,s);break;case"/api/modules/code":bc(n,s);break;case"/api/upload":xc(s);break;case"/api/upload-files":e==="POST"?Ia(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":vc(n,s);break;case"/api/import":wc(n,s);break;case"/api/setup":Cl(s);break;case"/api/setup/create":kl(n,s);break;case"/api/setup/fetch":Al(n,s);break;case"/api/setup/open":$l(n,s);break;case"/api/setup/resume":Tl(n,s);break;case"/api/setup/apikey":Il(n,s);break;case"/api/setup/remote-themes":e==="GET"?El(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?Ml(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?Ol(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?Rl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Fl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?Jl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?jl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?Dl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Hl(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?Ll(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Bl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Ul(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Vl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Kl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?zl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Gl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Mi()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Yl(e,n,s);break;case"/api/themes/switch":e==="POST"?ql(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Xl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Zl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?Cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?kc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?ic(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":ac(e,n,s);break;case"/api/templates/activate":e==="POST"?lc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?dc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?uc(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":pc(e,n,s);break;case"/api/brand-assets/extract":e==="POST"?gc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?fc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?rc(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?ki(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?Ai(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?$i(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?gl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?fl(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?Wl(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?mc(t,n,s):p(s,404,{error:"Not found"})}}function Gp(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(di()){Re("user",o),j();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let r="",l=await ci(o,d=>{r+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=hl(l||r);c.plan&&(mi(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})),Re("assistant",c.cleanedContent),j(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}Re("user",o),j();let a=ui();a.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await Ms(o,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:m,...g}=u;e.send(JSON.stringify(g))}else e.send(JSON.stringify(u));if(u.type==="agent_step")l.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let m=l[l.length-1];m&&(m.decisions||(m.decisions=[]),m.decisions.push(u.decision))}else u.type==="design_system_ready"?oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),Ke(u.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(oe({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)})),c.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&c.push({name:u.module,status:"failed"})},i);At(d,{steps:l,modules:c,stats:d.stats})}else ai(l=>{e.send(JSON.stringify({type:"parse_warning",message:l}))}),await An(o,l=>{e.send(JSON.stringify({type:"stream",content:l}))},l=>{e.send(JSON.stringify({type:"stream_status",content:l}))},i);let r=v();if(r){_e();let l=xe(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${r.themeName}-theme.css`),l.sharedJs&&d.push(`js/${r.themeName}-animations.js`),c=bo(r.themePath,l.id,o,d)}else c=St(r.themePath,o);c&&e.send(JSON.stringify({type:"version_created",hash:c}))}e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(l=>l.moduleName)}));{let l=v();l&&a.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&e.send(JSON.stringify({type:"suggest_brand_extraction"}))}}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}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:a}=await Promise.resolve().then(()=>(Ti(),Dc)),r=a(o);if(!r){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=v();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:y}=await import("fs"),{createThemeScaffold:h}=await Promise.resolve().then(()=>(Qn(),Zi)),b=m(g(),"vibespot-themes"),x=m(b,i);if(!y(b)){let{mkdirSync:w}=await import("fs");w(b,{recursive:!0})}y(x)||h(x,i),vt(x,i),j()}e.send(JSON.stringify({type:"figma_import_started",fileName:r.fileName}));let c=[],d=[],u=await $n(r,i,m=>{if(m.type==="module_progress"&&m.moduleFiles){let{moduleFiles:g,...y}=m;e.send(JSON.stringify(y))}else e.send(JSON.stringify(m));if(m.type==="agent_step")c.push({step:m.step,label:m.label});else if(m.type==="agent_decision"){let g=c[c.length-1];g&&(g.decisions||(g.decisions=[]),g.decisions.push(m.decision))}else m.type==="design_system_ready"?oe({sharedCss:m.sharedCss,sharedJs:m.sharedJs}):m.type==="blueprint_ready"?(oe({sharedCss:m.sharedCss,sharedJs:m.sharedJs}),Ke(m.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(g=>g.moduleName)}))):m.type==="module_progress"&&m.status==="complete"&&m.moduleFiles?(oe({modules:[{moduleName:m.module,fieldsJson:m.moduleFiles.fieldsJson,metaJson:m.moduleFiles.metaJson,moduleHtml:m.moduleFiles.moduleHtml,moduleCss:m.moduleFiles.moduleCss,moduleJs:m.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(g=>g.moduleName)})),d.push({name:m.module,status:"complete"})):m.type==="module_progress"&&m.status==="failed"&&d.push({name:m.module,status:"failed"})});At(u,{steps:c,modules:d,stats:u.stats}),_e(),St(v().themePath,`Figma import: ${r.fileName}`),e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))}catch(l){e.send(JSON.stringify({type:"error",message:l instanceof Error?l.message:String(l)}))}break}case"extract_brand_assets":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=P(),{engine:a,apiKey:r,model:l}=Vt(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ks(),jo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(xi(),Si)),m=await u(d,o.brandAssets?.themeContext,a,r,l),{mkdirSync:g,writeFileSync:y}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let h=dt(o.themePath,".vibespot");Pn(h)||g(h,{recursive:!0}),y(dt(h,"theme-context.md"),m),j(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:h}=await Promise.resolve().then(()=>(Bs(),Ls)),b=await h(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let x=dt(o.themePath,".vibespot");Pn(x)||g(x,{recursive:!0}),y(dt(x,"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=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{_e();let i=us(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(P().hubspotUploadMode||"api")==="api"){let l=Se();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 ms(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
1805
+ 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 Hd(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}if(!Be()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?Na(n.themePath,o,50):Pa(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function Bd(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(Ge("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=Fa(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}rl()}else{let r=Oa(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}il()}J(),p(t,200,{ok:!0,modules:ce().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}Oi();gr();g();Fe();me();g();Q();import{readdirSync as br,statSync as xh}from"fs";import{join as K,relative as vh}from"path";var $t=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],wh=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],Ch=["enable_domain_stylesheets","is_available_for_new_content"],yt="marketplace.json";function mn(e){let t=K(e,yt);if(!b(t))return null;try{return JSON.parse(T(t))}catch{return null}}function Eo(e,t){let n=K(e,yt);L(n,JSON.stringify(t,null,2)+`
1806
+ `)}function Xn(e){let t=[];if(!b(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),hr(e,t,null);let n=yr(K(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."}),hr(e,t,mn(e));kh(e,n,t),Ah(e,n,t),Th(e,t),Ih(e,t),Eh(e,t),Mh(e,t);let s=mn(e);return Rh(s,t),hr(e,t,s)}function hr(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 kh(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 wh)it(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 Ch)(!(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.'}):(it(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."}),it(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."}),it(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=au(e,i);b(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 Ah(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=au(e,s);if(!b(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 Th(e,t){let n=K(e,"modules");if(!b(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=br(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=K(n,i);$h(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 $h(e,t,n,s){let o=yr(K(t,"meta.json")),i=Ve(e,K(t,"meta.json"));o?(it(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=K(t,"fields.json"),a=Ve(e,r);if(!b(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=yr(r);Array.isArray(c)?iu(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=K(t,"module.html");b(l)||s.push({severity:"error",rule:"module.html.missing",file:Ve(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function iu(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)";it(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}),!it(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)&&iu(i.children,t,n,s)}}function Ih(e,t){let n=[],s=K(e,"css");Io(s,".css").forEach(i=>{ou(i,n,e)});let o=K(e,"modules");if(b(o))for(let i of Zn(o)){if(!i.endsWith(".module"))continue;let r=K(o,i);["module.css","module.html"].forEach(a=>{let l=K(r,a);b(l)&&ou(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 ou(e,t,n){let s;try{s=T(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:Ve(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:Ve(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:Ve(n,e),match:r[0]})}function Eh(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=K(e,"css");Io(o,".css").forEach(a=>s.push(a));let i=K(e,"js");Io(i,".js").forEach(a=>s.push(a));let r=K(e,"modules");if(b(r))for(let a of Zn(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=K(r,a,l);b(c)&&s.push(c)});for(let a of s){let l;try{l=T(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:Ve(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function Mh(e,t){let n=K(e,"modules");if(b(n))for(let s of Zn(n)){if(!s.endsWith(".module"))continue;let o=K(n,s,"module.html");if(!b(o))continue;let i;try{i=T(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:Ve(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:Ve(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 Rh(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:yt,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?$t.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:yt,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${$t.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:yt,message:"marketplace.json has no category",fix:`Pick one of: ${$t.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:yt,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:yt,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:yt,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:yt,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function Mo(e){let t=[],n=[],s=K(e,"modules");if(b(s))for(let i of Zn(s)){if(!i.endsWith(".module"))continue;let r=K(s,i),a=i.replace(/\.module$/,""),l=K(r,"meta.json");if(b(l))try{let d=JSON.parse(T(l));it(d,"label")||(d.label=lu(a),L(l,JSON.stringify(d,null,2)+`
1807
+ `),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=K(r,"fields.json");if(b(c))try{let d=JSON.parse(T(c));if(Array.isArray(d)){let u=ru(d);u>0&&(L(c,JSON.stringify(d,null,2)+`
1808
+ `),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=_h(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function _h(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=T(c)}catch{return}let u=d.replace(n,"");u!==d&&(L(c,u),t.push(Ve(e,c)))}function a(c){let d;try{d=T(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(L(c,u),t.push(Ve(e,c)))}Io(K(e,"css"),".css").forEach(r);let l=K(e,"modules");if(b(l))for(let c of Zn(l)){if(!c.endsWith(".module"))continue;let d=K(l,c),u=K(d,"module.css"),m=K(d,"module.html");b(u)&&r(u),b(m)&&a(m)}return t}function ru(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!it(s,"label")&&it(s,"name")&&(s.label=lu(String(s.name)),t++),Array.isArray(s.children)&&(t+=ru(s.children))}return t}function yr(e){if(!b(e))return null;try{let t=JSON.parse(T(e));return t&&typeof t=="object"?t:null}catch{return null}}function it(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function au(e,t){let n=t.replace(/^\.?\//,"");return K(e,n)}function Ve(e,t){return vh(e,t).split("\\").join("/")}function Zn(e){try{return br(e)}catch{return[]}}function Io(e,t){if(!b(e))return[];try{let n=[];for(let s of br(e)){let o=K(e,s);xh(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function lu(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function Sr(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{we()}catch{}return t.themePath}function cu(e,t){let n=Sr(t);if(!n)return;let s=Xn(n);p(t,200,{report:s,categories:$t})}function du(e,t){let n=Sr(t);if(!n)return;let s=Mo(n),o=Xn(n);p(t,200,{fix:s,report:o})}function uu(e,t,n){let s=Sr(n);if(s){if(e==="GET"){p(n,200,{metadata:mn(s),categories:$t});return}if(e==="POST"){Oe(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};Eo(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}g();Fe();me();qs();function Ph(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{we()}catch{}return t.themePath}function mu(e,t){let n=Ph(t);if(!n)return;let s=Ks(n);p(t,200,{report:s})}function pu(e,t){let n=C();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=sn(n.themePath),o=_n(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=Ys(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 hu={".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"},_o=null,Po=[];function ve(e){_o&&_o.readyState===Fh.OPEN&&_o.send(JSON.stringify(e))}function Ro(e){Po.push(e),ve(e)}function bt(){Po=[]}function xr(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;Ro(o)}else Ro(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"?Ie({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(Ie({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),wt(n.moduleOrder),Ro({type:"modules_updated",modules:ce().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(Ie({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),Ro({type:"modules_updated",modules:ce().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 yu(e){let{port:t,uiDir:n}=e,s=Nh((i,r)=>jh(i,r,n)),o=new Oh({server:s});return o.on("connection",i=>Jh(i)),new Promise((i,r)=>{s.on("error",a=>{a.code==="EADDRINUSE"?s.listen(t+1,()=>{i({port:t+1,close:()=>{s.close(),o.close()}})}):r(a)}),s.listen(t,()=>{i({port:t,close:()=>{s.close(),o.close()}})})})}function jh(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.startsWith("/api/")){Dh(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=Ci();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=ki(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){Lh(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";fu(i,St(n,"docs"),e,t);return}fu(s.pathname,n,e,t)}function Dh(e,t,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1)(:\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":Nd(e,s);break;case"/api/modules":Od(e,n,s);break;case"/api/modules/reorder":jd(n,s);break;case"/api/modules/code":Fd(n,s);break;case"/api/upload":Dd(s);break;case"/api/upload-files":e==="POST"?Nl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":Jd(n,s);break;case"/api/import":Ld(n,s);break;case"/api/setup":Bc(s);break;case"/api/setup/create":Uc(n,s);break;case"/api/setup/fetch":Wc(n,s);break;case"/api/setup/open":Vc(n,s);break;case"/api/setup/resume":zc(n,s);break;case"/api/setup/apikey":Kc(n,s);break;case"/api/setup/remote-themes":e==="GET"?Yc(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?Gc(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?td(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?nd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?sd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?od(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?id(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?rd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?ad(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?ld(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?cd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?dd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?ud(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?fd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?gd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?hd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?md(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:_r()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":yd(e,n,s);break;case"/api/themes/switch":e==="POST"?bd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Sd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?xd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?Hd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?Bd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Cd(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Ad(e,n,s);break;case"/api/templates/activate":e==="POST"?Td(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?$d(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?Id(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?Ed(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":Rd(e,n,s);break;case"/api/brand-assets/extract":e==="POST"?_d(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?Pd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?kd(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?mr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?pr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?fr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?kc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Ac(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?Tc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?cu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?du(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":uu(e,n,s);break;case"/api/inverse/analyze":e==="GET"?mu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?pu(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?pd(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?Md(t,n,s):p(s,404,{error:"Not found"})}}function Jh(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(qi()){Ge("user",o),J();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await Yi(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=$c(l||a);c.plan&&(uo(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})),Ge("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}Ge("user",o),J();let r=Xi();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){bt();let l=[],c=[],d=await lo(o,xr(l,c),i);Dt(d,{steps:l,modules:c,stats:d.stats})}else zi(l=>{ve({type:"parse_warning",message:l})}),await Un(o,l=>{ve({type:"stream",content:l})},l=>{ve({type:"stream_status",content:l})},i);let a=C();if(a){we();let l=ye(),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=si(a.themePath,l.id,o,d)}else c=_t(a.themePath,o);c&&ve({type:"version_created",hash:c})}ve({type:"generation_complete"}),ve({type:"modules_updated",modules:ce().map(l=>l.moduleName)}),bt();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&ve({type:"suggest_brand_extraction"})}}catch(a){bt(),ve({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(()=>(gr(),su)),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:f}=await import("os"),{existsSync:y}=await import("fs"),{createThemeScaffold:h}=await Promise.resolve().then(()=>(xs(),Xr)),S=m(f(),"vibespot-themes"),x=m(S,i);if(!y(S)){let{mkdirSync:w}=await import("fs");w(S,{recursive:!0})}y(x)||h(x,i),tn(x,i),J()}ve({type:"figma_import_started",fileName:a.fileName}),bt();let c=[],d=[],u=await Gn(a,i,xr(c,d));Dt(u,{steps:c,modules:d,stats:u.stats}),we(),_t(C().themePath,`Figma import: ${a.fileName}`),ve({type:"generation_complete"}),ve({type:"modules_updated",modules:ce().map(m=>m.moduleName)}),bt()}catch(l){bt(),ve({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}=ln(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Fn(),Qs)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(So(),bo)),m=await u(d,o.brandAssets?.themeContext,r,a,l),{mkdirSync:f,writeFileSync:y}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let h=St(o.themePath,".vibespot");Qn(h)||f(h,{recursive:!0}),y(St(h,"theme-context.md"),m),J(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:h}=await Promise.resolve().then(()=>(Kn(),zn)),S=await h(o.themePath);if(S){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=S,o.updatedAt=Date.now();let x=St(o.themePath,".vibespot");Qn(x)||f(x,{recursive:!0}),y(St(x,"styleguide.md"),S),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{we();let i=_s(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(R().hubspotUploadMode||"api")==="api"){let l=$e();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 Ps(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
1796
1809
  `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
1797
1810
  `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
1798
- `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=ut();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName}))}else{let d=cs(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
1799
- `),errors:d}))}}else{let l=Rs(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:dt(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}))};bl(l,c);let d=setInterval(()=>{let u=Os(l);if(!(!u||u.status==="running"))if(clearInterval(d),Sl(l,c),u.status==="completed"){let m=Ue(),g=m.portalId?sn(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName}))}else{let m=ds(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.
1811
+ `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=xt();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName}))}else{let d=Ms(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
1812
+ `),errors:d}))}}else{let l=po(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:St(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}))};Ec(l,c);let d=setInterval(()=>{let u=mo(l);if(!(!u||u.status==="running"))if(clearInterval(d),Mc(l,c),u.status==="completed"){let m=Xe(),f=m.portalId?vn(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:f,themeName:o.themeName}))}else{let m=Rs(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.
1800
1813
 
1801
1814
  IMPORTANT: Be verbose in your response. For each error:
1802
1815
  1. State exactly which file has the problem and what the error is
@@ -1809,9 +1822,11 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
1809
1822
  After fixing all errors, summarize the changes you made.
1810
1823
 
1811
1824
  Upload log:
1812
- ${o}`;Re("user",i),j(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await An(i,r=>{e.send(JSON.stringify({type:"stream",content:r})),e.send(JSON.stringify({type:"upload_fix_stream",content:r}))});let a=v();if(a){_e();let r=St(a.themePath,"AI fix: upload errors");r&&e.send(JSON.stringify({type:"version_created",hash:r}))}e.send(JSON.stringify({type:"upload_fix_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(r=>r.moduleName)}))}catch(a){e.send(JSON.stringify({type:"upload_failed",output:a instanceof Error?a.message:String(a),errors:[{file:"AI fix",message:a instanceof Error?a.message:String(a),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=v();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}W({planMode:!1});let a="Implement the approved plan.";Re("user",a),j();try{let r=[],l=[],c=await Ms(a,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:m,...g}=u;e.send(JSON.stringify(g))}else e.send(JSON.stringify(u));if(u.type==="agent_step")r.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let m=r[r.length-1];m&&(m.decisions||(m.decisions=[]),m.decisions.push(u.decision))}else u.type==="design_system_ready"?oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),Ke(u.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(oe({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)})),l.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&l.push({name:u.module,status:"failed"})});At(c,{steps:r,modules:l,stats:c.stats});let d=v();if(d){_e();let u=xe(),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=bo(d.themePath,u.id,"Approved plan: implementation",g)}else m=St(d.themePath,"Approved plan: implementation");m&&e.send(JSON.stringify({type:"version_created",hash:m}))}e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(u=>u.moduleName)}))}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"plan_discard":{pi(),W({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}});let t=v();if(t){let n=P(),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=xe();e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:X().map(i=>i.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:Oe(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",templateId:o?.id||null,pageType:o?.pageType||null,templates:(t.templates||[]).map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||""}))}else e.send(JSON.stringify({type:"needs_setup"}))}function Wp(e,t){let n=v();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=dt(n.themePath,"assets",e);if(!Pn(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Lc(s),i=Bc[o]||"application/octet-stream",a=Ii(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(a)}function Hc(e,t,n,s){let i=dt(t,e==="/"?"/index.html":e);if(!Pn(i)){let c=dt(t,"index.html");if(Pn(c)){let d=Ii(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 a=Lc(i),r=Bc[a]||"application/octet-stream",l=a===".html";try{let c=Ii(i),d='"'+Hp("md5").update(c).digest("hex").slice(0,16)+'"';if(n.headers["if-none-match"]===d){s.writeHead(304),s.end();return}s.writeHead(200,{"Content-Type":r,"Cache-Control":"no-cache",ETag:d}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}pe();var Kp=4200;async function Gc(){let e=Ys.hex("#e8613a"),t=Ys.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
1813
- `));let n=zp();n||(console.error(Ys.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await Uc({port:Kp,uiDir:n}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Press Ctrl+C to stop
1814
- `));try{process.platform==="darwin"?Ei("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ei("cmd",["/c","start","",i],{stdio:"ignore"}):Ei("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
1815
- Saving session...`)),j(),o(),console.log(t(` Goodbye!
1816
- `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Ys.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function zp(){let e=[zs(import.meta.dirname,"../../ui"),zs(import.meta.dirname,"../ui"),zs(process.cwd(),"ui")];for(let t of e)if(Vp(zs(t,"index.html")))return t;return null}te();function Wc(){let e=new Yp;return e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Nt()).action(Gc),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Ar),e.command("init").description("Check and install required tools").action($r),e.command("convert").description("Convert a React project to HubSpot modules").action(Tr),e.command("upload").description("Upload theme to HubSpot").action(Ir),e.command("doctor").description("Diagnose environment issues").action(Er),e}var qp=Wc();qp.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
1825
+ ${o}`;Ge("user",i),J(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await Un(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){we();let a=_t(r.themePath,"AI fix: upload errors");a&&e.send(JSON.stringify({type:"version_created",hash:a}))}e.send(JSON.stringify({type:"upload_fix_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:ce().map(a=>a.moduleName)}))}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}V({planMode:!1});let r="Implement the approved plan.";Ge("user",r),J();try{bt();let a=[],l=[],c=await lo(r,xr(a,l));Dt(c,{steps:a,modules:l,stats:c.stats});let d=C();if(d){we();let u=ye(),m=null;if(u){let f=u.moduleOrder.map(y=>`modules/${y}.module`);u.templateFile&&f.push(u.templateFile),u.sharedCss&&f.push(`css/${d.themeName}-theme.css`),u.sharedJs&&f.push(`js/${d.themeName}-animations.js`),m=si(d.themePath,u.id,"Approved plan: implementation",f)}else m=_t(d.themePath,"Approved plan: implementation");m&&ve({type:"version_created",hash:m})}ve({type:"generation_complete"}),ve({type:"modules_updated",modules:ce().map(u=>u.moduleName)}),bt()}catch(a){bt(),ve({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{Qi(),V({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),_o=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=ye();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:ce().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:Be(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",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&&Po.length>0)for(let r of Po)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function Lh(e,t){let n=C();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=St(n.themePath,"assets",e);if(!Qn(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=gu(s),i=hu[o]||"application/octet-stream",r=vr(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function fu(e,t,n,s){let i=St(t,e==="/"?"/index.html":e);if(!Qn(i)){let c=St(t,"index.html");if(Qn(c)){let d=vr(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=gu(i),a=hu[r]||"application/octet-stream",l=r===".html";try{let c=vr(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")}}me();var bu=Hh(Uh(import.meta.url)),Gh=4200;async function Su(){let e=Oo.hex("#e8613a"),t=Oo.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
1826
+ `));let n=Wh();n||(console.error(Oo.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await yu({port:Gh,uiDir:n}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Press Ctrl+C to stop
1827
+ `));try{process.platform==="darwin"?wr("open",[i],{stdio:"ignore"}):process.platform==="win32"?wr("cmd",["/c","start","",i],{stdio:"ignore"}):wr("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
1828
+ Saving session...`)),J(),o(),console.log(t(` Goodbye!
1829
+ `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Oo.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Wh(){let e=[No(bu,"../../ui"),No(bu,"../ui"),No(process.cwd(),"ui")];for(let t of e)if(Bh(No(t,"index.html")))return t;return null}g();import{resolve as xu}from"path";import{existsSync as Cr}from"fs";X();async function vu(e={}){let t=await Cu(e.path);if(e.fix){let o=Mo(t);if(o.applied.length>0){H(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)P(` ${i}`)}else P(A.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)Z(i)}let n=Xn(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
1830
+ `),n.passed||process.exit(1);return}pe(),await se("Marketplace check");let s=`${n.errorCount} error${Ar(n.errorCount)}, ${n.warningCount} warning${Ar(n.warningCount)}, ${n.infoCount} note${Ar(n.infoCount)}`;n.passed?H(`Theme passes Marketplace checks (${s}).`):z(`Theme is not yet ready: ${s}.`),kr("Errors",n.findings.filter(o=>o.severity==="error")),kr("Warnings",n.findings.filter(o=>o.severity==="warning")),kr("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(P(""),P(`Tip: run ${A.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await oe("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function wu(e={}){let t=await Cu(e.path);pe(),await se("Marketplace listing details");let n=mn(t)??{},s=await dt({message:"Category",options:$t.map(u=>({value:u,label:u}))}),o=await le({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 le({message:"Key features (comma-separated, 2\u20135 items)",placeholder:"Hero, Pricing, Testimonials, Footer",defaultValue:(n.features??[]).join(", "),validate:u=>{let m=u.split(",").map(f=>f.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 le({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 le({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 dt({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};Eo(t,d),H("Saved marketplace.json"),await oe(`Run ${A.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function Cu(e){if(e){let o=xu(e);if(!Cr(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&Cr(t.lastThemePath))return t.lastThemePath;pe();let n=await le({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=xu(n);if(!Cr(s))throw new Error(`Theme not found: ${s}`);return s}function kr(e,t){if(t.length!==0){P(""),P(A.heading(e));for(let n of t){let s=n.file?A.muted(`[${n.file}] `):"",o=n.severity==="error"?A.error("\u2717"):n.severity==="warning"?A.warn("!"):A.muted("\xB7");P(` ${o} ${s}${n.message}`),n.fix&&P(` ${A.muted("\u2192 "+n.fix)}`)}}}function Ar(e){return e===1?"":"s"}g();import{resolve as ku}from"path";import{existsSync as Tr}from"fs";import{basename as Vh}from"path";X();qs();async function Au(e={}){let t=await zh(e.path),n=Vh(t);if(e.applyTokens){let i=Ys(t,n);i?H(`Wrote design tokens to ${i}`):P(A.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=gi(t);e.json||H(`Wrote imported theme snapshot to ${i}`)}let s=Ks(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
1831
+ `),process.exit(0)),pe(),await se("Inverse pipeline analyzer");let o=s.summary;if(P(`${A.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){P(""),P(A.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?A.muted(` (${i.varName})`):"";P(` ${i.value} ${A.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){P(""),P(A.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))P(` ${i}`)}if(s.graph.templates.length>0){P(""),P(A.heading("Template \u2192 modules"));for(let i of s.graph.templates)P(` ${i.id}: ${i.modules.length===0?A.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){P(""),P(A.heading("Orphan modules"));for(let i of s.graph.orphanModules)P(` ${i}`)}if(s.roundTripDiff.hasSnapshot){P(""),P(A.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)P(` ${A.muted("No changes from imported snapshot.")}`);else{P(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))P(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&P(` ${A.muted(`...and ${i.files.length-12} more`)}`)}}$r("Errors",s.findings.filter(i=>i.severity==="error")),$r("Warnings",s.findings.filter(i=>i.severity==="warning")),$r("Notes",s.findings.filter(i=>i.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(P(""),P(`Tip: run ${A.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await oe("Analysis complete."),process.exit(0)}async function zh(e){if(e){let o=ku(e);if(!Tr(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&Tr(t.lastThemePath))return t.lastThemePath;pe();let n=await le({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=ku(n);if(!Tr(s))throw new Error(`Theme not found: ${s}`);return s}function $r(e,t){if(t.length!==0){P(""),P(A.heading(e));for(let n of t){let s=n.file?A.muted(`[${n.file}] `):"",o=n.severity==="error"?A.error("\u2717"):n.severity==="warning"?A.warn("!"):A.muted("\xB7");P(` ${o} ${s}${n.message}`),n.fix&&P(` ${A.muted("\u2192 "+n.fix)}`)}}}Q();function Tu(){let e=new Kh;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Vt()).action(Su),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(ka),e.command("init").description("Check and install required tools").action(Aa),e.command("convert").description("Convert a React project to HubSpot modules").action(Ta),e.command("upload").description("Upload theme to HubSpot").action($a),e.command("doctor").description("Diagnose environment issues").action(Ia);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=>vu(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>wu(n)),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=>Au(n)),e}var Yh=Tu();Yh.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
1817
1832
  //# sourceMappingURL=index.js.map