vibespot 1.0.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,45 @@
1
- var jl=Object.defineProperty;var D=(e,t)=>()=>(e&&(t=e(e=0)),t);var nt=(e,t)=>{for(var n in t)jl(e,n,{get:t[n],enumerable:!0})};import cm from"path";import{fileURLToPath as um}from"url";var g=D(()=>{"use strict"});import{readFileSync as Ts,writeFileSync as Fl,mkdirSync as Ko,existsSync as Sn}from"fs";import{dirname as Jl,join as Ve}from"path";function k(e){return Ts(e,"utf-8")}function U(e,t){Ko(Jl(e),{recursive:!0}),Fl(e,t,"utf-8")}function b(e){return Sn(e)}function Ae(e){Ko(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 Yo(){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=D(()=>{"use strict";g();xt="";bn=""});import{execSync as zo}from"child_process";function E(e,t={}){try{return{stdout:zo(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 qo(e,t={}){try{return zo(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var ut=D(()=>{"use strict";g()});var Zo={};nt(Zo,{addHubSpotAccount:()=>Jt,getActiveHubSpotAccount:()=>st,getApiKeyForEngine:()=>ge,getConfigDir:()=>Ll,getHubSpotPak:()=>he,isCliToolEnabled:()=>Dt,loadConfig:()=>_,maskApiKey:()=>wn,removeHubSpotAccount:()=>$s,saveConfig:()=>K,setActiveHubSpotAccount:()=>Es,setCliToolEnabled:()=>_s});import{join as Xo}from"path";import{homedir as Dl}from"os";import{chmodSync as Hl}from"fs";function _(){if(!b(xn))return{};try{let e=JSON.parse(k(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(U(xn,JSON.stringify(n,null,2)),process.platform!=="win32")try{Hl(xn,384)}catch{}}function Ll(){return Qo}function st(){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 st()?.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 Qo,xn,Z=D(()=>{"use strict";g();Q();Qo=Xo(Dl(),".vibespot"),xn=Xo(Qo,"config.json")});var Os={};nt(Os,{OAUTH_EXTRA_HEADERS:()=>Ht,OAUTH_SYSTEM_PREFIX:()=>At,clearOAuthTokens:()=>kn,getOAuthTokenInfo:()=>Lt,getValidAccessToken:()=>Ms,hasValidOAuthToken:()=>Re,saveInitialToken:()=>Ps});import{join as Ul}from"path";import{homedir as Gl}from"os";import{chmodSync as Bl,unlinkSync as Wl}from"fs";function An(){if(!b(Ct))return null;try{return JSON.parse(k(Ct))}catch{return null}}function ei(e){if(U(Ct,JSON.stringify(e,null,2)),process.platform!=="win32")try{Bl(Ct,384)}catch{}}async function zl(e){let t=await fetch(Kl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:Vl})});if(!t.ok)throw kn(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();ei({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Ps(e,t=""){ei({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()>Yl)return e.access_token;if(e.refresh_token){Cn||(Cn=zl(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{Wl(Ct)}catch{}}var Vl,Kl,Ct,Yl,Ht,At,Cn,Ke=D(()=>{"use strict";g();Q();Vl="9d1c250a-e61b-44d9-88ed-5944d1962f5e",Kl="https://console.anthropic.com/v1/oauth/token",Ct=Ul(Gl(),".vibespot","claude-oauth.json"),Yl=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 Zl}from"path";async function ii(e){let t=oi.get(e);if(t&&t.expiresAt-Date.now()>nc)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 oi.set(e,o),o}async function kt(e){let{accessToken:t}=await ii(e);return{Authorization:`Bearer ${t}`}}function Pn(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function sc(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function oc(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=ec){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=tc*Math.pow(2,s);await oc(i);continue}return o}return fetch(e,t)}async function Mn(e){let t=await ii(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:sc(e)}}async function ri(e,t,n){let s=Ql(n),o=Zl(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 Fs(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 ai(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 li(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,ec,tc,nc,oi,pt=D(()=>{"use strict";g();Ye="https://api.hubapi.com",ec=3,tc=1e3,nc=300*1e3,oi=new Map});var fi={};nt(fi,{fetchTheme:()=>qt});import{mkdirSync as pi,writeFileSync as lc}from"fs";import{join as cc,dirname as dc}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 uc(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`);pi(n,{recursive:!0}),await uc(i,o,async a=>{let r=a.startsWith(t+"/")?a.slice(t.length+1):a,l=cc(n,r);pi(dc(l),{recursive:!0});let c=await ai(e,a);lc(l,c),s.onFile?.(r)})}var Jn=D(()=>{"use strict";g();pt()});function Tt(e){let t=gi.get(e);if(t!==void 0)return t;try{t=k(vn(e))}catch{t=""}return gi.set(e,t),t}function oe(){return Tt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function Us(){return Tt("design-guide.md")}function Gs(){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 hi(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
1
+ var Wc=Object.defineProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var ke=(e,t)=>{for(var n in t)Wc(e,n,{get:t[n],enumerable:!0})};import Xp from"path";import{fileURLToPath as Qp}from"url";var f=L(()=>{"use strict"});import{readFileSync as Xs,writeFileSync as Vc,mkdirSync as Ni,existsSync as Rn}from"fs";import{dirname as Kc,join as et}from"path";function I(e){return Xs(e,"utf-8")}function G(e,t){Ni(Kc(e),{recursive:!0}),Vc(e,t,"utf-8")}function C(e){return Rn(e)}function Te(e){Ni(e,{recursive:!0})}function Fn(e){let t=[et(import.meta.dirname,"../../assets",e),et(import.meta.dirname,"../assets",e),et(process.cwd(),"assets",e)];for(let n of t)if(Rn(n))return n;throw new Error(`Asset not found: ${e}`)}function Pt(){if(_t)return _t;let e=[et(import.meta.dirname,"../../package.json"),et(import.meta.dirname,"../package.json"),et(process.cwd(),"package.json")];for(let t of e)if(Rn(t))try{let n=JSON.parse(Xs(t,"utf-8"));if(n.name==="vibespot"&&n.version)return _t=n.version,_t}catch{}return _t="dev",_t}function Mi(){if(On)return On;let e=[et(import.meta.dirname,"../../CHANGELOG.md"),et(import.meta.dirname,"../CHANGELOG.md"),et(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Rn(t))try{return On=Xs(t,"utf-8"),On}catch{}return""}var _t,On,te=L(()=>{"use strict";f();_t="";On=""});import{execSync as Oi}from"child_process";function F(e,t={}){try{return{stdout:Oi(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Ri(e,t={}){try{return Oi(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var ht=L(()=>{"use strict";f()});var ji={};ke(ji,{addHubSpotAccount:()=>qt,getActiveHubSpotAccount:()=>ut,getApiKeyForEngine:()=>be,getConfigDir:()=>qc,getHubSpotPak:()=>Se,isCliToolEnabled:()=>Xt,loadConfig:()=>N,maskApiKey:()=>jn,removeHubSpotAccount:()=>Zs,saveConfig:()=>W,setActiveHubSpotAccount:()=>Qs,setCliToolEnabled:()=>eo});import{join as Fi}from"path";import{homedir as zc}from"os";import{chmodSync as Yc}from"fs";function N(){if(!C(Jn))return{};try{let e=JSON.parse(I(Jn));return e.aiEngine==="api"&&(e.aiEngine="anthropic-api"),e}catch{return{}}}function be(e,t){let n=t||N();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;default:return}}function jn(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function W(e){let n={...N(),...e};if(G(Jn,JSON.stringify(n,null,2)),process.platform!=="win32")try{Yc(Jn,384)}catch{}}function qc(){return Ji}function ut(){let e=N();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function qt(e,t,n,s){let i=N().hubspotAccounts||[],a=i.findIndex(l=>l.portalId===t),r={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};a>=0?i[a]=r:i.push(r),W({hubspotAccounts:i,activeHubSpotAccount:t})}function Zs(e){let t=N(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),W(s)}function Qs(e){W({activeHubSpotAccount:e})}function Se(){return ut()?.personalAccessKey||null}function Xt(e){return N().enabledCLITools?.includes(e)??!1}function eo(e,t){let n=N(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),W({enabledCLITools:[...s]})}var Ji,Jn,Q=L(()=>{"use strict";f();te();Ji=Fi(zc(),".vibespot"),Jn=Fi(Ji,"config.json")});var so={};ke(so,{OAUTH_EXTRA_HEADERS:()=>Zt,OAUTH_SYSTEM_PREFIX:()=>Mt,clearOAuthTokens:()=>Ln,getOAuthTokenInfo:()=>Qt,getValidAccessToken:()=>no,hasValidOAuthToken:()=>Le,saveInitialToken:()=>to});import{join as Xc}from"path";import{homedir as Zc}from"os";import{chmodSync as Qc,unlinkSync as ed}from"fs";function Hn(){if(!C(Nt))return null;try{return JSON.parse(I(Nt))}catch{return null}}function Di(e){if(G(Nt,JSON.stringify(e,null,2)),process.platform!=="win32")try{Qc(Nt,384)}catch{}}async function od(e){let t=await fetch(nd,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:td})});if(!t.ok)throw Ln(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Di({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function to(e,t=""){Di({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Le(){let e=Hn();return e?e.expires_at>Date.now():!1}async function no(){let e=Hn();if(!e)return null;if(e.expires_at-Date.now()>sd)return e.access_token;if(e.refresh_token){Dn||(Dn=od(e.refresh_token).finally(()=>{Dn=null}));try{await Dn}catch{return null}return Hn()?.access_token??null}return e.access_token}function Qt(){let e=Hn();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function Ln(){if(C(Nt))try{ed(Nt)}catch{}}var td,nd,Nt,sd,Zt,Mt,Dn,tt=L(()=>{"use strict";f();te();td="9d1c250a-e61b-44d9-88ed-5944d1962f5e",nd="https://console.anthropic.com/v1/oauth/token",Nt=Xc(Zc(),".vibespot","claude-oauth.json"),sd=300*1e3,Zt={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},Mt="You are Claude Code, Anthropic's official CLI for Claude.";Dn=null});import{readFileSync as ad}from"fs";import{basename as ld}from"path";async function Gi(e){let t=Ui.get(e);if(t&&t.expiresAt-Date.now()>ud)return t;let n=await fetch(`${nt}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:e})});if(!n.ok){let i=await n.text().catch(()=>"");throw new Error(n.status===401||n.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${n.status}): ${i.slice(0,200)}`)}let s=await n.json(),o={accessToken:s.oauthAccessToken,expiresAt:s.expiresAtMillis,hubId:s.hubId,hubName:s.hubName||""};return Ui.set(e,o),o}async function Ot(e){let{accessToken:t}=await Gi(e);return{Authorization:`Bearer ${t}`}}function Kn(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function md(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function pd(e){return new Promise(t=>setTimeout(t,e))}async function an(e,t){let n=`HTTP ${e.status}`,s,o;try{let i=await e.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let a=i.errors[0];o=a.message||JSON.stringify(a)}}catch{try{let i=await e.text();i&&(n=i.slice(0,500))}catch{}}return{status:e.status,message:t?`${n} (${t})`:n,category:s,detail:o}}async function ln(e,t,n=cd){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=dd*Math.pow(2,s);await pd(i);continue}return o}return fetch(e,t)}async function zn(e){let t=await Gi(e),n=`${nt}/account-info/v3/details`,s=await ln(n,{headers:await Ot(e)});if(!s.ok){let r=await an(s);throw new Error(`Failed to get account info: ${r.message}`)}let o=await s.json(),i=String(o.portalId||t.hubId||""),a=t.hubName||o.uiDomain||i;return{portalId:i,portalName:a,dataCenter:md(e)}}async function Wi(e,t,n){let s=ad(n),o=ld(n),i=new FormData,a=new Blob([s]);i.append("file",a,o);let r=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,l=await ln(r,{method:"PUT",headers:await Ot(e),body:i});if(!l.ok){let c=await an(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function ao(e,t){let n=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,s=await ln(n,{method:"DELETE",headers:await Ot(e)});if(!s.ok&&s.status!==404){let o=await an(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Vi(e,t){let n=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,s=await ln(n,{method:"GET",headers:await Ot(e)});if(!s.ok){let i=await an(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Yn(e,t){let n=`${nt}/cms/v3/source-code/published/metadata/${Kn(t)}`,s=await ln(n,{method:"GET",headers:await Ot(e)});if(s.status===404)return null;if(!s.ok){let o=await an(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Ki(e){let t=await Ot(e),n=[`${nt}/cms/v3/source-code/published/metadata`,`${nt}/cms/v3/source-code/published/metadata/`,`${nt}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let i=await o.json(),a=i.children||i.objects||(Array.isArray(i)?i:null);if(a&&a.length>0)return a.filter(r=>r.folder)}}catch{}return[]}var nt,cd,dd,ud,Ui,bt=L(()=>{"use strict";f();nt="https://api.hubapi.com",cd=3,dd=1e3,ud=300*1e3,Ui=new Map});var Zi={};ke(Zi,{createThemeScaffold:()=>cn});import{mkdirSync as mt,writeFileSync as Zn}from"fs";import{join as Ne}from"path";function cn(e,t){mt(e,{recursive:!0}),mt(Ne(e,"templates"),{recursive:!0}),mt(Ne(e,"modules"),{recursive:!0}),mt(Ne(e,"css"),{recursive:!0}),mt(Ne(e,"js"),{recursive:!0}),mt(Ne(e,"images"),{recursive:!0}),mt(Ne(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};Zn(Ne(e,"theme.json"),JSON.stringify(n,null,2)+`
2
+ `),Zn(Ne(e,"fields.json"),`[]
3
+ `);let s=`<!--
4
+ templateType: page
5
+ isAvailableForNewContent: false
6
+ label: ${t} (placeholder)
7
+ screenshotPath: ../images/template-previews/home.png
8
+ -->
9
+ {% extends "./layouts/base.html" %}
10
+
11
+ {% block body %}
12
+ {% dnd_area "main_content"
13
+ label="Main Content",
14
+ class="body-container body-container--${t}"
15
+ %}
16
+ {% end_dnd_area %}
17
+ {% endblock body %}
18
+ `;Zn(Ne(e,"templates","home.html"),s);let o=`<!--
19
+ templateType: none
20
+ isAvailableForNewContent: false
21
+ label: Base Layout
22
+ -->
23
+ <!DOCTYPE html>
24
+ <html lang="{{ html_lang }}" {{ html_lang_dir }}>
25
+ <head>
26
+ <meta charset="utf-8">
27
+ <meta name="viewport" content="width=device-width, initial-scale=1">
28
+ {% if template_css %}
29
+ {{ require_css(get_asset_url(template_css)) }}
30
+ {% endif %}
31
+ {{ standard_header_includes }}
32
+ </head>
33
+ <body>
34
+ {% block body %}{% endblock body %}
35
+ {% if template_js %}
36
+ {{ require_js(get_asset_url(template_js)) }}
37
+ {% endif %}
38
+ {{ standard_footer_includes }}
39
+ </body>
40
+ </html>
41
+ `;mt(Ne(e,"templates","layouts"),{recursive:!0}),Zn(Ne(e,"templates","layouts","base.html"),o)}var Qn=L(()=>{"use strict";f()});var er={};ke(er,{fetchTheme:()=>dn});import{mkdirSync as Qi,writeFileSync as yd}from"fs";import{join as bd,dirname as Sd}from"path";async function mo(e,t){let n=await Yn(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let i of o){let a=typeof i=="string"?i:i.name;if(!a)continue;let r=`${t}/${a}`;if(typeof i=="string")s.push(...await mo(e,r));else{let l=i;l.folder?s.push(...await mo(e,l.path||r)):s.push(l.path||r)}}return s}async function xd(e,t,n){let s=0;async function o(){for(;s<e.length;){let a=s++;await n(e[a])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function dn(e,t,n,s={}){let o=s.concurrency??5,i=await mo(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);Qi(n,{recursive:!0}),await xd(i,o,async a=>{let r=a.startsWith(t+"/")?a.slice(t.length+1):a,l=bd(n,r);Qi(Sd(l),{recursive:!0});let c=await Vi(e,a);yd(l,c),s.onFile?.(r)})}var es=L(()=>{"use strict";f();bt()});function Ft(e){let t=tr.get(e);if(t!==void 0)return t;try{t=I(Fn(e))}catch{t=""}return tr.set(e,t),t}function ce(){return Ft("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function po(){return Ft("design-guide.md")}function go(){return Ft("content-guide.md")}function Me(){return Ft("hubspot-rules.md")}function fo(){return Ft("humanify-guide.md")}function ho(e){let t=Ft("page-types.md");if(!t)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[e];if(!s)return"";let o=t.indexOf(s);if(o<0)return"";let i=t.indexOf(`
42
+ ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function nr(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
3
43
 
4
44
  ## Rules
5
45
  Follow the conversion guide below EXACTLY. Key rules:
@@ -16,10 +56,10 @@ Follow the conversion guide below EXACTLY. Key rules:
16
56
  - Convert React hooks to vanilla JS (no React, no npm packages)
17
57
 
18
58
  ## HubSpot CMS Rules
19
- ${Ee()}
59
+ ${Me()}
20
60
 
21
61
  ## Conversion Guide
22
- ${e}`}function yi(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
62
+ ${e}`}function sr(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
23
63
 
24
64
  Return a JSON object with these keys:
25
65
  - fieldsJson: complete fields.json content (as JSON string)
@@ -34,7 +74,7 @@ ${n}
34
74
  React component source:
35
75
  ${e}
36
76
 
37
- Return ONLY valid JSON, no markdown fences.`}function bi(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
77
+ Return ONLY valid JSON, no markdown fences.`}function or(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
38
78
 
39
79
  Extract the design system from the source CSS and Tailwind config below.
40
80
  Use the class prefix ".${n}-" for all custom classes.
@@ -58,7 +98,7 @@ ${e}
58
98
  Tailwind config:
59
99
  ${t}
60
100
 
61
- Return ONLY the CSS content, no markdown fences.`}function Si(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
101
+ Return ONLY the CSS content, no markdown fences.`}function ir(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
62
102
 
63
103
  Convert the React hooks and interactive components below to plain JavaScript.
64
104
  Use the class prefix "${n}-" to match the CSS.
@@ -76,7 +116,7 @@ ${e}
76
116
  Interactive component sources:
77
117
  ${t}
78
118
 
79
- Return ONLY the JavaScript content, no markdown fences.`}function vi(e,t,n){return`Create a HubSpot page template that assembles these modules:
119
+ Return ONLY the JavaScript content, no markdown fences.`}function rr(e,t,n){return`Create a HubSpot page template that assembles these modules:
80
120
 
81
121
  ${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
82
122
  `)}
@@ -91,21 +131,21 @@ Template requirements:
91
131
  - Each module in its own dnd_section with padding zeroed and full_width=true
92
132
  - dnd_area label: "${t} Landing Page"
93
133
 
94
- Return ONLY the template HTML content, no markdown fences.`}var gi,qe=D(()=>{"use strict";g();Q();gi=new Map});var Bi=D(()=>{"use strict";g()});import{existsSync as Qe,writeFileSync as Dc,mkdirSync as Hc}from"fs";import{join as He}from"path";function Vi(e){return/^[0-9a-f]{4,40}$/i.test(e)}function _e(){return Xn!==null||(Xn=E("git --version").success),Xn}function Qn(e){if(!_e())return!1;if(Qe(He(e,".git")))return Wi(e),!0;let t=E("git init",{cwd:e});return t.success?(Lc(e),Wi(e),E("git add -A",{cwd:e}),E('git commit -m "Initial theme"',{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Wi(e){let t=He(e,".vibespot");Qe(t)||Hc(t,{recursive:!0})}function Lc(e){let t=He(e,".gitignore");Dc(t,[".vibespot/","node_modules/",""].join(`
95
- `),"utf-8")}function Ks(e,t){if(!_e()||!Qe(He(e,".git"))||(E("git add -A",{cwd:e}),E("git diff --cached --quiet",{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=E(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=E("git rev-parse --short HEAD",{cwd:e});return i.success?i.stdout:null}function Ki(e,t,n,s){if(!_e()||!Qe(He(e,".git")))return null;for(let u of s){let m=He(e,u);Qe(m)&&E(`git add "${u}"`,{cwd:e})}if(E("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=E(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=E("git rev-parse --short HEAD",{cwd:e});return d.success?d.stdout:null}function Yi(e,t=50){if(!_e())return[];if(!Qe(He(e,".git")))return[];let n=E(`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 zi(e,t,n=50){if(!_e())return[];if(!Qe(He(e,".git")))return[];let s=t.replace(/[[\]\\]/g,"\\$&"),o=E(`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 qi(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(!Vi(t))return{success:!1,error:"Invalid commit hash"};let n=E(`git cat-file -t ${t}`,{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=E(`git log --format="%s" -1 ${t}`,{cwd:e}),o=s.success?s.stdout:t,i=E(`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 E(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}function Xi(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(!Vi(n))return{success:!1,error:"Invalid commit hash"};let o=E(`git cat-file -t ${n}`,{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=E(`git log --format="%s" -1 ${n}`,{cwd:e}),a=i.success?i.stdout:n,r=0;for(let d of s)E(`git checkout ${n} -- "${d}"`,{cwd:e}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};E("git add -A",{cwd:e});let c=`${`[${t}] `}Rollback to: ${a}`.slice(0,72);return E(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}var Xn,Zt=D(()=>{"use strict";g();ut();Xn=null});import{readFileSync as Uc,existsSync as Qi,writeFileSync as Gc,mkdirSync as Bc,rmSync as Wc}from"fs";import{join as Zn}from"path";function ft(e){let t=v();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages)}function it(){let e=v();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 rt(e,t,n){let s=v();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),it(),Vc()}function Zi(e){let t=v();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),L())}function Le(e){let t=v();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);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(),it()}}function Et(e){let t=v();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),it())}function er(e){let t=v();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=Zn(t.themePath,"modules",`${e}.module`);Qi(n)&&Wc(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),it()}}function tr(e){let t=v();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),it())}function nr(e,t,n){let s=v();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);or(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),it()}catch{}}function me(){let e=v();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Vc(){let e=v();if(e)try{let t=Zn(e.themePath,".vibespot");Bc(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};Gc(Zn(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function sr(e){let t=Zn(e,".vibespot","chat.json");if(!Qi(t))return[];try{let n=JSON.parse(Uc(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function or(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&&or(i.children,s.slice(1).join("."),n))}var es=D(()=>{"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=v();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function qs(e){let t=v();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 ir(e,t){let n=v();if(!n)throw new Error("No active session");let s=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${s}`,a={id:i,label:t,pageType:e,templateFile:e==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(a),n.activeTemplateId=i,ft(a),n.updatedAt=Date.now(),a}function rr(e,t){let n=v();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),r=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:r,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${r}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[]};return n.templates.push(l),n.activeTemplateId=r,ft(l),n.updatedAt=Date.now(),l}function ar(e,t){let n=v();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function lr(e,t=!1){let n=v();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=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 at(){let e=v();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}return Array.from(t.values())}var en=D(()=>{"use strict";g();tn();es()});import{readFileSync as Ze,readdirSync as to,existsSync as ye,writeFileSync as ns,mkdirSync as cr,rmSync as Xs,renameSync as Qs}from"fs";import{join as re,dirname as Kc}from"path";import{homedir as Yc}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{cr(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 zc(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 qc(e){let t=ss().filter(n=>n.id!==e);os(t)}function Xc(e){let t=ss().filter(n=>n.themeName!==e);os(t)}function v(){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 L(){if(!be)return;cr(ne,{recursive:!0});let e=re(ne,`${be.id}.json`);ns(e,JSON.stringify(be,null,2),"utf-8"),zc(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 dr(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{}Xc(s)}else qc(e);be?.id===e&&(be=null)}function ur(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(Kc(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=D(()=>{"use strict";g();Zt();en();ne=re(Yc(),".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 mr}from"fs";import{join as M}from"path";function ae(e){try{return no(e,"utf-8")}catch{return""}}function Zc(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 ed(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 td(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=ed(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=v();if(!t)return;let n=sr(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 w=M(s,y.name),x=y.name.replace(/\.module$/,""),S={moduleName:x,fieldsJson:ae(M(w,"fields.json")),metaJson:ae(M(w,"meta.json")),moduleHtml:ae(M(w,"module.html")),moduleCss:ae(M(w,"module.css")),moduleJs:ae(M(w,"module.js"))||void 0};S.fieldsJson&&S.moduleHtml&&(t.modules.push(S),t.moduleOrder.push(x))}let i=M(e,"css"),a=M(e,"js"),r="",l="";if(pe(i)){let y=rn(i).filter(w=>w.endsWith("-theme.css"));y.length>0&&(r=ae(M(i,y[0])),t.sharedCss=r)}if(pe(a)){let y=rn(a).filter(w=>w.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=td(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 w=new Set(t.moduleOrder),x=y.filter(S=>w.has(S));for(let S of t.moduleOrder)x.includes(S)||x.push(S);t.moduleOrder=x}ft(h[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),ts(t)}function lt(){let e=v();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=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)&&mr(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||od(l),d=pr(c,l.label,l.pageType),u=`${l.id}.html`;Ie(M(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&(id(o,l),r.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||rd(),c=pr(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)&&mr(M(o,l),{force:!0})}catch{}nd(),sd()}function fr(){let e=v();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",an(e.themePath),e.updatedAt=Date.now(),it())}function gr(){let e=v();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 nd(){let e=v();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+`
134
+ Return ONLY the template HTML content, no markdown fences.`}var tr,ot=L(()=>{"use strict";f();te();tr=new Map});var _r=L(()=>{"use strict";f()});import{existsSync as rt,writeFileSync as zd,mkdirSync as Yd}from"fs";import{join as Ve}from"path";function Nr(e){return/^[0-9a-f]{4,40}$/i.test(e)}function Oe(){return ps!==null||(ps=F("git --version").success),ps}function gs(e){if(!Oe())return!1;if(rt(Ve(e,".git")))return Pr(e),!0;let t=F("git init",{cwd:e});return t.success?(qd(e),Pr(e),F("git add -A",{cwd:e}),F('git commit -m "Initial theme"',{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Pr(e){let t=Ve(e,".vibespot");rt(t)||Yd(t,{recursive:!0})}function qd(e){let t=Ve(e,".gitignore");zd(t,[".vibespot/","node_modules/",""].join(`
135
+ `),"utf-8")}function St(e,t){if(!Oe()||!rt(Ve(e,".git"))||(F("git add -A",{cwd:e}),F("git diff --cached --quiet",{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=F(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=F("git rev-parse --short HEAD",{cwd:e});return i.success?i.stdout:null}function bo(e,t,n,s){if(!Oe()||!rt(Ve(e,".git")))return null;for(let u of s){let m=Ve(e,u);rt(m)&&F(`git add "${u}"`,{cwd:e})}if(F("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=F(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=F("git rev-parse --short HEAD",{cwd:e});return d.success?d.stdout:null}function Mr(e,t=50){if(!Oe())return[];if(!rt(Ve(e,".git")))return[];let n=F(`git log --pretty=format:"%h|%H|%s|%at" -n ${t}`,{cwd:e});if(!n.success||!n.stdout.trim())return[];let s=[];for(let o of n.stdout.split(`
136
+ `)){let i=o.split("|");if(i.length<4)continue;let a=parseInt(i[3],10)*1e3;s.push({hash:i[0],fullHash:i[1],message:i[2],timestamp:a,date:new Date(a).toISOString()})}return s}function Or(e,t,n=50){if(!Oe())return[];if(!rt(Ve(e,".git")))return[];let s=t.replace(/[[\]\\]/g,"\\$&"),o=F(`git log --grep="\\[${s}\\]" --pretty=format:"%h|%H|%s|%at" -n ${n}`,{cwd:e});if(!o.success||!o.stdout.trim())return[];let i=[];for(let a of o.stdout.split(`
137
+ `)){let r=a.split("|");if(r.length<4)continue;let l=parseInt(r[3],10)*1e3;i.push({hash:r[0],fullHash:r[1],message:r[2],timestamp:l,date:new Date(l).toISOString()})}return i}function Rr(e,t){if(!Oe())return{success:!1,error:"Git not available"};if(!rt(Ve(e,".git")))return{success:!1,error:"Not a git repo"};if(!Nr(t))return{success:!1,error:"Invalid commit hash"};let n=F(`git cat-file -t ${t}`,{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=F(`git log --format="%s" -1 ${t}`,{cwd:e}),o=s.success?s.stdout:t,i=F(`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 F(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}function Fr(e,t,n,s){if(!Oe())return{success:!1,error:"Git not available"};if(!rt(Ve(e,".git")))return{success:!1,error:"Not a git repo"};if(!Nr(n))return{success:!1,error:"Invalid commit hash"};let o=F(`git cat-file -t ${n}`,{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=F(`git log --format="%s" -1 ${n}`,{cwd:e}),a=i.success?i.stdout:n,r=0;for(let d of s)F(`git checkout ${n} -- "${d}"`,{cwd:e}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};F("git add -A",{cwd:e});let c=`${`[${t}] `}Rollback to: ${a}`.slice(0,72);return F(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}var ps,jt=L(()=>{"use strict";f();ht();ps=null});import{readFileSync as Xd,existsSync as Jr,writeFileSync as Zd,mkdirSync as Qd,rmSync as eu}from"fs";import{join as fs}from"path";function xt(e){let t=v();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages)}function pt(){let e=v();if(!e)return;let t=xe();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages)}function Re(e,t,n){let s=v();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),pt(),tu()}function jr(e){let t=v();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),j())}function oe(e){let t=v();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);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(),pt()}}function Ke(e){let t=v();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),pt())}function Dr(e){let t=v();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=fs(t.themePath,"modules",`${e}.module`);Jr(n)&&eu(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),pt()}}function Hr(e){let t=v();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),pt())}function Lr(e,t,n){let s=v();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);Ur(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),pt()}catch{}}function X(){let e=v();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function tu(){let e=v();if(e)try{let t=fs(e.themePath,".vibespot");Qd(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};Zd(fs(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Br(e){let t=fs(e,".vibespot","chat.json");if(!Jr(t))return[];try{let n=JSON.parse(Xd(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Ur(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&&Ur(i.children,s.slice(1).join("."),n))}var pn=L(()=>{"use strict";f();gn();Dt()});import{existsSync as So,rmSync as xo}from"fs";import{join as fn}from"path";function hs(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function xe(){let e=v();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function vo(e){let t=v();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,xt(n),t.updatedAt=Date.now(),!0):!1}function ys(e,t){let n=v();if(!n)throw new Error("No active session");let s=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${s}`,a={id:i,label:t,pageType:e,templateFile:e==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(a),n.activeTemplateId=i,xt(a),n.updatedAt=Date.now(),a}function Gr(e,t){let n=v();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),r=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:r,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${r}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[]};return n.templates.push(l),n.activeTemplateId=r,xt(l),n.updatedAt=Date.now(),l}function Wr(e,t){let n=v();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function Vr(e,t=!1){let n=v();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=fn(n.themePath,"templates"),a=`${o.id}.html`,r=fn(i,a);if(So(r)&&xo(r,{force:!0}),o.pageType==="blog_post"){let l=fn(i,`${o.id}-listing.html`);So(l)&&xo(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let r of n.templates)for(let l of r.modules)i.add(l.moduleName);for(let r of n.modules)i.add(r.moduleName);let a=o.modules.map(r=>r.moduleName).filter(r=>!i.has(r));if(n.themePath&&a.length>0){let r=fn(n.themePath,"modules");for(let l of a){let c=fn(r,`${l}.module`);So(c)&&xo(c,{recursive:!0,force:!0})}}}return n.activeTemplateId===e&&(n.templates.length>0?vo(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[])),n.updatedAt=Date.now(),!0}function at(){let e=v();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}return Array.from(t.values())}var Dt=L(()=>{"use strict";f();gn();pn()});import{readFileSync as lt,readdirSync as $o,existsSync as ve,writeFileSync as bs,mkdirSync as Kr,rmSync as wo,renameSync as Co}from"fs";import{join as ue,dirname as nu}from"path";import{homedir as su}from"os";function Ss(){if(Ht)return Ht;try{return ve(ko)?(Ht=JSON.parse(lt(ko,"utf-8")),Ht):Ao()}catch{return Ao()}}function xs(e){Ht=e;try{Kr(ie,{recursive:!0}),bs(ko,JSON.stringify(e),"utf-8")}catch{}}function Ao(){if(!ve(ie))return[];let e=[];for(let t of $o(ie).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(lt(ue(ie,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length})}catch{}return Ht=e,xs(e),e}function ou(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),xs(t)}function iu(e){let t=Ss().filter(n=>n.id!==e);xs(t)}function ru(e){let t=Ss().filter(n=>n.themeName!==e);xs(t)}function v(){return we}function au(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function vt(e,t){let n={id:au(),themePath:e,themeName:t,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return we=n,gs(e),n}function j(){if(!we)return;Kr(ie,{recursive:!0});let e=ue(ie,`${we.id}.json`);bs(e,JSON.stringify(we,null,2),"utf-8"),ou(we)}function vs(e){let t=ue(ie,e+".json");if(!ve(t))return null;try{let n=JSON.parse(lt(t,"utf-8"));return n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),hs(n),we=n,n}catch{return null}}function Lt(){return ve(ie)?Ss():[]}function zr(e,t=!1){let n=ue(ie,e+".json"),s="";if(t)try{let o=JSON.parse(lt(n,"utf-8"));s=o.themeName||"",o.themePath&&ve(o.themePath)&&wo(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(lt(n,"utf-8")).themeName||""}catch{}try{ve(n)&&wo(n)}catch{}if(s&&ve(ie)){for(let o of $o(ie).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(lt(ue(ie,o),"utf-8")).themeName===s&&wo(ue(ie,o))}catch{}ru(s)}else iu(e);we?.id===e&&(we=null)}function Yr(e,t){let n=ue(ie,e+".json");if(!ve(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(lt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,a=ue(nu(i),t);if(ve(i)){if(ve(a))return{ok:!1,error:"A project with that name already exists"};try{Co(i,a)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let r=ue(a,"css",`${o}-theme.css`),l=ue(a,"css",`${t}-theme.css`);if(ve(r))try{Co(r,l)}catch{}let c=ue(a,"js",`${o}-animations.js`),d=ue(a,"js",`${t}-animations.js`);if(ve(c))try{Co(c,d)}catch{}let u=ue(a,"theme.json");if(ve(u))try{let m=JSON.parse(lt(u,"utf-8"));m.label=t,m.name=t,bs(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(ve(ie))for(let r of $o(ie).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(lt(ue(ie,r),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=a,l.updatedAt=Date.now(),bs(ue(ie,r),JSON.stringify(l,null,2),"utf-8"))}catch{}return we&&we.themeName===o&&(we.themeName=t,we.themePath=a,we.updatedAt=Date.now()),Ao(),{ok:!0}}var ie,ko,Ht,we,gn=L(()=>{"use strict";f();jt();Dt();ie=ue(su(),".vibespot","sessions"),ko=ue(ie,"_index.json"),Ht=null;we=null});import{readFileSync as To,readdirSync as yn,existsSync as me,writeFileSync as Ee,mkdirSync as hn,rmSync as qr}from"fs";import{join as D}from"path";function re(e){try{return To(e,"utf-8")}catch{return""}}function lu(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 cu(e,t){let n=re(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 du(e,t,n,s,o){if(!me(e))return[];let i=[],a=yn(e).filter(r=>r.endsWith(".html")&&r!=="home.html");for(let r of a){let l=D(e,r),c=cu(l,r);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let g=t.get(m);g&&(d.push(g),u.push(m))}i.push({id:c.id,label:c.label,pageType:c.pageType,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:n,sharedJs:s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function bn(e){let t=v();if(!t)return;let n=Br(e);n.length>0&&t.messages.length===0&&(t.messages=n),gs(e);let s=D(e,"modules");if(!me(s))return;let o=yn(s,{withFileTypes:!0});for(let b of o){if(!b.isDirectory()||!b.name.endsWith(".module"))continue;let x=D(s,b.name),w=b.name.replace(/\.module$/,""),S={moduleName:w,fieldsJson:re(D(x,"fields.json")),metaJson:re(D(x,"meta.json")),moduleHtml:re(D(x,"module.html")),moduleCss:re(D(x,"module.css")),moduleJs:re(D(x,"module.js"))||void 0};S.fieldsJson&&S.moduleHtml&&(t.modules.push(S),t.moduleOrder.push(w))}let i=D(e,"css"),a=D(e,"js"),r="",l="";if(me(i)){let b=yn(i).filter(x=>x.endsWith("-theme.css"));b.length>0&&(r=re(D(i,b[0])),t.sharedCss=r)}if(me(a)){let b=yn(a).filter(x=>x.endsWith("-animations.js"));b.length>0&&(l=re(D(a,b[0])),t.sharedJs=l)}let c=D(e,".vibespot","styleguide.md"),d=D(e,".vibespot","brandvoice.md"),u=D(e,".vibespot","theme-context.md"),m=D(e,".vibespot","plan.md");(me(c)||me(d)||me(u)||me(m))&&(t.brandAssets||(t.brandAssets={}),me(c)&&(t.brandAssets.styleguide=re(c)),me(d)&&(t.brandAssets.brandvoice=re(d)),me(u)&&(t.brandAssets.themeContext=re(u)),me(m)&&(t.brandAssets.plan=re(m)));let g=D(e,"templates"),y=new Map(t.modules.map(b=>[b.moduleName,b])),h=du(g,y,r,l,t.messages);if(h.length>0){t.templates=h,t.activeTemplateId=h[0].id;let b=h[0].moduleOrder;if(b.length>0){let x=new Set(t.moduleOrder),w=b.filter(S=>x.has(S));for(let S of t.moduleOrder)w.includes(S)||w.push(S);t.moduleOrder=w}xt(h[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),hs(t)}function _e(){let e=v();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=D(t,"modules");hn(s,{recursive:!0});for(let l of n.values())hn(D(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=D(s,`${l.moduleName}.module`);Ee(D(c,"fields.json"),l.fieldsJson,"utf-8"),Ee(D(c,"meta.json"),l.metaJson,"utf-8"),Ee(D(c,"module.html"),l.moduleHtml,"utf-8"),Ee(D(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ee(D(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=D(t,"css");hn(l,{recursive:!0}),Ee(D(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=D(t,"js");hn(l,{recursive:!0}),Ee(D(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=D(t,"templates");hn(o,{recursive:!0});let i=D(o,"home.html");(e.templates.length>0||e.modules.length>0)&&me(i)&&qr(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||pu(l),d=Xr(c,l.label,l.pageType),u=`${l.id}.html`;Ee(D(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&(gu(o,l),r.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||fu(),c=Xr(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ee(D(o,d),c,"utf-8"),r.add(d)}try{for(let l of yn(o))l.startsWith("lp-")&&l.endsWith(".html")&&!r.has(l)&&qr(D(o,l),{force:!0})}catch{}uu(),mu()}function Zr(){let e=v();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",bn(e.themePath),e.updatedAt=Date.now(),pt())}function Qr(){let e=v();if(!e)return;let t=xe();if(!t)return;let n=e.themePath,s=D(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=D(s,`${o}.module`);if(!me(i))continue;let a={moduleName:o,fieldsJson:re(D(i,"fields.json")),metaJson:re(D(i,"meta.json")),moduleHtml:re(D(i,"module.html")),moduleCss:re(D(i,"module.css")),moduleJs:re(D(i,"module.js"))||void 0};a.fieldsJson&&a.moduleHtml&&t.modules.push(a)}if(t.templateFile){let o=D(n,t.templateFile);me(o)&&(t.template=re(o))}xt(t),e.updatedAt=Date.now()}function uu(){let e=v();if(!e)return;let t=D(e.themePath,"templates","layouts","base.html");if(me(t))try{let n=To(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
138
  {% if template_js %}
99
139
  {{ require_js(get_asset_url(template_js)) }}
100
140
  {% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
101
141
  {{ require_js(get_asset_url(template_js)) }}
102
142
  {% endif %}
103
- {{ standard_footer_includes }}`),Ie(t,n,"utf-8")}catch{}}function sd(){let e=v();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 pr(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
143
+ {{ standard_footer_includes }}`),Ee(t,n,"utf-8")}catch{}}function mu(){let e=v();if(!e)return;let t=D(e.themePath,"theme.json");if(me(t))try{let n=JSON.parse(To(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ee(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Xr(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
104
144
  templateType: ${n==="blog_post"?"blog_post":"page"}
105
145
  isAvailableForNewContent: true
106
146
  label: "${t}"
107
147
  -->
108
- `+e}function od(e){if(e.modules.length===0)return"";let n=v().themeName,o=Zc(e).map(a=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
148
+ `+e}function pu(e){if(e.modules.length===0)return"";let n=v().themeName,o=lu(e).map(a=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
109
149
  {% dnd_module path="../modules/${a.moduleName}.module" %}
110
150
  {% end_dnd_module %}
111
151
  {% end_dnd_section %}`).join(`
@@ -136,7 +176,7 @@ ${o}
136
176
 
137
177
  {% block footer %}
138
178
  {% endblock footer %}
139
- `}function id(e,t){let n=`<!--
179
+ `}function gu(e,t){let n=`<!--
140
180
  templateType: blog_listing
141
181
  isAvailableForNewContent: true
142
182
  label: "${t.label} - Listing"
@@ -161,7 +201,7 @@ ${o}
161
201
  {% endif %}
162
202
  </div>
163
203
  {% endblock body %}
164
- `;Ie(M(e,`${t.id}-listing.html`),n,"utf-8")}function rd(){let e=v();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 %}
204
+ `;Ee(D(e,`${t.id}-listing.html`),n,"utf-8")}function fu(){let e=v();if(!e||e.modules.length===0)return"";let t=e.themeName,s=X().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
165
205
  {% dnd_module path="../modules/${o.moduleName}.module" %}
166
206
  {% end_dnd_module %}
167
207
  {% end_dnd_section %}`).join(`
@@ -192,7 +232,7 @@ ${s}
192
232
 
193
233
  {% block footer %}
194
234
  {% endblock footer %}
195
- `}var hr=D(()=>{"use strict";g();tn();es();en();Zt()});var yr=D(()=>{"use strict";g();Bi();tn();es();hr();en()});var Se=D(()=>{"use strict";g();yr()});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=gd(n),n=xr(n,t),n=wr(n,t),n=Cr(n,t),n=yd(n),n}function io(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
235
+ `}var Io=L(()=>{"use strict";f();gn();pn();Dt();jt()});var ea=L(()=>{"use strict";f();_r();gn();pn();Io();Dt()});var pe=L(()=>{"use strict";f();ea()});function ws(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]=ws(n.children):t[n.name]=n.default??"";return t}function _o(e,t){let n=e;return n=ku(n),n=oa(n,t),n=ia(n,t),n=ra(n,t),n=$u(n),n}function Po(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
196
236
  `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
197
237
  `),s=e.renderedModules.join(`
198
238
  `);return`<!DOCTYPE html>
@@ -239,11 +279,11 @@ document.querySelectorAll('img').forEach(function(img){
239
279
  });
240
280
  </script>
241
281
  </body>
242
- </html>`}function gd(e){return e=e.replace(ad,""),e=e.replace(ld,""),e=e.replace(cd,""),br.lastIndex=0,e=e.replace(br,(t,n)=>`/theme-assets/${n}`),Sr.lastIndex=0,e=e.replace(Sr,""),e=e.replace(dd,""),e=e.replace(ud,""),e=e.replace(md,""),e=e.replace(pd,""),e=e.replace(fd,""),e}function xr(e,t){let n=e,s=0;for(;s<30;){s++;let o=hd(n);if(!o)break;let{varName:i,iterExpr:a,body:r,start:l,end:c}=o,d=bd(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=xr(r,h);return y=wr(y,h),y=Cr(y,h),y}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function hd(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 wr(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 Cr(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=kr(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 yd(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function bd(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=vr(n[1],t),i=vr(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 vr(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=kr(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 Ar(o)}function Ar(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function kr(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 Ar(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 ad,ld,cd,br,Sr,dd,ud,md,pd,fd,so,Ir=D(()=>{"use strict";g();ad=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,ld=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,cd=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,br=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Sr=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,dd=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,ud=/\{%[-\s]*module\b.*?%\}/gs,md=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,pd=/\{#.*?#\}/gs,fd=/\{\{[-\s]*content\.\w+.*?\}\}/gs,so=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var lo={};nt(lo,{buildModulePreviewHtml:()=>ao,buildPreviewHtml:()=>ro});function Sd(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=v();if(!e)return Tr();let t=me(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return Tr();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=Sd(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}">
282
+ </html>`}function ku(e){return e=e.replace(hu,""),e=e.replace(yu,""),e=e.replace(bu,""),ta.lastIndex=0,e=e.replace(ta,(t,n)=>`/theme-assets/${n}`),na.lastIndex=0,e=e.replace(na,""),e=e.replace(Su,""),e=e.replace(xu,""),e=e.replace(vu,""),e=e.replace(wu,""),e=e.replace(Cu,""),e}function oa(e,t){let n=e,s=0;for(;s<30;){s++;let o=Au(n);if(!o)break;let{varName:i,iterExpr:a,body:r,start:l,end:c}=o,d=Tu(a,t),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let y={...t,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},h=oa(r,y);return h=ia(h,y),h=ra(h,y),h}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Au(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 ia(e,t){let n=e,s=0;for(;Eo.test(n)&&s<50;)s++,n=n.replace(Eo,(o,i,a)=>{let r=a.split(/\{%[-\s]*else\s*-?%\}/),l=r[0],c=r[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(Bt(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(Bt(m,t))return g}return c}return Bt(i,t)?l:c}),Eo.lastIndex=0;return n}function ra(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),a=i[0].trim(),r=wt(t,a);for(let c=1;c<i.length;c++)r=la(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 $u(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Tu(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=sa(n[1],t),i=sa(n[2],t),a=[];for(let r=o;r<i;r++)a.push(r);return a}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=wt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return wt(t,e)}function sa(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=wt(t,o);for(let a=1;a<s.length;a++)i=la(i,s[a].trim());return Number(i)||0}function wt(e,t){let n=t.split("."),s=e;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function Bt(e,t){let n=e.trim();if(n.startsWith("not "))return!Bt(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Bt(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Bt(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=wt(t,s[1].trim()),a=s[2],r=s[3].trim();switch(typeof r=="string"&&r.startsWith('"')&&r.endsWith('"')||typeof r=="string"&&r.startsWith("'")&&r.endsWith("'")?r=r.slice(1,-1):isNaN(Number(r))?r=wt(t,r):r=Number(r),a){case"==":return i==r;case"!=":return i!=r;case">":return Number(i)>Number(r);case"<":return Number(i)<Number(r);case">=":return Number(i)>=Number(r);case"<=":return Number(i)<=Number(r)}}let o=wt(t,n);return aa(o)}function aa(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function la(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 aa(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 hu,yu,bu,ta,na,Su,xu,vu,wu,Cu,Eo,ca=L(()=>{"use strict";f();hu=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,yu=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,bu=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,ta=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,na=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Su=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,xu=/\{%[-\s]*module\b.*?%\}/gs,vu=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,wu=/\{#.*?#\}/gs,Cu=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Eo=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Oo={};ke(Oo,{buildModulePreviewHtml:()=>Mo,buildPreviewHtml:()=>No});function Iu(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 No(){let e=v();if(!e)return da();let t=X(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return da();let s=[],o=[],i=[],a=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d;try{let g=JSON.parse(c.fieldsJson);d={module:ws(g)}}catch{d={module:{}}}let u=_o(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=Iu(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
283
  <div class="vibespot-placeholder">
244
284
  <div class="vibespot-placeholder__name">${c}</div>
245
285
  </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 io({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function Tr(){return`<!DOCTYPE html>
286
+ </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 Po({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function da(){return`<!DOCTYPE html>
247
287
  <html lang="en">
248
288
  <head>
249
289
  <meta charset="utf-8">
@@ -294,9 +334,9 @@ document.querySelectorAll('img').forEach(function(img){
294
334
  <div class="welcome__sub">Build Something Great</div>
295
335
  </div>
296
336
  </body>
297
- </html>`}function ao(e){let t=v();if(!t)return"";let n;for(let i of t.templates)if(n=i.modules.find(a=>a.moduleName===e),n)break;if(n||(n=t.modules.find(i=>i.moduleName===e)),!n)return"";let s;try{let i=JSON.parse(n.fieldsJson);s={module: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=D(()=>{"use strict";g();Ir();Se()});import{appendFileSync as vd,mkdirSync as xd,readdirSync as wd,unlinkSync as Cd}from"fs";import{join as po}from"path";import{homedir as Ad}from"os";function Id(){if(!uo)try{xd(ls,{recursive:!0}),uo=!0}catch{}}function Td(){if(!mo){mo=!0;try{let e=Date.now()-kd*864e5;for(let t of wd(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{Cd(po(ls,t))}catch{}}}catch{}}}function $d(){let t=new Date().toISOString().slice(0,10);return po(ls,`vibespot-${t}.log`)}function Ed(){return new Date().toISOString().slice(11,23)}function co(e,t){if(Id(),!!uo){mo||Td();try{vd($d(),`${Ed()} ${e} ${t}
298
- `)}catch{}}}var ls,kd,uo,mo,$,ve=D(()=>{"use strict";g();ls=po(Ad(),".vibespot","logs"),kd=7,uo=!1,mo=!1;$={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 Ue(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 Ue(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 $r(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{$.info("parse","Found vibespot-modules block",{length:s[1].length});let i=Ue(s[1]);if(!i||typeof i!="object")throw $.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){$.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=Ue(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){$.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"')){$.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&&($.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){$.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.";$.warn("parse",r),t&&t(r)}}}var cs=D(()=>{"use strict";g();Se();ve()});function Ot(){let e=v();return e?{pageType:Ce()?.pageType,brandAssets:e.brandAssets}:{}}function Er(e,t,n=!1,s,o){let a=[{type:"text",text:Pd(t,n)}];if(n){let l=`## HubSpot CMS Rules
299
- ${Ee()}
337
+ </html>`}function Mo(e){let t=v();if(!t)return"";let n;for(let i of t.templates)if(n=i.modules.find(a=>a.moduleName===e),n)break;if(n||(n=t.modules.find(i=>i.moduleName===e)),!n)return"";let s;try{let i=JSON.parse(n.fieldsJson);s={module:ws(i)}}catch{s={module:{}}}let o=_o(n.moduleHtml,s);return Po({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 Cs=L(()=>{"use strict";f();ca();pe()});import{appendFileSync as Eu,mkdirSync as _u,readdirSync as Pu,unlinkSync as Nu}from"fs";import{join as jo}from"path";import{homedir as Mu}from"os";function Ru(){if(!Fo)try{_u(ks,{recursive:!0}),Fo=!0}catch{}}function Fu(){if(!Jo){Jo=!0;try{let e=Date.now()-Ou*864e5;for(let t of Pu(ks)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{Nu(jo(ks,t))}catch{}}}catch{}}}function Ju(){let t=new Date().toISOString().slice(0,10);return jo(ks,`vibespot-${t}.log`)}function ju(){return new Date().toISOString().slice(11,23)}function Ro(e,t){if(Ru(),!!Fo){Jo||Fu();try{Eu(Ju(),`${ju()} ${e} ${t}
338
+ `)}catch{}}}var ks,Ou,Fo,Jo,T,ae=L(()=>{"use strict";f();ks=jo(Mu(),".vibespot","logs"),Ou=7,Fo=!1,Jo=!1;T={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),Ro("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),Ro("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),Ro("ERROR",o)}}});function ze(e){try{return JSON.parse(e)}catch{}let t=e,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(t)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let a=parseInt(i[1],10);if(a<=n)return null;n=a;let r=Math.max(0,a-5),c=t.slice(r,a+1).lastIndexOf('"');if(c===-1)return null;let d=r+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function Sn(e){let t=e.indexOf('"modules"');if(t===-1)return null;let n=e.indexOf("[",t);if(n===-1)return null;let s=-1,o=0,i=!1,a=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(a){a=!1;continue}if(u==="\\"){a=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=e.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ze(c)}function Do(e){return{moduleName:String(e.moduleName||""),fieldsJson:typeof e.fieldsJson=="string"?e.fieldsJson:JSON.stringify(e.fieldsJson,null,2),metaJson:typeof e.metaJson=="string"?e.metaJson:JSON.stringify(e.metaJson,null,2),moduleHtml:String(e.moduleHtml||""),moduleCss:String(e.moduleCss||""),moduleJs:e.moduleJs?String(e.moduleJs):void 0}}function ua(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=ze(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)&&(oe({modules:a.modules.map(r=>Do(r)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(i){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=ze(s[1]);if(!a||typeof a!="object")throw new Error("Invalid JSON after repair");let r=a;r.modules&&Array.isArray(r.modules)&&(oe({modules:r.modules.map(l=>Do(l)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(a){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=Sn(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}),oe({modules:c.modules.map(d=>Do(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){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 As=L(()=>{"use strict";f();pe();ae()});function Ut(){let e=v();return e?{pageType:xe()?.pageType,brandAssets:e.brandAssets}:{}}function ma(e,t,n=!1,s,o){let a=[{type:"text",text:Hu(t,n)}];if(n){let l=`## HubSpot CMS Rules
339
+ ${Me()}
300
340
 
301
341
  ## Conversion Guide Reference
302
342
  ${e}`;a.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
@@ -322,22 +362,22 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
322
362
  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
363
 
324
364
  ## Design Guide
325
- ${Us()}
365
+ ${po()}
326
366
 
327
367
  ## Content & Copywriting Guide
328
- ${Gs()}
368
+ ${go()}
329
369
 
330
370
  ## HubSpot CMS Rules
331
- ${Ee()}
371
+ ${Me()}
332
372
 
333
373
  ## 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
374
+ ${e}`;a.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let r=Du(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 Du(e,t){let n=[];if(e){let s=ho(e);s&&n.push(`## Page Type Context
335
375
  ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
336
376
  ${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)
377
+ ${t.brandvoice}`),t?.humanify!==!1){let s=fo();s&&n.push(`## Anti-AI Copy Rules (Humanify)
338
378
  ${s}`)}return n.join(`
339
379
 
340
- `)}function Pd(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
380
+ `)}function Hu(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
341
381
 
342
382
  ## Your Role
343
383
  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.
@@ -416,7 +456,7 @@ The current template's modules are listed in page order in the user message. Thi
416
456
  - **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
457
  - **Remove**: When the user asks to remove a section, omit it from the output.
418
458
  - **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.
459
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function xn(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
420
460
 
421
461
  ## Your Role
422
462
  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.
@@ -495,7 +535,7 @@ The current template's modules are listed in page order in the user message. Thi
495
535
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
496
536
  - **Remove**: When the user asks to remove a section, omit it from the output.
497
537
  - **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.
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?`
538
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,a=s?ho(s):"",r=a?`
499
539
 
500
540
  ## Page Type Context
501
541
  ${a}`:"",l="";if(o?.styleguide&&(l+=`
@@ -504,13 +544,13 @@ ${a}`:"",l="";if(o?.styleguide&&(l+=`
504
544
  ${o.styleguide}`),o?.brandvoice&&(l+=`
505
545
 
506
546
  ## Brand Voice
507
- ${o.brandvoice}`),o?.humanify!==!1){let d=Bs();d&&(l+=`
547
+ ${o.brandvoice}`),o?.humanify!==!1){let d=fo();d&&(l+=`
508
548
 
509
549
  ## Anti-AI Copy Rules (Humanify)
510
550
  ${d}`)}let c="\n\n## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory.";return n?i+r+l+`
511
551
 
512
552
  ## HubSpot CMS Rules
513
- ${Ee()}
553
+ ${Me()}
514
554
 
515
555
  ## Conversion Guide Reference
516
556
  ${e}`+c:i+r+l+`
@@ -538,16 +578,16 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
538
578
  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.
539
579
 
540
580
  ## Design Guide
541
- ${Us()}
581
+ ${po()}
542
582
 
543
583
  ## Content & Copywriting Guide
544
- ${Gs()}
584
+ ${go()}
545
585
 
546
586
  ## HubSpot CMS Rules
547
- ${Ee()}
587
+ ${Me()}
548
588
 
549
589
  ## Conversion Guide Reference
550
- ${e}`+c}function dn(){let e=v(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
590
+ ${e}`+c}function vn(){let e=v(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
551
591
 
552
592
  ## Page Narrative (module sequence)
553
593
  `),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
@@ -590,7 +630,7 @@ ${e.sharedJs}
590
630
  `);for(let r of a)t.push(`- ${r.module.moduleName} (used in: ${r.usedIn.join(", ")})
591
631
  `);t.push(`
592
632
  The user can ask to reuse any of these modules by name.
593
- `)}return t.join("")}function go(e,t){let n=v(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===e&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=dn(),a="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(a=`
633
+ `)}return t.join("")}function Ho(e,t){let n=v(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===e&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=vn(),a="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(a=`
594
634
 
595
635
  ## Available Theme Assets
596
636
  These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
@@ -604,44 +644,49 @@ ${i}`),a&&(r+=a),r+="\n\n---\nRemember: respond with a ```vibespot-modules JSON
604
644
  [Attached document: ${d.originalName}]
605
645
  ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(r+=`
606
646
 
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 _r=D(()=>{"use strict";g();qe();Se()});import{spawn as Md}from"child_process";async function Pr(){return ho||(ho=(await import("@anthropic-ai/sdk")).default),ho}function Mr(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
647
+ [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?t.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:r}),o.push({role:"user",content:d})}else o.push({role:"user",content:r});return o}var pa=L(()=>{"use strict";f();ot();pe()});import{spawn as ga}from"child_process";async function fa(){return Lo||(Lo=(await import("@anthropic-ai/sdk")).default),Lo}function ha(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
608
648
  [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
609
649
 
610
650
  ---
611
651
  [Attached document: ${n.originalName}]
612
- ${n.extractedText}`);return t.join("")}async function Or(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];$.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 Nr(e,t,n){let s=oe(),i=v().modules.length>0,a=go(e,n),r=Ot(),l=Er(s,t,i,r.pageType,r.brandAssets);return{messages:a,systemBlocks:l,conversionGuide:s,editMode:i}}async function Rr(e,t,n,s,o,i,a,r){let l=await Pr(),c=new l({apiKey:t}),{messages:d,systemBlocks:u}=Nr(e,n,r);$.info("anthropic","API call",{model:s,systemBlockCount:u.length,cachedBlocks:u.filter(m=>m.cache_control).length,messageCount:d.length}),await Or(c,u,d,s,o,i,a)}async function jr(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 Pr(),c=new l({authToken:r,defaultHeaders:Ht}),{messages:d,systemBlocks:u}=Nr(e,t,a),m=[{type:"text",text:At},...u];$.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(f=>f.cache_control).length,messageCount:d.length}),await Or(c,m,d,n,s,o,i)}async function Fr(e,t,n,s,o,i,a,r){let l=oe(),c=v().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(T=>T.type==="text"?{type:"text",text:T.text}:{type:"image_url",image_url:{url:`data:${T.source.media_type};base64,${T.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 w=setInterval(()=>{h++,y(fe[Math.min(h,fe.length-1)])},6e3),x="",S=f.body.getReader(),P=new TextDecoder,j="";try{for(;;){let{done:G,value:T}=await S.read();if(G)break;j+=P.decode(T,{stream:!0});let V=j.split(`
613
- `);j=V.pop()||"";for(let N of V){if(!N.startsWith("data: "))continue;let O=N.slice(6).trim();if(O==="[DONE]")break;try{let F=JSON.parse(O).choices?.[0]?.delta?.content;F&&(x+=F,o(F))}catch{}}}}finally{clearInterval(w)}a&&a(x)}async function Jr(e,t,n,s,o,i,a){let r=oe(),l=v(),c=l.modules.length>0,d=dn(),u=Ot(),m=[];for(let O of l.messages.slice(-20))m.push({role:O.role==="assistant"?"model":"user",parts:[{text:O.content}]});let f=d?`${e}
652
+ ${n.extractedText}`);return t.join("")}async function ya(e,t,n,s,o,i,a){for(let r=0;;r++)try{let l="",c=0,d=i||(()=>{});d(ye[0]);let u=setInterval(()=>{c++,d(ye[Math.min(c,ye.length-1)])},6e3);try{let m=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});for await(let g of m)if(g.type==="content_block_delta"&&g.delta.type==="text_delta"){let y=g.delta.text;l+=y,o(y)}}finally{clearInterval(u)}a&&a(l);return}catch(l){let c=l.status,d=l.error?.type;if(!(c===429||d==="rate_limit_error"||l instanceof Error&&l.message.includes("429"))||r>=Bo.length)throw l;let m=Bo[r];T.warn("ai-engine",`Rate limited (429), attempt ${r+1}/${Bo.length} \u2014 waiting ${m}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${m}s...`),await new Promise(g=>setTimeout(g,m*1e3)),i&&i("Retrying...")}}function ba(e,t,n){let s=ce(),i=v().modules.length>0,a=Ho(e,n),r=Ut(),l=ma(s,t,i,r.pageType,r.brandAssets);return{messages:a,systemBlocks:l,conversionGuide:s,editMode:i}}async function Sa(e,t,n,s,o,i,a,r){let l=await fa(),c=new l({apiKey:t}),{messages:d,systemBlocks:u}=ba(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 ya(c,u,d,s,o,i,a)}async function xa(e,t,n,s,o,i,a){let r=await no();if(!r)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await fa(),c=new l({authToken:r,defaultHeaders:Zt}),{messages:d,systemBlocks:u}=ba(e,t,a),m=[{type:"text",text:Mt},...u];T.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await ya(c,m,d,n,s,o,i)}async function va(e,t,n,s,o,i,a,r){let l=ce(),c=v().modules.length>0,d=Ho(e,r),u=Ut(),m=d.map(R=>typeof R.content=="string"?R:{role:R.role,content:R.content.map(O=>O.type==="text"?{type:"text",text:O.text}:{type:"image_url",image_url:{url:`data:${O.source.media_type};base64,${O.source.data}`}})}),g=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:xn(l,n,c,u.pageType,u.brandAssets)},...m]})});if(!g.ok){let R=await g.text();throw new Error(`OpenAI API error (${g.status}): ${R}`)}let y=0,h=i||(()=>{});h(ye[0]);let b=setInterval(()=>{y++,h(ye[Math.min(y,ye.length-1)])},6e3),x="",w=g.body.getReader(),S=new TextDecoder,M="";try{for(;;){let{done:R,value:O}=await w.read();if(R)break;M+=S.decode(O,{stream:!0});let H=M.split(`
653
+ `);M=H.pop()||"";for(let z of H){if(!z.startsWith("data: "))continue;let P=z.slice(6).trim();if(P==="[DONE]")break;try{let k=JSON.parse(P).choices?.[0]?.delta?.content;k&&(x+=k,o(k))}catch{}}}}finally{clearInterval(b)}a&&a(x)}async function wa(e,t,n,s,o,i,a){let r=ce(),l=v(),c=l.modules.length>0,d=vn(),u=Ut(),m=[];for(let P of l.messages.slice(-20))m.push({role:P.role==="assistant"?"model":"user",parts:[{text:P.content}]});let g=d?`${e}
614
654
 
615
655
  ---
616
- ${d}`:e;if(a?.length)for(let O of a)O.type==="document"&&O.extractedText&&(f+=`
656
+ ${d}`:e;if(a?.length)for(let P of a)P.type==="document"&&P.extractedText&&(g+=`
617
657
 
618
658
  ---
619
- [Attached document: ${O.originalName}]
620
- ${O.extractedText}`),O.type==="image"&&O.usage==="asset"&&O.assetPath&&(f+=`
621
-
622
- [Uploaded image: ${O.originalName} \u2192 available as get_asset_url("${O.assetPath}")]`);let h=[];if(a?.length)for(let O of a)O.type==="image"&&O.base64&&h.push({inlineData:{mimeType:O.mimeType,data:O.base64}});h.push({text:f}),m.push({role:"user",parts:h});let w=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${t}`,x=await fetch(w,{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(!x.ok){let O=await x.text();throw new Error(`Gemini API error (${x.status}): ${O}`)}let S=0,P=o||(()=>{});P(fe[0]);let j=setInterval(()=>{S++,P(fe[Math.min(S,fe.length-1)])},6e3),G="",T=x.body.getReader(),V=new TextDecoder,N="";try{for(;;){let{done:O,value:J}=await T.read();if(O)break;N+=V.decode(J,{stream:!0});let F=N.split(`
623
- `);N=F.pop()||"";for(let X of F){if(!X.startsWith("data: "))continue;let le=X.slice(6).trim();try{let Ft=JSON.parse(le).candidates?.[0]?.content?.parts?.[0]?.text;Ft&&(G+=Ft,s(Ft))}catch{}}}}finally{clearInterval(j)}i&&i(G)}function ds(e,t,n,s,o){return new Promise((i,a)=>{let r={...process.env};delete r.CLAUDECODE;let l=Md(e,t,{stdio:["pipe","pipe","pipe"],env:r}),c="",d="",u=!1,m=x=>{u||(u=!0,x())};l.stdout.on("data",x=>{let S=x.toString();c+=S,s&&s(S)}),l.stderr.on("data",x=>{d+=x.toString()}),l.on("error",x=>m(()=>a(new Error(`${e} failed to start: ${x.message}`)))),l.on("close",x=>{m(()=>{x!==0?a(new Error(`${e} exited with code ${x}.
659
+ [Attached document: ${P.originalName}]
660
+ ${P.extractedText}`),P.type==="image"&&P.usage==="asset"&&P.assetPath&&(g+=`
661
+
662
+ [Uploaded image: ${P.originalName} \u2192 available as get_asset_url("${P.assetPath}")]`);let y=[];if(a?.length)for(let P of a)P.type==="image"&&P.base64&&y.push({inlineData:{mimeType:P.mimeType,data:P.base64}});y.push({text:g}),m.push({role:"user",parts:y});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${t}`,x=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:xn(r,n,c,u.pageType,u.brandAssets)}]},contents:m,generationConfig:{maxOutputTokens:48e3}})});if(!x.ok){let P=await x.text();throw new Error(`Gemini API error (${x.status}): ${P}`)}let w=0,S=o||(()=>{});S(ye[0]);let M=setInterval(()=>{w++,S(ye[Math.min(w,ye.length-1)])},6e3),R="",O=x.body.getReader(),H=new TextDecoder,z="";try{for(;;){let{done:P,value:J}=await O.read();if(P)break;z+=H.decode(J,{stream:!0});let k=z.split(`
663
+ `);z=k.pop()||"";for(let E of k){if(!E.startsWith("data: "))continue;let Z=E.slice(6).trim();try{let ft=JSON.parse(Z).candidates?.[0]?.content?.parts?.[0]?.text;ft&&(R+=ft,s(ft))}catch{}}}}finally{clearInterval(M)}i&&i(R)}function Uo(e,t,n={},s){return new Promise((o,i)=>{let a={...process.env};delete a.CLAUDECODE;let r=ga("claude",e,{stdio:["pipe","pipe","pipe"],env:a}),l="",c="",d="",u=!1,m=null,g=S=>{u||(u=!0,S())},y=S=>{try{if(S.type==="assistant"&&S.message?.content){for(let M of S.message.content)if(M.type==="text"&&typeof M.text=="string"){let R=M.text;l+=R,n.onChunk&&n.onChunk(R)}else if(M.type==="tool_use"){let R=M;R.name&&n.onToolUse&&n.onToolUse(R.name,R.input)}}S.type==="result"&&(m=S,!l&&typeof S.result=="string"&&(l=S.result,n.onChunk&&n.onChunk(S.result))),n.onEvent&&n.onEvent(S)}catch{}};r.stdout.on("data",S=>{d+=S.toString();let M;for(;(M=d.indexOf(`
664
+ `))>=0;){let R=d.slice(0,M).trim();if(d=d.slice(M+1),!!R)try{y(JSON.parse(R))}catch{}}}),r.stderr.on("data",S=>{c+=S.toString()}),r.on("error",S=>g(()=>i(new Error(`claude failed to start: ${S.message}`)))),r.on("close",S=>{if(d.trim()){try{y(JSON.parse(d.trim()))}catch{}d=""}g(()=>{S!==0||m&&m.is_error?i(new Error(`claude exited with code ${S}.
665
+ `+(c?`Stderr: ${c.slice(0,500)}
666
+ `:"")+(l?`Output: ${l.slice(0,500)}`:"No output"))):o(l)})}),r.stdin.on("error",()=>{}),r.stdin.write(t)?r.stdin.end():r.stdin.once("drain",()=>r.stdin.end());let b=s||6e5,x=Math.round(b/6e4),w=setTimeout(()=>{r.kill(),g(()=>i(new Error(`claude (stream-json) timed out after ${x} minutes.
667
+ `+(c?`Stderr: ${c.slice(0,500)}
668
+ `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);r.on("close",()=>clearTimeout(w))})}function Go(e,t,n,s,o){return new Promise((i,a)=>{let r={...process.env};delete r.CLAUDECODE;let l=ga(e,t,{stdio:["pipe","pipe","pipe"],env:r}),c="",d="",u=!1,m=x=>{u||(u=!0,x())};l.stdout.on("data",x=>{let w=x.toString();c+=w,s&&s(w)}),l.stderr.on("data",x=>{d+=x.toString()}),l.on("error",x=>m(()=>a(new Error(`${e} failed to start: ${x.message}`)))),l.on("close",x=>{m(()=>{x!==0?a(new Error(`${e} exited with code ${x}.
624
669
  `+(d?`Stderr: ${d.slice(0,500)}
625
- `:"")+(c?`Output: ${c.slice(0,500)}`:"No output"))):i(c)})}),l.stdin.on("error",()=>{}),l.stdin.write(n)?l.stdin.end():l.stdin.once("drain",()=>l.stdin.end());let h=o||6e5,y=Math.round(h/6e4),w=setTimeout(()=>{l.kill(),m(()=>a(new Error(`${e} timed out after ${y} minutes.
670
+ `:"")+(c?`Output: ${c.slice(0,500)}`:"No output"))):i(c)})}),l.stdin.on("error",()=>{}),l.stdin.write(n)?l.stdin.end():l.stdin.once("drain",()=>l.stdin.end());let y=o||6e5,h=Math.round(y/6e4),b=setTimeout(()=>{l.kill(),m(()=>a(new Error(`${e} timed out after ${h} minutes.
626
671
  `+(d?`Stderr: ${d.slice(0,500)}
627
- `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(w))})}async function Dr(e,t,n,s,o,i){let a=oe(),r=_(),l=v().modules.length>0,c=Ot(),d=cn(a,t,l,c.pageType,c.brandAssets);d+=`
672
+ `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},y);l.on("close",()=>clearTimeout(b))})}async function Ca(e,t,n,s,o,i){let a=ce(),r=N(),l=v().modules.length>0,c=Ut(),d=xn(a,t,l,c.pageType,c.brandAssets);d+=`
628
673
 
629
674
  ## User Request
630
- `+e,d+=dn(),d+=Mr(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,w=>{n(w)});o&&o(y)}finally{clearInterval(h)}}async function bo(e,t,n,s,o,i,a){let r=oe(),l=v().modules.length>0,c=Ot(),d=cn(r,n,l,c.pageType,c.brandAssets);d+=`
675
+ `+e,d+=vn(),d+=ha(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print"];r.claudeCodeModel&&u.push("--model",r.claudeCodeModel),r.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let m=0,g=s||(()=>{});g(ye[0]);let y=setInterval(()=>{m++;let h=ye[Math.min(m,ye.length-1)];g(h)},6e3);try{let h=await Uo(u,d,{onChunk:b=>n(b),onToolUse:(b,x)=>{g(Lu(b,x))}});o&&o(h)}finally{clearInterval(y)}}function Lu(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function Wo(e,t,n,s,o,i,a){let r=ce(),l=v().modules.length>0,c=Ut(),d=xn(r,n,l,c.pageType,c.brandAssets);d+=`
631
676
 
632
677
  ## User Request
633
- `+t,d+=dn(),d+=Mr(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 w=fe[Math.min(f,fe.length-1)];h(w)},6e3);try{let w=await ds(u,m,d,x=>{s(x)});i&&i(w)}finally{clearInterval(y)}}var ho,fe,yo,So=D(()=>{"use strict";g();qe();Z();Ke();Se();_r();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 R(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){R(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var et=D(()=>{"use strict";g()});import{createWriteStream as Od,mkdirSync as Hr,existsSync as xo,readFileSync as wo}from"fs";import{join as ht,extname as Nd}from"path";import{randomUUID as Rd}from"crypto";import jd from"busboy";function Hd(e,t){if(Ur.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return Dd[n]??t}function Ld(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Ud(e,t){if(!xo(ht(e,t)))return t;let n=Nd(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 Gd(e){let t=(await import("pdf-parse")).default,n=wo(e);return(await t(n)).text}async function Bd(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function Wd(e){return wo(e,"utf-8")}function Gr(e,t){let n=v();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],a=0,r=[],l=jd({headers:e.headers,limits:{fileSize:Fd,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:f}=u;a++;let h=Hd(m,f);if(!Ur.has(h)){i.push(`Unsupported file type: ${m} (${f})`),d.resume();return}let y=Lr.has(h),w=Ld(m),x=Rd(),S,P;y?(S=ht(n.themePath,"assets"),Hr(S,{recursive:!0}),P=Ud(S,w)):(S=ht(n.themePath,".vibespot","uploads"),Hr(S,{recursive:!0}),P=`${x}-${w}`);let j=ht(S,P),G=Od(j),T=0,V=!1;d.on("data",N=>{T+=N.length}),d.on("limit",()=>{V=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(G),r.push(new Promise(N=>{G.on("finish",()=>{if(!V){let O={id:x,filename:P,originalName:m,type:y?"image":"document",usage:y?"asset":"context",mimeType:h,size:T,addedAt:new Date().toISOString()};o.push(O),Zi(O)}N()}),G.on("error",()=>{i.push(`Failed to write: ${m}`),N()})}))}),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 Gd(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await Bd(d):c.extractedText=Wd(d),$.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){$.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=>{$.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Co(e){let t=v();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=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 Fd,Lr,Jd,Ur,Dd,Ao=D(()=>{"use strict";g();et();Se();ve();Fd=10*1024*1024,Lr=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Jd=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),Ur=new Set([...Lr,...Jd]),Dd={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});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>=ko.length)throw s;let r=ko[n];$.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${ko.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 Br(){return Io||(Io=(await import("@anthropic-ai/sdk")).default),Io}async function Vd(e,t,n,s,o){let i=await Br(),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 Kd(e,t,n){let s=await Br(),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 To(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"?To(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=To(t.items)),t}async function Yd(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:To(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 $.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:r}}return{type:"text",text:r}}async function zd(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 $.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function qd(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 Xd(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(`
678
+ `+t,d+=vn(),d+=ha(a),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;e==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,y=o||(()=>{});y(ye[0]);let h=setInterval(()=>{g++;let b=ye[Math.min(g,ye.length-1)];y(b)},6e3);try{let b=await Go(u,m,d,x=>{s(x)});i&&i(b)}finally{clearInterval(h)}}var Lo,ye,Bo,Vo=L(()=>{"use strict";f();ot();Q();tt();pe();pa();ae();Lo=null;ye=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],Bo=[10,20,40,60,120]});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function B(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function Ye(e,t,n){B(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Fe=L(()=>{"use strict";f()});import{createWriteStream as Bu,mkdirSync as ka,existsSync as Ko,readFileSync as zo}from"fs";import{join as Ct,extname as Uu}from"path";import{randomUUID as Gu}from"crypto";import Wu from"busboy";function Yu(e,t){if($a.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return zu[n]??t}function qu(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Xu(e,t){if(!Ko(Ct(e,t)))return t;let n=Uu(t),s=t.slice(0,-n.length||void 0),o=1;for(;Ko(Ct(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function Zu(e){let t=(await import("pdf-parse")).default,n=zo(e);return(await t(n)).text}async function Qu(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function em(e){return zo(e,"utf-8")}function Ta(e,t){let n=v();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],a=0,r=[],l=Wu({headers:e.headers,limits:{fileSize:Vu,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;a++;let y=Yu(m,g);if(!$a.has(y)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let h=Aa.has(y),b=qu(m),x=Gu(),w,S;h?(w=Ct(n.themePath,"assets"),ka(w,{recursive:!0}),S=Xu(w,b)):(w=Ct(n.themePath,".vibespot","uploads"),ka(w,{recursive:!0}),S=`${x}-${b}`);let M=Ct(w,S),R=Bu(M),O=0,H=!1;d.on("data",z=>{O+=z.length}),d.on("limit",()=>{H=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(R),r.push(new Promise(z=>{R.on("finish",()=>{if(!H){let P={id:x,filename:S,originalName:m,type:h?"image":"document",usage:h?"asset":"context",mimeType:y,size:O,addedAt:new Date().toISOString()};o.push(P),jr(P)}z()}),R.on("error",()=>{i.push(`Failed to write: ${m}`),z()})}))}),l.on("finish",async()=>{await Promise.all(r);for(let c of o)if(c.type==="document"){let d=Ct(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await Zu(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await Qu(d):c.extractedText=em(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 $s(e){let t=v();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=Ct(t.themePath,"assets",s.filename);Ko(i)&&(o.base64=zo(i).toString("base64")),o.assetPath=`${t.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var Vu,Aa,Ku,$a,zu,Yo=L(()=>{"use strict";f();Fe();pe();ae();Vu=10*1024*1024,Aa=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Ku=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),$a=new Set([...Aa,...Ku]),zu={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var Pa={};ke(Pa,{callAgent:()=>Ce,callAgentAPI:()=>_a,isAgenticCapable:()=>Cn,isCLIEngine:()=>Gt,resolveThinkingBudget:()=>Qo});async function Ts(e,t){for(let n=0;;n++)try{return await e()}catch(s){let o=s.status,i=s.error?.type;if(!(o===429||i==="rate_limit_error"||s instanceof Error&&s.message.includes("429"))||n>=qo.length)throw s;let r=qo[n];T.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${qo.length} \u2014 waiting ${r}s`),t&&t(`Rate limited \u2014 retrying in ${r}s...`),await new Promise(l=>setTimeout(l,r*1e3)),t&&t("Retrying...")}}function wn(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;for(let n of["fieldsJson","metaJson"])t[n]&&typeof t[n]=="object"&&(t[n]=JSON.stringify(t[n]))}return e}async function Ia(){return Xo||(Xo=(await import("@anthropic-ai/sdk")).default),Xo}async function tm(e,t,n,s,o){let i=await Ia(),a=new i({apiKey:e,...s?{defaultHeaders:s}:{}}),r=n.messages,l=n.systemPrompt;if(n.systemBlocks?l=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(l=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let c={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Ts(async()=>{let d=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:r,tools:[c],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for(let m of d.content)if(m.type==="tool_use")return{type:"structured",data:wn(m.input)};return{type:"text",text:d.content.filter(m=>m.type==="text").map(m=>m.text).join("")}},n.onStatus)}return Ts(async()=>{let c="",d=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:r,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let u of d)u.type==="content_block_delta"&&u.delta.type==="text_delta"&&(c+=u.delta.text,n.onChunk&&n.onChunk(u.delta.text));return{type:"text",text:c}},n.onStatus)}async function nm(e,t,n){let s=await Ia(),o=new s({authToken:e,defaultHeaders:Zt}),i=n.messages,a;if(n.systemBlocks?a=[{type:"text",text:Mt},...n.systemBlocks]:a=[{type:"text",text:Mt},{type:"text",text:n.systemPrompt}],n.structuredOutput){let r={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Ts(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:a,messages:i,tools:[r],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for(let d of l.content)if(d.type==="tool_use")return{type:"structured",data:wn(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return Ts(async()=>{let r="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:a,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let c of l)c.type==="content_block_delta"&&c.delta.type==="text_delta"&&(r+=c.delta.text,n.onChunk&&n.onChunk(c.delta.text));return{type:"text",text:r}},n.onStatus)}function Zo(e){let t={...e};if(t.type==="object"&&(t.additionalProperties=!1,t.properties&&typeof t.properties=="object")){let n={};for(let[s,o]of Object.entries(t.properties))n[s]=o&&typeof o=="object"?Zo(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Zo(t.items)),t}async function sm(e,t,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:t,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:Zo(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let r=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:wn(JSON.parse(r))}}catch{return T.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:r}}return{type:"text",text:r}}async function om(e,t,n){let s=t||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${e}`,r=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!r.ok){let d=await r.text(),u=r.status;if(u===429){let m=new Error(`Gemini rate limit: ${d}`);throw m.status=429,m}throw new Error(`Gemini API error (${u}): ${d}`)}let c=(await r.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:wn(JSON.parse(c))}}catch{return T.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function im(e,t){switch(e){case"claude-code":{let n=N(),s=["--print"];return n.claudeCodeModel&&s.push("--model",n.claudeCodeModel),t?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":return{bin:"gemini",args:[]};case"codex-cli":return{bin:"codex",args:["exec","--full-auto"]};default:throw new Error(`Not a CLI engine: ${e}`)}}function rm(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
679
  `);t.push(`
635
680
 
636
681
  ## ${s}
637
- ${o}`)}if(e.structuredOutput){let n=Wr(e.structuredOutput.schema);t.push(`
682
+ ${o}`)}if(e.structuredOutput){let n=Ea(e.structuredOutput.schema);t.push(`
638
683
 
639
684
  ## Output Format \u2014 CRITICAL
640
685
  Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
641
686
 
642
687
  The JSON must match this structure:
643
- ${n}`)}return t.join("")}function Wr(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}": ${Wr(r,t+1)}${l}${d}`):i.push(`${n} "${a}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
644
- `)}function Qd(e){let t=e.trim(),n=Ue(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=Ue(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=Ue(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 Zd(e,t,n){let{bin:s,args:o}=qd(e),i=Xd(n),a=await ds(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:a};let r=Qd(a);return r?{type:"structured",data:un(r)}:($.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 tu(e,t,n,s){switch($.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 Vd(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 Kd(i,n,s)}case"openai-api":return Yd(t,n,s);case"gemini-api":return zd(t,n,s);default:throw new Error(`Unsupported API engine: ${e}`)}}async function Pe(e,t,n,s){return eu.has(e)?tu(e,t,n,s):($.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),Zd(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 ko,Io,eu,ct=D(()=>{"use strict";g();So();cs();Z();Ke();ve();ko=[10,20,40,60,120];Io=null;eu=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api"])});function Vr(e,t,n,s){let o=t.length>0?`Current template modules (in page order):
688
+ ${n}`)}return t.join("")}function Ea(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}": ${Ea(r,t+1)}${l}${d}`):i.push(`${n} "${a}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
689
+ `)}function am(e){let t=e.trim(),n=ze(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let r=s[1].trim(),l=ze(r);if(l&&typeof l=="object")return l;let c=Sn(r);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let r=t.slice(o,i+1),l=ze(r);if(l&&typeof l=="object")return l;let c=Sn(r);if(c&&typeof c=="object")return c}let a=Sn(t);return a&&typeof a=="object"?a:null}async function lm(e,t,n){let{bin:s,args:o}=im(e,n),i=rm(n),a;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];a=await Uo(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=cm(c,d);n.onStatus(u)}})}else a=await Go(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:a};let r=am(a);return r?{type:"structured",data:wn(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})}function cm(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function _a(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 tm(t,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(tt(),so)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return nm(i,n,s)}case"openai-api":return sm(t,n,s);case"gemini-api":return om(t,n,s);default:throw new Error(`Unsupported API engine: ${e}`)}}async function Ce(e,t,n,s){return dm.has(e)?_a(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}),lm(e,n,s))}function Qo(e){if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=N();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Cn(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function Gt(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var qo,Xo,dm,qe=L(()=>{"use strict";f();Vo();As();Q();tt();ae();qo=[10,20,40,60,120];Xo=null;dm=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api"])});function Na(e,t,n,s){let o=t.length>0?`Current template modules (in page order):
645
690
  ${t.map((r,l)=>`${l+1}. ${r}`).join(`
646
691
  `)}`:"No modules yet (new page).",i=n.length>0?`
647
692
 
@@ -697,7 +742,7 @@ CRITICAL: When the user corrects a misclassification (e.g., "I was referencing t
697
742
  If the user asks for multiple things (e.g., "make hero taller AND add testimonials"), capture ALL parts:
698
743
  - Affected existing modules in \`affectedModules\`
699
744
  - New modules in \`newModules\`
700
- - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Kr,Yr=D(()=>{"use strict";g();Kr={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 zr(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=Vr(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:Kr,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){$.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||[],$.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:nu(m)}),m}function nu(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 qr=D(()=>{"use strict";g();ct();Yr();ve()});function $o(e,t){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
745
+ - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Ma,Oa=L(()=>{"use strict";f();Ma={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 Ra(e,t,n,s,o,i,a){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let r=t.modules.map(g=>g.moduleName),l=Na(t.themeName,r,a,t.brandAssets?.themeContext),c=[],d=t.messages.slice(-6);for(let g of d)if(g.role==="user"||g.role==="assistant"){let y=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:y})}c.push({role:"user",content:e});let u=await Ce(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Ma,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){T.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:r,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:g}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],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:um(m)}),m}function um(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 Fa=L(()=>{"use strict";f();qe();Oa();ae()});function ei(e,t){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
701
746
 
702
747
  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.
703
748
 
@@ -784,22 +829,22 @@ Good system font stacks by style:
784
829
  | Geometric | Futura, "Century Gothic", "Trebuchet MS", sans-serif | system-ui, sans-serif |`),n.push(`
785
830
 
786
831
  ## Design Guide
787
- ${ta()}`),t?.styleguide&&n.push(`
832
+ ${La()}`),t?.styleguide&&n.push(`
788
833
 
789
834
  ## Brand Style Guide
790
835
  ${t.styleguide}`),t?.themeContext&&n.push(`
791
836
 
792
837
  ## Product Context
793
- ${t.themeContext}`),n.join("")}function Xr(e,t){let n=$o(e),o=n.indexOf(`
838
+ ${t.themeContext}`),n.join("")}function Ja(e,t){let n=ei(e),o=n.indexOf(`
794
839
 
795
840
  ## Design Guide
796
841
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),a=`## Design Guide
797
- ${ta()}`,r=[{type:"text",text:i},{type:"text",text:a,cache_control:{type:"ephemeral"}}],l=[];return t?.styleguide&&l.push(`## Brand Style Guide
842
+ ${La()}`,r=[{type:"text",text:i},{type:"text",text:a,cache_control:{type:"ephemeral"}}],l=[];return t?.styleguide&&l.push(`## Brand Style Guide
798
843
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
799
844
  ${t.themeContext}`),l.length>0&&r.push({type:"text",text:l.join(`
800
845
 
801
- `)}),r}function su(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
802
- `)}function Zr(e,t,n,s){let o=[],i=su(t);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
846
+ `)}),r}function mm(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
847
+ `)}function Da(e,t,n,s){let o=[],i=mm(t);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
803
848
 
804
849
  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.
805
850
 
@@ -820,7 +865,7 @@ ${i}
820
865
  - moduleOrder: list module names in the order they should appear on the page`),(!s||s.includes("content"))&&o.push(`
821
866
 
822
867
  ## Content & Copywriting Guide
823
- ${ou()}`),n?.brandvoice&&o.push(`
868
+ ${pm()}`),n?.brandvoice&&o.push(`
824
869
 
825
870
  ## Brand Voice
826
871
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -829,7 +874,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
829
874
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
830
875
 
831
876
  ## Anti-AI Copy Rules
832
- ${iu()}`),o.join("")}function ta(){return`### Design Philosophy
877
+ ${gm()}`),o.join("")}function La(){return`### Design Philosophy
833
878
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
834
879
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
835
880
 
@@ -932,7 +977,7 @@ Include these in shared CSS:
932
977
  | All animations same speed | Stagger with increasing delays |
933
978
  | Skip hover/focus states | Every interactive element needs feedback |
934
979
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
935
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function ou(){return`### Mandatory Page Sections (generate all)
980
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function pm(){return`### Mandatory Page Sections (generate all)
936
981
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
937
982
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
938
983
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -1020,7 +1065,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
1020
1065
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
1021
1066
  - Keep paragraphs to 2-3 sentences max
1022
1067
  - Aim for 6th-grade reading level
1023
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function iu(){return`### Banned Punctuation
1068
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function gm(){return`### Banned Punctuation
1024
1069
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
1025
1070
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
1026
1071
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -1050,28 +1095,28 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
1050
1095
  - Use plain short words: use > utilize, start > commence, help > facilitate
1051
1096
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
1052
1097
  - Front-load the benefit in the first 5 words
1053
- - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Qr,ea,na=D(()=>{"use strict";g();Qr={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"]};ea={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 sa(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=$o(n.themeName,n.brandAssets),c=r?Xr(n.themeName,n.brandAssets):void 0,d=`## User Request
1098
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var ja,Ha,Ba=L(()=>{"use strict";f();ja={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"]};Ha={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 Ua(e,t,n,s,o,i,a){a({type:"agent_step",step:"designing",label:"Creating design system..."});let r=s==="anthropic-api"||s==="claude-oauth",l=ei(n.themeName,n.brandAssets),c=r?Ja(n.themeName,n.brandAssets):void 0,d=`## User Request
1054
1099
  ${e}`;n.modules.length>0&&t.designSystemChanges&&(d+=`
1055
1100
 
1056
1101
  ## Current Shared CSS (update this)
1057
1102
  \`\`\`css
1058
1103
  ${n.sharedCss}
1059
- \`\`\``);let u=await Pe(s,o,i,{systemPrompt:l,systemBlocks:c,messages:[{role:"user",content:d}],structuredOutput:{schema:Qr,name:"design_system"},maxTokens:16e3}),m;u.type!=="structured"?($.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,$.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 {
1060
- ${Object.entries(h).map(([O,J])=>` ${O.startsWith("--")?O:`--${O}`}: ${J};`).join(`
1104
+ \`\`\``);let u=Qo(s),m=await Ce(s,o,i,{systemPrompt:l,systemBlocks:c,messages:[{role:"user",content:d}],structuredOutput:{schema:ja,name:"design_system"},maxTokens:16e3,...u>0?{thinkingBudgetTokens:u}:{}}),g;m.type!=="structured"?(T.warn("page-architect","Design system: did not get structured output, using fallback"),g={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(g=m.data,T.info("page-architect","Design system created",{aesthetic:g.aesthetic,varCount:Object.keys(g.cssVariables||{}).length,cssLength:g.sharedCss?.length||0}));let y=g.sharedCss||"",h=g.cssVariables;h&&typeof h=="object"&&Object.keys(h).length>0&&(y.includes(":root")||(y=`:root {
1105
+ ${Object.entries(h).map(([J,k])=>` ${J.startsWith("--")?J:`--${J}`}: ${k};`).join(`
1061
1106
  `)}
1062
1107
  }
1063
1108
 
1064
- ${f}`));let y=[],w=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,x=[...new Set((e.match(w)||[]).map(N=>N.trim()))];if(x.length>0){let N=x.filter(J=>f.toLowerCase().includes(J.toLowerCase())),O=x.filter(J=>!N.includes(J));O.length>0&&y.push(`Note: ${O.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let S=[`Design system: ${m.aesthetic||"created"} | ${Object.keys(h||{}).length} variables, ${f.length} chars CSS`,...y];a({type:"agent_decision",step:"designing",decision:S.join(`
1065
- `)}),a({type:"design_system_ready",sharedCss:f,sharedJs:m.sharedJs||"",aesthetic:m.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let P=Zr(n.themeName,f,n.brandAssets,t.guidesNeeded),j=`## User Request
1066
- ${e}`;t.newModules.length>0&&(j+=`
1109
+ ${y}`));let b=[],x=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,w=[...new Set((e.match(x)||[]).map(P=>P.trim()))];if(w.length>0){let P=w.filter(k=>y.toLowerCase().includes(k.toLowerCase())),J=w.filter(k=>!P.includes(k));J.length>0&&b.push(`Note: ${J.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let S=[`Design system: ${g.aesthetic||"created"} | ${Object.keys(h||{}).length} variables, ${y.length} chars CSS`,...b];a({type:"agent_decision",step:"designing",decision:S.join(`
1110
+ `)}),a({type:"design_system_ready",sharedCss:y,sharedJs:g.sharedJs||"",aesthetic:g.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let M=Da(n.themeName,y,n.brandAssets,t.guidesNeeded),R=`## User Request
1111
+ ${e}`;t.newModules.length>0&&(R+=`
1067
1112
 
1068
1113
  ## Planned Modules
1069
- ${t.newModules.map((N,O)=>`${O+1}. **${N.name}** \u2014 ${N.description}`).join(`
1070
- `)}`),n.modules.length>0&&!t.designSystemChanges&&(j+=`
1114
+ ${t.newModules.map((P,J)=>`${J+1}. **${P.name}** \u2014 ${P.description}`).join(`
1115
+ `)}`),n.modules.length>0&&!t.designSystemChanges&&(R+=`
1071
1116
 
1072
1117
  ## Existing Modules (keeping)
1073
- ${n.modules.map(N=>`- ${N.moduleName}`).join(`
1074
- `)}`);let G=await Pe(s,o,i,{systemPrompt:P,messages:[{role:"user",content:j}],structuredOutput:{schema:ea,name:"module_plan"},maxTokens:8e3}),T,V={modules:t.newModules.map(N=>({name:N.name,description:N.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(N=>N.name),narrative:"Page generated from user request"};if(G.type!=="structured")$.warn("page-architect","Module planner: did not get structured output, using fallback"),T=V;else{let N=G.data;Array.isArray(N?.modules)&&N.modules.length>0?(T=N,T.moduleOrder=T.moduleOrder||T.modules.map(O=>O.name),T.narrative=T.narrative||"Page generated from user request"):($.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:N?Object.keys(N):[]}),T=V),$.info("page-architect","Module plan",{moduleCount:T.modules.length})}return a({type:"agent_decision",step:"designing",decision:`Page: ${T.narrative} | ${T.modules.length} modules planned`}),{designSystem:{cssVariables:m.cssVariables||{},sharedCss:f,sharedJs:m.sharedJs},modules:T.modules,moduleOrder:T.moduleOrder,narrative:T.narrative}}var oa=D(()=>{"use strict";g();ct();na();ve()});function ia(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 ra=D(()=>{"use strict";g()});function Eo(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1118
+ ${n.modules.map(P=>`- ${P.moduleName}`).join(`
1119
+ `)}`);let O=await Ce(s,o,i,{systemPrompt:M,messages:[{role:"user",content:R}],structuredOutput:{schema:Ha,name:"module_plan"},maxTokens:8e3,...u>0?{thinkingBudgetTokens:u}:{}}),H,z={modules:t.newModules.map(P=>({name:P.name,description:P.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(P=>P.name),narrative:"Page generated from user request"};if(O.type!=="structured")T.warn("page-architect","Module planner: did not get structured output, using fallback"),H=z;else{let P=O.data;Array.isArray(P?.modules)&&P.modules.length>0?(H=P,H.moduleOrder=H.moduleOrder||H.modules.map(J=>J.name),H.narrative=H.narrative||"Page generated from user request"):(T.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:P?Object.keys(P):[]}),H=z),T.info("page-architect","Module plan",{moduleCount:H.modules.length})}return a({type:"agent_decision",step:"designing",decision:`Page: ${H.narrative} | ${H.modules.length} modules planned`}),{designSystem:{cssVariables:g.cssVariables||{},sharedCss:y,sharedJs:g.sharedJs},modules:H.modules,moduleOrder:H.moduleOrder,narrative:H.narrative}}var Ga=L(()=>{"use strict";f();qe();Ba();ae()});function Is(e){let t=0,n=[];return async function(o){t>=e&&await new Promise(i=>n.push(i)),t++;try{return await o()}finally{t--,n.length>0&&n.shift()()}}}var ti=L(()=>{"use strict";f()});function kn(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1075
1120
 
1076
1121
  Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code.
1077
1122
 
@@ -1123,29 +1168,29 @@ ${t}
1123
1168
  \`\`\``),(!n||n.includes("hubspot_rules"))&&o.push(`
1124
1169
 
1125
1170
  ## HubSpot CMS Rules
1126
- ${Ee()}`),(!n||n.includes("conversion"))&&o.push(`
1171
+ ${Me()}`),(!n||n.includes("conversion"))&&o.push(`
1127
1172
 
1128
1173
  ## Conversion Guide
1129
- ${oe()}`),s?.themeContext&&o.push(`
1174
+ ${ce()}`),s?.themeContext&&o.push(`
1130
1175
 
1131
1176
  ## Product Context
1132
1177
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1133
1178
 
1134
1179
  ## Anti-AI Copy Rules
1135
- ${la()}`),o.join("")}function aa(e,t,n,s){let o=[],i=Eo(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1180
+ ${Wa()}`),o.join("")}function Es(e,t,n,s){let o=[],i=kn(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1136
1181
 
1137
1182
  ## Theme Shared CSS (use these custom properties)
1138
1183
  \`\`\`css
1139
1184
  ${t}
1140
1185
  \`\`\``),o.push({type:"text",text:i});let a=[];(!n||n.includes("hubspot_rules"))&&a.push(`## HubSpot CMS Rules
1141
- ${Ee()}`),(!n||n.includes("conversion"))&&a.push(`## Conversion Guide
1142
- ${oe()}`),a.length>0&&o.push({type:"text",text:a.join(`
1186
+ ${Me()}`),(!n||n.includes("conversion"))&&a.push(`## Conversion Guide
1187
+ ${ce()}`),a.length>0&&o.push({type:"text",text:a.join(`
1143
1188
 
1144
1189
  `),cache_control:{type:"ephemeral"}});let r=[];return s?.themeContext&&r.push(`## Product Context
1145
1190
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&r.push(`## Anti-AI Copy Rules
1146
- ${la()}`),r.length>0&&o.push({type:"text",text:r.join(`
1191
+ ${Wa()}`),r.length>0&&o.push({type:"text",text:r.join(`
1147
1192
 
1148
- `)}),o}function la(){return`### Banned Punctuation
1193
+ `)}),o}function Wa(){return`### Banned Punctuation
1149
1194
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1150
1195
  - **Semicolons**: Use periods instead in marketing copy.
1151
1196
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1184,7 +1229,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1184
1229
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1185
1230
  - Full names, specific roles (not "John D., CEO")
1186
1231
  - Never start with "This product is..." \u2014 start with the person's situation
1187
- - Vary length and voice across testimonials`}function ca(e,t,n){let s=[];return s.push(`## User Request
1232
+ - Vary length and voice across testimonials`}function Va(e,t,n){let s=[];return s.push(`## User Request
1188
1233
  ${e}`),s.push(`
1189
1234
 
1190
1235
  ## Module Specification
@@ -1211,39 +1256,284 @@ ${n.moduleCss}
1211
1256
  **module.js:**
1212
1257
  \`\`\`js
1213
1258
  ${n.moduleJs}
1214
- \`\`\``)),s.join("")}var da,ua=D(()=>{"use strict";g();qe();da={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 ma(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=Eo(s,n,c,d),f=u?aa(s,n,c,d):void 0,h=ia(r),y=t.length,w=t.map((S,P)=>h(async()=>{l({type:"module_progress",module:S.name,status:"generating",current:P+1,total:y});let j="";for(let G=0;G<2;G++)try{G>0&&($.warn("module-developer",`${S.name}: retrying after failure (attempt ${G+1})`),l({type:"module_progress",module:S.name,status:"retrying",current:P+1,total:y}));let T=await pa(e,S,m,o,i,a,0,f);return l({type:"module_progress",module:S.name,status:"complete",current:P+1,total:y,moduleFiles:T}),{moduleName:S.name,module:T}}catch(T){j=T instanceof Error?T.message:typeof T=="object"&&T!==null?JSON.stringify(T):String(T),$.error("module-developer",`Failed: ${S.name} (attempt ${G+1})`,{error:j})}return l({type:"module_progress",module:S.name,status:"failed",current:P+1,total:y}),{moduleName:S.name,error:j}}));return(await Promise.allSettled(w)).map(S=>S.status==="fulfilled"?S.value:{moduleName:"unknown",error:S.reason instanceof Error?S.reason.message:String(S.reason)})}async function pa(e,t,n,s,o,i,a=0,r){let l=ca(e,t,t.existingCode),c=await Pe(s,o,i,{systemPrompt:n,systemBlocks:r,messages:[{role:"user",content:l}],structuredOutput:{schema:da,name:"module_output"},maxTokens:16e3});if(c.type!=="structured"){if(a<2)return $.warn("module-developer",`${t.name}: no structured output, retry ${a+1}`),pa(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 fa=D(()=>{"use strict";g();ct();ra();ua();ve()});function ha(e,t,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),e.map(s=>{let o=[],i={...s};i.fieldsJson=ga(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=ga(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=ru(i.fieldsJson,i.moduleName,o),i.fieldsJson=au(i.fieldsJson,i.moduleName,o),i.moduleCss=lu(i.moduleCss,i.moduleName,"moduleCss",o),i.moduleCss=du(i.moduleCss,i.moduleName,t,o),i.moduleHtml=uu(i.moduleHtml,i.moduleName,t,o),i.moduleHtml=pu(i.moduleHtml,i.moduleName,o),i.metaJson=fu(i.metaJson,i.moduleName,o);let a=o.every(r=>r.autoFixed);return o.length>0&&$.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 ga(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):(Ue(e)===null&&s.push({module:t,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),e)}function ru(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 au(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 lu(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 ya(e){return cu.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function du(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)&&!ya(c)&&a.add(c)}if(a.size<=3)return e;let l=e;for(let c of a){let d=new RegExp(`\\.${mu(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 uu(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)&&!ya(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 mu(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function pu(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(`
1259
+ \`\`\``)),s.join("")}var _s,ni=L(()=>{"use strict";f();ot();_s={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function Ka(e,t,n,s,o,i,a,r,l,c,d){l({type:"agent_step",step:"developing",label:`Generating ${t.length} module${t.length===1?"":"s"}...`});let u=o==="anthropic-api"||o==="claude-oauth",m=kn(s,n,c,d),g=u?Es(s,n,c,d):void 0,y=Is(r),h=t.length,b=t.map((w,S)=>y(async()=>{l({type:"module_progress",module:w.name,status:"generating",current:S+1,total:h});let M="";for(let R=0;R<2;R++)try{R>0&&(T.warn("module-developer",`${w.name}: retrying after failure (attempt ${R+1})`),l({type:"module_progress",module:w.name,status:"retrying",current:S+1,total:h}));let O=await za(e,w,m,o,i,a,0,g);return l({type:"module_progress",module:w.name,status:"complete",current:S+1,total:h,moduleFiles:O}),{moduleName:w.name,module:O}}catch(O){M=O instanceof Error?O.message:typeof O=="object"&&O!==null?JSON.stringify(O):String(O),T.error("module-developer",`Failed: ${w.name} (attempt ${R+1})`,{error:M})}return l({type:"module_progress",module:w.name,status:"failed",current:S+1,total:h}),{moduleName:w.name,error:M}}));return(await Promise.allSettled(b)).map(w=>w.status==="fulfilled"?w.value:{moduleName:"unknown",error:w.reason instanceof Error?w.reason.message:String(w.reason)})}async function za(e,t,n,s,o,i,a=0,r){let l=Va(e,t,t.existingCode),c=await Ce(s,o,i,{systemPrompt:n,systemBlocks:r,messages:[{role:"user",content:l}],structuredOutput:{schema:_s,name:"module_output"},maxTokens:16e3});if(c.type!=="structured"){if(a<2)return T.warn("module-developer",`${t.name}: no structured output, retry ${a+1}`),za(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 Ya=L(()=>{"use strict";f();qe();ti();ni();ae()});function Ps(e,t,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),e.map(s=>{let o=[],i={...s};i.fieldsJson=qa(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=qa(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=fm(i.fieldsJson,i.moduleName,o),i.fieldsJson=hm(i.fieldsJson,i.moduleName,o),i.moduleCss=ym(i.moduleCss,i.moduleName,"moduleCss",o),i.moduleCss=Sm(i.moduleCss,i.moduleName,t,o),i.moduleHtml=xm(i.moduleHtml,i.moduleName,t,o),i.moduleHtml=wm(i.moduleHtml,i.moduleName,o),i.metaJson=Cm(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 qa(e,t,n,s){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:["PAGE"],is_available_for_new_content:!0}):e):(ze(e)===null&&s.push({module:t,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),e)}function fm(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 hm(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 ym(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 Xa(e){return bm.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Sm(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)&&!Xa(c)&&a.add(c)}if(a.size<=3)return e;let l=e;for(let c of a){let d=new RegExp(`\\.${vm(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 xm(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,a=!1,r=e.replace(i,(l,c)=>{let d=c.split(/\s+/),u=!1,m=d.map(g=>g&&!g.startsWith(o)&&!Xa(g)&&/^[a-zA-Z][\w-]*$/.test(g)?(u=!0,o+g):g);return u?(a=!0,`class="${m.join(" ")}"`):l});return a&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),r}function vm(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function wm(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(`
1215
1260
  `);s=`${s}
1216
- ${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 fu(e,t,n){let s=Ue(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 cu,ba=D(()=>{"use strict";g();cs();ve();cu=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"])});import{execSync as gu}from"child_process";async function Sa(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{gu(`command -v ${F}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${F}" to be installed and on your PATH.`)}}let d=await zr(e,t,n,s,o,a,r);if(d.intent==="question"&&d.answer){let J=Date.now()-l;return a({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:J,answer:d.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:J}}}let u=null,m=t.sharedCss,f=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await sa(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 J of u.modules)y.push({name:J.name,description:J.description,contentBrief:J.contentBrief,layoutNotes:J.layoutNotes});else{for(let J of d.newModules)y.push({name:J.name,description:J.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let J of d.affectedModules){let F=t.modules.find(X=>X.moduleName===J);F&&y.push({name:J,description:`Modify existing module: ${J}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:F})}}let w=[],x=[];if(y.length>0){let J=await ma(e,y,m,t.themeName,n,s,o,c,a,d.guidesNeeded,t.brandAssets);for(let F of J)F.module?w.push(F.module):x.push(F.moduleName)}let S=null;if(w.length>0){S=ha(w,t.themeName,a),w=S.map(F=>F.module);let J=S.reduce((F,X)=>F+X.issues.length,0);if(J>0){let F=S.reduce((le,Wo)=>le+Wo.issues.filter(Ft=>Ft.autoFixed).length,0);$.info("pipeline",`Quality check: ${J} issues, ${F} auto-fixed`);let X=S.flatMap(le=>le.issues).map(le=>`${le.autoFixed?"\u2713":"\u26A0"} ${le.module}: ${le.message}`).join(`
1217
- `);a({type:"agent_decision",step:"quality_check",decision:`${J} issues found, ${F} auto-fixed
1218
- ${X}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let P=hu(t,d,w,u,r),j=yu(t,d,u,P);if(u?.moduleOrder?.length){let J=new Set(u.moduleOrder),F=P.filter(X=>!J.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,T=w.length,V=d.unchangedModules.length,N=S?S.flatMap(J=>J.issues):[],O=bu(d,T,V,x,G,u,N);return x.length>0?a({type:"pipeline_partial",succeeded:w.map(J=>J.moduleName),failed:x,durationMs:G}):a({type:"pipeline_complete",modulesGenerated:T,modulesUnchanged:V,durationMs:G}),{modules:P,moduleOrder:j,sharedCss:m,sharedJs:f,assistantMessage:O,stats:{modulesGenerated:T,modulesUnchanged:V,modulesFailed:x.length,durationMs:G}}}function hu(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 yu(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),$.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 bu(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(`
1261
+ ${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 Cm(e,t,n){let s=ze(e);if(!s||typeof s!="object")return e;let o=s,i=!1;return o.host_template_types||(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content===void 0&&(o.is_available_for_new_content=!0,i=!0),i?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(o,null,2)):e}var bm,si=L(()=>{"use strict";f();As();ae();bm=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"])});import{execSync as km}from"child_process";async function Za(e,t,n,s,o,i,a,r){let l=Date.now(),c=i;if(Gt(n)){let k={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(k)try{km(`command -v ${k}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${k}" to be installed and on your PATH.`)}}let d=await Ra(e,t,n,s,o,a,r);if(d.intent==="question"&&d.answer){let J=Date.now()-l;return a({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:J,answer:d.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:J}}}let u=null,m=t.sharedCss,g=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Ua(e,d,t,n,s,o,a),m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g,a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let h=[];if(u)for(let J of u.modules)h.push({name:J.name,description:J.description,contentBrief:J.contentBrief,layoutNotes:J.layoutNotes});else{for(let J of d.newModules)h.push({name:J.name,description:J.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let J of d.affectedModules){let k=t.modules.find(E=>E.moduleName===J);k&&h.push({name:J,description:`Modify existing module: ${J}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:k})}}let b=[],x=[];if(h.length>0){let J=await Ka(e,h,m,t.themeName,n,s,o,c,a,d.guidesNeeded,t.brandAssets);for(let k of J)k.module?b.push(k.module):x.push(k.moduleName)}let w=null;if(b.length>0){w=Ps(b,t.themeName,a),b=w.map(k=>k.module);let J=w.reduce((k,E)=>k+E.issues.length,0);if(J>0){let k=w.reduce((Z,Mn)=>Z+Mn.issues.filter(ft=>ft.autoFixed).length,0);T.info("pipeline",`Quality check: ${J} issues, ${k} auto-fixed`);let E=w.flatMap(Z=>Z.issues).map(Z=>`${Z.autoFixed?"\u2713":"\u26A0"} ${Z.module}: ${Z.message}`).join(`
1262
+ `);a({type:"agent_decision",step:"quality_check",decision:`${J} issues found, ${k} auto-fixed
1263
+ ${E}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let S=Am(t,d,b,u,r),M=$m(t,d,u,S);if(u?.moduleOrder?.length){let J=new Set(u.moduleOrder),k=S.filter(E=>!J.has(E.moduleName)).map(E=>E.moduleName);k.length>0&&a({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${k.length} module${k.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${k.join(", ")}`})}let R=Date.now()-l,O=b.length,H=d.unchangedModules.length,z=w?w.flatMap(J=>J.issues):[],P=Tm(d,O,H,x,R,u,z);return x.length>0?a({type:"pipeline_partial",succeeded:b.map(J=>J.moduleName),failed:x,durationMs:R}):a({type:"pipeline_complete",modulesGenerated:O,modulesUnchanged:H,durationMs:R}),{modules:S,moduleOrder:M,sharedCss:m,sharedJs:g,assistantMessage:P,stats:{modulesGenerated:O,modulesUnchanged:H,modulesFailed:x.length,durationMs:R}}}function Am(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 $m(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 Tm(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(`
1219
1264
 
1220
1265
  ${i.narrative}`),s.length>0&&l.push(`
1221
1266
 
1222
1267
  **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(`
1223
1268
 
1224
1269
  ${u.join(`
1225
- `)}`)}return l.join("")}var va=D(()=>{"use strict";g();ct();qr();oa();fa();ba();ve();ct()});var xa={};nt(xa,{applyPipelineResult:()=>Ro,handleAgenticGenerate:()=>No,handleGenerate:()=>Su,handleGenerateStream:()=>pn,isGenerating:()=>Nt,resolveAgenticEngine:()=>ps,setParseWarningCallback:()=>Mo,shouldUseAgenticMode:()=>jo});import{execSync as _o}from"child_process";function Mo(e){Po=e}function Nt(){return bt!==null}function yt(e){if(bt){let t=v();if(!t||t.id!==bt){$.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}rt("assistant",e),$r(e,Po||void 0),L()}async function pn(e,t,n,s){let o=v();if(!o)throw new Error("No active session");bt=o.id;let a=s?.length?Co(s):void 0;try{let r=_(),l=r.aiEngine||Oo();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 Rr(e,c,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,yt,a);break}case"claude-oauth":{await jr(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 Dr(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,Po=null}}function Oo(){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 _o("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return _o("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return _o("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Su(e){let t="";return await pn(e,n=>{t+=n}),t}function vu(){let e=v(),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||Oo();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 No(e,t,n){let s=v();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=vu(),u=n?.length?Co(n):void 0,m=e;if(u?.length)for(let S of u)S.type==="document"&&S.extractedText&&(m+=`
1270
+ `)}`)}return l.join("")}var Qa=L(()=>{"use strict";f();qe();Fa();Ga();Ya();si();ae();qe()});var ol={};ke(ol,{runFigmaConversion:()=>Im});import{basename as nl}from"path";async function Im(e,t,n,s,o,i,a,r,l){let c=Date.now();a({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=Em(e.designTokens,t);a({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),a({type:"agent_decision",step:"designing",decision:`Generated CSS variables and utility classes from ${e.designTokens.colors.length} colors, ${e.designTokens.typography.length} typography styles`});let{specs:m,moduleOrder:g}=Pm(e.sections,e.assets,t);a({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),a({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${g.join(", ")}`}),a({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let y=n==="anthropic-api"||n==="claude-oauth",h=kn(t,d,["hubspot_rules","conversion"],r),b=y?Es(t,d,["hubspot_rules","conversion"],r):void 0,x=Is(i),w=m.length,S=m.map((E,Z)=>{let Mn=e.sections[Z];return x(async()=>{a({type:"module_progress",module:E.name,status:"generating",current:Z+1,total:w});let ft=Om(Mn,E,e.assets,t,l!==!1),qs="";for(let Yt=0;Yt<2;Yt++)try{Yt>0&&(T.warn("figma-pipeline",`${E.name}: retrying (attempt ${Yt+1})`),a({type:"module_progress",module:E.name,status:"retrying",current:Z+1,total:w}));let It=await Ce(n,s,o,{systemPrompt:h,systemBlocks:b,messages:[{role:"user",content:ft}],structuredOutput:{schema:_s,name:"module_output"},maxTokens:16e3});if(It.type!=="structured")throw new Error("No structured output returned");let je=It.data,_i={moduleName:E.name,fieldsJson:typeof je.fieldsJson=="string"?je.fieldsJson:JSON.stringify(je.fieldsJson,null,2),metaJson:typeof je.metaJson=="string"?je.metaJson:JSON.stringify(je.metaJson,null,2),moduleHtml:String(je.moduleHtml||""),moduleCss:String(je.moduleCss||""),moduleJs:je.moduleJs?String(je.moduleJs):void 0};return a({type:"module_progress",module:E.name,status:"complete",current:Z+1,total:w,moduleFiles:_i}),{moduleName:E.name,module:_i}}catch(It){qs=It instanceof Error?It.message:String(It),T.error("figma-pipeline",`Failed: ${E.name} (attempt ${Yt+1}): ${qs}`)}return a({type:"module_progress",module:E.name,status:"failed",current:Z+1,total:w}),{moduleName:E.name,error:qs}})}),R=(await Promise.allSettled(S)).map(E=>E.status==="fulfilled"?E.value:{moduleName:"unknown",error:String(E.reason)}),O=R.filter(E=>E.module).map(E=>E.module),H=R.filter(E=>E.error).map(E=>E.moduleName),P=Ps(O,t,a).map(E=>E.module),J=Date.now()-c,k=Math.round(J/1e3);return H.length>0?a({type:"pipeline_partial",succeeded:P.map(E=>E.moduleName),failed:H,durationMs:J}):a({type:"pipeline_complete",modulesGenerated:P.length,modulesUnchanged:0,durationMs:J}),{modules:P,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:`Imported ${P.length} modules from Figma design "${e.fileName}" in ${k}s.`,stats:{modulesGenerated:P.length,modulesUnchanged:0,modulesFailed:H.length,durationMs:J}}}function Ns(e){let t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,s=parseInt(e.slice(5,7),16)/255,o=Math.max(t,n,s),i=Math.min(t,n,s),a=(o+i)/2;if(o===i)return{h:0,s:0,l:a};let r=o-i,l=a>.5?r/(2-o-i):r/(o+i),c=0;return o===t?c=((n-s)/r+(n<s?6:0))/6:o===n?c=((s-t)/r+2)/6:c=((t-n)/r+4)/6,{h:c*360,s:l,l:a}}function Em(e,t){let n=[],s=t,o=[...e.colors].sort((k,E)=>E.occurrences-k.occurrences),i=o.filter(k=>k.usage==="background"||k.usage==="fill"),a=o.filter(k=>k.usage==="text"),r=i[0]||o[0],l=r?Ns(r.hex).l<.4:!1;r&&n.push(` --${s}-color-bg: ${r.hex}`);let c=a[0]||(l?o.find(k=>Ns(k.hex).l>.7):o.find(k=>Ns(k.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([r?.hex,c?.hex].filter(Boolean)),u=o.filter(k=>!d.has(k.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(k=>!d.has(k.hex)).slice(0,6).forEach((k,E)=>n.push(` --${s}-color-${E+1}: ${k.hex}`)),r){let k=Ns(r.hex).l;n.push(` --${s}-color-surface: ${l?el(r.hex,.05):tl(r.hex,.03)}`),n.push(` --${s}-color-border: ${l?el(r.hex,.15):tl(r.hex,.12)}`)}let g=e.typography.filter(k=>k.role==="heading"||k.role==="subheading"),y=e.typography.filter(k=>k.role==="body"||k.role==="label"||k.role==="caption"),h=g[0]?.fontFamily||y[0]?.fontFamily||"system-ui",b=y[0]?.fontFamily||h;n.push(` --${s}-font-display: "${h}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let x=g.sort((k,E)=>E.fontSize-k.fontSize);x[0]&&n.push(` --${s}-size-h1: ${x[0].fontSize}px`),x[1]&&n.push(` --${s}-size-h2: ${x[1].fontSize}px`),x[2]&&n.push(` --${s}-size-h3: ${x[2].fontSize}px`);let w=y.sort((k,E)=>E.occurrences-k.occurrences)[0];w&&n.push(` --${s}-size-body: ${w.fontSize}px`);let S=[...new Set(e.spacing.map(k=>k.value))].sort((k,E)=>k-E),M=["xs","sm","md","lg","xl","2xl","section"];S.slice(0,M.length).forEach((k,E)=>{n.push(` --${s}-space-${M[E]}: ${k}px`)});let R=e.effects.filter(k=>k.type==="shadow"),O=e.effects.filter(k=>k.type==="radius");R[0]&&n.push(` --${s}-shadow: ${R[0].cssValue}`),O.sort((k,E)=>parseFloat(k.cssValue)-parseFloat(E.cssValue)),O[0]&&n.push(` --${s}-radius: ${O[0].cssValue}`),O[1]&&n.push(` --${s}-radius-lg: ${O[1].cssValue}`);let H=`:root {
1271
+ ${n.join(`;
1272
+ `)};
1273
+ }`,z=`
1274
+ /* Reset */
1275
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
1276
+
1277
+ body {
1278
+ font-family: var(--${s}-font-body);
1279
+ font-size: var(--${s}-size-body, 16px);
1280
+ color: var(--${s}-color-text);
1281
+ background: var(--${s}-color-bg);
1282
+ line-height: 1.6;
1283
+ -webkit-font-smoothing: antialiased;
1284
+ }
1285
+
1286
+ .${s}-container {
1287
+ width: 100%;
1288
+ max-width: 1200px;
1289
+ margin: 0 auto;
1290
+ padding: 0 var(--${s}-space-md, 24px);
1291
+ }
1292
+
1293
+ .${s}-section {
1294
+ padding: var(--${s}-space-section, 80px) 0;
1295
+ }
1296
+
1297
+ .${s}-section--dark {
1298
+ background: var(--${s}-color-text, #1a1a2e);
1299
+ color: var(--${s}-color-bg, #ffffff);
1300
+ }
1301
+
1302
+ .${s}-grid { display: grid; gap: var(--${s}-space-md, 24px); }
1303
+ .${s}-grid--2 { grid-template-columns: repeat(2, 1fr); }
1304
+ .${s}-grid--3 { grid-template-columns: repeat(3, 1fr); }
1305
+ .${s}-grid--4 { grid-template-columns: repeat(4, 1fr); }
1306
+
1307
+ .${s}-btn {
1308
+ display: inline-flex;
1309
+ align-items: center;
1310
+ gap: 8px;
1311
+ padding: 12px 28px;
1312
+ border-radius: var(--${s}-radius, 8px);
1313
+ font-family: var(--${s}-font-body);
1314
+ font-size: var(--${s}-size-body, 16px);
1315
+ font-weight: 600;
1316
+ text-decoration: none;
1317
+ border: none;
1318
+ cursor: pointer;
1319
+ transition: opacity 0.2s, transform 0.2s;
1320
+ }
1321
+ .${s}-btn:hover { opacity: 0.9; transform: translateY(-1px); }
1322
+ .${s}-btn--primary {
1323
+ background: var(--${s}-color-primary);
1324
+ color: var(--${s}-color-bg, #fff);
1325
+ }
1326
+ .${s}-btn--secondary {
1327
+ background: transparent;
1328
+ border: 2px solid var(--${s}-color-primary);
1329
+ color: var(--${s}-color-primary);
1330
+ }
1331
+
1332
+ .${s}-card {
1333
+ background: var(--${s}-color-surface, var(--${s}-color-bg));
1334
+ border: 1px solid var(--${s}-color-border, transparent);
1335
+ border-radius: var(--${s}-radius, 8px);
1336
+ padding: var(--${s}-space-md, 24px);
1337
+ transition: transform 0.2s, box-shadow 0.2s;
1338
+ }
1339
+ .${s}-card:hover {
1340
+ transform: translateY(-4px);
1341
+ box-shadow: var(--${s}-shadow, 0 8px 24px rgba(0,0,0,0.1));
1342
+ }
1343
+
1344
+ /* Responsive \u2014 tablet */
1345
+ @media (max-width: 1023px) {
1346
+ .${s}-grid--3, .${s}-grid--4 { grid-template-columns: repeat(2, 1fr); }
1347
+ }
1348
+
1349
+ /* Responsive \u2014 mobile */
1350
+ @media (max-width: 767px) {
1351
+ .${s}-grid--2, .${s}-grid--3, .${s}-grid--4 { grid-template-columns: 1fr; }
1352
+ .${s}-section { padding: var(--${s}-space-lg, 48px) 0; }
1353
+ .${s}-container { padding: 0 var(--${s}-space-sm, 16px); }
1354
+ h1 { font-size: 2rem; }
1355
+ h2 { font-size: 1.5rem; }
1356
+ h3 { font-size: 1.25rem; }
1357
+ }`;return{sharedCss:H+`
1358
+ `+z,sharedJs:`(function() {
1359
+ var observer = new IntersectionObserver(function(entries) {
1360
+ entries.forEach(function(entry) {
1361
+ if (entry.isIntersecting) {
1362
+ entry.target.classList.add('is-visible');
1363
+ observer.unobserve(entry.target);
1364
+ }
1365
+ });
1366
+ }, { threshold: 0.1 });
1367
+ document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
1368
+ })();`}}function el(e,t){return sl(e,t)}function tl(e,t){return sl(e,-t)}function sl(e,t){let n=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return n=Math.min(255,Math.max(0,Math.round(n+255*t))),s=Math.min(255,Math.max(0,Math.round(s+255*t))),o=Math.min(255,Math.max(0,Math.round(o+255*t))),`#${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${o.toString(16).padStart(2,"0")}`}function _m(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Pm(e,t,n){let s=new Set,o=[];for(let i of e){let a=_m(i.name);if(s.has(a)){let d=2;for(;s.has(`${a}-${d}`);)d++;a=`${a}-${d}`}s.add(a);let r=Nm(i.textContent),l=Mm(i,t,n),c=`Figma section "${i.name}" \u2014 ${i.width}x${i.height}px, ${i.textContent.length} text elements, ${i.children.length} children`;o.push({name:a,description:c,contentBrief:r,layoutNotes:l})}return{specs:o,moduleOrder:o.map(i=>i.name)}}function Nm(e){let t={};for(let o of e){let i=o.role;t[i]||(t[i]=[]),t[i].push(o.text)}let n=[],s=["headline","subheadline","body","cta","label","caption"];for(let o of s)if(t[o])for(let i of t[o])n.push(`**${o}** (use as field default): "${i}"`);return n.join(`
1369
+ `)}function Mm(e,t,n){let s=[];if(s.push(`Dimensions: ${e.width}x${e.height}px`),e.backgroundColor&&s.push(`Background: ${e.backgroundColor}`),e.layoutMode&&s.push(`Layout: ${e.layoutMode}`),e.itemSpacing&&s.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&s.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`),e.children.length>0){s.push(`
1370
+ Children (${e.children.length}):`);for(let o of e.children){let i=` - ${o.type} "${o.name}" (${o.width}x${o.height})`;o.layoutMode&&(i+=` [${o.layoutMode}]`),o.childCount>0&&(i+=` [${o.childCount} children]`),o.characters&&(i+=` text: "${o.characters.slice(0,60)}"`),s.push(i)}}if(t.length>0){s.push(`
1371
+ Available image assets:`);for(let o of t){let i=nl(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
1372
+ `)}function Om(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
1373
+
1374
+ TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
1375
+ - Use the EXACT text content from the design as field default values
1376
+ - Match the colors, spacing, and layout from the design tokens in the shared CSS
1377
+ - Do NOT invent new content \u2014 every word comes from the Figma design
1378
+ - Reference the shared CSS custom properties (--${s}-*) for all styling
1379
+
1380
+ ### Responsive Requirements
1381
+ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
1382
+ - Use the shared utility classes (${s}-container, ${s}-grid, ${s}-section)
1383
+ - Add a \`@media (max-width: 767px)\` block in moduleCss for mobile overrides:
1384
+ - Stack horizontal layouts vertically (flex-direction: column)
1385
+ - Make multi-column grids single-column
1386
+ - Reduce font sizes for headings (scale down ~20-30%)
1387
+ - Reduce section padding (roughly halve large values)
1388
+ - Make images full-width (width: 100%)
1389
+ - Hide purely decorative elements if they break mobile layout
1390
+ - Add a \`@media (max-width: 1023px)\` block for tablet if the layout has 3+ columns
1391
+
1392
+ ## Section: "${e.name}" (${e.width}x${e.height}px)`),e.backgroundColor&&i.push(`Background: ${e.backgroundColor}`),(e.layoutMode||e.itemSpacing||e.paddingTop)&&(i.push(`
1393
+ ### Layout`),e.layoutMode&&i.push(`Direction: ${e.layoutMode}`),e.itemSpacing&&i.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&i.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`)),e.textContent.length>0){i.push(`
1394
+ ### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let a of e.textContent)i.push(`- **${a.role}** (${a.fontSize}px, weight ${a.fontWeight}): "${a.text}"`)}if(e.children.length>0){i.push(`
1395
+ ### Structure (${e.children.length} children)`);for(let a of e.children){let r=`- ${a.type} "${a.name}" (${a.width}x${a.height})`;a.layoutMode&&(r+=` layout: ${a.layoutMode}`),a.childCount>0&&(r+=`, ${a.childCount} children`),a.characters&&(r+=`
1396
+ text: "${a.characters.slice(0,100)}"`),i.push(r)}}if(n.length>0)if(o){i.push(`
1397
+ ### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let a of n){let r=nl(a.localPath);i.push(`- \`get_asset_url("${s}/assets/${r}")\` \u2014 ${a.name}`)}}else{i.push(`
1398
+ ### Images \u2014 USE IMAGE FIELDS WITH PLACEHOLDERS`),i.push('Do NOT use get_asset_url(). Instead, create "image" type fields in fields.json for each image.'),i.push('Set a descriptive default.src (e.g. "https://placehold.co/600x400?text=Hero+Image") and default.alt text.'),i.push("In the module HTML, use: {{ module.field_name.src }} and {{ module.field_name.alt }}"),i.push("This gives content editors full control to replace images in HubSpot.");for(let a of n)i.push(`- "${a.name}" \u2014 create an image field for this`)}return i.push(`
1399
+ ## Module Specification
1400
+ - **Name**: ${t.name}
1401
+ - **Description**: ${t.description}`),i.join(`
1402
+ `)}var il=L(()=>{"use strict";f();qe();ti();ni();si();ae()});var rl={};ke(rl,{buildPlanModePrompt:()=>Rm});function Rm(e,t,n,s,o){let i=Fm(o,!!t?.plan),a=[];return a.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
1403
+
1404
+ Plan mode is a DELIBERATION PHASE. Your job is to help the user articulate what they want to build BEFORE any code is generated. You do NOT write modules, HTML, or CSS in this mode. You ask questions, surface gaps, and maintain a living plan document.
1405
+
1406
+ ## Output structure
1407
+
1408
+ Every response has two parts:
1409
+
1410
+ 1. **Conversational reply** (shown in chat): friendly, brief acknowledgement of what's been said + your next question(s) or summary. Keep this part short \u2014 a few sentences. Do NOT paste the plan here.
1411
+
1412
+ 2. **Plan block** (always at the end of your response, even if minimal): a fenced markdown block tagged \`vibespot-plan\` containing the current draft plan. Format:
1413
+
1414
+ \`\`\`vibespot-plan
1415
+ # {Project Title}
1416
+
1417
+ ## Goal
1418
+ ...
1419
+
1420
+ ## Audience
1421
+ ...
1422
+
1423
+ ## Sections / Modules
1424
+ 1. **Hero** \u2014 purpose, headline, CTA
1425
+ 2. **Trust bar** \u2014 logos
1426
+ 3. ...
1427
+
1428
+ ## Brand & Tone
1429
+ ...
1430
+
1431
+ ## Open questions
1432
+ - [ ] ...
1433
+ \`\`\`
1434
+
1435
+ The plan accumulates across turns \u2014 never reset it, only refine. If sections are still unknown, mark them with TBD or list them in **Open questions**. The user reads this plan in a separate pane and refines it via chat or direct edits.
1436
+
1437
+ ## Optional: choice chips
1438
+
1439
+ When asking a question that has 2\u20136 discrete options, also emit a fenced \`vibespot-choices\` JSON block. The UI renders clickable chips that send the chosen value as the next message. Example:
1440
+
1441
+ \`\`\`vibespot-choices
1442
+ {"question": "What's the primary goal of this page?", "options": ["Lead capture", "Sign-ups", "Demo bookings", "Brand awareness"]}
1443
+ \`\`\`
1444
+
1445
+ Only emit choices when options are mutually exclusive and well-defined. Skip for open-ended questions.
1446
+
1447
+ Do NOT include an "Other" option. The chat input is always available below the chips for free-text answers \u2014 adding "Other" is redundant and creates a dead-end click for users.
1448
+
1449
+ ## Hard rules
1450
+
1451
+ - **NEVER emit \`vibespot-modules\` or any code generation block.** Generation only happens after the user explicitly approves the plan.
1452
+ - **NEVER skip the \`vibespot-plan\` block** \u2014 emit it on every response, even on the first turn (where it may be mostly TBDs).
1453
+ - Keep the conversational reply SHORT (2\u20135 sentences typical). The plan block carries the structured detail.
1454
+ - Ask AT MOST 2\u20133 questions per turn. Pick the highest-leverage gaps.
1455
+ - Never invent details the user hasn't given you. Use TBD markers or move unknowns to **Open questions**.
1456
+
1457
+ ## What to gather
1458
+
1459
+ Drive toward filling these gaps in priority order:
1460
+ 1. **Goal** \u2014 what should this page accomplish? (lead capture, sales, signup, info, etc.)
1461
+ 2. **Audience** \u2014 who is this for?
1462
+ 3. **Primary CTA** \u2014 the single most important action a visitor should take
1463
+ 4. **Sections / modules** \u2014 high-level page structure (hero, features, testimonials, pricing, FAQ, footer, etc.)
1464
+ 5. **Content** \u2014 actual copy, value props, social proof, key messages
1465
+ 6. **Brand voice and visual style** \u2014 formal/casual, palette preferences, reference sites
1466
+ 7. **Constraints** \u2014 must-haves, must-avoids, integrations needed`),t?.styleguide&&a.push(`## Available styleguide
1467
+
1468
+ The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
1469
+
1470
+ \`\`\`
1471
+ ${oi(t.styleguide,1500)}
1472
+ \`\`\``),t?.brandvoice&&a.push(`## Available brand voice
1473
+
1474
+ \`\`\`
1475
+ ${oi(t.brandvoice,1e3)}
1476
+ \`\`\``),t?.themeContext&&a.push(`## Theme context
1477
+
1478
+ \`\`\`
1479
+ ${oi(t.themeContext,1e3)}
1480
+ \`\`\``),n.length>0&&a.push(`## Existing modules in this theme
1481
+
1482
+ These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
1483
+
1484
+ ${n.map(r=>`- ${r}`).join(`
1485
+ `)}`),s.length>0&&a.push(`## Module library (reusable across templates)
1486
+
1487
+ These modules exist in other templates and could be reused here. Reference them by name in the plan if appropriate.
1488
+
1489
+ ${s.map(r=>`- **${r.name}** (used in: ${r.usedIn.join(", ")})`).join(`
1490
+ `)}`),t?.plan&&a.push(`## Current plan (continue refining)
1491
+
1492
+ The plan in progress so far. Build on it \u2014 preserve what's there, only update sections that are changing based on the user's latest message.
1493
+
1494
+ \`\`\`markdown
1495
+ ${t.plan}
1496
+ \`\`\``),a.push(`## Phase guidance for this turn
1497
+
1498
+ ${i}`),a.join(`
1499
+
1500
+ `)}function Fm(e,t){return e===0&&!t?"**Phase 1: UNDERSTAND.** This is the user's first message in plan mode. Acknowledge what they said, then ask 2\u20133 high-leverage questions to surface gaps. The plan block should be a skeleton with TBDs and an **Open questions** section. Do NOT propose specific sections or content yet \u2014 you don't know enough.":e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function oi(e,t){return e.length<=t?e:e.slice(0,t)+`
1501
+ ... [truncated]`}var al=L(()=>{"use strict";f()});var cl={};ke(cl,{applyPipelineResult:()=>At,handleAgenticGenerate:()=>Ms,handleFigmaImport:()=>$n,handleGenerate:()=>Jm,handleGenerateStream:()=>An,handlePlanModeStream:()=>ci,isGenerating:()=>Wt,isPlanModeActive:()=>di,resolveAgenticEngine:()=>Vt,setParseWarningCallback:()=>ai,shouldUseAgenticMode:()=>ui});import{execSync as ii}from"child_process";function ai(e){ri=e}function Wt(){return ct!==null}function kt(e){if(ct){let t=v();if(!t||t.id!==ct){T.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}Re("assistant",e),ua(e,ri||void 0),j()}async function An(e,t,n,s){let o=v();if(!o)throw new Error("No active session");ct=o.id;let a=s?.length?$s(s):void 0;try{let r=N(),l=r.aiEngine||li();switch(l){case"anthropic-api":case"api":{let c=be("anthropic-api",r);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await Sa(e,c,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,kt,a);break}case"claude-oauth":{await xa(e,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,kt,a);break}case"openai-api":{let c=be("openai-api",r);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await va(e,c,o.themeName,r.openaiApiModel||"gpt-4o",t,n,kt,a);break}case"gemini-api":{let c=be("gemini-api",r);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await wa(e,c,o.themeName,t,n,kt,a);break}case"claude-code":await Ca(e,o.themeName,t,n,kt,a);break;case"gemini-cli":await Wo("gemini",e,o.themeName,t,n,kt,a);break;case"codex-cli":await Wo("codex",e,o.themeName,t,n,kt,a);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{ct=null,ri=null}}function li(){let e=N();if(Le())return"claude-oauth";if(e.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(e.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(e.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return ii("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return ii("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return ii("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Jm(e){let t="";return await An(e,n=>{t+=n}),t}function ll(){let e=v(),t=xe(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder];return{modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,brandAssets:e.brandAssets?{...e.brandAssets}:void 0}}function Vt(e){let t=e.aiEngine||li();if(!Cn(t))throw new Error("Agentic pipeline is not available for this engine.");if(Gt(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Le())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=be(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-4o";break;case"gemini-api":s="gemini-2.5-flash";break;default:s=""}return{engine:t,apiKey:n,model:s}}async function Ms(e,t,n){let s=v();if(!s)throw new Error("No active session");let o=s.id;ct=o;try{let i=N(),{engine:a,apiKey:r,model:l}=Vt(i),c=i.agenticConcurrency||20,d=ll(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
1502
+
1503
+ Build the page according to this plan exactly. The user reviewed and approved it; do not deviate from its goal, audience, sections, or content unless the user message below explicitly requests changes.
1504
+
1505
+ ${u}
1506
+
1507
+ ---
1508
+
1509
+ ## User message
1510
+
1511
+ ${e}`);let g=n?.length?$s(n):void 0;if(g?.length)for(let S of g)S.type==="document"&&S.extractedText&&(m+=`
1226
1512
 
1227
1513
  ---
1228
1514
  [Attached document: ${S.originalName}]
1229
1515
  ${S.extractedText}`),S.type==="image"&&S.usage==="asset"&&S.assetPath&&(m+=`
1230
1516
 
1231
- [Uploaded image: ${S.originalName} \u2192 available as get_asset_url("${S.assetPath}")]`);let f=at(),h=new Set(d.modules.map(S=>S.moduleName)),y=f.filter(S=>!h.has(S.module.moduleName)).map(S=>({name:S.module.moduleName,usedIn:S.usedIn})),w=await Sa(m,d,a,r,l,c,t,y),x=v();if(!x||x.id!==o)throw $.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return w}finally{bt=null}}function Ro(e,t){Le({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Et(e.moduleOrder),rt("assistant",e.assistantMessage,t),L()}function jo(){let e=_(),t=e.aiEngine||Oo();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 Po,bt,fs=D(()=>{"use strict";g();Z();Se();cs();ve();So();Ke();Ao();va();Po=null;bt=null});var ws={};nt(ws,{collectThemeFiles:()=>il,extractDesignContext:()=>Lu});import{existsSync as Ss,readdirSync as vs,readFileSync as Fu}from"fs";import{join as Ge}from"path";import{spawn as Ju}from"child_process";async function ol(){return Jo||(Jo=(await import("@anthropic-ai/sdk")).default),Jo}function hn(e){try{return Fu(e,"utf-8")}catch{return""}}function il(e){let t=[],n=0;function s(r,l){if(!l.trim())return!0;let c=`
1517
+ [Uploaded image: ${S.originalName} \u2192 available as get_asset_url("${S.assetPath}")]`);let y=at(),h=new Set(d.modules.map(S=>S.moduleName)),b=y.filter(S=>!h.has(S.module.moduleName)).map(S=>({name:S.module.moduleName,usedIn:S.usedIn})),x=await Za(m,d,a,r,l,c,t,b),w=v();if(!w||w.id!==o)throw T.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return x}finally{ct=null}}async function $n(e,t,n,s){let o=v();if(!o)throw new Error("No active session");let i=o.id;ct=i;try{let{runFigmaConversion:a}=await Promise.resolve().then(()=>(il(),ol)),r=N(),{engine:l,apiKey:c,model:d}=Vt(r),u=r.agenticConcurrency||20,m=ll(),g=await a(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets),y=v();if(!y||y.id!==i)throw T.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{ct=null}}function At(e,t){oe({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Ke(e.moduleOrder),Re("assistant",e.assistantMessage,t),j()}async function ci(e,t,n){let s=v();if(!s)throw new Error("No active session");let o=N(),{engine:i,apiKey:a,model:r}=Vt(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(al(),rl)),Promise.resolve().then(()=>(qe(),Pa))]),d=s.messages.filter(S=>S.role==="assistant").length,u=s.modules.map(S=>S.moduleName),m=at(),g=new Set(u),y=m.filter(S=>!g.has(S.module.moduleName)).map(S=>({name:S.module.moduleName,usedIn:S.usedIn})),h=l(s.themeName,s.brandAssets,u,y,d),b=n?.length?$s(n):void 0,x=e;if(b?.length)for(let S of b)S.type==="document"&&S.extractedText&&(x+=`
1518
+
1519
+ ---
1520
+ [Attached document: ${S.originalName}]
1521
+ ${S.extractedText}`);let w=await c(i,a,r,{systemPrompt:h,messages:[{role:"user",content:x}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return w.type==="text"?w.text:JSON.stringify(w.data)}function di(){return!!N().planMode}function ui(){let e=N(),t=e.aiEngine||li();return Cn(t)?e.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:e.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var ri,ct,Tn=L(()=>{"use strict";f();Q();pe();As();ae();Vo();tt();Yo();Qa();ri=null;ct=null});var Ls={};ke(Ls,{collectThemeFiles:()=>Ql,extractDesignContext:()=>lp});import{existsSync as js,readdirSync as Ds,readFileSync as op}from"fs";import{join as Xe}from"path";import{spawn as ip}from"child_process";async function Zl(){return yi||(yi=(await import("@anthropic-ai/sdk")).default),yi}function _n(e){try{return op(e,"utf-8")}catch{return""}}function Ql(e){let t=[],n=0;function s(r,l){if(!l.trim())return!0;let c=`
1232
1522
  ### ${r}
1233
1523
  \`\`\`
1234
1524
  ${l}
1235
1525
  \`\`\`
1236
- `;return n+c.length>Du?!1:(t.push(c),n+=c.length,!0)}let o=hn(Ge(e,"theme.json"));o&&s("theme.json",o);let i=Ge(e,"css");if(Ss(i)){for(let r of vs(i).filter(l=>l.endsWith(".css")))if(!s(`css/${r}`,hn(Ge(i,r))))break}let a=Ge(e,"modules");if(Ss(a))for(let r of vs(a).filter(l=>l.endsWith(".module"))){let l=Ge(a,r),c=hn(Ge(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=Ge(a,r),c=hn(Ge(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=Ge(a,r),c=hn(Ge(l,"fields.json"));if(c&&!s(`modules/${r}/fields.json`,c))break}return t.join("")}function Hu(){if(!xs)try{xs=k(vn("extraction-prompt.md"))}catch{xs=""}return xs}function Do(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let a=Ju(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 Lu(e,t){t?.({status:"Collecting theme files..."});let n=il(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=Hu();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:
1237
- ${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 ol();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 ol();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}
1526
+ `;return n+c.length>rp?!1:(t.push(c),n+=c.length,!0)}let o=_n(Xe(e,"theme.json"));o&&s("theme.json",o);let i=Xe(e,"css");if(js(i)){for(let r of Ds(i).filter(l=>l.endsWith(".css")))if(!s(`css/${r}`,_n(Xe(i,r))))break}let a=Xe(e,"modules");if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"module.css"));if(c&&!s(`modules/${r}/module.css`,c))break}if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"module.html"));if(c&&!s(`modules/${r}/module.html`,c))break}if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"fields.json"));if(c&&!s(`modules/${r}/fields.json`,c))break}return t.join("")}function ap(){if(!Hs)try{Hs=I(Fn("extraction-prompt.md"))}catch{Hs=""}return Hs}function bi(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let a=ip(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 lp(e,t){t?.({status:"Collecting theme files..."});let n=Ql(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=ap();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:
1527
+ ${n}`;t?.({status:"Analyzing design patterns..."});let i=N(),a=i.aiEngine||"anthropic-api",r="";switch(a){case"anthropic-api":case"api":{let l=be("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Zl();r=(await new c({apiKey:l}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(m=>m.type==="text"?m.text:"").join("");break}case"claude-oauth":{let{getValidAccessToken:l,OAUTH_EXTRA_HEADERS:c,OAUTH_SYSTEM_PREFIX:d}=await Promise.resolve().then(()=>(tt(),so)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await Zl();r=(await new m({authToken:u,defaultHeaders:c}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:d},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(h=>h.type==="text"?h.text:"").join("");break}case"openai-api":{let l=be("openai-api");if(!l)throw new Error("OpenAI API key not configured. Open Settings to add one.");let c=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify({model:i.openaiApiModel||"gpt-4o",max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!c.ok)throw new Error(`OpenAI API error: ${c.status} ${await c.text()}`);r=(await c.json()).choices?.[0]?.message?.content||"";break}case"gemini-api":{let l=be("gemini-api");if(!l)throw new Error("Gemini API key not configured. Open Settings to add one.");let c=i.geminiApiModel||"gemini-2.5-flash",d=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${c}:generateContent?key=${l}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!d.ok)throw new Error(`Gemini API error: ${d.status} ${await d.text()}`);r=(await d.json()).candidates?.[0]?.content?.parts?.map(m=>m.text).join("")||"";break}case"claude-code":{let l=`${s}
1238
1528
 
1239
1529
  ## User Request
1240
- ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await Do("claude",c,l);break}case"gemini-cli":{let l=`${s}
1530
+ ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await bi("claude",c,l);break}case"gemini-cli":{let l=`${s}
1241
1531
 
1242
1532
  ## User Request
1243
- ${o}`;r=await Do("gemini",[],l);break}case"codex-cli":{let l=`${s}
1533
+ ${o}`;r=await bi("gemini",[],l);break}case"codex-cli":{let l=`${s}
1244
1534
 
1245
1535
  ## User Request
1246
- ${o}`;r=await Do("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,Du,xs,Cs=D(()=>{"use strict";g();Q();Z();Jo=null;Du=8e4;xs=""});var rl={};nt(rl,{extractBrandvoice:()=>Uu});async function Uu(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.
1536
+ ${o}`;r=await bi("codex",[],l);break}default:throw new Error(`Unknown AI engine: ${a}. Open Settings to configure one.`)}if(!r.trim())throw new Error("AI returned empty response.");return t?.({status:"Design extraction complete."}),r}var yi,rp,Hs,Bs=L(()=>{"use strict";f();te();Q();yi=null;rp=8e4;Hs=""});var ec={};ke(ec,{extractBrandvoice:()=>cp});async function cp(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.
1247
1537
 
1248
1538
  Return a markdown document with these sections (skip any section where the content provides no signal):
1249
1539
 
@@ -1263,7 +1553,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
1263
1553
  ## Dos and Don'ts
1264
1554
  3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
1265
1555
 
1266
- 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:($.info("brandvoice-extractor",`Extracted brand voice (${a.length} chars)`),a.trim())}catch(i){let a=i instanceof Error?i.message:String(i);return $.warn("brandvoice-extractor",`Brand voice extraction failed: ${a}`),null}}var al=D(()=>{"use strict";g();ct();ve()});var Ho={};nt(Ho,{extractThemeContext:()=>Gu});async function Gu(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.
1556
+ Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Ce(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),a=i.type==="text"?i.text:JSON.stringify(i.data);return!a||a.trim().length<20?null:(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 tc=L(()=>{"use strict";f();qe();ae()});var Si={};ke(Si,{extractThemeContext:()=>dp});async function dp(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.
1267
1557
 
1268
1558
  Return a markdown document with these sections (skip any section where the content provides no information):
1269
1559
 
@@ -1285,74 +1575,39 @@ Specific terms, product names, or branded language used consistently.
1285
1575
  Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
1286
1576
 
1287
1577
  Existing product context (update if the new content adds info, keep what's still accurate):
1288
- ${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:($.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(r){let l=r instanceof Error?r.message:String(r);return $.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var Lo=D(()=>{"use strict";g();ct();ve()});g();g();import{Command as im}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"},Vo=!!process.env.NO_COLOR;function We(e){return Vo?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:Vo?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 ti,existsSync as $n,readdirSync as ql}from"fs";var mt=process.platform==="win32"?"where":"which";function Ut(){let e=E("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:E(`${mt} node`).stdout}}function Gt(){let e=E("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:E(`${mt} git`).stdout}}function je(){let e=E("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:E(`${mt} hs`).stdout}}function Bt(){let e=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=ql(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:E(`${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=ti(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 Fe(){let e=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(`
1289
- `);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=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:E(`${mt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function Kt(){let e=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=ti(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:E(`${mt} codex`).stdout,authenticated:s,authDetail:o}}function Rs(){let e=E("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
1290
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:E(`${mt} gh`).stdout}}function js(){let e=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 ni(){return!!process.env.ANTHROPIC_API_KEY}function En(e){return parseInt(e.split(".")[0],10)>=18}function si(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function Xl(){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=st();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=Ut(),n=Gt(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let x=je(),S=x.found?Fe():{authenticated:!1,portalName:"",portalId:"",accounts:[]},P=S.portalId?Wt(S.portalId):"na1";o={...x,...S,dataCenter:P,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...Xl()};let i=Rs(),a=i.found?js():{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(x,...S){if(x)return{configured:!0,masked:wn(x),source:"config"};for(let P of S)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"),w=[];return c.found&&c.authenticated&&w.push("claude-code"),r.authenticated&&w.push("claude-oauth"),f.configured&&w.push("anthropic-api"),h.configured&&w.push("openai-api"),d.found&&d.authenticated&&w.push("gemini-cli"),y.configured&&w.push("gemini-api"),u.found&&u.authenticated&&w.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:w,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 H(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=Ut();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)),H(`Node.js v${e.version}`);let t=Gt();t.found||(B("Git not found. Install it from https://git-scm.com"),process.exit(1)),H(`Git ${t.version}`);let n=_(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let w=he(),x=st();if(w)o=x?.portalId||"",i=x?.portalName||"",H(`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.
1578
+ ${t}`:""}`;try{let r=await Ce(n,s,o,{systemPrompt:a,messages:[{role:"user",content:e}],maxTokens:1e3}),l=r.type==="text"?r.text:JSON.stringify(r.data);return!l||l.trim().length<20?null:(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 xi=L(()=>{"use strict";f();qe();ae()});import{writeFileSync as hp,mkdirSync as Ac}from"fs";import{join as Gs}from"path";import{randomUUID as yp}from"crypto";function $c(e){let t=e.match(bp);if(!t)return null;let n=t[1],s=t[2]?decodeURIComponent(t[2].replace(/-/g," ")):void 0,o;try{let a=new URL(e).searchParams.get("node-id");a&&(o=a.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function Vs(e,t){let n=await fetch(`${Sp}${e}`,{headers:{"X-Figma-Token":t}});if(!n.ok){let s=await n.text().catch(()=>""),o=new Error(`Figma API ${n.status}: ${s.slice(0,200)}`);throw o.status=n.status,o}return n.json()}async function Ci(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=kc.length)throw s;let a=kc[n];T.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${a}s`),t&&t(`Figma rate limited \u2014 retrying in ${a}s...`),await new Promise(r=>setTimeout(r,a*1e3))}}function Tt(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)Tt(s,t,n+1)}function Tc(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=Tc(n,t);if(s)return s}return null}function xp(e,t){if(t){let s=Tc(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>wi.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>wi.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>wi.has(s.type)):[]}function Ws(e){let t=Math.round(e.r*255),n=Math.round(e.g*255),s=Math.round(e.b*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}`}function vp(e){let t=new Map;for(let n of e)Tt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=Ws(o.color),a=t.get(i),r=s.type==="TEXT",l=r?"text":"fill";a?(a.occurrences++,r&&a.usage!=="text"&&(a.usage="text")):t.set(i,{hex:i,opacity:o.opacity??o.color.a,occurrences:1,usage:l})}}if(s.strokes){for(let o of s.strokes)if(o.type==="SOLID"&&o.color){let i=Ws(o.color),a=t.get(i);a?a.occurrences++:t.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function wp(e){let t=new Map;for(let n of e)Tt(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,a=o.fontWeight||400,r=o.lineHeightPx?Math.round(o.lineHeightPx/i*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";i>=32?d="heading":i>=20?d="subheading":i<=12?d="caption":a>=600&&i<=14&&(d="label");let u=`${c}-${i}-${a}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:a,lineHeight:r,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function Cp(e){let t=[],n=new Set;for(let s of e)Tt(s,o=>{if(!o.layoutMode||o.layoutMode==="NONE")return;if(o.itemSpacing&&o.itemSpacing>0){let c=`gap-${o.itemSpacing}-${o.name}`;n.has(c)||(n.add(c),t.push({context:`${o.name} gap`,value:o.itemSpacing,type:"gap"}))}let i=o.paddingTop||0,a=o.paddingRight||0,r=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||a>0||r>0||l>0){let c=`pad-${i}-${a}-${r}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===r&&l===a&&i===l?i:Math.max(i,a,r,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function kp(e){let t=[],n=new Set;for(let s of e)Tt(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r:a,g:r,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(a*255)},${Math.round(r*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let i=`${o.cornerRadius}px`;n.has(`radius-${i}`)||(n.add(`radius-${i}`),t.push({type:"radius",cssValue:i,context:o.name}))}});return t}function Ap(e,t){let n=[];return Tt(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,a="body";o>=32?a="headline":o>=20?a="subheadline":o<=12?a="caption":i>=600&&o<=16&&(a="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(a="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:a,sectionName:t})}),n}function $p(e){let t=e.absoluteBoundingBox;return{name:e.name,type:e.type,nodeId:e.id,width:t?.width||0,height:t?.height||0,layoutMode:e.layoutMode==="NONE"?void 0:e.layoutMode,childCount:e.children?.length||0,characters:e.type==="TEXT"?e.characters:void 0}}function Tp(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Ws(t.color)}if(e.backgroundColor)return Ws(e.backgroundColor)}function Ip(e){return e.map(t=>{let n=t.absoluteBoundingBox;return{name:t.name,nodeId:t.id,width:n?.width||0,height:n?.height||0,textContent:Ap(t,t.name),children:(t.children||[]).slice(0,20).map($p),backgroundColor:Tp(t),layoutMode:t.layoutMode==="NONE"?void 0:t.layoutMode,itemSpacing:t.itemSpacing,paddingTop:t.paddingTop,paddingRight:t.paddingRight,paddingBottom:t.paddingBottom,paddingLeft:t.paddingLeft}})}function Ep(e){let t=[];for(let n of e)Tt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="IMAGE"&&o.imageRef){t.push({nodeId:s.id,name:s.name||"image"});break}}});return t}async function Ic(e,t){let n=await fetch(e);if(!n.ok)throw new Error(`Failed to download image: ${n.status}`);let s=Buffer.from(await n.arrayBuffer());hp(t,s)}async function _p(e,t,n,s,o){if(t.length===0)return new Map;Ac(s,{recursive:!0});let a=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let r=await Ci(()=>Vs(`/v1/images/${e}?ids=${a}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(r.images)){if(!d)continue;let u=c.replace(/:/g,"-"),m=Gs(s,`frame-${u}.png`);try{await Ic(d,m),l.set(c,m),T.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){T.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function Pp(e,t,n,s,o){if(t.length===0)return[];Ac(s,{recursive:!0});let i=50,a=[];for(let r=0;r<t.length;r+=i){let l=t.slice(r,r+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${r+1}-${Math.min(r+i,t.length)} of ${t.length})...`);let d=await Ci(()=>Vs(`/v1/images/${e}?ids=${c}&format=png&scale=2`,n),o);for(let u of l){let m=d.images[u.nodeId];if(!m)continue;let y=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${yp().slice(0,6)}.png`,h=Gs(s,y);try{await Ic(m,h),a.push({name:u.name,localPath:h,nodeId:u.nodeId,format:"png"}),T.info("figma",`Downloaded asset: ${y}`)}catch(b){T.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return a}async function Ec(e,t,n,s,o){o&&o("Fetching Figma file...");let i=t?`/v1/files/${e}?ids=${t}&geometry=paths`:`/v1/files/${e}?geometry=paths`,a=await Ci(()=>Vs(i,n),o);T.info("figma",`Fetched file: ${a.name}`);let r=xp(a.document,t);if(r.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");T.info("figma",`Found ${r.length} top-level frames`),o&&o(`Found ${r.length} sections. Extracting design tokens...`);let l={colors:vp(r),typography:wp(r),spacing:Cp(r),effects:kp(r)};T.info("figma","Design tokens extracted",{colors:l.colors.length,typography:l.typography.length,spacing:l.spacing.length,effects:l.effects.length}),o&&o("Mapping page structure...");let c=Ip(r),d=Gs(s,".vibespot","figma-frames"),u=await _p(e,r,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=Ep(r),y=Gs(s,"assets"),h=await Pp(e,g,n,y,o);return T.info("figma",`Extraction complete: ${m.length} sections, ${h.length} assets`),{fileName:a.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:h}}function _c(e){let t=e.fileName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,30);return{fileName:e.fileName,fileUrl:e.fileUrl,sectionNames:e.sections.map(n=>n.name),sectionCount:e.sections.length,colorPalette:e.designTokens.colors.slice(0,10).map(n=>n.hex),fontFamilies:[...new Set(e.designTokens.typography.map(n=>n.fontFamily))],textBlockCount:e.sections.reduce((n,s)=>n+s.textContent.length,0),assetCount:e.assets.length,suggestedThemeName:t}}async function Pc(e){return await Vs("/v1/me",e)}var bp,Sp,kc,wi,Nc=L(()=>{"use strict";f();ae();bp=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;Sp="https://api.figma.com",kc=[10,20,40,60,120];wi=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var jc={};ke(jc,{getCachedExtraction:()=>Jc,handleFigmaExtractRoute:()=>Ai,handleFigmaGenerateRoute:()=>$i,handleFigmaTestTokenRoute:()=>ki});import{randomUUID as Mc}from"crypto";import{existsSync as Oc,mkdirSync as Rc,writeFileSync as Np,copyFileSync as Mp}from"fs";import{join as Ks,basename as Op}from"path";function Fc(){let e=Date.now();for(let[t,n]of Pn)n.expires<e&&Pn.delete(t)}function Jc(e){Fc();let t=Pn.get(e);return t?(Pn.delete(e),t.extraction):null}function ki(e,t){Ye(e,t,async n=>{let s=n.token||N().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Pc(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);T.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function Ai(e,t){Ye(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||N().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=$c(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let r=v()?.themePath||`/tmp/vibespot-figma-${Mc().slice(0,8)}`;t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
1579
+
1580
+ `)};try{let c=await Ec(i.fileKey,i.nodeId,o,r,m=>l({type:"progress",message:m})),d=Mc();Fc(),Pn.set(d,{extraction:c,expires:Date.now()+Rp});let u=_c(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);T.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function Fp(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((r,l)=>l.count-r.count),i=o[0],a=o[1];i&&s.push(`- **Primary:** \`${i.hex}\` (${i.name||"dominant color"})`),a&&s.push(`- **Secondary:** \`${a.hex}\` (${a.name||"accent color"})`),s.push(""),s.push("### Full palette","");for(let r of o.slice(0,15)){let l=r.name?`${r.name}`:`${r.count}\xD7 used`;s.push(`- \`${r.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(a=>a.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let i=new Set;for(let a of t.typography){let r=`${a.role}-${a.fontSize}-${a.fontWeight}`;i.has(r)||(i.add(r),s.push(`| ${a.role} | ${a.fontFamily} | ${a.fontSize}px | ${a.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(i=>i.value))].sort((i,a)=>i-a);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let i of t.spacing)s.push(`- **${i.property}** (${i.context}): ${i.value}px`);s.push("")}if(t.effects.length>0){s.push("## Effects","");for(let o of t.effects)o.boxShadow&&s.push(`- **Box shadow:** \`${o.boxShadow}\``),o.borderRadius&&s.push(`- **Border radius:** ${o.borderRadius}px`);s.push("")}return s.join(`
1581
+ `)}function $i(e,t){Ye(e,t,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(t,400,{error:"Missing extractionId or themeName"});return}let a=Jc(s);if(!a){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let r=v();if(!r){p(t,400,{error:"No active session. Create a theme first."});return}t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
1582
+
1583
+ `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=Fp(a),d=Ks(r.themePath,".vibespot");if(Oc(d)||Rc(d,{recursive:!0}),Np(Ks(d,"styleguide.md"),c),r.brandAssets||(r.brandAssets={}),r.brandAssets.styleguide=c,j(),l({type:"progress",message:"Styleguide saved."}),r.templates.length===0)ys("landing_page","Landing Page");else{r.modules=[],r.moduleOrder=[],r.sharedCss="",r.sharedJs="";let h=r.templates.find(b=>b.id===r.activeTemplateId);h&&(h.modules=[],h.moduleOrder=[],h.sharedCss="",h.sharedJs="")}if(j(),i&&a.assets.length>0){let h=Ks(r.themePath,"assets");Rc(h,{recursive:!0});let b=0;for(let x of a.assets)if(Oc(x.localPath)){let w=Ks(h,Op(x.localPath));try{Mp(x.localPath,w),x.localPath=w,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],g=await $n(a,o,h=>{if(h.type==="agent_step")u.push({step:h.step,label:h.label}),l({type:"progress",message:`${h.label}...`});else if(h.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(h.decision)),l({type:"progress",message:` ${h.decision}`})}else h.type==="design_system_ready"?oe({sharedCss:h.sharedCss,sharedJs:h.sharedJs}):h.type==="blueprint_ready"?(oe({sharedCss:h.sharedCss,sharedJs:h.sharedJs}),Ke(h.moduleOrder),l({type:"progress",message:`Planned ${h.moduleOrder.length} modules`})):h.type==="module_progress"&&(h.status==="generating"?l({type:"progress",message:`Generating module: ${h.module}`}):h.status==="complete"&&h.moduleFiles?(oe({modules:[{moduleName:h.module,fieldsJson:h.moduleFiles.fieldsJson,metaJson:h.moduleFiles.metaJson,moduleHtml:h.moduleFiles.moduleHtml,moduleCss:h.moduleFiles.moduleCss,moduleJs:h.moduleFiles.moduleJs}]}),m.push({name:h.module,status:"complete"}),l({type:"progress",message:`Module complete: ${h.module}`})):h.status==="failed"&&(m.push({name:h.module,status:"failed"}),l({type:"progress",message:`Module failed: ${h.module}`})))},{useAssets:i});At(g,{steps:u,modules:m,stats:g.stats}),_e(),St(r.themePath,`Figma import: ${a.fileName}`);let y=X().map(h=>h.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${y.length} modules generated`}),l({type:"complete",ok:!0,modules:y})}catch(c){let d=c instanceof Error?c.message:String(c);T.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Pn,Rp,Ti=L(()=>{"use strict";f();Fe();Q();ae();Nc();pe();pn();Io();jt();Tn();Dt();Pn=new Map,Rp=1800*1e3});f();f();import{Command as Kp}from"commander";f();f();f();import Et from"chalk";var De={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Pi=!!process.env.NO_COLOR;function Qe(e){return Pi?Et:Et.hex(e)}var _={accent:Qe(De.accent),accentBright:Qe(De.accentBright),success:Qe(De.success),info:Qe(De.info),warn:Qe(De.warn),error:Qe(De.error),muted:Qe(De.muted),vibes:Qe(De.vibes),heading:Pi?Et.bold:Et.bold.hex(De.accent),command:Qe(De.accentBright),dim:Et.dim,bold:Et.bold};te();function He(){let e=_.vibes,t=_.accent,n=_.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${_.dim(`v${Pt()}`)}`),console.log()}f();f();ht();Q();tt();import{join as Bn}from"path";import{homedir as Un}from"os";import{readFileSync as Hi,existsSync as Gn,readdirSync as id}from"fs";var yt=process.platform==="win32"?"where":"which";function en(){let e=F("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:F(`${yt} node`).stdout}}function tn(){let e=F("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:F(`${yt} git`).stdout}}function Be(){let e=F("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:F(`${yt} hs`).stdout}}function nn(){let e=F("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Bn(Un(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Gn(t)){let o=id(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:F(`${yt} claude`).stdout,authenticated:n,authDetail:s}}function sn(e){try{let t=Bn(Un(),".hscli","config.yml");if(!Gn(t))return"na1";let n=Hi(t,"utf-8"),s=n.indexOf(`accountId: ${e}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let a=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!a)return"na1";if(a[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function Ue(){let e=F("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(`
1584
+ `);for(let a of i){let r=a.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(r&&!/Account ID/i.test(a)&&!/^-+$/.test(a.trim())&&!/^Name\s/i.test(a.trim())){let l=r[1].trim(),c=r[2].trim(),d=r[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function on(){let e=F("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Bn(Un(),".config","gcloud","application_default_credentials.json"),n=Gn(t),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:e.stdout,path:F(`${yt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function rn(){let e=F("codex --version");if(!e.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=!!process.env.OPENAI_API_KEY,n=!1;try{let i=Bn(Un(),".codex","auth.json");Gn(i)&&(n=Hi(i,"utf-8").length>10)}catch{}let s=t||n,o=n?"Authenticated (OAuth)":t?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:e.stdout,path:F(`${yt} codex`).stdout,authenticated:s,authDetail:o}}function io(){let e=F("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
1585
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:F(`${yt} gh`).stdout}}function ro(){let e=F("gh auth status 2>&1");if(!e.success&&!e.stdout)return{authenticated:!1,username:""};let t=e.stdout||e.stderr||"",n=t.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=t.match(/account\s+(\S+)/);return s&&t.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:t.includes("Logged in"),username:""}}function Li(){return!!process.env.ANTHROPIC_API_KEY}function Wn(e){return parseInt(e.split(".")[0],10)>=18}function Bi(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function rd(){let e=N(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=ut();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}var oo={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function Vn(){let e=N(),t=en(),n=tn(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let x=Be(),w=x.found?Ue():{authenticated:!1,portalName:"",portalId:"",accounts:[]},S=w.portalId?sn(w.portalId):"na1";o={...x,...w,dataCenter:S,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...rd()};let i=io(),a=i.found?ro():{authenticated:!1,username:""},r={authenticated:Le(),expiresAt:Qt()?.expiresAt},l=e.enabledCLITools||[],c=Xt("claude-code")?nn():{...oo,name:"Claude Code"},d=Xt("gemini-cli")?on():{...oo,name:"Gemini CLI"},u=Xt("codex-cli")?rn():{...oo,name:"OpenAI Codex CLI"};function m(x,...w){if(x)return{configured:!0,masked:jn(x),source:"config"};for(let S of w)if(process.env[S])return{configured:!0,masked:jn(process.env[S]),source:"env"};return{configured:!1,masked:"",source:null}}let g=m(e.anthropicApiKey,"ANTHROPIC_API_KEY"),y=m(e.openaiApiKey,"OPENAI_API_KEY"),h=m(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),b=[];return c.found&&c.authenticated&&b.push("claude-code"),r.authenticated&&b.push("claude-oauth"),g.configured&&b.push("anthropic-api"),y.configured&&b.push("openai-api"),d.found&&d.authenticated&&b.push("gemini-cli"),h.configured&&b.push("gemini-api"),u.found&&u.authenticated&&b.push("codex-cli"),{tools:{node:t,git:n,hubspot:o,github:{...i,...a},claudeCode:c,claudeOAuth:r,geminiCli:d,codexCli:u},apiKeys:{anthropic:g,openai:y,gemini:h},activeEngine:e.aiEngine||null,availableEngines:b,enabledCLITools:l}}tt();ht();Q();bt();f();import*as Y from"@clack/prompts";function lo(e){Y.isCancel(e)&&(Y.cancel(_.muted("Operation cancelled.")),process.exit(0))}async function ge(e){Y.intro(_.heading(e))}async function fe(e){Y.outro(_.success(e))}async function Ge(e,t){Y.note(e,t?_.heading(t):void 0)}async function Pe(e){let t=await Y.text({message:_.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return lo(t),t}async function le(e){let t=await Y.confirm({message:_.accent(e.message),initialValue:e.initialValue??!0});return lo(t),t}async function Rt(e){let t=await Y.select({message:_.accent(e.message),options:e.options});return lo(t),t}async function he(){let e=Y.spinner();return{start:t=>e.start(_.muted(t)),stop:t=>e.stop(_.success(t)),message:t=>e.message(_.muted(t))}}function ne(e){Y.log.info(e)}function U(e){Y.log.success(_.success(e))}function q(e){Y.log.warn(_.warn(e))}function V(e){Y.log.error(_.error(e))}async function qn(){await ge("Checking your environment");let e=en();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Wn(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),U(`Node.js v${e.version}`);let t=tn();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),U(`Git ${t.version}`);let n=N(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Se(),x=ut();if(b)o=x?.portalId||"",i=x?.portalName||"",U(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{q("No HubSpot account connected"),await Ge(`You need a Personal Access Key to deploy themes.
1291
1586
  Create one at: https://app.hubspot.com/l/personal-access-key
1292
- Make sure the Content scope is enabled.`,"HubSpot connection required");let S=await Te({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:j=>j.trim()?void 0:"Key is required"}),P=await ue();P.start("Validating key...");try{let j=await Mn(S);Jt(S,j.portalId,j.portalName,j.dataCenter),w=S,o=j.portalId,i=j.portalName,P.stop(`Connected to ${j.portalName} (${j.portalId})`)}catch(j){P.stop("Validation failed"),B(`Invalid key: ${j instanceof Error?j.message:String(j)}`),process.exit(1)}}}else{let w=je();if(w.found)H(`HubSpot CLI v${w.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..."),E("npm install -g @hubspot/cli").success||(P.stop("Failed"),B("Try: npm install -g @hubspot/cli"),process.exit(1)),w=je(),P.stop(`HubSpot CLI v${w.version} installed`)}let x=Fe();if(x.authenticated)H(`HubSpot portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.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..."),qo("hs init")||(P.stop("Authentication failed"),process.exit(1)),x=Fe(),P.stop(`Connected to portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`)}o=x.portalId,i=x.portalName}let a=Bt(),r=Vt(),l=Kt(),c=ni(),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((w,x)=>w.value===f?-1:x.value===f?1:0),h.length===1)m=h[0].value,H(`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.
1587
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let w=await Pe({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:M=>M.trim()?void 0:"Key is required"}),S=await he();S.start("Validating key...");try{let M=await zn(w);qt(w,M.portalId,M.portalName,M.dataCenter),b=w,o=M.portalId,i=M.portalName,S.stop(`Connected to ${M.portalName} (${M.portalId})`)}catch(M){S.stop("Validation failed"),V(`Invalid key: ${M instanceof Error?M.message:String(M)}`),process.exit(1)}}}else{let b=Be();if(b.found)U(`HubSpot CLI v${b.version}`);else{q("HubSpot CLI not found"),await le({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let S=await he();S.start("Installing HubSpot CLI..."),F("npm install -g @hubspot/cli").success||(S.stop("Failed"),V("Try: npm install -g @hubspot/cli"),process.exit(1)),b=Be(),S.stop(`HubSpot CLI v${b.version} installed`)}let x=Ue();if(x.authenticated)U(`HubSpot portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`);else{q("HubSpot not authenticated"),await le({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let S=await he();S.start("Waiting for HubSpot authentication..."),Ri("hs init")||(S.stop("Authentication failed"),process.exit(1)),x=Ue(),S.stop(`Connected to portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`)}o=x.portalId,i=x.portalName}let a=nn(),r=on(),l=rn(),c=Li(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"},u=Le(),m,g=n.aiEngine,y=[];if(a.found&&y.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&y.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),r.found&&y.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&y.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&y.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&y.sort((b,x)=>b.value===g?-1:x.value===g?1:0),y.length===1)m=y[0].value,U(`AI engine: ${d[m]} (auto-detected)`);else if(y.length>1)m=await Rt({message:"Choose your AI engine:",options:y});else if(await Ge(`You need an AI coding assistant to power the conversion.
1293
1588
 
1294
- ${I.bold("Option 1:")} Install Claude Code ${I.muted("(recommended)")}
1589
+ ${_.bold("Option 1:")} Install Claude Code ${_.muted("(recommended)")}
1295
1590
  https://claude.ai/code
1296
1591
 
1297
- ${I.bold("Option 2:")} Install Gemini CLI
1592
+ ${_.bold("Option 2:")} Install Gemini CLI
1298
1593
  https://github.com/google-gemini/gemini-cli
1299
1594
 
1300
- ${I.bold("Option 3:")} Install OpenAI Codex
1595
+ ${_.bold("Option 3:")} Install OpenAI Codex
1301
1596
  https://github.com/openai/codex
1302
1597
 
1303
- ${I.bold("Option 4:")} Set an Anthropic API key
1598
+ ${_.bold("Option 4:")} Set an Anthropic API key
1304
1599
  export ANTHROPIC_API_KEY=sk-ant-...
1305
- (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 w=await Te({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:x=>x.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=w,K({anthropicApiKey:w})}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 ic}from"fs";import{join as te,basename as Hs,extname as rc}from"path";function ci(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(!ic(a).isFile())continue;let l=rc(i);if(![".tsx",".jsx"].includes(l))continue;let c=Hs(i,l);if(c.startsWith("ui")||c==="index")continue;let d=k(a),u=ac(c,d);t.push({name:c,path:a,description:u})}}catch{}return t}function ac(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 di(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=k(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 ui(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=k(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 mi(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=E(`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=ci(t),o=b(te(t,"tailwind.config.ts"))||b(te(t,"tailwind.config.js")),{varCount:i,fonts:a}=di(t),r=ui(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))H(`Using existing clone: ${I.dim(t)}`);else{let y=await ue();y.start("Cloning repository..."),E(`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)),H(`Using local source: ${I.dim(t)}`);let s=await ue();s.start("Analyzing project structure...");let o=ci(t),i=b(te(t,"tailwind.config.ts"))||b(te(t,"tailwind.config.js")),{varCount:a,fonts:r}=di(t),l=ui(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(`
1306
- `),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}
1600
+ (get one at https://console.anthropic.com)`,"AI engine required"),m=await Rt({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),m==="api"){let b=await Pe({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:x=>x.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,W({anthropicApiKey:b})}let h;return m==="claude-code"&&(h=await Rt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),W({aiEngine:m}),await fe("Environment ready!"),{aiEngine:m,model:h,portalId:o,portalName:i}}f();ht();te();import{readdirSync as co,statSync as gd}from"fs";import{join as se,basename as uo,extname as fd}from"path";function zi(e){let t=[],n=[se(e,"src/components/landing"),se(e,"src/components/sections"),se(e,"src/components"),se(e,"src/pages"),se(e,"app/components"),se(e,"components")];for(let s of n)if(C(s))try{let o=co(s);for(let i of o){let a=se(s,i);if(!gd(a).isFile())continue;let l=fd(i);if(![".tsx",".jsx"].includes(l))continue;let c=uo(i,l);if(c.startsWith("ui")||c==="index")continue;let d=I(a),u=hd(c,d);t.push({name:c,path:a,description:u})}}catch{}return t}function hd(e,t){let n=[];return/carousel|slider|swiper|embla/i.test(t)&&n.push("carousel"),/accordion|collapsible|expand/i.test(t)&&n.push("accordion"),/form|submit|input.*email/i.test(t)&&n.push("form"),/nav|navigation|menu/i.test(t)&&n.push("navigation"),/hero|headline|tagline/i.test(t)&&n.push("hero"),/footer|copyright/i.test(t)&&n.push("footer"),/testimonial|quote|review/i.test(t)&&n.push("testimonials"),/pricing|plan|tier/i.test(t)&&n.push("pricing"),/faq|question.*answer/i.test(t)&&n.push("FAQ"),/feature|benefit|advantage/i.test(t)&&n.push("features"),/contact|get.in.touch/i.test(t)&&n.push("contact"),/cta|call.to.action/i.test(t)&&n.push("CTA"),/team|member|bio/i.test(t)&&n.push("team"),n.length===0?e.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function Yi(e){let t=[se(e,"src/index.css"),se(e,"src/globals.css"),se(e,"src/app/globals.css"),se(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!C(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 qi(e){let t=[],n=se(e,"src/hooks");if(C(n))try{let o=co(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=se(e,"src/components/landing");if(C(s))try{let o=co(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let a=I(se(s,i));/carousel|embla|swiper/i.test(a)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(a)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(a)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(a)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function Xi(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let l=uo(e.replace(/\.git$/,""))||"react-source";if(t=se(process.cwd(),"workspace",l),!C(t)){let c=F(`git clone --depth 1 "${e}" "${t}"`);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!C(t))throw new Error(`Directory not found: ${t}`);let s=zi(t),o=C(se(t,"tailwind.config.ts"))||C(se(t,"tailwind.config.js")),{varCount:i,fonts:a}=Yi(t),r=qi(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:a,interactions:r}}async function Xn(){await ge("Source Project");let e=await Pe({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:y=>{if(!y.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let y=uo(e.replace(/\.git$/,""))||"react-source";if(t=se(process.cwd(),"workspace",y),C(t))U(`Using existing clone: ${_.dim(t)}`);else{let h=await he();h.start("Cloning repository..."),F(`git clone --depth 1 "${e}" "${t}"`).success||(h.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),h.stop(`Cloned to ${_.dim(t)}`)}}else t=e,C(t)||(V(`Directory not found: ${t}`),process.exit(1)),U(`Using local source: ${_.dim(t)}`);let s=await he();s.start("Analyzing project structure...");let o=zi(t),i=C(se(t,"tailwind.config.ts"))||C(se(t,"tailwind.config.js")),{varCount:a,fonts:r}=Yi(t),l=qi(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(q("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((y,h)=>` ${_.dim(`${h+1}.`)} ${_.bold(y.name)} ${_.muted(`\u2014 ${y.description}`)}`).join(`
1601
+ `),d=i?`Tailwind + custom CSS (${a} variables)`:`Custom CSS (${a} variables)`,u=r.length>0?r.join(", "):"System fonts",m=l.join(", ");return await Ge(`${c}
1307
1602
 
1308
1603
  CSS: ${d}
1309
1604
  JS: ${m}
1310
- 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 ot,writeFileSync as jn}from"fs";import{join as $e}from"path";function Fn(e,t){ot(e,{recursive:!0}),ot($e(e,"templates"),{recursive:!0}),ot($e(e,"modules"),{recursive:!0}),ot($e(e,"css"),{recursive:!0}),ot($e(e,"js"),{recursive:!0}),ot($e(e,"images"),{recursive:!0}),ot($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"}};jn($e(e,"theme.json"),JSON.stringify(n,null,2)+`
1311
- `),jn($e(e,"fields.json"),`[]
1312
- `);let s=`<!--
1313
- templateType: page
1314
- isAvailableForNewContent: false
1315
- label: ${t} (placeholder)
1316
- screenshotPath: ../images/template-previews/home.png
1317
- -->
1318
- {% extends "./layouts/base.html" %}
1319
-
1320
- {% block body %}
1321
- {% dnd_area "main_content"
1322
- label="Main Content",
1323
- class="body-container body-container--${t}"
1324
- %}
1325
- {% end_dnd_area %}
1326
- {% endblock body %}
1327
- `;jn($e(e,"templates","home.html"),s);let o=`<!--
1328
- templateType: none
1329
- isAvailableForNewContent: false
1330
- label: Base Layout
1331
- -->
1332
- <!DOCTYPE html>
1333
- <html lang="{{ html_lang }}" {{ html_lang_dir }}>
1334
- <head>
1335
- <meta charset="utf-8">
1336
- <meta name="viewport" content="width=device-width, initial-scale=1">
1337
- {% if template_css %}
1338
- {{ require_css(get_asset_url(template_css)) }}
1339
- {% endif %}
1340
- {{ standard_header_includes }}
1341
- </head>
1342
- <body>
1343
- {% block body %}{% endblock body %}
1344
- {% if template_js %}
1345
- {{ require_js(get_asset_url(template_js)) }}
1346
- {% endif %}
1347
- {{ standard_footer_includes }}
1348
- </body>
1349
- </html>
1350
- `;ot($e(e,"templates","layouts"),{recursive:!0}),jn($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)E(`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{Fn(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)),H("base.html found");let i=k(o),a=!1;if(i.includes("template_css"))H("template_css support");else{z("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
1605
+ Font: ${u}`,`${o.length} components detected`),await le({message:"Does this look right?"})||(V("Please adjust your source directory and try again."),process.exit(0)),await fe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:a,fonts:r,interactions:l}}f();ht();te();import{join as un}from"path";Q();Qn();es();async function ts(){await ge("HubSpot Theme Setup");let e=await Rt({message:"Do you have an existing HubSpot theme?",options:[{value:"fetch",label:"Fetch my existing theme from HubSpot",hint:"downloads your current theme"},{value:"create",label:"Start fresh (HubSpot Boilerplate)",hint:"creates a new starter theme"}]}),t,n,s=un(process.cwd(),"workspace");if(Te(s),e==="fetch"){t=await Pe({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=un(s,t);let l=await he();l.start("Fetching theme from HubSpot...");let c=N(),d=Se();if(c.hubspotUploadMode==="cli"||!d)F(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),V(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await dn(d,t,n)}catch(u){l.stop("Fetch failed"),V(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${_.dim(n)}`)}else{t=await Pe({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=un(s,t);let l=await he();l.start("Creating theme...");try{cn(n,t)}catch(c){l.stop("Creation failed"),V(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${_.dim(n)}`)}await ge("Checking theme compatibility");let o=un(n,"templates/layouts/base.html");C(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),U("base.html found");let i=I(o),a=!1;if(i.includes("template_css"))U("template_css support");else{q("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
1351
1606
  `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
1352
1607
  `,l);i=i.slice(0,c)+`
1353
1608
  {% if template_css %}
1354
1609
  {{ require_css(get_asset_url(template_css)) }}
1355
- {% endif %}`+i.slice(c),a=!0}}if(i.includes("template_js"))H("template_js support");else{z("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
1610
+ {% endif %}`+i.slice(c),a=!0}}if(i.includes("template_js"))U("template_js support");else{q("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
1356
1611
  `,l),d=i.indexOf(`
1357
1612
  `,c+1),u=`
1358
1613
  {% if template_js %}
@@ -1360,17 +1615,17 @@ ${I.bold("Option 4:")} Set an Anthropic API key
1360
1615
  {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
1361
1616
  `)+1;i=i.slice(0,i.indexOf(`
1362
1617
  `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
1363
- `,i.indexOf("}}",l)+2)),a=!0}}if(a){let l=await ue();l.start("Patching base.html..."),U(o,i),l.stop("base.html patched with template_css/template_js support")}let r=Xt(n,".hsignore");if(b(r)){let l=k(r);l.includes("docs/")||(U(r,l+`
1618
+ `,i.indexOf("}}",l)+2)),a=!0}}if(a){let l=await he();l.start("Patching base.html..."),G(o,i),l.stop("base.html patched with template_css/template_js support")}let r=un(n,".hsignore");if(C(r)){let l=I(r);l.includes("docs/")||(G(r,l+`
1364
1619
  docs/
1365
- `),H("Added docs/ to .hsignore"))}else U(r,`docs/
1620
+ `),U("Added docs/ to .hsignore"))}else G(r,`docs/
1366
1621
  *.md
1367
1622
  node_modules/
1368
1623
  .git
1369
- `),H("Created .hsignore");return await de("Theme ready!"),{themePath:n,themeName:t}}g();import{join as ke}from"path";import{readdirSync as Qt,rmSync as Ci}from"fs";g();qe();Q();import{spawn as mc}from"child_process";import{join as W,basename as pc}from"path";import{readdirSync as De,statSync as xi,writeFileSync as fc}from"fs";var gc=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(W(s,"css")),c=this.listDir(W(s,"js")),d=this.listDir(W(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((S,P)=>{let j={...process.env};delete j.CLAUDECODE;let G=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&G.push("--model",this.model);let T=mc("claude",G,{cwd:s,stdio:["pipe","pipe","pipe"],env:j,shell:!0});T.stdout.on("data",V=>{m+=V.toString()}),T.stderr.on("data",V=>{f+=V.toString()}),T.on("error",V=>P(new Error(`Claude Code failed to start: ${V.message}`))),T.on("close",V=>{V!==0?P(new Error(`Claude Code exited with code ${V}.
1370
- `+(f?`Stderr: ${f.slice(0,500)}
1371
- `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):S()}),T.stdin.on("error",()=>{}),T.stdin.write(u),T.stdin.end(),setTimeout(()=>{T.kill(),P(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let y=W(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)+`
1372
- ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",f||"(empty)",""].join(`
1373
- `);fc(y,P,"utf-8"),o("status",`Log written to ${pc(y)}`)}catch{}o("scan","Scanning generated files...");let w=this.scanGeneratedFiles(s);if(w.modules.filter(S=>!r.has(S.moduleName+".module")).length===0){let S=m.slice(0,1500)||"(no output)",P=f.slice(0,500);throw new Error(`Claude Code did not create any new module files.
1624
+ `),U("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}f();import{join as Ie}from"path";import{readdirSync as mn,rmSync as cr}from"fs";f();ot();te();import{spawn as vd}from"child_process";import{join as K,basename as wd}from"path";import{readdirSync as We,statSync as ar,writeFileSync as Cd}from"fs";var kd=new Set(["about.html","blog-index.html","blog-post.html","contact.html","home.html","hubdb.html","landing-page.html","pricing.html","qa-test.html","base.html"]),ns=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(t){this.model=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let a=this.countSourceComponents(n),r=this.listModules(s),l=this.listDir(K(s,"css")),c=this.listDir(K(s,"js")),d=this.listDir(K(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${a} source components found)...`);let m="",g="",y=setInterval(()=>{this.reportProgress(s,r,l,c,d,o)},3e3);try{await new Promise((w,S)=>{let M={...process.env};delete M.CLAUDECODE;let R=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&R.push("--model",this.model);let O=vd("claude",R,{cwd:s,stdio:["pipe","pipe","pipe"],env:M,shell:!0});O.stdout.on("data",H=>{m+=H.toString()}),O.stderr.on("data",H=>{g+=H.toString()}),O.on("error",H=>S(new Error(`Claude Code failed to start: ${H.message}`))),O.on("close",H=>{H!==0?S(new Error(`Claude Code exited with code ${H}.
1625
+ `+(g?`Stderr: ${g.slice(0,500)}
1626
+ `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):w()}),O.stdin.on("error",()=>{}),O.stdin.write(u),O.stdin.end(),setTimeout(()=>{O.kill(),S(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(y)}let h=K(s,"..","vibespot-conversion.log");try{let S=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
1627
+ ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
1628
+ `);Cd(h,S,"utf-8"),o("status",`Log written to ${wd(h)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(w=>!r.has(w.moduleName+".module")).length===0){let w=m.slice(0,1500)||"(no output)",S=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
1374
1629
 
1375
1630
  This usually means the model described the conversion instead of using Write tool to create files.
1376
1631
 
@@ -1381,12 +1636,12 @@ Possible causes:
1381
1636
 
1382
1637
  Source: ${t.sourceDir}
1383
1638
  Theme: ${s}
1384
- `+(P?`
1639
+ `+(S?`
1385
1640
  Stderr:
1386
- ${P}
1641
+ ${S}
1387
1642
  `:"")+`
1388
1643
  Claude output:
1389
- ${S}`)}return w}reportProgress(t,n,s,o,i,a){let r=0,l=this.listDir(W(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(W(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(W(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.
1644
+ ${w}`)}return b}reportProgress(t,n,s,o,i,a){let r=0,l=this.listDir(K(t,"css"));for(let m of l){if(s.has(m)||!m.endsWith(".css"))continue;let g=`css:${m}`;this.reported.has(g)||(this.reported.add(g),a("created",`Shared CSS (${m})`),r++)}let c=this.listDir(K(t,"js"));for(let m of c){if(o.has(m)||!m.endsWith(".js"))continue;let g=`js:${m}`;this.reported.has(g)||(this.reported.add(g),a("created",`Shared JS (${m})`),r++)}this.expectedModules===0&&(this.expectedModules=this.detectExpectedModules(t,i));let d=this.listModules(t);for(let m of d){if(n.has(m))continue;let g=`module:${m}`;if(!this.reported.has(g)){this.reported.add(g),this.moduleCount++;let y=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;a("created",`Module ${y}: ${m.replace(".module","")}`),r++}}let u=this.listDir(K(t,"templates"));for(let m of u){if(i.has(m)||!m.endsWith(".html"))continue;let g=`template:${m}`;this.reported.has(g)||(this.reported.add(g),a("created",`Page template (${m})`),r++)}if(r===0)if(this.moduleCount>0){let m=this.expectedModules>0?`/${this.expectedModules}`:"";a("status",`${this.moduleCount}${m} modules created, conversion continuing...`)}else this.reported.size>0?a("status","Shared assets created, building modules..."):a("status","Claude Code is analyzing source files...")}buildFullPrompt(t,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
1390
1645
 
1391
1646
  SOURCE DIRECTORY: ${t}
1392
1647
  THEME DIRECTORY: ${n}
@@ -1429,16 +1684,16 @@ CSS QUALITY: The converted page must visually match the original React page. Eve
1429
1684
  Do NOT run hs upload \u2014 I will handle that separately.
1430
1685
 
1431
1686
  HUBSPOT CMS RULES:
1432
- ${Ee()}
1687
+ ${Me()}
1433
1688
 
1434
1689
  CONVERSION GUIDE:
1435
- ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=W(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=k(W(s,r));break}}let o=W(t,"js");if(b(o)){for(let r of De(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=k(W(o,r));break}}let i=W(t,"templates");if(b(i)){for(let r of De(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=k(W(i,r));break}if(!n.template){for(let r of De(i))if(r.endsWith(".html")&&!gc.has(r)&&!r.startsWith("system")){let l=k(W(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=k(W(i,r));if(l.includes("dnd_area")){n.template=l;break}}}}let a=W(t,"modules");if(b(a))for(let r of De(a)){if(!r.endsWith(".module"))continue;let l=W(a,r);if(!xi(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=W(l,"fields.json");b(d)&&(c.fieldsJson=k(d));let u=W(l,"meta.json");b(u)&&(c.metaJson=k(u));let m=W(l,"module.html");b(m)&&(c.moduleHtml=k(m));let f=W(l,"module.css");b(f)&&(c.moduleCss=k(f));let h=W(l,"module.js");b(h)&&(c.moduleJs=k(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=W(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=W(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=k(W(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=W(t,"src");return b(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of De(t)){let o=W(t,s);try{xi(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 hc from"@anthropic-ai/sdk";import{join as q,basename as yc}from"path";import{readdirSync as wi}from"fs";var Ln=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new hc({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,a=hi(o),r=yc(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,bi(c,d,l)),m=q(s,"css",`${l}-theme.css`);U(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,Si(f,h,l)),w=q(s,"js",`${l}-animations.js`);U(w,y),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let x=this.findComponents(n),S=[];for(let T=0;T<x.length;T++){let V=x[T],N=V.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${N}.module (${T+1}/${x.length})...`);let O=k(V.path),J=await this.complete(a,yi(O,N,`See css/${l}-theme.css`));try{let F=JSON.parse(J),X={moduleName:N,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",`${N}.module`);Ae(le),U(q(le,"fields.json"),X.fieldsJson),U(q(le,"meta.json"),X.metaJson),U(q(le,"module.html"),X.moduleHtml),U(q(le,"module.css"),X.moduleCss),X.moduleJs&&U(q(le,"module.js"),X.moduleJs),S.push(X),i("module-done",`${N}.module (${this.countFiles(X)} files)`)}catch{i("module-error",`Failed to parse ${N} \u2014 skipping`)}}i("template","Creating page template...");let P=S.map(T=>T.moduleName),j=await this.complete(a,vi(P,r,l)),G=q(s,"templates",`lp-${l}.html`);return U(G,j),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:y,template:j,modules:S}}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 k(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 k(s);return""}findAndReadHooks(t){let n=q(t,"src/hooks");if(!b(n))return"";try{return wi(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
1436
- ${k(q(n,s))}`).join(`
1690
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=K(t,"css");if(C(s)){for(let r of We(s))if(r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(K(s,r));break}}let o=K(t,"js");if(C(o)){for(let r of We(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(K(o,r));break}}let i=K(t,"templates");if(C(i)){for(let r of We(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=I(K(i,r));break}if(!n.template){for(let r of We(i))if(r.endsWith(".html")&&!kd.has(r)&&!r.startsWith("system")){let l=I(K(i,r));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let r of We(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(K(i,r));if(l.includes("dnd_area")){n.template=l;break}}}}let a=K(t,"modules");if(C(a))for(let r of We(a)){if(!r.endsWith(".module"))continue;let l=K(a,r);if(!ar(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=K(l,"fields.json");C(d)&&(c.fieldsJson=I(d));let u=K(l,"meta.json");C(u)&&(c.metaJson=I(u));let m=K(l,"module.html");C(m)&&(c.moduleHtml=I(m));let g=K(l,"module.css");C(g)&&(c.moduleCss=I(g));let y=K(l,"module.js");C(y)&&(c.moduleJs=I(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=K(t,"modules");return C(n)?new Set(We(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return C(t)?new Set(We(t)):new Set}detectExpectedModules(t,n){let s=K(t,"templates");if(!C(s))return 0;for(let o of We(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=I(K(s,o));if(i.includes("dnd_area")){let a=i.match(/dnd_module/g);return a?a.length:0}}catch{}return 0}countSourceComponents(t){let n=K(t,"src");return C(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of We(t)){let o=K(t,s);try{ar(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};f();ot();te();import Ad from"@anthropic-ai/sdk";import{join as ee,basename as $d}from"path";import{readdirSync as lr}from"fs";var ss=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new Ad({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,a=nr(o),r=$d(n)||"page",l=r.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);i("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(a,or(c,d,l)),m=ee(s,"css",`${l}-theme.css`);G(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),y=this.findInteractiveComponents(n),h=await this.complete(a,ir(g,y,l)),b=ee(s,"js",`${l}-animations.js`);G(b,h),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let x=this.findComponents(n),w=[];for(let O=0;O<x.length;O++){let H=x[O],z=H.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${z}.module (${O+1}/${x.length})...`);let P=I(H.path),J=await this.complete(a,sr(P,z,`See css/${l}-theme.css`));try{let k=JSON.parse(J),E={moduleName:z,fieldsJson:typeof k.fieldsJson=="string"?k.fieldsJson:JSON.stringify(k.fieldsJson,null,2),metaJson:typeof k.metaJson=="string"?k.metaJson:JSON.stringify(k.metaJson,null,2),moduleHtml:k.moduleHtml||"",moduleCss:k.moduleCss||"",moduleJs:k.moduleJs||void 0},Z=ee(s,"modules",`${z}.module`);Te(Z),G(ee(Z,"fields.json"),E.fieldsJson),G(ee(Z,"meta.json"),E.metaJson),G(ee(Z,"module.html"),E.moduleHtml),G(ee(Z,"module.css"),E.moduleCss),E.moduleJs&&G(ee(Z,"module.js"),E.moduleJs),w.push(E),i("module-done",`${z}.module (${this.countFiles(E)} files)`)}catch{i("module-error",`Failed to parse ${z} \u2014 skipping`)}}i("template","Creating page template...");let S=w.map(O=>O.moduleName),M=await this.complete(a,rr(S,r,l)),R=ee(s,"templates",`lp-${l}.html`);return G(R,M),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:h,template:M,modules:w}}async complete(t,n){return(await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]})).content.find(i=>i.type==="text")?.text||""}findAndReadCSS(t){let n=[ee(t,"src/index.css"),ee(t,"src/globals.css"),ee(t,"src/app/globals.css"),ee(t,"app/globals.css")];for(let s of n)if(C(s))return I(s);return""}findAndReadTailwind(t){let n=[ee(t,"tailwind.config.ts"),ee(t,"tailwind.config.js"),ee(t,"tailwind.config.mjs")];for(let s of n)if(C(s))return I(s);return""}findAndReadHooks(t){let n=ee(t,"src/hooks");if(!C(n))return"";try{return lr(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
1691
+ ${I(ee(n,s))}`).join(`
1437
1692
 
1438
- `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=k(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
1693
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),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}
1439
1694
  ${i}`)}return s.join(`
1440
1695
 
1441
- `)}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 wi(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 bc}from"child_process";import{join as xe}from"path";import{readdirSync as Un,statSync as Sc}from"fs";var Gn=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=bc("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}.
1696
+ `)}findComponents(t){let n=[ee(t,"src/components/landing"),ee(t,"src/components/sections"),ee(t,"src/components")];for(let s of n)if(C(s))try{return lr(s).filter(o=>(o.endsWith(".tsx")||o.endsWith(".jsx"))&&!o.startsWith("ui")&&o!=="index.tsx"&&o!=="index.jsx").map(o=>({name:o.replace(/\.(tsx|jsx)$/,""),path:ee(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};f();ot();te();import{spawn as Td}from"child_process";import{join as Ae}from"path";import{readdirSync as os,statSync as Id}from"fs";var is=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce(),a=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((r,l)=>{let c=Td("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}.
1442
1697
 
1443
1698
  INSTRUCTIONS:
1444
1699
  1. Analyze all .tsx/.jsx components in the React source
@@ -1453,7 +1708,7 @@ CONVERSION GUIDE:
1453
1708
  ${s}
1454
1709
 
1455
1710
  Do NOT run hs upload \u2014 I will handle that separately.
1456
- 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 Un(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=k(xe(s,r));break}}let o=xe(t,"js");if(b(o)){for(let r of Un(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=k(xe(o,r));break}}let i=xe(t,"templates");if(b(i)){for(let r of Un(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=k(xe(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=xe(t,"modules");if(b(a))for(let r of Un(a)){if(!r.endsWith(".module"))continue;let l=xe(a,r);if(!Sc(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=xe(l,"fields.json");b(d)&&(c.fieldsJson=k(d));let u=xe(l,"meta.json");b(u)&&(c.metaJson=k(u));let m=xe(l,"module.html");b(m)&&(c.moduleHtml=k(m));let f=xe(l,"module.css");b(f)&&(c.moduleCss=k(f));let h=xe(l,"module.js");b(h)&&(c.moduleJs=k(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};g();qe();Q();import{spawn as vc}from"child_process";import{join as we}from"path";import{readdirSync as Bn,statSync as xc}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=vc("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}.
1711
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ae(t,"css");if(C(s)){for(let r of os(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(Ae(s,r));break}}let o=Ae(t,"js");if(C(o)){for(let r of os(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(Ae(o,r));break}}let i=Ae(t,"templates");if(C(i)){for(let r of os(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(Ae(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=Ae(t,"modules");if(C(a))for(let r of os(a)){if(!r.endsWith(".module"))continue;let l=Ae(a,r);if(!Id(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ae(l,"fields.json");C(d)&&(c.fieldsJson=I(d));let u=Ae(l,"meta.json");C(u)&&(c.metaJson=I(u));let m=Ae(l,"module.html");C(m)&&(c.moduleHtml=I(m));let g=Ae(l,"module.css");C(g)&&(c.moduleCss=I(g));let y=Ae(l,"module.js");C(y)&&(c.moduleJs=I(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};f();ot();te();import{spawn as Ed}from"child_process";import{join as $e}from"path";import{readdirSync as rs,statSync as _d}from"fs";var as=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce(),a=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((r,l)=>{let c=Ed("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}.
1457
1712
 
1458
1713
  INSTRUCTIONS:
1459
1714
  1. Analyze all .tsx/.jsx components in the React source
@@ -1468,15 +1723,15 @@ CONVERSION GUIDE:
1468
1723
  ${s}
1469
1724
 
1470
1725
  Do NOT run hs upload \u2014 I will handle that separately.
1471
- 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=k(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=k(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=k(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(!xc(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=we(l,"fields.json");b(d)&&(c.fieldsJson=k(d));let u=we(l,"meta.json");b(u)&&(c.metaJson=k(u));let m=we(l,"module.html");b(m)&&(c.moduleHtml=k(m));let f=we(l,"module.css");b(f)&&(c.moduleCss=k(f));let h=we(l,"module.js");b(h)&&(c.moduleJs=k(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};qe();Q();function wc(e,t){switch(e){case"claude-code":return new Hn(t);case"gemini-cli":return new Gn;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
1472
- HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=wc(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"?H(y):s.message(y)}}),a=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${a}s)`);let r=Cc(e.themePath);for(let h of r)H(`Auto-fixed: ${h}`);let l=Ac(e.themePath,i),c=[];for(let h of l){let y=h.passed?"\u2705":"\u274C",w=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${y} ${h.label}${w}`)}let d=l.filter(h=>h.passed).length;c.push(`
1473
- ${d}/${l.length} checks passed`),await Je(c.join(`
1474
- `),"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:
1475
- `+u.map(y=>` - ${y.label}`).join(`
1476
- `)),!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:
1477
- `+m.map(h=>` - ${h.label}`).join(`
1478
- `));let f=ke(e.themePath,"..","vibespot-conversion.log");return b(f)&&(await se({message:"Keep conversion log file for debugging?",initialValue:!1})?H(`Log saved: ${f}`):Ci(f)),await de("Files ready for upload!"),i}function Cc(e){let t=[];kc(e),Ic(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=k(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;Ai(d)&&(u=!0,t.push(`${a}: fixed choice field format`)),ki(d)&&(u=!0,t.push(`${a}: fixed link field default value`)),u&&(r=JSON.stringify(d,null,2)+`
1479
- `,l=!0)}catch{t.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&U(i,r);let c=ke(n,o,"module.html");if(b(c)){let d=k(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),U(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=k(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(Ci(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Ai(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)&&Ai(s.children)&&(t=!0)}return t}function ki(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)&&ki(s.children)&&(t=!0)}return t}function Ac(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=k(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 kc(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=k(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+=`
1726
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=$e(t,"css");if(C(s)){for(let r of rs(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I($e(s,r));break}}let o=$e(t,"js");if(C(o)){for(let r of rs(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I($e(o,r));break}}let i=$e(t,"templates");if(C(i)){for(let r of rs(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I($e(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=$e(t,"modules");if(C(a))for(let r of rs(a)){if(!r.endsWith(".module"))continue;let l=$e(a,r);if(!_d(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=$e(l,"fields.json");C(d)&&(c.fieldsJson=I(d));let u=$e(l,"meta.json");C(u)&&(c.metaJson=I(u));let m=$e(l,"module.html");C(m)&&(c.moduleHtml=I(m));let g=$e(l,"module.css");C(g)&&(c.moduleCss=I(g));let y=$e(l,"module.js");C(y)&&(c.moduleJs=I(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};ot();te();function Pd(e,t){switch(e){case"claude-code":return new ns(t);case"gemini-cli":return new is;case"codex-cli":return new as;case"api":return new ss}}async function ls(e){await ge("Converting React to HubSpot Modules"),await Ge(`AI will now analyze your React code and create
1727
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=Pd(e.aiEngine,e.model),n=ce(),s=await he();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(y,h)=>{y==="created"?U(h):s.message(h)}}),a=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${a}s)`);let r=Nd(e.themePath);for(let y of r)U(`Auto-fixed: ${y}`);let l=Md(e.themePath,i),c=[];for(let y of l){let h=y.passed?"\u2705":"\u274C",b=y.passed?"":y.critical?" (CRITICAL)":" (cosmetic)";c.push(`${h} ${y.label}${b}`)}let d=l.filter(y=>y.passed).length;c.push(`
1728
+ ${d}/${l.length} checks passed`),await Ge(c.join(`
1729
+ `),"Conversion Checklist");let u=l.filter(y=>!y.passed&&y.critical),m=l.filter(y=>!y.passed&&!y.critical);if(u.length>0){if(V(`${u.length} critical issue(s) \u2014 upload will likely fail:
1730
+ `+u.map(h=>` - ${h.label}`).join(`
1731
+ `)),!await le({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&q(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
1732
+ `+m.map(y=>` - ${y.label}`).join(`
1733
+ `));let g=Ie(e.themePath,"..","vibespot-conversion.log");return C(g)&&(await le({message:"Keep conversion log file for debugging?",initialValue:!1})?U(`Log saved: ${g}`):cr(g)),await fe("Files ready for upload!"),i}function Nd(e){let t=[];Od(e),Rd(e);let n=Ie(e,"modules");if(C(n))for(let o of mn(n)){if(!o.endsWith(".module"))continue;let i=Ie(n,o,"fields.json");if(!C(i))continue;let a=o.replace(".module",""),r=I(i),l=!1;r.includes('"textarea"')&&(r=r.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${a}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(r)&&(r=r.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${a}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(r),u=!1;dr(d)&&(u=!0,t.push(`${a}: fixed choice field format`)),ur(d)&&(u=!0,t.push(`${a}: fixed link field default value`)),u&&(r=JSON.stringify(d,null,2)+`
1734
+ `,l=!0)}catch{t.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&G(i,r);let c=Ie(n,o,"module.html");if(C(c)){let d=I(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),G(c,d),t.push(`${a}: now() \u2192 local_dt`))}}let s=Ie(e,"templates");if(C(s))for(let o of mn(s)){if(!o.endsWith(".html"))continue;let i=Ie(s,o),a=I(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(cr(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function dr(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let a=i.charAt(0).toUpperCase()+i.slice(1);return[i,a]}return i}),t=!0),Array.isArray(s.children)&&dr(s.children)&&(t=!0)}return t}function ur(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&ur(s.children)&&(t=!0)}return t}function Md(e,t){let n=[],s=t.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of t.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let a=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),r=a.length===0;n.push({label:r?"module.css created for each module":`module.css missing for: ${a.join(", ")}`,passed:s>0&&r,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=Ie(e,"templates"),d=!1;if(C(c))for(let u of mn(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=I(Ie(c,u));if(m.includes("dnd_area")&&/templateType\s*:\s*page/i.test(m)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function Od(e){let t=Ie(e,"templates");if(C(t))for(let n of mn(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=Ie(t,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+=`
1480
1735
  templateType: page`),a||(c+=`
1481
1736
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
1482
1737
  label: ${r}`),o=c+o.slice(l)}else o=`<!--
@@ -1484,32 +1739,34 @@ ${d}/${l.length} checks passed`),await Je(c.join(`
1484
1739
  isAvailableForNewContent: true
1485
1740
  label: ${r}
1486
1741
  -->
1487
- `+o;U(s,o),H(`Template "${n}" \u2014 annotations verified`)}}function Ic(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(k(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&&U(s,JSON.stringify(o,null,2)+`
1488
- `)}catch{}}}g();ut();import{join as ji,basename as jc}from"path";g();Q();import{join as ie}from"path";import{readdirSync as Xe,rmSync as Tc}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 Ti(e)&&t.push("textarea \u2192 text"),$i(e)&&t.push("name \u2192 item_name"),Ei(e)&&t.push("now() \u2192 local_dt"),_i(e)&&t.push("Removed HubDB templates"),Pi(e)&&t.push("Fixed link field defaults"),Mi(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),$c(e)&&t.push("Stripped CDN @import statements"),t}function Ii(e,t){return t.message.includes("textarea")?Ti(e):t.message.includes("reserved field name")?$i(e):t.message.includes("now()")?Ei(e):t.message.includes("HubDB")?_i(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?Pi(e):t.message.includes("invalid format")&&t.message.includes("color")?Mi(e):!1}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=k(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),U(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,"fields.json");if(!b(o))continue;let i=k(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),U(o,i),t=!0)}return t}function Ei(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=k(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),U(o,i),t=!0)}return t}function _i(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=k(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Tc(o),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(k(o));Ni(i)&&(U(o,JSON.stringify(i,null,2)+`
1489
- `),t=!0)}catch{}}return t}function $c(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=k(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(U(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=k(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(U(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=k(i),r=a.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");r!==a&&(U(i,r),t=!0)}return t}function Mi(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(k(o));Oi(i)&&(U(o,JSON.stringify(i,null,2)+`
1490
- `),t=!0)}catch{}}return t}function Oi(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"&&!Ec(i)){let a=_c(i);a&&(o.color=a.hex,a.opacity!==void 0&&(o.opacity=a.opacity),t=!0)}}Array.isArray(s.children)&&Oi(s.children)&&(t=!0)}return t}function Ec(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 Ni(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)&&Ni(s.children)&&(t=!0)}return t}Z();g();pt();pt();import{readdirSync as Pc}from"fs";import{join as Mc,relative as Oc}from"path";var Nc=new Set([".git","node_modules",".vibespot",".DS_Store"]);function Ri(e){let t=[];for(let n of Pc(e,{withFileTypes:!0})){if(Nc.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=Mc(e,n.name);n.isDirectory()?t.push(...Ri(s)):n.isFile()&&t.push(s)}return t}async function Rc(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=Ri(t),a=i.length,r=0,l=0,c=[];return await Rc(i,o,async d=>{let u=Oc(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let f=await ri(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 Fc(e){return(e.match(/^Uploaded file /gm)||[]).length}async function $t(e){await ce("Uploading to HubSpot");let t=jc(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=E(`hs cms upload "${e}" "${t}"`,{cwd:ji(e,"..")}),f=[m.stdout,m.stderr].filter(Boolean).join(`
1491
- `);c=Fc(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.
1492
- 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?Ii(e,m)?(H(`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.
1493
- 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 Fs(s,`${t}/modules`)}catch{}else E(`hs cms delete "${t}/modules"`,{cwd:ji(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 Jc}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.
1742
+ `+o;G(s,o),U(`Template "${n}" \u2014 annotations verified`)}}function Rd(e){let t=Ie(e,"modules");if(C(t))for(let n of mn(t)){if(!n.endsWith(".module"))continue;let s=Ie(t,n,"meta.json");if(C(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&&G(s,JSON.stringify(o,null,2)+`
1743
+ `)}catch{}}}f();ht();import{join as wr,basename as Wd}from"path";f();te();import{join as de}from"path";import{readdirSync as it,rmSync as Fd}from"fs";function cs(e){let t=[];for(let n of e){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function ds(e){let t=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(e)&&t.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(e)&&t.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(e)){let n=e.match(/field.*?(\w+)\s+has an invalid/i);t.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(e)){let n=e.match(/file '([^']+)'/i);t.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(e)&&t.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),t}function us(e){let t=[];return pr(e)&&t.push("textarea \u2192 text"),gr(e)&&t.push("name \u2192 item_name"),fr(e)&&t.push("now() \u2192 local_dt"),hr(e)&&t.push("Removed HubDB templates"),yr(e)&&t.push("Fixed link field defaults"),br(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),Jd(e)&&t.push("Stripped CDN @import statements"),t}function mr(e,t){return t.message.includes("textarea")?pr(e):t.message.includes("reserved field name")?gr(e):t.message.includes("now()")?fr(e):t.message.includes("HubDB")?hr(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?yr(e):t.message.includes("invalid format")&&t.message.includes("color")?br(e):!1}function pr(e){let t=!1,n=de(e,"modules");if(!C(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(!C(o))continue;let i=I(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),G(o,i),t=!0)}return t}function gr(e){let t=!1,n=de(e,"modules");if(!C(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(!C(o))continue;let i=I(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),G(o,i),t=!0)}return t}function fr(e){let t=!1,n=de(e,"modules");if(!C(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"module.html");if(!C(o))continue;let i=I(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),G(o,i),t=!0)}return t}function hr(e){let t=!1,n=de(e,"templates");if(!C(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=de(n,s),i=I(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Fd(o),t=!0)}return t}function yr(e){let t=!1,n=de(e,"modules");if(!C(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(C(o))try{let i=JSON.parse(I(o));xr(i)&&(G(o,JSON.stringify(i,null,2)+`
1744
+ `),t=!0)}catch{}}return t}function Jd(e){let t=!1,n=de(e,"css");if(C(n))for(let o of it(n)){if(!o.endsWith(".css"))continue;let i=de(n,o),a=I(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(G(i,r),t=!0)}let s=de(e,"modules");if(C(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=de(s,o,"module.css");if(!C(i))continue;let a=I(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(G(i,r),t=!0)}if(C(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=de(s,o,"module.html");if(!C(i))continue;let a=I(i),r=a.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");r!==a&&(G(i,r),t=!0)}return t}function br(e){let t=!1,n=de(e,"modules");if(!C(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(C(o))try{let i=JSON.parse(I(o));Sr(i)&&(G(o,JSON.stringify(i,null,2)+`
1745
+ `),t=!0)}catch{}}return t}function Sr(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="color"&&s.default&&typeof s.default=="object"){let o=s.default,i=o.color;if(typeof i=="string"&&!jd(i)){let a=Dd(i);a&&(o.color=a.hex,a.opacity!==void 0&&(o.opacity=a.opacity),t=!0)}}Array.isArray(s.children)&&Sr(s.children)&&(t=!0)}return t}function jd(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function Dd(e){let t=e.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(t)return{hex:`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`};let n=e.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),a=Math.min(255,parseInt(n[2])),r=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=e.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function xr(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&xr(s.children)&&(t=!0)}return t}Q();f();bt();bt();import{readdirSync as Hd}from"fs";import{join as Ld,relative as Bd}from"path";var Ud=new Set([".git","node_modules",".vibespot",".DS_Store"]);function vr(e){let t=[];for(let n of Hd(e,{withFileTypes:!0})){if(Ud.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=Ld(e,n.name);n.isDirectory()?t.push(...vr(s)):n.isFile()&&t.push(s)}return t}async function Gd(e,t,n){let s=0;async function o(){for(;s<e.length;){let a=s++;await n(e[a])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function ms(e,t,n,s={}){let o=s.concurrency??5,i=vr(t),a=i.length,r=0,l=0,c=[];return await Gd(i,o,async d=>{let u=Bd(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await Wi(e,m,d);if(g.success)r++,s.onFileComplete?.(u);else{l++;let y={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(y),s.onFileError?.(u,y)}s.onProgress?.(r+l,a)}),{success:l===0,uploaded:r,failed:l,total:a,errors:c}}function Vd(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Jt(e){await ge("Uploading to HubSpot");let t=Wd(e)||e,n=N(),s=Se(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await he(),a=3;for(let r=1;r<=a;r++){i.start(r===1?"Uploading theme...":`Retrying upload (attempt ${r}/${a})...`);let l=[],c=0,d=!1;if(o){let m=await ms(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=cs(m.errors)}else{let m=F(`hs cms upload "${e}" "${t}"`,{cwd:wr(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
1746
+ `);c=Vd(g),d=m.success,d||(l=ds(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await fe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(V("Upload failed with unknown error."),c>0&&(q(`Most files uploaded successfully. The theme may already be usable in HubSpot.
1747
+ You can check your HubSpot Design Manager to verify.`),await le({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(r<a){if(!await le({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?mr(e,m)?(U(`Auto-fixed: ${m.message}`),u=!0):q(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&r<a)){if(c>0&&(q(`${c} files uploaded successfully despite errors.
1748
+ The theme may work \u2014 check HubSpot Design Manager.`),await le({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await ao(s,`${t}/modules`)}catch{}else F(`hs cms delete "${t}/modules"`,{cwd:wr(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}f();import{execFileSync as yo}from"child_process";import{rmSync as Kd}from"fs";import{basename as Cr}from"path";te();async function kr(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ge("You're all set!");let a=sn(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await Ge(`Your React page has been converted and uploaded to HubSpot.
1494
1749
  The theme and modules are now in your account, but you still
1495
- need to ${I.bold("create a new landing page")} that uses them.
1750
+ need to ${_.bold("create a new landing page")} that uses them.
1496
1751
 
1497
1752
  Next steps:
1498
1753
 
1499
- ${I.bold("1.")} Go to HubSpot ${I.muted("\u2192")} Content ${I.muted("\u2192")} Landing Pages ${I.muted("\u2192")} Create
1500
- ${I.bold("2.")} Choose your uploaded theme from the theme picker
1501
- ${I.bold("3.")} Select the landing page template that was just created
1502
- ${I.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
1503
- ${I.bold("5.")} Click each section to edit text, images, and colors
1504
- ${I.bold("6.")} Upload images via File Manager ${I.muted("(Settings \u2192 Files)")}
1505
- ${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"}),H("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{Jc(d.path,{recursive:!0,force:!0}),H(`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 Di(){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 Hi(){Ne(),await Nn()}g();Z();async function Li(){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 Ui(){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=Ut();t.found?En(t.version)?H(`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=Gt();n.found?H(`Git ${n.version}`):(B("Git \u2014 not installed"),ee(" Install from https://git-scm.com"),e++);let s=je();if(!s.found)z("HubSpot CLI \u2014 not installed (only needed for deployment)"),ee(" Install: npm install -g @hubspot/cli");else if(!si(s.version))z(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),ee(" Update: npm install -g @hubspot/cli@latest"),e++;else{H(`HubSpot CLI v${s.version}`);let m=Fe();m.authenticated?H(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(z("HubSpot \u2014 not authenticated"),ee(" Run: hs init"))}let o=Bt();o.found?H(`Claude Code ${o.version} at ${o.path}`):ee(I.muted("Claude Code \u2014 not installed"));let i=Vt();i.found?H(`Gemini CLI ${i.version} at ${i.path}`):ee(I.muted("Gemini CLI \u2014 not installed"));let a=Kt();a.found?H(`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?H("Anthropic API key configured"):ee(I.muted("Anthropic API key \u2014 not set")),c?H("OpenAI API key configured"):ee(I.muted("OpenAI API key \u2014 not set")),d?H("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&&H(`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 nm}from"fs";import{execFileSync as Bo}from"child_process";import Is from"chalk";g();Se();Zt();as();fs();Z();import{createServer as zu}from"http";import{readFileSync as Go,existsSync as yn}from"fs";import{join as tt,extname as Pl}from"path";import{createHash as qu}from"crypto";import{WebSocketServer as Xu}from"ws";g();import{spawn as Fo}from"child_process";var dt=new Map;function wa(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+=`
1754
+ ${_.bold("1.")} Go to HubSpot ${_.muted("\u2192")} Content ${_.muted("\u2192")} Landing Pages ${_.muted("\u2192")} Create
1755
+ ${_.bold("2.")} Choose your uploaded theme from the theme picker
1756
+ ${_.bold("3.")} Select the landing page template that was just created
1757
+ ${_.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
1758
+ ${_.bold("5.")} Click each section to edit text, images, and colors
1759
+ ${_.bold("6.")} Upload images via File Manager ${_.muted("(Settings \u2192 Files)")}
1760
+ ${_.bold("7.")} Preview and publish!`,"What's next"),await le({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${a}/page-ui/${t}/management/pages/landing`:`https://${a}`;try{let d=process.platform;d==="darwin"?yo("open",[c],{stdio:"ignore"}):d==="win32"?yo("cmd",["/c","start","",c],{stdio:"ignore"}):yo("xdg-open",[c],{stdio:"ignore"}),U("Opening HubSpot Landing Pages...")}catch{ne(`Open this URL in your browser: ${_.info(c)}`)}}let l=[];if(o&&C(n)&&l.push({path:n,label:`Cloned source (${Cr(n)})`}),C(s)&&l.push({path:s,label:`Theme directory (${Cr(s)})`}),l.length>0&&await le({message:"Clean up local working directories?"}))for(let d of l)try{Kd(d.path,{recursive:!0,force:!0}),U(`Removed ${d.label}`)}catch{q(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await fe(`Thanks for using hub${_.vibes("Vibes")}! ${_.vibes("~")}`)}Q();async function Ar(){He();let e=await qn(),t=await Xn();W({lastSourcePath:t.sourceDir});let n=await ts();W({lastThemePath:n.themePath}),await ls({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Jt(n.themePath),await kr({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}f();async function $r(){He(),await qn()}f();Q();async function Tr(){He();let e=N();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await Xn(),n=await ts();await ls({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}f();Q();async function Ir(){He();let e=N();if(e.lastThemePath)if(await le({message:`Upload from ${e.lastThemePath}?`}))await Jt(e.lastThemePath);else{let n=await Pe({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Jt(n)}else{let t=await Pe({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Jt(t)}}f();Q();async function Er(){He(),await ge("Environment Diagnostics");let e=0,t=en();t.found?Wn(t.version)?U(`Node.js v${t.version}`):(q(`Node.js v${t.version} \u2014 too old (need 18+)`),ne(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),ne(" Install from https://nodejs.org"),e++);let n=tn();n.found?U(`Git ${n.version}`):(V("Git \u2014 not installed"),ne(" Install from https://git-scm.com"),e++);let s=Be();if(!s.found)q("HubSpot CLI \u2014 not installed (only needed for deployment)"),ne(" Install: npm install -g @hubspot/cli");else if(!Bi(s.version))q(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),ne(" Update: npm install -g @hubspot/cli@latest"),e++;else{U(`HubSpot CLI v${s.version}`);let m=Ue();m.authenticated?U(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(q("HubSpot \u2014 not authenticated"),ne(" Run: hs init"))}let o=nn();o.found?U(`Claude Code ${o.version} at ${o.path}`):ne(_.muted("Claude Code \u2014 not installed"));let i=on();i.found?U(`Gemini CLI ${i.version} at ${i.path}`):ne(_.muted("Gemini CLI \u2014 not installed"));let a=rn();a.found?U(`OpenAI Codex ${a.version} at ${a.path}`):ne(_.muted("OpenAI Codex \u2014 not installed"));let r=N(),l=!!(r.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(r.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(r.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?U("Anthropic API key configured"):ne(_.muted("Anthropic API key \u2014 not set")),c?U("OpenAI API key configured"):ne(_.muted("OpenAI API key \u2014 not set")),d?U("Google AI API key configured"):ne(_.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};r.aiEngine&&U(`AI engine: ${u[r.aiEngine]||r.aiEngine}`),r.lastThemePath&&ne(_.muted(`Last theme: ${r.lastThemePath}`)),!o.found&&!i.found&&!a.found&&!l&&!c&&!d&&(q("No AI engine available"),ne(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),ne(" Or install: Claude Code \u2014 https://claude.ai/code"),ne(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),ne(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await fe("Everything looks good!"):await fe(_.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}f();import{join as zs}from"path";import{existsSync as Gp}from"fs";import{execFileSync as Ei}from"child_process";import Ys from"chalk";f();pe();jt();Cs();Tn();import{createServer as Jp}from"http";import{readFileSync as Ii,existsSync as Nn}from"fs";import{join as dt,extname as Hc}from"path";import{createHash as jp}from"crypto";import{WebSocketServer as Dp}from"ws";f();Fe();pe();Q();ae();import{existsSync as dl,mkdirSync as jm,writeFileSync as Dm,rmSync as Hm}from"fs";import{join as ul}from"path";var Lm="plan.md";function ml(e){return ul(e,".vibespot",Lm)}function mi(e){let t=v();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;try{let n=ul(t.themePath,".vibespot");dl(n)||jm(n,{recursive:!0}),Dm(ml(t.themePath),e,"utf-8")}catch(n){T.warn("plan",`Failed to write plan.md: ${n instanceof Error?n.message:String(n)}`)}return j(),e}function pi(){let e=v();if(e){e.brandAssets&&delete e.brandAssets.plan;try{let t=ml(e.themePath);dl(t)&&Hm(t)}catch(t){T.warn("plan",`Failed to remove plan.md: ${t instanceof Error?t.message:String(t)}`)}j()}}function pl(e,t){Ye(e,t,n=>{if(!v()){p(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(t,400,{error:"Plan content cannot be empty"});return}mi(o),p(t,200,{ok:!0,plan:o})})}function gl(e,t){Ye(e,t,()=>{pi(),W({planMode:!1}),p(t,200,{ok:!0})})}f();var gi=/```vibespot-plan\s*\n([\s\S]*?)```/g,fi=/```vibespot-choices\s*\n([\s\S]*?)```/g;function fl(e){let t,n,s;for(gi.lastIndex=0;(s=gi.exec(e))!==null;)t=s[1].trim();let o;for(fi.lastIndex=0;(o=fi.exec(e))!==null;)try{let a=JSON.parse(o[1].trim());a&&typeof a.question=="string"&&Array.isArray(a.options)&&a.options.every(r=>typeof r=="string")&&a.options.length>0&&(n={question:a.question,options:a.options})}catch{}return{cleanedContent:e.replace(gi,"").replace(fi,"").replace(/\n{3,}/g,`
1761
+
1762
+ `).trim(),plan:t,choices:n}}Q();f();import{spawn as hi}from"child_process";var gt=new Map;function hl(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+=`
1506
1763
  Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
1507
- 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};dt.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()),wa(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};dt.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 wa(a,o,n?.timeout),s}function gs(e){return dt.get(e)}function xu(){let e=Date.now()-18e5;for(let[t,n]of dt)n.completedAt&&n.completedAt<e&&dt.delete(t)}setInterval(xu,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};dt.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+=`
1764
+ Process timed out`,t.completedAt=Date.now())},n||3e5)}function In(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};gt.set(o,i);let a=hi(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&a.stdin&&(a.stdin.write(s.stdin),a.stdin.end()),hl(a,i,s?.timeout),o}function $t(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};gt.set(s,o);let i=e.split(" "),a=hi(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return hl(a,o,n?.timeout),s}function Os(e){return gt.get(e)}function Bm(){let e=Date.now()-18e5;for(let[t,n]of gt)n.completedAt&&n.completedAt<e&&gt.delete(t)}setInterval(Bm,600*1e3);function Rs(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};gt.set(s,o);let i=e.split(" "),a=hi(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),r=c=>{for(let d of o.listeners)try{d(c)}catch{}};a.stdout?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.stderr?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),a.on("error",c=>{o.status="failed",o.output+=`
1508
1765
  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+=`
1509
- Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Ca(e,t){let n=dt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Aa(e,t){let n=dt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}et();Q();g();et();Z();import{existsSync as Rt,readdirSync as ka,rmSync as wu}from"fs";import{join as jt,basename as Cu}from"path";import{homedir as Au}from"os";import{execFileSync as Ia}from"child_process";Jn();pt();Se();fs();Z();Q();var Ta=process.platform==="win32"?{shell:!0}:{},Me=jt(Au(),"vibespot-themes"),ys=null,ku=5e3;function bs(){if(ys&&Date.now()-ys.ts<ku)return ys.data;let e=[];if(Rt(Me))try{for(let t of ka(Me,{withFileTypes:!0}))if(t.isDirectory()){let n=jt(Me,t.name,"theme.json");if(Rt(n)){let s=0,o=jt(Me,t.name,"modules");if(Rt(o))try{s=ka(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 $a(e){let t=v(),n=_n(),s=!1;try{Ia("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Ta}),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 Ea(e,t){R(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=jt(Me,o);Ae(Me),Rt(i)&&wu(i,{recursive:!0,force:!0}),Fn(i,o),sn(i,o),L(),p(t,200,{ok:!0,themeName:o,themePath:i})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function _a(e,t){R(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=jt(Me,r);Ae(Me),a.hubspotUploadMode==="cli"||!i?(Ia("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Ta}),sn(l,r),an(l),L(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})):qt(i,o,l).then(()=>{sn(l,r),an(l),L(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})}).catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Pa(e,t){R(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=jt(Me,s)),!Rt(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Cu(o);sn(o,i),an(o),L(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:v()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Ma(e,t){R(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 Oa(e,t){R(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 Na(e){let t=he();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await li(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 Iu,readFileSync as Tu,appendFileSync as $u}from"fs";import{join as Ra}from"path";import{homedir as ja}from"os";pt();Q();var gn={data:{},ts:0},Eu=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 _u(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 Pu(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 Mu(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 Ou(){if(Date.now()-gn.ts<Eu&&Object.keys(gn.data).length>0)return gn.data;let e=_(),t={...Fa},n=[],s=ge("anthropic-api",e);s&&n.push(_u(s).then(a=>{a.length&&(t["anthropic-api"]=a,t["claude-oauth"]=a)}).catch(()=>{}));let o=ge("openai-api",e);o&&n.push(Pu(o).then(a=>{a.length&&(t["openai-api"]=a)}).catch(()=>{}));let i=ge("gemini-api",e);return i&&n.push(Mu(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();Ou().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 Da(e,t){R(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 Ha(e,t){R(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 La(e,t){R(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 Ua(e,t){R(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(!je().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(!je().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=Fe();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){R(e,n=>{try{let s=JSON.parse(n||"{}");if(!Rs().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=js();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 Ba(e,t){R(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(!je().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 Wa(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 Va(e,t){R(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")?Ra(ja(),".zshrc"):Ra(ja(),".bashrc");try{(Iu(l)?Tu(l,"utf-8"):"").includes("OPENAI_API_KEY")||$u(l,`
1766
+ Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function yl(e,t){let n=gt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function bl(e,t){let n=gt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}Fe();te();f();Fe();Q();Qn();es();bt();pe();Tn();import{existsSync as Kt,readdirSync as Sl,rmSync as Um}from"fs";import{join as zt,basename as Gm}from"path";import{homedir as Wm}from"os";import{execFileSync as xl}from"child_process";Q();te();var vl=process.platform==="win32"?{shell:!0}:{},Je=zt(Wm(),"vibespot-themes"),Fs=null,Vm=5e3;function Js(){if(Fs&&Date.now()-Fs.ts<Vm)return Fs.data;let e=[];if(Kt(Je))try{for(let t of Sl(Je,{withFileTypes:!0}))if(t.isDirectory()){let n=zt(Je,t.name,"theme.json");if(Kt(n)){let s=0,o=zt(Je,t.name,"modules");if(Kt(o))try{s=Sl(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return Fs={data:e,ts:Date.now()},e}function wl(e){let t=v(),n=Vn(),s=!1;try{xl("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...vl}),s=!0}catch{}let o=Lt().sort((a,r)=>r.updatedAt-a.updatedAt).slice(0,10),i=Js();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i})}function Cl(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,""),i=zt(Je,o);Te(Je),Kt(i)&&Um(i,{recursive:!0,force:!0}),cn(i,o),vt(i,o),j(),p(t,200,{ok:!0,themeName:o,themePath:i})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function kl(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Se(),a=N(),r=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=zt(Je,r);Te(Je),a.hubspotUploadMode==="cli"||!i?(xl("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...vl}),vt(l,r),bn(l),j(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})):dn(i,o,l).then(()=>{vt(l,r),bn(l),j(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})}).catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Al(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme path is required"});return}let o=s;if(Kt(o)||(o=zt(Je,s)),!Kt(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Gm(o);vt(o,i),bn(o),j(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:v()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function $l(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Session ID is required"});return}let o=vs(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 Tl(e,t){B(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}W({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Il(e){let t=Se();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Ki(t);if(n.length===0){p(e,200,{themes:[]});return}let s=[],o=n.map(async r=>{let l=r.path||r.name;try{let c=await Yn(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:r.name,path:l})}catch{}});await Promise.all(o),s.sort((r,l)=>r.name.localeCompare(l.name));let i=Js(),a=new Set(i.map(r=>r.name));p(e,200,{themes:s.map(r=>({...r,existsLocally:a.has(r.name)}))})})().catch(n=>{p(e,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}f();Fe();Q();pe();import{existsSync as Km,readFileSync as zm,appendFileSync as Ym}from"fs";import{join as El}from"path";import{homedir as _l}from"os";bt();te();var En={data:{},ts:0},qm=600*1e3,Pl={"claude-code":[{id:"sonnet",label:"Claude Sonnet (default)"},{id:"opus",label:"Claude Opus"},{id:"haiku",label:"Claude Haiku"}],"codex-cli":[{id:"o4-mini",label:"o4 Mini (default)"},{id:"o3",label:"o3"},{id:"gpt-4o",label:"GPT-4o"}]};async function Xm(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 Zm(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 Qm(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 ep(){if(Date.now()-En.ts<qm&&Object.keys(En.data).length>0)return En.data;let e=N(),t={...Pl},n=[],s=be("anthropic-api",e);s&&n.push(Xm(s).then(a=>{a.length&&(t["anthropic-api"]=a,t["claude-oauth"]=a)}).catch(()=>{}));let o=be("openai-api",e);o&&n.push(Zm(o).then(a=>{a.length&&(t["openai-api"]=a)}).catch(()=>{}));let i=be("gemini-api",e);return i&&n.push(Qm(i).then(a=>{a.length&&(t["gemini-api"]=a,t["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n),En.data=t,En.ts=Date.now(),t}function Nl(e){let t=Vn(),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,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null},o=Lt().length,i=Js().length,a=Pt();ep().then(r=>{p(e,200,{version:a,environment:t,config:s,models:r,sessionCount:o,localThemeCount:i})}).catch(()=>{p(e,200,{version:a,environment:t,config:s,models:Pl,sessionCount:o,localThemeCount:i})})}function Ml(e,t){B(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let a={aiEngine:s};if(o)switch(s){case"claude-code":a.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":a.anthropicApiModel=o;break;case"openai-api":a.openaiApiModel=o;break}W(a),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ol(e,t){B(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"figma":l.figmaToken="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}W(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"figma":i.figmaToken=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}W(i);let a=null;if(!N().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(W({aiEngine:c}),a=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:a})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Rl(e,t){B(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let a=$t(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:a})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Fl(e,t){B(e,n=>{try{let s=JSON.parse(n||"{}"),o=N(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){zn(s.personalAccessKey).then(a=>{qt(s.personalAccessKey,a.portalId,a.portalName,a.dataCenter),p(t,200,{ok:!0,portalName:a.portalName,portalId:a.portalId,dataCenter:a.dataCenter})}).catch(a=>{p(t,400,{error:a instanceof Error?a.message:String(a)})});return}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=In("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:r});return}if(i==="api"){let a=o.hubspotAccounts||[];if(a.length>0&&!s.force){let r=a.find(l=>l.portalId===o.activeHubSpotAccount)||a[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=Ue();if(r.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Jl(e,t){B(e,n=>{try{let s=JSON.parse(n||"{}");if(!io().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=ro();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let r=In("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:r});return}let a=$t("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:a,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function jl(e,t){B(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((N().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Zs(s),p(t,200,{ok:!0});return}if(s){Qs(s),p(t,200,{ok:!0});return}}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=In("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=In("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}}p(t,400,{error:"portalId required"})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Dl(e){let t=$t("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function Hl(e,t){B(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=$t("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=$t("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,W({openaiApiKey:i}),process.platform!=="win32"){let a=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(a){let r=`export OPENAI_API_KEY="${a}"`,l=process.env.SHELL?.includes("zsh")?El(_l(),".zshrc"):El(_l(),".bashrc");try{(Km(l)?zm(l,"utf-8"):"").includes("OPENAI_API_KEY")||Ym(l,`
1510
1767
  # Added by vibeSpot
1511
1768
  ${r}
1512
- `)}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 Ka(e,t){R(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 Ya(e,t){R(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 za(e,t){R(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 qa(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 Xa(e,t){R(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 Qa(e,t){let n=Re(),s=Lt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Za(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 Nu,rmSync as Ru}from"fs";import{join as ju}from"path";function el(e,t,n){if(e==="GET"){let s=v(),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"){R(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);dr(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 tl(e,t){R(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 nl(e,t){R(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=ju(Me,s);if(!Nu(o)){p(t,404,{error:"Theme not found on disk"});return}Ru(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function sl(e,t){R(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=ur(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 Bu,rmSync as Uo}from"fs";import{join as Be,basename as Wu}from"path";import{execFileSync as Vu}from"child_process";var Ku=process.platform==="win32"?{shell:!0}:{};function dl(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}let n=at();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1}})}function ul(e){let t=v();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=Wu(n);try{let a=`${s}.zip`,r=Be(o,a);As(r)&&Uo(r),Vu("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...Ku});let l=Bu(r);Uo(r),e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${a}"`,"Content-Length":l.length}),e.end(l)}catch(a){$.error("download-zip","Failed to create zip archive",a),p(e,500,{error:"Failed to create zip archive"})}}function ml(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){R(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=ir(i,a);L(),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"){R(t,o=>{try{let{templateId:i,deleteModules:a}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!lr(i,!!a)){p(n,404,{error:"Template not found"});return}L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function pl(e,t){R(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}L();let i=v();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 fl(e,t){R(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(!ar(s,o.trim())){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function gl(e,t){R(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=rr(s,o);if(!i){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function hl(e){let t=at();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function yl(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}R(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let r=at().find(d=>d.module.moduleName===i);if(!r){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...r.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function bl(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){R(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(),L(),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),U(Be(l,r),a),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){R(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)&&Uo(r),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function ll(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),U(Be(o,s),n)}async function cl(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(),xa)),{loadConfig:o}=await Promise.resolve().then(()=>(Z(),Zo)),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(()=>(al(),rl));return m(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(Lo(),Ho));return u(d,e.brandAssets?.themeContext,a,r,l)}function Sl(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}R(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=>cl(n,u,a))),d={};for(let u=0;u<l.length;u++){let m=c[u],f=m.status==="fulfilled"?m.value:null;f&&ll(n,l[u],f),d[l[u]]=f}L(),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 cl(n,i,a);if(!r){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}ll(n,i,r),L(),p(t,200,{ok:!0,type:i,content:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function vl(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}R(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:w}=await Promise.resolve().then(()=>(Jn(),fi));await w(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),U(Be(d,"styleguide.md"),c),L(),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 Yu}from"path";Zt();function xl(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function wl(e,t,n){let s=v();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?er(o.moduleName):tr(o.moduleName),L(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function Cl(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}R(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(),L(),lt(),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(),L(),lt(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function Al(e,t){vo(e,t,n=>{Array.isArray(n.order)?(Et(n.order),L(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function kl(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}try{lt();let n=zn(t.themePath),s=hs(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:Yu(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function Il(e,t){R(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);nr(s,o,i),L(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function Tl(e,t){R(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=mi(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
1769
+ `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=$t("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:p(t,400,{error:`Unknown CLI: ${s}`})}}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ll(e,t){B(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}W({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Bl(e,t){B(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(t,400,{error:"toolId (string) and enabled (boolean) required"});return}eo(s,o),p(t,200,{ok:!0,toolId:s,enabled:o})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ul(e,t){B(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}let i={};for(let a of o)a in s&&(i[a]=s[a]);if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}W(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Gl(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=Os(n);if(!s){p(t,404,{error:"Job not found"});return}p(t,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}f();Fe();Q();tt();function Wl(e,t){B(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"access_token is required"});return}to(s.trim(),(o||"").trim());let i=N();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&W({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Vl(e,t){let n=Le(),s=Qt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Kl(e,t){try{Ln(),N().aiEngine==="claude-oauth"&&W({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}f();Fe();pe();import{existsSync as tp,rmSync as np}from"fs";import{join as sp}from"path";function zl(e,t,n){if(e==="GET"){let s=v(),o=Lt().sort((i,a)=>a.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName}:null,sessions:o});return}if(e==="DELETE"){B(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);zr(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 Yl(e,t){B(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=vs(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 ql(e,t){B(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=sp(Je,s);if(!tp(o)){p(t,404,{error:"Theme not found on disk"});return}np(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Xl(e,t){B(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){p(t,400,{error:"Invalid name"});return}let a=Yr(s,i);a.ok?p(t,200,{ok:!0,newName:i}):p(t,400,{error:a.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}f();Fe();ae();Q();pe();te();import{existsSync as Us,readFileSync as up,rmSync as vi}from"fs";import{join as Ze,basename as mp}from"path";import{execFileSync as pp}from"child_process";var gp=process.platform==="win32"?{shell:!0}:{};function oc(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}let n=at();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1}})}function ic(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!Us(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=Ze(n,".."),i=mp(n);try{let a=`${s}.zip`,r=Ze(o,a);Us(r)&&vi(r),pp("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...gp});let l=up(r);vi(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 rc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){B(t,o=>{try{let{pageType:i,label:a}=JSON.parse(o);if(!i||!a){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=ys(i,a);j(),p(n,200,{ok:!0,template:{id:l.id,label:l.label,pageType:l.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){B(t,o=>{try{let{templateId:i,deleteModules:a}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Vr(i,!!a)){p(n,404,{error:"Template not found"});return}j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function ac(e,t){B(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!vo(s)){p(t,404,{error:"Template not found"});return}j();let i=v();p(t,200,{ok:!0,modules:X().map(a=>a.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function lc(e,t){B(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"templateId and newLabel are required"});return}if(!Wr(s,o.trim())){p(t,404,{error:"Template not found"});return}j(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function cc(e,t){B(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=Gr(s,o);if(!i){p(t,404,{error:"Template not found"});return}j(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function dc(e){let t=at();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function uc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}B(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let r=at().find(d=>d.module.moduleName===i);if(!r){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...r.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function mc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){B(t,o=>{try{let{type:i,content:a}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=a==="on",s.updatedAt=Date.now(),j(),p(n,200,{ok:!0});return}if(!a){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let r=i,l=r==="themeContext"?"theme-context.md":`${r}.md`;s.brandAssets[r]=a,s.updatedAt=Date.now();let c=Ze(s.themePath,".vibespot");Te(c),G(Ze(c,l),a),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){B(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let a=i;s.brandAssets&&delete s.brandAssets[a],s.updatedAt=Date.now();let r=a==="themeContext"?"theme-context.md":`${a}.md`,l=Ze(s.themePath,".vibespot",r);Us(l)&&vi(l),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function nc(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Ze(e.themePath,".vibespot");Te(o),G(Ze(o,s),n)}async function sc(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Bs(),Ls));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Tn(),cl)),{loadConfig:o}=await Promise.resolve().then(()=>(Q(),ji)),i=o(),{engine:a,apiKey:r,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Cs(),Oo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(tc(),ec));return m(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(xi(),Si));return u(d,e.brandAssets?.themeContext,a,r,l)}function pc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",a=o.sourcePath;if(i==="all"){let l=["styleguide","brandvoice","themeContext"],c=await Promise.allSettled(l.map(u=>sc(n,u,a))),d={};for(let u=0;u<l.length;u++){let m=c[u],g=m.status==="fulfilled"?m.value:null;g&&nc(n,l[u],g),d[l[u]]=g}j(),p(t,200,{ok:!0,type:"all",extracted:d});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let r=await sc(n,i,a);if(!r){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}nc(n,i,r),j(),p(t,200,{ok:!0,type:i,content:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function gc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:a}=JSON.parse(s),r;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Se();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:y}=await import("os"),h=Ze(y(),"vibespot-themes",".references",g);Te(h);let{fetchTheme:b}=await Promise.resolve().then(()=>(es(),er));await b(u,m,h),r=h}else if(o==="local"){if(!a){p(t,400,{error:"localPath is required for local import"});return}if(!Us(a)){p(t,400,{error:`Path not found: ${a}`});return}r=a}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(Bs(),Ls)),c=await l(r);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ze(n.themePath,".vibespot");Te(d),G(Ze(d,"styleguide.md"),c),j(),p(t,200,{ok:!0,styleguide:c,source:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}f();Fe();pe();import{join as fp}from"path";jt();function fc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function hc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=X();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){Ye(t,n,o=>{o.deleteEntirely?Dr(o.moduleName):Hr(o.moduleName),j(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function yc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=xe();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),j(),_e(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:a,content:r}=o;if(!i||!a){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(a){case"html":l.moduleHtml=r;break;case"css":l.moduleCss=r;break;case"js":l.moduleJs=r||void 0;break;case"fields":try{JSON.parse(r)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=r;break;default:p(t,400,{error:`Invalid fileType: ${a}`});return}n.updatedAt=Date.now(),j(),_e(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function bc(e,t){Ye(e,t,n=>{Array.isArray(n.order)?(Ke(n.order),j(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function Sc(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}try{_e();let n=us(t.themePath),s=Rs(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:fp(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function xc(e,t){B(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Lr(s,o,i),j(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function vc(e,t){B(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=Xi(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
1513
1770
  `),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.
1514
1771
 
1515
1772
  Source analysis found ${o.components.length} components:
@@ -1519,11 +1776,11 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
1519
1776
  Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
1520
1777
  Interactions: ${o.interactions.join(", ")}
1521
1778
 
1522
- 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 $l(e,t){let n=v();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?zi(n.themePath,o,50):Yi(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function El(e,t){R(e,n=>{try{let s=v();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(rt("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=Xi(s.themePath,i,o,r);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}gr()}else{let a=qi(s.themePath,o);if(!a.success){p(t,500,{error:a.error||"Rollback failed"});return}fr()}L(),p(t,200,{ok:!0,modules:me().map(a=>a.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}Ao();var Ml={".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(e){let{port:t,uiDir:n}=e,s=zu((i,a)=>Qu(i,a,n)),o=new Xu({server:s});return o.on("connection",i=>em(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 Qu(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/")){tm(s.pathname.slice(14),t);return}if(s.pathname==="/docs"){t.writeHead(301,{Location:"/docs/"}),t.end();return}if(s.pathname.startsWith("/docs/")){let i=s.pathname.slice(5)||"/index.html";_l(i,tt(n,"docs"),e,t);return}_l(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":xl(e,s);break;case"/api/modules":wl(e,n,s);break;case"/api/modules/reorder":Al(n,s);break;case"/api/modules/code":Cl(n,s);break;case"/api/upload":kl(s);break;case"/api/upload-files":e==="POST"?Gr(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":Il(n,s);break;case"/api/import":Tl(n,s);break;case"/api/setup":$a(s);break;case"/api/setup/create":Ea(n,s);break;case"/api/setup/fetch":_a(n,s);break;case"/api/setup/open":Pa(n,s);break;case"/api/setup/resume":Ma(n,s);break;case"/api/setup/apikey":Oa(n,s);break;case"/api/setup/remote-themes":e==="GET"?Na(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"?Da(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?Ha(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?La(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?Ua(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"?Ba(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Wa(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?Va(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Ka(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Ya(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Xa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Qa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Za(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?za(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Yo()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":el(e,n,s);break;case"/api/themes/switch":e==="POST"?tl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?nl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?sl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?$l(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?El(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?dl(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":ml(e,n,s);break;case"/api/templates/activate":e==="POST"?pl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?fl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?gl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?hl(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":bl(e,n,s);break;case"/api/brand-assets/extract":e==="POST"?Sl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?vl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?ul(s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?qa(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?yl(t,n,s):p(s,404,{error:"Not found"})}}function em(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;rt("user",o),L();let i=Array.isArray(s.fileIds)?s.fileIds:void 0,a=jo();a.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await No(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);Ro(d,{steps:l,modules:c,stats:d.stats})}else Mo(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=v();if(r){lt();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=Ki(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=v();l&&a.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&e.send(JSON.stringify({type:"suggest_brand_extraction"}))}}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"extract_brand_assets":{let o=v();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(()=>(Lo(),Ho)),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=tt(o.themePath,".vibespot");yn(y)||f(y,{recursive:!0}),h(tt(y,"theme-context.md"),m),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:y}=await Promise.resolve().then(()=>(Cs(),ws)),w=await y(o.themePath);if(w){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=w,o.updatedAt=Date.now();let x=tt(o.themePath,".vibespot");yn(x)||f(x,{recursive:!0}),h(tt(x,"styleguide.md"),w),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{lt();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}
1779
+ 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 wc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}if(!Oe()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?Or(n.themePath,o,50):Mr(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function Cc(e,t){B(e,n=>{try{let s=v();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(Re("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let a=s.templates.find(c=>c.id===i);if(!a){p(t,404,{error:"Template not found"});return}let r=a.moduleOrder.map(c=>`modules/${c}.module`);a.templateFile&&r.push(a.templateFile);let l=Fr(s.themePath,i,o,r);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}Qr()}else{let a=Rr(s.themePath,o);if(!a.success){p(t,500,{error:a.error||"Rollback failed"});return}Zr()}j(),p(t,200,{ok:!0,modules:X().map(a=>a.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}Yo();Ti();var Lc={".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 Bc(e){let{port:t,uiDir:n}=e,s=Jp((i,a)=>Hp(i,a,n)),o=new Dp({server:s});return o.on("connection",i=>Bp(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 Hp(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/")){Lp(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=No();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=Mo(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(a||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){Up(s.pathname.slice(14),t);return}if(s.pathname==="/docs"){t.writeHead(301,{Location:"/docs/"}),t.end();return}if(s.pathname.startsWith("/docs/")){let i=s.pathname.slice(5)||"/index.html";Dc(i,dt(n,"docs"),e,t);return}Dc(s.pathname,n,e,t)}function Lp(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":fc(e,s);break;case"/api/modules":hc(e,n,s);break;case"/api/modules/reorder":bc(n,s);break;case"/api/modules/code":yc(n,s);break;case"/api/upload":Sc(s);break;case"/api/upload-files":e==="POST"?Ta(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":xc(n,s);break;case"/api/import":vc(n,s);break;case"/api/setup":wl(s);break;case"/api/setup/create":Cl(n,s);break;case"/api/setup/fetch":kl(n,s);break;case"/api/setup/open":Al(n,s);break;case"/api/setup/resume":$l(n,s);break;case"/api/setup/apikey":Tl(n,s);break;case"/api/setup/remote-themes":e==="GET"?Il(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?Nl(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?Ml(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?Ol(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Rl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?Fl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?Jl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?jl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Dl(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?Hl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Ll(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Bl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Wl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Vl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Kl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Ul(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Mi()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":zl(e,n,s);break;case"/api/themes/switch":e==="POST"?Yl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?ql(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Xl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?wc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?Cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?oc(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":rc(e,n,s);break;case"/api/templates/activate":e==="POST"?ac(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?lc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?dc(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":mc(e,n,s);break;case"/api/brand-assets/extract":e==="POST"?pc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?gc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?ic(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?ki(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?Ai(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?$i(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?pl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?gl(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?Gl(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?uc(t,n,s):p(s,404,{error:"Not found"})}}function Bp(e){e.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{e.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;let i=Array.isArray(s.fileIds)?s.fileIds:void 0;if(di()){Re("user",o),j();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let r="",l=await ci(o,d=>{r+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=fl(l||r);c.plan&&(mi(c.plan),e.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&e.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),Re("assistant",c.cleanedContent),j(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}Re("user",o),j();let a=ui();a.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await Ms(o,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:m,...g}=u;e.send(JSON.stringify(g))}else e.send(JSON.stringify(u));if(u.type==="agent_step")l.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let m=l[l.length-1];m&&(m.decisions||(m.decisions=[]),m.decisions.push(u.decision))}else u.type==="design_system_ready"?oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),Ke(u.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(oe({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)})),c.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&c.push({name:u.module,status:"failed"})},i);At(d,{steps:l,modules:c,stats:d.stats})}else ai(l=>{e.send(JSON.stringify({type:"parse_warning",message:l}))}),await An(o,l=>{e.send(JSON.stringify({type:"stream",content:l}))},l=>{e.send(JSON.stringify({type:"stream_status",content:l}))},i);let r=v();if(r){_e();let l=xe(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${r.themeName}-theme.css`),l.sharedJs&&d.push(`js/${r.themeName}-animations.js`),c=bo(r.themePath,l.id,o,d)}else c=St(r.themePath,o);c&&e.send(JSON.stringify({type:"version_created",hash:c}))}e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(l=>l.moduleName)}));{let l=v();l&&a.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&e.send(JSON.stringify({type:"suggest_brand_extraction"}))}}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:a}=await Promise.resolve().then(()=>(Ti(),jc)),r=a(o);if(!r){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=v();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:y}=await import("fs"),{createThemeScaffold:h}=await Promise.resolve().then(()=>(Qn(),Zi)),b=m(g(),"vibespot-themes"),x=m(b,i);if(!y(b)){let{mkdirSync:w}=await import("fs");w(b,{recursive:!0})}y(x)||h(x,i),vt(x,i),j()}e.send(JSON.stringify({type:"figma_import_started",fileName:r.fileName}));let c=[],d=[],u=await $n(r,i,m=>{if(m.type==="module_progress"&&m.moduleFiles){let{moduleFiles:g,...y}=m;e.send(JSON.stringify(y))}else e.send(JSON.stringify(m));if(m.type==="agent_step")c.push({step:m.step,label:m.label});else if(m.type==="agent_decision"){let g=c[c.length-1];g&&(g.decisions||(g.decisions=[]),g.decisions.push(m.decision))}else m.type==="design_system_ready"?oe({sharedCss:m.sharedCss,sharedJs:m.sharedJs}):m.type==="blueprint_ready"?(oe({sharedCss:m.sharedCss,sharedJs:m.sharedJs}),Ke(m.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(g=>g.moduleName)}))):m.type==="module_progress"&&m.status==="complete"&&m.moduleFiles?(oe({modules:[{moduleName:m.module,fieldsJson:m.moduleFiles.fieldsJson,metaJson:m.moduleFiles.metaJson,moduleHtml:m.moduleFiles.moduleHtml,moduleCss:m.moduleFiles.moduleCss,moduleJs:m.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(g=>g.moduleName)})),d.push({name:m.module,status:"complete"})):m.type==="module_progress"&&m.status==="failed"&&d.push({name:m.module,status:"failed"})});At(u,{steps:c,modules:d,stats:u.stats}),_e(),St(v().themePath,`Figma import: ${r.fileName}`),e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))}catch(l){e.send(JSON.stringify({type:"error",message:l instanceof Error?l.message:String(l)}))}break}case"extract_brand_assets":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=N(),{engine:a,apiKey:r,model:l}=Vt(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Cs(),Oo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(xi(),Si)),m=await u(d,o.brandAssets?.themeContext,a,r,l),{mkdirSync:g,writeFileSync:y}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let h=dt(o.themePath,".vibespot");Nn(h)||g(h,{recursive:!0}),y(dt(h,"theme-context.md"),m),j(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:h}=await Promise.resolve().then(()=>(Bs(),Ls)),b=await h(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let x=dt(o.themePath,".vibespot");Nn(x)||g(x,{recursive:!0}),y(dt(x,"styleguide.md"),b),j(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{_e();let i=us(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(N().hubspotUploadMode||"api")==="api"){let l=Se();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await ms(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
1523
1780
  `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
1524
1781
  `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
1525
- `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=st();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(`
1526
- `),errors:d}))}}else{let l=hs(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:tt(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}))};Ca(l,c);let d=setInterval(()=>{let u=gs(l);if(!(!u||u.status==="running"))if(clearInterval(d),Aa(l,c),u.status==="completed"){let m=Fe(),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.
1782
+ `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=ut();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName}))}else{let d=cs(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
1783
+ `),errors:d}))}}else{let l=Rs(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:dt(o.themePath,".."),timeout:18e4});e.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{e.send(JSON.stringify({type:"upload_output",chunk:u}))};yl(l,c);let d=setInterval(()=>{let u=Os(l);if(!(!u||u.status==="running"))if(clearInterval(d),bl(l,c),u.status==="completed"){let m=Ue(),g=m.portalId?sn(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName}))}else{let m=ds(u.output);e.send(JSON.stringify({type:"upload_failed",output:u.output,errors:m,exitCode:u.exitCode}))}},500)}}catch(i){e.send(JSON.stringify({type:"error",message:i instanceof Error?i.message:String(i)}))}break}case"upload_fix_with_ai":{let o=String(s.errorContext||"");if(!o.trim()){e.send(JSON.stringify({type:"error",message:"No error context provided"}));break}let i=`The HubSpot upload ("hs cms upload") failed. Below is the upload log output containing the errors.
1527
1784
 
1528
1785
  IMPORTANT: Be verbose in your response. For each error:
1529
1786
  1. State exactly which file has the problem and what the error is
@@ -1536,9 +1793,9 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
1536
1793
  After fixing all errors, summarize the changes you made.
1537
1794
 
1538
1795
  Upload log:
1539
- ${o}`;rt("user",i),L(),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=v();if(a){lt();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=v();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 tm(e,t){let n=v();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=tt(n.themePath,"assets",e);if(!yn(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Pl(s),i=Ml[o]||"application/octet-stream",a=Go(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(a)}function _l(e,t,n,s){let i=tt(t,e==="/"?"/index.html":e);if(!yn(i)){let c=tt(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=Pl(i),r=Ml[a]||"application/octet-stream",l=a===".html";try{let c=Go(i),d='"'+qu("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 sm=4200;async function Nl(){let e=Is.hex("#e8613a"),t=Is.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
1540
- `));let n=om();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 Ol({port:sm,uiDir:n}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Press Ctrl+C to stop
1541
- `));try{process.platform==="darwin"?Bo("open",[i],{stdio:"ignore"}):process.platform==="win32"?Bo("cmd",["/c","start","",i],{stdio:"ignore"}):Bo("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
1542
- Saving session...`)),L(),o(),console.log(t(` Goodbye!
1543
- `)),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 om(){let e=[ks(import.meta.dirname,"../../ui"),ks(import.meta.dirname,"../ui"),ks(process.cwd(),"ui")];for(let t of e)if(nm(ks(t,"index.html")))return t;return null}Q();function Rl(){let e=new im;return e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(wt()).action(Nl),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Di),e.command("init").description("Check and install required tools").action(Hi),e.command("convert").description("Convert a React project to HubSpot modules").action(Li),e.command("upload").description("Upload theme to HubSpot").action(Ui),e.command("doctor").description("Diagnose environment issues").action(Gi),e}var rm=Rl();rm.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
1796
+ ${o}`;Re("user",i),j(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await An(i,r=>{e.send(JSON.stringify({type:"stream",content:r})),e.send(JSON.stringify({type:"upload_fix_stream",content:r}))});let a=v();if(a){_e();let r=St(a.themePath,"AI fix: upload errors");r&&e.send(JSON.stringify({type:"version_created",hash:r}))}e.send(JSON.stringify({type:"upload_fix_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(r=>r.moduleName)}))}catch(a){e.send(JSON.stringify({type:"upload_failed",output:a instanceof Error?a.message:String(a),errors:[{file:"AI fix",message:a instanceof Error?a.message:String(a),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.brandAssets?.plan;if(!i||!i.trim()){e.send(JSON.stringify({type:"error",message:"No plan to approve. Send a chat message first."}));break}W({planMode:!1});let a="Implement the approved plan.";Re("user",a),j();try{let r=[],l=[],c=await Ms(a,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:m,...g}=u;e.send(JSON.stringify(g))}else e.send(JSON.stringify(u));if(u.type==="agent_step")r.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let m=r[r.length-1];m&&(m.decisions||(m.decisions=[]),m.decisions.push(u.decision))}else u.type==="design_system_ready"?oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),Ke(u.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(oe({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)})),l.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&l.push({name:u.module,status:"failed"})});At(c,{steps:r,modules:l,stats:c.stats});let d=v();if(d){_e();let u=xe(),m=null;if(u){let g=u.moduleOrder.map(y=>`modules/${y}.module`);u.templateFile&&g.push(u.templateFile),u.sharedCss&&g.push(`css/${d.themeName}-theme.css`),u.sharedJs&&g.push(`js/${d.themeName}-animations.js`),m=bo(d.themePath,u.id,"Approved plan: implementation",g)}else m=St(d.themePath,"Approved plan: implementation");m&&e.send(JSON.stringify({type:"version_created",hash:m}))}e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(u=>u.moduleName)}))}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"plan_discard":{pi(),W({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}});let t=v();if(t){let n=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=xe();e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:X().map(i=>i.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:Oe(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",templateId:o?.id||null,pageType:o?.pageType||null,templates:(t.templates||[]).map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||""}))}else e.send(JSON.stringify({type:"needs_setup"}))}function Up(e,t){let n=v();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=dt(n.themePath,"assets",e);if(!Nn(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Hc(s),i=Lc[o]||"application/octet-stream",a=Ii(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(a)}function Dc(e,t,n,s){let i=dt(t,e==="/"?"/index.html":e);if(!Nn(i)){let c=dt(t,"index.html");if(Nn(c)){let d=Ii(c);s.writeHead(200,{"Content-Type":"text/html","Cache-Control":"no-cache"}),s.end(d)}else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not found");return}let a=Hc(i),r=Lc[a]||"application/octet-stream",l=a===".html";try{let c=Ii(i),d='"'+jp("md5").update(c).digest("hex").slice(0,16)+'"';if(n.headers["if-none-match"]===d){s.writeHead(304),s.end();return}s.writeHead(200,{"Content-Type":r,"Cache-Control":"no-cache",ETag:d}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}pe();var Wp=4200;async function Uc(){let e=Ys.hex("#e8613a"),t=Ys.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
1797
+ `));let n=Vp();n||(console.error(Ys.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await Bc({port:Wp,uiDir:n}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Press Ctrl+C to stop
1798
+ `));try{process.platform==="darwin"?Ei("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ei("cmd",["/c","start","",i],{stdio:"ignore"}):Ei("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
1799
+ Saving session...`)),j(),o(),console.log(t(` Goodbye!
1800
+ `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Ys.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Vp(){let e=[zs(import.meta.dirname,"../../ui"),zs(import.meta.dirname,"../ui"),zs(process.cwd(),"ui")];for(let t of e)if(Gp(zs(t,"index.html")))return t;return null}te();function Gc(){let e=new Kp;return e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Pt()).action(Uc),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Ar),e.command("init").description("Check and install required tools").action($r),e.command("convert").description("Convert a React project to HubSpot modules").action(Tr),e.command("upload").description("Upload theme to HubSpot").action(Ir),e.command("doctor").description("Diagnose environment issues").action(Er),e}var zp=Gc();zp.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
1544
1801
  //# sourceMappingURL=index.js.map