vibespot 1.0.4 → 1.0.6

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 al=Object.defineProperty;var J=(t,e)=>()=>(t&&(e=t(t=0)),e);var lt=(t,e)=>{for(var n in e)al(t,n,{get:e[n],enumerable:!0})};import Au from"path";import{fileURLToPath as ku}from"url";var g=J(()=>{"use strict"});import{readFileSync as ys,writeFileSync as ll,mkdirSync as $o,existsSync as mn}from"fs";import{dirname as cl,join as We}from"path";function I(t){return ys(t,"utf-8")}function H(t,e){$o(cl(t),{recursive:!0}),ll(t,e,"utf-8")}function S(t){return mn(t)}function Ae(t){$o(t,{recursive:!0})}function pn(t){let e=[We(import.meta.dirname,"../../assets",t),We(import.meta.dirname,"../assets",t),We(process.cwd(),"assets",t)];for(let n of e)if(mn(n))return n;throw new Error(`Asset not found: ${t}`)}function St(){if(bt)return bt;let t=[We(import.meta.dirname,"../../package.json"),We(import.meta.dirname,"../package.json"),We(process.cwd(),"package.json")];for(let e of t)if(mn(e))try{let n=JSON.parse(ys(e,"utf-8"));if(n.name==="vibespot"&&n.version)return bt=n.version,bt}catch{}return bt="dev",bt}function To(){if(un)return un;let t=[We(import.meta.dirname,"../../CHANGELOG.md"),We(import.meta.dirname,"../CHANGELOG.md"),We(process.cwd(),"CHANGELOG.md")];for(let e of t)if(mn(e))try{return un=ys(e,"utf-8"),un}catch{}return""}var bt,un,Z=J(()=>{"use strict";g();bt="";un=""});import{execSync as Eo}from"child_process";function T(t,e={}){try{return{stdout:Eo(t,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...e}).trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function No(t,e={}){try{return Eo(t,{stdio:"inherit",timeout:3e5,...e}),!0}catch{return!1}}var ct=J(()=>{"use strict";g()});var _o={};lt(_o,{addHubSpotAccount:()=>Ot,getActiveHubSpotAccount:()=>Xe,getApiKeyForEngine:()=>ge,getConfigDir:()=>ml,getHubSpotPak:()=>he,isCliToolEnabled:()=>jt,loadConfig:()=>P,maskApiKey:()=>gn,removeHubSpotAccount:()=>bs,saveConfig:()=>q,setActiveHubSpotAccount:()=>Ss,setCliToolEnabled:()=>vs});import{join as Po}from"path";import{homedir as dl}from"os";import{chmodSync as ul}from"fs";function P(){if(!S(fn))return{};try{let t=JSON.parse(I(fn));return t.aiEngine==="api"&&(t.aiEngine="anthropic-api"),t}catch{return{}}}function ge(t,e){let n=e||P();switch(t){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;default:return}}function gn(t){return t.length<=12?"***":t.slice(0,7)+"..."+t.slice(-4)}function q(t){let n={...P(),...t};if(H(fn,JSON.stringify(n,null,2)),process.platform!=="win32")try{ul(fn,384)}catch{}}function ml(){return Mo}function Xe(){let t=P();if(!t.hubspotAccounts?.length)return null;let e=t.activeHubSpotAccount;if(e){let n=t.hubspotAccounts.find(s=>s.portalId===e);if(n)return n}return t.hubspotAccounts[0]||null}function Ot(t,e,n,s){let i=P().hubspotAccounts||[],a=i.findIndex(l=>l.portalId===e),r={portalId:e,portalName:n,personalAccessKey:t,dataCenter:s,addedAt:new Date().toISOString()};a>=0?i[a]=r:i.push(r),q({hubspotAccounts:i,activeHubSpotAccount:e})}function bs(t){let e=P(),n=(e.hubspotAccounts||[]).filter(o=>o.portalId!==t),s={hubspotAccounts:n};e.activeHubSpotAccount===t&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),q(s)}function Ss(t){q({activeHubSpotAccount:t})}function he(){return Xe()?.personalAccessKey||null}function jt(t){return P().enabledCLITools?.includes(t)??!1}function vs(t,e){let n=P(),s=new Set(n.enabledCLITools||[]);e?s.add(t):s.delete(t),q({enabledCLITools:[...s]})}var Mo,fn,ee=J(()=>{"use strict";g();Z();Mo=Po(dl(),".vibespot"),fn=Po(Mo,"config.json")});import{readFileSync as gl}from"fs";import{basename as hl}from"path";async function Jo(t){let e=Fo.get(t);if(e&&e.expiresAt-Date.now()>Sl)return e;let n=await fetch(`${Be}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:t})});if(!n.ok){let i=await n.text().catch(()=>"");throw new Error(n.status===401||n.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${n.status}): ${i.slice(0,200)}`)}let s=await n.json(),o={accessToken:s.oauthAccessToken,expiresAt:s.expiresAtMillis,hubId:s.hubId,hubName:s.hubName||""};return Fo.set(t,o),o}async function vt(t){let{accessToken:e}=await Jo(t);return{Authorization:`Bearer ${e}`}}function wn(t){return t.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function vl(t){return t.startsWith("pat-eu1-")?"eu1":t.startsWith("pat-na1-")?"na1":t.startsWith("CiRldTE")?"eu1":"na1"}function wl(t){return new Promise(e=>setTimeout(e,t))}async function Ut(t,e){let n=`HTTP ${t.status}`,s,o;try{let i=await t.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let a=i.errors[0];o=a.message||JSON.stringify(a)}}catch{try{let i=await t.text();i&&(n=i.slice(0,500))}catch{}}return{status:t.status,message:e?`${n} (${e})`:n,category:s,detail:o}}async function Wt(t,e,n=yl){for(let s=0;s<=n;s++){let o=await fetch(t,e);if(o.status===429||o.status>=500&&s<n){let i=bl*Math.pow(2,s);await wl(i);continue}return o}return fetch(t,e)}async function xn(t){let e=await Jo(t),n=`${Be}/account-info/v3/details`,s=await Wt(n,{headers:await vt(t)});if(!s.ok){let r=await Ut(s);throw new Error(`Failed to get account info: ${r.message}`)}let o=await s.json(),i=String(o.portalId||e.hubId||""),a=e.hubName||o.uiDomain||i;return{portalId:i,portalName:a,dataCenter:vl(t)}}async function Do(t,e,n){let s=gl(n),o=hl(n),i=new FormData,a=new Blob([s]);i.append("file",a,o);let r=`${Be}/cms/v3/source-code/published/content/${wn(e)}`,l=await Wt(r,{method:"PUT",headers:await vt(t),body:i});if(!l.ok){let c=await Ut(l,e);return{success:!1,path:e,error:c}}return{success:!0,path:e}}async function As(t,e){let n=`${Be}/cms/v3/source-code/published/content/${wn(e)}`,s=await Wt(n,{method:"DELETE",headers:await vt(t)});if(!s.ok&&s.status!==404){let o=await Ut(s,e);throw new Error(`Failed to delete ${e}: ${o.message}`)}}async function Lo(t,e){let n=`${Be}/cms/v3/source-code/published/content/${wn(e)}`,s=await Wt(n,{method:"GET",headers:await vt(t)});if(!s.ok){let i=await Ut(s,e);throw new Error(`Failed to download ${e}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Cn(t,e){let n=`${Be}/cms/v3/source-code/published/metadata/${wn(e)}`,s=await Wt(n,{method:"GET",headers:await vt(t)});if(s.status===404)return null;if(!s.ok){let o=await Ut(s,e);throw new Error(`Failed to get metadata for ${e}: ${o.message}`)}return await s.json()}async function Ho(t){let e=await vt(t),n=[`${Be}/cms/v3/source-code/published/metadata`,`${Be}/cms/v3/source-code/published/metadata/`,`${Be}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:e});if(o.ok){let i=await o.json(),a=i.children||i.objects||(Array.isArray(i)?i:null);if(a&&a.length>0)return a.filter(r=>r.folder)}}catch{}return[]}var Be,yl,bl,Sl,Fo,ut=J(()=>{"use strict";g();Be="https://api.hubapi.com",yl=3,bl=1e3,Sl=300*1e3,Fo=new Map});var Vo={};lt(Vo,{fetchTheme:()=>Bt});import{mkdirSync as Ko,writeFileSync as Il}from"fs";import{join as kl,dirname as $l}from"path";async function Ts(t,e){let n=await Cn(t,e);if(!n)return[];if(!n.folder)return[n.path||e];let s=[],o=n.children||[];for(let i of o){let a=typeof i=="string"?i:i.name;if(!a)continue;let r=`${e}/${a}`;if(typeof i=="string")s.push(...await Ts(t,r));else{let l=i;l.folder?s.push(...await Ts(t,l.path||r)):s.push(l.path||r)}}return s}async function Tl(t,e,n){let s=0;async function o(){for(;s<t.length;){let a=s++;await n(t[a])}}let i=Array.from({length:Math.min(e,t.length)},()=>o());await Promise.all(i)}async function Bt(t,e,n,s={}){let o=s.concurrency??5,i=await Ts(t,e);if(i.length===0)throw new Error(`Theme "${e}" not found on HubSpot or is empty`);Ko(n,{recursive:!0}),await Tl(i,o,async a=>{let r=a.startsWith(e+"/")?a.slice(e.length+1):a,l=kl(n,r);Ko($l(l),{recursive:!0});let c=await Lo(t,a);Il(l,c),s.onFile?.(r)})}var Tn=J(()=>{"use strict";g();ut()});function xt(t){let e=Yo.get(t);if(e!==void 0)return e;try{e=I(pn(t))}catch{e=""}return Yo.set(t,e),e}function le(){return xt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function zo(){return xt("design-guide.md")}function qo(){return xt("content-guide.md")}function Ze(){return xt("hubspot-rules.md")}function Xo(){return xt("humanify-guide.md")}function Qo(t){let e=xt("page-types.md");if(!e)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[t];if(!s)return"";let o=e.indexOf(s);if(o<0)return"";let i=e.indexOf(`
2
- ## `,o+s.length);return i>=0?e.slice(o,i).trim():e.slice(o).trim()}function Zo(t){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
1
+ var Nl=Object.defineProperty;var j=(e,t)=>()=>(e&&(t=e(e=0)),t);var tt=(e,t)=>{for(var n in t)Nl(e,n,{get:t[n],enumerable:!0})};import rm from"path";import{fileURLToPath as lm}from"url";var g=j(()=>{"use strict"});import{readFileSync as Ts,writeFileSync as Rl,mkdirSync as Vo,existsSync as Sn}from"fs";import{dirname as Fl,join as Ve}from"path";function A(e){return Ts(e,"utf-8")}function H(e,t){Vo(Fl(e),{recursive:!0}),Rl(e,t,"utf-8")}function b(e){return Sn(e)}function Ae(e){Vo(e,{recursive:!0})}function vn(e){let t=[Ve(import.meta.dirname,"../../assets",e),Ve(import.meta.dirname,"../assets",e),Ve(process.cwd(),"assets",e)];for(let n of t)if(Sn(n))return n;throw new Error(`Asset not found: ${e}`)}function wt(){if(xt)return xt;let e=[Ve(import.meta.dirname,"../../package.json"),Ve(import.meta.dirname,"../package.json"),Ve(process.cwd(),"package.json")];for(let t of e)if(Sn(t))try{let n=JSON.parse(Ts(t,"utf-8"));if(n.name==="vibespot"&&n.version)return xt=n.version,xt}catch{}return xt="dev",xt}function Ko(){if(bn)return bn;let e=[Ve(import.meta.dirname,"../../CHANGELOG.md"),Ve(import.meta.dirname,"../CHANGELOG.md"),Ve(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Sn(t))try{return bn=Ts(t,"utf-8"),bn}catch{}return""}var xt,bn,Q=j(()=>{"use strict";g();xt="";bn=""});import{execSync as Yo}from"child_process";function $(e,t={}){try{return{stdout:Yo(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 zo(e,t={}){try{return Yo(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var ut=j(()=>{"use strict";g()});var Qo={};tt(Qo,{addHubSpotAccount:()=>Jt,getActiveHubSpotAccount:()=>nt,getApiKeyForEngine:()=>ge,getConfigDir:()=>Dl,getHubSpotPak:()=>he,isCliToolEnabled:()=>Dt,loadConfig:()=>_,maskApiKey:()=>wn,removeHubSpotAccount:()=>$s,saveConfig:()=>K,setActiveHubSpotAccount:()=>Es,setCliToolEnabled:()=>_s});import{join as qo}from"path";import{homedir as jl}from"os";import{chmodSync as Jl}from"fs";function _(){if(!b(xn))return{};try{let e=JSON.parse(A(xn));return e.aiEngine==="api"&&(e.aiEngine="anthropic-api"),e}catch{return{}}}function ge(e,t){let n=t||_();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 wn(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function K(e){let n={..._(),...e};if(H(xn,JSON.stringify(n,null,2)),process.platform!=="win32")try{Jl(xn,384)}catch{}}function Dl(){return Xo}function nt(){let e=_();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 Jt(e,t,n,s){let i=_().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),K({hubspotAccounts:i,activeHubSpotAccount:t})}function $s(e){let t=_(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),K(s)}function Es(e){K({activeHubSpotAccount:e})}function he(){return nt()?.personalAccessKey||null}function Dt(e){return _().enabledCLITools?.includes(e)??!1}function _s(e,t){let n=_(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),K({enabledCLITools:[...s]})}var Xo,xn,Z=j(()=>{"use strict";g();Q();Xo=qo(jl(),".vibespot"),xn=qo(Xo,"config.json")});var Os={};tt(Os,{OAUTH_EXTRA_HEADERS:()=>Ht,OAUTH_SYSTEM_PREFIX:()=>At,clearOAuthTokens:()=>kn,getOAuthTokenInfo:()=>Lt,getValidAccessToken:()=>Ms,hasValidOAuthToken:()=>Re,saveInitialToken:()=>Ps});import{join as Hl}from"path";import{homedir as Ll}from"os";import{chmodSync as Gl,unlinkSync as Ul}from"fs";function An(){if(!b(Ct))return null;try{return JSON.parse(A(Ct))}catch{return null}}function Zo(e){if(H(Ct,JSON.stringify(e,null,2)),process.platform!=="win32")try{Gl(Ct,384)}catch{}}async function Kl(e){let t=await fetch(Wl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:Bl})});if(!t.ok)throw kn(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Zo({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Ps(e,t=""){Zo({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Re(){let e=An();return e?e.expires_at>Date.now():!1}async function Ms(){let e=An();if(!e)return null;if(e.expires_at-Date.now()>Vl)return e.access_token;if(e.refresh_token){Cn||(Cn=Kl(e.refresh_token).finally(()=>{Cn=null}));try{await Cn}catch{return null}return An()?.access_token??null}return e.access_token}function Lt(){let e=An();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function kn(){if(b(Ct))try{Ul(Ct)}catch{}}var Bl,Wl,Ct,Vl,Ht,At,Cn,Ke=j(()=>{"use strict";g();Q();Bl="9d1c250a-e61b-44d9-88ed-5944d1962f5e",Wl="https://console.anthropic.com/v1/oauth/token",Ct=Hl(Ll(),".vibespot","claude-oauth.json"),Vl=300*1e3,Ht={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},At="You are Claude Code, Anthropic's official CLI for Claude.";Cn=null});import{readFileSync as ql}from"fs";import{basename as Xl}from"path";async function oi(e){let t=si.get(e);if(t&&t.expiresAt-Date.now()>ec)return t;let n=await fetch(`${Ye}/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 si.set(e,o),o}async function kt(e){let{accessToken:t}=await oi(e);return{Authorization:`Bearer ${t}`}}function Pn(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function tc(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function nc(e){return new Promise(t=>setTimeout(t,e))}async function Yt(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 zt(e,t,n=Ql){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=Zl*Math.pow(2,s);await nc(i);continue}return o}return fetch(e,t)}async function Mn(e){let t=await oi(e),n=`${Ye}/account-info/v3/details`,s=await zt(n,{headers:await kt(e)});if(!s.ok){let r=await Yt(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:tc(e)}}async function ii(e,t,n){let s=ql(n),o=Xl(n),i=new FormData,a=new Blob([s]);i.append("file",a,o);let r=`${Ye}/cms/v3/source-code/published/content/${Pn(t)}`,l=await zt(r,{method:"PUT",headers:await kt(e),body:i});if(!l.ok){let c=await Yt(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function js(e,t){let n=`${Ye}/cms/v3/source-code/published/content/${Pn(t)}`,s=await zt(n,{method:"DELETE",headers:await kt(e)});if(!s.ok&&s.status!==404){let o=await Yt(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function ri(e,t){let n=`${Ye}/cms/v3/source-code/published/content/${Pn(t)}`,s=await zt(n,{method:"GET",headers:await kt(e)});if(!s.ok){let i=await Yt(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function On(e,t){let n=`${Ye}/cms/v3/source-code/published/metadata/${Pn(t)}`,s=await zt(n,{method:"GET",headers:await kt(e)});if(s.status===404)return null;if(!s.ok){let o=await Yt(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function ai(e){let t=await kt(e),n=[`${Ye}/cms/v3/source-code/published/metadata`,`${Ye}/cms/v3/source-code/published/metadata/`,`${Ye}/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 Ye,Ql,Zl,ec,si,pt=j(()=>{"use strict";g();Ye="https://api.hubapi.com",Ql=3,Zl=1e3,ec=300*1e3,si=new Map});var pi={};tt(pi,{fetchTheme:()=>qt});import{mkdirSync as mi,writeFileSync as rc}from"fs";import{join as ac,dirname as lc}from"path";async function Ls(e,t){let n=await On(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 Ls(e,r));else{let l=i;l.folder?s.push(...await Ls(e,l.path||r)):s.push(l.path||r)}}return s}async function cc(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 qt(e,t,n,s={}){let o=s.concurrency??5,i=await Ls(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);mi(n,{recursive:!0}),await cc(i,o,async a=>{let r=a.startsWith(t+"/")?a.slice(t.length+1):a,l=ac(n,r);mi(lc(l),{recursive:!0});let c=await ri(e,a);rc(l,c),s.onFile?.(r)})}var Jn=j(()=>{"use strict";g();pt()});function Tt(e){let t=fi.get(e);if(t!==void 0)return t;try{t=A(vn(e))}catch{t=""}return fi.set(e,t),t}function oe(){return Tt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function Gs(){return Tt("design-guide.md")}function Us(){return Tt("content-guide.md")}function Ee(){return Tt("hubspot-rules.md")}function Bs(){return Tt("humanify-guide.md")}function Ws(e){let t=Tt("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(`
2
+ ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function gi(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
3
3
 
4
4
  ## Rules
5
5
  Follow the conversion guide below EXACTLY. Key rules:
@@ -16,10 +16,10 @@ Follow the conversion guide below EXACTLY. Key rules:
16
16
  - Convert React hooks to vanilla JS (no React, no npm packages)
17
17
 
18
18
  ## HubSpot CMS Rules
19
- ${Ze()}
19
+ ${Ee()}
20
20
 
21
21
  ## Conversion Guide
22
- ${t}`}function ei(t,e,n){return`Convert this React component to a HubSpot module named "${e}".
22
+ ${e}`}function hi(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
23
23
 
24
24
  Return a JSON object with these keys:
25
25
  - fieldsJson: complete fields.json content (as JSON string)
@@ -32,9 +32,9 @@ Design system CSS variables available:
32
32
  ${n}
33
33
 
34
34
  React component source:
35
- ${t}
35
+ ${e}
36
36
 
37
- Return ONLY valid JSON, no markdown fences.`}function ti(t,e,n){return`Create a shared CSS file for a HubSpot CMS landing page.
37
+ Return ONLY valid JSON, no markdown fences.`}function yi(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
38
38
 
39
39
  Extract the design system from the source CSS and Tailwind config below.
40
40
  Use the class prefix ".${n}-" for all custom classes.
@@ -53,12 +53,12 @@ Requirements:
53
53
  - Responsive grid fallbacks
54
54
 
55
55
  Source CSS:
56
- ${t}
56
+ ${e}
57
57
 
58
58
  Tailwind config:
59
- ${e}
59
+ ${t}
60
60
 
61
- Return ONLY the CSS content, no markdown fences.`}function ni(t,e,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
61
+ Return ONLY the CSS content, no markdown fences.`}function bi(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
62
62
 
63
63
  Convert the React hooks and interactive components below to plain JavaScript.
64
64
  Use the class prefix "${n}-" to match the CSS.
@@ -71,14 +71,14 @@ Requirements:
71
71
  - DOMContentLoaded / readyState check
72
72
 
73
73
  React hooks source:
74
- ${t}
74
+ ${e}
75
75
 
76
76
  Interactive component sources:
77
- ${e}
77
+ ${t}
78
78
 
79
- Return ONLY the JavaScript content, no markdown fences.`}function si(t,e,n){return`Create a HubSpot page template that assembles these modules:
79
+ Return ONLY the JavaScript content, no markdown fences.`}function Si(e,t,n){return`Create a HubSpot page template that assembles these modules:
80
80
 
81
- ${t.map((s,o)=>`${o+1}. ${s}.module`).join(`
81
+ ${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
82
82
  `)}
83
83
 
84
84
  Template requirements:
@@ -89,31 +89,31 @@ Template requirements:
89
89
  - Empty header and footer blocks (modules handle them)
90
90
  - Wrap content in <div class="${n}-page">
91
91
  - Each module in its own dnd_section with padding zeroed and full_width=true
92
- - dnd_area label: "${e} Landing Page"
92
+ - dnd_area label: "${t} Landing Page"
93
93
 
94
- Return ONLY the template HTML content, no markdown fences.`}var Yo,Ve=J(()=>{"use strict";g();Z();Yo=new Map});var $i=J(()=>{"use strict";g()});import{existsSync as ze,writeFileSync as nc,mkdirSync as sc}from"fs";import{join as Je}from"path";function Ei(t){return/^[0-9a-f]{4,40}$/i.test(t)}function Ee(){return Hn!==null||(Hn=T("git --version").success),Hn}function Gn(t){if(!Ee())return!1;if(ze(Je(t,".git")))return Ti(t),!0;let e=T("git init",{cwd:t});return e.success?(oc(t),Ti(t),T("git add -A",{cwd:t}),T('git commit -m "Initial theme"',{cwd:t}),!0):(console.warn(`[project-git] git init failed in ${t}: ${e.stderr}`),!1)}function Ti(t){let e=Je(t,".vibespot");ze(e)||sc(e,{recursive:!0})}function oc(t){let e=Je(t,".gitignore");nc(e,[".vibespot/","node_modules/",""].join(`
95
- `),"utf-8")}function Ns(t,e){if(!Ee()||!ze(Je(t,".git"))||(T("git add -A",{cwd:t}),T("git diff --cached --quiet",{cwd:t}).success))return null;let s=e.length>72?e.slice(0,69)+"...":e,o=T(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:t});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=T("git rev-parse --short HEAD",{cwd:t});return i.success?i.stdout:null}function Ni(t,e,n,s){if(!Ee()||!ze(Je(t,".git")))return null;for(let u of s){let p=Je(t,u);ze(p)&&T(`git add "${u}"`,{cwd:t})}if(T("git diff --cached --quiet",{cwd:t}).success)return null;let i=`[${e}] `,a=72-i.length,r=n.length>a?n.slice(0,a-3)+"...":n,l=i+r,c=T(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:t});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=T("git rev-parse --short HEAD",{cwd:t});return d.success?d.stdout:null}function Pi(t,e=50){if(!Ee())return[];if(!ze(Je(t,".git")))return[];let n=T(`git log --pretty=format:"%h|%H|%s|%at" -n ${e}`,{cwd:t});if(!n.success||!n.stdout.trim())return[];let s=[];for(let o of n.stdout.split(`
96
- `)){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 Mi(t,e,n=50){if(!Ee())return[];if(!ze(Je(t,".git")))return[];let s=e.replace(/[[\]\\]/g,"\\$&"),o=T(`git log --grep="\\[${s}\\]" --pretty=format:"%h|%H|%s|%at" -n ${n}`,{cwd:t});if(!o.success||!o.stdout.trim())return[];let i=[];for(let a of o.stdout.split(`
97
- `)){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 _i(t,e){if(!Ee())return{success:!1,error:"Git not available"};if(!ze(Je(t,".git")))return{success:!1,error:"Not a git repo"};if(!Ei(e))return{success:!1,error:"Invalid commit hash"};let n=T(`git cat-file -t ${e}`,{cwd:t});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${e} not found`};let s=T(`git log --format="%s" -1 ${e}`,{cwd:t}),o=s.success?s.stdout:e,i=T(`git checkout ${e} -- .`,{cwd:t});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let a=`Rollback to: ${o}`.slice(0,72);return T(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:t}),{success:!0}}function Ri(t,e,n,s){if(!Ee())return{success:!1,error:"Git not available"};if(!ze(Je(t,".git")))return{success:!1,error:"Not a git repo"};if(!Ei(n))return{success:!1,error:"Invalid commit hash"};let o=T(`git cat-file -t ${n}`,{cwd:t});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=T(`git log --format="%s" -1 ${n}`,{cwd:t}),a=i.success?i.stdout:n,r=0;for(let d of s)T(`git checkout ${n} -- "${d}"`,{cwd:t}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};T("git add -A",{cwd:t});let c=`${`[${e}] `}Rollback to: ${a}`.slice(0,72);return T(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:t}),{success:!0}}var Hn,Yt=J(()=>{"use strict";g();ct();Hn=null});import{readFileSync as ic,existsSync as Oi,writeFileSync as rc,mkdirSync as ac,rmSync as lc}from"fs";import{join as Un}from"path";function mt(t){let e=v();e&&(e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages)}function et(){let t=v();if(!t)return;let e=Ce();e&&(e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages)}function tt(t,e,n){let s=v();if(!s)return;let o={role:t,content:e,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),et(),cc()}function ji(t){let e=v();e&&(e.assets||(e.assets=[]),e.assets.push(t),e.updatedAt=Date.now(),D())}function De(t){let e=v();if(e){if(t.sharedCss!==void 0&&(e.sharedCss=t.sharedCss),t.sharedJs!==void 0&&(e.sharedJs=t.sharedJs),t.template!==void 0&&(e.template=t.template),t.modules)for(let n of t.modules){let s=n.moduleName.toLowerCase(),o=e.modules.findIndex(i=>i.moduleName.toLowerCase()===s);o>=0?e.modules[o]=n:(e.modules.push(n),e.moduleOrder.some(i=>i.toLowerCase()===s)||e.moduleOrder.push(n.moduleName))}e.updatedAt=Date.now(),et()}}function At(t){let e=v();e&&(e.moduleOrder=t,e.updatedAt=Date.now(),et())}function Fi(t){let e=v();if(e){e.modules=e.modules.filter(n=>n.moduleName!==t),e.moduleOrder=e.moduleOrder.filter(n=>n!==t);for(let n of e.templates)n.modules=n.modules.filter(s=>s.moduleName!==t),n.moduleOrder=n.moduleOrder.filter(s=>s!==t);if(e.themePath){let n=Un(e.themePath,"modules",`${t}.module`);Oi(n)&&lc(n,{recursive:!0,force:!0})}e.updatedAt=Date.now(),et()}}function Ji(t){let e=v();e&&(e.moduleOrder=e.moduleOrder.filter(n=>n!==t),e.updatedAt=Date.now(),et())}function Di(t,e,n){let s=v();if(!s)return;let o=s.modules.find(i=>i.moduleName===t);if(o)try{let i=JSON.parse(o.fieldsJson);Hi(i,e,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),et()}catch{}}function me(){let t=v();if(!t)return[];let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function cc(){let t=v();if(t)try{let e=Un(t.themePath,".vibespot");ac(e,{recursive:!0});let n={sessionId:t.id,themeName:t.themeName,messages:t.messages,updatedAt:Date.now()};rc(Un(e,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Li(t){let e=Un(t,".vibespot","chat.json");if(!Oi(e))return[];try{let n=JSON.parse(ic(e,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Hi(t,e,n){let s=e.split("."),o=s[0],i=t.find(a=>a.name===o);i&&(s.length===1?i.default=n:i.children&&Hi(i.children,s.slice(1).join("."),n))}var Wn=J(()=>{"use strict";g();qt();zt()});import{existsSync as Ps,rmSync as Ms}from"fs";import{join as Xt}from"path";function Bn(t){if(t.templates&&t.templates.length>0)return;if(!t.modules||t.modules.length===0){t.templates=[],t.activeTemplateId="";return}let e=`lp-${t.themeName}`,n={id:e,label:`${t.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${t.themeName}.html`,modules:[...t.modules],moduleOrder:[...t.moduleOrder],sharedCss:t.sharedCss||"",sharedJs:t.sharedJs||"",template:t.template||"",messages:[...t.messages]};t.templates=[n],t.activeTemplateId=e}function Ce(){let t=v();return!t||!t.activeTemplateId||!t.templates?.length?null:t.templates.find(e=>e.id===t.activeTemplateId)||null}function _s(t){let e=v();if(!e)return!1;let n=e.templates.find(s=>s.id===t);return n?(e.activeTemplateId=t,mt(n),e.updatedAt=Date.now(),!0):!1}function Gi(t,e){let n=v();if(!n)throw new Error("No active session");let s=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${t==="blog_post"?"bp":t==="website_page"?"wp":t==="module_only"?"mo":"lp"}-${s}`,a={id:i,label:e,pageType:t,templateFile:t==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(a),n.activeTemplateId=i,mt(a),n.updatedAt=Date.now(),a}function Ui(t,e){let n=v();if(!n)return null;let s=n.templates.find(c=>c.id===t);if(!s)return null;let o=e||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),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,mt(l),n.updatedAt=Date.now(),l}function Wi(t,e){let n=v();if(!n)return!1;let s=n.templates.find(o=>o.id===t);return s?(s.label=e,n.updatedAt=Date.now(),!0):!1}function Bi(t,e=!1){let n=v();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===t);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Xt(n.themePath,"templates"),a=`${o.id}.html`,r=Xt(i,a);if(Ps(r)&&Ms(r,{force:!0}),o.pageType==="blog_post"){let l=Xt(i,`${o.id}-listing.html`);Ps(l)&&Ms(l,{force:!0})}}if(e&&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=Xt(n.themePath,"modules");for(let l of a){let c=Xt(r,`${l}.module`);Ps(c)&&Ms(c,{recursive:!0,force:!0})}}}return n.activeTemplateId===t&&(n.templates.length>0?_s(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[])),n.updatedAt=Date.now(),!0}function nt(){let t=v();if(!t)return[];let e=new Map;for(let n of t.templates)for(let s of n.modules){let o=e.get(s.moduleName);o?o.usedIn.push(n.label):e.set(s.moduleName,{module:s,usedIn:[n.label]})}return Array.from(e.values())}var zt=J(()=>{"use strict";g();qt();Wn()});import{readFileSync as qe,readdirSync as Js,existsSync as ye,writeFileSync as Kn,mkdirSync as Ki,rmSync as Rs,renameSync as Os}from"fs";import{join as ie,dirname as dc}from"path";import{homedir as uc}from"os";function Vn(){if(It)return It;try{return ye(js)?(It=JSON.parse(qe(js,"utf-8")),It):Fs()}catch{return Fs()}}function Yn(t){It=t;try{Ki(te,{recursive:!0}),Kn(js,JSON.stringify(t),"utf-8")}catch{}}function Fs(){if(!ye(te))return[];let t=[];for(let e of Js(te).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(qe(ie(te,e),"utf-8")),s=n.templates||[];t.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length})}catch{}return It=t,Yn(t),t}function mc(t){let e=Vn(),n=t.templates||[],s={id:t.id,themeName:t.themeName,updatedAt:t.updatedAt,moduleCount:n.reduce((i,a)=>i+(a.modules?.length||0),0),templateCount:n.length},o=e.findIndex(i=>i.id===t.id);o>=0?e[o]=s:e.push(s),Yn(e)}function pc(t){let e=Vn().filter(n=>n.id!==t);Yn(e)}function fc(t){let e=Vn().filter(n=>n.themeName!==t);Yn(e)}function v(){return be}function gc(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Qt(t,e){let n={id:gc(),themePath:t,themeName:e,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return be=n,Gn(t),n}function D(){if(!be)return;Ki(te,{recursive:!0});let t=ie(te,`${be.id}.json`);Kn(t,JSON.stringify(be,null,2),"utf-8"),mc(be)}function zn(t){let e=ie(te,t+".json");if(!ye(e))return null;try{let n=JSON.parse(qe(e,"utf-8"));return n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Bn(n),be=n,n}catch{return null}}function kt(){return ye(te)?Vn():[]}function Vi(t,e=!1){let n=ie(te,t+".json"),s="";if(e)try{let o=JSON.parse(qe(n,"utf-8"));s=o.themeName||"",o.themePath&&ye(o.themePath)&&Rs(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(qe(n,"utf-8")).themeName||""}catch{}try{ye(n)&&Rs(n)}catch{}if(s&&ye(te)){for(let o of Js(te).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(qe(ie(te,o),"utf-8")).themeName===s&&Rs(ie(te,o))}catch{}fc(s)}else pc(t);be?.id===t&&(be=null)}function Yi(t,e){let n=ie(te,t+".json");if(!ye(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(qe(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===e)return{ok:!0};let i=s.themePath,a=ie(dc(i),e);if(ye(i)){if(ye(a))return{ok:!1,error:"A project with that name already exists"};try{Os(i,a)}catch(p){return{ok:!1,error:`Failed to rename folder: ${p instanceof Error?p.message:String(p)}`}}let r=ie(a,"css",`${o}-theme.css`),l=ie(a,"css",`${e}-theme.css`);if(ye(r))try{Os(r,l)}catch{}let c=ie(a,"js",`${o}-animations.js`),d=ie(a,"js",`${e}-animations.js`);if(ye(c))try{Os(c,d)}catch{}let u=ie(a,"theme.json");if(ye(u))try{let p=JSON.parse(qe(u,"utf-8"));p.label=e,p.name=e,Kn(u,JSON.stringify(p,null,2),"utf-8")}catch{}}if(ye(te))for(let r of Js(te).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(qe(ie(te,r),"utf-8"));l.themeName===o&&(l.themeName=e,l.themePath=a,l.updatedAt=Date.now(),Kn(ie(te,r),JSON.stringify(l,null,2),"utf-8"))}catch{}return be&&be.themeName===o&&(be.themeName=e,be.themePath=a,be.updatedAt=Date.now()),Fs(),{ok:!0}}var te,js,It,be,qt=J(()=>{"use strict";g();Yt();zt();te=ie(uc(),".vibespot","sessions"),js=ie(te,"_index.json"),It=null;be=null});import{readFileSync as Ds,readdirSync as en,existsSync as pe,writeFileSync as ke,mkdirSync as Zt,rmSync as zi}from"fs";import{join as _}from"path";function re(t){try{return Ds(t,"utf-8")}catch{return""}}function hc(t){let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function yc(t,e){let n=re(t);if(!n||e==="home.html"||e.endsWith("-listing.html"))return null;let s=e.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:e}}function bc(t,e,n,s,o){if(!pe(t))return[];let i=[],a=en(t).filter(r=>r.endsWith(".html")&&r!=="home.html");for(let r of a){let l=_(t,r),c=yc(l,r);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let p of c.moduleNames){let f=e.get(p);f&&(d.push(f),u.push(p))}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 tn(t){let e=v();if(!e)return;let n=Li(t);n.length>0&&e.messages.length===0&&(e.messages=n),Gn(t);let s=_(t,"modules");if(!pe(s))return;let o=en(s,{withFileTypes:!0});for(let y of o){if(!y.isDirectory()||!y.name.endsWith(".module"))continue;let b=_(s,y.name),A=y.name.replace(/\.module$/,""),w={moduleName:A,fieldsJson:re(_(b,"fields.json")),metaJson:re(_(b,"meta.json")),moduleHtml:re(_(b,"module.html")),moduleCss:re(_(b,"module.css")),moduleJs:re(_(b,"module.js"))||void 0};w.fieldsJson&&w.moduleHtml&&(e.modules.push(w),e.moduleOrder.push(A))}let i=_(t,"css"),a=_(t,"js"),r="",l="";if(pe(i)){let y=en(i).filter(b=>b.endsWith("-theme.css"));y.length>0&&(r=re(_(i,y[0])),e.sharedCss=r)}if(pe(a)){let y=en(a).filter(b=>b.endsWith("-animations.js"));y.length>0&&(l=re(_(a,y[0])),e.sharedJs=l)}let c=_(t,".vibespot","styleguide.md"),d=_(t,".vibespot","brandvoice.md"),u=_(t,".vibespot","theme-context.md");(pe(c)||pe(d)||pe(u))&&(e.brandAssets||(e.brandAssets={}),pe(c)&&(e.brandAssets.styleguide=re(c)),pe(d)&&(e.brandAssets.brandvoice=re(d)),pe(u)&&(e.brandAssets.themeContext=re(u)));let p=_(t,"templates"),f=new Map(e.modules.map(y=>[y.moduleName,y])),h=bc(p,f,r,l,e.messages);if(h.length>0){e.templates=h,e.activeTemplateId=h[0].id;let y=h[0].moduleOrder;if(y.length>0){let b=new Set(e.moduleOrder),A=y.filter(w=>b.has(w));for(let w of e.moduleOrder)A.includes(w)||A.push(w);e.moduleOrder=A}mt(h[0])}else e.templates||(e.templates=[]),e.activeTemplateId||(e.activeTemplateId=""),Bn(e)}function st(){let t=v();if(!t)return;let e=t.themePath,n=new Map;if(t.templates.length>0)for(let l of t.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of t.modules)n.set(l.moduleName,l);let s=_(e,"modules");Zt(s,{recursive:!0});for(let l of n.values())Zt(_(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=_(s,`${l.moduleName}.module`);ke(_(c,"fields.json"),l.fieldsJson,"utf-8"),ke(_(c,"meta.json"),l.metaJson,"utf-8"),ke(_(c,"module.html"),l.moduleHtml,"utf-8"),ke(_(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&ke(_(c,"module.js"),l.moduleJs,"utf-8")}if(t.sharedCss){let l=_(e,"css");Zt(l,{recursive:!0}),ke(_(l,`${t.themeName}-theme.css`),t.sharedCss,"utf-8")}if(t.sharedJs){let l=_(e,"js");Zt(l,{recursive:!0}),ke(_(l,`${t.themeName}-animations.js`),t.sharedJs,"utf-8")}let o=_(e,"templates");Zt(o,{recursive:!0});let i=_(o,"home.html");(t.templates.length>0||t.modules.length>0)&&pe(i)&&zi(i,{force:!0});let r=new Set;if(t.templates.length>0)for(let l of t.templates){if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||wc(l),d=qi(c,l.label,l.pageType),u=`${l.id}.html`;ke(_(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&(xc(o,l),r.add(`${l.id}-listing.html`))}else if(t.modules.length>0){let l=t.template||Cc(),c=qi(l,`${t.themeName} Landing Page`),d=`lp-${t.themeName}.html`;ke(_(o,d),c,"utf-8"),r.add(d)}try{for(let l of en(o))l.startsWith("lp-")&&l.endsWith(".html")&&!r.has(l)&&zi(_(o,l),{force:!0})}catch{}Sc(),vc()}function Xi(){let t=v();t&&(t.modules=[],t.moduleOrder=[],t.sharedCss="",t.sharedJs="",t.template="",tn(t.themePath),t.updatedAt=Date.now(),et())}function Qi(){let t=v();if(!t)return;let e=Ce();if(!e)return;let n=t.themePath,s=_(n,"modules");e.modules=[];for(let o of e.moduleOrder){let i=_(s,`${o}.module`);if(!pe(i))continue;let a={moduleName:o,fieldsJson:re(_(i,"fields.json")),metaJson:re(_(i,"meta.json")),moduleHtml:re(_(i,"module.html")),moduleCss:re(_(i,"module.css")),moduleJs:re(_(i,"module.js"))||void 0};a.fieldsJson&&a.moduleHtml&&e.modules.push(a)}if(e.templateFile){let o=_(n,e.templateFile);pe(o)&&(e.template=re(o))}mt(e),t.updatedAt=Date.now()}function Sc(){let t=v();if(!t)return;let e=_(t.themePath,"templates","layouts","base.html");if(pe(e))try{let n=Ds(e,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
94
+ Return ONLY the template HTML content, no markdown fences.`}var fi,qe=j(()=>{"use strict";g();Q();fi=new Map});var Ui=j(()=>{"use strict";g()});import{existsSync as Qe,writeFileSync as jc,mkdirSync as Jc}from"fs";import{join as He}from"path";function Wi(e){return/^[0-9a-f]{4,40}$/i.test(e)}function _e(){return Xn!==null||(Xn=$("git --version").success),Xn}function Qn(e){if(!_e())return!1;if(Qe(He(e,".git")))return Bi(e),!0;let t=$("git init",{cwd:e});return t.success?(Dc(e),Bi(e),$("git add -A",{cwd:e}),$('git commit -m "Initial theme"',{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Bi(e){let t=He(e,".vibespot");Qe(t)||Jc(t,{recursive:!0})}function Dc(e){let t=He(e,".gitignore");jc(t,[".vibespot/","node_modules/",""].join(`
95
+ `),"utf-8")}function Ks(e,t){if(!_e()||!Qe(He(e,".git"))||($("git add -A",{cwd:e}),$("git diff --cached --quiet",{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=$(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=$("git rev-parse --short HEAD",{cwd:e});return i.success?i.stdout:null}function Vi(e,t,n,s){if(!_e()||!Qe(He(e,".git")))return null;for(let u of s){let m=He(e,u);Qe(m)&&$(`git add "${u}"`,{cwd:e})}if($("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=$(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=$("git rev-parse --short HEAD",{cwd:e});return d.success?d.stdout:null}function Ki(e,t=50){if(!_e())return[];if(!Qe(He(e,".git")))return[];let n=$(`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(`
96
+ `)){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 Yi(e,t,n=50){if(!_e())return[];if(!Qe(He(e,".git")))return[];let s=t.replace(/[[\]\\]/g,"\\$&"),o=$(`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(`
97
+ `)){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 zi(e,t){if(!_e())return{success:!1,error:"Git not available"};if(!Qe(He(e,".git")))return{success:!1,error:"Not a git repo"};if(!Wi(t))return{success:!1,error:"Invalid commit hash"};let n=$(`git cat-file -t ${t}`,{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=$(`git log --format="%s" -1 ${t}`,{cwd:e}),o=s.success?s.stdout:t,i=$(`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 $(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}function qi(e,t,n,s){if(!_e())return{success:!1,error:"Git not available"};if(!Qe(He(e,".git")))return{success:!1,error:"Not a git repo"};if(!Wi(n))return{success:!1,error:"Invalid commit hash"};let o=$(`git cat-file -t ${n}`,{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=$(`git log --format="%s" -1 ${n}`,{cwd:e}),a=i.success?i.stdout:n,r=0;for(let d of s)$(`git checkout ${n} -- "${d}"`,{cwd:e}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};$("git add -A",{cwd:e});let c=`${`[${t}] `}Rollback to: ${a}`.slice(0,72);return $(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}var Xn,Zt=j(()=>{"use strict";g();ut();Xn=null});import{readFileSync as Hc,existsSync as Xi,writeFileSync as Lc,mkdirSync as Gc,rmSync as Uc}from"fs";import{join as Zn}from"path";function ft(e){let t=S();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 ot(){let e=S();if(!e)return;let t=Ce();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 it(e,t,n){let s=S();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),ot(),Bc()}function Qi(e){let t=S();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),D())}function Le(e){let t=S();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);o>=0?t.modules[o]=n:(t.modules.push(n),t.moduleOrder.some(i=>i.toLowerCase()===s)||t.moduleOrder.push(n.moduleName))}t.updatedAt=Date.now(),ot()}}function Et(e){let t=S();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),ot())}function Zi(e){let t=S();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=Zn(t.themePath,"modules",`${e}.module`);Xi(n)&&Uc(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),ot()}}function er(e){let t=S();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),ot())}function tr(e,t,n){let s=S();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);sr(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),ot()}catch{}}function me(){let e=S();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 Bc(){let e=S();if(e)try{let t=Zn(e.themePath,".vibespot");Gc(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};Lc(Zn(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function nr(e){let t=Zn(e,".vibespot","chat.json");if(!Xi(t))return[];try{let n=JSON.parse(Hc(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function sr(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&&sr(i.children,s.slice(1).join("."),n))}var es=j(()=>{"use strict";g();tn();en()});import{existsSync as Ys,rmSync as zs}from"fs";import{join as nn}from"path";function ts(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function Ce(){let e=S();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function qs(e){let t=S();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,ft(n),t.updatedAt=Date.now(),!0):!1}function or(e,t){let n=S();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,ft(a),n.updatedAt=Date.now(),a}function ir(e,t){let n=S();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,ft(l),n.updatedAt=Date.now(),l}function rr(e,t){let n=S();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 ar(e,t=!1){let n=S();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=nn(n.themePath,"templates"),a=`${o.id}.html`,r=nn(i,a);if(Ys(r)&&zs(r,{force:!0}),o.pageType==="blog_post"){let l=nn(i,`${o.id}-listing.html`);Ys(l)&&zs(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=nn(n.themePath,"modules");for(let l of a){let c=nn(r,`${l}.module`);Ys(c)&&zs(c,{recursive:!0,force:!0})}}}return n.activeTemplateId===e&&(n.templates.length>0?qs(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[])),n.updatedAt=Date.now(),!0}function rt(){let e=S();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 en=j(()=>{"use strict";g();tn();es()});import{readFileSync as Ze,readdirSync as to,existsSync as ye,writeFileSync as ns,mkdirSync as lr,rmSync as Xs,renameSync as Qs}from"fs";import{join as re,dirname as Wc}from"path";import{homedir as Vc}from"os";function ss(){if(_t)return _t;try{return ye(Zs)?(_t=JSON.parse(Ze(Zs,"utf-8")),_t):eo()}catch{return eo()}}function os(e){_t=e;try{lr(ne,{recursive:!0}),ns(Zs,JSON.stringify(e),"utf-8")}catch{}}function eo(){if(!ye(ne))return[];let e=[];for(let t of to(ne).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(Ze(re(ne,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 _t=e,os(e),e}function Kc(e){let t=ss(),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),os(t)}function Yc(e){let t=ss().filter(n=>n.id!==e);os(t)}function zc(e){let t=ss().filter(n=>n.themeName!==e);os(t)}function S(){return be}function qc(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function sn(e,t){let n={id:qc(),themePath:e,themeName:t,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return be=n,Qn(e),n}function D(){if(!be)return;lr(ne,{recursive:!0});let e=re(ne,`${be.id}.json`);ns(e,JSON.stringify(be,null,2),"utf-8"),Kc(be)}function is(e){let t=re(ne,e+".json");if(!ye(t))return null;try{let n=JSON.parse(Ze(t,"utf-8"));return n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),ts(n),be=n,n}catch{return null}}function Pt(){return ye(ne)?ss():[]}function cr(e,t=!1){let n=re(ne,e+".json"),s="";if(t)try{let o=JSON.parse(Ze(n,"utf-8"));s=o.themeName||"",o.themePath&&ye(o.themePath)&&Xs(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(Ze(n,"utf-8")).themeName||""}catch{}try{ye(n)&&Xs(n)}catch{}if(s&&ye(ne)){for(let o of to(ne).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(Ze(re(ne,o),"utf-8")).themeName===s&&Xs(re(ne,o))}catch{}zc(s)}else Yc(e);be?.id===e&&(be=null)}function dr(e,t){let n=re(ne,e+".json");if(!ye(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(Ze(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=re(Wc(i),t);if(ye(i)){if(ye(a))return{ok:!1,error:"A project with that name already exists"};try{Qs(i,a)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let r=re(a,"css",`${o}-theme.css`),l=re(a,"css",`${t}-theme.css`);if(ye(r))try{Qs(r,l)}catch{}let c=re(a,"js",`${o}-animations.js`),d=re(a,"js",`${t}-animations.js`);if(ye(c))try{Qs(c,d)}catch{}let u=re(a,"theme.json");if(ye(u))try{let m=JSON.parse(Ze(u,"utf-8"));m.label=t,m.name=t,ns(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(ye(ne))for(let r of to(ne).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(Ze(re(ne,r),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=a,l.updatedAt=Date.now(),ns(re(ne,r),JSON.stringify(l,null,2),"utf-8"))}catch{}return be&&be.themeName===o&&(be.themeName=t,be.themePath=a,be.updatedAt=Date.now()),eo(),{ok:!0}}var ne,Zs,_t,be,tn=j(()=>{"use strict";g();Zt();en();ne=re(Vc(),".vibespot","sessions"),Zs=re(ne,"_index.json"),_t=null;be=null});import{readFileSync as no,readdirSync as rn,existsSync as pe,writeFileSync as Ie,mkdirSync as on,rmSync as ur}from"fs";import{join as M}from"path";function ae(e){try{return no(e,"utf-8")}catch{return""}}function Xc(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 Qc(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 Zc(e,t,n,s,o){if(!pe(e))return[];let i=[],a=rn(e).filter(r=>r.endsWith(".html")&&r!=="home.html");for(let r of a){let l=M(e,r),c=Qc(l,r);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 an(e){let t=S();if(!t)return;let n=nr(e);n.length>0&&t.messages.length===0&&(t.messages=n),Qn(e);let s=M(e,"modules");if(!pe(s))return;let o=rn(s,{withFileTypes:!0});for(let y of o){if(!y.isDirectory()||!y.name.endsWith(".module"))continue;let v=M(s,y.name),C=y.name.replace(/\.module$/,""),k={moduleName:C,fieldsJson:ae(M(v,"fields.json")),metaJson:ae(M(v,"meta.json")),moduleHtml:ae(M(v,"module.html")),moduleCss:ae(M(v,"module.css")),moduleJs:ae(M(v,"module.js"))||void 0};k.fieldsJson&&k.moduleHtml&&(t.modules.push(k),t.moduleOrder.push(C))}let i=M(e,"css"),a=M(e,"js"),r="",l="";if(pe(i)){let y=rn(i).filter(v=>v.endsWith("-theme.css"));y.length>0&&(r=ae(M(i,y[0])),t.sharedCss=r)}if(pe(a)){let y=rn(a).filter(v=>v.endsWith("-animations.js"));y.length>0&&(l=ae(M(a,y[0])),t.sharedJs=l)}let c=M(e,".vibespot","styleguide.md"),d=M(e,".vibespot","brandvoice.md"),u=M(e,".vibespot","theme-context.md");(pe(c)||pe(d)||pe(u))&&(t.brandAssets||(t.brandAssets={}),pe(c)&&(t.brandAssets.styleguide=ae(c)),pe(d)&&(t.brandAssets.brandvoice=ae(d)),pe(u)&&(t.brandAssets.themeContext=ae(u)));let m=M(e,"templates"),f=new Map(t.modules.map(y=>[y.moduleName,y])),h=Zc(m,f,r,l,t.messages);if(h.length>0){t.templates=h,t.activeTemplateId=h[0].id;let y=h[0].moduleOrder;if(y.length>0){let v=new Set(t.moduleOrder),C=y.filter(k=>v.has(k));for(let k of t.moduleOrder)C.includes(k)||C.push(k);t.moduleOrder=C}ft(h[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),ts(t)}function at(){let e=S();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=M(t,"modules");on(s,{recursive:!0});for(let l of n.values())on(M(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=M(s,`${l.moduleName}.module`);Ie(M(c,"fields.json"),l.fieldsJson,"utf-8"),Ie(M(c,"meta.json"),l.metaJson,"utf-8"),Ie(M(c,"module.html"),l.moduleHtml,"utf-8"),Ie(M(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ie(M(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=M(t,"css");on(l,{recursive:!0}),Ie(M(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=M(t,"js");on(l,{recursive:!0}),Ie(M(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=M(t,"templates");on(o,{recursive:!0});let i=M(o,"home.html");(e.templates.length>0||e.modules.length>0)&&pe(i)&&ur(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||nd(l),d=mr(c,l.label,l.pageType),u=`${l.id}.html`;Ie(M(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&(sd(o,l),r.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||od(),c=mr(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ie(M(o,d),c,"utf-8"),r.add(d)}try{for(let l of rn(o))l.startsWith("lp-")&&l.endsWith(".html")&&!r.has(l)&&ur(M(o,l),{force:!0})}catch{}ed(),td()}function pr(){let e=S();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",an(e.themePath),e.updatedAt=Date.now(),ot())}function fr(){let e=S();if(!e)return;let t=Ce();if(!t)return;let n=e.themePath,s=M(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=M(s,`${o}.module`);if(!pe(i))continue;let a={moduleName:o,fieldsJson:ae(M(i,"fields.json")),metaJson:ae(M(i,"meta.json")),moduleHtml:ae(M(i,"module.html")),moduleCss:ae(M(i,"module.css")),moduleJs:ae(M(i,"module.js"))||void 0};a.fieldsJson&&a.moduleHtml&&t.modules.push(a)}if(t.templateFile){let o=M(n,t.templateFile);pe(o)&&(t.template=ae(o))}ft(t),e.updatedAt=Date.now()}function ed(){let e=S();if(!e)return;let t=M(e.themePath,"templates","layouts","base.html");if(pe(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+`
98
98
  {% if template_js %}
99
99
  {{ require_js(get_asset_url(template_js)) }}
100
100
  {% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
101
101
  {{ require_js(get_asset_url(template_js)) }}
102
102
  {% endif %}
103
- {{ standard_footer_includes }}`),ke(e,n,"utf-8")}catch{}}function vc(){let t=v();if(!t)return;let e=_(t.themePath,"theme.json");if(pe(e))try{let n=JSON.parse(Ds(e,"utf-8"));n.label=t.themeName,n.name=t.themeName,ke(e,JSON.stringify(n,null,2),"utf-8")}catch{}}function qi(t,e,n="landing_page"){return t.includes("templateType")?t:`<!--
103
+ {{ standard_footer_includes }}`),Ie(t,n,"utf-8")}catch{}}function td(){let e=S();if(!e)return;let t=M(e.themePath,"theme.json");if(pe(t))try{let n=JSON.parse(no(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ie(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function mr(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
104
104
  templateType: ${n==="blog_post"?"blog_post":"page"}
105
105
  isAvailableForNewContent: true
106
- label: "${e}"
106
+ label: "${t}"
107
107
  -->
108
- `+t}function wc(t){if(t.modules.length===0)return"";let n=v().themeName,o=hc(t).map(a=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
108
+ `+e}function nd(e){if(e.modules.length===0)return"";let n=S().themeName,o=Xc(e).map(a=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
109
109
  {% dnd_module path="../modules/${a.moduleName}.module" %}
110
110
  {% end_dnd_module %}
111
111
  {% end_dnd_section %}`).join(`
112
112
 
113
113
  `);return`<!--
114
- templateType: ${t.pageType==="blog_post"?"blog_post":"page"}
114
+ templateType: ${e.pageType==="blog_post"?"blog_post":"page"}
115
115
  isAvailableForNewContent: true
116
- label: "${t.label}"
116
+ label: "${e.label}"
117
117
  -->
118
118
  {% extends "./layouts/base.html" %}
119
119
 
@@ -125,7 +125,7 @@ Return ONLY the template HTML content, no markdown fences.`}var Yo,Ve=J(()=>{"us
125
125
 
126
126
  {% block body %}
127
127
  <div class="${n}-page">
128
- {% dnd_area "main_content" label="${t.label}" %}
128
+ {% dnd_area "main_content" label="${e.label}" %}
129
129
 
130
130
  ${o}
131
131
 
@@ -136,10 +136,10 @@ ${o}
136
136
 
137
137
  {% block footer %}
138
138
  {% endblock footer %}
139
- `}function xc(t,e){let n=`<!--
139
+ `}function sd(e,t){let n=`<!--
140
140
  templateType: blog_listing
141
141
  isAvailableForNewContent: true
142
- label: "${e.label} - Listing"
142
+ label: "${t.label} - Listing"
143
143
  -->
144
144
  {% extends "./layouts/base.html" %}
145
145
 
@@ -161,7 +161,7 @@ ${o}
161
161
  {% endif %}
162
162
  </div>
163
163
  {% endblock body %}
164
- `;ke(_(t,`${e.id}-listing.html`),n,"utf-8")}function Cc(){let t=v();if(!t||t.modules.length===0)return"";let e=t.themeName,s=me().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
164
+ `;Ie(M(e,`${t.id}-listing.html`),n,"utf-8")}function od(){let e=S();if(!e||e.modules.length===0)return"";let t=e.themeName,s=me().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
165
165
  {% dnd_module path="../modules/${o.moduleName}.module" %}
166
166
  {% end_dnd_module %}
167
167
  {% end_dnd_section %}`).join(`
@@ -169,38 +169,38 @@ ${o}
169
169
  `);return`<!--
170
170
  templateType: page
171
171
  isAvailableForNewContent: true
172
- label: "${e} Landing Page"
172
+ label: "${t} Landing Page"
173
173
  -->
174
174
  {% extends "./layouts/base.html" %}
175
175
 
176
- {% set template_css = "../../css/${e}-theme.css" %}
177
- {% set template_js = "../../js/${e}-animations.js" %}
176
+ {% set template_css = "../../css/${t}-theme.css" %}
177
+ {% set template_js = "../../js/${t}-animations.js" %}
178
178
 
179
179
  {% block header %}
180
180
  {% endblock header %}
181
181
 
182
182
  {% block body %}
183
- <div class="${e}-page">
184
- {% dnd_area "main_content" label="${e} Landing Page" %}
183
+ <div class="${t}-page">
184
+ {% dnd_area "main_content" label="${t} Landing Page" %}
185
185
 
186
186
  ${s}
187
187
 
188
188
  {% end_dnd_area %}
189
189
  </div>
190
- {{ require_js(get_asset_url("../../js/${e}-animations.js")) }}
190
+ {{ require_js(get_asset_url("../../js/${t}-animations.js")) }}
191
191
  {% endblock body %}
192
192
 
193
193
  {% block footer %}
194
194
  {% endblock footer %}
195
- `}var Zi=J(()=>{"use strict";g();qt();Wn();zt();Yt()});var er=J(()=>{"use strict";g();$i();qt();Wn();Zi();zt()});var Se=J(()=>{"use strict";g();er()});function qn(t){let e={};for(let n of t)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?e[n.name]=n.default:n.type==="group"&&n.children?e[n.name]=qn(n.children):e[n.name]=n.default??"";return e}function Hs(t,e){let n=t;return n=Mc(n),n=or(n,e),n=ir(n,e),n=rr(n,e),n=Rc(n),n}function Gs(t){let e=[t.sharedCss||"",...t.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
196
- `),n=[t.sharedJs||"",...t.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
197
- `),s=t.renderedModules.join(`
195
+ `}var gr=j(()=>{"use strict";g();tn();es();en();Zt()});var hr=j(()=>{"use strict";g();Ui();tn();es();gr();en()});var Se=j(()=>{"use strict";g();hr()});function rs(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]=rs(n.children):t[n.name]=n.default??"";return t}function oo(e,t){let n=e;return n=pd(n),n=vr(n,t),n=xr(n,t),n=wr(n,t),n=gd(n),n}function io(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
196
+ `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
197
+ `),s=e.renderedModules.join(`
198
198
  `);return`<!DOCTYPE html>
199
199
  <html lang="en">
200
200
  <head>
201
201
  <meta charset="utf-8">
202
202
  <meta name="viewport" content="width=device-width, initial-scale=1">
203
- ${e}
203
+ ${t}
204
204
  <style>
205
205
  html{scroll-behavior:smooth}
206
206
  .vsp-img-wrap{position:relative;display:inline-block}
@@ -239,11 +239,11 @@ document.querySelectorAll('img').forEach(function(img){
239
239
  });
240
240
  </script>
241
241
  </body>
242
- </html>`}function Mc(t){return t=t.replace(Ac,""),t=t.replace(Ic,""),t=t.replace(kc,""),tr.lastIndex=0,t=t.replace(tr,(e,n)=>`/theme-assets/${n}`),nr.lastIndex=0,t=t.replace(nr,""),t=t.replace($c,""),t=t.replace(Tc,""),t=t.replace(Ec,""),t=t.replace(Nc,""),t=t.replace(Pc,""),t}function or(t,e){let n=t,s=0;for(;s<30;){s++;let o=_c(n);if(!o)break;let{varName:i,iterExpr:a,body:r,start:l,end:c}=o,d=Oc(a,e),u="";Array.isArray(d)&&(u=d.map((p,f)=>{let h={...e,[i]:p,loop:{index:f+1,index0:f,first:f===0,last:f===d.length-1,length:d.length}},y=or(r,h);return y=ir(y,h),y=rr(y,h),y}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function _c(t){let e=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=e.exec(t);if(!s)return null;let o=s[1],i=s[2],a=s.index+s[0].length;n.lastIndex=a;let r=1,l;for(;(l=n.exec(t))!==null;)if(l[1].startsWith("for"))r++;else if(r--,r===0){let c=t.slice(a,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function ir(t,e){let n=t,s=0;for(;Ls.test(n)&&s<50;)s++,n=n.replace(Ls,(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($t(i,e))return d[0];for(let u=1;u<d.length;u+=2){let p=d[u],f=d[u+1]||"";if($t(p,e))return f}return c}return $t(i,e)?l:c}),Ls.lastIndex=0;return n}function rr(t,e){return t.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),a=i[0].trim(),r=pt(e,a);for(let c=1;c<i.length;c++)r=lr(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 Rc(t){return t=t.replace(/\{%.*?%\}/gs,""),t=t.replace(/\{\{.*?\}\}/gs,""),t}function Oc(t,e){let n=t.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=sr(n[1],e),i=sr(n[2],e),a=[];for(let r=o;r<i;r++)a.push(r);return a}let s=t.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=pt(e,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return pt(e,t)}function sr(t,e){let s=t.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=pt(e,o);for(let a=1;a<s.length;a++)i=lr(i,s[a].trim());return Number(i)||0}function pt(t,e){let n=e.split("."),s=t;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function $t(t,e){let n=t.trim();if(n.startsWith("not "))return!$t(n.slice(4),e);if(n.includes(" and "))return n.split(" and ").every(i=>$t(i,e));if(n.includes(" or "))return n.split(" or ").some(i=>$t(i,e));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=pt(e,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=pt(e,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=pt(e,n);return ar(o)}function ar(t){return!(t==null||t===""||t===0||t===!1||Array.isArray(t)&&t.length===0)}function lr(t,e){let n=t==null?"":String(t),s=e.match(/^(\w+)\((.*)\)$/),o=s?s[1]:e,i=s?s[2].replace(/^["']|["']$/g,""):void 0;switch(o){case"escape":case"e":return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");case"lower":return n.toLowerCase();case"upper":return n.toUpperCase();case"capitalize":return n.charAt(0).toUpperCase()+n.slice(1);case"trim":return n.trim();case"truncate":if(i){let a=parseInt(i,10);return n.length>a?n.slice(0,a)+"...":n}return n;case"default":return ar(t)?t:i??"";case"length":return Array.isArray(t)?t.length:n.length;case"join":return Array.isArray(t)?t.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));default:return t}}var Ac,Ic,kc,tr,nr,$c,Tc,Ec,Nc,Pc,Ls,cr=J(()=>{"use strict";g();Ac=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Ic=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,kc=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,tr=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,nr=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,$c=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Tc=/\{%[-\s]*module\b.*?%\}/gs,Ec=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Nc=/\{#.*?#\}/gs,Pc=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Ls=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Bs={};lt(Bs,{buildModulePreviewHtml:()=>Ws,buildPreviewHtml:()=>Us});function jc(t){if(!t)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let e=(r,l)=>{for(let c of r){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=t.match(d);if(u)return u[1].trim()}return l},n=e(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=e(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=e(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=e(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),a=e(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:a}}function Us(){let t=v();if(!t)return dr();let e=me(),n=t.moduleOrder||[];if(e.length===0&&n.length===0)return dr();let s=[],o=[],i=[],a=new Set;for(let c of e){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d;try{let f=JSON.parse(c.fieldsJson);d={module:qn(f)}}catch{d={module:{}}}let u=Hs(c.moduleHtml,d),p=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${p}" data-module="${c.moduleName}">${u}</div>`),a.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let r=jc(t.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}">
242
+ </html>`}function pd(e){return e=e.replace(id,""),e=e.replace(rd,""),e=e.replace(ad,""),yr.lastIndex=0,e=e.replace(yr,(t,n)=>`/theme-assets/${n}`),br.lastIndex=0,e=e.replace(br,""),e=e.replace(ld,""),e=e.replace(cd,""),e=e.replace(dd,""),e=e.replace(ud,""),e=e.replace(md,""),e}function vr(e,t){let n=e,s=0;for(;s<30;){s++;let o=fd(n);if(!o)break;let{varName:i,iterExpr:a,body:r,start:l,end:c}=o,d=hd(a,t),u="";Array.isArray(d)&&(u=d.map((m,f)=>{let h={...t,[i]:m,loop:{index:f+1,index0:f,first:f===0,last:f===d.length-1,length:d.length}},y=vr(r,h);return y=xr(y,h),y=wr(y,h),y}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function fd(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 xr(e,t){let n=e,s=0;for(;so.test(n)&&s<50;)s++,n=n.replace(so,(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(Mt(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],f=d[u+1]||"";if(Mt(m,t))return f}return c}return Mt(i,t)?l:c}),so.lastIndex=0;return n}function wr(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),a=i[0].trim(),r=gt(t,a);for(let c=1;c<i.length;c++)r=Ar(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 gd(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function hd(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Sr(n[1],t),i=Sr(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=gt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return gt(t,e)}function Sr(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=gt(t,o);for(let a=1;a<s.length;a++)i=Ar(i,s[a].trim());return Number(i)||0}function gt(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 Mt(e,t){let n=e.trim();if(n.startsWith("not "))return!Mt(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Mt(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Mt(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=gt(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=gt(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=gt(t,n);return Cr(o)}function Cr(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function Ar(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 Cr(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 id,rd,ad,yr,br,ld,cd,dd,ud,md,so,kr=j(()=>{"use strict";g();id=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,rd=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,ad=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,yr=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,br=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,ld=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,cd=/\{%[-\s]*module\b.*?%\}/gs,dd=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,ud=/\{#.*?#\}/gs,md=/\{\{[-\s]*content\.\w+.*?\}\}/gs,so=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var lo={};tt(lo,{buildModulePreviewHtml:()=>ao,buildPreviewHtml:()=>ro});function yd(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 ro(){let e=S();if(!e)return Ir();let t=me(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return Ir();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 f=JSON.parse(c.fieldsJson);d={module:rs(f)}}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=yd(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}">
243
243
  <div class="vibespot-placeholder">
244
244
  <div class="vibespot-placeholder__name">${c}</div>
245
245
  </div>
246
- </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 Gs({renderedModules:s,sharedCss:t.sharedCss,moduleCssArray:[l,...o],sharedJs:t.sharedJs,moduleJsArray:i})}function dr(){return`<!DOCTYPE html>
246
+ </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 io({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function Ir(){return`<!DOCTYPE html>
247
247
  <html lang="en">
248
248
  <head>
249
249
  <meta charset="utf-8">
@@ -294,8 +294,50 @@ document.querySelectorAll('img').forEach(function(img){
294
294
  <div class="welcome__sub">Build Something Great</div>
295
295
  </div>
296
296
  </body>
297
- </html>`}function Ws(t){let e=v();if(!e)return"";let n;for(let i of e.templates)if(n=i.modules.find(a=>a.moduleName===t),n)break;if(n||(n=e.modules.find(i=>i.moduleName===t)),!n)return"";let s;try{let i=JSON.parse(n.fieldsJson);s={module:qn(i)}}catch{s={module:{}}}let o=Hs(n.moduleHtml,s);return Gs({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${o}</div>`],sharedCss:e.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:e.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}var Xn=J(()=>{"use strict";g();cr();Se()});import{appendFileSync as Fc,mkdirSync as Jc,readdirSync as Dc,unlinkSync as Lc}from"fs";import{join as zs}from"path";import{homedir as Hc}from"os";function Uc(){if(!Vs)try{Jc(Qn,{recursive:!0}),Vs=!0}catch{}}function Wc(){if(!Ys){Ys=!0;try{let t=Date.now()-Gc*864e5;for(let e of Dc(Qn)){if(!e.startsWith("vibespot-")||!e.endsWith(".log"))continue;let n=e.slice(9,19),s=new Date(n).getTime();if(s&&s<t)try{Lc(zs(Qn,e))}catch{}}}catch{}}}function Bc(){let e=new Date().toISOString().slice(0,10);return zs(Qn,`vibespot-${e}.log`)}function Kc(){return new Date().toISOString().slice(11,23)}function Ks(t,e){if(Uc(),!!Vs){Ys||Wc();try{Fc(Bc(),`${Kc()} ${t} ${e}
298
- `)}catch{}}}var Qn,Gc,Vs,Ys,E,ve=J(()=>{"use strict";g();Qn=zs(Hc(),".vibespot","logs"),Gc=7,Vs=!1,Ys=!1;E={info(t,e,n){let s=n?`[${t}] ${e} ${JSON.stringify(n)}`:`[${t}] ${e}`;console.log(s),Ks("INFO",s)},warn(t,e,n){let s=n?`[${t}] ${e} ${JSON.stringify(n)}`:`[${t}] ${e}`;console.warn(s),Ks("WARN",s)},error(t,e,n){let s=n instanceof Error?n.message:n?String(n):"",o=s?`[${t}] ${e}: ${s}`:`[${t}] ${e}`;console.error(o),Ks("ERROR",o)}}});function Le(t){try{return JSON.parse(t)}catch{}let e=t,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(e)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let a=parseInt(i[1],10);if(a<=n)return null;n=a;let r=Math.max(0,a-5),c=e.slice(r,a+1).lastIndexOf('"');if(c===-1)return null;let d=r+c;if(d>0&&e[d-1]==="\\")return null;e=e.slice(0,d)+'\\"'+e.slice(d+1)}return null}function nn(t){let e=t.indexOf('"modules"');if(e===-1)return null;let n=t.indexOf("[",e);if(n===-1)return null;let s=-1,o=0,i=!1,a=!1;for(let d=n+1;d<t.length;d++){let u=t[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=t.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return Le(c)}function qs(t){return{moduleName:String(t.moduleName||""),fieldsJson:typeof t.fieldsJson=="string"?t.fieldsJson:JSON.stringify(t.fieldsJson,null,2),metaJson:typeof t.metaJson=="string"?t.metaJson:JSON.stringify(t.metaJson,null,2),moduleHtml:String(t.moduleHtml||""),moduleCss:String(t.moduleCss||""),moduleJs:t.moduleJs?String(t.moduleJs):void 0}}function ur(t,e){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(t))!==null;)try{E.info("parse","Found vibespot-modules block",{length:s[1].length});let i=Le(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 a=i;a.modules&&Array.isArray(a.modules)&&(De({modules:a.modules.map(r=>qs(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){E.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(t))!==null;)if(s[1].includes('"modules"'))try{let a=Le(s[1]);if(!a||typeof a!="object")throw new Error("Invalid JSON after repair");let r=a;r.modules&&Array.isArray(r.modules)&&(De({modules:r.modules.map(l=>qs(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){E.warn("parse","Failed to parse JSON module block",{error:a instanceof Error?a.message:String(a)})}}if(!n&&(t.match(/```/g)||[]).length%2!==0&&t.includes('"modules"')){E.info("parse","Detected truncated response (odd fence count), attempting salvage");let a=t.lastIndexOf("```"),r=t.slice(a+3);r=r.replace(/^[\w-]*\s*\n?/,"");let l=nn(r);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(E.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),De({modules:c.modules.map(d=>qs(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,e&&e("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){E.info("parse","No modules applied",{responseLength:t.length,hasVibespot:t.includes("vibespot-modules"),hasModules:t.includes('"modules"'),fenceCount:(t.match(/```/g)||[]).length});let i=t.includes("vibespot-modules")||t.includes('"modules"'),a=/\bmodule|modul/i.test(t)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(t)||/\|.*\|.*\|/m.test(t));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.";E.warn("parse",r),e&&e(r)}}}var Zn=J(()=>{"use strict";g();Se();ve()});function Tt(){let t=v();return t?{pageType:Ce()?.pageType,brandAssets:t.brandAssets}:{}}function Et(t,e,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
297
+ </html>`}function ao(e){let t=S();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:rs(i)}}catch{s={module:{}}}let o=oo(n.moduleHtml,s);return io({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 as=j(()=>{"use strict";g();kr();Se()});import{appendFileSync as bd,mkdirSync as Sd,readdirSync as vd,unlinkSync as xd}from"fs";import{join as po}from"path";import{homedir as wd}from"os";function Ad(){if(!uo)try{Sd(ls,{recursive:!0}),uo=!0}catch{}}function kd(){if(!mo){mo=!0;try{let e=Date.now()-Cd*864e5;for(let t of vd(ls)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{xd(po(ls,t))}catch{}}}catch{}}}function Id(){let t=new Date().toISOString().slice(0,10);return po(ls,`vibespot-${t}.log`)}function Td(){return new Date().toISOString().slice(11,23)}function co(e,t){if(Ad(),!!uo){mo||kd();try{bd(Id(),`${Td()} ${e} ${t}
298
+ `)}catch{}}}var ls,Cd,uo,mo,T,ve=j(()=>{"use strict";g();ls=po(wd(),".vibespot","logs"),Cd=7,uo=!1,mo=!1;T={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),co("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),co("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),co("ERROR",o)}}});function Ge(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 ln(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 Ge(c)}function fo(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 Tr(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{T.info("parse","Found vibespot-modules block",{length:s[1].length});let i=Ge(s[1]);if(!i||typeof i!="object")throw T.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let a=i;a.modules&&Array.isArray(a.modules)&&(Le({modules:a.modules.map(r=>fo(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){T.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let a=Ge(s[1]);if(!a||typeof a!="object")throw new Error("Invalid JSON after repair");let r=a;r.modules&&Array.isArray(r.modules)&&(Le({modules:r.modules.map(l=>fo(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){T.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"')){T.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=ln(r);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(T.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),Le({modules:c.modules.map(d=>fo(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){T.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),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.";T.warn("parse",r),t&&t(r)}}}var cs=j(()=>{"use strict";g();Se();ve()});function Ot(){let e=S();return e?{pageType:Ce()?.pageType,brandAssets:e.brandAssets}:{}}function $r(e,t,n=!1,s,o){let a=[{type:"text",text:Ed(t,n)}];if(n){let l=`## HubSpot CMS Rules
299
+ ${Ee()}
300
+
301
+ ## Conversion Guide Reference
302
+ ${e}`;a.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
303
+ - Use modern, clean design with proper spacing and typography
304
+ - Include responsive CSS (mobile breakpoint at 767px)
305
+ - Add scroll animation classes where appropriate
306
+ - Use CSS custom properties for the design system
307
+ - Make content editable through fields.json (headlines, text, colors, images, links)
308
+
309
+ ## Scroll Animation CSS Fallback (IMPORTANT)
310
+ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include a CSS-only fallback animation in sharedCss that auto-reveals elements after a delay. This ensures content is visible even if the JS file fails to load:
311
+ \`\`\`css
312
+ @keyframes scroll-animate-fallback {
313
+ to { opacity: 1; transform: none; }
314
+ }
315
+ .scroll-animate {
316
+ animation: scroll-animate-fallback 0.1s 3s forwards;
317
+ }
318
+ .scroll-animate.visible {
319
+ animation: none;
320
+ }
321
+ \`\`\`
322
+ 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.
323
+
324
+ ## Design Guide
325
+ ${Gs()}
326
+
327
+ ## Content & Copywriting Guide
328
+ ${Us()}
329
+
330
+ ## HubSpot CMS Rules
331
+ ${Ee()}
332
+
333
+ ## Conversion Guide Reference
334
+ ${e}`;a.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let r=$d(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 $d(e,t){let n=[];if(e){let s=Ws(e);s&&n.push(`## Page Type Context
335
+ ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
336
+ ${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
337
+ ${t.brandvoice}`),t?.humanify!==!1){let s=Bs();s&&n.push(`## Anti-AI Copy Rules (Humanify)
338
+ ${s}`)}return n.join(`
339
+
340
+ `)}function Ed(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
299
341
 
300
342
  ## Your Role
301
343
  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.
@@ -358,6 +400,85 @@ NEVER respond with only a text summary. The vibespot-modules JSON block is manda
358
400
  - Size placeholders appropriately for their context (hero: 1920x800, cards: 600x400, icons: 200x200, avatars: 150x150)
359
401
  - If the user's intent is ambiguous (design reference vs page asset), ask them to clarify
360
402
 
403
+ ## Navigation & Anchor Links
404
+ - For anchor links, add an id attribute directly on the module's root element in module.html:
405
+ <section id="pricing" class="..."> (NOT on an external wrapper \u2014 HubSpot's dnd system strips those)
406
+ - The id should be the moduleName lowercased with spaces replaced by hyphens (e.g. "Pricing Cards" \u2192 id="pricing-cards")
407
+ - For navigation/menu modules, use anchor links that match these ids: e.g. href="#features"
408
+ - Always include smooth scrolling behavior in navigation link clicks
409
+ - For nav modules, make menu items editable via a repeater group with "label" (text) and "anchor" (text) fields`+(t?`
410
+
411
+ ## When modifying existing modules
412
+ The current template's modules are listed in page order in the user message. This sequence forms the page narrative.
413
+
414
+ - **Modify**: When the user references an existing module by name or describes changes to existing content, update that module's code. Keep the moduleName unchanged.
415
+ - **Add**: When the user asks for a new section, create a new module and insert it at the narratively correct position. Consider the page flow: navigation \u2192 hero \u2192 content sections \u2192 social proof \u2192 CTA \u2192 footer.
416
+ - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
417
+ - **Remove**: When the user asks to remove a section, omit it from the output.
418
+ - **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.
419
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function cn(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
420
+
421
+ ## Your Role
422
+ 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.
423
+
424
+ ## Output Format \u2014 CRITICAL
425
+ You MUST include a \`\`\`vibespot-modules code block with ALL module data as JSON. This is the ONLY way modules get created. A text summary, table, or description of modules does NOT work \u2014 you must output the actual JSON.
426
+
427
+ \`\`\`vibespot-modules
428
+ {
429
+ "modules": [
430
+ {
431
+ "moduleName": "Hero",
432
+ "fieldsJson": "...",
433
+ "metaJson": "...",
434
+ "moduleHtml": "...",
435
+ "moduleCss": "...",
436
+ "moduleJs": null
437
+ }
438
+ ],
439
+ "sharedCss": "...",
440
+ "sharedJs": "..."
441
+ }
442
+ \`\`\`
443
+
444
+ NEVER respond with only a text summary. The vibespot-modules JSON block is mandatory.
445
+
446
+ ## Rules
447
+ - fieldsJson, metaJson must be valid JSON strings
448
+ - moduleHtml uses HubL template syntax ({{ module.field_name }})
449
+ - moduleCss is vanilla CSS (no Tailwind, no Sass)
450
+ - moduleJs is optional vanilla JS (wrapped in IIFE)
451
+ - NEVER use CDN imports (@import url(), <link> to external CDNs like Google Fonts, cdnjs, unpkg, jsdelivr)
452
+ - For fonts, use system font stacks with good fallbacks. Define them as CSS custom properties in sharedCss:
453
+ --font-heading: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
454
+ --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
455
+ --font-mono: 'SF Mono', SFMono-Regular, Consolas, monospace;
456
+ - All assets must be self-contained \u2014 no external HTTP requests in CSS or HTML
457
+ - Use "type": "text" (NEVER "textarea" \u2014 it's deprecated)
458
+ - NEVER use "name": "name" (reserved) \u2014 use "item_name" instead
459
+ - NEVER put literal \\n newline sequences in field default values \u2014 use plain text without line breaks
460
+ - Wrap style fields in a "styles" group with "tab": "STYLE"
461
+ - All CSS classes must use a unique prefix "${t}-" to avoid theme conflicts
462
+ - Use BEM naming: ${t}-module__element--modifier
463
+ - metaJson must include: host_template_types: ["PAGE"], is_available_for_new_content: true
464
+ - For repeater groups, use "occurrence": { "min": 0, "max": 100 } and iterate with {% for %}
465
+ - Color fields: type "color", default { "color": "#hex", "opacity": 100 }
466
+ - Link fields: type "link", default { "url": { "href": "#", "type": "EXTERNAL" }, "open_in_new_tab": false, "no_follow": false }
467
+ - Image fields: type "image", default { "src": "https://placehold.co/800x600/1a1a2e/ffffff?text=Replace+in+HubSpot", "alt": "Placeholder image", "width": 800, "height": 600 }
468
+
469
+ ## Images & Media
470
+ - Users can upload images that get placed in the theme's assets/ folder automatically
471
+ - When the user uploads an image and wants it on the page, reference it with: {{ get_asset_url("${t}/assets/filename.ext") }}
472
+ - IMPORTANT: get_asset_url() paths must include the theme name prefix "${t}/" because HubSpot resolves from the Design Manager root
473
+ - For background images with uploaded assets: style="background-image: url('{{ get_asset_url(\\"${t}/assets/filename.ext\\") }}')"
474
+ - For images without an uploaded asset, use image fields (type "image") with placehold.co defaults
475
+ - ALWAYS use image fields (type "image") so users can swap images in the page editor
476
+ - Use placehold.co URLs as defaults so the preview looks complete (e.g. https://placehold.co/800x600/1a1a2e/ffffff?text=Hero+Image)
477
+ - In module.html, render images with: <img src="{{ module.field_name.src }}" alt="{{ module.field_name.alt }}" width="{{ module.field_name.width }}" height="{{ module.field_name.height }}">
478
+ - For background images in CSS, use inline styles: style="background-image: url('{{ module.field_name.src }}')"
479
+ - Size placeholders appropriately for their context (hero: 1920x800, cards: 600x400, icons: 200x200, avatars: 150x150)
480
+ - If the user's intent is ambiguous (design reference vs page asset), ask them to clarify
481
+
361
482
  ## Navigation & Anchor Links
362
483
  - For anchor links, add an id attribute directly on the module's root element in module.html:
363
484
  <section id="pricing" class="..."> (NOT on an external wrapper \u2014 HubSpot's dnd system strips those)
@@ -374,7 +495,7 @@ The current template's modules are listed in page order in the user message. Thi
374
495
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
375
496
  - **Remove**: When the user asks to remove a section, omit it from the output.
376
497
  - **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.
377
- - **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?Qo(s):"",r=a?`
498
+ - **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?Ws(s):"",r=a?`
378
499
 
379
500
  ## Page Type Context
380
501
  ${a}`:"",l="";if(o?.styleguide&&(l+=`
@@ -383,16 +504,16 @@ ${a}`:"",l="";if(o?.styleguide&&(l+=`
383
504
  ${o.styleguide}`),o?.brandvoice&&(l+=`
384
505
 
385
506
  ## Brand Voice
386
- ${o.brandvoice}`),o?.humanify!==!1){let d=Xo();d&&(l+=`
507
+ ${o.brandvoice}`),o?.humanify!==!1){let d=Bs();d&&(l+=`
387
508
 
388
509
  ## Anti-AI Copy Rules (Humanify)
389
510
  ${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+`
390
511
 
391
512
  ## HubSpot CMS Rules
392
- ${Ze()}
513
+ ${Ee()}
393
514
 
394
515
  ## Conversion Guide Reference
395
- ${t}`+c:i+r+l+`
516
+ ${e}`+c:i+r+l+`
396
517
 
397
518
  ## Design Quality
398
519
  - Use modern, clean design with proper spacing and typography
@@ -417,111 +538,111 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
417
538
  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.
418
539
 
419
540
  ## Design Guide
420
- ${zo()}
541
+ ${Gs()}
421
542
 
422
543
  ## Content & Copywriting Guide
423
- ${qo()}
544
+ ${Us()}
424
545
 
425
546
  ## HubSpot CMS Rules
426
- ${Ze()}
547
+ ${Ee()}
427
548
 
428
549
  ## Conversion Guide Reference
429
- ${t}`+c}function sn(){let t=v(),e=[],n=t.modules,s=n.length;if(s>0){e.push(`
550
+ ${e}`+c}function dn(){let e=S(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
430
551
 
431
552
  ## Page Narrative (module sequence)
432
- `),e.push(`This template has ${s} module${s===1?"":"s"} in this order:
433
- `);for(let r=0;r<s;r++)e.push(`${r+1}. ${n[r].moduleName}
434
- `);e.push(`
553
+ `),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
554
+ `);for(let r=0;r<s;r++)t.push(`${r+1}. ${n[r].moduleName}
555
+ `);t.push(`
435
556
  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.
436
- `),e.push(`
557
+ `),t.push(`
437
558
  ## Current Module State
438
- `);for(let r=0;r<s;r++){let l=n[r];e.push(`
559
+ `);for(let r=0;r<s;r++){let l=n[r];t.push(`
439
560
  ### ${r+1}/${s}: ${l.moduleName}.module
440
- `),e.push(`**fields.json:**
561
+ `),t.push(`**fields.json:**
441
562
  \`\`\`json
442
563
  ${l.fieldsJson}
443
564
  \`\`\`
444
- `),e.push(`**module.html:**
565
+ `),t.push(`**module.html:**
445
566
  \`\`\`html
446
567
  ${l.moduleHtml}
447
568
  \`\`\`
448
- `),e.push(`**module.css:**
569
+ `),t.push(`**module.css:**
449
570
  \`\`\`css
450
571
  ${l.moduleCss}
451
572
  \`\`\`
452
- `),l.moduleJs&&e.push(`**module.js:**
573
+ `),l.moduleJs&&t.push(`**module.js:**
453
574
  \`\`\`js
454
575
  ${l.moduleJs}
455
576
  \`\`\`
456
- `)}t.sharedCss&&e.push(`
577
+ `)}e.sharedCss&&t.push(`
457
578
  ### Shared CSS
458
579
  \`\`\`css
459
- ${t.sharedCss}
580
+ ${e.sharedCss}
460
581
  \`\`\`
461
- `),t.sharedJs&&e.push(`
582
+ `),e.sharedJs&&t.push(`
462
583
  ### Shared JS
463
584
  \`\`\`js
464
- ${t.sharedJs}
585
+ ${e.sharedJs}
465
586
  \`\`\`
466
- `)}let o=nt(),i=new Set(t.modules.map(r=>r.moduleName)),a=o.filter(r=>!i.has(r.module.moduleName));if(a.length>0){e.push(`
587
+ `)}let o=rt(),i=new Set(e.modules.map(r=>r.moduleName)),a=o.filter(r=>!i.has(r.module.moduleName));if(a.length>0){t.push(`
467
588
 
468
589
  ## Available modules in this theme (reusable)
469
- `);for(let r of a)e.push(`- ${r.module.moduleName} (used in: ${r.usedIn.join(", ")})
470
- `);e.push(`
590
+ `);for(let r of a)t.push(`- ${r.module.moduleName} (used in: ${r.usedIn.join(", ")})
591
+ `);t.push(`
471
592
  The user can ask to reuse any of these modules by name.
472
- `)}return e.join("")}function Xs(t,e){let n=v(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===t&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=sn(),a="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(a=`
593
+ `)}return t.join("")}function go(e,t){let n=S(),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=dn(),a="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(a=`
473
594
 
474
595
  ## Available Theme Assets
475
596
  These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
476
597
  ${d.map(u=>`- ${u.filename} (${u.originalName}) \u2192 get_asset_url("${n.themeName}/assets/${u.filename}")`).join(`
477
- `)}`)}let r=t;i&&(r+=`
598
+ `)}`)}let r=e;i&&(r+=`
478
599
 
479
600
  ---
480
- ${i}`),a&&(r+=a),r+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let l=e&&e.length>0;if(l)for(let d of e)d.type==="document"&&d.extractedText&&(r+=`
601
+ ${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+=`
481
602
 
482
603
  ---
483
604
  [Attached document: ${d.originalName}]
484
605
  ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(r+=`
485
606
 
486
- [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?e.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:r}),o.push({role:"user",content:d})}else o.push({role:"user",content:r});return o}var mr=J(()=>{"use strict";g();Ve();Se()});import{spawn as Vc}from"child_process";async function Yc(){return Qs||(Qs=(await import("@anthropic-ai/sdk")).default),Qs}function pr(t){if(!t?.length)return"";let e=[];for(let n of t)n.type==="image"&&n.usage==="asset"&&n.assetPath&&e.push(`
487
- [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&e.push(`
607
+ [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 Er=j(()=>{"use strict";g();qe();Se()});import{spawn as _d}from"child_process";async function _r(){return ho||(ho=(await import("@anthropic-ai/sdk")).default),ho}function Pr(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
608
+ [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
488
609
 
489
610
  ---
490
611
  [Attached document: ${n.originalName}]
491
- ${n.extractedText}`);return e.join("")}async function fr(t,e,n,s,o,i,a,r){let l=await Yc(),c=new l({apiKey:e}),d=le(),p=v().modules.length>0,f=Xs(t,r),h=Tt(),y=Et(d,n,p,h.pageType,h.brandAssets);E.info("anthropic","API call",{model:s,systemPromptLength:y.length,messageCount:f.length,messageRoles:f.map(b=>b.role),lastMessageLength:typeof f[f.length-1]?.content=="string"?f[f.length-1].content.length:"multimodal",conversionGuideLength:d.length});for(let b=0;;b++)try{let A="",w=0,$=i||(()=>{});$(fe[0]);let R=setInterval(()=>{w++,$(fe[Math.min(w,fe.length-1)])},6e3);try{let M=c.messages.stream({model:s,max_tokens:48e3,system:y,messages:f});for await(let N of M)if(N.type==="content_block_delta"&&N.delta.type==="text_delta"){let L=N.delta.text;A+=L,o(L)}}finally{clearInterval(R)}a&&a(A);return}catch(A){let w=A.status,$=A.error?.type;if(!(w===429||$==="rate_limit_error"||A instanceof Error&&A.message.includes("429"))||b>=Zs.length)throw A;let M=Zs[b];E.warn("ai-engine",`Rate limited (429), attempt ${b+1}/${Zs.length} \u2014 waiting ${M}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${M}s...`),await new Promise(N=>setTimeout(N,M*1e3)),i&&i("Retrying...")}}async function gr(t,e,n,s,o,i,a,r){let l=le(),c=v().modules.length>0,d=Xs(t,r),u=Tt(),p=d.map(M=>typeof M.content=="string"?M:{role:M.role,content:M.content.map(N=>N.type==="text"?{type:"text",text:N.text}:{type:"image_url",image_url:{url:`data:${N.source.media_type};base64,${N.source.data}`}})}),f=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:Et(l,n,c,u.pageType,u.brandAssets)},...p]})});if(!f.ok){let M=await f.text();throw new Error(`OpenAI API error (${f.status}): ${M}`)}let h=0,y=i||(()=>{});y(fe[0]);let b=setInterval(()=>{h++,y(fe[Math.min(h,fe.length-1)])},6e3),A="",w=f.body.getReader(),$=new TextDecoder,R="";try{for(;;){let{done:M,value:N}=await w.read();if(M)break;R+=$.decode(N,{stream:!0});let L=R.split(`
492
- `);R=L.pop()||"";for(let ne of L){if(!ne.startsWith("data: "))continue;let U=ne.slice(6).trim();if(U==="[DONE]")break;try{let O=JSON.parse(U).choices?.[0]?.delta?.content;O&&(A+=O,o(O))}catch{}}}}finally{clearInterval(b)}a&&a(A)}async function hr(t,e,n,s,o,i,a){let r=le(),l=v(),c=l.modules.length>0,d=sn(),u=Tt(),p=[];for(let U of l.messages.slice(-20))p.push({role:U.role==="assistant"?"model":"user",parts:[{text:U.content}]});let f=d?`${t}
612
+ ${n.extractedText}`);return t.join("")}async function Mr(e,t,n,s,o,i,a){for(let r=0;;r++)try{let l="",c=0,d=i||(()=>{});d(fe[0]);let u=setInterval(()=>{c++,d(fe[Math.min(c,fe.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 h=f.delta.text;l+=h,o(h)}}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>=yo.length)throw l;let m=yo[r];T.warn("ai-engine",`Rate limited (429), attempt ${r+1}/${yo.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 Or(e,t,n){let s=oe(),i=S().modules.length>0,a=go(e,n),r=Ot(),l=$r(s,t,i,r.pageType,r.brandAssets);return{messages:a,systemBlocks:l,conversionGuide:s,editMode:i}}async function Nr(e,t,n,s,o,i,a,r){let l=await _r(),c=new l({apiKey:t}),{messages:d,systemBlocks:u}=Or(e,n,r);T.info("anthropic","API call",{model:s,systemBlockCount:u.length,cachedBlocks:u.filter(m=>m.cache_control).length,messageCount:d.length}),await Mr(c,u,d,s,o,i,a)}async function Rr(e,t,n,s,o,i,a){let r=await Ms();if(!r)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await _r(),c=new l({authToken:r,defaultHeaders:Ht}),{messages:d,systemBlocks:u}=Or(e,t,a),m=[{type:"text",text:At},...u];T.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(f=>f.cache_control).length,messageCount:d.length}),await Mr(c,m,d,n,s,o,i)}async function Fr(e,t,n,s,o,i,a,r){let l=oe(),c=S().modules.length>0,d=go(e,r),u=Ot(),m=d.map(G=>typeof G.content=="string"?G:{role:G.role,content:G.content.map(E=>E.type==="text"?{type:"text",text:E.text}:{type:"image_url",image_url:{url:`data:${E.source.media_type};base64,${E.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:cn(l,n,c,u.pageType,u.brandAssets)},...m]})});if(!f.ok){let G=await f.text();throw new Error(`OpenAI API error (${f.status}): ${G}`)}let h=0,y=i||(()=>{});y(fe[0]);let v=setInterval(()=>{h++,y(fe[Math.min(h,fe.length-1)])},6e3),C="",k=f.body.getReader(),P=new TextDecoder,O="";try{for(;;){let{done:G,value:E}=await k.read();if(G)break;O+=P.decode(E,{stream:!0});let R=O.split(`
613
+ `);O=R.pop()||"";for(let W of R){if(!W.startsWith("data: "))continue;let L=W.slice(6).trim();if(L==="[DONE]")break;try{let F=JSON.parse(L).choices?.[0]?.delta?.content;F&&(C+=F,o(F))}catch{}}}}finally{clearInterval(v)}a&&a(C)}async function jr(e,t,n,s,o,i,a){let r=oe(),l=S(),c=l.modules.length>0,d=dn(),u=Ot(),m=[];for(let L of l.messages.slice(-20))m.push({role:L.role==="assistant"?"model":"user",parts:[{text:L.content}]});let f=d?`${e}
493
614
 
494
615
  ---
495
- ${d}`:t;if(a?.length)for(let U of a)U.type==="document"&&U.extractedText&&(f+=`
616
+ ${d}`:e;if(a?.length)for(let L of a)L.type==="document"&&L.extractedText&&(f+=`
496
617
 
497
618
  ---
498
- [Attached document: ${U.originalName}]
499
- ${U.extractedText}`),U.type==="image"&&U.usage==="asset"&&U.assetPath&&(f+=`
619
+ [Attached document: ${L.originalName}]
620
+ ${L.extractedText}`),L.type==="image"&&L.usage==="asset"&&L.assetPath&&(f+=`
500
621
 
501
- [Uploaded image: ${U.originalName} \u2192 available as get_asset_url("${U.assetPath}")]`);let h=[];if(a?.length)for(let U of a)U.type==="image"&&U.base64&&h.push({inlineData:{mimeType:U.mimeType,data:U.base64}});h.push({text:f}),p.push({role:"user",parts:h});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${e}`,A=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:Et(r,n,c,u.pageType,u.brandAssets)}]},contents:p,generationConfig:{maxOutputTokens:48e3}})});if(!A.ok){let U=await A.text();throw new Error(`Gemini API error (${A.status}): ${U}`)}let w=0,$=o||(()=>{});$(fe[0]);let R=setInterval(()=>{w++,$(fe[Math.min(w,fe.length-1)])},6e3),M="",N=A.body.getReader(),L=new TextDecoder,ne="";try{for(;;){let{done:U,value:G}=await N.read();if(U)break;ne+=L.decode(G,{stream:!0});let O=ne.split(`
502
- `);ne=O.pop()||"";for(let z of O){if(!z.startsWith("data: "))continue;let ae=z.slice(6).trim();try{let Rt=JSON.parse(ae).candidates?.[0]?.content?.parts?.[0]?.text;Rt&&(M+=Rt,s(Rt))}catch{}}}}finally{clearInterval(R)}i&&i(M)}function es(t,e,n,s){return new Promise((o,i)=>{let a={...process.env};delete a.CLAUDECODE;let r=Vc(t,e,{stdio:["pipe","pipe","pipe"],env:a}),l="",c="",d=!1,u=h=>{d||(d=!0,h())};r.stdout.on("data",h=>{let y=h.toString();l+=y,s&&s(y)}),r.stderr.on("data",h=>{c+=h.toString()}),r.on("error",h=>u(()=>i(new Error(`${t} failed to start: ${h.message}`)))),r.on("close",h=>{u(()=>{h!==0?i(new Error(`${t} exited with code ${h}.
622
+ [Uploaded image: ${L.originalName} \u2192 available as get_asset_url("${L.assetPath}")]`);let h=[];if(a?.length)for(let L of a)L.type==="image"&&L.base64&&h.push({inlineData:{mimeType:L.mimeType,data:L.base64}});h.push({text:f}),m.push({role:"user",parts:h});let v=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${t}`,C=await fetch(v,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:cn(r,n,c,u.pageType,u.brandAssets)}]},contents:m,generationConfig:{maxOutputTokens:48e3}})});if(!C.ok){let L=await C.text();throw new Error(`Gemini API error (${C.status}): ${L}`)}let k=0,P=o||(()=>{});P(fe[0]);let O=setInterval(()=>{k++,P(fe[Math.min(k,fe.length-1)])},6e3),G="",E=C.body.getReader(),R=new TextDecoder,W="";try{for(;;){let{done:L,value:U}=await E.read();if(L)break;W+=R.decode(U,{stream:!0});let F=W.split(`
623
+ `);W=F.pop()||"";for(let X of F){if(!X.startsWith("data: "))continue;let le=X.slice(6).trim();try{let jt=JSON.parse(le).candidates?.[0]?.content?.parts?.[0]?.text;jt&&(G+=jt,s(jt))}catch{}}}}finally{clearInterval(O)}i&&i(G)}function ds(e,t,n,s){return new Promise((o,i)=>{let a={...process.env};delete a.CLAUDECODE;let r=_d(e,t,{stdio:["pipe","pipe","pipe"],env:a}),l="",c="",d=!1,u=h=>{d||(d=!0,h())};r.stdout.on("data",h=>{let y=h.toString();l+=y,s&&s(y)}),r.stderr.on("data",h=>{c+=h.toString()}),r.on("error",h=>u(()=>i(new Error(`${e} failed to start: ${h.message}`)))),r.on("close",h=>{u(()=>{h!==0?i(new Error(`${e} exited with code ${h}.
503
624
  `+(c?`Stderr: ${c.slice(0,500)}
504
- `:"")+(l?`Output: ${l.slice(0,500)}`:"No output"))):o(l)})}),r.stdin.on("error",()=>{}),r.stdin.write(n)?r.stdin.end():r.stdin.once("drain",()=>r.stdin.end());let f=setTimeout(()=>{r.kill(),u(()=>i(new Error(`${t} timed out after 5 minutes.
625
+ `:"")+(l?`Output: ${l.slice(0,500)}`:"No output"))):o(l)})}),r.stdin.on("error",()=>{}),r.stdin.write(n)?r.stdin.end():r.stdin.once("drain",()=>r.stdin.end());let f=setTimeout(()=>{r.kill(),u(()=>i(new Error(`${e} timed out after 5 minutes.
505
626
  `+(c?`Stderr: ${c.slice(0,500)}
506
- `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},3e5);r.on("close",()=>clearTimeout(f))})}async function yr(t,e,n,s,o,i){let a=le(),r=P(),l=v().modules.length>0,c=Tt(),d=Et(a,e,l,c.pageType,c.brandAssets);d+=`
627
+ `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},3e5);r.on("close",()=>clearTimeout(f))})}async function Jr(e,t,n,s,o,i){let a=oe(),r=_(),l=S().modules.length>0,c=Ot(),d=cn(a,t,l,c.pageType,c.brandAssets);d+=`
507
628
 
508
629
  ## User Request
509
- `+t,d+=sn(),d+=pr(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);let p=0,f=s||(()=>{});f(fe[0]);let h=setInterval(()=>{p++;let y=fe[Math.min(p,fe.length-1)];f(y)},6e3);try{let y=await es("claude",u,d,b=>{n(b)});o&&o(y)}finally{clearInterval(h)}}async function eo(t,e,n,s,o,i,a){let r=le(),l=v().modules.length>0,c=Tt(),d=Et(r,n,l,c.pageType,c.brandAssets);d+=`
630
+ `+e,d+=dn(),d+=Pr(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);let m=0,f=s||(()=>{});f(fe[0]);let h=setInterval(()=>{m++;let y=fe[Math.min(m,fe.length-1)];f(y)},6e3);try{let y=await ds("claude",u,d,v=>{n(v)});o&&o(y)}finally{clearInterval(h)}}async function bo(e,t,n,s,o,i,a){let r=oe(),l=S().modules.length>0,c=Ot(),d=cn(r,n,l,c.pageType,c.brandAssets);d+=`
510
631
 
511
632
  ## User Request
512
- `+e,d+=sn(),d+=pr(a),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,p;t==="gemini"?(u="gemini",p=[]):(u="codex",p=["exec","--full-auto"]);let f=0,h=o||(()=>{});h(fe[0]);let y=setInterval(()=>{f++;let b=fe[Math.min(f,fe.length-1)];h(b)},6e3);try{let b=await es(u,p,d,A=>{s(A)});i&&i(b)}finally{clearInterval(y)}}var Qs,fe,Zs,to=J(()=>{"use strict";g();Ve();ee();Se();mr();ve();Qs=null;fe=["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..."],Zs=[10,20,40,60,120]});function m(t,e,n){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(n))}function j(t,e){let n=[];t.on("data",s=>n.push(s)),t.on("end",()=>e(Buffer.concat(n).toString("utf-8")))}function no(t,e,n){j(t,s=>{try{n(JSON.parse(s||"{}"))}catch{m(e,400,{error:"Invalid JSON in request body"})}})}var ot=J(()=>{"use strict";g()});import{createWriteStream as zc,mkdirSync as br,existsSync as so,readFileSync as oo}from"fs";import{join as ft,extname as qc}from"path";import{randomUUID as Xc}from"crypto";import Qc from"busboy";function nd(t){return t.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function sd(t,e){if(!so(ft(t,e)))return e;let n=qc(e),s=e.slice(0,-n.length||void 0),o=1;for(;so(ft(t,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function od(t){let e=(await import("pdf-parse")).default,n=oo(t);return(await e(n)).text}async function id(t){return(await(await import("mammoth")).extractRawText({path:t})).value}function rd(t){return oo(t,"utf-8")}function vr(t,e){let n=v();if(!n){m(e,400,{error:"No active session"});return}if(!(t.headers["content-type"]||"").includes("multipart/form-data")){m(e,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],a=0,r=[],l=Qc({headers:t.headers,limits:{fileSize:Zc,files:10}});l.on("file",(c,d,u)=>{let{filename:p,mimeType:f}=u;if(a++,!td.has(f)){i.push(`Unsupported file type: ${p} (${f})`),d.resume();return}let h=Sr.has(f),y=nd(p),b=Xc(),A,w;h?(A=ft(n.themePath,"assets"),br(A,{recursive:!0}),w=sd(A,y)):(A=ft(n.themePath,".vibespot","uploads"),br(A,{recursive:!0}),w=`${b}-${y}`);let $=ft(A,w),R=zc($),M=0,N=!1;d.on("data",L=>{M+=L.length}),d.on("limit",()=>{N=!0,i.push(`File too large (>10MB): ${p}`)}),d.pipe(R),r.push(new Promise(L=>{R.on("finish",()=>{if(!N){let ne={id:b,filename:w,originalName:p,type:h?"image":"document",usage:h?"asset":"context",mimeType:f,size:M,addedAt:new Date().toISOString()};o.push(ne),ji(ne)}L()}),R.on("error",()=>{i.push(`Failed to write: ${p}`),L()})}))}),l.on("finish",async()=>{await Promise.all(r);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 od(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await id(d):c.extractedText=rd(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(a===0){m(e,400,{error:"No files uploaded"});return}m(e,200,{files:o.map(c=>({id:c.id,filename:c.filename,originalName:c.originalName,type:c.type,usage:c.usage,size:c.size})),errors:i.length>0?i:void 0})}),l.on("error",c=>{E.error("upload",`Busboy error: ${c}`),m(e,500,{error:"Upload failed"})}),t.pipe(l)}function wr(t){let e=v();return e?.assets?t.map(n=>{let s=e.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=ft(e.themePath,"assets",s.filename);so(i)&&(o.base64=oo(i).toString("base64")),o.assetPath=`${e.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var Zc,Sr,ed,td,io=J(()=>{"use strict";g();ot();Se();ve();Zc=10*1024*1024,Sr=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),ed=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),td=new Set([...Sr,...ed])});async function xr(t,e){for(let n=0;;n++)try{return await t()}catch(s){let o=s.status,i=s.error?.type;if(!(o===429||i==="rate_limit_error"||s instanceof Error&&s.message.includes("429"))||n>=ro.length)throw s;let r=ro[n];E.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${ro.length} \u2014 waiting ${r}s`),e&&e(`Rate limited \u2014 retrying in ${r}s...`),await new Promise(l=>setTimeout(l,r*1e3)),e&&e("Retrying...")}}function ts(t){if(t&&typeof t=="object"&&!Array.isArray(t)){let e=t;for(let n of["fieldsJson","metaJson"])e[n]&&typeof e[n]=="object"&&(e[n]=JSON.stringify(e[n]))}return t}async function ad(){return ao||(ao=(await import("@anthropic-ai/sdk")).default),ao}async function ld(t,e,n){let s=await ad(),o=new s({apiKey:t}),i=n.messages;if(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};return xr(async()=>{let r=await o.messages.create({model:e,max_tokens:n.maxTokens||16e3,system:n.systemPrompt,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name}});for(let c of r.content)if(c.type==="tool_use")return{type:"structured",data:ts(c.input)};return{type:"text",text:r.content.filter(c=>c.type==="text").map(c=>c.text).join("")}},n.onStatus)}return xr(async()=>{let a="",r=o.messages.stream({model:e,max_tokens:n.maxTokens||16e3,system:n.systemPrompt,messages:i});for await(let l of r)l.type==="content_block_delta"&&l.delta.type==="text_delta"&&(a+=l.delta.text,n.onChunk&&n.onChunk(l.delta.text));return{type:"text",text:a}},n.onStatus)}function lo(t){let e={...t};if(e.type==="object"&&(e.additionalProperties=!1,e.properties&&typeof e.properties=="object")){let n={};for(let[s,o]of Object.entries(e.properties))n[s]=o&&typeof o=="object"?lo(o):o;e.properties=n}return e.items&&typeof e.items=="object"&&(e.items=lo(e.items)),e}async function cd(t,e,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:e,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:lo(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let r=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:ts(JSON.parse(r))}}catch{return E.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:r}}return{type:"text",text:r}}async function dd(t,e,n){let s=e||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${t}`,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 p=new Error(`Gemini rate limit: ${d}`);throw p.status=429,p}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:ts(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 ud(t){switch(t){case"claude-code":{let e=P(),n=["--print"];return e.claudeCodeModel&&n.push("--model",e.claudeCodeModel),{bin:"claude",args:n}}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: ${t}`)}}function md(t){let e=[t.systemPrompt];for(let n of t.messages){let s=n.role==="user"?"User":"Assistant",o=typeof n.content=="string"?n.content:n.content.map(i=>i.text).join(`
513
- `);e.push(`
633
+ `+t,d+=dn(),d+=Pr(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 f=0,h=o||(()=>{});h(fe[0]);let y=setInterval(()=>{f++;let v=fe[Math.min(f,fe.length-1)];h(v)},6e3);try{let v=await ds(u,m,d,C=>{s(C)});i&&i(v)}finally{clearInterval(y)}}var ho,fe,yo,So=j(()=>{"use strict";g();qe();Z();Ke();Se();Er();ve();ho=null;fe=["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..."],yo=[10,20,40,60,120]});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function N(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function vo(e,t,n){N(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var et=j(()=>{"use strict";g()});import{createWriteStream as Pd,mkdirSync as Dr,existsSync as xo,readFileSync as wo}from"fs";import{join as ht,extname as Md}from"path";import{randomUUID as Od}from"crypto";import Nd from"busboy";function Jd(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Dd(e,t){if(!xo(ht(e,t)))return t;let n=Md(t),s=t.slice(0,-n.length||void 0),o=1;for(;xo(ht(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function Hd(e){let t=(await import("pdf-parse")).default,n=wo(e);return(await t(n)).text}async function Ld(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function Gd(e){return wo(e,"utf-8")}function Lr(e,t){let n=S();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=Nd({headers:e.headers,limits:{fileSize:Rd,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:f}=u;if(a++,!jd.has(f)){i.push(`Unsupported file type: ${m} (${f})`),d.resume();return}let h=Hr.has(f),y=Jd(m),v=Od(),C,k;h?(C=ht(n.themePath,"assets"),Dr(C,{recursive:!0}),k=Dd(C,y)):(C=ht(n.themePath,".vibespot","uploads"),Dr(C,{recursive:!0}),k=`${v}-${y}`);let P=ht(C,k),O=Pd(P),G=0,E=!1;d.on("data",R=>{G+=R.length}),d.on("limit",()=>{E=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(O),r.push(new Promise(R=>{O.on("finish",()=>{if(!E){let W={id:v,filename:k,originalName:m,type:h?"image":"document",usage:h?"asset":"context",mimeType:f,size:G,addedAt:new Date().toISOString()};o.push(W),Qi(W)}R()}),O.on("error",()=>{i.push(`Failed to write: ${m}`),R()})}))}),l.on("finish",async()=>{await Promise.all(r);for(let c of o)if(c.type==="document"){let d=ht(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await Hd(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await Ld(d):c.extractedText=Gd(d),T.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){T.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(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=>{T.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Gr(e){let t=S();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=ht(t.themePath,"assets",s.filename);xo(i)&&(o.base64=wo(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 Rd,Hr,Fd,jd,Co=j(()=>{"use strict";g();et();Se();ve();Rd=10*1024*1024,Hr=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Fd=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),jd=new Set([...Hr,...Fd])});async function us(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>=Ao.length)throw s;let r=Ao[n];T.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${Ao.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 un(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 Ur(){return ko||(ko=(await import("@anthropic-ai/sdk")).default),ko}async function Ud(e,t,n,s,o){let i=await Ur(),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};return us(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}});for(let m of d.content)if(m.type==="tool_use")return{type:"structured",data:un(m.input)};return{type:"text",text:d.content.filter(m=>m.type==="text").map(m=>m.text).join("")}},n.onStatus)}return us(async()=>{let c="",d=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:r});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 Bd(e,t,n){let s=await Ur(),o=new s({authToken:e,defaultHeaders:Ht}),i=n.messages,a;if(n.systemBlocks?a=[{type:"text",text:At},...n.systemBlocks]:a=[{type:"text",text:At},{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};return us(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}});for(let d of l.content)if(d.type==="tool_use")return{type:"structured",data:un(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return us(async()=>{let r="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:a,messages:i});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 Io(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"?Io(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Io(t.items)),t}async function Wd(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:Io(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:un(JSON.parse(r))}}catch{return T.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:r}}return{type:"text",text:r}}async function Vd(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:un(JSON.parse(c))}}catch{return T.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function Kd(e){switch(e){case"claude-code":{let t=_(),n=["--print"];return t.claudeCodeModel&&n.push("--model",t.claudeCodeModel),{bin:"claude",args:n}}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 Yd(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(`
634
+ `);t.push(`
514
635
 
515
636
  ## ${s}
516
- ${o}`)}if(t.structuredOutput){let n=Cr(t.structuredOutput.schema);e.push(`
637
+ ${o}`)}if(e.structuredOutput){let n=Br(e.structuredOutput.schema);t.push(`
517
638
 
518
639
  ## Output Format \u2014 CRITICAL
519
640
  Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
520
641
 
521
642
  The JSON must match this structure:
522
- ${n}`)}return e.join("")}function Cr(t,e=0){let n=" ".repeat(e),s=t.properties,o=t.required||[];if(!s)return`${n}${JSON.stringify(t)}`;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 p=r.items.type||"object";i.push(`${n} "${a}": ${c}<${p}>${l}${d}${u}`)}else c==="object"&&r.properties?i.push(`${n} "${a}": ${Cr(r,e+1)}${l}${d}`):i.push(`${n} "${a}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
523
- `)}function pd(t){let e=t.trim(),n=Le(e);if(n&&typeof n=="object")return n;let s=e.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let r=s[1].trim(),l=Le(r);if(l&&typeof l=="object")return l;let c=nn(r);if(c&&typeof c=="object")return c}let o=e.indexOf("{"),i=e.lastIndexOf("}");if(o!==-1&&i>o){let r=e.slice(o,i+1),l=Le(r);if(l&&typeof l=="object")return l;let c=nn(r);if(c&&typeof c=="object")return c}let a=nn(e);return a&&typeof a=="object"?a:null}async function fd(t,e,n){let{bin:s,args:o}=ud(t),i=md(n),a=await es(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:a};let r=pd(a);return r?{type:"structured",data:ts(r)}:(E.warn("agent-cli",`${t}: failed to parse structured output, returning text`,{outputPreview:a.slice(0,500),outputLength:a.length}),{type:"text",text:a})}async function hd(t,e,n,s){switch(E.info("agent-adapter",`${t} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),t){case"anthropic-api":return ld(e,n,s);case"openai-api":return cd(e,n,s);case"gemini-api":return dd(e,n,s);default:throw new Error(`Unsupported API engine: ${t}`)}}async function Ne(t,e,n,s){return gd.has(t)?hd(t,e,n,s):(E.info("agent-adapter",`${t} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),fd(t,n,s))}function ns(t){return t==="anthropic-api"||t==="openai-api"||t==="gemini-api"||t==="claude-code"||t==="gemini-cli"||t==="codex-cli"}function on(t){return t==="claude-code"||t==="gemini-cli"||t==="codex-cli"}var ro,ao,gd,it=J(()=>{"use strict";g();to();Zn();ee();ve();ro=[10,20,40,60,120];ao=null;gd=new Set(["anthropic-api","openai-api","gemini-api"])});function Ar(t,e,n,s){let o=e.length>0?`Current template modules (in page order):
524
- ${e.map((r,l)=>`${l+1}. ${r}`).join(`
643
+ ${n}`)}return t.join("")}function Br(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}": ${Br(r,t+1)}${l}${d}`):i.push(`${n} "${a}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
644
+ `)}function zd(e){let t=e.trim(),n=Ge(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=Ge(r);if(l&&typeof l=="object")return l;let c=ln(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=Ge(r);if(l&&typeof l=="object")return l;let c=ln(r);if(c&&typeof c=="object")return c}let a=ln(t);return a&&typeof a=="object"?a:null}async function qd(e,t,n){let{bin:s,args:o}=Kd(e),i=Yd(n),a=await ds(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:a};let r=zd(a);return r?{type:"structured",data:un(r)}:(T.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:a.slice(0,500),outputLength:a.length}),{type:"text",text:a})}async function Qd(e,t,n,s){switch(T.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 Ud(t,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(Ke(),Os)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return Bd(i,n,s)}case"openai-api":return Wd(t,n,s);case"gemini-api":return Vd(t,n,s);default:throw new Error(`Unsupported API engine: ${e}`)}}async function Pe(e,t,n,s){return Xd.has(e)?Qd(e,t,n,s):(T.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),qd(e,n,s))}function ms(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function mn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Ao,ko,Xd,lt=j(()=>{"use strict";g();So();cs();Z();Ke();ve();Ao=[10,20,40,60,120];ko=null;Xd=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api"])});function Wr(e,t,n,s){let o=t.length>0?`Current template modules (in page order):
645
+ ${t.map((r,l)=>`${l+1}. ${r}`).join(`
525
646
  `)}`:"No modules yet (new page).",i=n.length>0?`
526
647
 
527
648
  Module library (reusable from other templates):
@@ -533,7 +654,7 @@ ${s}`:"";return`You are the Intent Analyzer for vibeSpot, a HubSpot CMS page bui
533
654
 
534
655
  Your job: classify the user's request and plan which modules need work. You do NOT generate module code \u2014 you only plan.
535
656
 
536
- ## Theme: "${t}"
657
+ ## Theme: "${e}"
537
658
 
538
659
  ${o}${i}${a}
539
660
 
@@ -576,11 +697,11 @@ CRITICAL: When the user corrects a misclassification (e.g., "I was referencing t
576
697
  If the user asks for multiple things (e.g., "make hero taller AND add testimonials"), capture ALL parts:
577
698
  - Affected existing modules in \`affectedModules\`
578
699
  - New modules in \`newModules\`
579
- - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Ir,kr=J(()=>{"use strict";g();Ir={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 $r(t,e,n,s,o,i,a){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let r=e.modules.map(f=>f.moduleName),l=Ar(e.themeName,r,a,e.brandAssets?.themeContext),c=[],d=e.messages.slice(-6);for(let f of d)if(f.role==="user"||f.role==="assistant"){let h=f.role==="assistant"&&f.content.length>300?f.content.slice(0,300)+"...":f.content;c.push({role:f.role,content:h})}c.push({role:"user",content:t});let u=await Ne(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Ir,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){E.warn("intent-analyzer","Did not get structured output, falling back");let f=e.modules.length===0;return{intent:f?"create":"modify",affectedModules:f?[]:r,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:f}}let p=u.data;return p.affectedModules=p.affectedModules||[],p.unchangedModules=p.unchangedModules||[],p.newModules=p.newModules||[],p.guidesNeeded=p.guidesNeeded||[],E.info("intent-analyzer","Plan",{intent:p.intent,affected:p.affectedModules.length,unchanged:p.unchangedModules.length,new:p.newModules.length,reuse:p.reuseModules?.length||0,designSystem:p.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:yd(p)}),p}function yd(t){let e=[`Intent: ${t.intent}`];return t.affectedModules.length>0&&e.push(`Modifying: ${t.affectedModules.join(", ")}`),t.unchangedModules.length>0&&e.push(`Unchanged: ${t.unchangedModules.join(", ")}`),t.newModules.length>0&&e.push(`New: ${t.newModules.map(n=>n.name).join(", ")}`),t.reuseModules?.length&&e.push(`Reuse: ${t.reuseModules.map(n=>`${n.name} from ${n.sourceTemplate}`).join(", ")}`),t.designSystemChanges&&e.push("Design system changes: yes"),e.join(" | ")}var Tr=J(()=>{"use strict";g();it();kr();ve()});function Er(t,e){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
700
+ - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Vr,Kr=j(()=>{"use strict";g();Vr={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 Yr(e,t,n,s,o,i,a){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let r=t.modules.map(f=>f.moduleName),l=Wr(t.themeName,r,a,t.brandAssets?.themeContext),c=[],d=t.messages.slice(-6);for(let f of d)if(f.role==="user"||f.role==="assistant"){let h=f.role==="assistant"&&f.content.length>300?f.content.slice(0,300)+"...":f.content;c.push({role:f.role,content:h})}c.push({role:"user",content:e});let u=await Pe(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Vr,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){T.warn("intent-analyzer","Did not get structured output, falling back");let f=t.modules.length===0;return{intent:f?"create":"modify",affectedModules:f?[]:r,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||[],T.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:Zd(m)}),m}function Zd(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 zr=j(()=>{"use strict";g();lt();Kr();ve()});function To(e,t){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
580
701
 
581
702
  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.
582
703
 
583
- ## Theme: "${t}"
704
+ ## Theme: "${e}"
584
705
 
585
706
  ## Output Requirements
586
707
 
@@ -588,36 +709,36 @@ Your job: create a complete, production-ready CSS design system for a landing pa
588
709
  A flat object mapping CSS custom property names to values. Every variable your CSS references MUST be defined here. Include ALL of these categories:
589
710
 
590
711
  **Colors** (at minimum):
591
- - --${t}-color-bg: page background
592
- - --${t}-color-surface: card/section background
593
- - --${t}-color-dark: dark section background
594
- - --${t}-color-dark-surface: card bg inside dark sections
595
- - --${t}-color-text: primary text color
596
- - --${t}-color-text-inverse: text on dark backgrounds
597
- - --${t}-color-text-muted: secondary/muted text
598
- - --${t}-color-primary: primary brand color
599
- - --${t}-color-primary-dark: darker variant for hover states
600
- - --${t}-color-accent: accent/highlight color
601
- - --${t}-color-accent-light: light tint for pill/badge backgrounds
602
- - --${t}-color-border: default border color
603
- - --${t}-color-border-hover: border on hover
712
+ - --${e}-color-bg: page background
713
+ - --${e}-color-surface: card/section background
714
+ - --${e}-color-dark: dark section background
715
+ - --${e}-color-dark-surface: card bg inside dark sections
716
+ - --${e}-color-text: primary text color
717
+ - --${e}-color-text-inverse: text on dark backgrounds
718
+ - --${e}-color-text-muted: secondary/muted text
719
+ - --${e}-color-primary: primary brand color
720
+ - --${e}-color-primary-dark: darker variant for hover states
721
+ - --${e}-color-accent: accent/highlight color
722
+ - --${e}-color-accent-light: light tint for pill/badge backgrounds
723
+ - --${e}-color-border: default border color
724
+ - --${e}-color-border-hover: border on hover
604
725
 
605
726
  **Typography**:
606
- - --${t}-font-display: display/heading font stack (system fonts only)
607
- - --${t}-font-body: body text font stack (system fonts only)
608
- - --${t}-size-h1 through --${t}-size-h3: heading sizes using clamp()
609
- - --${t}-size-body, --${t}-size-lg, --${t}-size-small, --${t}-size-label
610
- - --${t}-leading-tight, --${t}-leading-snug, --${t}-leading-body: line heights
611
- - --${t}-tracking-tight, --${t}-tracking-wide: letter spacing
727
+ - --${e}-font-display: display/heading font stack (system fonts only)
728
+ - --${e}-font-body: body text font stack (system fonts only)
729
+ - --${e}-size-h1 through --${e}-size-h3: heading sizes using clamp()
730
+ - --${e}-size-body, --${e}-size-lg, --${e}-size-small, --${e}-size-label
731
+ - --${e}-leading-tight, --${e}-leading-snug, --${e}-leading-body: line heights
732
+ - --${e}-tracking-tight, --${e}-tracking-wide: letter spacing
612
733
 
613
734
  **Spacing**:
614
- - --${t}-space-xs through --${t}-space-xl, --${t}-space-section
615
- - --${t}-max-width: content max-width (1152-1280px)
735
+ - --${e}-space-xs through --${e}-space-xl, --${e}-space-section
736
+ - --${e}-max-width: content max-width (1152-1280px)
616
737
 
617
738
  **Effects**:
618
- - --${t}-radius-sm, --${t}-radius-md, --${t}-radius-lg, --${t}-radius-full
619
- - --${t}-shadow-card-hover, --${t}-shadow-button
620
- - --${t}-transition-fast, --${t}-transition-base, --${t}-transition-slow
739
+ - --${e}-radius-sm, --${e}-radius-md, --${e}-radius-lg, --${e}-radius-full
740
+ - --${e}-shadow-card-hover, --${e}-shadow-button
741
+ - --${e}-transition-fast, --${e}-transition-base, --${e}-transition-slow
621
742
 
622
743
  ### sharedCss
623
744
  Complete CSS file content. MUST include:
@@ -625,15 +746,15 @@ Complete CSS file content. MUST include:
625
746
  2. Reset (box-sizing, margin, padding)
626
747
  3. Body styles referencing your variables
627
748
  4. Typography rules (h1-h6, p)
628
- 5. Layout utilities (.${t}-container, .${t}-section, .${t}-section--dark)
629
- 6. Grid system (.${t}-grid, .${t}-grid--2/3/4 with responsive breakpoints)
630
- 7. Card component (.${t}-card with hover lift)
631
- 8. Button component (.${t}-btn, .${t}-btn--primary, .${t}-btn--secondary)
749
+ 5. Layout utilities (.${e}-container, .${e}-section, .${e}-section--dark)
750
+ 6. Grid system (.${e}-grid, .${e}-grid--2/3/4 with responsive breakpoints)
751
+ 7. Card component (.${e}-card with hover lift)
752
+ 8. Button component (.${e}-btn, .${e}-btn--primary, .${e}-btn--secondary)
632
753
  CRITICAL: Re-declare color, text-decoration:none, and font-family on :hover/:focus \u2014 HubSpot overrides link hover styles
633
- 9. Pill/badge (.${t}-pill)
754
+ 9. Pill/badge (.${e}-pill)
634
755
  10. Decorative elements (at least one background treatment: grid pattern, noise, gradient orb)
635
756
  11. Scroll animation CSS ([data-animate], [data-animate-stagger]) with 3s CSS-only fallback
636
- 12. Section label (.${t}-label) \u2014 uppercase, letter-spacing, accent color
757
+ 12. Section label (.${e}-label) \u2014 uppercase, letter-spacing, accent color
637
758
  13. Stat number styling
638
759
  14. Responsive mobile styles (@media max-width: 767px)
639
760
 
@@ -641,8 +762,8 @@ Complete CSS file content. MUST include:
641
762
  IntersectionObserver-based scroll animation JS. Wrap in IIFE.
642
763
 
643
764
  ## CSS Rules \u2014 CRITICAL
644
- - All classes MUST use prefix "${t}-"
645
- - Use BEM naming: ${t}-module__element--modifier
765
+ - All classes MUST use prefix "${e}-"
766
+ - Use BEM naming: ${e}-module__element--modifier
646
767
  - Use system font stacks ONLY (no Google Fonts @import, no external CDN)
647
768
  - Every var() reference in CSS must have a matching declaration in :root
648
769
  - No Tailwind, no Sass, no PostCSS
@@ -663,36 +784,44 @@ Good system font stacks by style:
663
784
  | Geometric | Futura, "Century Gothic", "Trebuchet MS", sans-serif | system-ui, sans-serif |`),n.push(`
664
785
 
665
786
  ## Design Guide
666
- ${bd()}`),e?.styleguide&&n.push(`
787
+ ${ea()}`),t?.styleguide&&n.push(`
667
788
 
668
789
  ## Brand Style Guide
669
- ${e.styleguide}`),e?.themeContext&&n.push(`
790
+ ${t.styleguide}`),t?.themeContext&&n.push(`
670
791
 
671
792
  ## Product Context
672
- ${e.themeContext}`),n.join("")}function Pr(t,e,n,s){let o=[];return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
793
+ ${t.themeContext}`),n.join("")}function qr(e,t){let n=To(e),o=n.indexOf(`
794
+
795
+ ## Design Guide
796
+ `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),a=`## Design Guide
797
+ ${ea()}`,r=[{type:"text",text:i},{type:"text",text:a,cache_control:{type:"ephemeral"}}],l=[];return t?.styleguide&&l.push(`## Brand Style Guide
798
+ ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
799
+ ${t.themeContext}`),l.length>0&&r.push({type:"text",text:l.join(`
800
+
801
+ `)}),r}function Qr(e,t,n,s){let o=[];return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
673
802
 
674
803
  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.
675
804
 
676
805
  The Design System has already been created. Your module plans MUST reference the existing CSS classes and variables.
677
806
 
678
- ## Theme: "${t}"
807
+ ## Theme: "${e}"
679
808
 
680
809
  ## Available CSS Classes
681
810
  The following shared CSS classes are available for modules to use. Reference these in your layoutNotes:
682
811
 
683
812
  \`\`\`css
684
- ${e}
813
+ ${t}
685
814
  \`\`\`
686
815
 
687
816
  ## Output Rules
688
817
  - Module names: descriptive, title-case (e.g., "Hero Banner", "Pricing Cards")
689
818
  - Content briefs: describe the actual copy/content each module needs (headlines, body text, CTAs, stats)
690
819
  - Layout notes: describe the visual layout using the available CSS classes above
691
- - Reference specific CSS classes from the shared CSS in your layout notes (e.g., "Use ${t}-grid--3 for card layout, ${t}-section--dark for background")
820
+ - Reference specific CSS classes from the shared CSS in your layout notes (e.g., "Use ${e}-grid--3 for card layout, ${e}-section--dark for background")
692
821
  - moduleOrder: list module names in the order they should appear on the page`),(!s||s.includes("content"))&&o.push(`
693
822
 
694
823
  ## Content & Copywriting Guide
695
- ${Sd()}`),n?.brandvoice&&o.push(`
824
+ ${eu()}`),n?.brandvoice&&o.push(`
696
825
 
697
826
  ## Brand Voice
698
827
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -701,7 +830,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
701
830
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
702
831
 
703
832
  ## Anti-AI Copy Rules
704
- ${vd()}`),o.join("")}function bd(){return`### Design Philosophy
833
+ ${tu()}`),o.join("")}function ea(){return`### Design Philosophy
705
834
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
706
835
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
707
836
 
@@ -804,7 +933,7 @@ Include these in shared CSS:
804
933
  | All animations same speed | Stagger with increasing delays |
805
934
  | Skip hover/focus states | Every interactive element needs feedback |
806
935
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
807
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function Sd(){return`### Mandatory Page Sections (generate all)
936
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function eu(){return`### Mandatory Page Sections (generate all)
808
937
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
809
938
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
810
939
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -892,7 +1021,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
892
1021
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
893
1022
  - Keep paragraphs to 2-3 sentences max
894
1023
  - Aim for 6th-grade reading level
895
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function vd(){return`### Banned Punctuation
1024
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function tu(){return`### Banned Punctuation
896
1025
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
897
1026
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
898
1027
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -922,32 +1051,32 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
922
1051
  - Use plain short words: use > utilize, start > commence, help > facilitate
923
1052
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
924
1053
  - Front-load the benefit in the first 5 words
925
- - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Nr,Mr,_r=J(()=>{"use strict";g();Nr={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"]};Mr={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module name in title-case"},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 Rr(t,e,n,s,o,i,a){a({type:"agent_step",step:"designing",label:"Creating design system..."});let r=Er(n.themeName,n.brandAssets),l=`## User Request
926
- ${t}`;n.modules.length>0&&e.designSystemChanges&&(l+=`
1054
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Xr,Zr,ta=j(()=>{"use strict";g();Xr={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"]};Zr={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module name in title-case"},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 na(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=To(n.themeName,n.brandAssets),c=r?qr(n.themeName,n.brandAssets):void 0,d=`## User Request
1055
+ ${e}`;n.modules.length>0&&t.designSystemChanges&&(d+=`
927
1056
 
928
1057
  ## Current Shared CSS (update this)
929
1058
  \`\`\`css
930
1059
  ${n.sharedCss}
931
- \`\`\``);let c=await Ne(s,o,i,{systemPrompt:r,messages:[{role:"user",content:l}],structuredOutput:{schema:Nr,name:"design_system"},maxTokens:16e3}),d;c.type!=="structured"?(E.warn("page-architect","Design system: did not get structured output, using fallback"),d={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(d=c.data,E.info("page-architect","Design system created",{aesthetic:d.aesthetic,varCount:Object.keys(d.cssVariables||{}).length,cssLength:d.sharedCss?.length||0}));let u=d.sharedCss||"",p=d.cssVariables;p&&typeof p=="object"&&Object.keys(p).length>0&&(u.includes(":root")||(u=`:root {
932
- ${Object.entries(p).map(([N,L])=>` ${N.startsWith("--")?N:`--${N}`}: ${L};`).join(`
1060
+ \`\`\``);let u=await Pe(s,o,i,{systemPrompt:l,systemBlocks:c,messages:[{role:"user",content:d}],structuredOutput:{schema:Xr,name:"design_system"},maxTokens:16e3}),m;u.type!=="structured"?(T.warn("page-architect","Design system: did not get structured output, using fallback"),m={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(m=u.data,T.info("page-architect","Design system created",{aesthetic:m.aesthetic,varCount:Object.keys(m.cssVariables||{}).length,cssLength:m.sharedCss?.length||0}));let f=m.sharedCss||"",h=m.cssVariables;h&&typeof h=="object"&&Object.keys(h).length>0&&(f.includes(":root")||(f=`:root {
1061
+ ${Object.entries(h).map(([W,L])=>` ${W.startsWith("--")?W:`--${W}`}: ${L};`).join(`
933
1062
  `)}
934
1063
  }
935
1064
 
936
- ${u}`));let f=[],h=/\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,y=[...new Set((t.match(h)||[]).map(M=>M.trim()))];if(y.length>0){let M=y.filter(L=>u.toLowerCase().includes(L.toLowerCase())),N=y.filter(L=>!M.includes(L));N.length>0&&f.push(`Note: ${N.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let b=[`Design system: ${d.aesthetic||"created"} | ${Object.keys(p||{}).length} variables, ${u.length} chars CSS`,...f];a({type:"agent_decision",step:"designing",decision:b.join(`
937
- `)}),a({type:"design_system_ready",sharedCss:u,sharedJs:d.sharedJs||"",aesthetic:d.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let A=Pr(n.themeName,u,n.brandAssets,e.guidesNeeded),w=`## User Request
938
- ${t}`;e.newModules.length>0&&(w+=`
1065
+ ${f}`));let y=[],v=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,C=[...new Set((e.match(v)||[]).map(R=>R.trim()))];if(C.length>0){let R=C.filter(L=>f.toLowerCase().includes(L.toLowerCase())),W=C.filter(L=>!R.includes(L));W.length>0&&y.push(`Note: ${W.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let k=[`Design system: ${m.aesthetic||"created"} | ${Object.keys(h||{}).length} variables, ${f.length} chars CSS`,...y];a({type:"agent_decision",step:"designing",decision:k.join(`
1066
+ `)}),a({type:"design_system_ready",sharedCss:f,sharedJs:m.sharedJs||"",aesthetic:m.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let P=Qr(n.themeName,f,n.brandAssets,t.guidesNeeded),O=`## User Request
1067
+ ${e}`;t.newModules.length>0&&(O+=`
939
1068
 
940
1069
  ## Planned Modules
941
- ${e.newModules.map((M,N)=>`${N+1}. **${M.name}** \u2014 ${M.description}`).join(`
942
- `)}`),n.modules.length>0&&!e.designSystemChanges&&(w+=`
1070
+ ${t.newModules.map((R,W)=>`${W+1}. **${R.name}** \u2014 ${R.description}`).join(`
1071
+ `)}`),n.modules.length>0&&!t.designSystemChanges&&(O+=`
943
1072
 
944
1073
  ## Existing Modules (keeping)
945
- ${n.modules.map(M=>`- ${M.moduleName}`).join(`
946
- `)}`);let $=await Ne(s,o,i,{systemPrompt:A,messages:[{role:"user",content:w}],structuredOutput:{schema:Mr,name:"module_plan"},maxTokens:8e3}),R;return $.type!=="structured"?(E.warn("page-architect","Module planner: did not get structured output, using fallback"),R={modules:e.newModules.map(M=>({name:M.name,description:M.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:e.newModules.map(M=>M.name),narrative:"Page generated from user request"}):(R=$.data,E.info("page-architect","Module plan",{moduleCount:R.modules.length})),a({type:"agent_decision",step:"designing",decision:`Page: ${R.narrative} | ${R.modules.length} modules planned`}),{designSystem:{cssVariables:d.cssVariables||{},sharedCss:u,sharedJs:d.sharedJs},modules:R.modules,moduleOrder:R.moduleOrder,narrative:R.narrative}}var Or=J(()=>{"use strict";g();it();_r();ve()});function jr(t){let e=0,n=[];return async function(o){e>=t&&await new Promise(i=>n.push(i)),e++;try{return await o()}finally{e--,n.length>0&&n.shift()()}}}var Fr=J(()=>{"use strict";g()});function Jr(t,e,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1074
+ ${n.modules.map(R=>`- ${R.moduleName}`).join(`
1075
+ `)}`);let G=await Pe(s,o,i,{systemPrompt:P,messages:[{role:"user",content:O}],structuredOutput:{schema:Zr,name:"module_plan"},maxTokens:8e3}),E;return G.type!=="structured"?(T.warn("page-architect","Module planner: did not get structured output, using fallback"),E={modules:t.newModules.map(R=>({name:R.name,description:R.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(R=>R.name),narrative:"Page generated from user request"}):(E=G.data,T.info("page-architect","Module plan",{moduleCount:E.modules.length})),a({type:"agent_decision",step:"designing",decision:`Page: ${E.narrative} | ${E.modules.length} modules planned`}),{designSystem:{cssVariables:m.cssVariables||{},sharedCss:f,sharedJs:m.sharedJs},modules:E.modules,moduleOrder:E.moduleOrder,narrative:E.narrative}}var sa=j(()=>{"use strict";g();lt();ta();ve()});function oa(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 ia=j(()=>{"use strict";g()});function $o(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
947
1076
 
948
1077
  Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code.
949
1078
 
950
- ## Theme: "${t}"
1079
+ ## Theme: "${e}"
951
1080
 
952
1081
  ## Output Rules \u2014 CRITICAL
953
1082
  You produce a single module with these fields:
@@ -959,8 +1088,8 @@ You produce a single module with these fields:
959
1088
  - **moduleJs**: Optional vanilla JS wrapped in IIFE, or null
960
1089
 
961
1090
  ## CSS Rules
962
- - All CSS classes must use prefix "${t}-"
963
- - Use BEM naming: ${t}-moduleName__element--modifier
1091
+ - All CSS classes must use prefix "${e}-"
1092
+ - Use BEM naming: ${e}-moduleName__element--modifier
964
1093
  - Reference the theme's CSS custom properties (shown below)
965
1094
  - No CDN imports (@import url(), external <link> tags)
966
1095
  - Use system font stacks \u2014 no Google Fonts
@@ -977,7 +1106,7 @@ You produce a single module with these fields:
977
1106
  - For repeater groups, use "occurrence": { "min": 0, "max": 100 }
978
1107
 
979
1108
  ## Images & Assets
980
- - Use get_asset_url("${t}/assets/filename.ext") for uploaded assets
1109
+ - Use get_asset_url("${e}/assets/filename.ext") for uploaded assets
981
1110
  - For placeholder images, use image fields with placehold.co defaults
982
1111
  - Size placeholders appropriately (hero: 1920x800, cards: 600x400, icons: 200x200)
983
1112
 
@@ -987,24 +1116,37 @@ You produce a single module with these fields:
987
1116
  - Include smooth scroll behavior in nav click handlers
988
1117
 
989
1118
  ## metaJson Template
990
- { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`),e&&o.push(`
1119
+ { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`),t&&o.push(`
991
1120
 
992
1121
  ## Theme Shared CSS (use these custom properties)
993
1122
  \`\`\`css
994
- ${e}
1123
+ ${t}
995
1124
  \`\`\``),(!n||n.includes("hubspot_rules"))&&o.push(`
996
1125
 
997
1126
  ## HubSpot CMS Rules
998
- ${Ze()}`),(!n||n.includes("conversion"))&&o.push(`
1127
+ ${Ee()}`),(!n||n.includes("conversion"))&&o.push(`
999
1128
 
1000
1129
  ## Conversion Guide
1001
- ${le()}`),s?.themeContext&&o.push(`
1130
+ ${oe()}`),s?.themeContext&&o.push(`
1002
1131
 
1003
1132
  ## Product Context
1004
1133
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1005
1134
 
1006
1135
  ## Anti-AI Copy Rules
1007
- ${wd()}`),o.join("")}function wd(){return`### Banned Punctuation
1136
+ ${aa()}`),o.join("")}function ra(e,t,n,s){let o=[],i=$o(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1137
+
1138
+ ## Theme Shared CSS (use these custom properties)
1139
+ \`\`\`css
1140
+ ${t}
1141
+ \`\`\``),o.push({type:"text",text:i});let a=[];(!n||n.includes("hubspot_rules"))&&a.push(`## HubSpot CMS Rules
1142
+ ${Ee()}`),(!n||n.includes("conversion"))&&a.push(`## Conversion Guide
1143
+ ${oe()}`),a.length>0&&o.push({type:"text",text:a.join(`
1144
+
1145
+ `),cache_control:{type:"ephemeral"}});let r=[];return s?.themeContext&&r.push(`## Product Context
1146
+ ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&r.push(`## Anti-AI Copy Rules
1147
+ ${aa()}`),r.length>0&&o.push({type:"text",text:r.join(`
1148
+
1149
+ `)}),o}function aa(){return`### Banned Punctuation
1008
1150
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1009
1151
  - **Semicolons**: Use periods instead in marketing copy.
1010
1152
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1043,14 +1185,14 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1043
1185
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1044
1186
  - Full names, specific roles (not "John D., CEO")
1045
1187
  - Never start with "This product is..." \u2014 start with the person's situation
1046
- - Vary length and voice across testimonials`}function Dr(t,e,n){let s=[];return s.push(`## User Request
1047
- ${t}`),s.push(`
1188
+ - Vary length and voice across testimonials`}function la(e,t,n){let s=[];return s.push(`## User Request
1189
+ ${e}`),s.push(`
1048
1190
 
1049
1191
  ## Module Specification
1050
- - **Name**: ${e.name}
1051
- - **Description**: ${e.description}
1052
- - **Content Brief**: ${e.contentBrief}
1053
- - **Layout Notes**: ${e.layoutNotes}`),n&&(s.push(`
1192
+ - **Name**: ${t.name}
1193
+ - **Description**: ${t.description}
1194
+ - **Content Brief**: ${t.contentBrief}
1195
+ - **Layout Notes**: ${t.layoutNotes}`),n&&(s.push(`
1054
1196
 
1055
1197
  ## Existing Module Code (modify this)
1056
1198
  **fields.json:**
@@ -1070,33 +1212,33 @@ ${n.moduleCss}
1070
1212
  **module.js:**
1071
1213
  \`\`\`js
1072
1214
  ${n.moduleJs}
1073
- \`\`\``)),s.join("")}var Lr,Hr=J(()=>{"use strict";g();Ve();Lr={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 Gr(t,e,n,s,o,i,a,r,l,c,d){l({type:"agent_step",step:"developing",label:`Generating ${e.length} module${e.length===1?"":"s"}...`});let u=Jr(s,n,c,d),p=jr(r),f=e.length,h=e.map((b,A)=>p(async()=>{l({type:"module_progress",module:b.name,status:"generating",current:A+1,total:f});let w="";for(let $=0;$<2;$++)try{$>0&&(E.warn("module-developer",`${b.name}: retrying after failure (attempt ${$+1})`),l({type:"module_progress",module:b.name,status:"retrying",current:A+1,total:f}));let R=await Ur(t,b,u,o,i,a);return l({type:"module_progress",module:b.name,status:"complete",current:A+1,total:f,moduleFiles:R}),{moduleName:b.name,module:R}}catch(R){w=R instanceof Error?R.message:typeof R=="object"&&R!==null?JSON.stringify(R):String(R),E.error("module-developer",`Failed: ${b.name} (attempt ${$+1})`,{error:w})}return l({type:"module_progress",module:b.name,status:"failed",current:A+1,total:f}),{moduleName:b.name,error:w}}));return(await Promise.allSettled(h)).map(b=>b.status==="fulfilled"?b.value:{moduleName:"unknown",error:b.reason instanceof Error?b.reason.message:String(b.reason)})}async function Ur(t,e,n,s,o,i,a=0){let r=Dr(t,e,e.existingCode),l=await Ne(s,o,i,{systemPrompt:n,messages:[{role:"user",content:r}],structuredOutput:{schema:Lr,name:"module_output"},maxTokens:16e3});if(l.type!=="structured"){if(a<2)return E.warn("module-developer",`${e.name}: no structured output, retry ${a+1}`),Ur(t,e,n,s,o,i,a+1);throw new Error(`Module "${e.name}" failed to produce structured output after ${a+1} attempts`)}let c=l.data,d=typeof c.fieldsJson=="string"?c.fieldsJson:JSON.stringify(c.fieldsJson,null,2),u=typeof c.metaJson=="string"?c.metaJson:JSON.stringify(c.metaJson,null,2);return{moduleName:e.name,fieldsJson:d,metaJson:u,moduleHtml:String(c.moduleHtml||""),moduleCss:String(c.moduleCss||""),moduleJs:c.moduleJs?String(c.moduleJs):void 0}}var Wr=J(()=>{"use strict";g();it();Fr();Hr();ve()});function Kr(t,e,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),t.map(s=>{let o=[],i={...s};i.fieldsJson=Br(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=Br(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=xd(i.fieldsJson,i.moduleName,o),i.fieldsJson=Cd(i.fieldsJson,i.moduleName,o),i.moduleCss=Ad(i.moduleCss,i.moduleName,"moduleCss",o),Id(i.moduleCss,i.moduleName,e,o),i.moduleHtml=kd(i.moduleHtml,i.moduleName,o),i.metaJson=$d(i.metaJson,i.moduleName,o);let a=o.every(r=>r.autoFixed);return o.length>0&&E.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 Br(t,e,n,s){return!t||t.trim()===""?(s.push({module:e,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:["PAGE"],is_available_for_new_content:!0}):t):(Le(t)===null&&s.push({module:e,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),t)}function xd(t,e,n){let s=t;return/"name"\s*:\s*"name"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"name" is a reserved field name \u2192 renamed to "item_name"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"name"/g,'"name": "item_name"')),/"name"\s*:\s*"label"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"label" is a reserved field name \u2192 renamed to "section_label"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"label"/g,'"name": "section_label"')),s}function Cd(t,e,n){let s=t;return/"type"\s*:\s*"textarea"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"textarea" is deprecated \u2192 changed to "text"',autoFixed:!0}),s=s.replace(/"type"\s*:\s*"textarea"/g,'"type": "text"')),s}function Ad(t,e,n,s){if(!t)return t;let o=t,i=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return i.test(o)&&(s.push({module:e,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(i,"/* CDN import removed */")),o}function Id(t,e,n,s){if(!t)return;let o=/\.([a-zA-Z][\w-]*)/g,i,a=0;for(;(i=o.exec(t))!==null;){let r=i[1];r.startsWith(n+"-")||r==="visible"||r==="active"||r==="scroll-animate"||r.startsWith("body-wrapper")||r.startsWith("dnd-")||r.startsWith("row-")||a++}a>3&&s.push({module:e,field:"moduleCss",message:`${a} CSS classes without "${n}-" prefix`,autoFixed:!1})}function kd(t,e,n){if(!t)return t;let s=t,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:e,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(`
1215
+ \`\`\``)),s.join("")}var ca,da=j(()=>{"use strict";g();qe();ca={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 ua(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=$o(s,n,c,d),f=u?ra(s,n,c,d):void 0,h=oa(r),y=t.length,v=t.map((k,P)=>h(async()=>{l({type:"module_progress",module:k.name,status:"generating",current:P+1,total:y});let O="";for(let G=0;G<2;G++)try{G>0&&(T.warn("module-developer",`${k.name}: retrying after failure (attempt ${G+1})`),l({type:"module_progress",module:k.name,status:"retrying",current:P+1,total:y}));let E=await ma(e,k,m,o,i,a,0,f);return l({type:"module_progress",module:k.name,status:"complete",current:P+1,total:y,moduleFiles:E}),{moduleName:k.name,module:E}}catch(E){O=E instanceof Error?E.message:typeof E=="object"&&E!==null?JSON.stringify(E):String(E),T.error("module-developer",`Failed: ${k.name} (attempt ${G+1})`,{error:O})}return l({type:"module_progress",module:k.name,status:"failed",current:P+1,total:y}),{moduleName:k.name,error:O}}));return(await Promise.allSettled(v)).map(k=>k.status==="fulfilled"?k.value:{moduleName:"unknown",error:k.reason instanceof Error?k.reason.message:String(k.reason)})}async function ma(e,t,n,s,o,i,a=0,r){let l=la(e,t,t.existingCode),c=await Pe(s,o,i,{systemPrompt:n,systemBlocks:r,messages:[{role:"user",content:l}],structuredOutput:{schema:ca,name:"module_output"},maxTokens:16e3});if(c.type!=="structured"){if(a<2)return T.warn("module-developer",`${t.name}: no structured output, retry ${a+1}`),ma(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 pa=j(()=>{"use strict";g();lt();ia();da();ve()});function ga(e,t,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),e.map(s=>{let o=[],i={...s};i.fieldsJson=fa(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=fa(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=nu(i.fieldsJson,i.moduleName,o),i.fieldsJson=su(i.fieldsJson,i.moduleName,o),i.moduleCss=ou(i.moduleCss,i.moduleName,"moduleCss",o),i.moduleCss=ru(i.moduleCss,i.moduleName,t,o),i.moduleHtml=au(i.moduleHtml,i.moduleName,t,o),i.moduleHtml=cu(i.moduleHtml,i.moduleName,o),i.metaJson=du(i.metaJson,i.moduleName,o);let a=o.every(r=>r.autoFixed);return o.length>0&&T.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 fa(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):(Ge(e)===null&&s.push({module:t,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),e)}function nu(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 su(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 ou(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 ha(e){return iu.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function ru(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)&&!ha(c)&&a.add(c)}if(a.size<=3)return e;let l=e;for(let c of a){let d=new RegExp(`\\.${lu(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 au(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(f=>f&&!f.startsWith(o)&&!ha(f)&&/^[a-zA-Z][\w-]*$/.test(f)?(u=!0,o+f):f);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 lu(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function cu(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(`
1074
1216
  `);s=`${s}
1075
- ${d}`,n.push({module:e,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:e,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function $d(t,e,n){let s=Le(t);if(!s||typeof s!="object")return t;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:e,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(o,null,2)):t}var Vr=J(()=>{"use strict";g();Zn();ve()});import{execSync as Td}from"child_process";async function Yr(t,e,n,s,o,i,a,r){let l=Date.now(),c=i;if(on(n)){let O={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(O)try{Td(`command -v ${O}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${O}" to be installed and on your PATH.`)}}let d=await $r(t,e,n,s,o,a,r);if(d.intent==="question"&&d.answer){let G=Date.now()-l;return a({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:e.modules.length,durationMs:G}),{modules:[...e.modules],moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:e.modules.length,modulesFailed:0,durationMs:G}}}let u=null,p=e.sharedCss,f=e.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Rr(t,d,e,n,s,o,a),p=u.designSystem.sharedCss||p,f=u.designSystem.sharedJs||f,a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:p,sharedJs:f}));let y=[];if(u)for(let G of u.modules)y.push({name:G.name,description:G.description,contentBrief:G.contentBrief,layoutNotes:G.layoutNotes});else{for(let G of d.newModules)y.push({name:G.name,description:G.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let G of d.affectedModules){let O=e.modules.find(z=>z.moduleName===G);O&&y.push({name:G,description:`Modify existing module: ${G}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:O})}}let b=[],A=[];if(y.length>0){let G=await Gr(t,y,p,e.themeName,n,s,o,c,a,d.guidesNeeded,e.brandAssets);for(let O of G)O.module?b.push(O.module):A.push(O.moduleName)}let w=null;if(b.length>0){w=Kr(b,e.themeName,a),b=w.map(O=>O.module);let G=w.reduce((O,z)=>O+z.issues.length,0);if(G>0){let O=w.reduce((ae,Io)=>ae+Io.issues.filter(Rt=>Rt.autoFixed).length,0);E.info("pipeline",`Quality check: ${G} issues, ${O} auto-fixed`);let z=w.flatMap(ae=>ae.issues).map(ae=>`${ae.autoFixed?"\u2713":"\u26A0"} ${ae.module}: ${ae.message}`).join(`
1076
- `);a({type:"agent_decision",step:"quality_check",decision:`${G} issues found, ${O} auto-fixed
1077
- ${z}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let $=Ed(e,d,b,u,r),R=Nd(e,d,u,$);if(u?.moduleOrder?.length){let G=new Set(u.moduleOrder),O=$.filter(z=>!G.has(z.moduleName)).map(z=>z.moduleName);O.length>0&&a({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${O.length} module${O.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${O.join(", ")}`})}let M=Date.now()-l,N=b.length,L=d.unchangedModules.length,ne=w?w.flatMap(G=>G.issues):[],U=Pd(d,N,L,A,M,u,ne);return A.length>0?a({type:"pipeline_partial",succeeded:b.map(G=>G.moduleName),failed:A,durationMs:M}):a({type:"pipeline_complete",modulesGenerated:N,modulesUnchanged:L,durationMs:M}),{modules:$,moduleOrder:R,sharedCss:p,sharedJs:f,assistantMessage:U,stats:{modulesGenerated:N,modulesUnchanged:L,modulesFailed:A.length,durationMs:M}}}function Ed(t,e,n,s,o){let i=[],a=new Set;for(let r of n)i.push(r),a.add(r.moduleName);for(let r of e.unchangedModules){if(a.has(r))continue;let l=t.modules.find(c=>c.moduleName===r);l&&(i.push(l),a.add(r))}if(e.reuseModules)for(let r of e.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 Nd(t,e,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),E.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return r}if(e.intent==="create")return s.map(r=>r.moduleName);let o=[...t.moduleOrder],i=[...e.newModules.map(r=>({name:r.name,position:r.position})),...(e.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 Pd(t,e,n,s,o,i,a){let r=Math.round(o/1e3),l=[];if(t.intent==="create")l.push(`Created ${e} module${e===1?"":"s"} in ${r}s.`);else if(t.intent==="modify"||t.intent==="style_change")l.push(`Updated ${e} module${e===1?"":"s"} in ${r}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(t.intent==="add"){let u=t.newModules.map(p=>p.name).join(", ");l.push(`Added ${u} in ${r}s.`)}else t.intent==="remove"?l.push(`Removed modules in ${r}s.`):t.intent==="rearrange"&&l.push(`Rearranged modules in ${r}s.`);i?.narrative&&l.push(`
1217
+ ${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 du(e,t,n){let s=Ge(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 iu,ya=j(()=>{"use strict";g();cs();ve();iu=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"])});import{execSync as uu}from"child_process";async function ba(e,t,n,s,o,i,a,r){let l=Date.now(),c=i;if(mn(n)){let F={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(F)try{uu(`command -v ${F}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${F}" to be installed and on your PATH.`)}}let d=await Yr(e,t,n,s,o,a,r);if(d.intent==="question"&&d.answer){let U=Date.now()-l;return a({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:U,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:U}}}let u=null,m=t.sharedCss,f=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await na(e,d,t,n,s,o,a),m=u.designSystem.sharedCss||m,f=u.designSystem.sharedJs||f,a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:f}));let y=[];if(u)for(let U of u.modules)y.push({name:U.name,description:U.description,contentBrief:U.contentBrief,layoutNotes:U.layoutNotes});else{for(let U of d.newModules)y.push({name:U.name,description:U.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let U of d.affectedModules){let F=t.modules.find(X=>X.moduleName===U);F&&y.push({name:U,description:`Modify existing module: ${U}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:F})}}let v=[],C=[];if(y.length>0){let U=await ua(e,y,m,t.themeName,n,s,o,c,a,d.guidesNeeded,t.brandAssets);for(let F of U)F.module?v.push(F.module):C.push(F.moduleName)}let k=null;if(v.length>0){k=ga(v,t.themeName,a),v=k.map(F=>F.module);let U=k.reduce((F,X)=>F+X.issues.length,0);if(U>0){let F=k.reduce((le,Bo)=>le+Bo.issues.filter(jt=>jt.autoFixed).length,0);T.info("pipeline",`Quality check: ${U} issues, ${F} auto-fixed`);let X=k.flatMap(le=>le.issues).map(le=>`${le.autoFixed?"\u2713":"\u26A0"} ${le.module}: ${le.message}`).join(`
1218
+ `);a({type:"agent_decision",step:"quality_check",decision:`${U} issues found, ${F} auto-fixed
1219
+ ${X}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let P=mu(t,d,v,u,r),O=pu(t,d,u,P);if(u?.moduleOrder?.length){let U=new Set(u.moduleOrder),F=P.filter(X=>!U.has(X.moduleName)).map(X=>X.moduleName);F.length>0&&a({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${F.length} module${F.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${F.join(", ")}`})}let G=Date.now()-l,E=v.length,R=d.unchangedModules.length,W=k?k.flatMap(U=>U.issues):[],L=fu(d,E,R,C,G,u,W);return C.length>0?a({type:"pipeline_partial",succeeded:v.map(U=>U.moduleName),failed:C,durationMs:G}):a({type:"pipeline_complete",modulesGenerated:E,modulesUnchanged:R,durationMs:G}),{modules:P,moduleOrder:O,sharedCss:m,sharedJs:f,assistantMessage:L,stats:{modulesGenerated:E,modulesUnchanged:R,modulesFailed:C.length,durationMs:G}}}function mu(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 pu(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),T.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 fu(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(`
1078
1220
 
1079
1221
  ${i.narrative}`),s.length>0&&l.push(`
1080
1222
 
1081
- **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(p=>`${p.module}: ${p.message}`).join(", ")}`),c.length>0&&u.push(`**Warnings:** ${c.map(p=>`${p.module}: ${p.message}`).join(", ")}`),l.push(`
1223
+ **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(`
1082
1224
 
1083
1225
  ${u.join(`
1084
- `)}`)}return l.join("")}var zr=J(()=>{"use strict";g();it();Tr();Or();Wr();Vr();ve();it()});var qr={};lt(qr,{applyPipelineResult:()=>go,handleAgenticGenerate:()=>fo,handleGenerate:()=>Md,handleGenerateStream:()=>rn,isGenerating:()=>Pt,resolveAgenticEngine:()=>ss,setParseWarningCallback:()=>mo,shouldUseAgenticMode:()=>ho});import{execSync as co}from"child_process";function mo(t){uo=t}function Pt(){return gt!==null}function Nt(t){if(gt){let e=v();if(!e||e.id!==gt){E.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}tt("assistant",t),ur(t,uo||void 0),D()}async function rn(t,e,n,s){let o=v();if(!o)throw new Error("No active session");gt=o.id;let a=s?.length?wr(s):void 0;try{let r=P(),l=r.aiEngine||po();switch(l){case"anthropic-api":case"api":{let c=ge("anthropic-api",r);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await fr(t,c,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",e,n,Nt,a);break}case"openai-api":{let c=ge("openai-api",r);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await gr(t,c,o.themeName,r.openaiApiModel||"gpt-4o",e,n,Nt,a);break}case"gemini-api":{let c=ge("gemini-api",r);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await hr(t,c,o.themeName,e,n,Nt,a);break}case"claude-code":await yr(t,o.themeName,e,n,Nt,a);break;case"gemini-cli":await eo("gemini",t,o.themeName,e,n,Nt,a);break;case"codex-cli":await eo("codex",t,o.themeName,e,n,Nt,a);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{gt=null,uo=null}}function po(){let t=P();if(t.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(t.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(t.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return co("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return co("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return co("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Md(t){let e="";return await rn(t,n=>{e+=n}),e}function _d(){let t=v(),e=Ce(),n=e?[...e.modules]:[...t.modules],s=e?[...e.moduleOrder]:[...t.moduleOrder];return{modules:n,moduleOrder:s,sharedCss:e?.sharedCss||t.sharedCss,sharedJs:e?.sharedJs||t.sharedJs,messages:[...t.messages],themeName:t.themeName,themePath:t.themePath,brandAssets:t.brandAssets?{...t.brandAssets}:void 0}}function ss(t){let e=t.aiEngine||po();if(!ns(e))throw new Error("Agentic pipeline is not available for this engine.");if(on(e)){let o="";return e==="claude-code"&&(o=t.claudeCodeModel||""),{engine:e,apiKey:"",model:o}}let n=ge(e,t);if(!n)throw new Error(`API key not configured for ${e}. Open Settings to add one.`);let s;switch(e){case"anthropic-api":s=t.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=t.openaiApiModel||"gpt-4o";break;case"gemini-api":s="gemini-2.5-flash";break;default:s=""}return{engine:e,apiKey:n,model:s}}async function fo(t,e,n){let s=v();if(!s)throw new Error("No active session");let o=s.id;gt=o;try{let i=P(),{engine:a,apiKey:r,model:l}=ss(i),c=i.agenticConcurrency||20,d=_d(),u=nt(),p=new Set(d.modules.map(b=>b.moduleName)),f=u.filter(b=>!p.has(b.module.moduleName)).map(b=>({name:b.module.moduleName,usedIn:b.usedIn})),h=await Yr(t,d,a,r,l,c,e,f),y=v();if(!y||y.id!==o)throw E.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return h}finally{gt=null}}function go(t,e){De({modules:t.modules,sharedCss:t.sharedCss,sharedJs:t.sharedJs}),At(t.moduleOrder),tt("assistant",t.assistantMessage,e),D()}function ho(){let t=P(),e=t.aiEngine||po();return ns(e)?t.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:t.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var uo,gt,os=J(()=>{"use strict";g();ee();Se();Zn();ve();to();io();zr();uo=null;gt=null});var ms={};lt(ms,{collectThemeFiles:()=>Na,extractDesignContext:()=>tu});import{existsSync as cs,readdirSync as ds,readFileSync as qd}from"fs";import{join as He}from"path";import{spawn as Xd}from"child_process";async function Qd(){return bo||(bo=(await import("@anthropic-ai/sdk")).default),bo}function cn(t){try{return qd(t,"utf-8")}catch{return""}}function Na(t){let e=[],n=0;function s(r,l){if(!l.trim())return!0;let c=`
1226
+ `)}`)}return l.join("")}var Sa=j(()=>{"use strict";g();lt();zr();sa();pa();ya();ve();lt()});var va={};tt(va,{applyPipelineResult:()=>No,handleAgenticGenerate:()=>Oo,handleGenerate:()=>gu,handleGenerateStream:()=>pn,isGenerating:()=>Nt,resolveAgenticEngine:()=>ps,setParseWarningCallback:()=>Po,shouldUseAgenticMode:()=>Ro});import{execSync as Eo}from"child_process";function Po(e){_o=e}function Nt(){return bt!==null}function yt(e){if(bt){let t=S();if(!t||t.id!==bt){T.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}it("assistant",e),Tr(e,_o||void 0),D()}async function pn(e,t,n,s){let o=S();if(!o)throw new Error("No active session");bt=o.id;let a=s?.length?Gr(s):void 0;try{let r=_(),l=r.aiEngine||Mo();switch(l){case"anthropic-api":case"api":{let c=ge("anthropic-api",r);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await Nr(e,c,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,yt,a);break}case"claude-oauth":{await Rr(e,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,yt,a);break}case"openai-api":{let c=ge("openai-api",r);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await Fr(e,c,o.themeName,r.openaiApiModel||"gpt-4o",t,n,yt,a);break}case"gemini-api":{let c=ge("gemini-api",r);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await jr(e,c,o.themeName,t,n,yt,a);break}case"claude-code":await Jr(e,o.themeName,t,n,yt,a);break;case"gemini-cli":await bo("gemini",e,o.themeName,t,n,yt,a);break;case"codex-cli":await bo("codex",e,o.themeName,t,n,yt,a);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{bt=null,_o=null}}function Mo(){let e=_();if(Re())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 Eo("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return Eo("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return Eo("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function gu(e){let t="";return await pn(e,n=>{t+=n}),t}function hu(){let e=S(),t=Ce(),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 ps(e){let t=e.aiEngine||Mo();if(!ms(t))throw new Error("Agentic pipeline is not available for this engine.");if(mn(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Re())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=ge(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 Oo(e,t,n){let s=S();if(!s)throw new Error("No active session");let o=s.id;bt=o;try{let i=_(),{engine:a,apiKey:r,model:l}=ps(i),c=i.agenticConcurrency||20,d=hu(),u=rt(),m=new Set(d.modules.map(v=>v.moduleName)),f=u.filter(v=>!m.has(v.module.moduleName)).map(v=>({name:v.module.moduleName,usedIn:v.usedIn})),h=await ba(e,d,a,r,l,c,t,f),y=S();if(!y||y.id!==o)throw T.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return h}finally{bt=null}}function No(e,t){Le({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Et(e.moduleOrder),it("assistant",e.assistantMessage,t),D()}function Ro(){let e=_(),t=e.aiEngine||Mo();return ms(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 _o,bt,fs=j(()=>{"use strict";g();Z();Se();cs();ve();So();Ke();Co();Sa();_o=null;bt=null});var ws={};tt(ws,{collectThemeFiles:()=>ol,extractDesignContext:()=>ju});import{existsSync as Ss,readdirSync as vs,readFileSync as Ou}from"fs";import{join as Ue}from"path";import{spawn as Nu}from"child_process";async function sl(){return jo||(jo=(await import("@anthropic-ai/sdk")).default),jo}function hn(e){try{return Ou(e,"utf-8")}catch{return""}}function ol(e){let t=[],n=0;function s(r,l){if(!l.trim())return!0;let c=`
1085
1227
  ### ${r}
1086
1228
  \`\`\`
1087
1229
  ${l}
1088
1230
  \`\`\`
1089
- `;return n+c.length>Zd?!1:(e.push(c),n+=c.length,!0)}let o=cn(He(t,"theme.json"));o&&s("theme.json",o);let i=He(t,"css");if(cs(i)){for(let r of ds(i).filter(l=>l.endsWith(".css")))if(!s(`css/${r}`,cn(He(i,r))))break}let a=He(t,"modules");if(cs(a))for(let r of ds(a).filter(l=>l.endsWith(".module"))){let l=He(a,r),c=cn(He(l,"module.css"));if(c&&!s(`modules/${r}/module.css`,c))break}if(cs(a))for(let r of ds(a).filter(l=>l.endsWith(".module"))){let l=He(a,r),c=cn(He(l,"module.html"));if(c&&!s(`modules/${r}/module.html`,c))break}if(cs(a))for(let r of ds(a).filter(l=>l.endsWith(".module"))){let l=He(a,r),c=cn(He(l,"fields.json"));if(c&&!s(`modules/${r}/fields.json`,c))break}return e.join("")}function eu(){if(!us)try{us=I(pn("extraction-prompt.md"))}catch{us=""}return us}function So(t,e,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let a=Xd(t,e,{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(`${t} failed to start: ${c.message}`))),a.on("close",c=>{c===0||r.trim()?s(r.trim()):o(new Error(`${t} exited with code ${c}: ${l.trim()}`))}),a.stdin.write(n),a.stdin.end()})}async function tu(t,e){e?.({status:"Collecting theme files..."});let n=Na(t);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=eu();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:
1090
- ${n}`;e?.({status:"Analyzing design patterns..."});let i=P(),a=i.aiEngine||"anthropic-api",r="";switch(a){case"anthropic-api":case"api":{let l=ge("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Qd();r=(await new c({apiKey:l}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:s,messages:[{role:"user",content:o}]})).content.filter(p=>p.type==="text").map(p=>p.text).join("");break}case"openai-api":{let l=ge("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=ge("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(p=>p.text).join("")||"";break}case"claude-code":{let l=`${s}
1231
+ `;return n+c.length>Ru?!1:(t.push(c),n+=c.length,!0)}let o=hn(Ue(e,"theme.json"));o&&s("theme.json",o);let i=Ue(e,"css");if(Ss(i)){for(let r of vs(i).filter(l=>l.endsWith(".css")))if(!s(`css/${r}`,hn(Ue(i,r))))break}let a=Ue(e,"modules");if(Ss(a))for(let r of vs(a).filter(l=>l.endsWith(".module"))){let l=Ue(a,r),c=hn(Ue(l,"module.css"));if(c&&!s(`modules/${r}/module.css`,c))break}if(Ss(a))for(let r of vs(a).filter(l=>l.endsWith(".module"))){let l=Ue(a,r),c=hn(Ue(l,"module.html"));if(c&&!s(`modules/${r}/module.html`,c))break}if(Ss(a))for(let r of vs(a).filter(l=>l.endsWith(".module"))){let l=Ue(a,r),c=hn(Ue(l,"fields.json"));if(c&&!s(`modules/${r}/fields.json`,c))break}return t.join("")}function Fu(){if(!xs)try{xs=A(vn("extraction-prompt.md"))}catch{xs=""}return xs}function Jo(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let a=Nu(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 ju(e,t){t?.({status:"Collecting theme files..."});let n=ol(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=Fu();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:
1232
+ ${n}`;t?.({status:"Analyzing design patterns..."});let i=_(),a=i.aiEngine||"anthropic-api",r="";switch(a){case"anthropic-api":case"api":{let l=ge("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await sl();r=(await new c({apiKey:l}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:s,messages:[{role:"user",content:o}]})).content.filter(m=>m.type==="text").map(m=>m.text).join("");break}case"claude-oauth":{let{getValidAccessToken:l,OAUTH_EXTRA_HEADERS:c,OAUTH_SYSTEM_PREFIX:d}=await Promise.resolve().then(()=>(Ke(),Os)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await sl();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}],messages:[{role:"user",content:o}]})).content.filter(y=>y.type==="text").map(y=>y.text).join("");break}case"openai-api":{let l=ge("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=ge("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}
1091
1233
 
1092
1234
  ## User Request
1093
- ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await So("claude",c,l);break}case"gemini-cli":{let l=`${s}
1235
+ ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await Jo("claude",c,l);break}case"gemini-cli":{let l=`${s}
1094
1236
 
1095
1237
  ## User Request
1096
- ${o}`;r=await So("gemini",[],l);break}case"codex-cli":{let l=`${s}
1238
+ ${o}`;r=await Jo("gemini",[],l);break}case"codex-cli":{let l=`${s}
1097
1239
 
1098
1240
  ## User Request
1099
- ${o}`;r=await So("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 e?.({status:"Design extraction complete."}),r}var bo,Zd,us,ps=J(()=>{"use strict";g();Z();ee();bo=null;Zd=8e4;us=""});var Pa={};lt(Pa,{extractBrandvoice:()=>nu});async function nu(t,e,n,s){if(!t||t.length<50)return null;let o=`You are a brand strategist. Analyze the rendered landing page HTML below and extract a concise brand voice guide. The HTML contains the actual text content with all template variables resolved to their default values.
1241
+ ${o}`;r=await Jo("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 jo,Ru,xs,Cs=j(()=>{"use strict";g();Q();Z();jo=null;Ru=8e4;xs=""});var il={};tt(il,{extractBrandvoice:()=>Ju});async function Ju(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.
1100
1242
 
1101
1243
  Return a markdown document with these sections (skip any section where the content provides no signal):
1102
1244
 
@@ -1116,7 +1258,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
1116
1258
  ## Dos and Don'ts
1117
1259
  3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
1118
1260
 
1119
- Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Ne(e,n,s,{systemPrompt:o,messages:[{role:"user",content:t}],maxTokens:1e3}),a=i.type==="text"?i.text:JSON.stringify(i.data);return!a||a.trim().length<20?null:(E.info("brandvoice-extractor",`Extracted brand voice (${a.length} chars)`),a.trim())}catch(i){let a=i instanceof Error?i.message:String(i);return E.warn("brandvoice-extractor",`Brand voice extraction failed: ${a}`),null}}var Ma=J(()=>{"use strict";g();it();ve()});var vo={};lt(vo,{extractThemeContext:()=>su});async function su(t,e,n,s,o){if(!t||t.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.
1261
+ Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Pe(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),a=i.type==="text"?i.text:JSON.stringify(i.data);return!a||a.trim().length<20?null:(T.info("brandvoice-extractor",`Extracted brand voice (${a.length} chars)`),a.trim())}catch(i){let a=i instanceof Error?i.message:String(i);return T.warn("brandvoice-extractor",`Brand voice extraction failed: ${a}`),null}}var rl=j(()=>{"use strict";g();lt();ve()});var Do={};tt(Do,{extractThemeContext:()=>Du});async function Du(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.
1120
1262
 
1121
1263
  Return a markdown document with these sections (skip any section where the content provides no information):
1122
1264
 
@@ -1135,37 +1277,37 @@ Communication style (e.g., professional, casual, technical, friendly).
1135
1277
  ## Key Terminology
1136
1278
  Specific terms, product names, or branded language used consistently.
1137
1279
 
1138
- Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${e?`
1280
+ Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
1139
1281
 
1140
1282
  Existing product context (update if the new content adds info, keep what's still accurate):
1141
- ${e}`:""}`;try{let r=await Ne(n,s,o,{systemPrompt:a,messages:[{role:"user",content:t}],maxTokens:1e3}),l=r.type==="text"?r.text:JSON.stringify(r.data);return!l||l.trim().length<20?null:(E.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(r){let l=r instanceof Error?r.message:String(r);return E.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var wo=J(()=>{"use strict";g();it();ve()});g();g();import{Command as vu}from"commander";g();g();g();import yt from"chalk";var Me={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ko=!!process.env.NO_COLOR;function Ue(t){return ko?yt:yt.hex(t)}var k={accent:Ue(Me.accent),accentBright:Ue(Me.accentBright),success:Ue(Me.success),info:Ue(Me.info),warn:Ue(Me.warn),error:Ue(Me.error),muted:Ue(Me.muted),vibes:Ue(Me.vibes),heading:ko?yt.bold:yt.bold.hex(Me.accent),command:Ue(Me.accentBright),dim:yt.dim,bold:yt.bold};Z();function _e(){let t=k.vibes,e=k.accent,n=k.muted,s=[`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B ")}${e("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${e(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${k.dim(`v${St()}`)}`),console.log()}g();g();ct();ee();import{join as hn}from"path";import{homedir as yn}from"os";import{readFileSync as Ro,existsSync as bn,readdirSync as pl}from"fs";var dt=process.platform==="win32"?"where":"which";function Ft(){let t=T("node --version");return{name:"Node.js",found:t.success,version:t.stdout.replace(/^v/,""),path:T(`${dt} node`).stdout}}function Jt(){let t=T("git --version");return{name:"Git",found:t.success,version:t.stdout.replace("git version ",""),path:T(`${dt} git`).stdout}}function Re(){let t=T("hs --version");return{name:"HubSpot CLI",found:t.success,version:t.stdout,path:T(`${dt} hs`).stdout}}function Dt(){let t=T("claude --version");if(!t.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=hn(yn(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(bn(e)){let o=pl(e);(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:t.stdout,path:T(`${dt} claude`).stdout,authenticated:n,authDetail:s}}function Lt(t){try{let e=hn(yn(),".hscli","config.yml");if(!bn(e))return"na1";let n=Ro(e,"utf-8"),s=n.indexOf(`accountId: ${t}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let 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 Oe(){let t=T("hs accounts list");if(!t.success||!t.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let e=[],n="",s="",o=t.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=t.stdout.split(`
1142
- `);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";e.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:e}:e.length>0?{authenticated:!0,portalName:e[0].name,portalId:e[0].portalId,accounts:e}:{authenticated:t.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Ht(){let t=T("gemini --version");if(!t.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=hn(yn(),".config","gcloud","application_default_credentials.json"),n=bn(e),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:t.stdout,path:T(`${dt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function Gt(){let t=T("codex --version");if(!t.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=!!process.env.OPENAI_API_KEY,n=!1;try{let i=hn(yn(),".codex","auth.json");bn(i)&&(n=Ro(i,"utf-8").length>10)}catch{}let s=e||n,o=n?"Authenticated (OAuth)":e?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:t.stdout,path:T(`${dt} codex`).stdout,authenticated:s,authDetail:o}}function xs(){let t=T("gh --version");return{name:"GitHub CLI",found:t.success,version:t.stdout.split(`
1143
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:T(`${dt} gh`).stdout}}function Cs(){let t=T("gh auth status 2>&1");if(!t.success&&!t.stdout)return{authenticated:!1,username:""};let e=t.stdout||t.stderr||"",n=e.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=e.match(/account\s+(\S+)/);return s&&e.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:e.includes("Logged in"),username:""}}function Oo(){return!!process.env.ANTHROPIC_API_KEY}function Sn(t){return parseInt(t.split(".")[0],10)>=18}function jo(t){let e=parseInt(t.split(".")[0],10);return!isNaN(e)&&e>=8}function fl(){let t=P(),e=t.hubspotUploadMode||"api",n=t.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(t.activeHubSpotAccount||n[0]?.portalId)})),o=Xe();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:e}}var ws={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function vn(){let t=P(),e=Ft(),n=Jt(),s=t.hubspotUploadMode||"api",o;if(s==="cli"){let b=Re(),A=b.found?Oe():{authenticated:!1,portalName:"",portalId:"",accounts:[]},w=A.portalId?Lt(A.portalId):"na1";o={...b,...A,dataCenter:w,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...fl()};let i=xs(),a=i.found?Cs():{authenticated:!1,username:""},r=t.enabledCLITools||[],l=jt("claude-code")?Dt():{...ws,name:"Claude Code"},c=jt("gemini-cli")?Ht():{...ws,name:"Gemini CLI"},d=jt("codex-cli")?Gt():{...ws,name:"OpenAI Codex CLI"};function u(b,...A){if(b)return{configured:!0,masked:gn(b),source:"config"};for(let w of A)if(process.env[w])return{configured:!0,masked:gn(process.env[w]),source:"env"};return{configured:!1,masked:"",source:null}}let p=u(t.anthropicApiKey,"ANTHROPIC_API_KEY"),f=u(t.openaiApiKey,"OPENAI_API_KEY"),h=u(t.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),y=[];return l.found&&l.authenticated&&y.push("claude-code"),p.configured&&y.push("anthropic-api"),f.configured&&y.push("openai-api"),c.found&&c.authenticated&&y.push("gemini-cli"),h.configured&&y.push("gemini-api"),d.found&&d.authenticated&&y.push("codex-cli"),{tools:{node:e,git:n,hubspot:o,github:{...i,...a},claudeCode:l,geminiCli:c,codexCli:d},apiKeys:{anthropic:p,openai:f,gemini:h},activeEngine:t.aiEngine||null,availableEngines:y,enabledCLITools:r}}ct();ee();ut();g();import*as K from"@clack/prompts";function Is(t){K.isCancel(t)&&(K.cancel(k.muted("Operation cancelled.")),process.exit(0))}async function ce(t){K.intro(k.heading(t))}async function de(t){K.outro(k.success(t))}async function je(t,e){K.note(t,e?k.heading(e):void 0)}async function $e(t){let e=await K.text({message:k.accent(t.message),placeholder:t.placeholder,defaultValue:t.defaultValue,validate:t.validate});return Is(e),e}async function se(t){let e=await K.confirm({message:k.accent(t.message),initialValue:t.initialValue??!0});return Is(e),e}async function wt(t){let e=await K.select({message:k.accent(t.message),options:t.options});return Is(e),e}async function ue(){let t=K.spinner();return{start:e=>t.start(k.muted(e)),stop:e=>t.stop(k.success(e)),message:e=>t.message(k.muted(e))}}function X(t){K.log.info(t)}function F(t){K.log.success(k.success(t))}function V(t){K.log.warn(k.warn(t))}function W(t){K.log.error(k.error(t))}async function An(){await ce("Checking your environment");let t=Ft();t.found||(W("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Sn(t.version)||(W(`Node.js ${t.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),F(`Node.js v${t.version}`);let e=Jt();e.found||(W("Git not found. Install it from https://git-scm.com"),process.exit(1)),F(`Git ${e.version}`);let n=P(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let y=he(),b=Xe();if(y)o=b?.portalId||"",i=b?.portalName||"",F(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{V("No HubSpot account connected"),await je(`You need a Personal Access Key to deploy themes.
1283
+ ${t}`:""}`;try{let r=await Pe(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:(T.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(r){let l=r instanceof Error?r.message:String(r);return T.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var Ho=j(()=>{"use strict";g();lt();ve()});g();g();import{Command as nm}from"commander";g();g();g();import vt from"chalk";var Oe={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Wo=!!process.env.NO_COLOR;function We(e){return Wo?vt:vt.hex(e)}var I={accent:We(Oe.accent),accentBright:We(Oe.accentBright),success:We(Oe.success),info:We(Oe.info),warn:We(Oe.warn),error:We(Oe.error),muted:We(Oe.muted),vibes:We(Oe.vibes),heading:Wo?vt.bold:vt.bold.hex(Oe.accent),command:We(Oe.accentBright),dim:vt.dim,bold:vt.bold};Q();function Ne(){let e=I.vibes,t=I.accent,n=I.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${I.dim(`v${wt()}`)}`),console.log()}g();g();ut();Z();Ke();import{join as In}from"path";import{homedir as Tn}from"os";import{readFileSync as ei,existsSync as $n,readdirSync as Yl}from"fs";var mt=process.platform==="win32"?"where":"which";function Gt(){let e=$("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:$(`${mt} node`).stdout}}function Ut(){let e=$("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:$(`${mt} git`).stdout}}function Fe(){let e=$("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:$(`${mt} hs`).stdout}}function Bt(){let e=$("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=In(Tn(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if($n(t)){let o=Yl(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:$(`${mt} claude`).stdout,authenticated:n,authDetail:s}}function Wt(e){try{let t=In(Tn(),".hscli","config.yml");if(!$n(t))return"na1";let n=ei(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 je(){let e=$("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(`
1284
+ `);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 Vt(){let e=$("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=In(Tn(),".config","gcloud","application_default_credentials.json"),n=$n(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:$(`${mt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function Kt(){let e=$("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=In(Tn(),".codex","auth.json");$n(i)&&(n=ei(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:$(`${mt} codex`).stdout,authenticated:s,authDetail:o}}function Rs(){let e=$("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
1285
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:$(`${mt} gh`).stdout}}function Fs(){let e=$("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 ti(){return!!process.env.ANTHROPIC_API_KEY}function En(e){return parseInt(e.split(".")[0],10)>=18}function ni(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function zl(){let e=_(),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=nt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}var Ns={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function _n(){let e=_(),t=Gt(),n=Ut(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let C=Fe(),k=C.found?je():{authenticated:!1,portalName:"",portalId:"",accounts:[]},P=k.portalId?Wt(k.portalId):"na1";o={...C,...k,dataCenter:P,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...zl()};let i=Rs(),a=i.found?Fs():{authenticated:!1,username:""},r={authenticated:Re(),expiresAt:Lt()?.expiresAt},l=e.enabledCLITools||[],c=Dt("claude-code")?Bt():{...Ns,name:"Claude Code"},d=Dt("gemini-cli")?Vt():{...Ns,name:"Gemini CLI"},u=Dt("codex-cli")?Kt():{...Ns,name:"OpenAI Codex CLI"};function m(C,...k){if(C)return{configured:!0,masked:wn(C),source:"config"};for(let P of k)if(process.env[P])return{configured:!0,masked:wn(process.env[P]),source:"env"};return{configured:!1,masked:"",source:null}}let f=m(e.anthropicApiKey,"ANTHROPIC_API_KEY"),h=m(e.openaiApiKey,"OPENAI_API_KEY"),y=m(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),v=[];return c.found&&c.authenticated&&v.push("claude-code"),r.authenticated&&v.push("claude-oauth"),f.configured&&v.push("anthropic-api"),h.configured&&v.push("openai-api"),d.found&&d.authenticated&&v.push("gemini-cli"),y.configured&&v.push("gemini-api"),u.found&&u.authenticated&&v.push("codex-cli"),{tools:{node:t,git:n,hubspot:o,github:{...i,...a},claudeCode:c,claudeOAuth:r,geminiCli:d,codexCli:u},apiKeys:{anthropic:f,openai:h,gemini:y},activeEngine:e.aiEngine||null,availableEngines:v,enabledCLITools:l}}Ke();ut();Z();pt();g();import*as Y from"@clack/prompts";function Js(e){Y.isCancel(e)&&(Y.cancel(I.muted("Operation cancelled.")),process.exit(0))}async function ce(e){Y.intro(I.heading(e))}async function de(e){Y.outro(I.success(e))}async function Je(e,t){Y.note(e,t?I.heading(t):void 0)}async function Te(e){let t=await Y.text({message:I.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return Js(t),t}async function se(e){let t=await Y.confirm({message:I.accent(e.message),initialValue:e.initialValue??!0});return Js(t),t}async function It(e){let t=await Y.select({message:I.accent(e.message),options:e.options});return Js(t),t}async function ue(){let e=Y.spinner();return{start:t=>e.start(I.muted(t)),stop:t=>e.stop(I.success(t)),message:t=>e.message(I.muted(t))}}function ee(e){Y.log.info(e)}function J(e){Y.log.success(I.success(e))}function z(e){Y.log.warn(I.warn(e))}function B(e){Y.log.error(I.error(e))}async function Nn(){await ce("Checking your environment");let e=Gt();e.found||(B("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),En(e.version)||(B(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),J(`Node.js v${e.version}`);let t=Ut();t.found||(B("Git not found. Install it from https://git-scm.com"),process.exit(1)),J(`Git ${t.version}`);let n=_(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let v=he(),C=nt();if(v)o=C?.portalId||"",i=C?.portalName||"",J(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{z("No HubSpot account connected"),await Je(`You need a Personal Access Key to deploy themes.
1144
1286
  Create one at: https://app.hubspot.com/l/personal-access-key
1145
- Make sure the Content scope is enabled.`,"HubSpot connection required");let A=await $e({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:$=>$.trim()?void 0:"Key is required"}),w=await ue();w.start("Validating key...");try{let $=await xn(A);Ot(A,$.portalId,$.portalName,$.dataCenter),y=A,o=$.portalId,i=$.portalName,w.stop(`Connected to ${$.portalName} (${$.portalId})`)}catch($){w.stop("Validation failed"),W(`Invalid key: ${$ instanceof Error?$.message:String($)}`),process.exit(1)}}}else{let y=Re();if(y.found)F(`HubSpot CLI v${y.version}`);else{V("HubSpot CLI not found"),await se({message:"Install HubSpot CLI globally?"})||(W("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let w=await ue();w.start("Installing HubSpot CLI..."),T("npm install -g @hubspot/cli").success||(w.stop("Failed"),W("Try: npm install -g @hubspot/cli"),process.exit(1)),y=Re(),w.stop(`HubSpot CLI v${y.version} installed`)}let b=Oe();if(b.authenticated)F(`HubSpot portal${b.portalName?`: ${b.portalName}`:""} (ID: ${b.portalId})`);else{V("HubSpot not authenticated"),await se({message:"Run `hs init` now?"})||(W("Run `hs init` manually."),process.exit(1));let w=await ue();w.start("Waiting for HubSpot authentication..."),No("hs init")||(w.stop("Authentication failed"),process.exit(1)),b=Oe(),w.stop(`Connected to portal${b.portalName?`: ${b.portalName}`:""} (ID: ${b.portalId})`)}o=b.portalId,i=b.portalName}let a=Dt(),r=Ht(),l=Gt(),c=Oo(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"},u,p=n.aiEngine,f=[];if(a.found&&f.push({value:"claude-code",label:"Claude Code",hint:p==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),r.found&&f.push({value:"gemini-cli",label:"Gemini CLI",hint:p==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&f.push({value:"codex-cli",label:"OpenAI Codex",hint:p==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&f.push({value:"api",label:"Anthropic API",hint:p==="api"?"last used":"uses your API key"}),p&&f.sort((y,b)=>y.value===p?-1:b.value===p?1:0),f.length===1)u=f[0].value,F(`AI engine: ${d[u]} (auto-detected)`);else if(f.length>1)u=await wt({message:"Choose your AI engine:",options:f});else if(await je(`You need an AI coding assistant to power the conversion.
1287
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let k=await Te({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:O=>O.trim()?void 0:"Key is required"}),P=await ue();P.start("Validating key...");try{let O=await Mn(k);Jt(k,O.portalId,O.portalName,O.dataCenter),v=k,o=O.portalId,i=O.portalName,P.stop(`Connected to ${O.portalName} (${O.portalId})`)}catch(O){P.stop("Validation failed"),B(`Invalid key: ${O instanceof Error?O.message:String(O)}`),process.exit(1)}}}else{let v=Fe();if(v.found)J(`HubSpot CLI v${v.version}`);else{z("HubSpot CLI not found"),await se({message:"Install HubSpot CLI globally?"})||(B("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let P=await ue();P.start("Installing HubSpot CLI..."),$("npm install -g @hubspot/cli").success||(P.stop("Failed"),B("Try: npm install -g @hubspot/cli"),process.exit(1)),v=Fe(),P.stop(`HubSpot CLI v${v.version} installed`)}let C=je();if(C.authenticated)J(`HubSpot portal${C.portalName?`: ${C.portalName}`:""} (ID: ${C.portalId})`);else{z("HubSpot not authenticated"),await se({message:"Run `hs init` now?"})||(B("Run `hs init` manually."),process.exit(1));let P=await ue();P.start("Waiting for HubSpot authentication..."),zo("hs init")||(P.stop("Authentication failed"),process.exit(1)),C=je(),P.stop(`Connected to portal${C.portalName?`: ${C.portalName}`:""} (ID: ${C.portalId})`)}o=C.portalId,i=C.portalName}let a=Bt(),r=Vt(),l=Kt(),c=ti(),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=Re(),m,f=n.aiEngine,h=[];if(a.found&&h.push({value:"claude-code",label:"Claude Code",hint:f==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&h.push({value:"claude-oauth",label:"Claude (OAuth)",hint:f==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),r.found&&h.push({value:"gemini-cli",label:"Gemini CLI",hint:f==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&h.push({value:"codex-cli",label:"OpenAI Codex",hint:f==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&h.push({value:"api",label:"Anthropic API",hint:f==="api"?"last used":"uses your API key"}),f&&h.sort((v,C)=>v.value===f?-1:C.value===f?1:0),h.length===1)m=h[0].value,J(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await It({message:"Choose your AI engine:",options:h});else if(await Je(`You need an AI coding assistant to power the conversion.
1146
1288
 
1147
- ${k.bold("Option 1:")} Install Claude Code ${k.muted("(recommended)")}
1289
+ ${I.bold("Option 1:")} Install Claude Code ${I.muted("(recommended)")}
1148
1290
  https://claude.ai/code
1149
1291
 
1150
- ${k.bold("Option 2:")} Install Gemini CLI
1292
+ ${I.bold("Option 2:")} Install Gemini CLI
1151
1293
  https://github.com/google-gemini/gemini-cli
1152
1294
 
1153
- ${k.bold("Option 3:")} Install OpenAI Codex
1295
+ ${I.bold("Option 3:")} Install OpenAI Codex
1154
1296
  https://github.com/openai/codex
1155
1297
 
1156
- ${k.bold("Option 4:")} Set an Anthropic API key
1298
+ ${I.bold("Option 4:")} Set an Anthropic API key
1157
1299
  export ANTHROPIC_API_KEY=sk-ant-...
1158
- (get one at https://console.anthropic.com)`,"AI engine required"),u=await wt({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),u==="api"){let y=await $e({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:b=>b.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=y,q({anthropicApiKey:y})}let h;return u==="claude-code"&&(h=await wt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),q({aiEngine:u}),await de("Environment ready!"),{aiEngine:u,model:h,portalId:o,portalName:i}}g();ct();Z();import{readdirSync as ks,statSync as xl}from"fs";import{join as Q,basename as $s,extname as Cl}from"path";function Go(t){let e=[],n=[Q(t,"src/components/landing"),Q(t,"src/components/sections"),Q(t,"src/components"),Q(t,"src/pages"),Q(t,"app/components"),Q(t,"components")];for(let s of n)if(S(s))try{let o=ks(s);for(let i of o){let a=Q(s,i);if(!xl(a).isFile())continue;let l=Cl(i);if(![".tsx",".jsx"].includes(l))continue;let c=$s(i,l);if(c.startsWith("ui")||c==="index")continue;let d=I(a),u=Al(c,d);e.push({name:c,path:a,description:u})}}catch{}return e}function Al(t,e){let n=[];return/carousel|slider|swiper|embla/i.test(e)&&n.push("carousel"),/accordion|collapsible|expand/i.test(e)&&n.push("accordion"),/form|submit|input.*email/i.test(e)&&n.push("form"),/nav|navigation|menu/i.test(e)&&n.push("navigation"),/hero|headline|tagline/i.test(e)&&n.push("hero"),/footer|copyright/i.test(e)&&n.push("footer"),/testimonial|quote|review/i.test(e)&&n.push("testimonials"),/pricing|plan|tier/i.test(e)&&n.push("pricing"),/faq|question.*answer/i.test(e)&&n.push("FAQ"),/feature|benefit|advantage/i.test(e)&&n.push("features"),/contact|get.in.touch/i.test(e)&&n.push("contact"),/cta|call.to.action/i.test(e)&&n.push("CTA"),/team|member|bio/i.test(e)&&n.push("team"),n.length===0?t.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function Uo(t){let e=[Q(t,"src/index.css"),Q(t,"src/globals.css"),Q(t,"src/app/globals.css"),Q(t,"app/globals.css")],n=0,s=[];for(let o of e){if(!S(o))continue;let i=I(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 Wo(t){let e=[],n=Q(t,"src/hooks");if(S(n))try{let o=ks(n);for(let i of o)/scroll/i.test(i)&&e.push("Scroll animations"),/intersection/i.test(i)&&e.push("Scroll animations")}catch{}let s=Q(t,"src/components/landing");if(S(s))try{let o=ks(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let a=I(Q(s,i));/carousel|embla|swiper/i.test(a)&&!e.includes("Carousel")&&e.push("Carousel"),/accordion|collapsible/i.test(a)&&!e.includes("Accordion")&&e.push("Accordion"),/typing|typewriter/i.test(a)&&!e.includes("Typing animation")&&e.push("Typing animation"),/parallax|requestAnimationFrame/i.test(a)&&!e.includes("Parallax")&&e.push("Parallax")}}catch{}return e.length===0&&e.push("Scroll animations"),e}function Bo(t){let e,n=!1;if(t.startsWith("http")||t.startsWith("git@")){n=!0;let l=$s(t.replace(/\.git$/,""))||"react-source";if(e=Q(process.cwd(),"workspace",l),!S(e)){let c=T(`git clone --depth 1 "${t}" "${e}"`);if(!c.success)throw new Error(`Failed to clone ${t}: ${c.stderr}`)}}else if(e=t,!S(e))throw new Error(`Directory not found: ${e}`);let s=Go(e),o=S(Q(e,"tailwind.config.ts"))||S(Q(e,"tailwind.config.js")),{varCount:i,fonts:a}=Uo(e),r=Wo(e);return{sourceDir:e,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:a,interactions:r}}async function In(){await ce("Source Project");let t=await $e({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),e,n=!1;if(t.startsWith("http")||t.startsWith("git@")){n=!0;let h=$s(t.replace(/\.git$/,""))||"react-source";if(e=Q(process.cwd(),"workspace",h),S(e))F(`Using existing clone: ${k.dim(e)}`);else{let y=await ue();y.start("Cloning repository..."),T(`git clone --depth 1 "${t}" "${e}"`).success||(y.stop("Clone failed"),W(`Failed to clone ${t}. Check the URL and your access permissions.`),process.exit(1)),y.stop(`Cloned to ${k.dim(e)}`)}}else e=t,S(e)||(W(`Directory not found: ${e}`),process.exit(1)),F(`Using local source: ${k.dim(e)}`);let s=await ue();s.start("Analyzing project structure...");let o=Go(e),i=S(Q(e,"tailwind.config.ts"))||S(Q(e,"tailwind.config.js")),{varCount:a,fonts:r}=Uo(e),l=Wo(e);s.stop(`Found ${o.length} landing page components`),o.length===0&&(V("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,y)=>` ${k.dim(`${y+1}.`)} ${k.bold(h.name)} ${k.muted(`\u2014 ${h.description}`)}`).join(`
1159
- `),d=i?`Tailwind + custom CSS (${a} variables)`:`Custom CSS (${a} variables)`,u=r.length>0?r.join(", "):"System fonts",p=l.join(", ");return await je(`${c}
1300
+ (get one at https://console.anthropic.com)`,"AI engine required"),m=await It({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 v=await Te({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:C=>C.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=v,K({anthropicApiKey:v})}let y;return m==="claude-code"&&(y=await It({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"}]})),K({aiEngine:m}),await de("Environment ready!"),{aiEngine:m,model:y,portalId:o,portalName:i}}g();ut();Q();import{readdirSync as Ds,statSync as sc}from"fs";import{join as te,basename as Hs,extname as oc}from"path";function li(e){let t=[],n=[te(e,"src/components/landing"),te(e,"src/components/sections"),te(e,"src/components"),te(e,"src/pages"),te(e,"app/components"),te(e,"components")];for(let s of n)if(b(s))try{let o=Ds(s);for(let i of o){let a=te(s,i);if(!sc(a).isFile())continue;let l=oc(i);if(![".tsx",".jsx"].includes(l))continue;let c=Hs(i,l);if(c.startsWith("ui")||c==="index")continue;let d=A(a),u=ic(c,d);t.push({name:c,path:a,description:u})}}catch{}return t}function ic(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 ci(e){let t=[te(e,"src/index.css"),te(e,"src/globals.css"),te(e,"src/app/globals.css"),te(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!b(o))continue;let i=A(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 di(e){let t=[],n=te(e,"src/hooks");if(b(n))try{let o=Ds(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=te(e,"src/components/landing");if(b(s))try{let o=Ds(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let a=A(te(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 ui(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let l=Hs(e.replace(/\.git$/,""))||"react-source";if(t=te(process.cwd(),"workspace",l),!b(t)){let c=$(`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=li(t),o=b(te(t,"tailwind.config.ts"))||b(te(t,"tailwind.config.js")),{varCount:i,fonts:a}=ci(t),r=di(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:a,interactions:r}}async function Rn(){await ce("Source Project");let e=await Te({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let h=Hs(e.replace(/\.git$/,""))||"react-source";if(t=te(process.cwd(),"workspace",h),b(t))J(`Using existing clone: ${I.dim(t)}`);else{let y=await ue();y.start("Cloning repository..."),$(`git clone --depth 1 "${e}" "${t}"`).success||(y.stop("Clone failed"),B(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),y.stop(`Cloned to ${I.dim(t)}`)}}else t=e,b(t)||(B(`Directory not found: ${t}`),process.exit(1)),J(`Using local source: ${I.dim(t)}`);let s=await ue();s.start("Analyzing project structure...");let o=li(t),i=b(te(t,"tailwind.config.ts"))||b(te(t,"tailwind.config.js")),{varCount:a,fonts:r}=ci(t),l=di(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((h,y)=>` ${I.dim(`${y+1}.`)} ${I.bold(h.name)} ${I.muted(`\u2014 ${h.description}`)}`).join(`
1301
+ `),d=i?`Tailwind + custom CSS (${a} variables)`:`Custom CSS (${a} variables)`,u=r.length>0?r.join(", "):"System fonts",m=l.join(", ");return await Je(`${c}
1160
1302
 
1161
1303
  CSS: ${d}
1162
- JS: ${p}
1163
- Font: ${u}`,`${o.length} components detected`),await se({message:"Does this look right?"})||(W("Please adjust your source directory and try again."),process.exit(0)),await de("Source analyzed!"),{sourceDir:e,wasCloned:n,components:o,hasTailwind:i,cssVarCount:a,fonts:r,interactions:l}}g();ct();Z();import{join as Kt}from"path";ee();g();import{mkdirSync as Qe,writeFileSync as kn}from"fs";import{join as Te}from"path";function $n(t,e){Qe(t,{recursive:!0}),Qe(Te(t,"templates"),{recursive:!0}),Qe(Te(t,"modules"),{recursive:!0}),Qe(Te(t,"css"),{recursive:!0}),Qe(Te(t,"js"),{recursive:!0}),Qe(Te(t,"images"),{recursive:!0}),Qe(Te(t,"assets"),{recursive:!0});let n={label:e,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};kn(Te(t,"theme.json"),JSON.stringify(n,null,2)+`
1164
- `),kn(Te(t,"fields.json"),`[]
1304
+ JS: ${m}
1305
+ Font: ${u}`,`${o.length} components detected`),await se({message:"Does this look right?"})||(B("Please adjust your source directory and try again."),process.exit(0)),await de("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:a,fonts:r,interactions:l}}g();ut();Q();import{join as Xt}from"path";Z();g();import{mkdirSync as st,writeFileSync as Fn}from"fs";import{join as $e}from"path";function jn(e,t){st(e,{recursive:!0}),st($e(e,"templates"),{recursive:!0}),st($e(e,"modules"),{recursive:!0}),st($e(e,"css"),{recursive:!0}),st($e(e,"js"),{recursive:!0}),st($e(e,"images"),{recursive:!0}),st($e(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"}};Fn($e(e,"theme.json"),JSON.stringify(n,null,2)+`
1306
+ `),Fn($e(e,"fields.json"),`[]
1165
1307
  `);let s=`<!--
1166
1308
  templateType: page
1167
1309
  isAvailableForNewContent: false
1168
- label: ${e} (placeholder)
1310
+ label: ${t} (placeholder)
1169
1311
  screenshotPath: ../images/template-previews/home.png
1170
1312
  -->
1171
1313
  {% extends "./layouts/base.html" %}
@@ -1173,11 +1315,11 @@ ${k.bold("Option 4:")} Set an Anthropic API key
1173
1315
  {% block body %}
1174
1316
  {% dnd_area "main_content"
1175
1317
  label="Main Content",
1176
- class="body-container body-container--${e}"
1318
+ class="body-container body-container--${t}"
1177
1319
  %}
1178
1320
  {% end_dnd_area %}
1179
1321
  {% endblock body %}
1180
- `;kn(Te(t,"templates","home.html"),s);let o=`<!--
1322
+ `;Fn($e(e,"templates","home.html"),s);let o=`<!--
1181
1323
  templateType: none
1182
1324
  isAvailableForNewContent: false
1183
1325
  label: Base Layout
@@ -1200,30 +1342,30 @@ ${k.bold("Option 4:")} Set an Anthropic API key
1200
1342
  {{ standard_footer_includes }}
1201
1343
  </body>
1202
1344
  </html>
1203
- `;Qe(Te(t,"templates","layouts"),{recursive:!0}),kn(Te(t,"templates","layouts","base.html"),o)}Tn();async function En(){await ce("HubSpot Theme Setup");let t=await wt({message:"Do you have an existing HubSpot theme?",options:[{value:"fetch",label:"Fetch my existing theme from HubSpot",hint:"downloads your current theme"},{value:"create",label:"Start fresh (HubSpot Boilerplate)",hint:"creates a new starter theme"}]}),e,n,s=Kt(process.cwd(),"workspace");if(Ae(s),t==="fetch"){e=await $e({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=Kt(s,e);let l=await ue();l.start("Fetching theme from HubSpot...");let c=P(),d=he();if(c.hubspotUploadMode==="cli"||!d)T(`hs cms fetch "${e}" "${n}"`).success||(l.stop("Fetch failed"),W(`Could not fetch theme "${e}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await Bt(d,e,n)}catch(u){l.stop("Fetch failed"),W(`Could not fetch theme "${e}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${k.dim(n)}`)}else{e=await $e({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=Kt(s,e);let l=await ue();l.start("Creating theme...");try{$n(n,e)}catch(c){l.stop("Creation failed"),W(`Could not create theme "${e}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${k.dim(n)}`)}await ce("Checking theme compatibility");let o=Kt(n,"templates/layouts/base.html");S(o)||(W(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),F("base.html found");let i=I(o),a=!1;if(i.includes("template_css"))F("template_css support");else{V("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
1345
+ `;st($e(e,"templates","layouts"),{recursive:!0}),Fn($e(e,"templates","layouts","base.html"),o)}Jn();async function Dn(){await ce("HubSpot Theme Setup");let e=await It({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=Xt(process.cwd(),"workspace");if(Ae(s),e==="fetch"){t=await Te({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=Xt(s,t);let l=await ue();l.start("Fetching theme from HubSpot...");let c=_(),d=he();if(c.hubspotUploadMode==="cli"||!d)$(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),B(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await qt(d,t,n)}catch(u){l.stop("Fetch failed"),B(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${I.dim(n)}`)}else{t=await Te({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=Xt(s,t);let l=await ue();l.start("Creating theme...");try{jn(n,t)}catch(c){l.stop("Creation failed"),B(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${I.dim(n)}`)}await ce("Checking theme compatibility");let o=Xt(n,"templates/layouts/base.html");b(o)||(B(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),J("base.html found");let i=A(o),a=!1;if(i.includes("template_css"))J("template_css support");else{z("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
1204
1346
  `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
1205
1347
  `,l);i=i.slice(0,c)+`
1206
1348
  {% if template_css %}
1207
1349
  {{ require_css(get_asset_url(template_css)) }}
1208
- {% endif %}`+i.slice(c),a=!0}}if(i.includes("template_js"))F("template_js support");else{V("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
1350
+ {% endif %}`+i.slice(c),a=!0}}if(i.includes("template_js"))J("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(`
1209
1351
  `,l),d=i.indexOf(`
1210
1352
  `,c+1),u=`
1211
1353
  {% if template_js %}
1212
1354
  {{ require_js(get_asset_url(template_js)) }}
1213
- {% endif %}`,p=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
1355
+ {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
1214
1356
  `)+1;i=i.slice(0,i.indexOf(`
1215
1357
  `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
1216
- `,i.indexOf("}}",l)+2)),a=!0}}if(a){let l=await ue();l.start("Patching base.html..."),H(o,i),l.stop("base.html patched with template_css/template_js support")}let r=Kt(n,".hsignore");if(S(r)){let l=I(r);l.includes("docs/")||(H(r,l+`
1358
+ `,i.indexOf("}}",l)+2)),a=!0}}if(a){let l=await ue();l.start("Patching base.html..."),H(o,i),l.stop("base.html patched with template_css/template_js support")}let r=Xt(n,".hsignore");if(b(r)){let l=A(r);l.includes("docs/")||(H(r,l+`
1217
1359
  docs/
1218
- `),F("Added docs/ to .hsignore"))}else H(r,`docs/
1360
+ `),J("Added docs/ to .hsignore"))}else H(r,`docs/
1219
1361
  *.md
1220
1362
  node_modules/
1221
1363
  .git
1222
- `),F("Created .hsignore");return await de("Theme ready!"),{themePath:n,themeName:e}}g();import{join as Ie}from"path";import{readdirSync as Vt,rmSync as ri}from"fs";g();Ve();Z();import{spawn as El}from"child_process";import{join as B,basename as Nl}from"path";import{readdirSync as Fe,statSync as oi,writeFileSync as Pl}from"fs";var Ml=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"]),Nn=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(e){this.model=e}async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||le();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let a=this.countSourceComponents(n),r=this.listModules(s),l=this.listDir(B(s,"css")),c=this.listDir(B(s,"js")),d=this.listDir(B(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${a} source components found)...`);let p="",f="",h=setInterval(()=>{this.reportProgress(s,r,l,c,d,o)},3e3);try{await new Promise((w,$)=>{let R={...process.env};delete R.CLAUDECODE;let M=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&M.push("--model",this.model);let N=El("claude",M,{cwd:s,stdio:["pipe","pipe","pipe"],env:R,shell:!0});N.stdout.on("data",L=>{p+=L.toString()}),N.stderr.on("data",L=>{f+=L.toString()}),N.on("error",L=>$(new Error(`Claude Code failed to start: ${L.message}`))),N.on("close",L=>{L!==0?$(new Error(`Claude Code exited with code ${L}.
1364
+ `),J("Created .hsignore");return await de("Theme ready!"),{themePath:n,themeName:t}}g();import{join as ke}from"path";import{readdirSync as Qt,rmSync as wi}from"fs";g();qe();Q();import{spawn as dc}from"child_process";import{join as V,basename as uc}from"path";import{readdirSync as De,statSync as vi,writeFileSync as mc}from"fs";var pc=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"]),Hn=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||oe();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let a=this.countSourceComponents(n),r=this.listModules(s),l=this.listDir(V(s,"css")),c=this.listDir(V(s,"js")),d=this.listDir(V(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${a} source components found)...`);let m="",f="",h=setInterval(()=>{this.reportProgress(s,r,l,c,d,o)},3e3);try{await new Promise((k,P)=>{let O={...process.env};delete O.CLAUDECODE;let G=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&G.push("--model",this.model);let E=dc("claude",G,{cwd:s,stdio:["pipe","pipe","pipe"],env:O,shell:!0});E.stdout.on("data",R=>{m+=R.toString()}),E.stderr.on("data",R=>{f+=R.toString()}),E.on("error",R=>P(new Error(`Claude Code failed to start: ${R.message}`))),E.on("close",R=>{R!==0?P(new Error(`Claude Code exited with code ${R}.
1223
1365
  `+(f?`Stderr: ${f.slice(0,500)}
1224
- `:"")+(p?`Output: ${p.slice(0,500)}`:"No output"))):w()}),N.stdin.on("error",()=>{}),N.stdin.write(u),N.stdin.end(),setTimeout(()=>{N.kill(),$(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let y=B(s,"..","vibespot-conversion.log");try{let $=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
1225
- ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",p||"(empty)","","=== CLAUDE CODE STDERR ===",f||"(empty)",""].join(`
1226
- `);Pl(y,$,"utf-8"),o("status",`Log written to ${Nl(y)}`)}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=p.slice(0,1500)||"(no output)",$=f.slice(0,500);throw new Error(`Claude Code did not create any new module files.
1366
+ `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):k()}),E.stdin.on("error",()=>{}),E.stdin.write(u),E.stdin.end(),setTimeout(()=>{E.kill(),P(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let y=V(s,"..","vibespot-conversion.log");try{let P=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
1367
+ ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",f||"(empty)",""].join(`
1368
+ `);mc(y,P,"utf-8"),o("status",`Log written to ${uc(y)}`)}catch{}o("scan","Scanning generated files...");let v=this.scanGeneratedFiles(s);if(v.modules.filter(k=>!r.has(k.moduleName+".module")).length===0){let k=m.slice(0,1500)||"(no output)",P=f.slice(0,500);throw new Error(`Claude Code did not create any new module files.
1227
1369
 
1228
1370
  This usually means the model described the conversion instead of using Write tool to create files.
1229
1371
 
@@ -1232,23 +1374,23 @@ Possible causes:
1232
1374
  - Claude Code hit a rate limit or API error
1233
1375
  - The source directory was not accessible
1234
1376
 
1235
- Source: ${e.sourceDir}
1377
+ Source: ${t.sourceDir}
1236
1378
  Theme: ${s}
1237
- `+($?`
1379
+ `+(P?`
1238
1380
  Stderr:
1239
- ${$}
1381
+ ${P}
1240
1382
  `:"")+`
1241
1383
  Claude output:
1242
- ${w}`)}return b}reportProgress(e,n,s,o,i,a){let r=0,l=this.listDir(B(e,"css"));for(let p of l){if(s.has(p)||!p.endsWith(".css"))continue;let f=`css:${p}`;this.reported.has(f)||(this.reported.add(f),a("created",`Shared CSS (${p})`),r++)}let c=this.listDir(B(e,"js"));for(let p of c){if(o.has(p)||!p.endsWith(".js"))continue;let f=`js:${p}`;this.reported.has(f)||(this.reported.add(f),a("created",`Shared JS (${p})`),r++)}this.expectedModules===0&&(this.expectedModules=this.detectExpectedModules(e,i));let d=this.listModules(e);for(let p of d){if(n.has(p))continue;let f=`module:${p}`;if(!this.reported.has(f)){this.reported.add(f),this.moduleCount++;let h=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;a("created",`Module ${h}: ${p.replace(".module","")}`),r++}}let u=this.listDir(B(e,"templates"));for(let p of u){if(i.has(p)||!p.endsWith(".html"))continue;let f=`template:${p}`;this.reported.has(f)||(this.reported.add(f),a("created",`Page template (${p})`),r++)}if(r===0)if(this.moduleCount>0){let p=this.expectedModules>0?`/${this.expectedModules}`:"";a("status",`${this.moduleCount}${p} 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(e,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
1384
+ ${k}`)}return v}reportProgress(t,n,s,o,i,a){let r=0,l=this.listDir(V(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),a("created",`Shared CSS (${m})`),r++)}let c=this.listDir(V(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),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 f=`module:${m}`;if(!this.reported.has(f)){this.reported.add(f),this.moduleCount++;let h=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;a("created",`Module ${h}: ${m.replace(".module","")}`),r++}}let u=this.listDir(V(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),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.
1243
1385
 
1244
- SOURCE DIRECTORY: ${e}
1386
+ SOURCE DIRECTORY: ${t}
1245
1387
  THEME DIRECTORY: ${n}
1246
1388
 
1247
1389
  IMPORTANT \u2014 YOU MUST CREATE REAL FILES:
1248
1390
  You have access to Write, Edit, Read, Glob, Grep, and Bash tools. You MUST use the Write tool to create each file. Do NOT just describe or list what files should be created \u2014 actually call the Write tool for every single file. If you do not call Write, no files will be created and the conversion will fail.
1249
1391
 
1250
1392
  STEP-BY-STEP PROCESS:
1251
- 1. Use Glob to find all .tsx/.jsx files in ${e}/src/
1393
+ 1. Use Glob to find all .tsx/.jsx files in ${t}/src/
1252
1394
  2. Use Read to read each component file and understand the page structure
1253
1395
  3. Use Write to create a shared CSS file at ${n}/css/<name>-theme.css
1254
1396
  - Include CSS custom properties, design system variables, utility classes
@@ -1282,16 +1424,16 @@ CSS QUALITY: The converted page must visually match the original React page. Eve
1282
1424
  Do NOT run hs upload \u2014 I will handle that separately.
1283
1425
 
1284
1426
  HUBSPOT CMS RULES:
1285
- ${Ze()}
1427
+ ${Ee()}
1286
1428
 
1287
1429
  CONVERSION GUIDE:
1288
- ${s}`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=B(e,"css");if(S(s)){for(let r of Fe(s))if(r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(B(s,r));break}}let o=B(e,"js");if(S(o)){for(let r of Fe(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(B(o,r));break}}let i=B(e,"templates");if(S(i)){for(let r of Fe(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=I(B(i,r));break}if(!n.template){for(let r of Fe(i))if(r.endsWith(".html")&&!Ml.has(r)&&!r.startsWith("system")){let l=I(B(i,r));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let r of Fe(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(B(i,r));if(l.includes("dnd_area")){n.template=l;break}}}}let a=B(e,"modules");if(S(a))for(let r of Fe(a)){if(!r.endsWith(".module"))continue;let l=B(a,r);if(!oi(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=B(l,"fields.json");S(d)&&(c.fieldsJson=I(d));let u=B(l,"meta.json");S(u)&&(c.metaJson=I(u));let p=B(l,"module.html");S(p)&&(c.moduleHtml=I(p));let f=B(l,"module.css");S(f)&&(c.moduleCss=I(f));let h=B(l,"module.js");S(h)&&(c.moduleJs=I(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(e){let n=B(e,"modules");return S(n)?new Set(Fe(n).filter(s=>s.endsWith(".module"))):new Set}listDir(e){return S(e)?new Set(Fe(e)):new Set}detectExpectedModules(e,n){let s=B(e,"templates");if(!S(s))return 0;for(let o of Fe(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=I(B(s,o));if(i.includes("dnd_area")){let a=i.match(/dnd_module/g);return a?a.length:0}}catch{}return 0}countSourceComponents(e){let n=B(e,"src");return S(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(e){let n=0;for(let s of Fe(e)){let o=B(e,s);try{oi(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();Ve();Z();import _l from"@anthropic-ai/sdk";import{join as Y,basename as Rl}from"path";import{readdirSync as ii}from"fs";var Pn=class{client;model="claude-sonnet-4-6";constructor(e){this.client=new _l({apiKey:e||process.env.ANTHROPIC_API_KEY})}async convert(e){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=e,a=Zo(o),r=Rl(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,ti(c,d,l)),p=Y(s,"css",`${l}-theme.css`);H(p,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let f=this.findAndReadHooks(n),h=this.findInteractiveComponents(n),y=await this.complete(a,ni(f,h,l)),b=Y(s,"js",`${l}-animations.js`);H(b,y),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let A=this.findComponents(n),w=[];for(let N=0;N<A.length;N++){let L=A[N],ne=L.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${ne}.module (${N+1}/${A.length})...`);let U=I(L.path),G=await this.complete(a,ei(U,ne,`See css/${l}-theme.css`));try{let O=JSON.parse(G),z={moduleName:ne,fieldsJson:typeof O.fieldsJson=="string"?O.fieldsJson:JSON.stringify(O.fieldsJson,null,2),metaJson:typeof O.metaJson=="string"?O.metaJson:JSON.stringify(O.metaJson,null,2),moduleHtml:O.moduleHtml||"",moduleCss:O.moduleCss||"",moduleJs:O.moduleJs||void 0},ae=Y(s,"modules",`${ne}.module`);Ae(ae),H(Y(ae,"fields.json"),z.fieldsJson),H(Y(ae,"meta.json"),z.metaJson),H(Y(ae,"module.html"),z.moduleHtml),H(Y(ae,"module.css"),z.moduleCss),z.moduleJs&&H(Y(ae,"module.js"),z.moduleJs),w.push(z),i("module-done",`${ne}.module (${this.countFiles(z)} files)`)}catch{i("module-error",`Failed to parse ${ne} \u2014 skipping`)}}i("template","Creating page template...");let $=w.map(N=>N.moduleName),R=await this.complete(a,si($,r,l)),M=Y(s,"templates",`lp-${l}.html`);return H(M,R),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:y,template:R,modules:w}}async complete(e,n){return(await this.client.messages.create({model:this.model,max_tokens:8192,system:e,messages:[{role:"user",content:n}]})).content.find(i=>i.type==="text")?.text||""}findAndReadCSS(e){let n=[Y(e,"src/index.css"),Y(e,"src/globals.css"),Y(e,"src/app/globals.css"),Y(e,"app/globals.css")];for(let s of n)if(S(s))return I(s);return""}findAndReadTailwind(e){let n=[Y(e,"tailwind.config.ts"),Y(e,"tailwind.config.js"),Y(e,"tailwind.config.mjs")];for(let s of n)if(S(s))return I(s);return""}findAndReadHooks(e){let n=Y(e,"src/hooks");if(!S(n))return"";try{return ii(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
1289
- ${I(Y(n,s))}`).join(`
1430
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=V(t,"css");if(b(s)){for(let r of De(s))if(r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=A(V(s,r));break}}let o=V(t,"js");if(b(o)){for(let r of De(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=A(V(o,r));break}}let i=V(t,"templates");if(b(i)){for(let r of De(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=A(V(i,r));break}if(!n.template){for(let r of De(i))if(r.endsWith(".html")&&!pc.has(r)&&!r.startsWith("system")){let l=A(V(i,r));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let r of De(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=A(V(i,r));if(l.includes("dnd_area")){n.template=l;break}}}}let a=V(t,"modules");if(b(a))for(let r of De(a)){if(!r.endsWith(".module"))continue;let l=V(a,r);if(!vi(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=V(l,"fields.json");b(d)&&(c.fieldsJson=A(d));let u=V(l,"meta.json");b(u)&&(c.metaJson=A(u));let m=V(l,"module.html");b(m)&&(c.moduleHtml=A(m));let f=V(l,"module.css");b(f)&&(c.moduleCss=A(f));let h=V(l,"module.js");b(h)&&(c.moduleJs=A(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=V(t,"modules");return b(n)?new Set(De(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return b(t)?new Set(De(t)):new Set}detectExpectedModules(t,n){let s=V(t,"templates");if(!b(s))return 0;for(let o of De(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=A(V(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=V(t,"src");return b(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of De(t)){let o=V(t,s);try{vi(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();qe();Q();import fc from"@anthropic-ai/sdk";import{join as q,basename as gc}from"path";import{readdirSync as xi}from"fs";var Ln=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new fc({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,a=gi(o),r=gc(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,yi(c,d,l)),m=q(s,"css",`${l}-theme.css`);H(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let f=this.findAndReadHooks(n),h=this.findInteractiveComponents(n),y=await this.complete(a,bi(f,h,l)),v=q(s,"js",`${l}-animations.js`);H(v,y),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let C=this.findComponents(n),k=[];for(let E=0;E<C.length;E++){let R=C[E],W=R.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${W}.module (${E+1}/${C.length})...`);let L=A(R.path),U=await this.complete(a,hi(L,W,`See css/${l}-theme.css`));try{let F=JSON.parse(U),X={moduleName:W,fieldsJson:typeof F.fieldsJson=="string"?F.fieldsJson:JSON.stringify(F.fieldsJson,null,2),metaJson:typeof F.metaJson=="string"?F.metaJson:JSON.stringify(F.metaJson,null,2),moduleHtml:F.moduleHtml||"",moduleCss:F.moduleCss||"",moduleJs:F.moduleJs||void 0},le=q(s,"modules",`${W}.module`);Ae(le),H(q(le,"fields.json"),X.fieldsJson),H(q(le,"meta.json"),X.metaJson),H(q(le,"module.html"),X.moduleHtml),H(q(le,"module.css"),X.moduleCss),X.moduleJs&&H(q(le,"module.js"),X.moduleJs),k.push(X),i("module-done",`${W}.module (${this.countFiles(X)} files)`)}catch{i("module-error",`Failed to parse ${W} \u2014 skipping`)}}i("template","Creating page template...");let P=k.map(E=>E.moduleName),O=await this.complete(a,Si(P,r,l)),G=q(s,"templates",`lp-${l}.html`);return H(G,O),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:y,template:O,modules:k}}async complete(t,n){return(await this.client.messages.create({model:this.model,max_tokens:8192,system:t,messages:[{role:"user",content:n}]})).content.find(i=>i.type==="text")?.text||""}findAndReadCSS(t){let n=[q(t,"src/index.css"),q(t,"src/globals.css"),q(t,"src/app/globals.css"),q(t,"app/globals.css")];for(let s of n)if(b(s))return A(s);return""}findAndReadTailwind(t){let n=[q(t,"tailwind.config.ts"),q(t,"tailwind.config.js"),q(t,"tailwind.config.mjs")];for(let s of n)if(b(s))return A(s);return""}findAndReadHooks(t){let n=q(t,"src/hooks");if(!b(n))return"";try{return xi(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
1431
+ ${A(q(n,s))}`).join(`
1290
1432
 
1291
- `)}catch{return""}}findInteractiveComponents(e){let n=this.findComponents(e),s=[];for(let o of n){let i=I(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
1433
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=A(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
1292
1434
  ${i}`)}return s.join(`
1293
1435
 
1294
- `)}findComponents(e){let n=[Y(e,"src/components/landing"),Y(e,"src/components/sections"),Y(e,"src/components")];for(let s of n)if(S(s))try{return ii(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:Y(s,o)}))}catch{continue}return[]}countFiles(e){let n=3;return e.moduleCss&&n++,e.moduleJs&&n++,n}};g();Ve();Z();import{spawn as Ol}from"child_process";import{join as we}from"path";import{readdirSync as Mn,statSync as jl}from"fs";var _n=class{async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||le(),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=Ol("gemini",["-p",a],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",p=>{d+=p.toString()}),c.stderr.on("data",p=>{u+=p.toString()}),c.on("error",p=>l(new Error(`Gemini CLI failed: ${p.message}`))),c.on("close",p=>{p!==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(e,n,s){return`Read the conversion guide below, then convert the React landing page at ${e} into native HubSpot CMS modules for the theme at ${n}.
1436
+ `)}findComponents(t){let n=[q(t,"src/components/landing"),q(t,"src/components/sections"),q(t,"src/components")];for(let s of n)if(b(s))try{return xi(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:q(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};g();qe();Q();import{spawn as hc}from"child_process";import{join as xe}from"path";import{readdirSync as Gn,statSync as yc}from"fs";var Un=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||oe(),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=hc("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}.
1295
1437
 
1296
1438
  INSTRUCTIONS:
1297
1439
  1. Analyze all .tsx/.jsx components in the React source
@@ -1306,7 +1448,7 @@ CONVERSION GUIDE:
1306
1448
  ${s}
1307
1449
 
1308
1450
  Do NOT run hs upload \u2014 I will handle that separately.
1309
- Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=we(e,"css");if(S(s)){for(let r of Mn(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(we(s,r));break}}let o=we(e,"js");if(S(o)){for(let r of Mn(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(we(o,r));break}}let i=we(e,"templates");if(S(i)){for(let r of Mn(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(we(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=we(e,"modules");if(S(a))for(let r of Mn(a)){if(!r.endsWith(".module"))continue;let l=we(a,r);if(!jl(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=we(l,"fields.json");S(d)&&(c.fieldsJson=I(d));let u=we(l,"meta.json");S(u)&&(c.metaJson=I(u));let p=we(l,"module.html");S(p)&&(c.moduleHtml=I(p));let f=we(l,"module.css");S(f)&&(c.moduleCss=I(f));let h=we(l,"module.js");S(h)&&(c.moduleJs=I(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};g();Ve();Z();import{spawn as Fl}from"child_process";import{join as xe}from"path";import{readdirSync as Rn,statSync as Jl}from"fs";var On=class{async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||le(),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=Fl("codex",["exec","--full-auto",a],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",p=>{d+=p.toString()}),c.stderr.on("data",p=>{u+=p.toString()}),c.on("error",p=>l(new Error(`Codex CLI failed: ${p.message}`))),c.on("close",p=>{p!==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(e,n,s){return`Read the conversion guide below, then convert the React landing page at ${e} into native HubSpot CMS modules for the theme at ${n}.
1451
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=xe(t,"css");if(b(s)){for(let r of Gn(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=A(xe(s,r));break}}let o=xe(t,"js");if(b(o)){for(let r of Gn(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=A(xe(o,r));break}}let i=xe(t,"templates");if(b(i)){for(let r of Gn(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=A(xe(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=xe(t,"modules");if(b(a))for(let r of Gn(a)){if(!r.endsWith(".module"))continue;let l=xe(a,r);if(!yc(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=xe(l,"fields.json");b(d)&&(c.fieldsJson=A(d));let u=xe(l,"meta.json");b(u)&&(c.metaJson=A(u));let m=xe(l,"module.html");b(m)&&(c.moduleHtml=A(m));let f=xe(l,"module.css");b(f)&&(c.moduleCss=A(f));let h=xe(l,"module.js");b(h)&&(c.moduleJs=A(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};g();qe();Q();import{spawn as bc}from"child_process";import{join as we}from"path";import{readdirSync as Bn,statSync as Sc}from"fs";var Wn=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||oe(),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=bc("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}.
1310
1452
 
1311
1453
  INSTRUCTIONS:
1312
1454
  1. Analyze all .tsx/.jsx components in the React source
@@ -1321,15 +1463,15 @@ CONVERSION GUIDE:
1321
1463
  ${s}
1322
1464
 
1323
1465
  Do NOT run hs upload \u2014 I will handle that separately.
1324
- Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=xe(e,"css");if(S(s)){for(let r of Rn(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(xe(s,r));break}}let o=xe(e,"js");if(S(o)){for(let r of Rn(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(xe(o,r));break}}let i=xe(e,"templates");if(S(i)){for(let r of Rn(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(xe(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=xe(e,"modules");if(S(a))for(let r of Rn(a)){if(!r.endsWith(".module"))continue;let l=xe(a,r);if(!Jl(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=xe(l,"fields.json");S(d)&&(c.fieldsJson=I(d));let u=xe(l,"meta.json");S(u)&&(c.metaJson=I(u));let p=xe(l,"module.html");S(p)&&(c.moduleHtml=I(p));let f=xe(l,"module.css");S(f)&&(c.moduleCss=I(f));let h=xe(l,"module.js");S(h)&&(c.moduleJs=I(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ve();Z();function Dl(t,e){switch(t){case"claude-code":return new Nn(e);case"gemini-cli":return new _n;case"codex-cli":return new On;case"api":return new Pn}}async function jn(t){await ce("Converting React to HubSpot Modules"),await je(`AI will now analyze your React code and create
1325
- HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let e=Dl(t.aiEngine,t.model),n=le(),s=await ue();s.start("Starting AI conversion...");let o=Date.now(),i=await e.convert({sourceDir:t.sourceDir,themePath:t.themePath,conversionGuide:n,onProgress:(h,y)=>{h==="created"?F(y):s.message(y)}}),a=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${a}s)`);let r=Ll(t.themePath);for(let h of r)F(`Auto-fixed: ${h}`);let l=Hl(t.themePath,i),c=[];for(let h of l){let y=h.passed?"\u2705":"\u274C",b=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${y} ${h.label}${b}`)}let d=l.filter(h=>h.passed).length;c.push(`
1326
- ${d}/${l.length} checks passed`),await je(c.join(`
1327
- `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),p=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(W(`${u.length} critical issue(s) \u2014 upload will likely fail:
1466
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=we(t,"css");if(b(s)){for(let r of Bn(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=A(we(s,r));break}}let o=we(t,"js");if(b(o)){for(let r of Bn(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=A(we(o,r));break}}let i=we(t,"templates");if(b(i)){for(let r of Bn(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=A(we(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=we(t,"modules");if(b(a))for(let r of Bn(a)){if(!r.endsWith(".module"))continue;let l=we(a,r);if(!Sc(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=we(l,"fields.json");b(d)&&(c.fieldsJson=A(d));let u=we(l,"meta.json");b(u)&&(c.metaJson=A(u));let m=we(l,"module.html");b(m)&&(c.moduleHtml=A(m));let f=we(l,"module.css");b(f)&&(c.moduleCss=A(f));let h=we(l,"module.js");b(h)&&(c.moduleJs=A(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};qe();Q();function vc(e,t){switch(e){case"claude-code":return new Hn(t);case"gemini-cli":return new Un;case"codex-cli":return new Wn;case"api":return new Ln}}async function Vn(e){await ce("Converting React to HubSpot Modules"),await Je(`AI will now analyze your React code and create
1467
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=vc(e.aiEngine,e.model),n=oe(),s=await ue();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(h,y)=>{h==="created"?J(y):s.message(y)}}),a=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${a}s)`);let r=xc(e.themePath);for(let h of r)J(`Auto-fixed: ${h}`);let l=wc(e.themePath,i),c=[];for(let h of l){let y=h.passed?"\u2705":"\u274C",v=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${y} ${h.label}${v}`)}let d=l.filter(h=>h.passed).length;c.push(`
1468
+ ${d}/${l.length} checks passed`),await Je(c.join(`
1469
+ `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(B(`${u.length} critical issue(s) \u2014 upload will likely fail:
1328
1470
  `+u.map(y=>` - ${y.label}`).join(`
1329
- `)),!await se({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else p.length>0&&V(`${p.length} non-critical issue(s) \u2014 page will work but may look incomplete:
1330
- `+p.map(h=>` - ${h.label}`).join(`
1331
- `));let f=Ie(t.themePath,"..","vibespot-conversion.log");return S(f)&&(await se({message:"Keep conversion log file for debugging?",initialValue:!1})?F(`Log saved: ${f}`):ri(f)),await de("Files ready for upload!"),i}function Ll(t){let e=[];Gl(t),Ul(t);let n=Ie(t,"modules");if(S(n))for(let o of Vt(n)){if(!o.endsWith(".module"))continue;let i=Ie(n,o,"fields.json");if(!S(i))continue;let a=o.replace(".module",""),r=I(i),l=!1;r.includes('"textarea"')&&(r=r.replace(/"textarea"/g,'"text"'),l=!0,e.push(`${a}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(r)&&(r=r.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,e.push(`${a}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(r),u=!1;ai(d)&&(u=!0,e.push(`${a}: fixed choice field format`)),li(d)&&(u=!0,e.push(`${a}: fixed link field default value`)),u&&(r=JSON.stringify(d,null,2)+`
1332
- `,l=!0)}catch{e.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&H(i,r);let c=Ie(n,o,"module.html");if(S(c)){let d=I(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),H(c,d),e.push(`${a}: now() \u2192 local_dt`))}}let s=Ie(t,"templates");if(S(s))for(let o of Vt(s)){if(!o.endsWith(".html"))continue;let i=Ie(s,o),a=I(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(ri(i),e.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return e}function ai(t){let e=!1;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let a=i.charAt(0).toUpperCase()+i.slice(1);return[i,a]}return i}),e=!0),Array.isArray(s.children)&&ai(s.children)&&(e=!0)}return e}function li(t){let e=!1;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},e=!0}}Array.isArray(s.children)&&li(s.children)&&(e=!0)}return e}function Hl(t,e){let n=[],s=e.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of e.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=e.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let a=e.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=e.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:e.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:e.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:e.template.length>0&&e.template.includes("dnd_area"),critical:!0});let c=Ie(t,"templates"),d=!1;if(S(c))for(let u of Vt(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let p=I(Ie(c,u));if(p.includes("dnd_area")&&/templateType\s*:\s*page/i.test(p)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function Gl(t){let e=Ie(t,"templates");if(S(e))for(let n of Vt(e)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=Ie(e,n),o=I(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+=`
1471
+ `)),!await se({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:
1472
+ `+m.map(h=>` - ${h.label}`).join(`
1473
+ `));let f=ke(e.themePath,"..","vibespot-conversion.log");return b(f)&&(await se({message:"Keep conversion log file for debugging?",initialValue:!1})?J(`Log saved: ${f}`):wi(f)),await de("Files ready for upload!"),i}function xc(e){let t=[];Cc(e),Ac(e);let n=ke(e,"modules");if(b(n))for(let o of Qt(n)){if(!o.endsWith(".module"))continue;let i=ke(n,o,"fields.json");if(!b(i))continue;let a=o.replace(".module",""),r=A(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;Ci(d)&&(u=!0,t.push(`${a}: fixed choice field format`)),Ai(d)&&(u=!0,t.push(`${a}: fixed link field default value`)),u&&(r=JSON.stringify(d,null,2)+`
1474
+ `,l=!0)}catch{t.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&H(i,r);let c=ke(n,o,"module.html");if(b(c)){let d=A(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),H(c,d),t.push(`${a}: now() \u2192 local_dt`))}}let s=ke(e,"templates");if(b(s))for(let o of Qt(s)){if(!o.endsWith(".html"))continue;let i=ke(s,o),a=A(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(wi(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Ci(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)&&Ci(s.children)&&(t=!0)}return t}function Ai(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)&&Ai(s.children)&&(t=!0)}return t}function wc(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=ke(e,"templates"),d=!1;if(b(c))for(let u of Qt(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=A(ke(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 Cc(e){let t=ke(e,"templates");if(b(t))for(let n of Qt(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=ke(t,n),o=A(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+=`
1333
1475
  templateType: page`),a||(c+=`
1334
1476
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
1335
1477
  label: ${r}`),o=c+o.slice(l)}else o=`<!--
@@ -1337,32 +1479,32 @@ ${d}/${l.length} checks passed`),await je(c.join(`
1337
1479
  isAvailableForNewContent: true
1338
1480
  label: ${r}
1339
1481
  -->
1340
- `+o;H(s,o),F(`Template "${n}" \u2014 annotations verified`)}}function Ul(t){let e=Ie(t,"modules");if(S(e))for(let n of Vt(e)){if(!n.endsWith(".module"))continue;let s=Ie(e,n,"meta.json");if(S(s))try{let o=JSON.parse(I(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&H(s,JSON.stringify(o,null,2)+`
1341
- `)}catch{}}}g();ct();import{join as Si,basename as Zl}from"path";g();Z();import{join as oe}from"path";import{readdirSync as Ye,rmSync as Wl}from"fs";function Fn(t){let e=[];for(let n of t){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),e.push({file:n.file||"unknown",message:s,fixable:o})}return e}function Jn(t){let e=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(t)){let n=t.match(/(?:in|file:?)\s+(\S+fields\.json)/i);e.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(t)){let n=t.match(/(?:in|file:?)\s+(\S+fields\.json)/i);e.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(t)&&e.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(t)&&e.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(t)){let n=t.match(/field.*?(\w+)\s+has an invalid/i);e.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(t)){let n=t.match(/file '([^']+)'/i);e.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(t)&&e.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),e}function Dn(t){let e=[];return di(t)&&e.push("textarea \u2192 text"),ui(t)&&e.push("name \u2192 item_name"),mi(t)&&e.push("now() \u2192 local_dt"),pi(t)&&e.push("Removed HubDB templates"),fi(t)&&e.push("Fixed link field defaults"),gi(t)&&e.push("Fixed rgba/invalid color values \u2192 hex"),Bl(t)&&e.push("Stripped CDN @import statements"),e}function ci(t,e){return e.message.includes("textarea")?di(t):e.message.includes("reserved field name")?ui(t):e.message.includes("now()")?mi(t):e.message.includes("HubDB")?pi(t):e.message.includes("invalid default value")||e.message.includes("deserialization")?fi(t):e.message.includes("invalid format")&&e.message.includes("color")?gi(t):!1}function di(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(!S(o))continue;let i=I(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),H(o,i),e=!0)}return e}function ui(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(!S(o))continue;let i=I(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),H(o,i),e=!0)}return e}function mi(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"module.html");if(!S(o))continue;let i=I(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),H(o,i),e=!0)}return e}function pi(t){let e=!1,n=oe(t,"templates");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".html"))continue;let o=oe(n,s),i=I(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Wl(o),e=!0)}return e}function fi(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(S(o))try{let i=JSON.parse(I(o));yi(i)&&(H(o,JSON.stringify(i,null,2)+`
1342
- `),e=!0)}catch{}}return e}function Bl(t){let e=!1,n=oe(t,"css");if(S(n))for(let o of Ye(n)){if(!o.endsWith(".css"))continue;let i=oe(n,o),a=I(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(H(i,r),e=!0)}let s=oe(t,"modules");if(S(s))for(let o of Ye(s)){if(!o.endsWith(".module"))continue;let i=oe(s,o,"module.css");if(!S(i))continue;let a=I(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(H(i,r),e=!0)}if(S(s))for(let o of Ye(s)){if(!o.endsWith(".module"))continue;let i=oe(s,o,"module.html");if(!S(i))continue;let a=I(i),r=a.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");r!==a&&(H(i,r),e=!0)}return e}function gi(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(S(o))try{let i=JSON.parse(I(o));hi(i)&&(H(o,JSON.stringify(i,null,2)+`
1343
- `),e=!0)}catch{}}return e}function hi(t){let e=!1;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="color"&&s.default&&typeof s.default=="object"){let o=s.default,i=o.color;if(typeof i=="string"&&!Kl(i)){let a=Vl(i);a&&(o.color=a.hex,a.opacity!==void 0&&(o.opacity=a.opacity),e=!0)}}Array.isArray(s.children)&&hi(s.children)&&(e=!0)}return e}function Kl(t){return/^#[0-9a-fA-F]{6}$/.test(t)}function Vl(t){let e=t.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(e)return{hex:`#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}`};let n=t.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),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=t.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function yi(t){let e=!1;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},e=!0}}Array.isArray(s.children)&&yi(s.children)&&(e=!0)}return e}ee();g();ut();ut();import{readdirSync as Yl}from"fs";import{join as zl,relative as ql}from"path";var Xl=new Set([".git","node_modules",".vibespot",".DS_Store"]);function bi(t){let e=[];for(let n of Yl(t,{withFileTypes:!0})){if(Xl.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=zl(t,n.name);n.isDirectory()?e.push(...bi(s)):n.isFile()&&e.push(s)}return e}async function Ql(t,e,n){let s=0;async function o(){for(;s<t.length;){let a=s++;await n(t[a])}}let i=Array.from({length:Math.min(e,t.length)},()=>o());await Promise.all(i)}async function Ln(t,e,n,s={}){let o=s.concurrency??5,i=bi(e),a=i.length,r=0,l=0,c=[];return await Ql(i,o,async d=>{let u=ql(e,d).replace(/\\/g,"/"),p=`${n}/${u}`;s.onFileStart?.(u);let f=await Do(t,p,d);if(f.success)r++,s.onFileComplete?.(u);else{l++;let h={file:u,status:f.error?.status||0,message:f.error?.message||"Unknown error",category:f.error?.category,detail:f.error?.detail};c.push(h),s.onFileError?.(u,h)}s.onProgress?.(r+l,a)}),{success:l===0,uploaded:r,failed:l,total:a,errors:c}}function ec(t){return(t.match(/^Uploaded file /gm)||[]).length}async function Ct(t){await ce("Uploading to HubSpot");let e=Zl(t)||t,n=P(),s=he(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await ue(),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 p=await Ln(s,t,e,{onFileComplete:()=>{c++}});d=p.success,d?c=p.uploaded:l=Fn(p.errors)}else{let p=T(`hs cms upload "${t}" "${e}"`,{cwd:Si(t,"..")}),f=[p.stdout,p.stderr].filter(Boolean).join(`
1344
- `);c=ec(f),d=p.success,d||(l=Jn(f))}if(d)return i.stop(`All files uploaded! (${c} files)`),await de("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(W("Upload failed with unknown error."),c>0&&(V(`Most files uploaded successfully. The theme may already be usable in HubSpot.
1345
- You can check your HubSpot Design Manager to verify.`),await se({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(r<a){if(!await se({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let p of l)p.fixable?ci(t,p)?(F(`Auto-fixed: ${p.message}`),u=!0):V(`Could not auto-fix: ${p.message}`):W(p.message);if(!(u&&r<a)){if(c>0&&(V(`${c} files uploaded successfully despite errors.
1346
- The theme may work \u2014 check HubSpot Design Manager.`),await se({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await As(s,`${e}/modules`)}catch{}else T(`hs cms delete "${e}/modules"`,{cwd:Si(t,"..")});i.stop("Cleaned up modules, retrying...")}}}return W("Upload failed after multiple attempts."),!1}g();import{execFileSync as Es}from"child_process";import{rmSync as tc}from"fs";import{basename as vi}from"path";Z();async function wi(t){let{portalId:e,sourceDir:n,themePath:s,wasCloned:o}=t;await ce("You're all set!");let a=Lt(e)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await je(`Your React page has been converted and uploaded to HubSpot.
1482
+ `+o;H(s,o),J(`Template "${n}" \u2014 annotations verified`)}}function Ac(e){let t=ke(e,"modules");if(b(t))for(let n of Qt(t)){if(!n.endsWith(".module"))continue;let s=ke(t,n,"meta.json");if(b(s))try{let o=JSON.parse(A(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&H(s,JSON.stringify(o,null,2)+`
1483
+ `)}catch{}}}g();ut();import{join as Ri,basename as Nc}from"path";g();Q();import{join as ie}from"path";import{readdirSync as Xe,rmSync as kc}from"fs";function Kn(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 Yn(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 zn(e){let t=[];return Ii(e)&&t.push("textarea \u2192 text"),Ti(e)&&t.push("name \u2192 item_name"),$i(e)&&t.push("now() \u2192 local_dt"),Ei(e)&&t.push("Removed HubDB templates"),_i(e)&&t.push("Fixed link field defaults"),Pi(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),Ic(e)&&t.push("Stripped CDN @import statements"),t}function ki(e,t){return t.message.includes("textarea")?Ii(e):t.message.includes("reserved field name")?Ti(e):t.message.includes("now()")?$i(e):t.message.includes("HubDB")?Ei(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?_i(e):t.message.includes("invalid format")&&t.message.includes("color")?Pi(e):!1}function Ii(e){let t=!1,n=ie(e,"modules");if(!b(n))return!1;for(let s of Xe(n)){if(!s.endsWith(".module"))continue;let o=ie(n,s,"fields.json");if(!b(o))continue;let i=A(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),H(o,i),t=!0)}return t}function Ti(e){let t=!1,n=ie(e,"modules");if(!b(n))return!1;for(let s of Xe(n)){if(!s.endsWith(".module"))continue;let o=ie(n,s,"fields.json");if(!b(o))continue;let i=A(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),H(o,i),t=!0)}return t}function $i(e){let t=!1,n=ie(e,"modules");if(!b(n))return!1;for(let s of Xe(n)){if(!s.endsWith(".module"))continue;let o=ie(n,s,"module.html");if(!b(o))continue;let i=A(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),H(o,i),t=!0)}return t}function Ei(e){let t=!1,n=ie(e,"templates");if(!b(n))return!1;for(let s of Xe(n)){if(!s.endsWith(".html"))continue;let o=ie(n,s),i=A(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(kc(o),t=!0)}return t}function _i(e){let t=!1,n=ie(e,"modules");if(!b(n))return!1;for(let s of Xe(n)){if(!s.endsWith(".module"))continue;let o=ie(n,s,"fields.json");if(b(o))try{let i=JSON.parse(A(o));Oi(i)&&(H(o,JSON.stringify(i,null,2)+`
1484
+ `),t=!0)}catch{}}return t}function Ic(e){let t=!1,n=ie(e,"css");if(b(n))for(let o of Xe(n)){if(!o.endsWith(".css"))continue;let i=ie(n,o),a=A(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(H(i,r),t=!0)}let s=ie(e,"modules");if(b(s))for(let o of Xe(s)){if(!o.endsWith(".module"))continue;let i=ie(s,o,"module.css");if(!b(i))continue;let a=A(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(H(i,r),t=!0)}if(b(s))for(let o of Xe(s)){if(!o.endsWith(".module"))continue;let i=ie(s,o,"module.html");if(!b(i))continue;let a=A(i),r=a.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");r!==a&&(H(i,r),t=!0)}return t}function Pi(e){let t=!1,n=ie(e,"modules");if(!b(n))return!1;for(let s of Xe(n)){if(!s.endsWith(".module"))continue;let o=ie(n,s,"fields.json");if(b(o))try{let i=JSON.parse(A(o));Mi(i)&&(H(o,JSON.stringify(i,null,2)+`
1485
+ `),t=!0)}catch{}}return t}function Mi(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"&&!Tc(i)){let a=$c(i);a&&(o.color=a.hex,a.opacity!==void 0&&(o.opacity=a.opacity),t=!0)}}Array.isArray(s.children)&&Mi(s.children)&&(t=!0)}return t}function Tc(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function $c(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 Oi(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)&&Oi(s.children)&&(t=!0)}return t}Z();g();pt();pt();import{readdirSync as Ec}from"fs";import{join as _c,relative as Pc}from"path";var Mc=new Set([".git","node_modules",".vibespot",".DS_Store"]);function Ni(e){let t=[];for(let n of Ec(e,{withFileTypes:!0})){if(Mc.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=_c(e,n.name);n.isDirectory()?t.push(...Ni(s)):n.isFile()&&t.push(s)}return t}async function Oc(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 qn(e,t,n,s={}){let o=s.concurrency??5,i=Ni(t),a=i.length,r=0,l=0,c=[];return await Oc(i,o,async d=>{let u=Pc(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let f=await ii(e,m,d);if(f.success)r++,s.onFileComplete?.(u);else{l++;let h={file:u,status:f.error?.status||0,message:f.error?.message||"Unknown error",category:f.error?.category,detail:f.error?.detail};c.push(h),s.onFileError?.(u,h)}s.onProgress?.(r+l,a)}),{success:l===0,uploaded:r,failed:l,total:a,errors:c}}function Rc(e){return(e.match(/^Uploaded file /gm)||[]).length}async function $t(e){await ce("Uploading to HubSpot");let t=Nc(e)||e,n=_(),s=he(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await ue(),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 qn(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Kn(m.errors)}else{let m=$(`hs cms upload "${e}" "${t}"`,{cwd:Ri(e,"..")}),f=[m.stdout,m.stderr].filter(Boolean).join(`
1486
+ `);c=Rc(f),d=m.success,d||(l=Yn(f))}if(d)return i.stop(`All files uploaded! (${c} files)`),await de("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(B("Upload failed with unknown error."),c>0&&(z(`Most files uploaded successfully. The theme may already be usable in HubSpot.
1487
+ You can check your HubSpot Design Manager to verify.`),await se({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(r<a){if(!await se({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?ki(e,m)?(J(`Auto-fixed: ${m.message}`),u=!0):z(`Could not auto-fix: ${m.message}`):B(m.message);if(!(u&&r<a)){if(c>0&&(z(`${c} files uploaded successfully despite errors.
1488
+ The theme may work \u2014 check HubSpot Design Manager.`),await se({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await js(s,`${t}/modules`)}catch{}else $(`hs cms delete "${t}/modules"`,{cwd:Ri(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return B("Upload failed after multiple attempts."),!1}g();import{execFileSync as Vs}from"child_process";import{rmSync as Fc}from"fs";import{basename as Fi}from"path";Q();async function ji(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ce("You're all set!");let a=Wt(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await Je(`Your React page has been converted and uploaded to HubSpot.
1347
1489
  The theme and modules are now in your account, but you still
1348
- need to ${k.bold("create a new landing page")} that uses them.
1490
+ need to ${I.bold("create a new landing page")} that uses them.
1349
1491
 
1350
1492
  Next steps:
1351
1493
 
1352
- ${k.bold("1.")} Go to HubSpot ${k.muted("\u2192")} Content ${k.muted("\u2192")} Landing Pages ${k.muted("\u2192")} Create
1353
- ${k.bold("2.")} Choose your uploaded theme from the theme picker
1354
- ${k.bold("3.")} Select the landing page template that was just created
1355
- ${k.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
1356
- ${k.bold("5.")} Click each section to edit text, images, and colors
1357
- ${k.bold("6.")} Upload images via File Manager ${k.muted("(Settings \u2192 Files)")}
1358
- ${k.bold("7.")} Preview and publish!`,"What's next"),await se({message:"Open HubSpot Landing Pages in your browser?"})){let c=e?`https://${a}/page-ui/${e}/management/pages/landing`:`https://${a}`;try{let d=process.platform;d==="darwin"?Es("open",[c],{stdio:"ignore"}):d==="win32"?Es("cmd",["/c","start","",c],{stdio:"ignore"}):Es("xdg-open",[c],{stdio:"ignore"}),F("Opening HubSpot Landing Pages...")}catch{X(`Open this URL in your browser: ${k.info(c)}`)}}let l=[];if(o&&S(n)&&l.push({path:n,label:`Cloned source (${vi(n)})`}),S(s)&&l.push({path:s,label:`Theme directory (${vi(s)})`}),l.length>0&&await se({message:"Clean up local working directories?"}))for(let d of l)try{tc(d.path,{recursive:!0,force:!0}),F(`Removed ${d.label}`)}catch{V(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await de(`Thanks for using hub${k.vibes("Vibes")}! ${k.vibes("~")}`)}ee();async function xi(){_e();let t=await An(),e=await In();q({lastSourcePath:e.sourceDir});let n=await En();q({lastThemePath:n.themePath}),await jn({aiEngine:t.aiEngine,model:t.model,sourceDir:e.sourceDir,themePath:n.themePath}),await Ct(n.themePath),await wi({portalId:t.portalId,sourceDir:e.sourceDir,themePath:n.themePath,wasCloned:e.wasCloned})}g();async function Ci(){_e(),await An()}g();ee();async function Ai(){_e();let t=P();t.aiEngine||(W("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let e=await In(),n=await En();await jn({aiEngine:t.aiEngine,sourceDir:e.sourceDir,themePath:n.themePath})}g();ee();async function Ii(){_e();let t=P();if(t.lastThemePath)if(await se({message:`Upload from ${t.lastThemePath}?`}))await Ct(t.lastThemePath);else{let n=await $e({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Ct(n)}else{let e=await $e({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Ct(e)}}g();ee();async function ki(){_e(),await ce("Environment Diagnostics");let t=0,e=Ft();e.found?Sn(e.version)?F(`Node.js v${e.version}`):(V(`Node.js v${e.version} \u2014 too old (need 18+)`),X(" Update at https://nodejs.org"),t++):(W("Node.js \u2014 not installed"),X(" Install from https://nodejs.org"),t++);let n=Jt();n.found?F(`Git ${n.version}`):(W("Git \u2014 not installed"),X(" Install from https://git-scm.com"),t++);let s=Re();if(!s.found)V("HubSpot CLI \u2014 not installed (only needed for deployment)"),X(" Install: npm install -g @hubspot/cli");else if(!jo(s.version))V(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),X(" Update: npm install -g @hubspot/cli@latest"),t++;else{F(`HubSpot CLI v${s.version}`);let p=Oe();p.authenticated?F(`HubSpot portal${p.portalName?`: ${p.portalName}`:""} (ID: ${p.portalId})`):(V("HubSpot \u2014 not authenticated"),X(" Run: hs init"))}let o=Dt();o.found?F(`Claude Code ${o.version} at ${o.path}`):X(k.muted("Claude Code \u2014 not installed"));let i=Ht();i.found?F(`Gemini CLI ${i.version} at ${i.path}`):X(k.muted("Gemini CLI \u2014 not installed"));let a=Gt();a.found?F(`OpenAI Codex ${a.version} at ${a.path}`):X(k.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?F("Anthropic API key configured"):X(k.muted("Anthropic API key \u2014 not set")),c?F("OpenAI API key configured"):X(k.muted("OpenAI API key \u2014 not set")),d?F("Google AI API key configured"):X(k.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};r.aiEngine&&F(`AI engine: ${u[r.aiEngine]||r.aiEngine}`),r.lastThemePath&&X(k.muted(`Last theme: ${r.lastThemePath}`)),!o.found&&!i.found&&!a.found&&!l&&!c&&!d&&(V("No AI engine available"),X(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),X(" Or install: Claude Code \u2014 https://claude.ai/code"),X(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),X(" Codex CLI \u2014 https://github.com/openai/codex"),t++),console.log(),t===0?await de("Everything looks good!"):await de(k.warn(`${t} issue${t>1?"s":""} found \u2014 see above`))}g();import{join as gs}from"path";import{existsSync as yu}from"fs";import{execFileSync as Ao}from"child_process";import hs from"chalk";g();Se();Yt();Xn();os();ee();import{createServer as cu}from"http";import{readFileSync as Co,existsSync as dn}from"fs";import{join as at,extname as nl}from"path";import{createHash as du}from"crypto";import{WebSocketServer as uu}from"ws";g();import{spawn as yo}from"child_process";var rt=new Map;function Xr(t,e,n){t.stdout?.on("data",o=>{e.output+=o.toString()}),t.stderr?.on("data",o=>{e.output+=o.toString()}),t.on("close",o=>{e.status=o===0?"completed":"failed",e.exitCode=o,e.completedAt=Date.now()}),t.on("error",o=>{e.status="failed",e.output+=`
1359
- Process error: ${o.message}`,e.completedAt=Date.now()}),setTimeout(()=>{e.status==="running"&&(t.kill(),e.status="failed",e.output+=`
1360
- Process timed out`,e.completedAt=Date.now())},n||3e5)}function an(t,e,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${t} ${e.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};rt.set(o,i);let a=yo(t,e,{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()),Xr(a,i,s?.timeout),o}function ht(t,e,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:t,description:e,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};rt.set(s,o);let i=t.split(" "),a=yo(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Xr(a,o,n?.timeout),s}function is(t){return rt.get(t)}function Rd(){let t=Date.now()-18e5;for(let[e,n]of rt)n.completedAt&&n.completedAt<t&&rt.delete(e)}setInterval(Rd,600*1e3);function rs(t,e,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:t,description:e,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};rt.set(s,o);let i=t.split(" "),a=yo(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+=`
1494
+ ${I.bold("1.")} Go to HubSpot ${I.muted("\u2192")} Content ${I.muted("\u2192")} Landing Pages ${I.muted("\u2192")} Create
1495
+ ${I.bold("2.")} Choose your uploaded theme from the theme picker
1496
+ ${I.bold("3.")} Select the landing page template that was just created
1497
+ ${I.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
1498
+ ${I.bold("5.")} Click each section to edit text, images, and colors
1499
+ ${I.bold("6.")} Upload images via File Manager ${I.muted("(Settings \u2192 Files)")}
1500
+ ${I.bold("7.")} Preview and publish!`,"What's next"),await se({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"?Vs("open",[c],{stdio:"ignore"}):d==="win32"?Vs("cmd",["/c","start","",c],{stdio:"ignore"}):Vs("xdg-open",[c],{stdio:"ignore"}),J("Opening HubSpot Landing Pages...")}catch{ee(`Open this URL in your browser: ${I.info(c)}`)}}let l=[];if(o&&b(n)&&l.push({path:n,label:`Cloned source (${Fi(n)})`}),b(s)&&l.push({path:s,label:`Theme directory (${Fi(s)})`}),l.length>0&&await se({message:"Clean up local working directories?"}))for(let d of l)try{Fc(d.path,{recursive:!0,force:!0}),J(`Removed ${d.label}`)}catch{z(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await de(`Thanks for using hub${I.vibes("Vibes")}! ${I.vibes("~")}`)}Z();async function Ji(){Ne();let e=await Nn(),t=await Rn();K({lastSourcePath:t.sourceDir});let n=await Dn();K({lastThemePath:n.themePath}),await Vn({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await $t(n.themePath),await ji({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}g();async function Di(){Ne(),await Nn()}g();Z();async function Hi(){Ne();let e=_();e.aiEngine||(B("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await Rn(),n=await Dn();await Vn({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}g();Z();async function Li(){Ne();let e=_();if(e.lastThemePath)if(await se({message:`Upload from ${e.lastThemePath}?`}))await $t(e.lastThemePath);else{let n=await Te({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await $t(n)}else{let t=await Te({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await $t(t)}}g();Z();async function Gi(){Ne(),await ce("Environment Diagnostics");let e=0,t=Gt();t.found?En(t.version)?J(`Node.js v${t.version}`):(z(`Node.js v${t.version} \u2014 too old (need 18+)`),ee(" Update at https://nodejs.org"),e++):(B("Node.js \u2014 not installed"),ee(" Install from https://nodejs.org"),e++);let n=Ut();n.found?J(`Git ${n.version}`):(B("Git \u2014 not installed"),ee(" Install from https://git-scm.com"),e++);let s=Fe();if(!s.found)z("HubSpot CLI \u2014 not installed (only needed for deployment)"),ee(" Install: npm install -g @hubspot/cli");else if(!ni(s.version))z(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),ee(" Update: npm install -g @hubspot/cli@latest"),e++;else{J(`HubSpot CLI v${s.version}`);let m=je();m.authenticated?J(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(z("HubSpot \u2014 not authenticated"),ee(" Run: hs init"))}let o=Bt();o.found?J(`Claude Code ${o.version} at ${o.path}`):ee(I.muted("Claude Code \u2014 not installed"));let i=Vt();i.found?J(`Gemini CLI ${i.version} at ${i.path}`):ee(I.muted("Gemini CLI \u2014 not installed"));let a=Kt();a.found?J(`OpenAI Codex ${a.version} at ${a.path}`):ee(I.muted("OpenAI Codex \u2014 not installed"));let r=_(),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?J("Anthropic API key configured"):ee(I.muted("Anthropic API key \u2014 not set")),c?J("OpenAI API key configured"):ee(I.muted("OpenAI API key \u2014 not set")),d?J("Google AI API key configured"):ee(I.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};r.aiEngine&&J(`AI engine: ${u[r.aiEngine]||r.aiEngine}`),r.lastThemePath&&ee(I.muted(`Last theme: ${r.lastThemePath}`)),!o.found&&!i.found&&!a.found&&!l&&!c&&!d&&(z("No AI engine available"),ee(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),ee(" Or install: Claude Code \u2014 https://claude.ai/code"),ee(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),ee(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await de("Everything looks good!"):await de(I.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}g();import{join as ks}from"path";import{existsSync as Zu}from"fs";import{execFileSync as Uo}from"child_process";import Is from"chalk";g();Se();Zt();as();fs();Z();import{createServer as Wu}from"http";import{readFileSync as Go,existsSync as yn}from"fs";import{join as dt,extname as El}from"path";import{createHash as Vu}from"crypto";import{WebSocketServer as Ku}from"ws";g();import{spawn as Fo}from"child_process";var ct=new Map;function xa(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+=`
1501
+ Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
1502
+ Process timed out`,t.completedAt=Date.now())},n||3e5)}function fn(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};ct.set(o,i);let a=Fo(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()),xa(a,i,s?.timeout),o}function St(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};ct.set(s,o);let i=e.split(" "),a=Fo(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return xa(a,o,n?.timeout),s}function gs(e){return ct.get(e)}function yu(){let e=Date.now()-18e5;for(let[t,n]of ct)n.completedAt&&n.completedAt<e&&ct.delete(t)}setInterval(yu,600*1e3);function hs(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};ct.set(s,o);let i=e.split(" "),a=Fo(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+=`
1361
1503
  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+=`
1362
- Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Qr(t,e){let n=rt.get(t);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{e(s.output)}catch{}s.listeners.add(e)}function Zr(t,e){let n=rt.get(t);!n||!("listeners"in n)||n.listeners.delete(e)}ot();Z();g();ot();ee();import{existsSync as Mt,readdirSync as ea,rmSync as Od}from"fs";import{join as _t,basename as jd}from"path";import{homedir as Fd}from"os";import{execFileSync as ta}from"child_process";Tn();ut();Se();os();ee();Z();var na=process.platform==="win32"?{shell:!0}:{},Pe=_t(Fd(),"vibespot-themes"),as=null,Jd=5e3;function ls(){if(as&&Date.now()-as.ts<Jd)return as.data;let t=[];if(Mt(Pe))try{for(let e of ea(Pe,{withFileTypes:!0}))if(e.isDirectory()){let n=_t(Pe,e.name,"theme.json");if(Mt(n)){let s=0,o=_t(Pe,e.name,"modules");if(Mt(o))try{s=ea(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}t.push({name:e.name,moduleCount:s})}}}catch{}return as={data:t,ts:Date.now()},t}function sa(t){let e=v(),n=vn(),s=!1;try{ta("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...na}),s=!0}catch{}let o=kt().sort((a,r)=>r.updatedAt-a.updatedAt).slice(0,10),i=ls();m(t,200,{hasActiveSession:!!e,activeSession:e?{id:e.id,themeName:e.themeName,moduleCount:e.modules.length}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i})}function oa(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,""),i=_t(Pe,o);Ae(Pe),Mt(i)&&Od(i,{recursive:!0,force:!0}),$n(i,o),Qt(i,o),D(),m(e,200,{ok:!0,themeName:o,themePath:i})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ia(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){m(e,400,{error:"Theme name is required"});return}let i=he(),a=P(),r=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=_t(Pe,r);Ae(Pe),a.hubspotUploadMode==="cli"||!i?(ta("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...na}),Qt(l,r),tn(l),D(),m(e,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})):Bt(i,o,l).then(()=>{Qt(l,r),tn(l),D(),m(e,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})}).catch(c=>{m(e,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ra(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme path is required"});return}let o=s;if(Mt(o)||(o=_t(Pe,s)),!Mt(o)){m(e,400,{error:`Theme folder not found: ${s}`});return}let i=jd(o);Qt(o,i),tn(o),D(),m(e,200,{ok:!0,themeName:i,themePath:o,moduleCount:v()?.modules.length||0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function aa(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Session ID is required"});return}let o=zn(s);if(!o){m(e,404,{error:"Session not found"});return}m(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function la(t,e){j(t,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"API key is required"});return}q({anthropicApiKey:s}),m(e,200,{ok:!0})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ca(t){let e=he();if(!e){m(t,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Ho(e);if(n.length===0){m(t,200,{themes:[]});return}let s=[],o=n.map(async r=>{let l=r.path||r.name;try{let c=await Cn(e,`${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=ls(),a=new Set(i.map(r=>r.name));m(t,200,{themes:s.map(r=>({...r,existsLocally:a.has(r.name)}))})})().catch(n=>{m(t,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}g();ot();ee();Se();import{existsSync as Dd,readFileSync as Ld,appendFileSync as Hd}from"fs";import{join as da}from"path";import{homedir as ua}from"os";ut();Z();var ln={data:{},ts:0},Gd=600*1e3,ma={"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 Ud(t){let e=await fetch("https://api.anthropic.com/v1/models",{headers:{"x-api-key":t,"anthropic-version":"2023-06-01"}});return e.ok?(await e.json()).data.filter(s=>!s.id.startsWith("claude-3-")&&!s.id.startsWith("claude-2")).map(s=>({id:s.id,label:s.display_name})):[]}async function Wd(t){let e=await fetch("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${t}`}});if(!e.ok)return[];let n=await e.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 Bd(t){let e=await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${t}`);return e.ok?(await e.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function Kd(){if(Date.now()-ln.ts<Gd&&Object.keys(ln.data).length>0)return ln.data;let t=P(),e={...ma},n=[],s=ge("anthropic-api",t);s&&n.push(Ud(s).then(a=>{a.length&&(e["anthropic-api"]=a)}).catch(()=>{}));let o=ge("openai-api",t);o&&n.push(Wd(o).then(a=>{a.length&&(e["openai-api"]=a)}).catch(()=>{}));let i=ge("gemini-api",t);return i&&n.push(Bd(i).then(a=>{a.length&&(e["gemini-api"]=a,e["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n),ln.data=e,ln.ts=Date.now(),e}function pa(t){let e=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},o=kt().length,i=ls().length,a=St();Kd().then(r=>{m(t,200,{version:a,environment:e,config:s,models:r,sessionCount:o,localThemeCount:i})}).catch(()=>{m(t,200,{version:a,environment:e,config:s,models:ma,sessionCount:o,localThemeCount:i})})}function fa(t,e){j(t,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","openai-api","gemini-cli","gemini-api","codex-cli"].includes(s)){m(e,400,{error:`Invalid engine: ${s}`});return}let a={aiEngine:s};if(o)switch(s){case"claude-code":a.claudeCodeModel=o;break;case"anthropic-api":a.anthropicApiModel=o;break;case"openai-api":a.openaiApiModel=o;break}q(a),m(e,200,{ok:!0,engine:s})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ga(t,e){j(t,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;default:m(e,400,{error:`Unknown provider: ${s}`});return}q(l),m(e,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;default:m(e,400,{error:`Unknown provider: ${s}`});return}q(i);let a=null;if(!P().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(q({aiEngine:c}),a=c)}m(e,200,{ok:!0,provider:s,autoSelectedEngine:a})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ha(t,e){j(t,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){m(e,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let a=ht(i.cmd,i.desc,{timeout:12e4});m(e,200,{ok:!0,jobId:a})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ya(t,e){j(t,n=>{try{let s=JSON.parse(n||"{}"),o=P(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){xn(s.personalAccessKey).then(a=>{Ot(s.personalAccessKey,a.portalId,a.portalName,a.dataCenter),m(e,200,{ok:!0,portalName:a.portalName,portalId:a.portalId,dataCenter:a.dataCenter})}).catch(a=>{m(e,400,{error:a instanceof Error?a.message:String(a)})});return}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=an("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});m(e,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];m(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=Oe();if(r.authenticated&&!s.force){m(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}m(e,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ba(t,e){j(t,n=>{try{let s=JSON.parse(n||"{}");if(!xs().found){m(e,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=Cs();if(i.authenticated&&!s.force){m(e,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let r=an("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});m(e,200,{ok:!0,jobId:r});return}let a=ht("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});m(e,200,{ok:!0,jobId:a,browserAuthRequired:!0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Sa(t,e){j(t,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((P().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){bs(s),m(e,200,{ok:!0});return}if(s){Ss(s),m(e,200,{ok:!0});return}}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){m(e,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=an("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});m(e,200,{ok:!0,jobId:c});return}if(l){let c=an("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});m(e,200,{ok:!0,jobId:c});return}}m(e,400,{error:"portalId required"})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function va(t){let e=ht("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});m(t,200,{ok:!0,jobId:e})}function wa(t,e){j(t,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=ht("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=ht("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,q({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")?da(ua(),".zshrc"):da(ua(),".bashrc");try{(Dd(l)?Ld(l,"utf-8"):"").includes("OPENAI_API_KEY")||Hd(l,`
1504
+ Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function wa(e,t){let n=ct.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Ca(e,t){let n=ct.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}et();Q();g();et();Z();import{existsSync as Rt,readdirSync as Aa,rmSync as bu}from"fs";import{join as Ft,basename as Su}from"path";import{homedir as vu}from"os";import{execFileSync as ka}from"child_process";Jn();pt();Se();fs();Z();Q();var Ia=process.platform==="win32"?{shell:!0}:{},Me=Ft(vu(),"vibespot-themes"),ys=null,xu=5e3;function bs(){if(ys&&Date.now()-ys.ts<xu)return ys.data;let e=[];if(Rt(Me))try{for(let t of Aa(Me,{withFileTypes:!0}))if(t.isDirectory()){let n=Ft(Me,t.name,"theme.json");if(Rt(n)){let s=0,o=Ft(Me,t.name,"modules");if(Rt(o))try{s=Aa(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return ys={data:e,ts:Date.now()},e}function Ta(e){let t=S(),n=_n(),s=!1;try{ka("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Ia}),s=!0}catch{}let o=Pt().sort((a,r)=>r.updatedAt-a.updatedAt).slice(0,10),i=bs();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 $a(e,t){N(e,n=>{try{if(Nt()){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=Ft(Me,o);Ae(Me),Rt(i)&&bu(i,{recursive:!0,force:!0}),jn(i,o),sn(i,o),D(),p(t,200,{ok:!0,themeName:o,themePath:i})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Ea(e,t){N(e,n=>{try{if(Nt()){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=he(),a=_(),r=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Ft(Me,r);Ae(Me),a.hubspotUploadMode==="cli"||!i?(ka("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Ia}),sn(l,r),an(l),D(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:S()?.modules.length||0})):qt(i,o,l).then(()=>{sn(l,r),an(l),D(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:S()?.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 _a(e,t){N(e,n=>{try{if(Nt()){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(Rt(o)||(o=Ft(Me,s)),!Rt(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Su(o);sn(o,i),an(o),D(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:S()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Pa(e,t){N(e,n=>{try{if(Nt()){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=is(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 Ma(e,t){N(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}K({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Oa(e){let t=he();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await ai(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 On(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=bs(),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)})})}g();et();Z();Se();import{existsSync as wu,readFileSync as Cu,appendFileSync as Au}from"fs";import{join as Na}from"path";import{homedir as Ra}from"os";pt();Q();var gn={data:{},ts:0},ku=600*1e3,Fa={"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 Iu(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 Tu(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 $u(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 Eu(){if(Date.now()-gn.ts<ku&&Object.keys(gn.data).length>0)return gn.data;let e=_(),t={...Fa},n=[],s=ge("anthropic-api",e);s&&n.push(Iu(s).then(a=>{a.length&&(t["anthropic-api"]=a,t["claude-oauth"]=a)}).catch(()=>{}));let o=ge("openai-api",e);o&&n.push(Tu(o).then(a=>{a.length&&(t["openai-api"]=a)}).catch(()=>{}));let i=ge("gemini-api",e);return i&&n.push($u(i).then(a=>{a.length&&(t["gemini-api"]=a,t["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n),gn.data=t,gn.ts=Date.now(),t}function ja(e){let t=_n(),n=_(),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},o=Pt().length,i=bs().length,a=wt();Eu().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:Fa,sessionCount:o,localThemeCount:i})})}function Ja(e,t){N(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}K(a),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Da(e,t){N(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;default:p(t,400,{error:`Unknown provider: ${s}`});return}K(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;default:p(t,400,{error:`Unknown provider: ${s}`});return}K(i);let a=null;if(!_().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(K({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 Ha(e,t){N(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=St(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 La(e,t){N(e,n=>{try{let s=JSON.parse(n||"{}"),o=_(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){Mn(s.personalAccessKey).then(a=>{Jt(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(!Fe().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=fn("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(!Fe().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=je();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 Ga(e,t){N(e,n=>{try{let s=JSON.parse(n||"{}");if(!Rs().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=Fs();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let r=fn("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:r});return}let a=St("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 Ua(e,t){N(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((_().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){$s(s),p(t,200,{ok:!0});return}if(s){Es(s),p(t,200,{ok:!0});return}}else{if(!Fe().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=fn("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=fn("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 Ba(e){let t=St("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function Wa(e,t){N(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=St("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=St("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,K({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")?Na(Ra(),".zshrc"):Na(Ra(),".bashrc");try{(wu(l)?Cu(l,"utf-8"):"").includes("OPENAI_API_KEY")||Au(l,`
1363
1505
  # Added by vibeSpot
1364
1506
  ${r}
1365
- `)}catch{}}}m(e,200,{ok:!0,message:"API key saved"})}else{let i=ht("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:m(e,400,{error:`Unknown CLI: ${s}`})}}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function xa(t,e){j(t,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){m(e,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}q({hubspotUploadMode:s}),m(e,200,{ok:!0,mode:s})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Ca(t,e){j(t,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){m(e,400,{error:"toolId (string) and enabled (boolean) required"});return}vs(s,o),m(e,200,{ok:!0,toolId:s,enabled:o})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Aa(t,e){j(t,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency"],i={};for(let a of o)a in s&&(i[a]=s[a]);if(Object.keys(i).length===0){m(e,400,{error:"No valid settings fields provided"});return}q(i),m(e,200,{ok:!0,updated:Object.keys(i)})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Ia(t,e){let n=t.replace("/api/settings/job/","");if(!n){m(e,400,{error:"Job ID required"});return}let s=is(n);if(!s){m(e,404,{error:"Job not found"});return}m(e,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}g();ot();Se();import{existsSync as Vd,rmSync as Yd}from"fs";import{join as zd}from"path";function ka(t,e,n){if(t==="GET"){let s=v(),o=kt().sort((i,a)=>a.updatedAt-i.updatedAt);m(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName}:null,sessions:o});return}if(t==="DELETE"){j(e,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Vi(o,i),m(n,200,{ok:!0})}catch(o){m(n,500,{error:o instanceof Error?o.message:String(o)})}});return}m(n,405,{error:"Method not allowed"})}function $a(t,e){j(t,n=>{try{let{sessionId:s}=JSON.parse(n),o=zn(s);if(!o){m(e,404,{error:"Session not found"});return}m(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ta(t,e){j(t,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=zd(Pe,s);if(!Vd(o)){m(e,404,{error:"Theme not found on disk"});return}Yd(o,{recursive:!0,force:!0}),m(e,200,{ok:!0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ea(t,e){j(t,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(e,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){m(e,400,{error:"Invalid name"});return}let a=Yi(s,i);a.ok?m(e,200,{ok:!0,newName:i}):m(e,400,{error:a.error})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}g();ot();ve();ee();Se();Z();import{existsSync as fs,readFileSync as ou,rmSync as xo}from"fs";import{join as Ge,basename as iu}from"path";import{execFileSync as ru}from"child_process";var au=process.platform==="win32"?{shell:!0}:{};function Oa(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}let n=nt();m(t,200,{themeName:e.themeName,themePath:e.themePath,templates:e.templates.map(s=>({id:s.id,label:s.label,pageType:s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:e.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!e.brandAssets?.styleguide,hasBrandvoice:!!e.brandAssets?.brandvoice,hasThemeContext:!!e.brandAssets?.themeContext,humanify:e.brandAssets?.humanify!==!1}})}function ja(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}let n=e.themePath;if(!fs(n)){m(t,404,{error:"Theme directory not found"});return}let s=e.themeName||"theme",o=Ge(n,".."),i=iu(n);try{let a=`${s}.zip`,r=Ge(o,a);fs(r)&&xo(r),ru("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...au});let l=ou(r);xo(r),t.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${a}"`,"Content-Length":l.length}),t.end(l)}catch(a){E.error("download-zip","Failed to create zip archive",a),m(t,500,{error:"Failed to create zip archive"})}}function Fa(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){m(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(t==="POST"){j(e,o=>{try{let{pageType:i,label:a}=JSON.parse(o);if(!i||!a){m(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only"].includes(i)){m(n,400,{error:`Invalid pageType: ${i}`});return}let l=Gi(i,a);D(),m(n,200,{ok:!0,template:{id:l.id,label:l.label,pageType:l.pageType}})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){j(e,o=>{try{let{templateId:i,deleteModules:a}=JSON.parse(o);if(!i){m(n,400,{error:"templateId is required"});return}if(!Bi(i,!!a)){m(n,404,{error:"Template not found"});return}D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}m(n,405,{error:"Method not allowed"})}function Ja(t,e){j(t,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){m(e,400,{error:"templateId is required"});return}if(!_s(s)){m(e,404,{error:"Template not found"});return}D();let i=v();m(e,200,{ok:!0,modules:me().map(a=>a.moduleName),messageCount:i?.messages.length||0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Da(t,e){j(t,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(e,400,{error:"templateId and newLabel are required"});return}if(!Wi(s,o.trim())){m(e,404,{error:"Template not found"});return}D(),m(e,200,{ok:!0,newLabel:o.trim()})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function La(t,e){j(t,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){m(e,400,{error:"templateId is required"});return}let i=Ui(s,o);if(!i){m(e,404,{error:"Template not found"});return}D(),m(e,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ha(t){let e=nt();m(t,200,{modules:e.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Ga(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}j(e,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){m(n,400,{error:"moduleName is required"});return}let r=nt().find(d=>d.module.moduleName===i);if(!r){m(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()),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}})}function Ua(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){m(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(t==="POST"){j(e,o=>{try{let{type:i,content:a}=JSON.parse(o);if(!i){m(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=a==="on",s.updatedAt=Date.now(),D(),m(n,200,{ok:!0});return}if(!a){m(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let r=i==="themeContext"?"theme-context.md":`${i}.md`;s.brandAssets[i]=a,s.updatedAt=Date.now();let l=Ge(s.themePath,".vibespot");Ae(l),H(Ge(l,r),a),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){j(e,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(n,400,{error:`Invalid type: ${i}`});return}s.brandAssets&&delete s.brandAssets[i],s.updatedAt=Date.now();let a=i==="themeContext"?"theme-context.md":`${i}.md`,r=Ge(s.themePath,".vibespot",a);fs(r)&&xo(r),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}m(n,405,{error:"Method not allowed"})}function _a(t,e,n){if(!t)return;t.brandAssets||(t.brandAssets={}),t.brandAssets[e]=n,t.updatedAt=Date.now();let s=e==="themeContext"?"theme-context.md":`${e}.md`,o=Ge(t.themePath,".vibespot");Ae(o),H(Ge(o,s),n)}async function Ra(t,e,n){if(e==="styleguide"){let{extractDesignContext:p}=await Promise.resolve().then(()=>(ps(),ms));return p(n||t.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(os(),qr)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),_o)),i=o(),{engine:a,apiKey:r,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Xn(),Bs)),d=c();if(!d||d.length<50)return null;if(e==="brandvoice"){let{extractBrandvoice:p}=await Promise.resolve().then(()=>(Ma(),Pa));return p(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(wo(),vo));return u(d,t.brandAssets?.themeContext,a,r,l)}function Wa(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,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=>Ra(n,u,a))),d={};for(let u=0;u<l.length;u++){let p=c[u],f=p.status==="fulfilled"?p.value:null;f&&_a(n,l[u],f),d[l[u]]=f}D(),m(e,200,{ok:!0,type:"all",extracted:d});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(e,400,{error:`Invalid type: ${i}`});return}let r=await Ra(n,i,a);if(!r){m(e,200,{ok:!1,type:i,error:"No content to extract from"});return}_a(n,i,r),D(),m(e,200,{ok:!0,type:i,content:r})}catch(o){m(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}function Ba(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{(async()=>{try{let{source:o,themeName:i,localPath:a}=JSON.parse(s),r;if(o==="hubspot"){if(!i){m(e,400,{error:"themeName is required for HubSpot import"});return}let u=he();if(!u){m(e,400,{error:"No HubSpot account connected"});return}let p=i.replace(/^\/+|\/+$/g,"");if(!p){m(e,400,{error:"Invalid theme name"});return}let f=p.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),y=Ge(h(),"vibespot-themes",".references",f);Ae(y);let{fetchTheme:b}=await Promise.resolve().then(()=>(Tn(),Vo));await b(u,p,y),r=y}else if(o==="local"){if(!a){m(e,400,{error:"localPath is required for local import"});return}if(!fs(a)){m(e,400,{error:`Path not found: ${a}`});return}r=a}else{m(e,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(ps(),ms)),c=await l(r);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ge(n.themePath,".vibespot");Ae(d),H(Ge(d,"styleguide.md"),c),D(),m(e,200,{ok:!0,styleguide:c,source:r})}catch(o){m(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}g();ot();Se();import{join as lu}from"path";Yt();function Ka(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}m(e,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function Va(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){let o=me();m(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(t==="DELETE"){no(e,n,o=>{o.deleteEntirely?Fi(o.moduleName):Ji(o.moduleName),D(),m(n,200,{ok:!0})});return}m(n,405,{error:"Method not allowed"})}function Ya(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{m(e,400,{error:"Invalid shared type"});return}let c=Ce();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),D(),st(),m(e,200,{ok:!0});return}let{moduleName:i,fileType:a,content:r}=o;if(!i||!a){m(e,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){m(e,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{m(e,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=r;break;default:m(e,400,{error:`Invalid fileType: ${a}`});return}n.updatedAt=Date.now(),D(),st(),m(e,200,{ok:!0})}catch(o){m(e,400,{error:String(o)})}})}function za(t,e){no(t,e,n=>{Array.isArray(n.order)?(At(n.order),D(),m(e,200,{ok:!0})):m(e,400,{error:"order must be an array"})})}async function qa(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}try{st();let n=Dn(e.themePath),s=rs(`hs cms upload "${e.themePath}" "${e.themeName}"`,"Uploading to HubSpot",{cwd:lu(e.themePath,".."),timeout:18e4});m(t,200,{ok:!0,jobId:s,fixes:n})}catch(n){m(t,500,{error:String(n)})}}function Xa(t,e){j(t,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Di(s,o,i),D(),m(e,200,{ok:!0})}catch(s){m(e,400,{error:String(s)})}})}function Qa(t,e){j(t,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"url is required"});return}let o=Bo(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
1507
+ `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=St("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 Va(e,t){N(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}K({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ka(e,t){N(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}_s(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 Ya(e,t){N(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency"],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}K(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function za(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=gs(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();et();Z();Ke();function qa(e,t){N(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}Ps(s.trim(),(o||"").trim());let i=_();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&K({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Xa(e,t){let n=Re(),s=Lt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Qa(e,t){try{kn(),_().aiEngine==="claude-oauth"&&K({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}g();et();Se();import{existsSync as _u,rmSync as Pu}from"fs";import{join as Mu}from"path";function Za(e,t,n){if(e==="GET"){let s=S(),o=Pt().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"){N(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);cr(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 el(e,t){N(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=is(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 tl(e,t){N(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=Mu(Me,s);if(!_u(o)){p(t,404,{error:"Theme not found on disk"});return}Pu(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function nl(e,t){N(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=dr(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)})}})}g();et();ve();Z();Se();Q();import{existsSync as As,readFileSync as Hu,rmSync as Lo}from"fs";import{join as Be,basename as Lu}from"path";import{execFileSync as Gu}from"child_process";var Uu=process.platform==="win32"?{shell:!0}:{};function cl(e){let t=S();if(!t){p(e,404,{error:"No active session"});return}let n=rt();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 dl(e){let t=S();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!As(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=Be(n,".."),i=Lu(n);try{let a=`${s}.zip`,r=Be(o,a);As(r)&&Lo(r),Gu("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...Uu});let l=Hu(r);Lo(r),e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${a}"`,"Content-Length":l.length}),e.end(l)}catch(a){T.error("download-zip","Failed to create zip archive",a),p(e,500,{error:"Failed to create zip archive"})}}function ul(e,t,n){let s=S();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"){N(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=or(i,a);D(),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"){N(t,o=>{try{let{templateId:i,deleteModules:a}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!ar(i,!!a)){p(n,404,{error:"Template not found"});return}D(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function ml(e,t){N(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!qs(s)){p(t,404,{error:"Template not found"});return}D();let i=S();p(t,200,{ok:!0,modules:me().map(a=>a.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function pl(e,t){N(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(!rr(s,o.trim())){p(t,404,{error:"Template not found"});return}D(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function fl(e,t){N(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=ir(s,o);if(!i){p(t,404,{error:"Template not found"});return}D(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function gl(e){let t=rt();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function hl(e,t,n){let s=S();if(!s){p(n,404,{error:"No active session"});return}N(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let r=rt().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()),D(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function yl(e,t,n){let s=S();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"){N(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(),D(),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==="themeContext"?"theme-context.md":`${i}.md`;s.brandAssets[i]=a,s.updatedAt=Date.now();let l=Be(s.themePath,".vibespot");Ae(l),H(Be(l,r),a),D(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){N(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}s.brandAssets&&delete s.brandAssets[i],s.updatedAt=Date.now();let a=i==="themeContext"?"theme-context.md":`${i}.md`,r=Be(s.themePath,".vibespot",a);As(r)&&Lo(r),D(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function al(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=Be(e.themePath,".vibespot");Ae(o),H(Be(o,s),n)}async function ll(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Cs(),ws));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(fs(),va)),{loadConfig:o}=await Promise.resolve().then(()=>(Z(),Qo)),i=o(),{engine:a,apiKey:r,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(as(),lo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(rl(),il));return m(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(Ho(),Do));return u(d,e.brandAssets?.themeContext,a,r,l)}function bl(e,t){let n=S();if(!n){p(t,404,{error:"No active session"});return}N(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=>ll(n,u,a))),d={};for(let u=0;u<l.length;u++){let m=c[u],f=m.status==="fulfilled"?m.value:null;f&&al(n,l[u],f),d[l[u]]=f}D(),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 ll(n,i,a);if(!r){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}al(n,i,r),D(),p(t,200,{ok:!0,type:i,content:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function Sl(e,t){let n=S();if(!n){p(t,404,{error:"No active session"});return}N(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=he();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:h}=await import("os"),y=Be(h(),"vibespot-themes",".references",f);Ae(y);let{fetchTheme:v}=await Promise.resolve().then(()=>(Jn(),pi));await v(u,m,y),r=y}else if(o==="local"){if(!a){p(t,400,{error:"localPath is required for local import"});return}if(!As(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(()=>(Cs(),ws)),c=await l(r);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Be(n.themePath,".vibespot");Ae(d),H(Be(d,"styleguide.md"),c),D(),p(t,200,{ok:!0,styleguide:c,source:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}g();et();Se();import{join as Bu}from"path";Zt();function vl(e,t){let n=S();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 xl(e,t,n){let s=S();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=me();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"){vo(t,n,o=>{o.deleteEntirely?Zi(o.moduleName):er(o.moduleName),D(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function wl(e,t){let n=S();if(!n){p(t,404,{error:"No active session"});return}N(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=Ce();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),D(),at(),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(),D(),at(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function Cl(e,t){vo(e,t,n=>{Array.isArray(n.order)?(Et(n.order),D(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function Al(e){let t=S();if(!t){p(e,404,{error:"No active session"});return}try{at();let n=zn(t.themePath),s=hs(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:Bu(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function kl(e,t){N(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);tr(s,o,i),D(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function Il(e,t){N(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=ui(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
1366
1508
  `),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.
1367
1509
 
1368
1510
  Source analysis found ${o.components.length} components:
@@ -1372,11 +1514,11 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
1372
1514
  Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
1373
1515
  Interactions: ${o.interactions.join(", ")}
1374
1516
 
1375
- 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.`};m(e,200,a)}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Za(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}if(!Ee()){m(e,200,{available:!1,commits:[]});return}let o=new URL(t.url||"/","http://localhost").searchParams.get("templateId"),i=o?Mi(n.themePath,o,50):Pi(n.themePath,50);m(e,200,{available:!0,commits:i,filtered:!!o})}function el(t,e){j(t,n=>{try{let s=v();if(!s){m(e,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){m(e,400,{error:"Commit hash is required"});return}if(tt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let a=s.templates.find(c=>c.id===i);if(!a){m(e,404,{error:"Template not found"});return}let r=a.moduleOrder.map(c=>`modules/${c}.module`);a.templateFile&&r.push(a.templateFile);let l=Ri(s.themePath,i,o,r);if(!l.success){m(e,500,{error:l.error||"Rollback failed"});return}Qi()}else{let a=_i(s.themePath,o);if(!a.success){m(e,500,{error:a.error||"Rollback failed"});return}Xi()}D(),m(e,200,{ok:!0,modules:me().map(a=>a.moduleName)})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}io();var sl={".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 ol(t){let{port:e,uiDir:n}=t,s=cu((i,a)=>mu(i,a,n)),o=new uu({server:s});return o.on("connection",i=>fu(i)),new Promise((i,a)=>{s.on("error",r=>{r.code==="EADDRINUSE"?s.listen(e+1,()=>{i({port:e+1,close:()=>{s.close(),o.close()}})}):a(r)}),s.listen(e,()=>{i({port:e,close:()=>{s.close(),o.close()}})})})}function mu(t,e,n){let s=new URL(t.url||"/",`http://${t.headers.host}`),o=t.method||"GET";if(e.setHeader("X-Content-Type-Options","nosniff"),e.setHeader("X-Frame-Options","DENY"),e.setHeader("X-XSS-Protection","1; mode=block"),e.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname.startsWith("/api/")){pu(o,s.pathname,t,e);return}if(s.pathname==="/preview"){let i=Us();e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",a=Ws(i);e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(a||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){gu(s.pathname.slice(14),e);return}hu(s.pathname,n,t,e)}function pu(t,e,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"),t==="OPTIONS"){s.writeHead(204),s.end();return}switch(e){case"/api/session":Ka(t,s);break;case"/api/modules":Va(t,n,s);break;case"/api/modules/reorder":za(n,s);break;case"/api/modules/code":Ya(n,s);break;case"/api/upload":qa(s);break;case"/api/upload-files":t==="POST"?vr(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/field":Xa(n,s);break;case"/api/import":Qa(n,s);break;case"/api/setup":sa(s);break;case"/api/setup/create":oa(n,s);break;case"/api/setup/fetch":ia(n,s);break;case"/api/setup/open":ra(n,s);break;case"/api/setup/resume":aa(n,s);break;case"/api/setup/apikey":la(n,s);break;case"/api/setup/remote-themes":t==="GET"?ca(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/status":t==="GET"?pa(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":t==="POST"?fa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":t==="POST"?ga(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/install":t==="POST"?ha(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":t==="POST"?ya(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":t==="POST"?ba(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":t==="POST"?Sa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":t==="POST"?va(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":t==="POST"?wa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":t==="POST"?xa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":t==="POST"?Ca(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings":t==="POST"?Aa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/changelog":t==="GET"?m(s,200,{changelog:To()}):m(s,405,{error:"Method not allowed"});break;case"/api/themes":ka(t,n,s);break;case"/api/themes/switch":t==="POST"?$a(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":t==="POST"?Ta(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":t==="POST"?Ea(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/history":t==="GET"?Za(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/rollback":t==="POST"?el(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/dashboard":t==="GET"?Oa(s):m(s,405,{error:"Method not allowed"});break;case"/api/templates":Fa(t,n,s);break;case"/api/templates/activate":t==="POST"?Ja(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":t==="POST"?Da(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":t==="POST"?La(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/module-library":t==="GET"?Ha(s):m(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":Ua(t,n,s);break;case"/api/brand-assets/extract":t==="POST"?Wa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":t==="POST"?Ba(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/download-zip":t==="GET"?ja(s):m(s,405,{error:"Method not allowed"});break;default:e.startsWith("/api/settings/job/")&&t==="GET"?Ia(e,s):e.match(/^\/api\/templates\/[^/]+\/add-module$/)&&t==="POST"?Ga(e,n,s):m(s,404,{error:"Not found"})}}function fu(t){t.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{t.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;tt("user",o),D();let i=Array.isArray(s.fileIds)?s.fileIds:void 0,a=ho();a.needsPrompt&&t.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await fo(o,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:p,...f}=u;t.send(JSON.stringify(f))}else t.send(JSON.stringify(u));if(u.type==="agent_step")l.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let p=l[l.length-1];p&&(p.decisions||(p.decisions=[]),p.decisions.push(u.decision))}else u.type==="design_system_ready"?De({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(De({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),At(u.moduleOrder),t.send(JSON.stringify({type:"modules_updated",modules:me().map(p=>p.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(De({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),t.send(JSON.stringify({type:"modules_updated",modules:me().map(p=>p.moduleName)})),c.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&c.push({name:u.module,status:"failed"})},i);go(d,{steps:l,modules:c,stats:d.stats})}else mo(l=>{t.send(JSON.stringify({type:"parse_warning",message:l}))}),await rn(o,l=>{t.send(JSON.stringify({type:"stream",content:l}))},l=>{t.send(JSON.stringify({type:"stream_status",content:l}))},i);let r=v();if(r){st();let l=Ce(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${r.themeName}-theme.css`),l.sharedJs&&d.push(`js/${r.themeName}-animations.js`),c=Ni(r.themePath,l.id,o,d)}else c=Ns(r.themePath,o);c&&t.send(JSON.stringify({type:"version_created",hash:c}))}t.send(JSON.stringify({type:"generation_complete"})),t.send(JSON.stringify({type:"modules_updated",modules:me().map(l=>l.moduleName)}));{let l=v();l&&a.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&t.send(JSON.stringify({type:"suggest_brand_extraction"}))}}catch(r){t.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"extract_brand_assets":{let o=v();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=P(),{engine:a,apiKey:r,model:l}=ss(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Xn(),Bs)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(wo(),vo)),p=await u(d,o.brandAssets?.themeContext,a,r,l),{mkdirSync:f,writeFileSync:h}=await import("fs");if(p){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=p,o.updatedAt=Date.now();let y=at(o.themePath,".vibespot");dn(y)||f(y,{recursive:!0}),h(at(y,"theme-context.md"),p),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:y}=await Promise.resolve().then(()=>(ps(),ms)),b=await y(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let A=at(o.themePath,".vibespot");dn(A)||f(A,{recursive:!0}),h(at(A,"styleguide.md"),b),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}t.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){t.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=v();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}try{st();let i=Dn(o.themePath);if(i.length>0&&t.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(P().hubspotUploadMode||"api")==="api"){let l=he();if(!l){t.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}t.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await Ln(l,o.themePath,o.themeName,{onFileStart:d=>{t.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
1376
- `}))},onFileComplete:d=>{t.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
1377
- `}))},onFileError:(d,u)=>{t.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
1378
- `}))},onProgress:(d,u)=>{t.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Xe();t.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName}))}else{let d=Fn(c.errors);t.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
1379
- `),errors:d}))}}else{let l=rs(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:at(o.themePath,".."),timeout:18e4});t.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{t.send(JSON.stringify({type:"upload_output",chunk:u}))};Qr(l,c);let d=setInterval(()=>{let u=is(l);if(!(!u||u.status==="running"))if(clearInterval(d),Zr(l,c),u.status==="completed"){let p=Oe(),f=p.portalId?Lt(p.portalId):"na1";t.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:p.portalId||"",dataCenter:f,themeName:o.themeName}))}else{let p=Jn(u.output);t.send(JSON.stringify({type:"upload_failed",output:u.output,errors:p,exitCode:u.exitCode}))}},500)}}catch(i){t.send(JSON.stringify({type:"error",message:i instanceof Error?i.message:String(i)}))}break}case"upload_fix_with_ai":{let o=String(s.errorContext||"");if(!o.trim()){t.send(JSON.stringify({type:"error",message:"No error context provided"}));break}let i=`The HubSpot upload ("hs cms upload") failed. Below is the upload log output containing the errors.
1517
+ 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 Tl(e,t){let n=S();if(!n){p(t,404,{error:"No active session"});return}if(!_e()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?Yi(n.themePath,o,50):Ki(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function $l(e,t){N(e,n=>{try{let s=S();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(it("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=qi(s.themePath,i,o,r);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}fr()}else{let a=zi(s.themePath,o);if(!a.success){p(t,500,{error:a.error||"Rollback failed"});return}pr()}D(),p(t,200,{ok:!0,modules:me().map(a=>a.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}Co();var _l={".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 Pl(e){let{port:t,uiDir:n}=e,s=Wu((i,a)=>Yu(i,a,n)),o=new Ku({server:s});return o.on("connection",i=>qu(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 Yu(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/")){zu(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=ro();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=ao(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(a||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){Xu(s.pathname.slice(14),t);return}Qu(s.pathname,n,e,t)}function zu(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":vl(e,s);break;case"/api/modules":xl(e,n,s);break;case"/api/modules/reorder":Cl(n,s);break;case"/api/modules/code":wl(n,s);break;case"/api/upload":Al(s);break;case"/api/upload-files":e==="POST"?Lr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":kl(n,s);break;case"/api/import":Il(n,s);break;case"/api/setup":Ta(s);break;case"/api/setup/create":$a(n,s);break;case"/api/setup/fetch":Ea(n,s);break;case"/api/setup/open":_a(n,s);break;case"/api/setup/resume":Pa(n,s);break;case"/api/setup/apikey":Ma(n,s);break;case"/api/setup/remote-themes":e==="GET"?Oa(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?ja(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?Ja(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?Da(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Ha(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?La(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?Ga(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?Ua(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Ba(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?Wa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Va(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Ka(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?qa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Xa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Qa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Ya(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Ko()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Za(e,n,s);break;case"/api/themes/switch":e==="POST"?el(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?tl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?nl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?Tl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?$l(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?cl(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":ul(e,n,s);break;case"/api/templates/activate":e==="POST"?ml(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?pl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?fl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?gl(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":yl(e,n,s);break;case"/api/brand-assets/extract":e==="POST"?bl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?Sl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?dl(s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?za(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?hl(t,n,s):p(s,404,{error:"Not found"})}}function qu(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;it("user",o),D();let i=Array.isArray(s.fileIds)?s.fileIds:void 0,a=Ro();a.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await Oo(o,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:m,...f}=u;e.send(JSON.stringify(f))}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"?Le({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(Le({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),Et(u.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:me().map(m=>m.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(Le({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:me().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);No(d,{steps:l,modules:c,stats:d.stats})}else Po(l=>{e.send(JSON.stringify({type:"parse_warning",message:l}))}),await pn(o,l=>{e.send(JSON.stringify({type:"stream",content:l}))},l=>{e.send(JSON.stringify({type:"stream_status",content:l}))},i);let r=S();if(r){at();let l=Ce(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${r.themeName}-theme.css`),l.sharedJs&&d.push(`js/${r.themeName}-animations.js`),c=Vi(r.themePath,l.id,o,d)}else c=Ks(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:me().map(l=>l.moduleName)}));{let l=S();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"extract_brand_assets":{let o=S();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=_(),{engine:a,apiKey:r,model:l}=ps(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(as(),lo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(Ho(),Do)),m=await u(d,o.brandAssets?.themeContext,a,r,l),{mkdirSync:f,writeFileSync:h}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let y=dt(o.themePath,".vibespot");yn(y)||f(y,{recursive:!0}),h(dt(y,"theme-context.md"),m),D(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:y}=await Promise.resolve().then(()=>(Cs(),ws)),v=await y(o.themePath);if(v){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=v,o.updatedAt=Date.now();let C=dt(o.themePath,".vibespot");yn(C)||f(C,{recursive:!0}),h(dt(C,"styleguide.md"),v),D(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=S();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{at();let i=zn(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(_().hubspotUploadMode||"api")==="api"){let l=he();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 qn(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
1518
+ `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
1519
+ `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
1520
+ `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=nt();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=Kn(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
1521
+ `),errors:d}))}}else{let l=hs(`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}))};wa(l,c);let d=setInterval(()=>{let u=gs(l);if(!(!u||u.status==="running"))if(clearInterval(d),Ca(l,c),u.status==="completed"){let m=je(),f=m.portalId?Wt(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:f,themeName:o.themeName}))}else{let m=Yn(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.
1380
1522
 
1381
1523
  IMPORTANT: Be verbose in your response. For each error:
1382
1524
  1. State exactly which file has the problem and what the error is
@@ -1389,9 +1531,9 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
1389
1531
  After fixing all errors, summarize the changes you made.
1390
1532
 
1391
1533
  Upload log:
1392
- ${o}`;tt("user",i),D(),t.send(JSON.stringify({type:"upload_fix_started"}));try{await rn(i,r=>{t.send(JSON.stringify({type:"stream",content:r})),t.send(JSON.stringify({type:"upload_fix_stream",content:r}))});let a=v();if(a){st();let r=Ns(a.themePath,"AI fix: upload errors");r&&t.send(JSON.stringify({type:"version_created",hash:r}))}t.send(JSON.stringify({type:"upload_fix_complete"})),t.send(JSON.stringify({type:"modules_updated",modules:me().map(r=>r.moduleName)}))}catch(a){t.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":t.send(JSON.stringify({type:"pong"}));break;default:t.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}});let e=v();if(e){let n=P(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Ce();t.send(JSON.stringify({type:"init",sessionId:e.id,themeName:e.themeName,modules:me().map(i=>i.moduleName),messageCount:e.messages.length,messages:e.messages,gitAvailable:Ee(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",templateId:o?.id||null,pageType:o?.pageType||null,templates:(e.templates||[]).map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))}))}else t.send(JSON.stringify({type:"needs_setup"}))}function gu(t,e){let n=v();if(!n){e.writeHead(404,{"Content-Type":"text/plain"}),e.end("No session");return}let s=at(n.themePath,"assets",t);if(!dn(s)){e.writeHead(404,{"Content-Type":"text/plain"}),e.end("Asset not found");return}let o=nl(s),i=sl[o]||"application/octet-stream",a=Co(s);e.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),e.end(a)}var tl=new Map;function hu(t,e,n,s){let i=at(e,t==="/"?"/index.html":t);if(!dn(i)){let c=at(e,"index.html");if(dn(c)){let d=Co(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=nl(i),r=sl[a]||"application/octet-stream",l=a===".html";try{let c=tl.get(i);if(!c){let u=Co(i),p='"'+du("md5").update(u).digest("hex").slice(0,16)+'"';c={buffer:u,etag:p,contentType:r},tl.set(i,c)}if(n.headers["if-none-match"]===c.etag){s.writeHead(304),s.end();return}s.writeHead(200,{"Content-Type":c.contentType,"Cache-Control":l?"no-cache":"public, max-age=3600",ETag:c.etag}),s.end(c.buffer)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}Se();var bu=4200;async function il(){let t=hs.hex("#e8613a"),e=hs.dim;console.log(""),console.log(t(" v vibeSpot")),console.log(e(` Starting...
1393
- `));let n=Su();n||(console.error(hs.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await ol({port:bu,uiDir:n}),i=`http://localhost:${s}`;console.log(t(` v ${i}`)),console.log(e(` Press Ctrl+C to stop
1394
- `));try{process.platform==="darwin"?Ao("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ao("cmd",["/c","start","",i],{stdio:"ignore"}):Ao("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(e(`
1395
- Saving session...`)),D(),o(),console.log(e(` Goodbye!
1396
- `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(hs.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Su(){let t=[gs(import.meta.dirname,"../../ui"),gs(import.meta.dirname,"../ui"),gs(process.cwd(),"ui")];for(let e of t)if(yu(gs(e,"index.html")))return e;return null}Z();function rl(){let t=new vu;return t.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(St()).action(il),t.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(xi),t.command("init").description("Check and install required tools").action(Ci),t.command("convert").description("Convert a React project to HubSpot modules").action(Ai),t.command("upload").description("Upload theme to HubSpot").action(Ii),t.command("doctor").description("Diagnose environment issues").action(ki),t}var wu=rl();wu.parseAsync(process.argv).catch(t=>{console.error(t),process.exit(1)});
1534
+ ${o}`;it("user",i),D(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await pn(i,r=>{e.send(JSON.stringify({type:"stream",content:r})),e.send(JSON.stringify({type:"upload_fix_stream",content:r}))});let a=S();if(a){at();let r=Ks(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:me().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;default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}});let t=S();if(t){let n=_(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Ce();e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:me().map(i=>i.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:_e(),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}))}))}else e.send(JSON.stringify({type:"needs_setup"}))}function Xu(e,t){let n=S();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=dt(n.themePath,"assets",e);if(!yn(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=El(s),i=_l[o]||"application/octet-stream",a=Go(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(a)}function Qu(e,t,n,s){let i=dt(t,e==="/"?"/index.html":e);if(!yn(i)){let c=dt(t,"index.html");if(yn(c)){let d=Go(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=El(i),r=_l[a]||"application/octet-stream",l=a===".html";try{let c=Go(i),d='"'+Vu("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")}}Se();var em=4200;async function Ml(){let e=Is.hex("#e8613a"),t=Is.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
1535
+ `));let n=tm();n||(console.error(Is.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await Pl({port:em,uiDir:n}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Press Ctrl+C to stop
1536
+ `));try{process.platform==="darwin"?Uo("open",[i],{stdio:"ignore"}):process.platform==="win32"?Uo("cmd",["/c","start","",i],{stdio:"ignore"}):Uo("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
1537
+ Saving session...`)),D(),o(),console.log(t(` Goodbye!
1538
+ `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Is.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function tm(){let e=[ks(import.meta.dirname,"../../ui"),ks(import.meta.dirname,"../ui"),ks(process.cwd(),"ui")];for(let t of e)if(Zu(ks(t,"index.html")))return t;return null}Q();function Ol(){let e=new nm;return e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(wt()).action(Ml),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Ji),e.command("init").description("Check and install required tools").action(Di),e.command("convert").description("Convert a React project to HubSpot modules").action(Hi),e.command("upload").description("Upload theme to HubSpot").action(Li),e.command("doctor").description("Diagnose environment issues").action(Gi),e}var sm=Ol();sm.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
1397
1539
  //# sourceMappingURL=index.js.map