vibespot 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- var 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"),`[]
1
+ var Vc=Object.defineProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var ke=(e,t)=>{for(var n in t)Vc(e,n,{get:t[n],enumerable:!0})};import Qp from"path";import{fileURLToPath as tg}from"url";var f=L(()=>{"use strict"});import{readFileSync as Xs,writeFileSync as Kc,mkdirSync as Pi,existsSync as Rn}from"fs";import{dirname as zc,join as et}from"path";function E(e){return Xs(e,"utf-8")}function G(e,t){Pi(zc(e),{recursive:!0}),Kc(e,t,"utf-8")}function k(e){return Rn(e)}function Te(e){Pi(e,{recursive:!0})}function Fn(e){let t=[et(import.meta.dirname,"../../assets",e),et(import.meta.dirname,"../assets",e),et(process.cwd(),"assets",e)];for(let n of t)if(Rn(n))return n;throw new Error(`Asset not found: ${e}`)}function Nt(){if(_t)return _t;let e=[et(import.meta.dirname,"../../package.json"),et(import.meta.dirname,"../package.json"),et(process.cwd(),"package.json")];for(let t of e)if(Rn(t))try{let n=JSON.parse(Xs(t,"utf-8"));if(n.name==="vibespot"&&n.version)return _t=n.version,_t}catch{}return _t="dev",_t}function Mi(){if(On)return On;let e=[et(import.meta.dirname,"../../CHANGELOG.md"),et(import.meta.dirname,"../CHANGELOG.md"),et(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Rn(t))try{return On=Xs(t,"utf-8"),On}catch{}return""}var _t,On,te=L(()=>{"use strict";f();_t="";On=""});import{execSync as Oi}from"child_process";function J(e,t={}){try{return{stdout:Oi(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Ri(e,t={}){try{return Oi(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var ht=L(()=>{"use strict";f()});var ji={};ke(ji,{addHubSpotAccount:()=>qt,getActiveHubSpotAccount:()=>ut,getApiKeyForEngine:()=>be,getConfigDir:()=>Xc,getHubSpotPak:()=>Se,isCliToolEnabled:()=>Xt,loadConfig:()=>P,maskApiKey:()=>jn,removeHubSpotAccount:()=>Zs,saveConfig:()=>W,setActiveHubSpotAccount:()=>Qs,setCliToolEnabled:()=>eo});import{join as Fi}from"path";import{homedir as Yc}from"os";import{chmodSync as qc}from"fs";function P(){if(!k(Jn))return{};try{let e=JSON.parse(E(Jn));return e.aiEngine==="api"&&(e.aiEngine="anthropic-api"),e}catch{return{}}}function be(e,t){let n=t||P();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;default:return}}function jn(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function W(e){let n={...P(),...e};if(G(Jn,JSON.stringify(n,null,2)),process.platform!=="win32")try{qc(Jn,384)}catch{}}function Xc(){return Ji}function ut(){let e=P();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function qt(e,t,n,s){let i=P().hubspotAccounts||[],a=i.findIndex(l=>l.portalId===t),r={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};a>=0?i[a]=r:i.push(r),W({hubspotAccounts:i,activeHubSpotAccount:t})}function Zs(e){let t=P(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),W(s)}function Qs(e){W({activeHubSpotAccount:e})}function Se(){return ut()?.personalAccessKey||null}function Xt(e){return P().enabledCLITools?.includes(e)??!1}function eo(e,t){let n=P(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),W({enabledCLITools:[...s]})}var Ji,Jn,Q=L(()=>{"use strict";f();te();Ji=Fi(Yc(),".vibespot"),Jn=Fi(Ji,"config.json")});var so={};ke(so,{OAUTH_EXTRA_HEADERS:()=>Zt,OAUTH_SYSTEM_PREFIX:()=>Mt,clearOAuthTokens:()=>Ln,getOAuthTokenInfo:()=>Qt,getValidAccessToken:()=>no,hasValidOAuthToken:()=>Le,saveInitialToken:()=>to});import{join as Zc}from"path";import{homedir as Qc}from"os";import{chmodSync as ed,unlinkSync as td}from"fs";function Hn(){if(!k(Pt))return null;try{return JSON.parse(E(Pt))}catch{return null}}function Di(e){if(G(Pt,JSON.stringify(e,null,2)),process.platform!=="win32")try{ed(Pt,384)}catch{}}async function id(e){let t=await fetch(sd,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:nd})});if(!t.ok)throw Ln(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Di({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function to(e,t=""){Di({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Le(){let e=Hn();return e?e.expires_at>Date.now():!1}async function no(){let e=Hn();if(!e)return null;if(e.expires_at-Date.now()>od)return e.access_token;if(e.refresh_token){Dn||(Dn=id(e.refresh_token).finally(()=>{Dn=null}));try{await Dn}catch{return null}return Hn()?.access_token??null}return e.access_token}function Qt(){let e=Hn();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function Ln(){if(k(Pt))try{td(Pt)}catch{}}var nd,sd,Pt,od,Zt,Mt,Dn,tt=L(()=>{"use strict";f();te();nd="9d1c250a-e61b-44d9-88ed-5944d1962f5e",sd="https://console.anthropic.com/v1/oauth/token",Pt=Zc(Qc(),".vibespot","claude-oauth.json"),od=300*1e3,Zt={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},Mt="You are Claude Code, Anthropic's official CLI for Claude.";Dn=null});import{readFileSync as ld}from"fs";import{basename as cd}from"path";async function Gi(e){let t=Ui.get(e);if(t&&t.expiresAt-Date.now()>md)return t;let n=await fetch(`${nt}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:e})});if(!n.ok){let i=await n.text().catch(()=>"");throw new Error(n.status===401||n.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${n.status}): ${i.slice(0,200)}`)}let s=await n.json(),o={accessToken:s.oauthAccessToken,expiresAt:s.expiresAtMillis,hubId:s.hubId,hubName:s.hubName||""};return Ui.set(e,o),o}async function Ot(e){let{accessToken:t}=await Gi(e);return{Authorization:`Bearer ${t}`}}function Kn(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function pd(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function gd(e){return new Promise(t=>setTimeout(t,e))}async function an(e,t){let n=`HTTP ${e.status}`,s,o;try{let i=await e.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let a=i.errors[0];o=a.message||JSON.stringify(a)}}catch{try{let i=await e.text();i&&(n=i.slice(0,500))}catch{}}return{status:e.status,message:t?`${n} (${t})`:n,category:s,detail:o}}async function ln(e,t,n=dd){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=ud*Math.pow(2,s);await gd(i);continue}return o}return fetch(e,t)}async function zn(e){let t=await Gi(e),n=`${nt}/account-info/v3/details`,s=await ln(n,{headers:await Ot(e)});if(!s.ok){let r=await an(s);throw new Error(`Failed to get account info: ${r.message}`)}let o=await s.json(),i=String(o.portalId||t.hubId||""),a=t.hubName||o.uiDomain||i;return{portalId:i,portalName:a,dataCenter:pd(e)}}async function Wi(e,t,n){let s=ld(n),o=cd(n),i=new FormData,a=new Blob([s]);i.append("file",a,o);let r=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,l=await ln(r,{method:"PUT",headers:await Ot(e),body:i});if(!l.ok){let c=await an(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function ao(e,t){let n=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,s=await ln(n,{method:"DELETE",headers:await Ot(e)});if(!s.ok&&s.status!==404){let o=await an(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Vi(e,t){let n=`${nt}/cms/v3/source-code/published/content/${Kn(t)}`,s=await ln(n,{method:"GET",headers:await Ot(e)});if(!s.ok){let i=await an(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Yn(e,t){let n=`${nt}/cms/v3/source-code/published/metadata/${Kn(t)}`,s=await ln(n,{method:"GET",headers:await Ot(e)});if(s.status===404)return null;if(!s.ok){let o=await an(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Ki(e){let t=await Ot(e),n=[`${nt}/cms/v3/source-code/published/metadata`,`${nt}/cms/v3/source-code/published/metadata/`,`${nt}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let i=await o.json(),a=i.children||i.objects||(Array.isArray(i)?i:null);if(a&&a.length>0)return a.filter(r=>r.folder)}}catch{}return[]}var nt,dd,ud,md,Ui,bt=L(()=>{"use strict";f();nt="https://api.hubapi.com",dd=3,ud=1e3,md=300*1e3,Ui=new Map});var Zi={};ke(Zi,{createThemeScaffold:()=>cn});import{mkdirSync as mt,writeFileSync as Zn}from"fs";import{join as Pe}from"path";function cn(e,t){mt(e,{recursive:!0}),mt(Pe(e,"templates"),{recursive:!0}),mt(Pe(e,"modules"),{recursive:!0}),mt(Pe(e,"css"),{recursive:!0}),mt(Pe(e,"js"),{recursive:!0}),mt(Pe(e,"images"),{recursive:!0}),mt(Pe(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};Zn(Pe(e,"theme.json"),JSON.stringify(n,null,2)+`
2
+ `),Zn(Pe(e,"fields.json"),`[]
3
3
  `);let s=`<!--
4
4
  templateType: page
5
5
  isAvailableForNewContent: false
@@ -15,7 +15,7 @@ var Wc=Object.defineProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var ke=(e,t)=>{f
15
15
  %}
16
16
  {% end_dnd_area %}
17
17
  {% endblock body %}
18
- `;Zn(Ne(e,"templates","home.html"),s);let o=`<!--
18
+ `;Zn(Pe(e,"templates","home.html"),s);let o=`<!--
19
19
  templateType: none
20
20
  isAvailableForNewContent: false
21
21
  label: Base Layout
@@ -38,7 +38,7 @@ var Wc=Object.defineProperty;var L=(e,t)=>()=>(e&&(t=e(e=0)),t);var ke=(e,t)=>{f
38
38
  {{ standard_footer_includes }}
39
39
  </body>
40
40
  </html>
41
- `;mt(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(`
41
+ `;mt(Pe(e,"templates","layouts"),{recursive:!0}),Zn(Pe(e,"templates","layouts","base.html"),o)}var Qn=L(()=>{"use strict";f()});var er={};ke(er,{fetchTheme:()=>dn});import{mkdirSync as Qi,writeFileSync as bd}from"fs";import{join as Sd,dirname as xd}from"path";async function mo(e,t){let n=await Yn(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let i of o){let a=typeof i=="string"?i:i.name;if(!a)continue;let r=`${t}/${a}`;if(typeof i=="string")s.push(...await mo(e,r));else{let l=i;l.folder?s.push(...await mo(e,l.path||r)):s.push(l.path||r)}}return s}async function vd(e,t,n){let s=0;async function o(){for(;s<e.length;){let a=s++;await n(e[a])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function dn(e,t,n,s={}){let o=s.concurrency??5,i=await mo(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);Qi(n,{recursive:!0}),await vd(i,o,async a=>{let r=a.startsWith(t+"/")?a.slice(t.length+1):a,l=Sd(n,r);Qi(xd(l),{recursive:!0});let c=await Vi(e,a);bd(l,c),s.onFile?.(r)})}var es=L(()=>{"use strict";f();bt()});function Ft(e){let t=tr.get(e);if(t!==void 0)return t;try{t=E(Fn(e))}catch{t=""}return tr.set(e,t),t}function ce(){return Ft("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function po(){return Ft("design-guide.md")}function go(){return Ft("content-guide.md")}function Me(){return Ft("hubspot-rules.md")}function fo(){return Ft("humanify-guide.md")}function ho(e){let t=Ft("page-types.md");if(!t)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[e];if(!s)return"";let o=t.indexOf(s);if(o<0)return"";let i=t.indexOf(`
42
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.
43
43
 
44
44
  ## Rules
@@ -131,21 +131,22 @@ Template requirements:
131
131
  - Each module in its own dnd_section with padding zeroed and full_width=true
132
132
  - dnd_area label: "${t} Landing Page"
133
133
 
134
- Return ONLY the template HTML content, no markdown fences.`}var tr,ot=L(()=>{"use strict";f();te();tr=new Map});var _r=L(()=>{"use strict";f()});import{existsSync as rt,writeFileSync as 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+`
134
+ Return ONLY the template HTML content, no markdown fences.`}var tr,ot=L(()=>{"use strict";f();te();tr=new Map});var _r=L(()=>{"use strict";f()});import{existsSync as rt,writeFileSync as Yd,mkdirSync as qd}from"fs";import{join as Ve}from"path";function Pr(e){return/^[0-9a-f]{4,40}$/i.test(e)}function Oe(){return ps!==null||(ps=J("git --version").success),ps}function gs(e){if(!Oe())return!1;if(rt(Ve(e,".git")))return Nr(e),!0;let t=J("git init",{cwd:e});return t.success?(Xd(e),Nr(e),J("git add -A",{cwd:e}),J('git commit -m "Initial theme"',{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Nr(e){let t=Ve(e,".vibespot");rt(t)||qd(t,{recursive:!0})}function Xd(e){let t=Ve(e,".gitignore");Yd(t,[".vibespot/","node_modules/",""].join(`
135
+ `),"utf-8")}function St(e,t){if(!Oe()||!rt(Ve(e,".git"))||(J("git add -A",{cwd:e}),J("git diff --cached --quiet",{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=J(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=J("git rev-parse --short HEAD",{cwd:e});return i.success?i.stdout:null}function bo(e,t,n,s){if(!Oe()||!rt(Ve(e,".git")))return null;for(let u of s){let m=Ve(e,u);rt(m)&&J(`git add "${u}"`,{cwd:e})}if(J("git diff --cached --quiet",{cwd:e}).success)return null;let i=`[${t}] `,a=72-i.length,r=n.length>a?n.slice(0,a-3)+"...":n,l=i+r,c=J(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=J("git rev-parse --short HEAD",{cwd:e});return d.success?d.stdout:null}function Mr(e,t=50){if(!Oe())return[];if(!rt(Ve(e,".git")))return[];let n=J(`git log --pretty=format:"%h|%H|%s|%at" -n ${t}`,{cwd:e});if(!n.success||!n.stdout.trim())return[];let s=[];for(let o of n.stdout.split(`
136
+ `)){let i=o.split("|");if(i.length<4)continue;let a=parseInt(i[3],10)*1e3;s.push({hash:i[0],fullHash:i[1],message:i[2],timestamp:a,date:new Date(a).toISOString()})}return s}function Or(e,t,n=50){if(!Oe())return[];if(!rt(Ve(e,".git")))return[];let s=t.replace(/[[\]\\]/g,"\\$&"),o=J(`git log --grep="\\[${s}\\]" --pretty=format:"%h|%H|%s|%at" -n ${n}`,{cwd:e});if(!o.success||!o.stdout.trim())return[];let i=[];for(let a of o.stdout.split(`
137
+ `)){let r=a.split("|");if(r.length<4)continue;let l=parseInt(r[3],10)*1e3;i.push({hash:r[0],fullHash:r[1],message:r[2],timestamp:l,date:new Date(l).toISOString()})}return i}function Rr(e,t){if(!Oe())return{success:!1,error:"Git not available"};if(!rt(Ve(e,".git")))return{success:!1,error:"Not a git repo"};if(!Pr(t))return{success:!1,error:"Invalid commit hash"};let n=J(`git cat-file -t ${t}`,{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=J(`git log --format="%s" -1 ${t}`,{cwd:e}),o=s.success?s.stdout:t,i=J(`git checkout ${t} -- .`,{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let a=`Rollback to: ${o}`.slice(0,72);return J(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}function Fr(e,t,n,s){if(!Oe())return{success:!1,error:"Git not available"};if(!rt(Ve(e,".git")))return{success:!1,error:"Not a git repo"};if(!Pr(n))return{success:!1,error:"Invalid commit hash"};let o=J(`git cat-file -t ${n}`,{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=J(`git log --format="%s" -1 ${n}`,{cwd:e}),a=i.success?i.stdout:n,r=0;for(let d of s)J(`git checkout ${n} -- "${d}"`,{cwd:e}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};J("git add -A",{cwd:e});let c=`${`[${t}] `}Rollback to: ${a}`.slice(0,72);return J(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:e}),{success:!0}}var ps,jt=L(()=>{"use strict";f();ht();ps=null});import{appendFileSync as Zd,mkdirSync as Qd,readdirSync as eu,unlinkSync as tu}from"fs";import{join as wo}from"path";import{homedir as nu}from"os";function ou(){if(!xo)try{Qd(fs,{recursive:!0}),xo=!0}catch{}}function iu(){if(!vo){vo=!0;try{let e=Date.now()-su*864e5;for(let t of eu(fs)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{tu(wo(fs,t))}catch{}}}catch{}}}function ru(){let t=new Date().toISOString().slice(0,10);return wo(fs,`vibespot-${t}.log`)}function au(){return new Date().toISOString().slice(11,23)}function So(e,t){if(ou(),!!xo){vo||iu();try{Zd(ru(),`${au()} ${e} ${t}
138
+ `)}catch{}}}var fs,su,xo,vo,A,ie=L(()=>{"use strict";f();fs=wo(nu(),".vibespot","logs"),su=7,xo=!1,vo=!1;A={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),So("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),So("WARN",s)},error(e,t,n){let s=n instanceof Error?n.message:n?String(n):"",o=s?`[${e}] ${t}: ${s}`:`[${e}] ${t}`;console.error(o),So("ERROR",o)}}});import{readFileSync as lu,existsSync as jr,writeFileSync as cu,mkdirSync as du,rmSync as uu}from"fs";import{join as hs}from"path";function xt(e){let t=v();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages)}function pt(){let e=v();if(!e)return;let t=xe();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages)}function Re(e,t,n){let s=v();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),pt(),pu()}function Dr(e){let t=v();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),j())}function Jr(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function mu(e,t){let n=Jr(e),s=Jr(t);return n===s?!0:n.length<4||s.length<4?!1:n.includes(s)||s.includes(n)}function oe(e){let t=v();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let i=t.modules.find(a=>mu(a.moduleName,n.moduleName));i&&A.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${i.moduleName}" \u2014 adding as a new module. This usually indicates the Module Planner re-named an existing module. Check the prompt's "preserve existing names" rule.`),t.modules.push(n),t.moduleOrder.some(a=>a.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),pt()}}function Ke(e){let t=v();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),pt())}function Hr(e){let t=v();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=hs(t.themePath,"modules",`${e}.module`);jr(n)&&uu(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),pt()}}function Lr(e){let t=v();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),pt())}function Br(e,t,n){let s=v();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);Gr(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),pt()}catch{}}function X(){let e=v();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function pu(){let e=v();if(e)try{let t=hs(e.themePath,".vibespot");du(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};cu(hs(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Ur(e){let t=hs(e,".vibespot","chat.json");if(!jr(t))return[];try{let n=JSON.parse(lu(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Gr(e,t,n){let s=t.split("."),o=s[0],i=e.find(a=>a.name===o);i&&(s.length===1?i.default=n:i.children&&Gr(i.children,s.slice(1).join("."),n))}var pn=L(()=>{"use strict";f();gn();Dt();ie()});import{existsSync as Co,rmSync as ko}from"fs";import{join as fn}from"path";function ys(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function xe(){let e=v();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function Ao(e){let t=v();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,xt(n),t.updatedAt=Date.now(),!0):!1}function bs(e,t){let n=v();if(!n)throw new Error("No active session");let s=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${s}`,a={id:i,label:t,pageType:e,templateFile:e==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(a),n.activeTemplateId=i,xt(a),n.updatedAt=Date.now(),a}function Wr(e,t){let n=v();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),r=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:r,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${r}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[]};return n.templates.push(l),n.activeTemplateId=r,xt(l),n.updatedAt=Date.now(),l}function Vr(e,t){let n=v();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function Kr(e,t=!1){let n=v();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=fn(n.themePath,"templates"),a=`${o.id}.html`,r=fn(i,a);if(Co(r)&&ko(r,{force:!0}),o.pageType==="blog_post"){let l=fn(i,`${o.id}-listing.html`);Co(l)&&ko(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let r of n.templates)for(let l of r.modules)i.add(l.moduleName);for(let r of n.modules)i.add(r.moduleName);let a=o.modules.map(r=>r.moduleName).filter(r=>!i.has(r));if(n.themePath&&a.length>0){let r=fn(n.themePath,"modules");for(let l of a){let c=fn(r,`${l}.module`);Co(c)&&ko(c,{recursive:!0,force:!0})}}}return n.activeTemplateId===e&&(n.templates.length>0?Ao(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[])),n.updatedAt=Date.now(),!0}function at(){let e=v();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}return Array.from(t.values())}var Dt=L(()=>{"use strict";f();gn();pn()});import{readFileSync as lt,readdirSync as _o,existsSync as ve,writeFileSync as Ss,mkdirSync as zr,rmSync as $o,renameSync as To}from"fs";import{join as ue,dirname as gu}from"path";import{homedir as fu}from"os";function xs(){if(Ht)return Ht;try{return ve(Io)?(Ht=JSON.parse(lt(Io,"utf-8")),Ht):Eo()}catch{return Eo()}}function vs(e){Ht=e;try{zr(re,{recursive:!0}),Ss(Io,JSON.stringify(e),"utf-8")}catch{}}function Eo(){if(!ve(re))return[];let e=[];for(let t of _o(re).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(lt(ue(re,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length})}catch{}return Ht=e,vs(e),e}function hu(e){let t=xs(),n=e.templates||[],s={id:e.id,themeName:e.themeName,updatedAt:e.updatedAt,moduleCount:n.reduce((i,a)=>i+(a.modules?.length||0),0),templateCount:n.length},o=t.findIndex(i=>i.id===e.id);o>=0?t[o]=s:t.push(s),vs(t)}function yu(e){let t=xs().filter(n=>n.id!==e);vs(t)}function bu(e){let t=xs().filter(n=>n.themeName!==e);vs(t)}function v(){return we}function Su(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function vt(e,t){let n={id:Su(),themePath:e,themeName:t,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return we=n,gs(e),n}function j(){if(!we)return;zr(re,{recursive:!0});let e=ue(re,`${we.id}.json`);Ss(e,JSON.stringify(we,null,2),"utf-8"),hu(we)}function ws(e){let t=ue(re,e+".json");if(!ve(t))return null;try{let n=JSON.parse(lt(t,"utf-8"));return n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),ys(n),we=n,n}catch{return null}}function Lt(){return ve(re)?xs():[]}function Yr(e,t=!1){let n=ue(re,e+".json"),s="";if(t)try{let o=JSON.parse(lt(n,"utf-8"));s=o.themeName||"",o.themePath&&ve(o.themePath)&&$o(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(lt(n,"utf-8")).themeName||""}catch{}try{ve(n)&&$o(n)}catch{}if(s&&ve(re)){for(let o of _o(re).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(lt(ue(re,o),"utf-8")).themeName===s&&$o(ue(re,o))}catch{}bu(s)}else yu(e);we?.id===e&&(we=null)}function qr(e,t){let n=ue(re,e+".json");if(!ve(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(lt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,a=ue(gu(i),t);if(ve(i)){if(ve(a))return{ok:!1,error:"A project with that name already exists"};try{To(i,a)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let r=ue(a,"css",`${o}-theme.css`),l=ue(a,"css",`${t}-theme.css`);if(ve(r))try{To(r,l)}catch{}let c=ue(a,"js",`${o}-animations.js`),d=ue(a,"js",`${t}-animations.js`);if(ve(c))try{To(c,d)}catch{}let u=ue(a,"theme.json");if(ve(u))try{let m=JSON.parse(lt(u,"utf-8"));m.label=t,m.name=t,Ss(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(ve(re))for(let r of _o(re).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(lt(ue(re,r),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=a,l.updatedAt=Date.now(),Ss(ue(re,r),JSON.stringify(l,null,2),"utf-8"))}catch{}return we&&we.themeName===o&&(we.themeName=t,we.themePath=a,we.updatedAt=Date.now()),Eo(),{ok:!0}}var re,Io,Ht,we,gn=L(()=>{"use strict";f();jt();Dt();re=ue(fu(),".vibespot","sessions"),Io=ue(re,"_index.json"),Ht=null;we=null});import{readFileSync as No,readdirSync as yn,existsSync as me,writeFileSync as Ee,mkdirSync as hn,rmSync as Xr}from"fs";import{join as D}from"path";function ae(e){try{return No(e,"utf-8")}catch{return""}}function xu(e){let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function vu(e,t){let n=ae(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o="landing_page";s.startsWith("bp-")?o="blog_post":s.startsWith("wp-")?o="website_page":s.startsWith("mo-")&&(o="module_only");let i=s,a=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);a&&(i=a[1].trim());let r=/dnd_module\s+path=["']\.\.\/modules\/(.+?)\.module["']/g,l=[],c;for(;(c=r.exec(n))!==null;)l.push(c[1]);return{id:s,label:i,pageType:o,moduleNames:l,templateContent:n,filename:t}}function wu(e,t,n,s,o){if(!me(e))return[];let i=[],a=yn(e).filter(r=>r.endsWith(".html")&&r!=="home.html");for(let r of a){let l=D(e,r),c=vu(l,r);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let g=t.get(m);g&&(d.push(g),u.push(m))}i.push({id:c.id,label:c.label,pageType:c.pageType,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:n,sharedJs:s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function bn(e){let t=v();if(!t)return;let n=Ur(e);n.length>0&&t.messages.length===0&&(t.messages=n),gs(e);let s=D(e,"modules");if(!me(s))return;let o=yn(s,{withFileTypes:!0});for(let b of o){if(!b.isDirectory()||!b.name.endsWith(".module"))continue;let x=D(s,b.name),w=b.name.replace(/\.module$/,""),S={moduleName:w,fieldsJson:ae(D(x,"fields.json")),metaJson:ae(D(x,"meta.json")),moduleHtml:ae(D(x,"module.html")),moduleCss:ae(D(x,"module.css")),moduleJs:ae(D(x,"module.js"))||void 0};S.fieldsJson&&S.moduleHtml&&(t.modules.push(S),t.moduleOrder.push(w))}let i=D(e,"css"),a=D(e,"js"),r="",l="";if(me(i)){let b=yn(i).filter(x=>x.endsWith("-theme.css"));b.length>0&&(r=ae(D(i,b[0])),t.sharedCss=r)}if(me(a)){let b=yn(a).filter(x=>x.endsWith("-animations.js"));b.length>0&&(l=ae(D(a,b[0])),t.sharedJs=l)}let c=D(e,".vibespot","styleguide.md"),d=D(e,".vibespot","brandvoice.md"),u=D(e,".vibespot","theme-context.md"),m=D(e,".vibespot","plan.md");(me(c)||me(d)||me(u)||me(m))&&(t.brandAssets||(t.brandAssets={}),me(c)&&(t.brandAssets.styleguide=ae(c)),me(d)&&(t.brandAssets.brandvoice=ae(d)),me(u)&&(t.brandAssets.themeContext=ae(u)),me(m)&&(t.brandAssets.plan=ae(m)));let g=D(e,"templates"),y=new Map(t.modules.map(b=>[b.moduleName,b])),h=wu(g,y,r,l,t.messages);if(h.length>0){t.templates=h,t.activeTemplateId=h[0].id;let b=h[0].moduleOrder;if(b.length>0){let x=new Set(t.moduleOrder),w=b.filter(S=>x.has(S));for(let S of t.moduleOrder)w.includes(S)||w.push(S);t.moduleOrder=w}xt(h[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),ys(t)}function _e(){let e=v();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=D(t,"modules");hn(s,{recursive:!0});for(let l of n.values())hn(D(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=D(s,`${l.moduleName}.module`);Ee(D(c,"fields.json"),l.fieldsJson,"utf-8"),Ee(D(c,"meta.json"),l.metaJson,"utf-8"),Ee(D(c,"module.html"),l.moduleHtml,"utf-8"),Ee(D(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ee(D(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=D(t,"css");hn(l,{recursive:!0}),Ee(D(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=D(t,"js");hn(l,{recursive:!0}),Ee(D(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=D(t,"templates");hn(o,{recursive:!0});let i=D(o,"home.html");(e.templates.length>0||e.modules.length>0)&&me(i)&&Xr(i,{force:!0});let r=new Set;if(e.templates.length>0)for(let l of e.templates){if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||Au(l),d=Zr(c,l.label,l.pageType),u=`${l.id}.html`;Ee(D(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&($u(o,l),r.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||Tu(),c=Zr(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ee(D(o,d),c,"utf-8"),r.add(d)}try{for(let l of yn(o))l.startsWith("lp-")&&l.endsWith(".html")&&!r.has(l)&&Xr(D(o,l),{force:!0})}catch{}Cu(),ku()}function Qr(){let e=v();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",bn(e.themePath),e.updatedAt=Date.now(),pt())}function ea(){let e=v();if(!e)return;let t=xe();if(!t)return;let n=e.themePath,s=D(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=D(s,`${o}.module`);if(!me(i))continue;let a={moduleName:o,fieldsJson:ae(D(i,"fields.json")),metaJson:ae(D(i,"meta.json")),moduleHtml:ae(D(i,"module.html")),moduleCss:ae(D(i,"module.css")),moduleJs:ae(D(i,"module.js"))||void 0};a.fieldsJson&&a.moduleHtml&&t.modules.push(a)}if(t.templateFile){let o=D(n,t.templateFile);me(o)&&(t.template=ae(o))}xt(t),e.updatedAt=Date.now()}function Cu(){let e=v();if(!e)return;let t=D(e.themePath,"templates","layouts","base.html");if(me(t))try{let n=No(t,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
138
139
  {% if template_js %}
139
140
  {{ require_js(get_asset_url(template_js)) }}
140
141
  {% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
141
142
  {{ require_js(get_asset_url(template_js)) }}
142
143
  {% endif %}
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:`<!--
144
+ {{ standard_footer_includes }}`),Ee(t,n,"utf-8")}catch{}}function ku(){let e=v();if(!e)return;let t=D(e.themePath,"theme.json");if(me(t))try{let n=JSON.parse(No(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ee(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Zr(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
144
145
  templateType: ${n==="blog_post"?"blog_post":"page"}
145
146
  isAvailableForNewContent: true
146
147
  label: "${t}"
147
148
  -->
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 %}
149
+ `+e}function Au(e){if(e.modules.length===0)return"";let n=v().themeName,o=xu(e).map(a=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
149
150
  {% dnd_module path="../modules/${a.moduleName}.module" %}
150
151
  {% end_dnd_module %}
151
152
  {% end_dnd_section %}`).join(`
@@ -176,7 +177,7 @@ ${o}
176
177
 
177
178
  {% block footer %}
178
179
  {% endblock footer %}
179
- `}function gu(e,t){let n=`<!--
180
+ `}function $u(e,t){let n=`<!--
180
181
  templateType: blog_listing
181
182
  isAvailableForNewContent: true
182
183
  label: "${t.label} - Listing"
@@ -201,7 +202,7 @@ ${o}
201
202
  {% endif %}
202
203
  </div>
203
204
  {% endblock body %}
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 %}
205
+ `;Ee(D(e,`${t.id}-listing.html`),n,"utf-8")}function Tu(){let e=v();if(!e||e.modules.length===0)return"";let t=e.themeName,s=X().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
205
206
  {% dnd_module path="../modules/${o.moduleName}.module" %}
206
207
  {% end_dnd_module %}
207
208
  {% end_dnd_section %}`).join(`
@@ -232,7 +233,7 @@ ${s}
232
233
 
233
234
  {% block footer %}
234
235
  {% endblock footer %}
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(`
236
+ `}var Po=L(()=>{"use strict";f();gn();pn();Dt();jt()});var ta=L(()=>{"use strict";f();_r();gn();pn();Po();Dt()});var pe=L(()=>{"use strict";f();ta()});function Cs(e){let t={};for(let n of e)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?t[n.name]=n.default:n.type==="group"&&n.children?t[n.name]=Cs(n.children):t[n.name]=n.default??"";return t}function Oo(e,t){let n=e;return n=Fu(n),n=ia(n,t),n=ra(n,t),n=aa(n,t),n=ju(n),n}function Ro(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
236
237
  `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
237
238
  `),s=e.renderedModules.join(`
238
239
  `);return`<!DOCTYPE html>
@@ -279,11 +280,11 @@ document.querySelectorAll('img').forEach(function(img){
279
280
  });
280
281
  </script>
281
282
  </body>
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}">
283
+ </html>`}function Fu(e){return e=e.replace(Iu,""),e=e.replace(Eu,""),e=e.replace(_u,""),na.lastIndex=0,e=e.replace(na,(t,n)=>`/theme-assets/${n}`),sa.lastIndex=0,e=e.replace(sa,""),e=e.replace(Nu,""),e=e.replace(Pu,""),e=e.replace(Mu,""),e=e.replace(Ou,""),e=e.replace(Ru,""),e}function ia(e,t){let n=e,s=0;for(;s<30;){s++;let o=Ju(n);if(!o)break;let{varName:i,iterExpr:a,body:r,start:l,end:c}=o,d=Du(a,t),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let y={...t,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},h=ia(r,y);return h=ra(h,y),h=aa(h,y),h}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Ju(e){let t=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=t.exec(e);if(!s)return null;let o=s[1],i=s[2],a=s.index+s[0].length;n.lastIndex=a;let r=1,l;for(;(l=n.exec(e))!==null;)if(l[1].startsWith("for"))r++;else if(r--,r===0){let c=e.slice(a,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function ra(e,t){let n=e,s=0;for(;Mo.test(n)&&s<50;)s++,n=n.replace(Mo,(o,i,a)=>{let r=a.split(/\{%[-\s]*else\s*-?%\}/),l=r[0],c=r[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(Bt(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(Bt(m,t))return g}return c}return Bt(i,t)?l:c}),Mo.lastIndex=0;return n}function aa(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),a=i[0].trim(),r=wt(t,a);for(let c=1;c<i.length;c++)r=ca(r,i[c].trim());if(r==null)return"";if(typeof r=="object")return JSON.stringify(r);let l=String(r);return l=l.replace(/\\n/g," ").replace(/\n/g," "),l})}function ju(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Du(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=oa(n[1],t),i=oa(n[2],t),a=[];for(let r=o;r<i;r++)a.push(r);return a}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=wt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return wt(t,e)}function oa(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=wt(t,o);for(let a=1;a<s.length;a++)i=ca(i,s[a].trim());return Number(i)||0}function wt(e,t){let n=t.split("."),s=e;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function Bt(e,t){let n=e.trim();if(n.startsWith("not "))return!Bt(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Bt(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Bt(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=wt(t,s[1].trim()),a=s[2],r=s[3].trim();switch(typeof r=="string"&&r.startsWith('"')&&r.endsWith('"')||typeof r=="string"&&r.startsWith("'")&&r.endsWith("'")?r=r.slice(1,-1):isNaN(Number(r))?r=wt(t,r):r=Number(r),a){case"==":return i==r;case"!=":return i!=r;case">":return Number(i)>Number(r);case"<":return Number(i)<Number(r);case">=":return Number(i)>=Number(r);case"<=":return Number(i)<=Number(r)}}let o=wt(t,n);return la(o)}function la(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function ca(e,t){let n=e==null?"":String(e),s=t.match(/^(\w+)\((.*)\)$/),o=s?s[1]:t,i=s?s[2].replace(/^["']|["']$/g,""):void 0;switch(o){case"escape":case"e":return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");case"lower":return n.toLowerCase();case"upper":return n.toUpperCase();case"capitalize":return n.charAt(0).toUpperCase()+n.slice(1);case"trim":return n.trim();case"truncate":if(i){let a=parseInt(i,10);return n.length>a?n.slice(0,a)+"...":n}return n;case"default":return la(e)?e:i??"";case"length":return Array.isArray(e)?e.length:n.length;case"join":return Array.isArray(e)?e.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));default:return e}}var Iu,Eu,_u,na,sa,Nu,Pu,Mu,Ou,Ru,Mo,da=L(()=>{"use strict";f();Iu=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Eu=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,_u=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,na=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,sa=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Nu=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Pu=/\{%[-\s]*module\b.*?%\}/gs,Mu=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Ou=/\{#.*?#\}/gs,Ru=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Mo=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var jo={};ke(jo,{buildModulePreviewHtml:()=>Jo,buildPreviewHtml:()=>Fo});function Hu(e){if(!e)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let t=(r,l)=>{for(let c of r){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=e.match(d);if(u)return u[1].trim()}return l},n=t(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=t(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=t(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=t(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),a=t(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:a}}function Fo(){let e=v();if(!e)return ua();let t=X(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return ua();let s=[],o=[],i=[],a=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d;try{let g=JSON.parse(c.fieldsJson);d={module:Cs(g)}}catch{d={module:{}}}let u=Oo(c.moduleHtml,d),m=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${m}" data-module="${c.moduleName}">${u}</div>`),a.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let r=Hu(e.sharedCss);for(let c of n)if(!a.has(c)){let d=c.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module vibespot-module--pending" id="${d}" data-module="${c}">
283
284
  <div class="vibespot-placeholder">
284
285
  <div class="vibespot-placeholder__name">${c}</div>
285
286
  </div>
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>
287
+ </div>`)}let l=`body{background:${r.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${r.surface};border:1px dashed ${r.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${r.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return Ro({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function ua(){return`<!DOCTYPE html>
287
288
  <html lang="en">
288
289
  <head>
289
290
  <meta charset="utf-8">
@@ -334,8 +335,7 @@ document.querySelectorAll('img').forEach(function(img){
334
335
  <div class="welcome__sub">Build Something Great</div>
335
336
  </div>
336
337
  </body>
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
338
+ </html>`}function Jo(e){let t=v();if(!t)return"";let n;for(let i of t.templates)if(n=i.modules.find(a=>a.moduleName===e),n)break;if(n||(n=t.modules.find(i=>i.moduleName===e)),!n)return"";let s;try{let i=JSON.parse(n.fieldsJson);s={module:Cs(i)}}catch{s={module:{}}}let o=Oo(n.moduleHtml,s);return Ro({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${o}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}var ks=L(()=>{"use strict";f();da();pe()});function ze(e){try{return JSON.parse(e)}catch{}let t=e,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(t)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let a=parseInt(i[1],10);if(a<=n)return null;n=a;let r=Math.max(0,a-5),c=t.slice(r,a+1).lastIndexOf('"');if(c===-1)return null;let d=r+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function Sn(e){let t=e.indexOf('"modules"');if(t===-1)return null;let n=e.indexOf("[",t);if(n===-1)return null;let s=-1,o=0,i=!1,a=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(a){a=!1;continue}if(u==="\\"){a=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=e.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ze(c)}function Do(e){return{moduleName:String(e.moduleName||""),fieldsJson:typeof e.fieldsJson=="string"?e.fieldsJson:JSON.stringify(e.fieldsJson,null,2),metaJson:typeof e.metaJson=="string"?e.metaJson:JSON.stringify(e.metaJson,null,2),moduleHtml:String(e.moduleHtml||""),moduleCss:String(e.moduleCss||""),moduleJs:e.moduleJs?String(e.moduleJs):void 0}}function ma(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{A.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ze(s[1]);if(!i||typeof i!="object")throw A.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let a=i;a.modules&&Array.isArray(a.modules)&&(oe({modules:a.modules.map(r=>Do(r)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(i){A.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let a=ze(s[1]);if(!a||typeof a!="object")throw new Error("Invalid JSON after repair");let r=a;r.modules&&Array.isArray(r.modules)&&(oe({modules:r.modules.map(l=>Do(l)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(a){A.warn("parse","Failed to parse JSON module block",{error:a instanceof Error?a.message:String(a)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){A.info("parse","Detected truncated response (odd fence count), attempting salvage");let a=e.lastIndexOf("```"),r=e.slice(a+3);r=r.replace(/^[\w-]*\s*\n?/,"");let l=Sn(r);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(A.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),oe({modules:c.modules.map(d=>Do(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){A.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),a=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(i||a){let r=i?"Module changes could not be applied \u2014 the AI response contained invalid JSON. Try sending your request again.":"The AI described modules but did not include the required structured data. Try sending your request again.";A.warn("parse",r),t&&t(r)}}}var As=L(()=>{"use strict";f();pe();ie()});function Ut(){let e=v();return e?{pageType:xe()?.pageType,brandAssets:e.brandAssets}:{}}function pa(e,t,n=!1,s,o){let a=[{type:"text",text:Bu(t,n)}];if(n){let l=`## HubSpot CMS Rules
339
339
  ${Me()}
340
340
 
341
341
  ## Conversion Guide Reference
@@ -371,13 +371,13 @@ ${go()}
371
371
  ${Me()}
372
372
 
373
373
  ## Conversion Guide Reference
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
374
+ ${e}`;a.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let r=Lu(s,o);return r&&a.push({type:"text",text:r}),a.push({type:"text",text:"## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory."}),a}function Lu(e,t){let n=[];if(e){let s=ho(e);s&&n.push(`## Page Type Context
375
375
  ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
376
376
  ${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
377
377
  ${t.brandvoice}`),t?.humanify!==!1){let s=fo();s&&n.push(`## Anti-AI Copy Rules (Humanify)
378
378
  ${s}`)}return n.join(`
379
379
 
380
- `)}function Hu(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
380
+ `)}function Bu(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
381
381
 
382
382
  ## Your Role
383
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.
@@ -644,49 +644,49 @@ ${i}`),a&&(r+=a),r+="\n\n---\nRemember: respond with a ```vibespot-modules JSON
644
644
  [Attached document: ${d.originalName}]
645
645
  ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(r+=`
646
646
 
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(`
647
+ [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?t.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:r}),o.push({role:"user",content:d})}else o.push({role:"user",content:r});return o}var ga=L(()=>{"use strict";f();ot();pe()});import{spawn as fa}from"child_process";async function ha(){return Lo||(Lo=(await import("@anthropic-ai/sdk")).default),Lo}function ya(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
648
648
  [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
649
649
 
650
650
  ---
651
651
  [Attached document: ${n.originalName}]
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}
652
+ ${n.extractedText}`);return t.join("")}async function ba(e,t,n,s,o,i,a){for(let r=0;;r++)try{let l="",c=0,d=i||(()=>{});d(ye[0]);let u=setInterval(()=>{c++,d(ye[Math.min(c,ye.length-1)])},6e3);try{let m=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});for await(let g of m)if(g.type==="content_block_delta"&&g.delta.type==="text_delta"){let y=g.delta.text;l+=y,o(y)}}finally{clearInterval(u)}a&&a(l);return}catch(l){let c=l.status,d=l.error?.type;if(!(c===429||d==="rate_limit_error"||l instanceof Error&&l.message.includes("429"))||r>=Bo.length)throw l;let m=Bo[r];A.warn("ai-engine",`Rate limited (429), attempt ${r+1}/${Bo.length} \u2014 waiting ${m}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${m}s...`),await new Promise(g=>setTimeout(g,m*1e3)),i&&i("Retrying...")}}function Sa(e,t,n){let s=ce(),i=v().modules.length>0,a=Ho(e,n),r=Ut(),l=pa(s,t,i,r.pageType,r.brandAssets);return{messages:a,systemBlocks:l,conversionGuide:s,editMode:i}}async function xa(e,t,n,s,o,i,a,r){let l=await ha(),c=new l({apiKey:t}),{messages:d,systemBlocks:u}=Sa(e,n,r);A.info("anthropic","API call",{model:s,systemBlockCount:u.length,cachedBlocks:u.filter(m=>m.cache_control).length,messageCount:d.length}),await ba(c,u,d,s,o,i,a)}async function va(e,t,n,s,o,i,a){let r=await no();if(!r)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await ha(),c=new l({authToken:r,defaultHeaders:Zt}),{messages:d,systemBlocks:u}=Sa(e,t,a),m=[{type:"text",text:Mt},...u];A.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await ba(c,m,d,n,s,o,i)}async function wa(e,t,n,s,o,i,a,r){let l=ce(),c=v().modules.length>0,d=Ho(e,r),u=Ut(),m=d.map(O=>typeof O.content=="string"?O:{role:O.role,content:O.content.map(R=>R.type==="text"?{type:"text",text:R.text}:{type:"image_url",image_url:{url:`data:${R.source.media_type};base64,${R.source.data}`}})}),g=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:xn(l,n,c,u.pageType,u.brandAssets)},...m]})});if(!g.ok){let O=await g.text();throw new Error(`OpenAI API error (${g.status}): ${O}`)}let y=0,h=i||(()=>{});h(ye[0]);let b=setInterval(()=>{y++,h(ye[Math.min(y,ye.length-1)])},6e3),x="",w=g.body.getReader(),S=new TextDecoder,M="";try{for(;;){let{done:O,value:R}=await w.read();if(O)break;M+=S.decode(R,{stream:!0});let H=M.split(`
653
+ `);M=H.pop()||"";for(let z of H){if(!z.startsWith("data: "))continue;let _=z.slice(6).trim();if(_==="[DONE]")break;try{let C=JSON.parse(_).choices?.[0]?.delta?.content;C&&(x+=C,o(C))}catch{}}}}finally{clearInterval(b)}a&&a(x)}async function Ca(e,t,n,s,o,i,a){let r=ce(),l=v(),c=l.modules.length>0,d=vn(),u=Ut(),m=[];for(let _ of l.messages.slice(-20))m.push({role:_.role==="assistant"?"model":"user",parts:[{text:_.content}]});let g=d?`${e}
654
654
 
655
655
  ---
656
- ${d}`:e;if(a?.length)for(let P of a)P.type==="document"&&P.extractedText&&(g+=`
656
+ ${d}`:e;if(a?.length)for(let _ of a)_.type==="document"&&_.extractedText&&(g+=`
657
657
 
658
658
  ---
659
- [Attached document: ${P.originalName}]
660
- ${P.extractedText}`),P.type==="image"&&P.usage==="asset"&&P.assetPath&&(g+=`
659
+ [Attached document: ${_.originalName}]
660
+ ${_.extractedText}`),_.type==="image"&&_.usage==="asset"&&_.assetPath&&(g+=`
661
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}.
662
+ [Uploaded image: ${_.originalName} \u2192 available as get_asset_url("${_.assetPath}")]`);let y=[];if(a?.length)for(let _ of a)_.type==="image"&&_.base64&&y.push({inlineData:{mimeType:_.mimeType,data:_.base64}});y.push({text:g}),m.push({role:"user",parts:y});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${t}`,x=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:xn(r,n,c,u.pageType,u.brandAssets)}]},contents:m,generationConfig:{maxOutputTokens:48e3}})});if(!x.ok){let _=await x.text();throw new Error(`Gemini API error (${x.status}): ${_}`)}let w=0,S=o||(()=>{});S(ye[0]);let M=setInterval(()=>{w++,S(ye[Math.min(w,ye.length-1)])},6e3),O="",R=x.body.getReader(),H=new TextDecoder,z="";try{for(;;){let{done:_,value:F}=await R.read();if(_)break;z+=H.decode(F,{stream:!0});let C=z.split(`
663
+ `);z=C.pop()||"";for(let I of C){if(!I.startsWith("data: "))continue;let Z=I.slice(6).trim();try{let ft=JSON.parse(Z).candidates?.[0]?.content?.parts?.[0]?.text;ft&&(O+=ft,s(ft))}catch{}}}}finally{clearInterval(M)}i&&i(O)}function Uo(e,t,n={},s){return new Promise((o,i)=>{let a={...process.env};delete a.CLAUDECODE;let r=fa("claude",e,{stdio:["pipe","pipe","pipe"],env:a}),l="",c="",d="",u=!1,m=null,g=S=>{u||(u=!0,S())},y=S=>{try{if(S.type==="assistant"&&S.message?.content){for(let M of S.message.content)if(M.type==="text"&&typeof M.text=="string"){let O=M.text;l+=O,n.onChunk&&n.onChunk(O)}else if(M.type==="tool_use"){let O=M;O.name&&n.onToolUse&&n.onToolUse(O.name,O.input)}}S.type==="result"&&(m=S,!l&&typeof S.result=="string"&&(l=S.result,n.onChunk&&n.onChunk(S.result))),n.onEvent&&n.onEvent(S)}catch{}};r.stdout.on("data",S=>{d+=S.toString();let M;for(;(M=d.indexOf(`
664
+ `))>=0;){let O=d.slice(0,M).trim();if(d=d.slice(M+1),!!O)try{y(JSON.parse(O))}catch{}}}),r.stderr.on("data",S=>{c+=S.toString()}),r.on("error",S=>g(()=>i(new Error(`claude failed to start: ${S.message}`)))),r.on("close",S=>{if(d.trim()){try{y(JSON.parse(d.trim()))}catch{}d=""}g(()=>{S!==0||m&&m.is_error?i(new Error(`claude exited with code ${S}.
665
665
  `+(c?`Stderr: ${c.slice(0,500)}
666
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
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}.
668
+ `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);r.on("close",()=>clearTimeout(w))})}function Go(e,t,n,s,o){return new Promise((i,a)=>{let r={...process.env};delete r.CLAUDECODE;let l=fa(e,t,{stdio:["pipe","pipe","pipe"],env:r}),c="",d="",u=!1,m=x=>{u||(u=!0,x())};l.stdout.on("data",x=>{let w=x.toString();c+=w,s&&s(w)}),l.stderr.on("data",x=>{d+=x.toString()}),l.on("error",x=>m(()=>a(new Error(`${e} failed to start: ${x.message}`)))),l.on("close",x=>{m(()=>{x!==0?a(new Error(`${e} exited with code ${x}.
669
669
  `+(d?`Stderr: ${d.slice(0,500)}
670
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.
671
671
  `+(d?`Stderr: ${d.slice(0,500)}
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+=`
672
+ `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},y);l.on("close",()=>clearTimeout(b))})}async function ka(e,t,n,s,o,i){let a=ce(),r=P(),l=v().modules.length>0,c=Ut(),d=xn(a,t,l,c.pageType,c.brandAssets);d+=`
673
673
 
674
674
  ## User Request
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+=`
675
+ `+e,d+=vn(),d+=ya(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print"];r.claudeCodeModel&&u.push("--model",r.claudeCodeModel),r.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let m=0,g=s||(()=>{});g(ye[0]);let y=setInterval(()=>{m++;let h=ye[Math.min(m,ye.length-1)];g(h)},6e3);try{let h=await Uo(u,d,{onChunk:b=>n(b),onToolUse:(b,x)=>{g(Uu(b,x))}});o&&o(h)}finally{clearInterval(y)}}function Uu(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function Wo(e,t,n,s,o,i,a){let r=ce(),l=v().modules.length>0,c=Ut(),d=xn(r,n,l,c.pageType,c.brandAssets);d+=`
676
676
 
677
677
  ## User Request
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(`
678
+ `+t,d+=vn(),d+=ya(a),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;e==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,y=o||(()=>{});y(ye[0]);let h=setInterval(()=>{g++;let b=ye[Math.min(g,ye.length-1)];y(b)},6e3);try{let b=await Go(u,m,d,x=>{s(x)});i&&i(b)}finally{clearInterval(h)}}var Lo,ye,Bo,Vo=L(()=>{"use strict";f();ot();Q();tt();pe();ga();ie();Lo=null;ye=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],Bo=[10,20,40,60,120]});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function B(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function Ye(e,t,n){B(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Fe=L(()=>{"use strict";f()});import{createWriteStream as Gu,mkdirSync as Aa,existsSync as Ko,readFileSync as zo}from"fs";import{join as Ct,extname as Wu}from"path";import{randomUUID as Vu}from"crypto";import Ku from"busboy";function Xu(e,t){if(Ta.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return qu[n]??t}function Zu(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function Qu(e,t){if(!Ko(Ct(e,t)))return t;let n=Wu(t),s=t.slice(0,-n.length||void 0),o=1;for(;Ko(Ct(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function em(e){let t=(await import("pdf-parse")).default,n=zo(e);return(await t(n)).text}async function tm(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function nm(e){return zo(e,"utf-8")}function Ia(e,t){let n=v();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],a=0,r=[],l=Ku({headers:e.headers,limits:{fileSize:zu,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;a++;let y=Xu(m,g);if(!Ta.has(y)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let h=$a.has(y),b=Zu(m),x=Vu(),w,S;h?(w=Ct(n.themePath,"assets"),Aa(w,{recursive:!0}),S=Qu(w,b)):(w=Ct(n.themePath,".vibespot","uploads"),Aa(w,{recursive:!0}),S=`${x}-${b}`);let M=Ct(w,S),O=Gu(M),R=0,H=!1;d.on("data",z=>{R+=z.length}),d.on("limit",()=>{H=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(O),r.push(new Promise(z=>{O.on("finish",()=>{if(!H){let _={id:x,filename:S,originalName:m,type:h?"image":"document",usage:h?"asset":"context",mimeType:y,size:R,addedAt:new Date().toISOString()};o.push(_),Dr(_)}z()}),O.on("error",()=>{i.push(`Failed to write: ${m}`),z()})}))}),l.on("finish",async()=>{await Promise.all(r);for(let c of o)if(c.type==="document"){let d=Ct(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await em(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await tm(d):c.extractedText=nm(d),A.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){A.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(a===0){p(t,400,{error:"No files uploaded"});return}p(t,200,{files:o.map(c=>({id:c.id,filename:c.filename,originalName:c.originalName,type:c.type,usage:c.usage,size:c.size})),errors:i.length>0?i:void 0})}),l.on("error",c=>{A.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function $s(e){let t=v();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=Ct(t.themePath,"assets",s.filename);Ko(i)&&(o.base64=zo(i).toString("base64")),o.assetPath=`${t.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var zu,$a,Yu,Ta,qu,Yo=L(()=>{"use strict";f();Fe();pe();ie();zu=10*1024*1024,$a=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Yu=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),Ta=new Set([...$a,...Yu]),qu={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var Pa={};ke(Pa,{callAgent:()=>Ce,callAgentAPI:()=>Na,isAgenticCapable:()=>Cn,isCLIEngine:()=>Gt,resolveThinkingBudget:()=>Qo});async function Ts(e,t){for(let n=0;;n++)try{return await e()}catch(s){let o=s.status,i=s.error?.type;if(!(o===429||i==="rate_limit_error"||s instanceof Error&&s.message.includes("429"))||n>=qo.length)throw s;let r=qo[n];A.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${qo.length} \u2014 waiting ${r}s`),t&&t(`Rate limited \u2014 retrying in ${r}s...`),await new Promise(l=>setTimeout(l,r*1e3)),t&&t("Retrying...")}}function wn(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;for(let n of["fieldsJson","metaJson"])t[n]&&typeof t[n]=="object"&&(t[n]=JSON.stringify(t[n]))}return e}async function Ea(){return Xo||(Xo=(await import("@anthropic-ai/sdk")).default),Xo}async function sm(e,t,n,s,o){let i=await Ea(),a=new i({apiKey:e,...s?{defaultHeaders:s}:{}}),r=n.messages,l=n.systemPrompt;if(n.systemBlocks?l=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(l=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let c={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Ts(async()=>{let d=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:r,tools:[c],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for(let m of d.content)if(m.type==="tool_use")return{type:"structured",data:wn(m.input)};return{type:"text",text:d.content.filter(m=>m.type==="text").map(m=>m.text).join("")}},n.onStatus)}return Ts(async()=>{let c="",d=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:l,messages:r,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let u of d)u.type==="content_block_delta"&&u.delta.type==="text_delta"&&(c+=u.delta.text,n.onChunk&&n.onChunk(u.delta.text));return{type:"text",text:c}},n.onStatus)}async function om(e,t,n){let s=await Ea(),o=new s({authToken:e,defaultHeaders:Zt}),i=n.messages,a;if(n.systemBlocks?a=[{type:"text",text:Mt},...n.systemBlocks]:a=[{type:"text",text:Mt},{type:"text",text:n.systemPrompt}],n.structuredOutput){let r={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return Ts(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:a,messages:i,tools:[r],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for(let d of l.content)if(d.type==="tool_use")return{type:"structured",data:wn(d.input)};return{type:"text",text:l.content.filter(d=>d.type==="text").map(d=>d.text).join("")}},n.onStatus)}return Ts(async()=>{let r="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:a,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let c of l)c.type==="content_block_delta"&&c.delta.type==="text_delta"&&(r+=c.delta.text,n.onChunk&&n.onChunk(c.delta.text));return{type:"text",text:r}},n.onStatus)}function Zo(e){let t={...e};if(t.type==="object"&&(t.additionalProperties=!1,t.properties&&typeof t.properties=="object")){let n={};for(let[s,o]of Object.entries(t.properties))n[s]=o&&typeof o=="object"?Zo(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Zo(t.items)),t}async function im(e,t,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:t,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:Zo(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let r=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:wn(JSON.parse(r))}}catch{return A.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:r}}return{type:"text",text:r}}async function rm(e,t,n){let s=t||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${e}`,r=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!r.ok){let d=await r.text(),u=r.status;if(u===429){let m=new Error(`Gemini rate limit: ${d}`);throw m.status=429,m}throw new Error(`Gemini API error (${u}): ${d}`)}let c=(await r.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:wn(JSON.parse(c))}}catch{return A.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function am(e,t){switch(e){case"claude-code":{let n=P(),s=["--print"];return n.claudeCodeModel&&s.push("--model",n.claudeCodeModel),t?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":return{bin:"gemini",args:[]};case"codex-cli":return{bin:"codex",args:["exec","--full-auto"]};default:throw new Error(`Not a CLI engine: ${e}`)}}function lm(e){let t=[e.systemPrompt];for(let n of e.messages){let s=n.role==="user"?"User":"Assistant",o=typeof n.content=="string"?n.content:n.content.map(i=>i.text).join(`
679
679
  `);t.push(`
680
680
 
681
681
  ## ${s}
682
- ${o}`)}if(e.structuredOutput){let n=Ea(e.structuredOutput.schema);t.push(`
682
+ ${o}`)}if(e.structuredOutput){let n=_a(e.structuredOutput.schema);t.push(`
683
683
 
684
684
  ## Output Format \u2014 CRITICAL
685
685
  Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
686
686
 
687
687
  The JSON must match this structure:
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):
688
+ ${n}`)}return t.join("")}function _a(e,t=0){let n=" ".repeat(t),s=e.properties,o=e.required||[];if(!s)return`${n}${JSON.stringify(e)}`;let i=["{"];for(let[a,r]of Object.entries(s)){let l=o.includes(a)?" (required)":"",c=r.type||"any",d=r.description?` \u2014 ${r.description}`:"",u=r.enum?` [${r.enum.join(", ")}]`:"";if(c==="array"&&r.items){let m=r.items.type||"object";i.push(`${n} "${a}": ${c}<${m}>${l}${d}${u}`)}else c==="object"&&r.properties?i.push(`${n} "${a}": ${_a(r,t+1)}${l}${d}`):i.push(`${n} "${a}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
689
+ `)}function cm(e){let t=e.trim(),n=ze(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let r=s[1].trim(),l=ze(r);if(l&&typeof l=="object")return l;let c=Sn(r);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let r=t.slice(o,i+1),l=ze(r);if(l&&typeof l=="object")return l;let c=Sn(r);if(c&&typeof c=="object")return c}let a=Sn(t);return a&&typeof a=="object"?a:null}async function dm(e,t,n){let{bin:s,args:o}=am(e,n),i=lm(n),a;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];a=await Uo(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=um(c,d);n.onStatus(u)}})}else a=await Go(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:a};let r=cm(a);return r?{type:"structured",data:wn(r)}:(A.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:a.slice(0,500),outputLength:a.length}),{type:"text",text:a})}function um(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function Na(e,t,n,s){switch(A.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),e){case"anthropic-api":return sm(t,n,s);case"claude-oauth":{let{getValidAccessToken:o}=await Promise.resolve().then(()=>(tt(),so)),i=await o();if(!i)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return om(i,n,s)}case"openai-api":return im(t,n,s);case"gemini-api":return rm(t,n,s);default:throw new Error(`Unsupported API engine: ${e}`)}}async function Ce(e,t,n,s){return mm.has(e)?Na(e,t,n,s):(A.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),dm(e,n,s))}function Qo(e){if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=P();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Cn(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function Gt(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var qo,Xo,mm,qe=L(()=>{"use strict";f();Vo();As();Q();tt();ie();qo=[10,20,40,60,120];Xo=null;mm=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api"])});function Ma(e,t,n,s){let o=t.length>0?`Current template modules (in page order):
690
690
  ${t.map((r,l)=>`${l+1}. ${r}`).join(`
691
691
  `)}`:"No modules yet (new page).",i=n.length>0?`
692
692
 
@@ -742,7 +742,7 @@ CRITICAL: When the user corrects a misclassification (e.g., "I was referencing t
742
742
  If the user asks for multiple things (e.g., "make hero taller AND add testimonials"), capture ALL parts:
743
743
  - Affected existing modules in \`affectedModules\`
744
744
  - New modules in \`newModules\`
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.
745
+ - Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Oa,Ra=L(()=>{"use strict";f();Oa={type:"object",properties:{intent:{type:"string",enum:["create","modify","add","remove","rearrange","style_change","question"]},affectedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that need changes"},unchangedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that stay as-is"},newModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},position:{type:"number"}},required:["name","description","position"]},description:"New modules to create"},reuseModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},sourceTemplate:{type:"string"},position:{type:"number"}},required:["name","sourceTemplate","position"]},description:"Modules to copy from the library (immutable structure)"},guidesNeeded:{type:"array",items:{type:"string",enum:["design","content","conversion","hubspot_rules","humanify"]}},designSystemChanges:{type:"boolean",description:"True if shared CSS / design system needs regeneration"},answer:{type:"string",description:'For "question" intent only \u2014 the answer to return directly'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function Fa(e,t,n,s,o,i,a){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let r=t.modules.map(g=>g.moduleName),l=Ma(t.themeName,r,a,t.brandAssets?.themeContext),c=[],d=t.messages.slice(-6);for(let g of d)if(g.role==="user"||g.role==="assistant"){let y=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:y})}c.push({role:"user",content:e});let u=await Ce(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Oa,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){A.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:r,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:g}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],A.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:pm(m)}),m}function pm(e){let t=[`Intent: ${e.intent}`];return e.affectedModules.length>0&&t.push(`Modifying: ${e.affectedModules.join(", ")}`),e.unchangedModules.length>0&&t.push(`Unchanged: ${e.unchangedModules.join(", ")}`),e.newModules.length>0&&t.push(`New: ${e.newModules.map(n=>n.name).join(", ")}`),e.reuseModules?.length&&t.push(`Reuse: ${e.reuseModules.map(n=>`${n.name} from ${n.sourceTemplate}`).join(", ")}`),e.designSystemChanges&&t.push("Design system changes: yes"),t.join(" | ")}var Ja=L(()=>{"use strict";f();qe();Ra();ie()});function ei(e,t){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
746
746
 
747
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.
748
748
 
@@ -829,22 +829,22 @@ Good system font stacks by style:
829
829
  | Geometric | Futura, "Century Gothic", "Trebuchet MS", sans-serif | system-ui, sans-serif |`),n.push(`
830
830
 
831
831
  ## Design Guide
832
- ${La()}`),t?.styleguide&&n.push(`
832
+ ${Ba()}`),t?.styleguide&&n.push(`
833
833
 
834
834
  ## Brand Style Guide
835
835
  ${t.styleguide}`),t?.themeContext&&n.push(`
836
836
 
837
837
  ## Product Context
838
- ${t.themeContext}`),n.join("")}function Ja(e,t){let n=ei(e),o=n.indexOf(`
838
+ ${t.themeContext}`),n.join("")}function ja(e,t){let n=ei(e),o=n.indexOf(`
839
839
 
840
840
  ## Design Guide
841
841
  `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),a=`## Design 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
842
+ ${Ba()}`,r=[{type:"text",text:i},{type:"text",text:a,cache_control:{type:"ephemeral"}}],l=[];return t?.styleguide&&l.push(`## Brand Style Guide
843
843
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
844
844
  ${t.themeContext}`),l.length>0&&r.push({type:"text",text:l.join(`
845
845
 
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.
846
+ `)}),r}function gm(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
847
+ `)}function Ha(e,t,n,s){let o=[],i=gm(t);return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
848
848
 
849
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.
850
850
 
@@ -858,14 +858,24 @@ Reference these in your layoutNotes:
858
858
  ${i}
859
859
 
860
860
  ## Output Rules
861
- - Module names: descriptive, title-case (e.g., "Hero Banner", "Pricing Cards")
861
+
862
+ ### Module names \u2014 CRITICAL
863
+ - **If the user message lists "Existing Modules to Re-plan", you MUST use those exact names verbatim** in \`modules[].name\` and in \`moduleOrder\`. Do not rename them. Do not retitle-case them. Do not "improve" them. The names are identifiers, not labels. Mismatched names create duplicate modules instead of regenerating existing ones.
864
+ - **For genuinely new modules** (not in any existing-modules list): use kebab-case identifiers (e.g., \`hero\`, \`pricing-cards\`, \`final-cta\`). This matches the convention used by Plan Mode and Figma Import.
865
+ - The \`description\` and \`contentBrief\` fields can be any text \u2014 they describe the module to humans, while \`name\` is the canonical identifier.
866
+
867
+ ### Content & layout
862
868
  - Content briefs: describe the actual copy/content each module needs (headlines, body text, CTAs, stats)
863
869
  - Layout notes: describe the visual layout using the available CSS classes above
864
870
  - Reference specific CSS classes from the shared CSS in your layout notes (e.g., "Use ${e}-grid--3 for card layout, ${e}-section--dark for background")
865
- - moduleOrder: list module names in the order they should appear on the page`),(!s||s.includes("content"))&&o.push(`
871
+
872
+ ### Module order
873
+ - \`moduleOrder\`: list **all** modules' names in the order they should appear on the page, including:
874
+ - the ones you just planned (in \`modules\`)
875
+ - any "Existing Modules to Keep" the user listed (these are not in \`modules\`, but still belong in \`moduleOrder\`)`),(!s||s.includes("content"))&&o.push(`
866
876
 
867
877
  ## Content & Copywriting Guide
868
- ${pm()}`),n?.brandvoice&&o.push(`
878
+ ${fm()}`),n?.brandvoice&&o.push(`
869
879
 
870
880
  ## Brand Voice
871
881
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -874,7 +884,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
874
884
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
875
885
 
876
886
  ## Anti-AI Copy Rules
877
- ${gm()}`),o.join("")}function La(){return`### Design Philosophy
887
+ ${hm()}`),o.join("")}function Ba(){return`### Design Philosophy
878
888
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
879
889
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
880
890
 
@@ -977,7 +987,7 @@ Include these in shared CSS:
977
987
  | All animations same speed | Stagger with increasing delays |
978
988
  | Skip hover/focus states | Every interactive element needs feedback |
979
989
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
980
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function pm(){return`### Mandatory Page Sections (generate all)
990
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function fm(){return`### Mandatory Page Sections (generate all)
981
991
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
982
992
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
983
993
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -1065,7 +1075,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
1065
1075
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
1066
1076
  - Keep paragraphs to 2-3 sentences max
1067
1077
  - Aim for 6th-grade reading level
1068
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function gm(){return`### Banned Punctuation
1078
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function hm(){return`### Banned Punctuation
1069
1079
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
1070
1080
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
1071
1081
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -1095,28 +1105,34 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
1095
1105
  - Use plain short words: use > utilize, start > commence, help > facilitate
1096
1106
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
1097
1107
  - Front-load the benefit in the first 5 words
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
1108
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Da,La,Ua=L(()=>{"use strict";f();Da={type:"object",properties:{cssVariables:{type:"object",description:"CSS custom property name \u2192 value map. Every var() used in sharedCss must be defined here."},sharedCss:{type:"string",description:"Complete shared CSS file. MUST start with :root {} block defining all cssVariables, followed by reset, typography, layout, components, animations, and responsive styles."},sharedJs:{type:"string",description:"Optional shared JS for scroll animations (IntersectionObserver). Wrap in IIFE. Empty string if not needed."},aesthetic:{type:"string",description:"Brief description of the chosen aesthetic direction (e.g., 'dark luxury with warm gold accents')"}},required:["cssVariables","sharedCss","aesthetic"]};La={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module identifier. If this module already exists in the project, use the existing name verbatim. For new modules, use kebab-case (e.g., 'hero', 'pricing-cards')."},description:{type:"string",description:"What this module does"},contentBrief:{type:"string",description:"Specific content: headlines, body copy, stats, CTAs"},layoutNotes:{type:"string",description:"Visual layout approach referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Module names in page display order"},narrative:{type:"string",description:"Brief description of the page story/flow"}},required:["modules","moduleOrder","narrative"]}});async function Ga(e,t,n,s,o,i,a){a({type:"agent_step",step:"designing",label:"Creating design system..."});let r=s==="anthropic-api"||s==="claude-oauth",l=ei(n.themeName,n.brandAssets),c=r?ja(n.themeName,n.brandAssets):void 0,d=`## User Request
1099
1109
  ${e}`;n.modules.length>0&&t.designSystemChanges&&(d+=`
1100
1110
 
1101
1111
  ## Current Shared CSS (update this)
1102
1112
  \`\`\`css
1103
1113
  ${n.sharedCss}
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(`
1114
+ \`\`\``);let u=Qo(s),m=await Ce(s,o,i,{systemPrompt:l,systemBlocks:c,messages:[{role:"user",content:d}],structuredOutput:{schema:Da,name:"design_system"},maxTokens:16e3,...u>0?{thinkingBudgetTokens:u}:{}}),g;m.type!=="structured"?(A.warn("page-architect","Design system: did not get structured output, using fallback"),g={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(g=m.data,A.info("page-architect","Design system created",{aesthetic:g.aesthetic,varCount:Object.keys(g.cssVariables||{}).length,cssLength:g.sharedCss?.length||0}));let y=g.sharedCss||"",h=g.cssVariables;h&&typeof h=="object"&&Object.keys(h).length>0&&(y.includes(":root")||(y=`:root {
1115
+ ${Object.entries(h).map(([F,C])=>` ${F.startsWith("--")?F:`--${F}`}: ${C};`).join(`
1106
1116
  `)}
1107
1117
  }
1108
1118
 
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+=`
1119
+ ${y}`));let b=[],x=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,w=[...new Set((e.match(x)||[]).map(_=>_.trim()))];if(w.length>0){let _=w.filter(C=>y.toLowerCase().includes(C.toLowerCase())),F=w.filter(C=>!_.includes(C));F.length>0&&b.push(`Note: ${F.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let S=[`Design system: ${g.aesthetic||"created"} | ${Object.keys(h||{}).length} variables, ${y.length} chars CSS`,...b];a({type:"agent_decision",step:"designing",decision:S.join(`
1120
+ `)}),a({type:"design_system_ready",sharedCss:y,sharedJs:g.sharedJs||"",aesthetic:g.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let M=Ha(n.themeName,y,n.brandAssets,t.guidesNeeded),O=`## User Request
1121
+ ${e}`;if(t.newModules.length>0&&(O+=`
1112
1122
 
1113
1123
  ## Planned Modules
1114
- ${t.newModules.map((P,J)=>`${J+1}. **${P.name}** \u2014 ${P.description}`).join(`
1115
- `)}`),n.modules.length>0&&!t.designSystemChanges&&(R+=`
1124
+ ${t.newModules.map((_,F)=>`${F+1}. **${_.name}** \u2014 ${_.description}`).join(`
1125
+ `)}`),n.modules.length>0){let _=new Set(t.affectedModules),F=n.modules.filter(I=>_.has(I.moduleName)),C=n.modules.filter(I=>!_.has(I.moduleName));F.length>0&&(O+=`
1126
+
1127
+ ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1128
+ These already exist and are being regenerated. Your output's module names MUST match these exactly \u2014 do NOT rename, retitle-case, or "improve" them. Their content/layout may change; their identifier must not.
1129
+ `+F.map(I=>`- \`${I.moduleName}\``).join(`
1130
+ `)),C.length>0&&(O+=`
1116
1131
 
1117
- ## Existing Modules (keeping)
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.
1132
+ ## Existing Modules to Keep (do not re-plan)
1133
+ These stay as-is. Do NOT include them in your output. They will appear in the final \`moduleOrder\` (you can reference them by name when you list it).
1134
+ `+C.map(I=>`- \`${I.moduleName}\``).join(`
1135
+ `))}let R=await Ce(s,o,i,{systemPrompt:M,messages:[{role:"user",content:O}],structuredOutput:{schema:La,name:"module_plan"},maxTokens:8e3,...u>0?{thinkingBudgetTokens:u}:{}}),H,z={modules:t.newModules.map(_=>({name:_.name,description:_.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(_=>_.name),narrative:"Page generated from user request"};if(R.type!=="structured")A.warn("page-architect","Module planner: did not get structured output, using fallback"),H=z;else{let _=R.data;Array.isArray(_?.modules)&&_.modules.length>0?(H=_,H.moduleOrder=H.moduleOrder||H.modules.map(F=>F.name),H.narrative=H.narrative||"Page generated from user request"):(A.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:_?Object.keys(_):[]}),H=z),A.info("page-architect","Module plan",{moduleCount:H.modules.length})}return a({type:"agent_decision",step:"designing",decision:`Page: ${H.narrative} | ${H.modules.length} modules planned`}),{designSystem:{cssVariables:g.cssVariables||{},sharedCss:y,sharedJs:g.sharedJs},modules:H.modules,moduleOrder:H.moduleOrder,narrative:H.narrative}}var Wa=L(()=>{"use strict";f();qe();Ua();ie()});function Is(e){let t=0,n=[];return async function(o){t>=e&&await new Promise(i=>n.push(i)),t++;try{return await o()}finally{t--,n.length>0&&n.shift()()}}}var ti=L(()=>{"use strict";f()});function kn(e,t,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
1120
1136
 
1121
1137
  Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code.
1122
1138
 
@@ -1177,7 +1193,7 @@ ${ce()}`),s?.themeContext&&o.push(`
1177
1193
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1178
1194
 
1179
1195
  ## Anti-AI Copy Rules
1180
- ${Wa()}`),o.join("")}function Es(e,t,n,s){let o=[],i=kn(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1196
+ ${Va()}`),o.join("")}function Es(e,t,n,s){let o=[],i=kn(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1181
1197
 
1182
1198
  ## Theme Shared CSS (use these custom properties)
1183
1199
  \`\`\`css
@@ -1188,9 +1204,9 @@ ${ce()}`),a.length>0&&o.push({type:"text",text:a.join(`
1188
1204
 
1189
1205
  `),cache_control:{type:"ephemeral"}});let r=[];return s?.themeContext&&r.push(`## Product Context
1190
1206
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&r.push(`## Anti-AI Copy Rules
1191
- ${Wa()}`),r.length>0&&o.push({type:"text",text:r.join(`
1207
+ ${Va()}`),r.length>0&&o.push({type:"text",text:r.join(`
1192
1208
 
1193
- `)}),o}function Wa(){return`### Banned Punctuation
1209
+ `)}),o}function Va(){return`### Banned Punctuation
1194
1210
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1195
1211
  - **Semicolons**: Use periods instead in marketing copy.
1196
1212
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1229,7 +1245,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1229
1245
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1230
1246
  - Full names, specific roles (not "John D., CEO")
1231
1247
  - Never start with "This product is..." \u2014 start with the person's situation
1232
- - Vary length and voice across testimonials`}function Va(e,t,n){let s=[];return s.push(`## User Request
1248
+ - Vary length and voice across testimonials`}function Ka(e,t,n){let s=[];return s.push(`## User Request
1233
1249
  ${e}`),s.push(`
1234
1250
 
1235
1251
  ## Module Specification
@@ -1256,18 +1272,18 @@ ${n.moduleCss}
1256
1272
  **module.js:**
1257
1273
  \`\`\`js
1258
1274
  ${n.moduleJs}
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(`
1275
+ \`\`\``)),s.join("")}var _s,ni=L(()=>{"use strict";f();ot();_s={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function za(e,t,n,s,o,i,a,r,l,c,d){l({type:"agent_step",step:"developing",label:`Generating ${t.length} module${t.length===1?"":"s"}...`});let u=o==="anthropic-api"||o==="claude-oauth",m=kn(s,n,c,d),g=u?Es(s,n,c,d):void 0,y=Is(r),h=t.length,b=t.map((w,S)=>y(async()=>{l({type:"module_progress",module:w.name,status:"generating",current:S+1,total:h});let M="";for(let O=0;O<2;O++)try{O>0&&(A.warn("module-developer",`${w.name}: retrying after failure (attempt ${O+1})`),l({type:"module_progress",module:w.name,status:"retrying",current:S+1,total:h}));let R=await Ya(e,w,m,o,i,a,0,g);return l({type:"module_progress",module:w.name,status:"complete",current:S+1,total:h,moduleFiles:R}),{moduleName:w.name,module:R}}catch(R){M=R instanceof Error?R.message:typeof R=="object"&&R!==null?JSON.stringify(R):String(R),A.error("module-developer",`Failed: ${w.name} (attempt ${O+1})`,{error:M})}return l({type:"module_progress",module:w.name,status:"failed",current:S+1,total:h}),{moduleName:w.name,error:M}}));return(await Promise.allSettled(b)).map(w=>w.status==="fulfilled"?w.value:{moduleName:"unknown",error:w.reason instanceof Error?w.reason.message:String(w.reason)})}async function Ya(e,t,n,s,o,i,a=0,r){let l=Ka(e,t,t.existingCode),c=await Ce(s,o,i,{systemPrompt:n,systemBlocks:r,messages:[{role:"user",content:l}],structuredOutput:{schema:_s,name:"module_output"},maxTokens:16e3});if(c.type!=="structured"){if(a<2)return A.warn("module-developer",`${t.name}: no structured output, retry ${a+1}`),Ya(e,t,n,s,o,i,a+1,r);throw new Error(`Module "${t.name}" failed to produce structured output after ${a+1} attempts`)}let d=c.data,u=typeof d.fieldsJson=="string"?d.fieldsJson:JSON.stringify(d.fieldsJson,null,2),m=typeof d.metaJson=="string"?d.metaJson:JSON.stringify(d.metaJson,null,2);return{moduleName:t.name,fieldsJson:u,metaJson:m,moduleHtml:String(d.moduleHtml||""),moduleCss:String(d.moduleCss||""),moduleJs:d.moduleJs?String(d.moduleJs):void 0}}var qa=L(()=>{"use strict";f();qe();ti();ni();ie()});function Ns(e,t,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),e.map(s=>{let o=[],i={...s};i.fieldsJson=Xa(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=Xa(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=ym(i.fieldsJson,i.moduleName,o),i.fieldsJson=bm(i.fieldsJson,i.moduleName,o),i.moduleCss=Sm(i.moduleCss,i.moduleName,"moduleCss",o),i.moduleCss=vm(i.moduleCss,i.moduleName,t,o),i.moduleHtml=wm(i.moduleHtml,i.moduleName,t,o),i.moduleHtml=km(i.moduleHtml,i.moduleName,o),i.metaJson=Am(i.metaJson,i.moduleName,o);let a=o.every(r=>r.autoFixed);return o.length>0&&A.info("validator",`${i.moduleName}: ${o.length} issues`,{autoFixed:o.filter(r=>r.autoFixed).length,unfixed:o.filter(r=>!r.autoFixed).length}),{module:i,issues:o,valid:a}})}function Xa(e,t,n,s){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:["PAGE"],is_available_for_new_content:!0}):e):(ze(e)===null&&s.push({module:t,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),e)}function ym(e,t,n){let s=e;return/"name"\s*:\s*"name"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"name" is a reserved field name \u2192 renamed to "item_name"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"name"/g,'"name": "item_name"')),/"name"\s*:\s*"label"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"label" is a reserved field name \u2192 renamed to "section_label"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"label"/g,'"name": "section_label"')),s}function bm(e,t,n){let s=e;return/"type"\s*:\s*"textarea"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"textarea" is deprecated \u2192 changed to "text"',autoFixed:!0}),s=s.replace(/"type"\s*:\s*"textarea"/g,'"type": "text"')),s}function Sm(e,t,n,s){if(!e)return e;let o=e,i=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return i.test(o)&&(s.push({module:t,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(i,"/* CDN import removed */")),o}function Za(e){return xm.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function vm(e,t,n,s){if(!e)return e;let o=n+"-",i=/\.([a-zA-Z][\w-]*)/g,a=new Set,r;for(;(r=i.exec(e))!==null;){let c=r[1];!c.startsWith(o)&&!Za(c)&&a.add(c)}if(a.size<=3)return e;let l=e;for(let c of a){let d=new RegExp(`\\.${Cm(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==e&&s.push({module:t,field:"moduleCss",message:`${a.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function wm(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,a=!1,r=e.replace(i,(l,c)=>{let d=c.split(/\s+/),u=!1,m=d.map(g=>g&&!g.startsWith(o)&&!Za(g)&&/^[a-zA-Z][\w-]*$/.test(g)?(u=!0,o+g):g);return u?(a=!0,`class="${m.join(" ")}"`):l});return a&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),r}function Cm(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function km(e,t,n){if(!e)return e;let s=e,o=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,i=[],a;for(;(a=o.exec(s))!==null;){let c=a[1],d=!c.startsWith("end"),u=d?c:c.replace("end","");i.push({tag:c,isOpen:d,baseTag:u,start:a.index,end:a.index+a[0].length})}let r=[],l=[];for(let c=0;c<i.length;c++)if(i[c].isOpen)r.push(c);else{let d=-1;for(let u=r.length-1;u>=0;u--)if(i[r[u]].baseTag===i[c].baseTag){d=u;break}d!==-1?r.splice(d,1):l.push(c)}if(l.length>0){for(let c=l.length-1;c>=0;c--){let d=i[l[c]];s=s.slice(0,d.start)+`<!-- removed orphan {% ${d.tag} %} -->`+s.slice(d.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${l.length} orphan closing tag${l.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(r.length>0){let c=r.map(u=>i[u].baseTag),d=c.reverse().map(u=>`{% end${u} %}`).join(`
1260
1276
  `);s=`${s}
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(`
1277
+ ${d}`,n.push({module:t,field:"moduleHtml",message:`Added ${c.length} missing closing tag${c.length===1?"":"s"}: ${c.map(u=>`{% end${u} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:t,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function Am(e,t,n){let s=ze(e);if(!s||typeof s!="object")return e;let o=s,i=!1;return o.host_template_types||(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content===void 0&&(o.is_available_for_new_content=!0,i=!0),i?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(o,null,2)):e}var xm,si=L(()=>{"use strict";f();As();ie();xm=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"])});import{execSync as $m}from"child_process";async function Qa(e,t,n,s,o,i,a,r){let l=Date.now(),c=i;if(Gt(n)){let C={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(C)try{$m(`command -v ${C}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${C}" to be installed and on your PATH.`)}}let d=await Fa(e,t,n,s,o,a,r);if(d.intent==="question"&&d.answer){let F=Date.now()-l;return a({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:F,answer:d.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:F}}}let u=null,m=t.sharedCss,g=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Ga(e,d,t,n,s,o,a),m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g,a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let h=[];if(u)for(let F of u.modules)h.push({name:F.name,description:F.description,contentBrief:F.contentBrief,layoutNotes:F.layoutNotes});else{for(let F of d.newModules)h.push({name:F.name,description:F.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let F of d.affectedModules){let C=t.modules.find(I=>I.moduleName===F);C&&h.push({name:F,description:`Modify existing module: ${F}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:C})}}let b=[],x=[];if(h.length>0){let F=await za(e,h,m,t.themeName,n,s,o,c,a,d.guidesNeeded,t.brandAssets);for(let C of F)C.module?b.push(C.module):x.push(C.moduleName)}let w=null;if(b.length>0){w=Ns(b,t.themeName,a),b=w.map(C=>C.module);let F=w.reduce((C,I)=>C+I.issues.length,0);if(F>0){let C=w.reduce((Z,Mn)=>Z+Mn.issues.filter(ft=>ft.autoFixed).length,0);A.info("pipeline",`Quality check: ${F} issues, ${C} auto-fixed`);let I=w.flatMap(Z=>Z.issues).map(Z=>`${Z.autoFixed?"\u2713":"\u26A0"} ${Z.module}: ${Z.message}`).join(`
1278
+ `);a({type:"agent_decision",step:"quality_check",decision:`${F} issues found, ${C} auto-fixed
1279
+ ${I}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let S=Tm(t,d,b,u,r),M=Im(t,d,u,S);if(u?.moduleOrder?.length){let F=new Set(u.moduleOrder),C=S.filter(I=>!F.has(I.moduleName)).map(I=>I.moduleName);C.length>0&&a({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${C.length} module${C.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${C.join(", ")}`})}let O=Date.now()-l,R=b.length,H=d.unchangedModules.length,z=w?w.flatMap(F=>F.issues):[],_=Em(d,R,H,x,O,u,z);return x.length>0?a({type:"pipeline_partial",succeeded:b.map(F=>F.moduleName),failed:x,durationMs:O}):a({type:"pipeline_complete",modulesGenerated:R,modulesUnchanged:H,durationMs:O}),{modules:S,moduleOrder:M,sharedCss:m,sharedJs:g,assistantMessage:_,stats:{modulesGenerated:R,modulesUnchanged:H,modulesFailed:x.length,durationMs:O}}}function Tm(e,t,n,s,o){let i=[],a=new Set;for(let r of n)i.push(r),a.add(r.moduleName);for(let r of t.unchangedModules){if(a.has(r))continue;let l=e.modules.find(c=>c.moduleName===r);l&&(i.push(l),a.add(r))}if(t.reuseModules)for(let r of t.reuseModules){if(a.has(r.name))continue;let l=o.find(c=>c.name===r.name&&c.module);l&&l.module&&(i.push(l.module),a.add(r.name))}return i}function Im(e,t,n,s){if(n?.moduleOrder?.length){let r=[...n.moduleOrder],l=new Set(r);for(let c of s)if(!l.has(c.moduleName)){let d=r.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?r.splice(d,0,c.moduleName):r.push(c.moduleName),l.add(c.moduleName),A.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return r}if(t.intent==="create")return s.map(r=>r.moduleName);let o=[...e.moduleOrder],i=[...t.newModules.map(r=>({name:r.name,position:r.position})),...(t.reuseModules||[]).map(r=>({name:r.name,position:r.position}))].sort((r,l)=>r.position-l.position);for(let r of i){let l=Math.min(r.position,o.length);o.splice(l,0,r.name)}let a=new Set(s.map(r=>r.moduleName));return o.filter(r=>a.has(r))}function Em(e,t,n,s,o,i,a){let r=Math.round(o/1e3),l=[];if(e.intent==="create")l.push(`Created ${t} module${t===1?"":"s"} in ${r}s.`);else if(e.intent==="modify"||e.intent==="style_change")l.push(`Updated ${t} module${t===1?"":"s"} in ${r}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(e.intent==="add"){let u=e.newModules.map(m=>m.name).join(", ");l.push(`Added ${u} in ${r}s.`)}else e.intent==="remove"?l.push(`Removed modules in ${r}s.`):e.intent==="rearrange"&&l.push(`Rearranged modules in ${r}s.`);i?.narrative&&l.push(`
1264
1280
 
1265
1281
  ${i.narrative}`),s.length>0&&l.push(`
1266
1282
 
1267
1283
  **Failed:** ${s.join(", ")}. You can retry these individually.`);let c=a.filter(u=>!u.autoFixed),d=a.filter(u=>u.autoFixed);if(d.length>0||c.length>0){let u=[];d.length>0&&u.push(`**Auto-fixed:** ${d.map(m=>`${m.module}: ${m.message}`).join(", ")}`),c.length>0&&u.push(`**Warnings:** ${c.map(m=>`${m.module}: ${m.message}`).join(", ")}`),l.push(`
1268
1284
 
1269
1285
  ${u.join(`
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 {
1286
+ `)}`)}return l.join("")}var el=L(()=>{"use strict";f();qe();Ja();Wa();qa();si();ie();qe()});var il={};ke(il,{runFigmaConversion:()=>_m});import{basename as sl}from"path";async function _m(e,t,n,s,o,i,a,r,l){let c=Date.now();a({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=Nm(e.designTokens,t);a({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),a({type:"agent_decision",step:"designing",decision:`Generated CSS variables and utility classes from ${e.designTokens.colors.length} colors, ${e.designTokens.typography.length} typography styles`});let{specs:m,moduleOrder:g}=Mm(e.sections,e.assets,t);a({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),a({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${g.join(", ")}`}),a({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let y=n==="anthropic-api"||n==="claude-oauth",h=kn(t,d,["hubspot_rules","conversion"],r),b=y?Es(t,d,["hubspot_rules","conversion"],r):void 0,x=Is(i),w=m.length,S=m.map((I,Z)=>{let Mn=e.sections[Z];return x(async()=>{a({type:"module_progress",module:I.name,status:"generating",current:Z+1,total:w});let ft=Fm(Mn,I,e.assets,t,l!==!1),qs="";for(let Yt=0;Yt<2;Yt++)try{Yt>0&&(A.warn("figma-pipeline",`${I.name}: retrying (attempt ${Yt+1})`),a({type:"module_progress",module:I.name,status:"retrying",current:Z+1,total:w}));let It=await Ce(n,s,o,{systemPrompt:h,systemBlocks:b,messages:[{role:"user",content:ft}],structuredOutput:{schema:_s,name:"module_output"},maxTokens:16e3});if(It.type!=="structured")throw new Error("No structured output returned");let je=It.data,_i={moduleName:I.name,fieldsJson:typeof je.fieldsJson=="string"?je.fieldsJson:JSON.stringify(je.fieldsJson,null,2),metaJson:typeof je.metaJson=="string"?je.metaJson:JSON.stringify(je.metaJson,null,2),moduleHtml:String(je.moduleHtml||""),moduleCss:String(je.moduleCss||""),moduleJs:je.moduleJs?String(je.moduleJs):void 0};return a({type:"module_progress",module:I.name,status:"complete",current:Z+1,total:w,moduleFiles:_i}),{moduleName:I.name,module:_i}}catch(It){qs=It instanceof Error?It.message:String(It),A.error("figma-pipeline",`Failed: ${I.name} (attempt ${Yt+1}): ${qs}`)}return a({type:"module_progress",module:I.name,status:"failed",current:Z+1,total:w}),{moduleName:I.name,error:qs}})}),O=(await Promise.allSettled(S)).map(I=>I.status==="fulfilled"?I.value:{moduleName:"unknown",error:String(I.reason)}),R=O.filter(I=>I.module).map(I=>I.module),H=O.filter(I=>I.error).map(I=>I.moduleName),_=Ns(R,t,a).map(I=>I.module),F=Date.now()-c,C=Math.round(F/1e3);return H.length>0?a({type:"pipeline_partial",succeeded:_.map(I=>I.moduleName),failed:H,durationMs:F}):a({type:"pipeline_complete",modulesGenerated:_.length,modulesUnchanged:0,durationMs:F}),{modules:_,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:`Imported ${_.length} modules from Figma design "${e.fileName}" in ${C}s.`,stats:{modulesGenerated:_.length,modulesUnchanged:0,modulesFailed:H.length,durationMs:F}}}function Ps(e){let t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,s=parseInt(e.slice(5,7),16)/255,o=Math.max(t,n,s),i=Math.min(t,n,s),a=(o+i)/2;if(o===i)return{h:0,s:0,l:a};let r=o-i,l=a>.5?r/(2-o-i):r/(o+i),c=0;return o===t?c=((n-s)/r+(n<s?6:0))/6:o===n?c=((s-t)/r+2)/6:c=((t-n)/r+4)/6,{h:c*360,s:l,l:a}}function Nm(e,t){let n=[],s=t,o=[...e.colors].sort((C,I)=>I.occurrences-C.occurrences),i=o.filter(C=>C.usage==="background"||C.usage==="fill"),a=o.filter(C=>C.usage==="text"),r=i[0]||o[0],l=r?Ps(r.hex).l<.4:!1;r&&n.push(` --${s}-color-bg: ${r.hex}`);let c=a[0]||(l?o.find(C=>Ps(C.hex).l>.7):o.find(C=>Ps(C.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([r?.hex,c?.hex].filter(Boolean)),u=o.filter(C=>!d.has(C.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(C=>!d.has(C.hex)).slice(0,6).forEach((C,I)=>n.push(` --${s}-color-${I+1}: ${C.hex}`)),r){let C=Ps(r.hex).l;n.push(` --${s}-color-surface: ${l?tl(r.hex,.05):nl(r.hex,.03)}`),n.push(` --${s}-color-border: ${l?tl(r.hex,.15):nl(r.hex,.12)}`)}let g=e.typography.filter(C=>C.role==="heading"||C.role==="subheading"),y=e.typography.filter(C=>C.role==="body"||C.role==="label"||C.role==="caption"),h=g[0]?.fontFamily||y[0]?.fontFamily||"system-ui",b=y[0]?.fontFamily||h;n.push(` --${s}-font-display: "${h}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let x=g.sort((C,I)=>I.fontSize-C.fontSize);x[0]&&n.push(` --${s}-size-h1: ${x[0].fontSize}px`),x[1]&&n.push(` --${s}-size-h2: ${x[1].fontSize}px`),x[2]&&n.push(` --${s}-size-h3: ${x[2].fontSize}px`);let w=y.sort((C,I)=>I.occurrences-C.occurrences)[0];w&&n.push(` --${s}-size-body: ${w.fontSize}px`);let S=[...new Set(e.spacing.map(C=>C.value))].sort((C,I)=>C-I),M=["xs","sm","md","lg","xl","2xl","section"];S.slice(0,M.length).forEach((C,I)=>{n.push(` --${s}-space-${M[I]}: ${C}px`)});let O=e.effects.filter(C=>C.type==="shadow"),R=e.effects.filter(C=>C.type==="radius");O[0]&&n.push(` --${s}-shadow: ${O[0].cssValue}`),R.sort((C,I)=>parseFloat(C.cssValue)-parseFloat(I.cssValue)),R[0]&&n.push(` --${s}-radius: ${R[0].cssValue}`),R[1]&&n.push(` --${s}-radius-lg: ${R[1].cssValue}`);let H=`:root {
1271
1287
  ${n.join(`;
1272
1288
  `)};
1273
1289
  }`,z=`
@@ -1365,11 +1381,11 @@ body {
1365
1381
  });
1366
1382
  }, { threshold: 0.1 });
1367
1383
  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(`
1384
+ })();`}}function tl(e,t){return ol(e,t)}function nl(e,t){return ol(e,-t)}function ol(e,t){let n=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return n=Math.min(255,Math.max(0,Math.round(n+255*t))),s=Math.min(255,Math.max(0,Math.round(s+255*t))),o=Math.min(255,Math.max(0,Math.round(o+255*t))),`#${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${o.toString(16).padStart(2,"0")}`}function Pm(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function Mm(e,t,n){let s=new Set,o=[];for(let i of e){let a=Pm(i.name);if(s.has(a)){let d=2;for(;s.has(`${a}-${d}`);)d++;a=`${a}-${d}`}s.add(a);let r=Om(i.textContent),l=Rm(i,t,n),c=`Figma section "${i.name}" \u2014 ${i.width}x${i.height}px, ${i.textContent.length} text elements, ${i.children.length} children`;o.push({name:a,description:c,contentBrief:r,layoutNotes:l})}return{specs:o,moduleOrder:o.map(i=>i.name)}}function Om(e){let t={};for(let o of e){let i=o.role;t[i]||(t[i]=[]),t[i].push(o.text)}let n=[],s=["headline","subheadline","body","cta","label","caption"];for(let o of s)if(t[o])for(let i of t[o])n.push(`**${o}** (use as field default): "${i}"`);return n.join(`
1385
+ `)}function Rm(e,t,n){let s=[];if(s.push(`Dimensions: ${e.width}x${e.height}px`),e.backgroundColor&&s.push(`Background: ${e.backgroundColor}`),e.layoutMode&&s.push(`Layout: ${e.layoutMode}`),e.itemSpacing&&s.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&s.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`),e.children.length>0){s.push(`
1370
1386
  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
1387
+ Available image assets:`);for(let o of t){let i=sl(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
1388
+ `)}function Fm(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
1373
1389
 
1374
1390
  TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
1375
1391
  - Use the EXACT text content from the design as field default values
@@ -1394,12 +1410,12 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
1394
1410
  ### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let a of e.textContent)i.push(`- **${a.role}** (${a.fontSize}px, weight ${a.fontWeight}): "${a.text}"`)}if(e.children.length>0){i.push(`
1395
1411
  ### Structure (${e.children.length} children)`);for(let a of e.children){let r=`- ${a.type} "${a.name}" (${a.width}x${a.height})`;a.layoutMode&&(r+=` layout: ${a.layoutMode}`),a.childCount>0&&(r+=`, ${a.childCount} children`),a.characters&&(r+=`
1396
1412
  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(`
1413
+ ### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let a of n){let r=sl(a.localPath);i.push(`- \`get_asset_url("${s}/assets/${r}")\` \u2014 ${a.name}`)}}else{i.push(`
1398
1414
  ### Images \u2014 USE IMAGE FIELDS WITH PLACEHOLDERS`),i.push('Do NOT use get_asset_url(). Instead, create "image" type fields in fields.json for each image.'),i.push('Set a descriptive default.src (e.g. "https://placehold.co/600x400?text=Hero+Image") and default.alt text.'),i.push("In the module HTML, use: {{ module.field_name.src }} and {{ module.field_name.alt }}"),i.push("This gives content editors full control to replace images in HubSpot.");for(let a of n)i.push(`- "${a.name}" \u2014 create an image field for this`)}return i.push(`
1399
1415
  ## Module Specification
1400
1416
  - **Name**: ${t.name}
1401
1417
  - **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}".
1418
+ `)}var rl=L(()=>{"use strict";f();qe();ti();ni();si();ie()});var al={};ke(al,{buildPlanModePrompt:()=>Jm});function Jm(e,t,n,s,o){let i=jm(o,!!t?.plan),a=[];return a.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
1403
1419
 
1404
1420
  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
1421
 
@@ -1497,8 +1513,8 @@ ${t.plan}
1497
1513
 
1498
1514
  ${i}`),a.join(`
1499
1515
 
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
1516
+ `)}function jm(e,t){return e===0&&!t?"**Phase 1: UNDERSTAND.** This is the user's first message in plan mode. Acknowledge what they said, then ask 2\u20133 high-leverage questions to surface gaps. The plan block should be a skeleton with TBDs and an **Open questions** section. Do NOT propose specific sections or content yet \u2014 you don't know enough.":e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function oi(e,t){return e.length<=t?e:e.slice(0,t)+`
1517
+ ... [truncated]`}var ll=L(()=>{"use strict";f()});var dl={};ke(dl,{applyPipelineResult:()=>At,handleAgenticGenerate:()=>Ms,handleFigmaImport:()=>$n,handleGenerate:()=>Dm,handleGenerateStream:()=>An,handlePlanModeStream:()=>ci,isGenerating:()=>Wt,isPlanModeActive:()=>di,resolveAgenticEngine:()=>Vt,setParseWarningCallback:()=>ai,shouldUseAgenticMode:()=>ui});import{execSync as ii}from"child_process";function ai(e){ri=e}function Wt(){return ct!==null}function kt(e){if(ct){let t=v();if(!t||t.id!==ct){A.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}Re("assistant",e),ma(e,ri||void 0),j()}async function An(e,t,n,s){let o=v();if(!o)throw new Error("No active session");ct=o.id;let a=s?.length?$s(s):void 0;try{let r=P(),l=r.aiEngine||li();switch(l){case"anthropic-api":case"api":{let c=be("anthropic-api",r);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await xa(e,c,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,kt,a);break}case"claude-oauth":{await va(e,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",t,n,kt,a);break}case"openai-api":{let c=be("openai-api",r);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await wa(e,c,o.themeName,r.openaiApiModel||"gpt-4o",t,n,kt,a);break}case"gemini-api":{let c=be("gemini-api",r);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await Ca(e,c,o.themeName,t,n,kt,a);break}case"claude-code":await ka(e,o.themeName,t,n,kt,a);break;case"gemini-cli":await Wo("gemini",e,o.themeName,t,n,kt,a);break;case"codex-cli":await Wo("codex",e,o.themeName,t,n,kt,a);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{ct=null,ri=null}}function li(){let e=P();if(Le())return"claude-oauth";if(e.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(e.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(e.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return ii("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return ii("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return ii("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Dm(e){let t="";return await An(e,n=>{t+=n}),t}function cl(){let e=v(),t=xe(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder];return{modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,brandAssets:e.brandAssets?{...e.brandAssets}:void 0}}function Vt(e){let t=e.aiEngine||li();if(!Cn(t))throw new Error("Agentic pipeline is not available for this engine.");if(Gt(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Le())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=be(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-4o";break;case"gemini-api":s="gemini-2.5-flash";break;default:s=""}return{engine:t,apiKey:n,model:s}}async function Ms(e,t,n){let s=v();if(!s)throw new Error("No active session");let o=s.id;ct=o;try{let i=P(),{engine:a,apiKey:r,model:l}=Vt(i),c=i.agenticConcurrency||20,d=cl(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
1502
1518
 
1503
1519
  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
1520
 
@@ -1514,17 +1530,17 @@ ${e}`);let g=n?.length?$s(n):void 0;if(g?.length)for(let S of g)S.type==="docume
1514
1530
  [Attached document: ${S.originalName}]
1515
1531
  ${S.extractedText}`),S.type==="image"&&S.usage==="asset"&&S.assetPath&&(m+=`
1516
1532
 
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+=`
1533
+ [Uploaded image: ${S.originalName} \u2192 available as get_asset_url("${S.assetPath}")]`);let y=at(),h=new Set(d.modules.map(S=>S.moduleName)),b=y.filter(S=>!h.has(S.module.moduleName)).map(S=>({name:S.module.moduleName,usedIn:S.usedIn})),x=await Qa(m,d,a,r,l,c,t,b),w=v();if(!w||w.id!==o)throw A.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return x}finally{ct=null}}async function $n(e,t,n,s){let o=v();if(!o)throw new Error("No active session");let i=o.id;ct=i;try{let{runFigmaConversion:a}=await Promise.resolve().then(()=>(rl(),il)),r=P(),{engine:l,apiKey:c,model:d}=Vt(r),u=r.agenticConcurrency||20,m=cl(),g=await a(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets),y=v();if(!y||y.id!==i)throw A.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{ct=null}}function At(e,t){oe({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Ke(e.moduleOrder),Re("assistant",e.assistantMessage,t),j()}async function ci(e,t,n){let s=v();if(!s)throw new Error("No active session");let o=P(),{engine:i,apiKey:a,model:r}=Vt(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(ll(),al)),Promise.resolve().then(()=>(qe(),Pa))]),d=s.messages.filter(S=>S.role==="assistant").length,u=s.modules.map(S=>S.moduleName),m=at(),g=new Set(u),y=m.filter(S=>!g.has(S.module.moduleName)).map(S=>({name:S.module.moduleName,usedIn:S.usedIn})),h=l(s.themeName,s.brandAssets,u,y,d),b=n?.length?$s(n):void 0,x=e;if(b?.length)for(let S of b)S.type==="document"&&S.extractedText&&(x+=`
1518
1534
 
1519
1535
  ---
1520
1536
  [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=`
1537
+ ${S.extractedText}`);let w=await c(i,a,r,{systemPrompt:h,messages:[{role:"user",content:x}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return w.type==="text"?w.text:JSON.stringify(w.data)}function di(){return!!P().planMode}function ui(){let e=P(),t=e.aiEngine||li();return Cn(t)?e.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:e.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var ri,ct,Tn=L(()=>{"use strict";f();Q();pe();As();ie();Vo();tt();Yo();el();ri=null;ct=null});var Ls={};ke(Ls,{collectThemeFiles:()=>ec,extractDesignContext:()=>dp});import{existsSync as js,readdirSync as Ds,readFileSync as rp}from"fs";import{join as Xe}from"path";import{spawn as ap}from"child_process";async function Ql(){return yi||(yi=(await import("@anthropic-ai/sdk")).default),yi}function _n(e){try{return rp(e,"utf-8")}catch{return""}}function ec(e){let t=[],n=0;function s(r,l){if(!l.trim())return!0;let c=`
1522
1538
  ### ${r}
1523
1539
  \`\`\`
1524
1540
  ${l}
1525
1541
  \`\`\`
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}
1542
+ `;return n+c.length>lp?!1:(t.push(c),n+=c.length,!0)}let o=_n(Xe(e,"theme.json"));o&&s("theme.json",o);let i=Xe(e,"css");if(js(i)){for(let r of Ds(i).filter(l=>l.endsWith(".css")))if(!s(`css/${r}`,_n(Xe(i,r))))break}let a=Xe(e,"modules");if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"module.css"));if(c&&!s(`modules/${r}/module.css`,c))break}if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"module.html"));if(c&&!s(`modules/${r}/module.html`,c))break}if(js(a))for(let r of Ds(a).filter(l=>l.endsWith(".module"))){let l=Xe(a,r),c=_n(Xe(l,"fields.json"));if(c&&!s(`modules/${r}/fields.json`,c))break}return t.join("")}function cp(){if(!Hs)try{Hs=E(Fn("extraction-prompt.md"))}catch{Hs=""}return Hs}function bi(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let a=ap(e,t,{stdio:["pipe","pipe","pipe"],env:i,shell:!0}),r="",l="";a.stdout.on("data",c=>{r+=c.toString()}),a.stderr.on("data",c=>{l+=c.toString()}),a.on("error",c=>o(new Error(`${e} failed to start: ${c.message}`))),a.on("close",c=>{c===0||r.trim()?s(r.trim()):o(new Error(`${e} exited with code ${c}: ${l.trim()}`))}),a.stdin.write(n),a.stdin.end()})}async function dp(e,t){t?.({status:"Collecting theme files..."});let n=ec(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=cp();if(!s)throw new Error("Extraction prompt not found (assets/extraction-prompt.md).");let o=`Analyze this HubSpot CMS theme and extract the design system:
1543
+ ${n}`;t?.({status:"Analyzing design patterns..."});let i=P(),a=i.aiEngine||"anthropic-api",r="";switch(a){case"anthropic-api":case"api":{let l=be("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Ql();r=(await new c({apiKey:l}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(m=>m.type==="text"?m.text:"").join("");break}case"claude-oauth":{let{getValidAccessToken:l,OAUTH_EXTRA_HEADERS:c,OAUTH_SYSTEM_PREFIX:d}=await Promise.resolve().then(()=>(tt(),so)),u=await l();if(!u)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let m=await Ql();r=(await new m({authToken:u,defaultHeaders:c}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:[{type:"text",text:d},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]})).content.map(h=>h.type==="text"?h.text:"").join("");break}case"openai-api":{let l=be("openai-api");if(!l)throw new Error("OpenAI API key not configured. Open Settings to add one.");let c=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify({model:i.openaiApiModel||"gpt-4o",max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!c.ok)throw new Error(`OpenAI API error: ${c.status} ${await c.text()}`);r=(await c.json()).choices?.[0]?.message?.content||"";break}case"gemini-api":{let l=be("gemini-api");if(!l)throw new Error("Gemini API key not configured. Open Settings to add one.");let c=i.geminiApiModel||"gemini-2.5-flash",d=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${c}:generateContent?key=${l}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!d.ok)throw new Error(`Gemini API error: ${d.status} ${await d.text()}`);r=(await d.json()).candidates?.[0]?.content?.parts?.map(m=>m.text).join("")||"";break}case"claude-code":{let l=`${s}
1528
1544
 
1529
1545
  ## User Request
1530
1546
  ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await bi("claude",c,l);break}case"gemini-cli":{let l=`${s}
@@ -1533,7 +1549,7 @@ ${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=awa
1533
1549
  ${o}`;r=await bi("gemini",[],l);break}case"codex-cli":{let l=`${s}
1534
1550
 
1535
1551
  ## User Request
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.
1552
+ ${o}`;r=await bi("codex",[],l);break}default:throw new Error(`Unknown AI engine: ${a}. Open Settings to configure one.`)}if(!r.trim())throw new Error("AI returned empty response.");return t?.({status:"Design extraction complete."}),r}var yi,lp,Hs,Bs=L(()=>{"use strict";f();te();Q();yi=null;lp=8e4;Hs=""});var tc={};ke(tc,{extractBrandvoice:()=>up});async function up(e,t,n,s){if(!e||e.length<50)return null;let o=`You are a brand strategist. Analyze the rendered landing page HTML below and extract a concise brand voice guide. The HTML contains the actual text content with all template variables resolved to their default values.
1537
1553
 
1538
1554
  Return a markdown document with these sections (skip any section where the content provides no signal):
1539
1555
 
@@ -1553,7 +1569,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
1553
1569
  ## Dos and Don'ts
1554
1570
  3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
1555
1571
 
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.
1572
+ Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Ce(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),a=i.type==="text"?i.text:JSON.stringify(i.data);return!a||a.trim().length<20?null:(A.info("brandvoice-extractor",`Extracted brand voice (${a.length} chars)`),a.trim())}catch(i){let a=i instanceof Error?i.message:String(i);return A.warn("brandvoice-extractor",`Brand voice extraction failed: ${a}`),null}}var nc=L(()=>{"use strict";f();qe();ie()});var Si={};ke(Si,{extractThemeContext:()=>mp});async function mp(e,t,n,s,o){if(!e||e.length<50)return null;let a=`You are a content analyst. Extract a concise product/company brief from the rendered landing page HTML below. The HTML contains the actual text content (headings, paragraphs, button labels, image alt text, etc.) with all template variables resolved to their default values.
1557
1573
 
1558
1574
  Return a markdown document with these sections (skip any section where the content provides no information):
1559
1575
 
@@ -1575,34 +1591,34 @@ Specific terms, product names, or branded language used consistently.
1575
1591
  Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
1576
1592
 
1577
1593
  Existing product context (update if the new content adds info, keep what's still accurate):
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)}
1594
+ ${t}`:""}`;try{let r=await Ce(n,s,o,{systemPrompt:a,messages:[{role:"user",content:e}],maxTokens:1e3}),l=r.type==="text"?r.text:JSON.stringify(r.data);return!l||l.trim().length<20?null:(A.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(r){let l=r instanceof Error?r.message:String(r);return A.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var xi=L(()=>{"use strict";f();qe();ie()});import{writeFileSync as bp,mkdirSync as $c}from"fs";import{join as Gs}from"path";import{randomUUID as Sp}from"crypto";function Tc(e){let t=e.match(xp);if(!t)return null;let n=t[1],s=t[2]?decodeURIComponent(t[2].replace(/-/g," ")):void 0,o;try{let a=new URL(e).searchParams.get("node-id");a&&(o=a.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function Vs(e,t){let n=await fetch(`${vp}${e}`,{headers:{"X-Figma-Token":t}});if(!n.ok){let s=await n.text().catch(()=>""),o=new Error(`Figma API ${n.status}: ${s.slice(0,200)}`);throw o.status=n.status,o}return n.json()}async function Ci(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=Ac.length)throw s;let a=Ac[n];A.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${a}s`),t&&t(`Figma rate limited \u2014 retrying in ${a}s...`),await new Promise(r=>setTimeout(r,a*1e3))}}function Tt(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)Tt(s,t,n+1)}function Ic(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=Ic(n,t);if(s)return s}return null}function wp(e,t){if(t){let s=Ic(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>wi.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>wi.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>wi.has(s.type)):[]}function Ws(e){let t=Math.round(e.r*255),n=Math.round(e.g*255),s=Math.round(e.b*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}`}function Cp(e){let t=new Map;for(let n of e)Tt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=Ws(o.color),a=t.get(i),r=s.type==="TEXT",l=r?"text":"fill";a?(a.occurrences++,r&&a.usage!=="text"&&(a.usage="text")):t.set(i,{hex:i,opacity:o.opacity??o.color.a,occurrences:1,usage:l})}}if(s.strokes){for(let o of s.strokes)if(o.type==="SOLID"&&o.color){let i=Ws(o.color),a=t.get(i);a?a.occurrences++:t.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function kp(e){let t=new Map;for(let n of e)Tt(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,a=o.fontWeight||400,r=o.lineHeightPx?Math.round(o.lineHeightPx/i*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";i>=32?d="heading":i>=20?d="subheading":i<=12?d="caption":a>=600&&i<=14&&(d="label");let u=`${c}-${i}-${a}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:a,lineHeight:r,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function Ap(e){let t=[],n=new Set;for(let s of e)Tt(s,o=>{if(!o.layoutMode||o.layoutMode==="NONE")return;if(o.itemSpacing&&o.itemSpacing>0){let c=`gap-${o.itemSpacing}-${o.name}`;n.has(c)||(n.add(c),t.push({context:`${o.name} gap`,value:o.itemSpacing,type:"gap"}))}let i=o.paddingTop||0,a=o.paddingRight||0,r=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||a>0||r>0||l>0){let c=`pad-${i}-${a}-${r}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===r&&l===a&&i===l?i:Math.max(i,a,r,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function $p(e){let t=[],n=new Set;for(let s of e)Tt(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r:a,g:r,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(a*255)},${Math.round(r*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let i=`${o.cornerRadius}px`;n.has(`radius-${i}`)||(n.add(`radius-${i}`),t.push({type:"radius",cssValue:i,context:o.name}))}});return t}function Tp(e,t){let n=[];return Tt(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,a="body";o>=32?a="headline":o>=20?a="subheadline":o<=12?a="caption":i>=600&&o<=16&&(a="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(a="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:a,sectionName:t})}),n}function Ip(e){let t=e.absoluteBoundingBox;return{name:e.name,type:e.type,nodeId:e.id,width:t?.width||0,height:t?.height||0,layoutMode:e.layoutMode==="NONE"?void 0:e.layoutMode,childCount:e.children?.length||0,characters:e.type==="TEXT"?e.characters:void 0}}function Ep(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Ws(t.color)}if(e.backgroundColor)return Ws(e.backgroundColor)}function _p(e){return e.map(t=>{let n=t.absoluteBoundingBox;return{name:t.name,nodeId:t.id,width:n?.width||0,height:n?.height||0,textContent:Tp(t,t.name),children:(t.children||[]).slice(0,20).map(Ip),backgroundColor:Ep(t),layoutMode:t.layoutMode==="NONE"?void 0:t.layoutMode,itemSpacing:t.itemSpacing,paddingTop:t.paddingTop,paddingRight:t.paddingRight,paddingBottom:t.paddingBottom,paddingLeft:t.paddingLeft}})}function Np(e){let t=[];for(let n of e)Tt(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="IMAGE"&&o.imageRef){t.push({nodeId:s.id,name:s.name||"image"});break}}});return t}async function Ec(e,t){let n=await fetch(e);if(!n.ok)throw new Error(`Failed to download image: ${n.status}`);let s=Buffer.from(await n.arrayBuffer());bp(t,s)}async function Pp(e,t,n,s,o){if(t.length===0)return new Map;$c(s,{recursive:!0});let a=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let r=await Ci(()=>Vs(`/v1/images/${e}?ids=${a}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(r.images)){if(!d)continue;let u=c.replace(/:/g,"-"),m=Gs(s,`frame-${u}.png`);try{await Ec(d,m),l.set(c,m),A.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){A.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function Mp(e,t,n,s,o){if(t.length===0)return[];$c(s,{recursive:!0});let i=50,a=[];for(let r=0;r<t.length;r+=i){let l=t.slice(r,r+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${r+1}-${Math.min(r+i,t.length)} of ${t.length})...`);let d=await Ci(()=>Vs(`/v1/images/${e}?ids=${c}&format=png&scale=2`,n),o);for(let u of l){let m=d.images[u.nodeId];if(!m)continue;let y=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${Sp().slice(0,6)}.png`,h=Gs(s,y);try{await Ec(m,h),a.push({name:u.name,localPath:h,nodeId:u.nodeId,format:"png"}),A.info("figma",`Downloaded asset: ${y}`)}catch(b){A.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return a}async function _c(e,t,n,s,o){o&&o("Fetching Figma file...");let i=t?`/v1/files/${e}?ids=${t}&geometry=paths`:`/v1/files/${e}?geometry=paths`,a=await Ci(()=>Vs(i,n),o);A.info("figma",`Fetched file: ${a.name}`);let r=wp(a.document,t);if(r.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");A.info("figma",`Found ${r.length} top-level frames`),o&&o(`Found ${r.length} sections. Extracting design tokens...`);let l={colors:Cp(r),typography:kp(r),spacing:Ap(r),effects:$p(r)};A.info("figma","Design tokens extracted",{colors:l.colors.length,typography:l.typography.length,spacing:l.spacing.length,effects:l.effects.length}),o&&o("Mapping page structure...");let c=_p(r),d=Gs(s,".vibespot","figma-frames"),u=await Pp(e,r,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=Np(r),y=Gs(s,"assets"),h=await Mp(e,g,n,y,o);return A.info("figma",`Extraction complete: ${m.length} sections, ${h.length} assets`),{fileName:a.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:h}}function Nc(e){let t=e.fileName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,30);return{fileName:e.fileName,fileUrl:e.fileUrl,sectionNames:e.sections.map(n=>n.name),sectionCount:e.sections.length,colorPalette:e.designTokens.colors.slice(0,10).map(n=>n.hex),fontFamilies:[...new Set(e.designTokens.typography.map(n=>n.fontFamily))],textBlockCount:e.sections.reduce((n,s)=>n+s.textContent.length,0),assetCount:e.assets.length,suggestedThemeName:t}}async function Pc(e){return await Vs("/v1/me",e)}var xp,vp,Ac,wi,Mc=L(()=>{"use strict";f();ie();xp=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;vp="https://api.figma.com",Ac=[10,20,40,60,120];wi=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var Dc={};ke(Dc,{getCachedExtraction:()=>jc,handleFigmaExtractRoute:()=>Ai,handleFigmaGenerateRoute:()=>$i,handleFigmaTestTokenRoute:()=>ki});import{randomUUID as Oc}from"crypto";import{existsSync as Rc,mkdirSync as Fc,writeFileSync as Op,copyFileSync as Rp}from"fs";import{join as Ks,basename as Fp}from"path";function Jc(){let e=Date.now();for(let[t,n]of Nn)n.expires<e&&Nn.delete(t)}function jc(e){Jc();let t=Nn.get(e);return t?(Nn.delete(e),t.extraction):null}function ki(e,t){Ye(e,t,async n=>{let s=n.token||P().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Pc(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);A.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function Ai(e,t){Ye(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||P().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=Tc(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let r=v()?.themePath||`/tmp/vibespot-figma-${Oc().slice(0,8)}`;t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
1579
1595
 
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)}
1596
+ `)};try{let c=await _c(i.fileKey,i.nodeId,o,r,m=>l({type:"progress",message:m})),d=Oc();Jc(),Nn.set(d,{extraction:c,expires:Date.now()+Jp});let u=Nc(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);A.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function jp(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((r,l)=>l.count-r.count),i=o[0],a=o[1];i&&s.push(`- **Primary:** \`${i.hex}\` (${i.name||"dominant color"})`),a&&s.push(`- **Secondary:** \`${a.hex}\` (${a.name||"accent color"})`),s.push(""),s.push("### Full palette","");for(let r of o.slice(0,15)){let l=r.name?`${r.name}`:`${r.count}\xD7 used`;s.push(`- \`${r.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(a=>a.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let i=new Set;for(let a of t.typography){let r=`${a.role}-${a.fontSize}-${a.fontWeight}`;i.has(r)||(i.add(r),s.push(`| ${a.role} | ${a.fontFamily} | ${a.fontSize}px | ${a.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(i=>i.value))].sort((i,a)=>i-a);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let i of t.spacing)s.push(`- **${i.property}** (${i.context}): ${i.value}px`);s.push("")}if(t.effects.length>0){s.push("## Effects","");for(let o of t.effects)o.boxShadow&&s.push(`- **Box shadow:** \`${o.boxShadow}\``),o.borderRadius&&s.push(`- **Border radius:** ${o.borderRadius}px`);s.push("")}return s.join(`
1597
+ `)}function $i(e,t){Ye(e,t,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(t,400,{error:"Missing extractionId or themeName"});return}let a=jc(s);if(!a){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let r=v();if(!r){p(t,400,{error:"No active session. Create a theme first."});return}t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
1582
1598
 
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.
1599
+ `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=jp(a),d=Ks(r.themePath,".vibespot");if(Rc(d)||Fc(d,{recursive:!0}),Op(Ks(d,"styleguide.md"),c),r.brandAssets||(r.brandAssets={}),r.brandAssets.styleguide=c,j(),l({type:"progress",message:"Styleguide saved."}),r.templates.length===0)bs("landing_page","Landing Page");else{r.modules=[],r.moduleOrder=[],r.sharedCss="",r.sharedJs="";let h=r.templates.find(b=>b.id===r.activeTemplateId);h&&(h.modules=[],h.moduleOrder=[],h.sharedCss="",h.sharedJs="")}if(j(),i&&a.assets.length>0){let h=Ks(r.themePath,"assets");Fc(h,{recursive:!0});let b=0;for(let x of a.assets)if(Rc(x.localPath)){let w=Ks(h,Fp(x.localPath));try{Rp(x.localPath,w),x.localPath=w,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],g=await $n(a,o,h=>{if(h.type==="agent_step")u.push({step:h.step,label:h.label}),l({type:"progress",message:`${h.label}...`});else if(h.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(h.decision)),l({type:"progress",message:` ${h.decision}`})}else h.type==="design_system_ready"?oe({sharedCss:h.sharedCss,sharedJs:h.sharedJs}):h.type==="blueprint_ready"?(oe({sharedCss:h.sharedCss,sharedJs:h.sharedJs}),Ke(h.moduleOrder),l({type:"progress",message:`Planned ${h.moduleOrder.length} modules`})):h.type==="module_progress"&&(h.status==="generating"?l({type:"progress",message:`Generating module: ${h.module}`}):h.status==="complete"&&h.moduleFiles?(oe({modules:[{moduleName:h.module,fieldsJson:h.moduleFiles.fieldsJson,metaJson:h.moduleFiles.metaJson,moduleHtml:h.moduleFiles.moduleHtml,moduleCss:h.moduleFiles.moduleCss,moduleJs:h.moduleFiles.moduleJs}]}),m.push({name:h.module,status:"complete"}),l({type:"progress",message:`Module complete: ${h.module}`})):h.status==="failed"&&(m.push({name:h.module,status:"failed"}),l({type:"progress",message:`Module failed: ${h.module}`})))},{useAssets:i});At(g,{steps:u,modules:m,stats:g.stats}),_e(),St(r.themePath,`Figma import: ${a.fileName}`);let y=X().map(h=>h.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${y.length} modules generated`}),l({type:"complete",ok:!0,modules:y})}catch(c){let d=c instanceof Error?c.message:String(c);A.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Nn,Jp,Ti=L(()=>{"use strict";f();Fe();Q();ie();Mc();pe();pn();Po();jt();Tn();Dt();Nn=new Map,Jp=1800*1e3});f();f();import{Command as Yp}from"commander";f();f();f();import Et from"chalk";var De={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Ni=!!process.env.NO_COLOR;function Qe(e){return Ni?Et:Et.hex(e)}var N={accent:Qe(De.accent),accentBright:Qe(De.accentBright),success:Qe(De.success),info:Qe(De.info),warn:Qe(De.warn),error:Qe(De.error),muted:Qe(De.muted),vibes:Qe(De.vibes),heading:Ni?Et.bold:Et.bold.hex(De.accent),command:Qe(De.accentBright),dim:Et.dim,bold:Et.bold};te();function He(){let e=N.vibes,t=N.accent,n=N.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${N.dim(`v${Nt()}`)}`),console.log()}f();f();ht();Q();tt();import{join as Bn}from"path";import{homedir as Un}from"os";import{readFileSync as Hi,existsSync as Gn,readdirSync as rd}from"fs";var yt=process.platform==="win32"?"where":"which";function en(){let e=J("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:J(`${yt} node`).stdout}}function tn(){let e=J("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:J(`${yt} git`).stdout}}function Be(){let e=J("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:J(`${yt} hs`).stdout}}function nn(){let e=J("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Bn(Un(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(Gn(t)){let o=rd(t);(o.some(a=>a.includes("credentials")||a.includes("auth")||a.includes("token")||a===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:J(`${yt} claude`).stdout,authenticated:n,authDetail:s}}function sn(e){try{let t=Bn(Un(),".hscli","config.yml");if(!Gn(t))return"na1";let n=Hi(t,"utf-8"),s=n.indexOf(`accountId: ${e}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let a=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!a)return"na1";if(a[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function Ue(){let e=J("hs accounts list");if(!e.success||!e.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let t=[],n="",s="",o=e.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=e.stdout.split(`
1600
+ `);for(let a of i){let r=a.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(r&&!/Account ID/i.test(a)&&!/^-+$/.test(a.trim())&&!/^Name\s/i.test(a.trim())){let l=r[1].trim(),c=r[2].trim(),d=r[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function on(){let e=J("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Bn(Un(),".config","gcloud","application_default_credentials.json"),n=Gn(t),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:e.stdout,path:J(`${yt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function rn(){let e=J("codex --version");if(!e.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=!!process.env.OPENAI_API_KEY,n=!1;try{let i=Bn(Un(),".codex","auth.json");Gn(i)&&(n=Hi(i,"utf-8").length>10)}catch{}let s=t||n,o=n?"Authenticated (OAuth)":t?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:e.stdout,path:J(`${yt} codex`).stdout,authenticated:s,authDetail:o}}function io(){let e=J("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
1601
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:J(`${yt} gh`).stdout}}function ro(){let e=J("gh auth status 2>&1");if(!e.success&&!e.stdout)return{authenticated:!1,username:""};let t=e.stdout||e.stderr||"",n=t.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=t.match(/account\s+(\S+)/);return s&&t.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:t.includes("Logged in"),username:""}}function Li(){return!!process.env.ANTHROPIC_API_KEY}function Wn(e){return parseInt(e.split(".")[0],10)>=18}function Bi(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function ad(){let e=P(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=ut();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}var oo={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function Vn(){let e=P(),t=en(),n=tn(),s=e.hubspotUploadMode||"api",o;if(s==="cli"){let x=Be(),w=x.found?Ue():{authenticated:!1,portalName:"",portalId:"",accounts:[]},S=w.portalId?sn(w.portalId):"na1";o={...x,...w,dataCenter:S,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...ad()};let i=io(),a=i.found?ro():{authenticated:!1,username:""},r={authenticated:Le(),expiresAt:Qt()?.expiresAt},l=e.enabledCLITools||[],c=Xt("claude-code")?nn():{...oo,name:"Claude Code"},d=Xt("gemini-cli")?on():{...oo,name:"Gemini CLI"},u=Xt("codex-cli")?rn():{...oo,name:"OpenAI Codex CLI"};function m(x,...w){if(x)return{configured:!0,masked:jn(x),source:"config"};for(let S of w)if(process.env[S])return{configured:!0,masked:jn(process.env[S]),source:"env"};return{configured:!1,masked:"",source:null}}let g=m(e.anthropicApiKey,"ANTHROPIC_API_KEY"),y=m(e.openaiApiKey,"OPENAI_API_KEY"),h=m(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),b=[];return c.found&&c.authenticated&&b.push("claude-code"),r.authenticated&&b.push("claude-oauth"),g.configured&&b.push("anthropic-api"),y.configured&&b.push("openai-api"),d.found&&d.authenticated&&b.push("gemini-cli"),h.configured&&b.push("gemini-api"),u.found&&u.authenticated&&b.push("codex-cli"),{tools:{node:t,git:n,hubspot:o,github:{...i,...a},claudeCode:c,claudeOAuth:r,geminiCli:d,codexCli:u},apiKeys:{anthropic:g,openai:y,gemini:h},activeEngine:e.aiEngine||null,availableEngines:b,enabledCLITools:l}}tt();ht();Q();bt();f();import*as Y from"@clack/prompts";function lo(e){Y.isCancel(e)&&(Y.cancel(N.muted("Operation cancelled.")),process.exit(0))}async function ge(e){Y.intro(N.heading(e))}async function fe(e){Y.outro(N.success(e))}async function Ge(e,t){Y.note(e,t?N.heading(t):void 0)}async function Ne(e){let t=await Y.text({message:N.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return lo(t),t}async function le(e){let t=await Y.confirm({message:N.accent(e.message),initialValue:e.initialValue??!0});return lo(t),t}async function Rt(e){let t=await Y.select({message:N.accent(e.message),options:e.options});return lo(t),t}async function he(){let e=Y.spinner();return{start:t=>e.start(N.muted(t)),stop:t=>e.stop(N.success(t)),message:t=>e.message(N.muted(t))}}function ne(e){Y.log.info(e)}function U(e){Y.log.success(N.success(e))}function q(e){Y.log.warn(N.warn(e))}function V(e){Y.log.error(N.error(e))}async function qn(){await ge("Checking your environment");let e=en();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Wn(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),U(`Node.js v${e.version}`);let t=tn();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),U(`Git ${t.version}`);let n=P(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Se(),x=ut();if(b)o=x?.portalId||"",i=x?.portalName||"",U(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{q("No HubSpot account connected"),await Ge(`You need a Personal Access Key to deploy themes.
1586
1602
  Create one at: https://app.hubspot.com/l/personal-access-key
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.
1603
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let w=await Ne({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:M=>M.trim()?void 0:"Key is required"}),S=await he();S.start("Validating key...");try{let M=await zn(w);qt(w,M.portalId,M.portalName,M.dataCenter),b=w,o=M.portalId,i=M.portalName,S.stop(`Connected to ${M.portalName} (${M.portalId})`)}catch(M){S.stop("Validation failed"),V(`Invalid key: ${M instanceof Error?M.message:String(M)}`),process.exit(1)}}}else{let b=Be();if(b.found)U(`HubSpot CLI v${b.version}`);else{q("HubSpot CLI not found"),await le({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let S=await he();S.start("Installing HubSpot CLI..."),J("npm install -g @hubspot/cli").success||(S.stop("Failed"),V("Try: npm install -g @hubspot/cli"),process.exit(1)),b=Be(),S.stop(`HubSpot CLI v${b.version} installed`)}let x=Ue();if(x.authenticated)U(`HubSpot portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`);else{q("HubSpot not authenticated"),await le({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let S=await he();S.start("Waiting for HubSpot authentication..."),Ri("hs init")||(S.stop("Authentication failed"),process.exit(1)),x=Ue(),S.stop(`Connected to portal${x.portalName?`: ${x.portalName}`:""} (ID: ${x.portalId})`)}o=x.portalId,i=x.portalName}let a=nn(),r=on(),l=rn(),c=Li(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"},u=Le(),m,g=n.aiEngine,y=[];if(a.found&&y.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&y.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),r.found&&y.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&y.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&y.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&y.sort((b,x)=>b.value===g?-1:x.value===g?1:0),y.length===1)m=y[0].value,U(`AI engine: ${d[m]} (auto-detected)`);else if(y.length>1)m=await Rt({message:"Choose your AI engine:",options:y});else if(await Ge(`You need an AI coding assistant to power the conversion.
1588
1604
 
1589
- ${_.bold("Option 1:")} Install Claude Code ${_.muted("(recommended)")}
1605
+ ${N.bold("Option 1:")} Install Claude Code ${N.muted("(recommended)")}
1590
1606
  https://claude.ai/code
1591
1607
 
1592
- ${_.bold("Option 2:")} Install Gemini CLI
1608
+ ${N.bold("Option 2:")} Install Gemini CLI
1593
1609
  https://github.com/google-gemini/gemini-cli
1594
1610
 
1595
- ${_.bold("Option 3:")} Install OpenAI Codex
1611
+ ${N.bold("Option 3:")} Install OpenAI Codex
1596
1612
  https://github.com/openai/codex
1597
1613
 
1598
- ${_.bold("Option 4:")} Set an Anthropic API key
1614
+ ${N.bold("Option 4:")} Set an Anthropic API key
1599
1615
  export ANTHROPIC_API_KEY=sk-ant-...
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(`
1616
+ (get one at https://console.anthropic.com)`,"AI engine required"),m=await Rt({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),m==="api"){let b=await Ne({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:x=>x.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,W({anthropicApiKey:b})}let h;return m==="claude-code"&&(h=await Rt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),W({aiEngine:m}),await fe("Environment ready!"),{aiEngine:m,model:h,portalId:o,portalName:i}}f();ht();te();import{readdirSync as co,statSync as fd}from"fs";import{join as se,basename as uo,extname as hd}from"path";function zi(e){let t=[],n=[se(e,"src/components/landing"),se(e,"src/components/sections"),se(e,"src/components"),se(e,"src/pages"),se(e,"app/components"),se(e,"components")];for(let s of n)if(k(s))try{let o=co(s);for(let i of o){let a=se(s,i);if(!fd(a).isFile())continue;let l=hd(i);if(![".tsx",".jsx"].includes(l))continue;let c=uo(i,l);if(c.startsWith("ui")||c==="index")continue;let d=E(a),u=yd(c,d);t.push({name:c,path:a,description:u})}}catch{}return t}function yd(e,t){let n=[];return/carousel|slider|swiper|embla/i.test(t)&&n.push("carousel"),/accordion|collapsible|expand/i.test(t)&&n.push("accordion"),/form|submit|input.*email/i.test(t)&&n.push("form"),/nav|navigation|menu/i.test(t)&&n.push("navigation"),/hero|headline|tagline/i.test(t)&&n.push("hero"),/footer|copyright/i.test(t)&&n.push("footer"),/testimonial|quote|review/i.test(t)&&n.push("testimonials"),/pricing|plan|tier/i.test(t)&&n.push("pricing"),/faq|question.*answer/i.test(t)&&n.push("FAQ"),/feature|benefit|advantage/i.test(t)&&n.push("features"),/contact|get.in.touch/i.test(t)&&n.push("contact"),/cta|call.to.action/i.test(t)&&n.push("CTA"),/team|member|bio/i.test(t)&&n.push("team"),n.length===0?e.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function Yi(e){let t=[se(e,"src/index.css"),se(e,"src/globals.css"),se(e,"src/app/globals.css"),se(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!k(o))continue;let i=E(o),a=i.match(/--[\w-]+:/g);a&&(n+=a.length);let r=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(r)for(let c of r){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function qi(e){let t=[],n=se(e,"src/hooks");if(k(n))try{let o=co(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=se(e,"src/components/landing");if(k(s))try{let o=co(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let a=E(se(s,i));/carousel|embla|swiper/i.test(a)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(a)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(a)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(a)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function Xi(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let l=uo(e.replace(/\.git$/,""))||"react-source";if(t=se(process.cwd(),"workspace",l),!k(t)){let c=J(`git clone --depth 1 "${e}" "${t}"`);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!k(t))throw new Error(`Directory not found: ${t}`);let s=zi(t),o=k(se(t,"tailwind.config.ts"))||k(se(t,"tailwind.config.js")),{varCount:i,fonts:a}=Yi(t),r=qi(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:a,interactions:r}}async function Xn(){await ge("Source Project");let e=await Ne({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:y=>{if(!y.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){n=!0;let y=uo(e.replace(/\.git$/,""))||"react-source";if(t=se(process.cwd(),"workspace",y),k(t))U(`Using existing clone: ${N.dim(t)}`);else{let h=await he();h.start("Cloning repository..."),J(`git clone --depth 1 "${e}" "${t}"`).success||(h.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),h.stop(`Cloned to ${N.dim(t)}`)}}else t=e,k(t)||(V(`Directory not found: ${t}`),process.exit(1)),U(`Using local source: ${N.dim(t)}`);let s=await he();s.start("Analyzing project structure...");let o=zi(t),i=k(se(t,"tailwind.config.ts"))||k(se(t,"tailwind.config.js")),{varCount:a,fonts:r}=Yi(t),l=qi(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(q("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((y,h)=>` ${N.dim(`${h+1}.`)} ${N.bold(y.name)} ${N.muted(`\u2014 ${y.description}`)}`).join(`
1601
1617
  `),d=i?`Tailwind + custom CSS (${a} variables)`:`Custom CSS (${a} variables)`,u=r.length>0?r.join(", "):"System fonts",m=l.join(", ");return await Ge(`${c}
1602
1618
 
1603
1619
  CSS: ${d}
1604
1620
  JS: ${m}
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(`
1621
+ Font: ${u}`,`${o.length} components detected`),await le({message:"Does this look right?"})||(V("Please adjust your source directory and try again."),process.exit(0)),await fe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:a,fonts:r,interactions:l}}f();ht();te();import{join as un}from"path";Q();Qn();es();async function ts(){await ge("HubSpot Theme Setup");let e=await Rt({message:"Do you have an existing HubSpot theme?",options:[{value:"fetch",label:"Fetch my existing theme from HubSpot",hint:"downloads your current theme"},{value:"create",label:"Start fresh (HubSpot Boilerplate)",hint:"creates a new starter theme"}]}),t,n,s=un(process.cwd(),"workspace");if(Te(s),e==="fetch"){t=await Ne({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=un(s,t);let l=await he();l.start("Fetching theme from HubSpot...");let c=P(),d=Se();if(c.hubspotUploadMode==="cli"||!d)J(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),V(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await dn(d,t,n)}catch(u){l.stop("Fetch failed"),V(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${N.dim(n)}`)}else{t=await Ne({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=un(s,t);let l=await he();l.start("Creating theme...");try{cn(n,t)}catch(c){l.stop("Creation failed"),V(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${N.dim(n)}`)}await ge("Checking theme compatibility");let o=un(n,"templates/layouts/base.html");k(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),U("base.html found");let i=E(o),a=!1;if(i.includes("template_css"))U("template_css support");else{q("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
1606
1622
  `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
1607
1623
  `,l);i=i.slice(0,c)+`
1608
1624
  {% if template_css %}
@@ -1615,17 +1631,17 @@ ${_.bold("Option 4:")} Set an Anthropic API key
1615
1631
  {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
1616
1632
  `)+1;i=i.slice(0,i.indexOf(`
1617
1633
  `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
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+`
1634
+ `,i.indexOf("}}",l)+2)),a=!0}}if(a){let l=await he();l.start("Patching base.html..."),G(o,i),l.stop("base.html patched with template_css/template_js support")}let r=un(n,".hsignore");if(k(r)){let l=E(r);l.includes("docs/")||(G(r,l+`
1619
1635
  docs/
1620
1636
  `),U("Added docs/ to .hsignore"))}else G(r,`docs/
1621
1637
  *.md
1622
1638
  node_modules/
1623
1639
  .git
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}.
1640
+ `),U("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}f();import{join as Ie}from"path";import{readdirSync as mn,rmSync as cr}from"fs";f();ot();te();import{spawn as wd}from"child_process";import{join as K,basename as Cd}from"path";import{readdirSync as We,statSync as ar,writeFileSync as kd}from"fs";var Ad=new Set(["about.html","blog-index.html","blog-post.html","contact.html","home.html","hubdb.html","landing-page.html","pricing.html","qa-test.html","base.html"]),ns=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(t){this.model=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let a=this.countSourceComponents(n),r=this.listModules(s),l=this.listDir(K(s,"css")),c=this.listDir(K(s,"js")),d=this.listDir(K(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${a} source components found)...`);let m="",g="",y=setInterval(()=>{this.reportProgress(s,r,l,c,d,o)},3e3);try{await new Promise((w,S)=>{let M={...process.env};delete M.CLAUDECODE;let O=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&O.push("--model",this.model);let R=wd("claude",O,{cwd:s,stdio:["pipe","pipe","pipe"],env:M,shell:!0});R.stdout.on("data",H=>{m+=H.toString()}),R.stderr.on("data",H=>{g+=H.toString()}),R.on("error",H=>S(new Error(`Claude Code failed to start: ${H.message}`))),R.on("close",H=>{H!==0?S(new Error(`Claude Code exited with code ${H}.
1625
1641
  `+(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)+`
1642
+ `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):w()}),R.stdin.on("error",()=>{}),R.stdin.write(u),R.stdin.end(),setTimeout(()=>{R.kill(),S(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(y)}let h=K(s,"..","vibespot-conversion.log");try{let S=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
1627
1643
  ... (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.
1644
+ `);kd(h,S,"utf-8"),o("status",`Log written to ${Cd(h)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(w=>!r.has(w.moduleName+".module")).length===0){let w=m.slice(0,1500)||"(no output)",S=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
1629
1645
 
1630
1646
  This usually means the model described the conversion instead of using Write tool to create files.
1631
1647
 
@@ -1687,13 +1703,13 @@ HUBSPOT CMS RULES:
1687
1703
  ${Me()}
1688
1704
 
1689
1705
  CONVERSION GUIDE:
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(`
1706
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=K(t,"css");if(k(s)){for(let r of We(s))if(r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=E(K(s,r));break}}let o=K(t,"js");if(k(o)){for(let r of We(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=E(K(o,r));break}}let i=K(t,"templates");if(k(i)){for(let r of We(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=E(K(i,r));break}if(!n.template){for(let r of We(i))if(r.endsWith(".html")&&!Ad.has(r)&&!r.startsWith("system")){let l=E(K(i,r));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let r of We(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=E(K(i,r));if(l.includes("dnd_area")){n.template=l;break}}}}let a=K(t,"modules");if(k(a))for(let r of We(a)){if(!r.endsWith(".module"))continue;let l=K(a,r);if(!ar(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=K(l,"fields.json");k(d)&&(c.fieldsJson=E(d));let u=K(l,"meta.json");k(u)&&(c.metaJson=E(u));let m=K(l,"module.html");k(m)&&(c.moduleHtml=E(m));let g=K(l,"module.css");k(g)&&(c.moduleCss=E(g));let y=K(l,"module.js");k(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=K(t,"modules");return k(n)?new Set(We(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return k(t)?new Set(We(t)):new Set}detectExpectedModules(t,n){let s=K(t,"templates");if(!k(s))return 0;for(let o of We(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=E(K(s,o));if(i.includes("dnd_area")){let a=i.match(/dnd_module/g);return a?a.length:0}}catch{}return 0}countSourceComponents(t){let n=K(t,"src");return k(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of We(t)){let o=K(t,s);try{ar(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};f();ot();te();import $d from"@anthropic-ai/sdk";import{join as ee,basename as Td}from"path";import{readdirSync as lr}from"fs";var ss=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new $d({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,a=nr(o),r=Td(n)||"page",l=r.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);i("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(a,or(c,d,l)),m=ee(s,"css",`${l}-theme.css`);G(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),y=this.findInteractiveComponents(n),h=await this.complete(a,ir(g,y,l)),b=ee(s,"js",`${l}-animations.js`);G(b,h),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let x=this.findComponents(n),w=[];for(let R=0;R<x.length;R++){let H=x[R],z=H.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${z}.module (${R+1}/${x.length})...`);let _=E(H.path),F=await this.complete(a,sr(_,z,`See css/${l}-theme.css`));try{let C=JSON.parse(F),I={moduleName:z,fieldsJson:typeof C.fieldsJson=="string"?C.fieldsJson:JSON.stringify(C.fieldsJson,null,2),metaJson:typeof C.metaJson=="string"?C.metaJson:JSON.stringify(C.metaJson,null,2),moduleHtml:C.moduleHtml||"",moduleCss:C.moduleCss||"",moduleJs:C.moduleJs||void 0},Z=ee(s,"modules",`${z}.module`);Te(Z),G(ee(Z,"fields.json"),I.fieldsJson),G(ee(Z,"meta.json"),I.metaJson),G(ee(Z,"module.html"),I.moduleHtml),G(ee(Z,"module.css"),I.moduleCss),I.moduleJs&&G(ee(Z,"module.js"),I.moduleJs),w.push(I),i("module-done",`${z}.module (${this.countFiles(I)} files)`)}catch{i("module-error",`Failed to parse ${z} \u2014 skipping`)}}i("template","Creating page template...");let S=w.map(R=>R.moduleName),M=await this.complete(a,rr(S,r,l)),O=ee(s,"templates",`lp-${l}.html`);return G(O,M),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:h,template:M,modules:w}}async complete(t,n){return(await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]})).content.find(i=>i.type==="text")?.text||""}findAndReadCSS(t){let n=[ee(t,"src/index.css"),ee(t,"src/globals.css"),ee(t,"src/app/globals.css"),ee(t,"app/globals.css")];for(let s of n)if(k(s))return E(s);return""}findAndReadTailwind(t){let n=[ee(t,"tailwind.config.ts"),ee(t,"tailwind.config.js"),ee(t,"tailwind.config.mjs")];for(let s of n)if(k(s))return E(s);return""}findAndReadHooks(t){let n=ee(t,"src/hooks");if(!k(n))return"";try{return lr(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
1707
+ ${E(ee(n,s))}`).join(`
1692
1708
 
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}
1709
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=E(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
1694
1710
  ${i}`)}return s.join(`
1695
1711
 
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}.
1712
+ `)}findComponents(t){let n=[ee(t,"src/components/landing"),ee(t,"src/components/sections"),ee(t,"src/components")];for(let s of n)if(k(s))try{return lr(s).filter(o=>(o.endsWith(".tsx")||o.endsWith(".jsx"))&&!o.startsWith("ui")&&o!=="index.tsx"&&o!=="index.jsx").map(o=>({name:o.replace(/\.(tsx|jsx)$/,""),path:ee(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};f();ot();te();import{spawn as Id}from"child_process";import{join as Ae}from"path";import{readdirSync as os,statSync as Ed}from"fs";var is=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce(),a=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((r,l)=>{let c=Id("gemini",["-p",a],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Gemini CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Gemini CLI failed: ${u}`)):r()}),setTimeout(()=>{c.kill(),l(new Error("Gemini CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
1697
1713
 
1698
1714
  INSTRUCTIONS:
1699
1715
  1. Analyze all .tsx/.jsx components in the React source
@@ -1708,7 +1724,7 @@ CONVERSION GUIDE:
1708
1724
  ${s}
1709
1725
 
1710
1726
  Do NOT run hs upload \u2014 I will handle that separately.
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}.
1727
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ae(t,"css");if(k(s)){for(let r of os(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=E(Ae(s,r));break}}let o=Ae(t,"js");if(k(o)){for(let r of os(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=E(Ae(o,r));break}}let i=Ae(t,"templates");if(k(i)){for(let r of os(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=E(Ae(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=Ae(t,"modules");if(k(a))for(let r of os(a)){if(!r.endsWith(".module"))continue;let l=Ae(a,r);if(!Ed(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ae(l,"fields.json");k(d)&&(c.fieldsJson=E(d));let u=Ae(l,"meta.json");k(u)&&(c.metaJson=E(u));let m=Ae(l,"module.html");k(m)&&(c.moduleHtml=E(m));let g=Ae(l,"module.css");k(g)&&(c.moduleCss=E(g));let y=Ae(l,"module.js");k(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};f();ot();te();import{spawn as _d}from"child_process";import{join as $e}from"path";import{readdirSync as rs,statSync as Nd}from"fs";var as=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ce(),a=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((r,l)=>{let c=_d("codex",["exec","--full-auto",a],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Codex CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Codex CLI failed: ${u}`)):r()}),setTimeout(()=>{c.kill(),l(new Error("Codex CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
1712
1728
 
1713
1729
  INSTRUCTIONS:
1714
1730
  1. Analyze all .tsx/.jsx components in the React source
@@ -1723,15 +1739,15 @@ CONVERSION GUIDE:
1723
1739
  ${s}
1724
1740
 
1725
1741
  Do NOT run hs upload \u2014 I will handle that separately.
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(`
1742
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=$e(t,"css");if(k(s)){for(let r of rs(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=E($e(s,r));break}}let o=$e(t,"js");if(k(o)){for(let r of rs(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=E($e(o,r));break}}let i=$e(t,"templates");if(k(i)){for(let r of rs(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=E($e(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=$e(t,"modules");if(k(a))for(let r of rs(a)){if(!r.endsWith(".module"))continue;let l=$e(a,r);if(!Nd(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=$e(l,"fields.json");k(d)&&(c.fieldsJson=E(d));let u=$e(l,"meta.json");k(u)&&(c.metaJson=E(u));let m=$e(l,"module.html");k(m)&&(c.moduleHtml=E(m));let g=$e(l,"module.css");k(g)&&(c.moduleCss=E(g));let y=$e(l,"module.js");k(y)&&(c.moduleJs=E(y)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};ot();te();function Pd(e,t){switch(e){case"claude-code":return new ns(t);case"gemini-cli":return new is;case"codex-cli":return new as;case"api":return new ss}}async function ls(e){await ge("Converting React to HubSpot Modules"),await Ge(`AI will now analyze your React code and create
1743
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=Pd(e.aiEngine,e.model),n=ce(),s=await he();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(y,h)=>{y==="created"?U(h):s.message(h)}}),a=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${a}s)`);let r=Md(e.themePath);for(let y of r)U(`Auto-fixed: ${y}`);let l=Od(e.themePath,i),c=[];for(let y of l){let h=y.passed?"\u2705":"\u274C",b=y.passed?"":y.critical?" (CRITICAL)":" (cosmetic)";c.push(`${h} ${y.label}${b}`)}let d=l.filter(y=>y.passed).length;c.push(`
1728
1744
  ${d}/${l.length} checks passed`),await Ge(c.join(`
1729
1745
  `),"Conversion Checklist");let u=l.filter(y=>!y.passed&&y.critical),m=l.filter(y=>!y.passed&&!y.critical);if(u.length>0){if(V(`${u.length} critical issue(s) \u2014 upload will likely fail:
1730
1746
  `+u.map(h=>` - ${h.label}`).join(`
1731
1747
  `)),!await le({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&q(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
1732
1748
  `+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+=`
1749
+ `));let g=Ie(e.themePath,"..","vibespot-conversion.log");return k(g)&&(await le({message:"Keep conversion log file for debugging?",initialValue:!1})?U(`Log saved: ${g}`):cr(g)),await fe("Files ready for upload!"),i}function Md(e){let t=[];Rd(e),Fd(e);let n=Ie(e,"modules");if(k(n))for(let o of mn(n)){if(!o.endsWith(".module"))continue;let i=Ie(n,o,"fields.json");if(!k(i))continue;let a=o.replace(".module",""),r=E(i),l=!1;r.includes('"textarea"')&&(r=r.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${a}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(r)&&(r=r.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${a}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(r),u=!1;dr(d)&&(u=!0,t.push(`${a}: fixed choice field format`)),ur(d)&&(u=!0,t.push(`${a}: fixed link field default value`)),u&&(r=JSON.stringify(d,null,2)+`
1750
+ `,l=!0)}catch{t.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&G(i,r);let c=Ie(n,o,"module.html");if(k(c)){let d=E(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),G(c,d),t.push(`${a}: now() \u2192 local_dt`))}}let s=Ie(e,"templates");if(k(s))for(let o of mn(s)){if(!o.endsWith(".html"))continue;let i=Ie(s,o),a=E(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(cr(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function dr(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let a=i.charAt(0).toUpperCase()+i.slice(1);return[i,a]}return i}),t=!0),Array.isArray(s.children)&&dr(s.children)&&(t=!0)}return t}function ur(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&ur(s.children)&&(t=!0)}return t}function Od(e,t){let n=[],s=t.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of t.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let a=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),r=a.length===0;n.push({label:r?"module.css created for each module":`module.css missing for: ${a.join(", ")}`,passed:s>0&&r,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=Ie(e,"templates"),d=!1;if(k(c))for(let u of mn(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=E(Ie(c,u));if(m.includes("dnd_area")&&/templateType\s*:\s*page/i.test(m)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function Rd(e){let t=Ie(e,"templates");if(k(t))for(let n of mn(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=Ie(t,n),o=E(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),a=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&a)continue;let r=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);i||(c+=`
1735
1751
  templateType: page`),a||(c+=`
1736
1752
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
1737
1753
  label: ${r}`),o=c+o.slice(l)}else o=`<!--
@@ -1739,34 +1755,34 @@ ${d}/${l.length} checks passed`),await Ge(c.join(`
1739
1755
  isAvailableForNewContent: true
1740
1756
  label: ${r}
1741
1757
  -->
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.
1758
+ `+o;G(s,o),U(`Template "${n}" \u2014 annotations verified`)}}function Fd(e){let t=Ie(e,"modules");if(k(t))for(let n of mn(t)){if(!n.endsWith(".module"))continue;let s=Ie(t,n,"meta.json");if(k(s))try{let o=JSON.parse(E(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&G(s,JSON.stringify(o,null,2)+`
1759
+ `)}catch{}}}f();ht();import{join as wr,basename as Vd}from"path";f();te();import{join as de}from"path";import{readdirSync as it,rmSync as Jd}from"fs";function cs(e){let t=[];for(let n of e){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function ds(e){let t=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(e)&&t.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(e)&&t.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(e)){let n=e.match(/field.*?(\w+)\s+has an invalid/i);t.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(e)){let n=e.match(/file '([^']+)'/i);t.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(e)&&t.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),t}function us(e){let t=[];return pr(e)&&t.push("textarea \u2192 text"),gr(e)&&t.push("name \u2192 item_name"),fr(e)&&t.push("now() \u2192 local_dt"),hr(e)&&t.push("Removed HubDB templates"),yr(e)&&t.push("Fixed link field defaults"),br(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),jd(e)&&t.push("Stripped CDN @import statements"),t}function mr(e,t){return t.message.includes("textarea")?pr(e):t.message.includes("reserved field name")?gr(e):t.message.includes("now()")?fr(e):t.message.includes("HubDB")?hr(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?yr(e):t.message.includes("invalid format")&&t.message.includes("color")?br(e):!1}function pr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(!k(o))continue;let i=E(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),G(o,i),t=!0)}return t}function gr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(!k(o))continue;let i=E(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),G(o,i),t=!0)}return t}function fr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"module.html");if(!k(o))continue;let i=E(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),G(o,i),t=!0)}return t}function hr(e){let t=!1,n=de(e,"templates");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=de(n,s),i=E(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Jd(o),t=!0)}return t}function yr(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(k(o))try{let i=JSON.parse(E(o));xr(i)&&(G(o,JSON.stringify(i,null,2)+`
1760
+ `),t=!0)}catch{}}return t}function jd(e){let t=!1,n=de(e,"css");if(k(n))for(let o of it(n)){if(!o.endsWith(".css"))continue;let i=de(n,o),a=E(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(G(i,r),t=!0)}let s=de(e,"modules");if(k(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=de(s,o,"module.css");if(!k(i))continue;let a=E(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(G(i,r),t=!0)}if(k(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=de(s,o,"module.html");if(!k(i))continue;let a=E(i),r=a.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");r!==a&&(G(i,r),t=!0)}return t}function br(e){let t=!1,n=de(e,"modules");if(!k(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=de(n,s,"fields.json");if(k(o))try{let i=JSON.parse(E(o));Sr(i)&&(G(o,JSON.stringify(i,null,2)+`
1761
+ `),t=!0)}catch{}}return t}function Sr(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="color"&&s.default&&typeof s.default=="object"){let o=s.default,i=o.color;if(typeof i=="string"&&!Dd(i)){let a=Hd(i);a&&(o.color=a.hex,a.opacity!==void 0&&(o.opacity=a.opacity),t=!0)}}Array.isArray(s.children)&&Sr(s.children)&&(t=!0)}return t}function Dd(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function Hd(e){let t=e.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(t)return{hex:`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`};let n=e.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),a=Math.min(255,parseInt(n[2])),r=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=e.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function xr(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&xr(s.children)&&(t=!0)}return t}Q();f();bt();bt();import{readdirSync as Ld}from"fs";import{join as Bd,relative as Ud}from"path";var Gd=new Set([".git","node_modules",".vibespot",".DS_Store"]);function vr(e){let t=[];for(let n of Ld(e,{withFileTypes:!0})){if(Gd.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=Bd(e,n.name);n.isDirectory()?t.push(...vr(s)):n.isFile()&&t.push(s)}return t}async function Wd(e,t,n){let s=0;async function o(){for(;s<e.length;){let a=s++;await n(e[a])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function ms(e,t,n,s={}){let o=s.concurrency??5,i=vr(t),a=i.length,r=0,l=0,c=[];return await Wd(i,o,async d=>{let u=Ud(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await Wi(e,m,d);if(g.success)r++,s.onFileComplete?.(u);else{l++;let y={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(y),s.onFileError?.(u,y)}s.onProgress?.(r+l,a)}),{success:l===0,uploaded:r,failed:l,total:a,errors:c}}function Kd(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Jt(e){await ge("Uploading to HubSpot");let t=Vd(e)||e,n=P(),s=Se(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await he(),a=3;for(let r=1;r<=a;r++){i.start(r===1?"Uploading theme...":`Retrying upload (attempt ${r}/${a})...`);let l=[],c=0,d=!1;if(o){let m=await ms(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=cs(m.errors)}else{let m=J(`hs cms upload "${e}" "${t}"`,{cwd:wr(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
1762
+ `);c=Kd(g),d=m.success,d||(l=ds(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await fe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(V("Upload failed with unknown error."),c>0&&(q(`Most files uploaded successfully. The theme may already be usable in HubSpot.
1747
1763
  You can check your HubSpot Design Manager to verify.`),await le({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(r<a){if(!await le({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?mr(e,m)?(U(`Auto-fixed: ${m.message}`),u=!0):q(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&r<a)){if(c>0&&(q(`${c} files uploaded successfully despite errors.
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.
1764
+ The theme may work \u2014 check HubSpot Design Manager.`),await le({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await ao(s,`${t}/modules`)}catch{}else J(`hs cms delete "${t}/modules"`,{cwd:wr(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}f();import{execFileSync as yo}from"child_process";import{rmSync as zd}from"fs";import{basename as Cr}from"path";te();async function kr(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ge("You're all set!");let a=sn(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await Ge(`Your React page has been converted and uploaded to HubSpot.
1749
1765
  The theme and modules are now in your account, but you still
1750
- need to ${_.bold("create a new landing page")} that uses them.
1766
+ need to ${N.bold("create a new landing page")} that uses them.
1751
1767
 
1752
1768
  Next steps:
1753
1769
 
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,`
1770
+ ${N.bold("1.")} Go to HubSpot ${N.muted("\u2192")} Content ${N.muted("\u2192")} Landing Pages ${N.muted("\u2192")} Create
1771
+ ${N.bold("2.")} Choose your uploaded theme from the theme picker
1772
+ ${N.bold("3.")} Select the landing page template that was just created
1773
+ ${N.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
1774
+ ${N.bold("5.")} Click each section to edit text, images, and colors
1775
+ ${N.bold("6.")} Upload images via File Manager ${N.muted("(Settings \u2192 Files)")}
1776
+ ${N.bold("7.")} Preview and publish!`,"What's next"),await le({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${a}/page-ui/${t}/management/pages/landing`:`https://${a}`;try{let d=process.platform;d==="darwin"?yo("open",[c],{stdio:"ignore"}):d==="win32"?yo("cmd",["/c","start","",c],{stdio:"ignore"}):yo("xdg-open",[c],{stdio:"ignore"}),U("Opening HubSpot Landing Pages...")}catch{ne(`Open this URL in your browser: ${N.info(c)}`)}}let l=[];if(o&&k(n)&&l.push({path:n,label:`Cloned source (${Cr(n)})`}),k(s)&&l.push({path:s,label:`Theme directory (${Cr(s)})`}),l.length>0&&await le({message:"Clean up local working directories?"}))for(let d of l)try{zd(d.path,{recursive:!0,force:!0}),U(`Removed ${d.label}`)}catch{q(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await fe(`Thanks for using hub${N.vibes("Vibes")}! ${N.vibes("~")}`)}Q();async function Ar(){He();let e=await qn(),t=await Xn();W({lastSourcePath:t.sourceDir});let n=await ts();W({lastThemePath:n.themePath}),await ls({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Jt(n.themePath),await kr({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}f();async function $r(){He(),await qn()}f();Q();async function Tr(){He();let e=P();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await Xn(),n=await ts();await ls({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}f();Q();async function Ir(){He();let e=P();if(e.lastThemePath)if(await le({message:`Upload from ${e.lastThemePath}?`}))await Jt(e.lastThemePath);else{let n=await Ne({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Jt(n)}else{let t=await Ne({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Jt(t)}}f();Q();async function Er(){He(),await ge("Environment Diagnostics");let e=0,t=en();t.found?Wn(t.version)?U(`Node.js v${t.version}`):(q(`Node.js v${t.version} \u2014 too old (need 18+)`),ne(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),ne(" Install from https://nodejs.org"),e++);let n=tn();n.found?U(`Git ${n.version}`):(V("Git \u2014 not installed"),ne(" Install from https://git-scm.com"),e++);let s=Be();if(!s.found)q("HubSpot CLI \u2014 not installed (only needed for deployment)"),ne(" Install: npm install -g @hubspot/cli");else if(!Bi(s.version))q(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),ne(" Update: npm install -g @hubspot/cli@latest"),e++;else{U(`HubSpot CLI v${s.version}`);let m=Ue();m.authenticated?U(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(q("HubSpot \u2014 not authenticated"),ne(" Run: hs init"))}let o=nn();o.found?U(`Claude Code ${o.version} at ${o.path}`):ne(N.muted("Claude Code \u2014 not installed"));let i=on();i.found?U(`Gemini CLI ${i.version} at ${i.path}`):ne(N.muted("Gemini CLI \u2014 not installed"));let a=rn();a.found?U(`OpenAI Codex ${a.version} at ${a.path}`):ne(N.muted("OpenAI Codex \u2014 not installed"));let r=P(),l=!!(r.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(r.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(r.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?U("Anthropic API key configured"):ne(N.muted("Anthropic API key \u2014 not set")),c?U("OpenAI API key configured"):ne(N.muted("OpenAI API key \u2014 not set")),d?U("Google AI API key configured"):ne(N.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};r.aiEngine&&U(`AI engine: ${u[r.aiEngine]||r.aiEngine}`),r.lastThemePath&&ne(N.muted(`Last theme: ${r.lastThemePath}`)),!o.found&&!i.found&&!a.found&&!l&&!c&&!d&&(q("No AI engine available"),ne(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),ne(" Or install: Claude Code \u2014 https://claude.ai/code"),ne(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),ne(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await fe("Everything looks good!"):await fe(N.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}f();import{join as zs}from"path";import{existsSync as Vp}from"fs";import{execFileSync as Ei}from"child_process";import Ys from"chalk";f();pe();jt();ks();Tn();import{createServer as Dp}from"http";import{readFileSync as Ii,existsSync as Pn}from"fs";import{join as dt,extname as Lc}from"path";import{createHash as Hp}from"crypto";import{WebSocketServer as Lp}from"ws";f();Fe();pe();Q();ie();import{existsSync as ul,mkdirSync as Hm,writeFileSync as Lm,rmSync as Bm}from"fs";import{join as ml}from"path";var Um="plan.md";function pl(e){return ml(e,".vibespot",Um)}function mi(e){let t=v();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;try{let n=ml(t.themePath,".vibespot");ul(n)||Hm(n,{recursive:!0}),Lm(pl(t.themePath),e,"utf-8")}catch(n){A.warn("plan",`Failed to write plan.md: ${n instanceof Error?n.message:String(n)}`)}return j(),e}function pi(){let e=v();if(e){e.brandAssets&&delete e.brandAssets.plan;try{let t=pl(e.themePath);ul(t)&&Bm(t)}catch(t){A.warn("plan",`Failed to remove plan.md: ${t instanceof Error?t.message:String(t)}`)}j()}}function gl(e,t){Ye(e,t,n=>{if(!v()){p(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(t,400,{error:"Plan content cannot be empty"});return}mi(o),p(t,200,{ok:!0,plan:o})})}function fl(e,t){Ye(e,t,()=>{pi(),W({planMode:!1}),p(t,200,{ok:!0})})}f();var gi=/```vibespot-plan\s*\n([\s\S]*?)```/g,fi=/```vibespot-choices\s*\n([\s\S]*?)```/g;function hl(e){let t,n,s;for(gi.lastIndex=0;(s=gi.exec(e))!==null;)t=s[1].trim();let o;for(fi.lastIndex=0;(o=fi.exec(e))!==null;)try{let a=JSON.parse(o[1].trim());a&&typeof a.question=="string"&&Array.isArray(a.options)&&a.options.every(r=>typeof r=="string")&&a.options.length>0&&(n={question:a.question,options:a.options})}catch{}return{cleanedContent:e.replace(gi,"").replace(fi,"").replace(/\n{3,}/g,`
1761
1777
 
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+=`
1778
+ `).trim(),plan:t,choices:n}}Q();f();import{spawn as hi}from"child_process";var gt=new Map;function yl(e,t,n){e.stdout?.on("data",o=>{t.output+=o.toString()}),e.stderr?.on("data",o=>{t.output+=o.toString()}),e.on("close",o=>{t.status=o===0?"completed":"failed",t.exitCode=o,t.completedAt=Date.now()}),e.on("error",o=>{t.status="failed",t.output+=`
1763
1779
  Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.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+=`
1780
+ Process timed out`,t.completedAt=Date.now())},n||3e5)}function In(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};gt.set(o,i);let a=hi(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&a.stdin&&(a.stdin.write(s.stdin),a.stdin.end()),yl(a,i,s?.timeout),o}function $t(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};gt.set(s,o);let i=e.split(" "),a=hi(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return yl(a,o,n?.timeout),s}function Os(e){return gt.get(e)}function Gm(){let e=Date.now()-18e5;for(let[t,n]of gt)n.completedAt&&n.completedAt<e&&gt.delete(t)}setInterval(Gm,600*1e3);function Rs(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};gt.set(s,o);let i=e.split(" "),a=hi(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),r=c=>{for(let d of o.listeners)try{d(c)}catch{}};a.stdout?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.stderr?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),a.on("error",c=>{o.status="failed",o.output+=`
1765
1781
  Process error: ${c.message}`,o.completedAt=Date.now(),o.listeners.clear()});let l=n?.timeout||3e5;return setTimeout(()=>{o.status==="running"&&(a.kill(),o.status="failed",o.output+=`
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,`
1782
+ Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function bl(e,t){let n=gt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Sl(e,t){let n=gt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}Fe();te();f();Fe();Q();Qn();es();bt();pe();Tn();import{existsSync as Kt,readdirSync as xl,rmSync as Wm}from"fs";import{join as zt,basename as Vm}from"path";import{homedir as Km}from"os";import{execFileSync as vl}from"child_process";Q();te();var wl=process.platform==="win32"?{shell:!0}:{},Je=zt(Km(),"vibespot-themes"),Fs=null,zm=5e3;function Js(){if(Fs&&Date.now()-Fs.ts<zm)return Fs.data;let e=[];if(Kt(Je))try{for(let t of xl(Je,{withFileTypes:!0}))if(t.isDirectory()){let n=zt(Je,t.name,"theme.json");if(Kt(n)){let s=0,o=zt(Je,t.name,"modules");if(Kt(o))try{s=xl(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return Fs={data:e,ts:Date.now()},e}function Cl(e){let t=v(),n=Vn(),s=!1;try{vl("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...wl}),s=!0}catch{}let o=Lt().sort((a,r)=>r.updatedAt-a.updatedAt).slice(0,10),i=Js();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i})}function kl(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,""),i=zt(Je,o);Te(Je),Kt(i)&&Wm(i,{recursive:!0,force:!0}),cn(i,o),vt(i,o),j(),p(t,200,{ok:!0,themeName:o,themePath:i})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Al(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Se(),a=P(),r=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=zt(Je,r);Te(Je),a.hubspotUploadMode==="cli"||!i?(vl("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...wl}),vt(l,r),bn(l),j(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})):dn(i,o,l).then(()=>{vt(l,r),bn(l),j(),p(t,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})}).catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function $l(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme path is required"});return}let o=s;if(Kt(o)||(o=zt(Je,s)),!Kt(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Vm(o);vt(o,i),bn(o),j(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:v()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Tl(e,t){B(e,n=>{try{if(Wt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Session ID is required"});return}let o=ws(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Il(e,t){B(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}W({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function El(e){let t=Se();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Ki(t);if(n.length===0){p(e,200,{themes:[]});return}let s=[],o=n.map(async r=>{let l=r.path||r.name;try{let c=await Yn(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:r.name,path:l})}catch{}});await Promise.all(o),s.sort((r,l)=>r.name.localeCompare(l.name));let i=Js(),a=new Set(i.map(r=>r.name));p(e,200,{themes:s.map(r=>({...r,existsLocally:a.has(r.name)}))})})().catch(n=>{p(e,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}f();Fe();Q();pe();import{existsSync as Ym,readFileSync as qm,appendFileSync as Xm}from"fs";import{join as _l}from"path";import{homedir as Nl}from"os";bt();te();var En={data:{},ts:0},Zm=600*1e3,Pl={"claude-code":[{id:"sonnet",label:"Claude Sonnet (default)"},{id:"opus",label:"Claude Opus"},{id:"haiku",label:"Claude Haiku"}],"codex-cli":[{id:"o4-mini",label:"o4 Mini (default)"},{id:"o3",label:"o3"},{id:"gpt-4o",label:"GPT-4o"}]};async function Qm(e){let t=await fetch("https://api.anthropic.com/v1/models",{headers:{"x-api-key":e,"anthropic-version":"2023-06-01"}});return t.ok?(await t.json()).data.filter(s=>!s.id.startsWith("claude-3-")&&!s.id.startsWith("claude-2")).map(s=>({id:s.id,label:s.display_name})):[]}async function ep(e){let t=await fetch("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});if(!t.ok)return[];let n=await t.json(),s=/^(gpt-4o|gpt-4o-mini|o[1-4](-mini)?|o[1-4]-pro)$/;return n.data.filter(o=>s.test(o.id)).sort((o,i)=>o.id.localeCompare(i.id)).map(o=>({id:o.id,label:o.id}))}async function tp(e){let t=await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${e}`);return t.ok?(await t.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function np(){if(Date.now()-En.ts<Zm&&Object.keys(En.data).length>0)return En.data;let e=P(),t={...Pl},n=[],s=be("anthropic-api",e);s&&n.push(Qm(s).then(a=>{a.length&&(t["anthropic-api"]=a,t["claude-oauth"]=a)}).catch(()=>{}));let o=be("openai-api",e);o&&n.push(ep(o).then(a=>{a.length&&(t["openai-api"]=a)}).catch(()=>{}));let i=be("gemini-api",e);return i&&n.push(tp(i).then(a=>{a.length&&(t["gemini-api"]=a,t["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n),En.data=t,En.ts=Date.now(),t}function Ml(e){let t=Vn(),n=P(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(r=>({portalId:r.portalId,portalName:r.portalName,dataCenter:r.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null},o=Lt().length,i=Js().length,a=Nt();np().then(r=>{p(e,200,{version:a,environment:t,config:s,models:r,sessionCount:o,localThemeCount:i})}).catch(()=>{p(e,200,{version:a,environment:t,config:s,models:Pl,sessionCount:o,localThemeCount:i})})}function Ol(e,t){B(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let a={aiEngine:s};if(o)switch(s){case"claude-code":a.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":a.anthropicApiModel=o;break;case"openai-api":a.openaiApiModel=o;break}W(a),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Rl(e,t){B(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"figma":l.figmaToken="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}W(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"figma":i.figmaToken=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}W(i);let a=null;if(!P().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(W({aiEngine:c}),a=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:a})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Fl(e,t){B(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let a=$t(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:a})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Jl(e,t){B(e,n=>{try{let s=JSON.parse(n||"{}"),o=P(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){zn(s.personalAccessKey).then(a=>{qt(s.personalAccessKey,a.portalId,a.portalName,a.dataCenter),p(t,200,{ok:!0,portalName:a.portalName,portalId:a.portalId,dataCenter:a.dataCenter})}).catch(a=>{p(t,400,{error:a instanceof Error?a.message:String(a)})});return}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=In("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:r});return}if(i==="api"){let a=o.hubspotAccounts||[];if(a.length>0&&!s.force){let r=a.find(l=>l.portalId===o.activeHubSpotAccount)||a[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=Ue();if(r.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function jl(e,t){B(e,n=>{try{let s=JSON.parse(n||"{}");if(!io().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=ro();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let r=In("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:r});return}let a=$t("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:a,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Dl(e,t){B(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((P().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Zs(s),p(t,200,{ok:!0});return}if(s){Qs(s),p(t,200,{ok:!0});return}}else{if(!Be().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=In("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=In("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}}p(t,400,{error:"portalId required"})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Hl(e){let t=$t("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function Ll(e,t){B(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=$t("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=$t("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,W({openaiApiKey:i}),process.platform!=="win32"){let a=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(a){let r=`export OPENAI_API_KEY="${a}"`,l=process.env.SHELL?.includes("zsh")?_l(Nl(),".zshrc"):_l(Nl(),".bashrc");try{(Ym(l)?qm(l,"utf-8"):"").includes("OPENAI_API_KEY")||Xm(l,`
1767
1783
  # Added by vibeSpot
1768
1784
  ${r}
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(`
1785
+ `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=$t("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:p(t,400,{error:`Unknown CLI: ${s}`})}}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Bl(e,t){B(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}W({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ul(e,t){B(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(t,400,{error:"toolId (string) and enabled (boolean) required"});return}eo(s,o),p(t,200,{ok:!0,toolId:s,enabled:o})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Gl(e,t){B(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}let i={};for(let a of o)a in s&&(i[a]=s[a]);if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}W(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Wl(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=Os(n);if(!s){p(t,404,{error:"Job not found"});return}p(t,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}f();Fe();Q();tt();function Vl(e,t){B(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"access_token is required"});return}to(s.trim(),(o||"").trim());let i=P();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&W({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Kl(e,t){let n=Le(),s=Qt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function zl(e,t){try{Ln(),P().aiEngine==="claude-oauth"&&W({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}f();Fe();pe();import{existsSync as sp,rmSync as op}from"fs";import{join as ip}from"path";function Yl(e,t,n){if(e==="GET"){let s=v(),o=Lt().sort((i,a)=>a.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName}:null,sessions:o});return}if(e==="DELETE"){B(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Yr(o,i),p(n,200,{ok:!0})}catch(o){p(n,500,{error:o instanceof Error?o.message:String(o)})}});return}p(n,405,{error:"Method not allowed"})}function ql(e,t){B(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=ws(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Xl(e,t){B(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=ip(Je,s);if(!sp(o)){p(t,404,{error:"Theme not found on disk"});return}op(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Zl(e,t){B(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){p(t,400,{error:"Invalid name"});return}let a=qr(s,i);a.ok?p(t,200,{ok:!0,newName:i}):p(t,400,{error:a.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}f();Fe();ie();Q();pe();te();import{existsSync as Us,readFileSync as pp,rmSync as vi}from"fs";import{join as Ze,basename as gp}from"path";import{execFileSync as fp}from"child_process";var hp=process.platform==="win32"?{shell:!0}:{};function ic(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}let n=at();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1}})}function rc(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!Us(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=Ze(n,".."),i=gp(n);try{let a=`${s}.zip`,r=Ze(o,a);Us(r)&&vi(r),fp("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...hp});let l=pp(r);vi(r),e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${a}"`,"Content-Length":l.length}),e.end(l)}catch(a){A.error("download-zip","Failed to create zip archive",a),p(e,500,{error:"Failed to create zip archive"})}}function ac(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){B(t,o=>{try{let{pageType:i,label:a}=JSON.parse(o);if(!i||!a){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=bs(i,a);j(),p(n,200,{ok:!0,template:{id:l.id,label:l.label,pageType:l.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){B(t,o=>{try{let{templateId:i,deleteModules:a}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Kr(i,!!a)){p(n,404,{error:"Template not found"});return}j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function lc(e,t){B(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!Ao(s)){p(t,404,{error:"Template not found"});return}j();let i=v();p(t,200,{ok:!0,modules:X().map(a=>a.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function cc(e,t){B(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"templateId and newLabel are required"});return}if(!Vr(s,o.trim())){p(t,404,{error:"Template not found"});return}j(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function dc(e,t){B(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=Wr(s,o);if(!i){p(t,404,{error:"Template not found"});return}j(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function uc(e){let t=at();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function mc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}B(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let r=at().find(d=>d.module.moduleName===i);if(!r){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...r.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function pc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){B(t,o=>{try{let{type:i,content:a}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=a==="on",s.updatedAt=Date.now(),j(),p(n,200,{ok:!0});return}if(!a){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let r=i,l=r==="themeContext"?"theme-context.md":`${r}.md`;s.brandAssets[r]=a,s.updatedAt=Date.now();let c=Ze(s.themePath,".vibespot");Te(c),G(Ze(c,l),a),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){B(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let a=i;s.brandAssets&&delete s.brandAssets[a],s.updatedAt=Date.now();let r=a==="themeContext"?"theme-context.md":`${a}.md`,l=Ze(s.themePath,".vibespot",r);Us(l)&&vi(l),j(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function sc(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Ze(e.themePath,".vibespot");Te(o),G(Ze(o,s),n)}async function oc(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Bs(),Ls));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Tn(),dl)),{loadConfig:o}=await Promise.resolve().then(()=>(Q(),ji)),i=o(),{engine:a,apiKey:r,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ks(),jo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(nc(),tc));return m(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(xi(),Si));return u(d,e.brandAssets?.themeContext,a,r,l)}function gc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",a=o.sourcePath;if(i==="all"){let l=["styleguide","brandvoice","themeContext"],c=await Promise.allSettled(l.map(u=>oc(n,u,a))),d={};for(let u=0;u<l.length;u++){let m=c[u],g=m.status==="fulfilled"?m.value:null;g&&sc(n,l[u],g),d[l[u]]=g}j(),p(t,200,{ok:!0,type:"all",extracted:d});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let r=await oc(n,i,a);if(!r){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}sc(n,i,r),j(),p(t,200,{ok:!0,type:i,content:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function fc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:a}=JSON.parse(s),r;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Se();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:y}=await import("os"),h=Ze(y(),"vibespot-themes",".references",g);Te(h);let{fetchTheme:b}=await Promise.resolve().then(()=>(es(),er));await b(u,m,h),r=h}else if(o==="local"){if(!a){p(t,400,{error:"localPath is required for local import"});return}if(!Us(a)){p(t,400,{error:`Path not found: ${a}`});return}r=a}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(Bs(),Ls)),c=await l(r);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ze(n.themePath,".vibespot");Te(d),G(Ze(d,"styleguide.md"),c),j(),p(t,200,{ok:!0,styleguide:c,source:r})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}f();Fe();pe();import{join as yp}from"path";jt();function hc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function yc(e,t,n){let s=v();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=X();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){Ye(t,n,o=>{o.deleteEntirely?Hr(o.moduleName):Lr(o.moduleName),j(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function bc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}B(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=xe();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),j(),_e(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:a,content:r}=o;if(!i||!a){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(a){case"html":l.moduleHtml=r;break;case"css":l.moduleCss=r;break;case"js":l.moduleJs=r||void 0;break;case"fields":try{JSON.parse(r)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=r;break;default:p(t,400,{error:`Invalid fileType: ${a}`});return}n.updatedAt=Date.now(),j(),_e(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function Sc(e,t){Ye(e,t,n=>{Array.isArray(n.order)?(Ke(n.order),j(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function xc(e){let t=v();if(!t){p(e,404,{error:"No active session"});return}try{_e();let n=us(t.themePath),s=Rs(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:yp(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function vc(e,t){B(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Br(s,o,i),j(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function wc(e,t){B(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=Xi(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
1770
1786
  `),a={sourceDir:o.sourceDir,componentCount:o.components.length,components:o.components.map(r=>({name:r.name,description:r.description})),hasTailwind:o.hasTailwind,cssVarCount:o.cssVarCount,fonts:o.fonts,interactions:o.interactions,conversionPrompt:`Import and convert the React landing page from ${s} to native HubSpot modules.
1771
1787
 
1772
1788
  Source analysis found ${o.components.length} components:
@@ -1776,11 +1792,11 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
1776
1792
  Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
1777
1793
  Interactions: ${o.interactions.join(", ")}
1778
1794
 
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}
1795
+ Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};p(t,200,a)}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Cc(e,t){let n=v();if(!n){p(t,404,{error:"No active session"});return}if(!Oe()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?Or(n.themePath,o,50):Mr(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function kc(e,t){B(e,n=>{try{let s=v();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(Re("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let a=s.templates.find(c=>c.id===i);if(!a){p(t,404,{error:"Template not found"});return}let r=a.moduleOrder.map(c=>`modules/${c}.module`);a.templateFile&&r.push(a.templateFile);let l=Fr(s.themePath,i,o,r);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}ea()}else{let a=Rr(s.themePath,o);if(!a.success){p(t,500,{error:a.error||"Rollback failed"});return}Qr()}j(),p(t,200,{ok:!0,modules:X().map(a=>a.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}Yo();Ti();var Bc={".html":"text/html",".css":"text/css",".js":"application/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".ico":"image/x-icon",".woff2":"font/woff2"};function Uc(e){let{port:t,uiDir:n}=e,s=Dp((i,a)=>Bp(i,a,n)),o=new Lp({server:s});return o.on("connection",i=>Gp(i)),new Promise((i,a)=>{s.on("error",r=>{r.code==="EADDRINUSE"?s.listen(t+1,()=>{i({port:t+1,close:()=>{s.close(),o.close()}})}):a(r)}),s.listen(t,()=>{i({port:t,close:()=>{s.close(),o.close()}})})})}function Bp(e,t,n){let s=new URL(e.url||"/",`http://${e.headers.host}`),o=e.method||"GET";if(t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("X-XSS-Protection","1; mode=block"),t.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname.startsWith("/api/")){Up(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=Fo();t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",a=Jo(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(a||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){Wp(s.pathname.slice(14),t);return}if(s.pathname==="/docs"){t.writeHead(301,{Location:"/docs/"}),t.end();return}if(s.pathname.startsWith("/docs/")){let i=s.pathname.slice(5)||"/index.html";Hc(i,dt(n,"docs"),e,t);return}Hc(s.pathname,n,e,t)}function Up(e,t,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(o)&&s.setHeader("Access-Control-Allow-Origin",o),s.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type"),e==="OPTIONS"){s.writeHead(204),s.end();return}switch(t){case"/api/session":hc(e,s);break;case"/api/modules":yc(e,n,s);break;case"/api/modules/reorder":Sc(n,s);break;case"/api/modules/code":bc(n,s);break;case"/api/upload":xc(s);break;case"/api/upload-files":e==="POST"?Ia(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":vc(n,s);break;case"/api/import":wc(n,s);break;case"/api/setup":Cl(s);break;case"/api/setup/create":kl(n,s);break;case"/api/setup/fetch":Al(n,s);break;case"/api/setup/open":$l(n,s);break;case"/api/setup/resume":Tl(n,s);break;case"/api/setup/apikey":Il(n,s);break;case"/api/setup/remote-themes":e==="GET"?El(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?Ml(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?Ol(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?Rl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Fl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?Jl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?jl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?Dl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Hl(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?Ll(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Bl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Ul(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Vl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Kl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?zl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Gl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Mi()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Yl(e,n,s);break;case"/api/themes/switch":e==="POST"?ql(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Xl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Zl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?Cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?kc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?ic(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":ac(e,n,s);break;case"/api/templates/activate":e==="POST"?lc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?cc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?dc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?uc(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":pc(e,n,s);break;case"/api/brand-assets/extract":e==="POST"?gc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?fc(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?rc(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?ki(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?Ai(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?$i(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?gl(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?fl(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?Wl(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?mc(t,n,s):p(s,404,{error:"Not found"})}}function Gp(e){e.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{e.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;let i=Array.isArray(s.fileIds)?s.fileIds:void 0;if(di()){Re("user",o),j();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let r="",l=await ci(o,d=>{r+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=hl(l||r);c.plan&&(mi(c.plan),e.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&e.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),Re("assistant",c.cleanedContent),j(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}Re("user",o),j();let a=ui();a.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await Ms(o,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:m,...g}=u;e.send(JSON.stringify(g))}else e.send(JSON.stringify(u));if(u.type==="agent_step")l.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let m=l[l.length-1];m&&(m.decisions||(m.decisions=[]),m.decisions.push(u.decision))}else u.type==="design_system_ready"?oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),Ke(u.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(oe({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)})),c.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&c.push({name:u.module,status:"failed"})},i);At(d,{steps:l,modules:c,stats:d.stats})}else ai(l=>{e.send(JSON.stringify({type:"parse_warning",message:l}))}),await An(o,l=>{e.send(JSON.stringify({type:"stream",content:l}))},l=>{e.send(JSON.stringify({type:"stream_status",content:l}))},i);let r=v();if(r){_e();let l=xe(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${r.themeName}-theme.css`),l.sharedJs&&d.push(`js/${r.themeName}-animations.js`),c=bo(r.themePath,l.id,o,d)}else c=St(r.themePath,o);c&&e.send(JSON.stringify({type:"version_created",hash:c}))}e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(l=>l.moduleName)}));{let l=v();l&&a.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&e.send(JSON.stringify({type:"suggest_brand_extraction"}))}}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:a}=await Promise.resolve().then(()=>(Ti(),Dc)),r=a(o);if(!r){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=v();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:y}=await import("fs"),{createThemeScaffold:h}=await Promise.resolve().then(()=>(Qn(),Zi)),b=m(g(),"vibespot-themes"),x=m(b,i);if(!y(b)){let{mkdirSync:w}=await import("fs");w(b,{recursive:!0})}y(x)||h(x,i),vt(x,i),j()}e.send(JSON.stringify({type:"figma_import_started",fileName:r.fileName}));let c=[],d=[],u=await $n(r,i,m=>{if(m.type==="module_progress"&&m.moduleFiles){let{moduleFiles:g,...y}=m;e.send(JSON.stringify(y))}else e.send(JSON.stringify(m));if(m.type==="agent_step")c.push({step:m.step,label:m.label});else if(m.type==="agent_decision"){let g=c[c.length-1];g&&(g.decisions||(g.decisions=[]),g.decisions.push(m.decision))}else m.type==="design_system_ready"?oe({sharedCss:m.sharedCss,sharedJs:m.sharedJs}):m.type==="blueprint_ready"?(oe({sharedCss:m.sharedCss,sharedJs:m.sharedJs}),Ke(m.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(g=>g.moduleName)}))):m.type==="module_progress"&&m.status==="complete"&&m.moduleFiles?(oe({modules:[{moduleName:m.module,fieldsJson:m.moduleFiles.fieldsJson,metaJson:m.moduleFiles.metaJson,moduleHtml:m.moduleFiles.moduleHtml,moduleCss:m.moduleFiles.moduleCss,moduleJs:m.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(g=>g.moduleName)})),d.push({name:m.module,status:"complete"})):m.type==="module_progress"&&m.status==="failed"&&d.push({name:m.module,status:"failed"})});At(u,{steps:c,modules:d,stats:u.stats}),_e(),St(v().themePath,`Figma import: ${r.fileName}`),e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))}catch(l){e.send(JSON.stringify({type:"error",message:l instanceof Error?l.message:String(l)}))}break}case"extract_brand_assets":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=P(),{engine:a,apiKey:r,model:l}=Vt(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ks(),jo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(xi(),Si)),m=await u(d,o.brandAssets?.themeContext,a,r,l),{mkdirSync:g,writeFileSync:y}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let h=dt(o.themePath,".vibespot");Pn(h)||g(h,{recursive:!0}),y(dt(h,"theme-context.md"),m),j(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:h}=await Promise.resolve().then(()=>(Bs(),Ls)),b=await h(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let x=dt(o.themePath,".vibespot");Pn(x)||g(x,{recursive:!0}),y(dt(x,"styleguide.md"),b),j(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{_e();let i=us(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(P().hubspotUploadMode||"api")==="api"){let l=Se();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await ms(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
1780
1796
  `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
1781
1797
  `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
1782
1798
  `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=ut();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName}))}else{let d=cs(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
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.
1799
+ `),errors:d}))}}else{let l=Rs(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:dt(o.themePath,".."),timeout:18e4});e.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{e.send(JSON.stringify({type:"upload_output",chunk:u}))};bl(l,c);let d=setInterval(()=>{let u=Os(l);if(!(!u||u.status==="running"))if(clearInterval(d),Sl(l,c),u.status==="completed"){let m=Ue(),g=m.portalId?sn(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName}))}else{let m=ds(u.output);e.send(JSON.stringify({type:"upload_failed",output:u.output,errors:m,exitCode:u.exitCode}))}},500)}}catch(i){e.send(JSON.stringify({type:"error",message:i instanceof Error?i.message:String(i)}))}break}case"upload_fix_with_ai":{let o=String(s.errorContext||"");if(!o.trim()){e.send(JSON.stringify({type:"error",message:"No error context provided"}));break}let i=`The HubSpot upload ("hs cms upload") failed. Below is the upload log output containing the errors.
1784
1800
 
1785
1801
  IMPORTANT: Be verbose in your response. For each error:
1786
1802
  1. State exactly which file has the problem and what the error is
@@ -1793,9 +1809,9 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
1793
1809
  After fixing all errors, summarize the changes you made.
1794
1810
 
1795
1811
  Upload log:
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
1812
+ ${o}`;Re("user",i),j(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await An(i,r=>{e.send(JSON.stringify({type:"stream",content:r})),e.send(JSON.stringify({type:"upload_fix_stream",content:r}))});let a=v();if(a){_e();let r=St(a.themePath,"AI fix: upload errors");r&&e.send(JSON.stringify({type:"version_created",hash:r}))}e.send(JSON.stringify({type:"upload_fix_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(r=>r.moduleName)}))}catch(a){e.send(JSON.stringify({type:"upload_failed",output:a instanceof Error?a.message:String(a),errors:[{file:"AI fix",message:a instanceof Error?a.message:String(a),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=v();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.brandAssets?.plan;if(!i||!i.trim()){e.send(JSON.stringify({type:"error",message:"No plan to approve. Send a chat message first."}));break}W({planMode:!1});let a="Implement the approved plan.";Re("user",a),j();try{let r=[],l=[],c=await Ms(a,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:m,...g}=u;e.send(JSON.stringify(g))}else e.send(JSON.stringify(u));if(u.type==="agent_step")r.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let m=r[r.length-1];m&&(m.decisions||(m.decisions=[]),m.decisions.push(u.decision))}else u.type==="design_system_ready"?oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(oe({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),Ke(u.moduleOrder),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(oe({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),e.send(JSON.stringify({type:"modules_updated",modules:X().map(m=>m.moduleName)})),l.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&l.push({name:u.module,status:"failed"})});At(c,{steps:r,modules:l,stats:c.stats});let d=v();if(d){_e();let u=xe(),m=null;if(u){let g=u.moduleOrder.map(y=>`modules/${y}.module`);u.templateFile&&g.push(u.templateFile),u.sharedCss&&g.push(`css/${d.themeName}-theme.css`),u.sharedJs&&g.push(`js/${d.themeName}-animations.js`),m=bo(d.themePath,u.id,"Approved plan: implementation",g)}else m=St(d.themePath,"Approved plan: implementation");m&&e.send(JSON.stringify({type:"version_created",hash:m}))}e.send(JSON.stringify({type:"generation_complete"})),e.send(JSON.stringify({type:"modules_updated",modules:X().map(u=>u.moduleName)}))}catch(r){e.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"plan_discard":{pi(),W({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}});let t=v();if(t){let n=P(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=xe();e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:X().map(i=>i.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:Oe(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",templateId:o?.id||null,pageType:o?.pageType||null,templates:(t.templates||[]).map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||""}))}else e.send(JSON.stringify({type:"needs_setup"}))}function Wp(e,t){let n=v();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=dt(n.themePath,"assets",e);if(!Pn(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Lc(s),i=Bc[o]||"application/octet-stream",a=Ii(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(a)}function Hc(e,t,n,s){let i=dt(t,e==="/"?"/index.html":e);if(!Pn(i)){let c=dt(t,"index.html");if(Pn(c)){let d=Ii(c);s.writeHead(200,{"Content-Type":"text/html","Cache-Control":"no-cache"}),s.end(d)}else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not found");return}let a=Lc(i),r=Bc[a]||"application/octet-stream",l=a===".html";try{let c=Ii(i),d='"'+Hp("md5").update(c).digest("hex").slice(0,16)+'"';if(n.headers["if-none-match"]===d){s.writeHead(304),s.end();return}s.writeHead(200,{"Content-Type":r,"Cache-Control":"no-cache",ETag:d}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}pe();var Kp=4200;async function Gc(){let e=Ys.hex("#e8613a"),t=Ys.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
1813
+ `));let n=zp();n||(console.error(Ys.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await Uc({port:Kp,uiDir:n}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Press Ctrl+C to stop
1798
1814
  `));try{process.platform==="darwin"?Ei("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ei("cmd",["/c","start","",i],{stdio:"ignore"}):Ei("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
1799
1815
  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)});
1816
+ `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Ys.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function zp(){let e=[zs(import.meta.dirname,"../../ui"),zs(import.meta.dirname,"../ui"),zs(process.cwd(),"ui")];for(let t of e)if(Vp(zs(t,"index.html")))return t;return null}te();function Wc(){let e=new Yp;return e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Nt()).action(Gc),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Ar),e.command("init").description("Check and install required tools").action($r),e.command("convert").description("Convert a React project to HubSpot modules").action(Tr),e.command("upload").description("Upload theme to HubSpot").action(Ir),e.command("doctor").description("Diagnose environment issues").action(Er),e}var qp=Wc();qp.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
1801
1817
  //# sourceMappingURL=index.js.map